Merge "IKXCLOCK-11260 smelt: bcmdhd: security patches for Broadcom" into msm-moto-3.10
diff --git a/CVE_2016_2465.patch.txt b/CVE_2016_2465.patch.txt
new file mode 100644
index 0000000..1664e8f
--- /dev/null
+++ b/CVE_2016_2465.patch.txt
@@ -0,0 +1,173 @@
+From c0cef7a615b4b22c834f83dfe5e99b93737bf0ef Mon Sep 17 00:00:00 2001
+From: Veera Sundaram Sankaran <veeras@codeaurora.org>
+Date: Tue, 15 Mar 2016 18:42:27 -0700
+Subject: [PATCH] msm: mdss: fix possible out-of-bounds and overflow issue in
+ mdp debugfs
+
+There are few cases where the count argument passed by the user
+space is not validated, which can potentially lead to out of bounds
+or overflow issues. In some cases, kernel might copy more data than
+what is requested. Add necessary checks to avoid such cases.
+
+Change-Id: Ifa42fbd475665a0ca581c907ce5432584ea0e7ed
+Signed-off-by: Veera Sundaram Sankaran <veeras@codeaurora.org>
+---
+ drivers/video/msm/mdss/mdss_debug.c | 44 +++++++++++++++++++++----------------
+ 1 file changed, 25 insertions(+), 19 deletions(-)
+
+diff --git a/drivers/video/msm/mdss/mdss_debug.c b/drivers/video/msm/mdss/mdss_debug.c
+index 3b01bfc..e07aeeb 100644
+--- a/drivers/video/msm/mdss/mdss_debug.c
++++ b/drivers/video/msm/mdss/mdss_debug.c
+@@ -1,4 +1,4 @@
+-/* Copyright (c) 2009-2015, The Linux Foundation. All rights reserved.
++/* Copyright (c) 2009-2016, The Linux Foundation. All rights reserved.
+  *
+  * This 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,10 +109,10 @@ static ssize_t panel_debug_base_offset_read(struct file *file,
+ 		return 0;	/* the end */
+ 
+ 	len = snprintf(buf, sizeof(buf), "0x%02zx %zx\n", dbg->off, dbg->cnt);
+-	if (len < 0)
++	if (len < 0 || len >= sizeof(buf))
+ 		return 0;
+ 
+-	if (copy_to_user(buff, buf, len))
++	if ((count < sizeof(buf)) || copy_to_user(buff, buf, len))
+ 		return -EFAULT;
+ 
+ 	*ppos += len;	/* increase offset */
+@@ -231,10 +231,11 @@ static ssize_t panel_debug_base_reg_read(struct file *file,
+ 	if (mdata->debug_inf.debug_enable_clock)
+ 		mdata->debug_inf.debug_enable_clock(0);
+ 
+-	if (len < 0)
++	if (len < 0 || len >= sizeof(to_user_buf))
+ 		return 0;
+ 
+-	if (copy_to_user(user_buf, to_user_buf, len))
++	if ((count < sizeof(to_user_buf))
++			|| copy_to_user(user_buf, to_user_buf, len))
+ 		return -EFAULT;
+ 
+ 	*ppos += len;	/* increase offset */
+@@ -368,7 +369,7 @@ static ssize_t mdss_debug_base_offset_read(struct file *file,
+ {
+ 	struct mdss_debug_base *dbg = file->private_data;
+ 	int len = 0;
+-	char buf[24];
++	char buf[24] = {'\0'};
+ 
+ 	if (!dbg)
+ 		return -ENODEV;
+@@ -377,10 +378,10 @@ static ssize_t mdss_debug_base_offset_read(struct file *file,
+ 		return 0;	/* the end */
+ 
+ 	len = snprintf(buf, sizeof(buf), "0x%08zx %zx\n", dbg->off, dbg->cnt);
+-	if (len < 0)
++	if (len < 0 || len >= sizeof(buf))
+ 		return 0;
+ 
+-	if (copy_to_user(buff, buf, len))
++	if ((count < sizeof(buf)) || copy_to_user(buff, buf, len))
+ 		return -EFAULT;
+ 
+ 	*ppos += len;	/* increase offset */
+@@ -702,7 +703,7 @@ static ssize_t mdss_debug_factor_read(struct file *file,
+ {
+ 	struct mdss_fudge_factor *factor = file->private_data;
+ 	int len = 0;
+-	char buf[32];
++	char buf[32] = {'\0'};
+ 
+ 	if (!factor)
+ 		return -ENODEV;
+@@ -712,10 +713,10 @@ static ssize_t mdss_debug_factor_read(struct file *file,
+ 
+ 	len = snprintf(buf, sizeof(buf), "%d/%d\n",
+ 			factor->numer, factor->denom);
+-	if (len < 0)
++	if (len < 0 || len >= sizeof(buf))
+ 		return 0;
+ 
+-	if (copy_to_user(buff, buf, len))
++	if ((count < sizeof(buf)) || copy_to_user(buff, buf, len))
+ 		return -EFAULT;
+ 
+ 	*ppos += len;	/* increase offset */
+@@ -746,6 +747,8 @@ static ssize_t mdss_debug_perf_mode_write(struct file *file,
+ 	if (copy_from_user(buf, user_buf, count))
+ 		return -EFAULT;
+ 
++	buf[count] = 0;	/* end of string */
++
+ 	if (sscanf(buf, "%d", &perf_mode) != 1)
+ 		return -EFAULT;
+ 
+@@ -766,7 +769,7 @@ static ssize_t mdss_debug_perf_mode_read(struct file *file,
+ {
+ 	struct mdss_perf_tune *perf_tune = file->private_data;
+ 	int len = 0;
+-	char buf[40];
++	char buf[40] = {'\0'};
+ 
+ 	if (!perf_tune)
+ 		return -ENODEV;
+@@ -774,14 +777,12 @@ static ssize_t mdss_debug_perf_mode_read(struct file *file,
+ 	if (*ppos)
+ 		return 0;	/* the end */
+ 
+-	buf[count] = 0;
+-
+ 	len = snprintf(buf, sizeof(buf), "min_mdp_clk %lu min_bus_vote %llu\n",
+ 	perf_tune->min_mdp_clk, perf_tune->min_bus_vote);
+-	if (len < 0)
++	if (len < 0 || len >= sizeof(buf))
+ 		return 0;
+ 
+-	if (copy_to_user(buff, buf, len))
++	if ((count < sizeof(buf)) || copy_to_user(buff, buf, len))
+ 		return -EFAULT;
+ 
+ 	*ppos += len;   /* increase offset */
+@@ -801,7 +802,7 @@ static ssize_t mdss_debug_perf_panic_read(struct file *file,
+ {
+ 	struct mdss_data_type *mdata = file->private_data;
+ 	int len = 0;
+-	char buf[40];
++	char buf[40] = {'\0'};
+ 
+ 	if (!mdata)
+ 		return -ENODEV;
+@@ -811,10 +812,10 @@ static ssize_t mdss_debug_perf_panic_read(struct file *file,
+ 
+ 	len = snprintf(buf, sizeof(buf), "%d\n",
+ 		!mdata->has_panic_ctrl);
+-	if (len < 0)
++	if (len < 0 || len >= sizeof(buf))
+ 		return 0;
+ 
+-	if (copy_to_user(buff, buf, len))
++	if ((count < sizeof(buf)) || copy_to_user(buff, buf, len))
+ 		return -EFAULT;
+ 
+ 	*ppos += len;   /* increase offset */
+@@ -877,9 +878,14 @@ static ssize_t mdss_debug_perf_panic_write(struct file *file,
+ 	if (!mdata)
+ 		return -EFAULT;
+ 
++	if (count >= sizeof(buf))
++		return -EFAULT;
++
+ 	if (copy_from_user(buf, user_buf, count))
+ 		return -EFAULT;
+ 
++	buf[count] = 0;	/* end of string */
++
+ 	if (sscanf(buf, "%d", &disable_panic) != 1)
+ 		return -EFAULT;
+ 
+-- 
+1.8.2.1
+
diff --git a/CVE_2016_2468.patch.txt b/CVE_2016_2468.patch.txt
new file mode 100644
index 0000000..7a59844
--- /dev/null
+++ b/CVE_2016_2468.patch.txt
@@ -0,0 +1,50 @@
+From 616b5bfab8f8c7c25a113bd1c5fe48215cddab1d Mon Sep 17 00:00:00 2001
+From: Rajesh Kemisetti <rajeshk@codeaurora.org>
+Date: Mon, 9 May 2016 22:12:20 +0530
+Subject: [PATCH] msm: kgsl: Add missing checks for alloc size and sglen
+
+In _kgsl_sharedmem_page_alloc(), check for boundary limits
+of requested alloc size before honoring and make sure sglen
+is greater than zero before marking it as end of sg list.
+
+Change-Id: I8b9e225e515a0f31593df6f4cad253236475d0ae
+Signed-off-by: Rajesh Kemisetti <rajeshk@codeaurora.org>
+---
+ drivers/gpu/msm/kgsl_sharedmem.c | 10 ++++++++--
+ 1 file changed, 8 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/gpu/msm/kgsl_sharedmem.c b/drivers/gpu/msm/kgsl_sharedmem.c
+index 24a1680..98f634d 100644
+--- a/drivers/gpu/msm/kgsl_sharedmem.c
++++ b/drivers/gpu/msm/kgsl_sharedmem.c
+@@ -1,4 +1,4 @@
+-/* Copyright (c) 2002,2007-2015, The Linux Foundation. All rights reserved.
++/* Copyright (c) 2002,2007-2016, The Linux Foundation. All rights reserved.
+  *
+  * This program is free software; you can redistribute it and/or modify
+  * it under the terms of the GNU General Public License version 2 and
+@@ -609,6 +609,10 @@ _kgsl_sharedmem_page_alloc(struct kgsl_memdesc *memdesc,
+ 	unsigned int align;
+ 	int step = ((VMALLOC_END - VMALLOC_START)/8) >> PAGE_SHIFT;
+ 
++	size = PAGE_ALIGN(size);
++	if (size == 0 || size > UINT_MAX)
++		return -EINVAL;
++
+ 	align = (memdesc->flags & KGSL_MEMALIGN_MASK) >> KGSL_MEMALIGN_SHIFT;
+ 
+ 	page_size = get_page_size(size, align);
+@@ -712,7 +716,9 @@ _kgsl_sharedmem_page_alloc(struct kgsl_memdesc *memdesc,
+ 
+ 	memdesc->sglen = sglen;
+ 	memdesc->size = size;
+-	sg_mark_end(&memdesc->sg[sglen - 1]);
++
++	if (sglen > 0)
++		sg_mark_end(&memdesc->sg[sglen - 1]);
+ 
+ 	/*
+ 	 * All memory that goes to the user has to be zeroed out before it gets
+-- 
+1.8.2.1
+
diff --git a/Documentation/arm/msm/tsc.txt b/Documentation/arm/msm/tsc.txt
deleted file mode 100644
index 11e74a2..0000000
--- a/Documentation/arm/msm/tsc.txt
+++ /dev/null
@@ -1,398 +0,0 @@
-Introduction
-============
-
-TSC Driver
-
-The TSC (Transport Stream Controller) is a hardware block used in products such
-as smart TVs, Set-top boxes and digital media adapters, and is responsible for
-two main functionalities:
-
-1. Mux function: enabling the routing of MPEG-2 transport streams (TS) received
-from terrestrial/cable/satelite in order to support the different topologies of
-the end product, as it may be deployed in many different topologies.
-In addition, the active topology may change according to various factors such as
-broadcast technology and/or conditional access system.
-
-2. CI function: acting as a common interface, complying with both PC Card and
-CI/+ specifications.
-
-The TSC driver has two different interfaces, one for each function.
-
-Hardware description
-====================
-The TSC HW contains the TSC core, and uses the VBIF unit (IOMMU) which is part
-of the broadcast subsystem HW.
-
-Mux function:
--------------
-The TSC can receive transport streams from:
-a. Two Transport Stream Interfaces (TSIFs) 0 or 1, connected to two external
-demods or to external bridge.
-b. One TSIF from an integrated demod.
-
-The TSC can route TS from any of the above TSIFs to an external CICAM, using a
-software configurable mux.
-The TSC can route TS from any of the above TSIFs, and TS received from the CI
-Conditional Access Mudule (CICAM) to two TSIF outputs (0 or 1), using two
-software configurable muexes.
-The CICAM input and outputs are also managed via two additional TSIFs: TSIF-out
-to the CAM, and TSIF-in from the CAM.
-
-CI function:
-------------
-The common interface is composed of:
-1. Card detection logic: the TSC notifies the SW of any change in the card
-detection status (via HW interrupt).
-
-2. Control interface used to send/receive the CI messages (APDUs), supporting
-data transmission in two formats:
-a. Single byte transactions: to/from the attribute memory space of the CAM and
-   the command area of the CAM.
-b. Buffer transactions: to/from the command area of the CAM, using a
-   configurable buffer size of 1k bytes-64k bytes. This enables transferring
-   large chunks of data between the CAM and applications.
-   The data buffer resides in the external memory and the interface to the
-   memory is done through BCSS VBIF.
-The TSC uses PCMCIA interface to interact with the CAM.
-
-The following diagram provides an overview of the TSC HW:
-+-------------------------------------------------------------------------+
-|                                                                         |
-|                +------------------------------+                         |
-| +-----------+  |          TSC Core     --.    |                         |
-| |Ext. TSIF 0+------------+------------>|  \   |  +-----------+          |
-| +-----------+  |   +-----|------------>|Mux)----->TSPP TSIF 0|          |
-| +-----------+  |   |  +--|------------>|  /   |  +-----------+          |
-| |Ext. TSIF 1+------|  |  |          +->--'    |                         |
-| +-----------+  |   |  |  |          |  --.    |                         |
-|                |   |  |  +----------|->|  \   |  +-----------+          |
-| +-----------+  |   +--|--|-+--------|->|Mux)----->TSPP TSIF 1|          |
-| |Int. TSIF  +---------+--|-|-+------|->|  /   |  +-----------+          |
-| +-----------+  |         | | |      +->--'    |                         |
-|                |         | | |      |         |                         |
-|                |         | | |      |         |                         |
-|                |+------+(v-v-v--)   |  +-----+|                         |
-|                ||Card  | \ Mux /    |  |CI/+ +---Data-Interface--+      |
-|                ||detect|  `---'     |  +----++|                  |      |
-|                |+-^-^--+    |       |       | |                  |      |
-|                +--|-|-------|-------|-------|-+           +------+----+ |
-|                   | |       |       |       |             |   VBIF    | |
-|                   | | +-----v--+ +--+----+  |             |           | |
-|                   | | |TSIF-Out| |TSIF-In|  |             +-----------+ |
-|                   | | +-----+--+ +--^----+  |                           |
-|                   | |       |       |       |                           |
-|                  ++-+-------v-------+-------++                          |
-|                  |         CICAM             |                          |
-|                  |                           |                          |
-|                  +---------------------------+                          |
-+-------------------------------------------------------------------------+
-
-Software description
-====================
-The TSC Linux kernel driver manages the TSC core. It is a standard Linux
-platform device driver. It can be configured as a loadable or built-in kernel
-module. The driver is supported only in platforms that contain the TSC HW.
-
-The TSC driver uses ION driver to control the IOMMU and map user-allocated
-buffers to the TSC IOMMU domain.
-
-The driver provides an abstraction of the TSC HW functionality for user-space
-clients via two separate interfaces: tsc_mux and tsc_ci. These interfaces may
-be used by upper layers to utilize the TSC HW for routing the TS and supporting
-the Common Interface specification.
-
-Driver initialization
----------------------
-The driver's probe function is invoked if there is a matching device tree node.
-The probe function gets the required memory resources (i.e., register address
-spaces) and maps them to kernel space for the driver's use.
-The probe function also requests the required IRQs, GPIOs and clocks, and gets
-the TSC IOMMU domain. The probe function also disables the TSIFs input.
-Finally, the function creates two character device drivers: "tsc_mux","tsc_ci".
-
-See API description in interface section.
-
-Data paths
------------
-The TSC does not process the TS data received from the TSIFs. It just manages
-the routing of that data.
-
-Control paths - Mux function
-----------------------------
-Example for routing the TS from external demod TSIF 0 to the CAM, and from the
-CAM to TSIF 1 of the TSPP:
-
-struct tsc_route tsif_cam = {TSC_SOURCE_EXTERNAL0, TSC_DEST_CICAM};
-struct tsc_route cam_tspp = {TSC_SOURCE_CICAM, TSC_DEST_TSPP1};
-int mux_fd, ret;
-enum tsc_source tsif0 = TSC_SOURCE_EXTERNAL0;
-enum tsc_source cam = TSC_SOURCE_CICAM;
-
-/* opening Mux char device */
-mux_fd = open("/dev/tsc_mux0");
-
-/* Configure the CAM mux to route TS from external demod TSIF 0: */
-ret = ioctl(mux_fd, TSC_CONFIG_ROUTE, &tsif_cam);
-
-/* Configure the TSPP TSIF 1 mux to route TS from CAM: */
-ret = ioctl(mux_fd, TSC_CONFIG_ROUTE, &cam_tspp);
-
-/* Enabling the external demod TSIF 0, and the CAM TSIF-in and TSIF-out */
-ret = ioctl(mux_fd, TSC_ENABLE_INPUT, &tsif0);
-ret = ioctl(mux_fd, TSC_ENABLE_INPUT, &cam);
-
-close(mux_fd);
-
-Control paths - CI function
----------------------------
-Example for writing a buffer to the CAM command area:
-
-Assumptions:
-1. The user allocated a buffer using ION driver and wrote to that buffer.
-Also, retrieved the ion fd of that buffer and saved it to:
-int buffer_fd;
-2. The user already performed buffer size negotiation with the CAM according to
-CI/+ specification, and had set the CAM size register with the buffer size. This
-size is saved to: int size;
-3. The user decided about the time the user wants to wait for the data
-transmission.
-struct tsc_buffer_mode buff_params = {buffer_fd, size, timeout};
-int ret;
-
-/* Perform a blocking write buffer transaction for at most timeout */
-ret = ioctl(fd, TSC_WRITE_CAM_BUFFER, &buff_params);
-/* ret indicate whether the transaction succeeded */
-
-Example for SW reset to the CAM (according to CI/+ specification):
-struct single_byte_mode cmd_params = {1, RS bit set, timeout};
-struct single_byte_mode stat_params = {1, not initialize, timeout};
-int ci_fd, ret;
-u8 data;
-
-/* opening CI char device */
-ci_fd = open("/dev/tsc_ci0");
-
-/* Setting the RS bit of the CAM command register */
-ret = ioctl(ci_fd, TSC_WRITE_CAM_IO, &cmd_params);
-
-/* Polling the FR bit of the CAM status register */
-ret = ioctl(ci_fd, TSC_READ_CAM_IO, &stat_params);
-data = stat_params.data;
-while (data & FR_BIT_MASK) {
-	ret = ioctl(ci_fd, TSC_READ_CAM_IO, &stat_params);
-	data = stat_params.data;
-}
-
-close(ci_fd);
-
-Design
-======
-The TSC driver is a regular Linux platform driver designed to support the
-TSC HW available on specific SoCs.
-
-The driver provides two user-space APIs: tsc_mux that allows the client full
-control over the configuration of the TS routing, and tsc_ci that enables the
-client to implement the Common Interface in front of the CAM. It does so while
-encapsulating HW implementation details that are not relevant to the clients.
-
-The driver enforces HW restrictions and checks for input parameters
-validity, providing a success or failure return value for each API function:
-0 upon success or negative value on failure. Errno parameter is set to indicate
-the failure reason.
-However, the driver does not enforce any high-level policy with regard to the
-correct use of the TSC HW for various use-cases.
-
-Power Management
-================
-The TSC driver prevents the CPU from sleeping while the HW is active by using
-wakeup_source API. When there are no open devices the driver releases the wakeup
-source. In a similar manner, the driver enables the HW clocks only when needed.
-
-SMP/multi-core
-==============
-The driver uses a spinlock to protect accesses to its internal databases,
-for synchronization between user control API and kernel interrupt handlers.
-
-The driver uses a mutex for all the Mux operations to synchronize access to the
-routing internal databases. The driver uses another mutex for all the CI
-operations to synchronize data sent and received to and from the CAM.
-
-Security
-========
-Although the TSC is the bridge the external conditional access module, it has no
-security aspects. Any protection which is needed is performed by the upper
-layers. For example, the messages which are written to the CAM are encrypted.
-Thus the TSC accesses only non-protected, HLOS accessible memory regions.
-
-Performance
-===========
-Control operations are not considered as performance critical.
-Most of the control operations are assumed to be fairly uncommon.
-
-Interface
-=========
-Kernel-space API
-----------------
-The TSC driver does not provide any kernel-space API, only a user-space API.
-
-User-space API
-----------------
-Open: upper layer can open tsc_mux device and/or tsc_ci device.
-Release: close the device and release all the allocated resources.
-Poll: two different functions- one for Mux, one for CI. The Mux poll wait for
-rate mismatch interrupt. The CI poll waits for card detection HW interrupt.
-The rate mismatch interrupt is not cleared in the interrupt handler because it
-will signal again all the time. Therefore it is cleared via a specific ioctl
-that upper layer can use after the problem is solved. Additionally, the
-interrupt is cleared when the card is removed.
-ioctl: two functions, one for mux and one for ci. The ioctl are specified below.
-
-TSC Mux - routing the TS:
--------------------------
-enum tsc_source {
-	TSC_SOURCE_EXTERNAL0,
-	TSC_SOURCE_EXTERNAL1,
-	TSC_SOURCE_INTERNAL,
-	TSC_SOURCE_CICAM
-};
-enum tsc_dest {
-	TSC_DEST_TSPP0,
-	TSC_DEST_TSPP1,
-	TSC_DSET_CICAM
-};
-
-struct tsc_route {
-	enum tsc_source source;
-	enum tsc_dest dest;
-};
-
-#define TSC_CONFIG_ROUTE _IOW(TSC_IOCTL_BASE, 0, struct tsc_tspp_route)
-#define TSC_ENABLE_INPUT _IOW(TSC_IOCTL_BASE, 1, enum tsc_source)
-#define TSC_DISABLE_INPUT _IOW(TSC_IOCTL_BASE, 2, enum tsc_source)
-
-These 3 IOCTLs control the 3 muxes that route the TS, and enable/disable the
-TSIFs input.
-
-TSC Mux - configuring the TSIFs:
---------------------------------
-enum tsc_data_type {
-	TSC_DATA_TYPE_SERIAL,
-	TSC_DATA_TYPE_PARALLEL
-};
-enum tsc_receive_mode {
-	TSC_RECEIVE_MODE_START_VALID,
-	TSC_RECEIVE_MODE_START_ONLY,
-	TSC_RECEIVE_MODE_VALID_ONLY
-};
-
-struct tsc_tsif_params {
-	enum tsc_source source;
-	enum tsc_receive_mode receive_mode;
-	enum tsc_data_type data_type;
-	int clock_polarity;
-	int data_polarity;
-	int start_polarity;
-	int valid_polarity;
-	int error_polarity;
-	int data_swap;
-	int set_error;
-};
-
-#define TSC_SET_TSIF_CONFIG _IOW(TSC_IOCTL_BASE, 3, struct tsc_tsif_params)
-
-This IOCTL enables configuring a specific TSIF with all possible configurations.
-
-TSC Mux - clearing rate mismatch interrupt
-------------------------------------------
-
-#define TSC_CLEAR_RATE_MISMATCH_IRQ _IO(TSC_IOCTL_BASE, 4)
-
-This IOCTL is used for clearing the interrupt, which is not done automatically
-by the driver.
-
-TSC CI - CAM configuration:
----------------------------
-enum tsc_cam_personality {
-	TSC_CICAM_PERSONALITY_CI,
-	TSC_CICAM_PERSONALITY_CIPLUS,
-	TSC_CICAM_PERSONALITY_PCCARD,
-	TSC_CICAM_PERSONALITY_DISABLE
-};
-enum tsc_card_status {
-	TSC_CARD_STATUS_NOT_DETECTED,
-	TSC_CARD_STATUS_DETECTED,
-	TSC_CARD_STATUS_FAILURE
-};
-
-#define TSC_CICAM_SET_CLOCK _IOW(TSC_IOCTL_BASE, 5, int)
-This IOCTL sets the clock rate of the TS from the TSC to the CAM
-
-#define TSC_CAM_RESET _IO(TSC_IOCTL_BASE, 6)
-This IOCTL performs HW reset to the CAM
-
-#define TSC_CICAM_PERSONALITY_CHANGE 		\
-	_IOW(TSC_IOCTL_BASE, 7, enum tsc_cam_personality)
-This IOCTL configures the PCMCIA pins according to the specified card type.
-
-#define TSC_GET_CARD_STATUS _IOR(TSC_IOCTL_BASE, 8, enum tsc_card_status)
-This IOCTL queries the card detection pins and returns their status.
-
-TSC CI - Data transactions:
----------------------------
-struct tsc_single_byte_mode {
-	u16 address;
-	u8 data;
-	int timeout; /* in msec */
-};
-struct tsc_buffer_mode {
-	int buffer_fd;
-	u16 buffer_size;
-	int timeout; /* in msec */
-};
-
-#define TSC_READ_CAM_MEMORY			\
-	_IOWR(TSC_IOCTL_BASE, 9, struct tsc_single_byte_mode)
-#define TSC_WRITE_CAM_MEMORY		\
-	_IOW(TSC_IOCTL_BASE, 10, struct tsc_single_byte_mode)
-#define TSC_READ_CAM_IO				\
-	_IOWR(TSC_IOCTL_BASE, 11, struct tsc_single_byte_mode)
-#define TSC_WRITE_CAM_IO			\
-	_IOW(TSC_IOCTL_BASE, 12, struct tsc_single_byte_mode)
-#define TSC_READ_CAM_BUFFER			\
-	_IOWR(TSC_IOCTL_BASE, 13, struct tsc_buffer_mode)
-#define TSC_WRITE_CAM_BUFFER		\
-	_IOW(TSC_IOCTL_BASE, 14, struct tsc_buffer_mode)
-
-These IOCTLs performs a read/write data transaction of the requested type.
-
-Driver parameters
-=================
-The TSC module receives one parameter:
-tsc_iommu_bypass -  0 for using the VBIF, 1 for not using it. Not using the VBIF
-is a debug configuration.
-
-Config options
-==============
-To enable the driver, set CONFIG_TSC to y (built-in) or m (kernel module)
-in the kernel configuration menu.
-
-Dependencies
-============
-The TSC driver uses the ION driver for IOMMU registration and buffer
-mapping to BCSS VBIF.
-
-User space utilities
-====================
-None.
-
-Other
-=====
-None.
-
-Known issues
-============
-None.
-
-To do
-=====
-None.
diff --git a/Documentation/arm/msm/tspp2.txt b/Documentation/arm/msm/tspp2.txt
deleted file mode 100644
index 006c688..0000000
--- a/Documentation/arm/msm/tspp2.txt
+++ /dev/null
@@ -1,497 +0,0 @@
-Introduction
-============
-
-TSPP2 Driver
-
-The TSPP2 (Transport Stream Packet Processor v2) is a hardware accelerator
-designed to process MPEG-2 Transport Stream (TS) data. It can be used to
-process broadcast TV services. The TSPP2 HW processes the TS packets, offloads
-the host CPU and supports the real-time processing requirements of such
-services.
-
-TS data can be received either from TSIF (Transport Stream Interface) input
-or from memory input, to support playing live broadcasts as well as
-playback from memory. Recording is also supported.
-
-TSPP2 is a significantly different HW unit than the TSPP unit described in
-Documentation/arm/msm/tspp.txt. The functionality is enhanced and the HW
-design is different.
-
-Hardware description
-====================
-The TSPP2 HW contains the TSPP2 core, a BAM (Bus Access Manager, used for DMA
-operations) unit, and a VBIF unit (IOMMU).
-
-The TSPP2 HW supports:
-a. Up to two TSIF inputs and up to eight memory inputs.
-b. Various TS packet sizes (188/192 bytes) and formats (timestamp location).
-c. PID filtering.
-d. Raw transmit operation for section filtering or recording.
-e. Full PES and separated PES transmit operation for audio and video playback.
-f. Decryption and re-encryption operations for secure transport streams.
-g. PCR extraction.
-h. Indexing - identifying patterns in video streams.
-
-The following diagram provides an overview of the TSPP2 HW:
-+------------------------------------------------------------------+
-|                                                                  |
-| +-------------+   +--------------------+                         |
-| |  TSIF 0     +--->      TSPP2 Core    |                         |
-| +-------------+   |                    |                         |
-|                   |  +---------------+ |                         |
-| +-------------+   |  |               | |                         |
-| |  TSIF 1     +--->  |   Source 0    | |                         |
-| +-------------+   |  |               | |                         |
-|                   |  |               | |                         |
-|                   |  |               | |                         |
-|                   |  | +------------+| |       +--------------+  |
-|                   |  | | Filter 0   +|--------->  BAM pipe 3  |  |
-|                   |  | +------------+| |       +--------------+  |
-|                   |  | +------------+| |       +--------------+  |
-| +-------------+   |  | | Filter 1   +|--------->  BAM pipe 4  |  |
-| |  BAM pipe 0 +--->  | +------------+| |       +--------------+  |
-| +-------------+   |  |               | |              |          |
-| +-------------+   |  +---------------+ |    +--------------+     |
-| |  BAM pipe 1 +--->--------------------|----|              |     |
-| +-------------+   |                    |    |   VBIF       |     |
-| +-------------+   |                    |    |   IOMMU      |     |
-| |  BAM pipe 2 +--->--------------------|----|              |     |
-| +-------------+   +--------------------+    +--------------+     |
-+------------------------------------------------------------------+
-
-A source is configured to have either a TSIF input (TSIF 0 or 1) or a
-memory input (a BAM pipe). One or more filters are attached to the source.
-Each filter has a 13-bit PID and mask values to perform the PID filtering.
-Additionally, one or more operations are added to each filter to achieve the
-required functionality. Each operation has specific parameters. The operation's
-output is usually placed in an output pipe.
-
-The TSPP HW uses its own virtual address space, mapping memory buffer addresses
-using the VBIF IOMMU.
-
-Software description
-====================
-The TSPP2 Linux kernel driver manages the TSPP2 core. The TSPP2 driver utilizes
-the SPS driver to configure and manage the BAM unit, which is used to perform
-DMA operations and move TS data to/from system memory.
-
-The TSPP2 driver uses the ION driver to control the IOMMU and map user-allocated
-buffers to the TSPP2 IOMMU domain.
-
-The TSPP2 is a standard Linux platform device driver. It can be configured as a
-loadable or built-in kernel module. The driver is supported only in platforms
-that contain the TSPP2 HW.
-
-The driver provides an abstraction of the TSPP2 HW functionality for
-kernel-space clients. For example, the dvb/demux kernel driver, which provides
-an API for upper layers to perform TS de-multiplexing (including PID filtering,
-recording, indexing etc.), uses the TSPP2 driver to utilize the TSPP2 HW and
-offload the CPU, instead of doing all the required processing in SW.
-
-For further information please refer to Documentation/dvb/qcom-mpq.txt.
-
-Terminology
------------
-This section describes some of the software "objects" implemented by the driver.
-
-a. TSPP2 device: an instance of the TSPP2 device representing the TSPP2 HW and
-its capabilities. The client identifies a device instance according to a
-device ID.
-
-b. Indexing table: A TSPP2 device contains 4 indexing tables. These tables are
-used to identify patterns in the video stream and report on them.
-The client identifies an indexing table according to a table ID.
-
-c. Pipe: a BAM pipe used for DMA operations. The TSPP2 HW has a BAM unit with
-31 pipes. A pipe contains a memory buffer and a corresponding descriptor ring,
-and is used as the output for TSPP2 data (e.g. PES payload, PES headers,
-indexing information etc.). For memory inputs, a pipe is used as the input
-buffer where data can be written to for TSPP2 processing. BAM Pipes are
-managed by the TSPP2 driver using the SPS driver which controls BAM HW. The
-client is responsible for buffer memory allocation, and can control many
-BAM-related pipe parameters.
-
-d. Source: a source object represents data "stream" from the TS input,
-through the filters and operations that perform the processing on the TS data,
-until the output. A source has the following properties:
-	- Either a TSIF or a memory input.
-	- For memory input: an input pipe.
-	- Source-related configuration (e.g., packet size and format).
-	- One or more PID filters. Each filter contains operations.
-	- One or more output pipes.
-The client is responsible to configure the source object as needed using the
-appropriate API. The client identifies a source using a source handle, which
-the driver provides when opening a source for use.
-
-e. Filter: a filter object represents a PID filter which is used to get only the
-TS packets with specific PIDs and filter out all other TS packets in the stream.
-The client adds filters to the source object to define the processing of data.
-Each filter has a 13-bit PID value and bit-mask, so a filter can be used to
-get TS packets with various PID values. Note, however, that it is highly
-recommended to use each filter with a unique PID (i.e., 0x1FFF mask), and it is
-mandatory that the PIDs handled by each source's filters are mutually exclusive
-(i.e., the client must not configure two filters in the same source that handle
-the same PID values). A filter has up to 16 operations that instruct the TSPP2
-HW how to process the data. The client identifies a filter using a filter
-handle, which the driver provides when opening a filter for use.
-
-f. Operation: an operation object represents a basic building block describing
-how data is processed. Operations are added to a filter and are performed on
-the data received by this filter, in the order they were added. One or more
-operations may be required to achieve the desired functionality. For example,
-a "section filtering" functionality requires a raw transmit operation, while a
-"recording" functionality requires a raw transmit operations as well as an
-indexing operation (to support trick modes).
-
-Driver initialization
----------------------
-The driver's probe function is invoked if there is a matching device tree node
-(or platform device). The probe function gets the required memory resources
-(i.e., register address spaces) and maps them to kernel space for the
-driver's use. The probe function also request the required IRQs and gets the
-TSPP2 IOMMU domain. Finally, the probe function resets all HW registers to
-appropriate default values, and resets all the required software structures.
-
-See API description in Interface section.
-
-Usage examples
---------------
-
-Section filtering example - opening a Raw filter with data from TSIF0:
-----------------------------------------------------------------------
-u32 dev_id = 0;
-u32 src_handle;
-u32 pipe_handle;
-u32 filter_handle;
-u32 iova;
-u32 vaddress;
-struct tspp2_config cfg = {...};
-struct tspp2_pipe_config_params pipe_config;
-struct tspp2_pipe_pull_mode_params pull_params = {0, 0};
-struct tspp2_operation raw_op;
-struct sps_event_notify event;
-struct sps_iovec desc;
-
-/* Open TSPP2 device for use */
-tspp2_device_open(dev_id);
-
-/* Set global configuration */
-tspp2_config_set(dev_id, &cfg);
-
-/* Open source with TSIF0 input */
-tspp2_src_open(dev_id, TSPP2_INPUT_TSIF0, &src_handle);
-
-/* Set parsing options if needed, for example: */
-tspp2_src_parsing_option_set(src_handle,
-				TSPP2_SRC_PARSING_OPT_CHECK_CONTINUITY, 1);
-
-/* Assume normal sync byte, assume no need for scrambling configuration */
-
-/* Set packet size and format: */
-tspp2_src_packet_format_set(src_handle, TSPP2_PACKET_FORMAT_188_RAW);
-
-/* Since this is TSIF input, flow control is in push mode */
-
-/* Allocate memory for output pipe via ION – not shown here */
-
-/* Open an output pipe for use */
-pipe_config.ion_client = ...
-pipe_config.buffer_handle = ...
-pipe_config.buffer_size = ...
-pipe_config.pipe_mode = TSPP2_SRC_PIPE_OUTPUT;
-pipe_config.sps_cfg.descriptor_size = 188;
-pipe_config.sps_cfg.setting = (SPS_O_AUTO_ENABLE | SPS_O_HYBRID |
-				SPS_O_OUT_OF_DESC | SPS_O_ACK_TRANSFERS);
-pipe_config.sps_cfg.wakeup_events = SPS_O_OUT_OF_DESC;
-pipe_config.sps_cfg.callback = ...
-pipe_config.sps_cfg.user_info = ...
-tspp2_pipe_open(dev_id, &pipe_config, &iova, &pipe_handle);
-
-/* Attache the pipe to the source */
-tspp2_src_pipe_attach(src_handle, pipe_handle, &pull_params);
-/* Open a filter for PID 13 */
-tspp2_filter_open(src_handle, 13, 0x1FFF, &filter_handle);
-
-/* Add a raw transmit operation */
-raw_op.type = TSPP2_OP_RAW_TRANSMIT;
-raw_op.params.raw_transmit.input = TSPP2_OP_BUFFER_A;
-raw_op.params.raw_transmit.timestamp_mode = TSPP2_OP_TIMESTAMP_NONE;
-raw_op.params.raw_transmit.skip_ts_packets_with_errors = 0;
-raw_op.params.raw_transmit.output_pipe_handle = pipe_handle;
-tspp2_filter_operations_add(filter_handle, &raw_op, 1);
-
-/* Enable filter and source to start getting data */
-tspp2_filter_enable(filter_handle);
-tspp2_source_enable(src_handle);
-
-/*
- * Data path: poll pipe (or get notifications from pipe via
- * registered callback).
- */
-tspp2_pipe_last_address_used_get(pipe_handle, &vaddress);
-
-/* Process data... */
-
-/* Get and release descriptors: */
-tspp2_pipe_descriptor_get(pipe_handle, &desc);
-tspp2_pipe_descriptor_put(pipe_handle, desc.addr, desc.size, ...);
-
-/* Teardown: */
-tspp2_src_disable(src_handle);
-tspp2_filter_disable(filter_handle);
-tspp2_filter_close(filter_handle);
-tspp2_src_pipe_detach(src_handle, pipe_handle);
-tspp2_pipe_close(pipe_handle);
-tspp2_src_close(src_handle);
-tspp2_device_close(dev_id);
-
-Debug facilities
-----------------
-The TSPP2 driver supports several debug facilities via debugfs:
-a. Ability to read the status of TSIF and TSPP2 HW registers via debugfs.
-b. Ability to print HW statistics, error and performance counters via debugfs.
-c. Ability to print SW status via debugfs.
-
-Design
-======
-The TSPP2 driver is a regular Linux platform driver designed to support the
-TSPP2 HW available on specific Qualcomm SoCs.
-
-The driver provides an extensive kernel-space API to allow the client full
-control over the configuration of the TSPP2 HW, while encapsulating HW
-implementation details that are not relevant to the client.
-
-The driver enforces HW restrictions and checks for input parameters
-validity, providing a success or failure return value for each API function.
-However, the driver does not enforce any high-level policy with regard to the
-correct use of the TSPP2 HW for various use-cases.
-
-Power Management
-================
-The TSPP2 driver prevents the CPU from sleeping while the HW is active by
-using the wakeup_source API. When the HW is not active (i.e., no sources
-configured), the driver indicates it is ready for system suspend by invoking
-__pm_relax(). When the HW needs to be active (i.e., a source has been opened and
-enabled), the driver invokes __pm_stay_awake().
-
-In a similar manner, the driver enables the HW clocks only when needed.
-The TSPP2 HW manages power saving automatically when the HW is not used.
-No SW involvement is required.
-
-SMP/multi-core
-==============
-The driver uses a mutex for mutual exclusion between kernel API calls.
-A spinlock is used to protect accesses to its internal databases which can be
-performed both from interrupt handler context and from API context.
-
-Security
-========
-None.
-
-Performance
-===========
-Control operations are not considered as performance critical.
-Most of the control operations are assumed to be fairly uncommon.
-Data-path operations involve only getting descriptors from the pipe and
-releasing them back to the pipe for reuse.
-
-Interface
-=========
-Kernel-space API
-----------------
-
-Control path API
--------------------
-
-TSPP2 device open / close API:
-------------------------------
-int tspp2_device_open(u32 dev_id);
-
-int tspp2_device_close(u32 dev_id);
-
-Global configuration for the TSPP2 device:
-------------------------------------------
-int tspp2_config_set(u32 dev_id, const struct tspp2_config *cfg);
-	Set device global configuration.
-
-int tspp2_config_get(u32 dev_id, struct tspp2_config *cfg);
-	Get current device global configuration.
-
-Configure Indexing Tables:
---------------------------
-int tspp2_indexing_prefix_set(u32 dev_id, u8 table_id, u32 value, u32 mask);
-	Set prefix value and mask of an indexing table.
-
-int tspp2_indexing_patterns_add(u32 dev_id, u8 table_id, const u32 *values,
-				const u32 *masks, u8 patterns_num);
-	Add patterns to an indexing table.
-
-int tspp2_indexing_patterns_clear(u32 dev_id, u8 table_id);
-	Clear all patterns of an indexing table
-
-Opening and closing Pipes:
---------------------------
-int tspp2_pipe_open(u32 dev_id, const struct tspp2_pipe_config_params *cfg,
-			u32 *iova, u32 *pipe_handle);
-	Open a pipe for use.
-
-int tspp2_pipe_close(u32 pipe_handle);
-	Close an opened pipe.
-
-Source configuration:
----------------------
-int tspp2_src_open(u32 dev_id, enum tspp2_src_input input, u32 *src_handle);
-	Open a new source for use.
-
-int tspp2_src_close(u32 src_handle);
-	Close an opened source.
-
-int tspp2_src_parsing_option_set(u32 src_handle,
-			enum tspp2_src_parsing_option option, int value);
-	Set source parsing configuration option.
-
-int tspp2_src_parsing_option_get(u32 src_handle,
-			enum tspp2_src_parsing_option option, int *value);
-	Get source parsing configuration option.
-
-int tspp2_src_sync_byte_config_set(u32 src_handle, int check_sync_byte,
-			u8 sync_byte_value);
-	Set source sync byte configuration.
-
-int tspp2_src_sync_byte_config_get(u32 src_handle, int *check_sync_byte,
-			u8 *sync_byte_value);
-	Get source sync byte configuration.
-
-int tspp2_src_scrambling_config_set(u32 src_handle,
-			const struct tspp2_src_scrambling_config *cfg);
-	Set source scrambling configuration.
-
-int tspp2_src_scrambling_config_get(u32 src_handle,
-			struct tspp2_src_scrambling_config *cfg);
-	Get source scrambling configuration.
-
-int tspp2_src_packet_format_set(u32 src_handle,
-			enum tspp2_packet_format format);
-	Set source packet size and format.
-
-int tspp2_src_pipe_attach(u32 src_handle, u32 pipe_handle,
-			const struct tspp2_pipe_pull_mode_params *cfg);
-	Attach a pipe to a source.
-
-int tspp2_src_pipe_detach(u32 src_handle, u32 pipe_handle);
-	Detach a pipe from a source.
-
-int tspp2_src_enable(u32 src_handle);
-	Enable source (start using it).
-
-int tspp2_src_disable(u32 src_handle);
-	Disable source (stop using it).
-
-int tspp2_src_filters_clear(u32 src_handle);
-	Clear all filters from a source.
-
-Filter and Operation configuration:
------------------------------------
-int tspp2_filter_open(u32 src_handle, u16 pid, u16 mask, u32 *filter_handle);
-	Open a new filter and add it to a source.
-
-int tspp2_filter_close(u32 filter_handle);
-	Close a filter.
-
-int tspp2_filter_enable(u32 filter_handle);
-	Enable a filter.
-
-int tspp2_filter_disable(u32 filter_handle);
-	Disable a filter.
-
-int tspp2_filter_operations_set(u32 filter_handle,
-			const struct tspp2_operation *ops, u8 operations_num);
-	Set (add or update) operations to a filter.
-
-int tspp2_filter_operations_clear(u32 filter_handle);
-	Clear all operations from a filter.
-
-int tspp2_filter_current_scrambling_bits_get(u32 filter_handle,
-			u8 *scrambling_bits_value);
-	Get the current scrambling bits.
-
-Events notifications registration:
-----------------------------------
-int tspp2_global_event_notification_register(u32 dev_id,
-			u32 global_event_bitmask,
-			void (*callback)(void *cookie),
-			void *cookie);
-	Get notified on a global event.
-
-int tspp2_src_event_notification_register(u32 src_handle,
-			u32 src_event_bitmask,
-			void (*callback)(void *cookie),
-			void *cookie);
-	Get notified on a source event.
-
-int tspp2_filter_event_notification_register(u32 filter_handle,
-			u32 filter_event_bitmask,
-			void (*callback)(void *cookie),
-			void *cookie);
-	Get notified on a filter event.
-
-Data path API
-----------------
-int tspp2_pipe_descriptor_get(u32 pipe_handle, struct sps_iovec *desc);
-	Get a data descriptor from a pipe.
-
-int tspp2_pipe_descriptor_put(u32 pipe_handle, u32 addr,
-				u32 size, u32 flags);
-	Put (release) a descriptor for reuse by the pipe.
-
-int tspp2_pipe_last_address_used_get(u32 pipe_handle, u32 *address);
-	Get the last address the TSPP2 used.
-
-int tspp2_data_write(u32 src_handle, u32 offset, u32 size);
-	Write (feed) data to a source.
-
-User-space API
---------------
-The TSPP2 driver does not provide any user-space API, only a kernel-space API.
-The dvb/demux driver, which utilizes the TSPP2 driver (and HW), provides an
-extensive user-space API, allowing upper layers to achieve complex demuxing
-functionality.
-
-For further information please refer to Documentation/dvb/qcom-mpq.txt.
-
-Driver parameters
-=================
-The TSPP2 driver supports the following module parameter:
-tspp2_iommu_bypass: Bypass VBIF/IOMMU and use physical buffer addresses
-instead. This is mostly useful for debug purposes if something is wrong with
-the IOMMU configuration. Default is false.
-
-Platform-dependent parameters (e.g., IRQ numbers) are provided to the driver
-via the device tree mechanism or the platform device data mechanism.
-
-Config options
-==============
-To enable the driver, set CONFIG_TSPP2 to y (built-in) or m (kernel module)
-in the kernel configuration menu.
-
-Dependencies
-============
-a. The TSPP2 driver uses the SPS driver to control the BAM unit.
-b. The TSPP2 driver uses the ION driver for IOMMU registration and buffer
-mapping. The client is responsible to allocate memory buffers via ION.
-
-User space utilities
-====================
-None.
-
-Other
-=====
-None.
-
-Known issues
-============
-None.
-
-To do
-=====
-None.
diff --git a/Documentation/devicetree/bindings/fb/mdss-dsi-ctrl.txt b/Documentation/devicetree/bindings/fb/mdss-dsi-ctrl.txt
index be70c75..d163edb 100644
--- a/Documentation/devicetree/bindings/fb/mdss-dsi-ctrl.txt
+++ b/Documentation/devicetree/bindings/fb/mdss-dsi-ctrl.txt
@@ -43,6 +43,7 @@
 					-- qcom,supply-max-voltage: maximum voltage level (uV)
 					-- qcom,supply-enable-load: load drawn (uA) from enabled supply
 					-- qcom,supply-disable-load: load drawn (uA) from disabled supply
+					-- qcom,supply-ulp-load: load drawn (uA) from supply in ultra-low power mode
 					-- qcom,supply-pre-on-sleep: time to sleep (ms) before turning on
 					-- qcom,supply-post-on-sleep: time to sleep (ms) after turning on
 					-- qcom,supply-pre-off-sleep: time to sleep (ms) before turning off
@@ -159,6 +160,7 @@
 				qcom,supply-max-voltage = <2800000>;
 				qcom,supply-enable-load = <100000>;
 				qcom,supply-disable-load = <100>;
+				qcom,supply-ulp-load = <100>;
 				qcom,supply-pre-on-sleep = <0>;
 				qcom,supply-post-on-sleep = <0>;
 				qcom,supply-pre-off-sleep = <0>;
@@ -172,6 +174,7 @@
 				qcom,supply-max-voltage = <1800000>;
 				qcom,supply-enable-load = <100000>;
 				qcom,supply-disable-load = <100>;
+				qcom,supply-ulp-load = <100>;
 				qcom,supply-pre-on-sleep = <0>;
 				qcom,supply-post-on-sleep = <0>;
 				qcom,supply-pre-off-sleep = <0>;
diff --git a/Documentation/devicetree/bindings/qseecom/qseecom.txt b/Documentation/devicetree/bindings/qseecom/qseecom.txt
index 83a77e3..2c584e8 100644
--- a/Documentation/devicetree/bindings/qseecom/qseecom.txt
+++ b/Documentation/devicetree/bindings/qseecom/qseecom.txt
@@ -16,7 +16,8 @@
   - qcom,support-bus-scaling : indicates if driver support scaling the bus for crypto operation.
   - qcom,support-fde : indicates if driver support key managing for full disk encryption feature.
   - qcom,support-pfe : indicates if driver support key managing for per file encryption feature.
-  - qcom,no-clock-support; indicates clocks are not handled by qseecom (could be handled by RPM)
+  - qcom,no-clock-support : indicates clocks are not handled by qseecom (could be handled by RPM)
+  - qcom,appsbl-qseecom-support : indicates if there is qseecom support in appsbootloader
 
 Example:
 	qcom,qseecom@fe806000 {
@@ -34,6 +35,7 @@
 		qcom,msm_bus,active_only = <0>;
 		qcom,msm_bus,num_paths = <1>;
 		qcom,no-clock-support;
+		qcom,appsbl-qseecom-support;
 		qcom,msm_bus,vectors =
 			<55 512 0 0>,
 			<55 512 3936000000 393600000>,
diff --git a/Documentation/devicetree/bindings/regulator/rpm-smd-regulator.txt b/Documentation/devicetree/bindings/regulator/rpm-smd-regulator.txt
index e9ddf67..c2c246d 100644
--- a/Documentation/devicetree/bindings/regulator/rpm-smd-regulator.txt
+++ b/Documentation/devicetree/bindings/regulator/rpm-smd-regulator.txt
@@ -88,6 +88,12 @@
 				current updates are only sent if the given
 				regulator has also been enabled by a Linux
 				consumer.
+- qcom,send-defaults:          Boolean flag which indicates that the initial
+				parameter values should be sent to the RPM
+				before consumers make their own requests.  If
+				this flag is not specified, then initial
+				parameters values will only be sent after some
+				consumer makes a request.
 
 The following properties specify initial values for parameters to be sent to the
 RPM in regulator requests.
diff --git a/arch/arm/boot/dts/qcom/Makefile b/arch/arm/boot/dts/qcom/Makefile
index 14417b2..deaf141 100644
--- a/arch/arm/boot/dts/qcom/Makefile
+++ b/arch/arm/boot/dts/qcom/Makefile
@@ -94,6 +94,7 @@
 	msm8926-v2-qrd-skug-pvt.dtb \
 	msm8926-v1-320p-w-mtp.dtb \
 	msm8926-v1-320p-w-g.dtb \
+	msm8926-v1-1080p-w-mtp.dtb \
 	msm8226-v1-qrd-skuf.dtb \
 	msm8226-v2-qrd-skuf.dtb \
 	apq8026-v1-xpm.dtb \
diff --git a/arch/arm/boot/dts/qcom/apq8026-v1-w-cdp.dts b/arch/arm/boot/dts/qcom/apq8026-v1-w-cdp.dts
index 8c0bf8e..6a79376 100644
--- a/arch/arm/boot/dts/qcom/apq8026-v1-w-cdp.dts
+++ b/arch/arm/boot/dts/qcom/apq8026-v1-w-cdp.dts
@@ -1,4 +1,4 @@
-/* Copyright (c) 2014, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2014-2015, The Linux Foundation. All rights reserved.
  *
  * This 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,3 +55,17 @@
 		status = "disabled";
 	};
 };
+
+&sdhc_2 {
+	status = "disabled";
+};
+
+&pm8226_l18 {
+	qcom,init-enable = <0>;
+	qcom,send-defaults;
+};
+
+&pm8226_l21 {
+	qcom,init-enable = <0>;
+	qcom,send-defaults;
+};
diff --git a/arch/arm/boot/dts/qcom/apq8026-v1-w-mtp.dts b/arch/arm/boot/dts/qcom/apq8026-v1-w-mtp.dts
index 97cbd22..a9ec2f4 100644
--- a/arch/arm/boot/dts/qcom/apq8026-v1-w-mtp.dts
+++ b/arch/arm/boot/dts/qcom/apq8026-v1-w-mtp.dts
@@ -1,4 +1,4 @@
-/* Copyright (c) 2014, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2014-2015, The Linux Foundation. All rights reserved.
  *
  * This 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,3 +48,17 @@
 &pm8x26_rtc {
 	qcom,qpnp-rtc-write = <1>;
 };
+
+&sdhc_2 {
+	status = "disabled";
+};
+
+&pm8226_l18 {
+	qcom,init-enable = <0>;
+	qcom,send-defaults;
+};
+
+&pm8226_l21 {
+	qcom,init-enable = <0>;
+	qcom,send-defaults;
+};
diff --git a/arch/arm/boot/dts/qcom/apq8026-v2-320p-w-cdp.dts b/arch/arm/boot/dts/qcom/apq8026-v2-320p-w-cdp.dts
index 8bf08e3..a063751 100644
--- a/arch/arm/boot/dts/qcom/apq8026-v2-320p-w-cdp.dts
+++ b/arch/arm/boot/dts/qcom/apq8026-v2-320p-w-cdp.dts
@@ -1,4 +1,4 @@
-/* Copyright (c) 2014, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2014-2015, The Linux Foundation. All rights reserved.
  *
  * This 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,3 +73,17 @@
 		status = "disabled";
 	};
 };
+
+&sdhc_2 {
+	status = "disabled";
+};
+
+&pm8226_l18 {
+	qcom,init-enable = <0>;
+	qcom,send-defaults;
+};
+
+&pm8226_l21 {
+	qcom,init-enable = <0>;
+	qcom,send-defaults;
+};
diff --git a/arch/arm/boot/dts/qcom/apq8026-v2-320p-w-g-mtp.dts b/arch/arm/boot/dts/qcom/apq8026-v2-320p-w-g-mtp.dts
index 86de278..87fdf1b 100644
--- a/arch/arm/boot/dts/qcom/apq8026-v2-320p-w-g-mtp.dts
+++ b/arch/arm/boot/dts/qcom/apq8026-v2-320p-w-g-mtp.dts
@@ -198,3 +198,17 @@
 	qcom,use-dynamic-ocv-setting;
 	qcom,ocv-rbatt-compensation;
 };
+
+&sdhc_2 {
+	status = "disabled";
+};
+
+&pm8226_l18 {
+	qcom,init-enable = <0>;
+	qcom,send-defaults;
+};
+
+&pm8226_l21 {
+	qcom,init-enable = <0>;
+	qcom,send-defaults;
+};
diff --git a/arch/arm/boot/dts/qcom/apq8026-v2-320p-w-mtp.dts b/arch/arm/boot/dts/qcom/apq8026-v2-320p-w-mtp.dts
index 58ea077..a08854e 100644
--- a/arch/arm/boot/dts/qcom/apq8026-v2-320p-w-mtp.dts
+++ b/arch/arm/boot/dts/qcom/apq8026-v2-320p-w-mtp.dts
@@ -1,4 +1,4 @@
-/* Copyright (c) 2014, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2014-2015, The Linux Foundation. All rights reserved.
  *
  * This 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,3 +59,17 @@
 &pm8x26_rtc {
 	qcom,qpnp-rtc-write = <1>;
 };
+
+&sdhc_2 {
+	status = "disabled";
+};
+
+&pm8226_l18 {
+	qcom,init-enable = <0>;
+	qcom,send-defaults;
+};
+
+&pm8226_l21 {
+	qcom,init-enable = <0>;
+	qcom,send-defaults;
+};
diff --git a/arch/arm/boot/dts/qcom/dsi-panel-auo-qvga-cmd.dtsi b/arch/arm/boot/dts/qcom/dsi-panel-auo-qvga-cmd.dtsi
index ada02b1..5e616c6 100644
--- a/arch/arm/boot/dts/qcom/dsi-panel-auo-qvga-cmd.dtsi
+++ b/arch/arm/boot/dts/qcom/dsi-panel-auo-qvga-cmd.dtsi
@@ -14,6 +14,7 @@
 	dsi_auo_qvga_cmd: qcom,mdss_dsi_auo_qvga_cmd {
 		qcom,mdss-dsi-panel-name = "AUO qvga command mode dsi panel";
 		qcom,mdss-dsi-panel-controller = <&mdss_dsi0>;
+		qcom,ulps-enabled;
 		qcom,mdss-dsi-panel-type = "dsi_cmd_mode";
 		qcom,mdss-dsi-panel-destination = "display_1";
 		qcom,mdss-dsi-panel-framerate = <60>;
diff --git a/arch/arm/boot/dts/qcom/dsi-panel-jdi-qvga-video.dtsi b/arch/arm/boot/dts/qcom/dsi-panel-jdi-qvga-video.dtsi
new file mode 100644
index 0000000..82146a7
--- /dev/null
+++ b/arch/arm/boot/dts/qcom/dsi-panel-jdi-qvga-video.dtsi
@@ -0,0 +1,72 @@
+/* Copyright (c) 2013-2015, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+/*---------------------------------------------------------------------------
+ * This file is autogenerated file using gcdb parser. Please do not edit it.
+ * Update input XML file to add a new entry or update variable in this file
+ * VERSION = "1.0"
+ *---------------------------------------------------------------------------*/
+&mdss_mdp {
+	dsi_jdi_qvga_vid: qcom,mdss_dsi_jdi_qvga_video {
+		qcom,mdss-dsi-panel-name = "jdi 1080p video mode dsi panel";
+		qcom,mdss-dsi-panel-controller = <&mdss_dsi0>;
+		qcom,mdss-dsi-panel-type = "dsi_video_mode";
+		qcom,mdss-dsi-panel-destination = "display_1";
+		qcom,mdss-dsi-panel-framerate = <60>;
+		qcom,mdss-dsi-virtual-channel-id = <0>;
+		qcom,mdss-dsi-stream = <0>;
+		qcom,mdss-dsi-panel-width = <320>;
+		qcom,mdss-dsi-panel-height = <240>;
+		qcom,mdss-dsi-h-front-porch = <96>;
+		qcom,mdss-dsi-h-back-porch = <64>;
+		qcom,mdss-dsi-h-pulse-width = <16>;
+		qcom,mdss-dsi-h-sync-skew = <0>;
+		qcom,mdss-dsi-v-back-porch = <16>;
+		qcom,mdss-dsi-v-front-porch = <4>;
+		qcom,mdss-dsi-v-pulse-width = <1>;
+		qcom,mdss-dsi-h-left-border = <0>;
+		qcom,mdss-dsi-h-right-border = <0>;
+		qcom,mdss-dsi-v-top-border = <0>;
+		qcom,mdss-dsi-v-bottom-border = <0>;
+		qcom,mdss-dsi-bpp = <24>;
+		qcom,mdss-dsi-underflow-color = <0xff>;
+		qcom,mdss-dsi-border-color = <0>;
+		qcom,mdss-dsi-on-command = [15 01 00 00 00 00 02 55 00
+			15 01 00 00 00 00 02 53 2C
+			15 01 00 00 00 00 02 35 00
+			05 01 00 00 78 00 02 29 00
+			05 01 00 00 78 00 02 11 00];
+		qcom,mdss-dsi-off-command = [05 01 00 00 02 00 02 28 00
+				 05 01 00 00 79 00 02 10 00];
+		qcom,mdss-dsi-on-command-state = "dsi_lp_mode";
+		qcom,mdss-dsi-off-command-state = "dsi_hs_mode";
+		qcom,mdss-dsi-h-sync-pulse = <0>;
+		qcom,mdss-dsi-traffic-mode = "burst_mode";
+		qcom,mdss-dsi-bllp-eof-power-mode;
+		qcom,mdss-dsi-bllp-power-mode;
+		qcom,mdss-dsi-lane-0-state;
+		qcom,mdss-dsi-lane-1-state;
+		qcom,mdss-dsi-lane-2-state;
+		qcom,mdss-dsi-lane-3-state;
+		qcom,mdss-dsi-panel-timings = [e7 36 24 00 66 6a 2a 3a 2d 03 04 00];
+		qcom,mdss-dsi-t-clk-post = <0x04>;
+		qcom,mdss-dsi-t-clk-pre = <0x1b>;
+		qcom,mdss-dsi-bl-min-level = <1>;
+		qcom,mdss-dsi-bl-max-level = <4095>;
+		qcom,mdss-dsi-dma-trigger = "trigger_sw";
+		qcom,mdss-dsi-mdp-trigger = "none";
+		qcom,mdss-dsi-bl-pmic-control-type = "bl_ctrl_wled";
+		qcom,mdss-dsi-reset-sequence = <1 10>, <0 10>, <1 10>;
+		qcom,mdss-pan-physical-width-dimension = <61>;
+		qcom,mdss-pan-physical-height-dimension = <110>;
+	};
+};
diff --git a/arch/arm/boot/dts/qcom/msm8226-mdss-panels.dtsi b/arch/arm/boot/dts/qcom/msm8226-mdss-panels.dtsi
index d8ca6dc..0bd5a68 100644
--- a/arch/arm/boot/dts/qcom/msm8226-mdss-panels.dtsi
+++ b/arch/arm/boot/dts/qcom/msm8226-mdss-panels.dtsi
@@ -19,3 +19,4 @@
 #include "dsi-panel-jdi-1080p-video.dtsi"
 #include "dsi-panel-nt35590-qvga-cmd.dtsi"
 #include "dsi-panel-auo-qvga-cmd.dtsi"
+#include "dsi-panel-jdi-qvga-video.dtsi"
diff --git a/arch/arm/boot/dts/qcom/msm8226-mdss.dtsi b/arch/arm/boot/dts/qcom/msm8226-mdss.dtsi
index dd298e3..5c1636f 100644
--- a/arch/arm/boot/dts/qcom/msm8226-mdss.dtsi
+++ b/arch/arm/boot/dts/qcom/msm8226-mdss.dtsi
@@ -167,6 +167,7 @@
 				qcom,supply-max-voltage = <1200000>;
 				qcom,supply-enable-load = <100000>;
 				qcom,supply-disable-load = <100>;
+				qcom,supply-ulp-load = <1000>;
 				qcom,supply-post-on-sleep = <20>;
 			};
 
@@ -177,6 +178,7 @@
 				qcom,supply-max-voltage = <1800000>;
 				qcom,supply-enable-load = <100000>;
 				qcom,supply-disable-load = <100>;
+				qcom,supply-ulp-load = <100>;
 			};
 		};
 
@@ -191,6 +193,7 @@
 				qcom,supply-max-voltage = <2800000>;
 				qcom,supply-enable-load = <100000>;
 				qcom,supply-disable-load = <100>;
+				qcom,supply-ulp-load = <100>;
 			};
 
 			qcom,panel-supply-entry@1 {
@@ -200,6 +203,7 @@
 				qcom,supply-max-voltage = <1800000>;
 				qcom,supply-enable-load = <100000>;
 				qcom,supply-disable-load = <100>;
+				qcom,supply-ulp-load = <100>;
 			};
 		};
 	};
diff --git a/arch/arm/boot/dts/qcom/msm8226-qseecom.dtsi b/arch/arm/boot/dts/qcom/msm8226-qseecom.dtsi
index 54990c6..84f87d8 100644
--- a/arch/arm/boot/dts/qcom/msm8226-qseecom.dtsi
+++ b/arch/arm/boot/dts/qcom/msm8226-qseecom.dtsi
@@ -24,6 +24,7 @@
 		qcom,msm-bus,num-paths = <1>;
 		qcom,support-bus-scaling;
 		qcom,support-fde;
+                qcom,appsbl-qseecom-support;
 		qcom,msm-bus,vectors-KBps =
 				<55 512 0 0>,
 				<55 512 0 0>,
diff --git a/arch/arm/boot/dts/qcom/msm8226-v1-w-cdp.dts b/arch/arm/boot/dts/qcom/msm8226-v1-w-cdp.dts
index 0dc53ee..2797c95 100644
--- a/arch/arm/boot/dts/qcom/msm8226-v1-w-cdp.dts
+++ b/arch/arm/boot/dts/qcom/msm8226-v1-w-cdp.dts
@@ -1,4 +1,4 @@
-/* Copyright (c) 2014, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2014-2015, The Linux Foundation. All rights reserved.
  *
  * This 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,3 +54,17 @@
 		status = "disabled";
 	};
 };
+
+&sdhc_2 {
+	status = "disabled";
+};
+
+&pm8226_l18 {
+	qcom,init-enable = <0>;
+	qcom,send-defaults;
+};
+
+&pm8226_l21 {
+	qcom,init-enable = <0>;
+	qcom,send-defaults;
+};
diff --git a/arch/arm/boot/dts/qcom/msm8226-v1-w-mtp.dts b/arch/arm/boot/dts/qcom/msm8226-v1-w-mtp.dts
index 01a0e92..323f9aa 100644
--- a/arch/arm/boot/dts/qcom/msm8226-v1-w-mtp.dts
+++ b/arch/arm/boot/dts/qcom/msm8226-v1-w-mtp.dts
@@ -1,4 +1,4 @@
-/* Copyright (c) 2014, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2014-2015, The Linux Foundation. All rights reserved.
  *
  * This 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,3 +47,17 @@
 &pm8x26_rtc {
 	qcom,qpnp-rtc-write = <1>;
 };
+
+&sdhc_2 {
+	status = "disabled";
+};
+
+&pm8226_l18 {
+	qcom,init-enable = <0>;
+	qcom,send-defaults;
+};
+
+&pm8226_l21 {
+	qcom,init-enable = <0>;
+	qcom,send-defaults;
+};
diff --git a/arch/arm/boot/dts/qcom/msm8226-v2-320p-w-cdp.dts b/arch/arm/boot/dts/qcom/msm8226-v2-320p-w-cdp.dts
index 67039de..f905f8e 100644
--- a/arch/arm/boot/dts/qcom/msm8226-v2-320p-w-cdp.dts
+++ b/arch/arm/boot/dts/qcom/msm8226-v2-320p-w-cdp.dts
@@ -1,4 +1,4 @@
-/* Copyright (c) 2014, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2014-2015, The Linux Foundation. All rights reserved.
  *
  * This 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,3 +63,17 @@
 		status = "disabled";
 	};
 };
+
+&sdhc_2 {
+	status = "disabled";
+};
+
+&pm8226_l18 {
+	qcom,init-enable = <0>;
+	qcom,send-defaults;
+};
+
+&pm8226_l21 {
+	qcom,init-enable = <0>;
+	qcom,send-defaults;
+};
diff --git a/arch/arm/boot/dts/qcom/msm8226-v2-320p-w-mtp.dts b/arch/arm/boot/dts/qcom/msm8226-v2-320p-w-mtp.dts
index 0182cae..a1086dd 100644
--- a/arch/arm/boot/dts/qcom/msm8226-v2-320p-w-mtp.dts
+++ b/arch/arm/boot/dts/qcom/msm8226-v2-320p-w-mtp.dts
@@ -1,4 +1,4 @@
-/* Copyright (c) 2014, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2014-2015, The Linux Foundation. All rights reserved.
  *
  * This 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,3 +49,17 @@
 &pm8x26_rtc {
 	qcom,qpnp-rtc-write = <1>;
 };
+
+&sdhc_2 {
+	status = "disabled";
+};
+
+&pm8226_l18 {
+	qcom,init-enable = <0>;
+	qcom,send-defaults;
+};
+
+&pm8226_l21 {
+	qcom,init-enable = <0>;
+	qcom,send-defaults;
+};
diff --git a/arch/arm/boot/dts/qcom/msm8226-w-qseecom.dtsi b/arch/arm/boot/dts/qcom/msm8226-w-qseecom.dtsi
index 39f755c..4ecd120 100644
--- a/arch/arm/boot/dts/qcom/msm8226-w-qseecom.dtsi
+++ b/arch/arm/boot/dts/qcom/msm8226-w-qseecom.dtsi
@@ -25,6 +25,7 @@
 		qcom,msm-bus,num-paths = <1>;
 		qcom,support-bus-scaling;
 		qcom,support-fde;
+		qcom,appsbl-qseecom-support;
 		qcom,msm-bus,vectors-KBps =
 				<55 512 0 0>,
 				<55 512 0 0>,
diff --git a/arch/arm/boot/dts/qcom/msm8926-v1-1080p-w-mtp.dts b/arch/arm/boot/dts/qcom/msm8926-v1-1080p-w-mtp.dts
new file mode 100644
index 0000000..d912604
--- /dev/null
+++ b/arch/arm/boot/dts/qcom/msm8926-v1-1080p-w-mtp.dts
@@ -0,0 +1,59 @@
+/* Copyright (c) 2015, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+
+/dts-v1/;
+#include "msm8926-v1.dtsi"
+#include "msm8926-w-memory.dtsi"
+#include "msm8226-w-qseecom.dtsi"
+#include "msm8926-w-sharedmem.dtsi"
+#include "msm8226-720p-mtp.dtsi"
+#include "msm8x26w-gpu.dtsi"
+
+/ {
+	model = "Qualcomm Technologies, Inc. MSM 8926W MTP";
+	compatible = "qcom,msm8926-mtp", "qcom,msm8926", "qcom,mtp";
+	qcom,board-id = <8 6>;
+};
+
+&mdss_fb0 {
+	/* cont_splash memory*/
+	qcom,memblock-reserve = <0x0149c000 0x64000>;
+};
+
+
+&mdss_mdp {
+	qcom,mdss-pref-prim-intf = "dsi";
+};
+
+&mdss_dsi0 {
+	qcom,dsi-pref-prim-pan = <&dsi_jdi_qvga_vid>;
+	qcom,platform-enable-gpio = <&msmgpio 109 0>;
+};
+
+&pm8x26_rtc {
+	qcom,qpnp-rtc-write = <1>;
+};
+
+&sdhc_2 {
+	status = "disabled";
+};
+
+&pm8226_l18 {
+	qcom,init-enable = <0>;
+	qcom,send-defaults;
+};
+
+&pm8226_l21 {
+	qcom,init-enable = <0>;
+	qcom,send-defaults;
+};
diff --git a/arch/arm/boot/dts/qcom/msm8926-v1-320p-w-cdp.dts b/arch/arm/boot/dts/qcom/msm8926-v1-320p-w-cdp.dts
index eb06964..8e6972f 100755
--- a/arch/arm/boot/dts/qcom/msm8926-v1-320p-w-cdp.dts
+++ b/arch/arm/boot/dts/qcom/msm8926-v1-320p-w-cdp.dts
@@ -48,3 +48,17 @@
 &pm8x26_rtc {
 	qcom,qpnp-rtc-write = <1>;
 };
+
+&sdhc_2 {
+	status = "disabled";
+};
+
+&pm8226_l18 {
+	qcom,init-enable = <0>;
+	qcom,send-defaults;
+};
+
+&pm8226_l21 {
+	qcom,init-enable = <0>;
+	qcom,send-defaults;
+};
diff --git a/arch/arm/boot/dts/qcom/msm8926-v1-320p-w-g.dts b/arch/arm/boot/dts/qcom/msm8926-v1-320p-w-g.dts
index fc10d4a..6801ca7 100755
--- a/arch/arm/boot/dts/qcom/msm8926-v1-320p-w-g.dts
+++ b/arch/arm/boot/dts/qcom/msm8926-v1-320p-w-g.dts
@@ -126,14 +126,17 @@
 		cdc-vdd-a-1p2v-supply = <&pm8226_l4>;
 		qcom,cdc-vdd-a-1p2v-voltage = <1200000 1200000>;
 		qcom,cdc-vdd-a-1p2v-current = <2000>;
+		qcom,cdc-vdd-a-1p2v-active-current = <2000>;
 
 		cdc-vddcx-1-supply = <&pm8226_l4>;
 		qcom,cdc-vddcx-1-voltage = <1200000 1200000>;
-		qcom,cdc-vddcx-1-current = <33000>;
+		qcom,cdc-vddcx-1-current = <2000>;
+		qcom,cdc-vddcx-1-active-current = <33000>;
 
 		cdc-vddcx-2-supply = <&pm8226_l4>;
 		qcom,cdc-vddcx-2-voltage = <1200000 1200000>;
-		qcom,cdc-vddcx-2-current = <33000>;
+		qcom,cdc-vddcx-2-current = <2000>;
+		qcom,cdc-vddcx-2-active-current = <33000>;
 
 		qcom,cdc-static-supplies = "cdc-vdd-buck",
 					   "cdc-vdd-tx-h",
@@ -162,6 +165,7 @@
 &spmi_bus {
 	qcom,pm8226@1{
 		qcom,leds@d800 {
+			status = "disabled";
                 };
         };
 
@@ -192,3 +196,17 @@
 	qcom,use-dynamic-ocv-setting;
 	qcom,ocv-rbatt-compensation;
 };
+
+&sdhc_2 {
+	status = "disabled";
+};
+
+&pm8226_l18 {
+	qcom,init-enable = <0>;
+	qcom,send-defaults;
+};
+
+&pm8226_l21 {
+	qcom,init-enable = <0>;
+	qcom,send-defaults;
+};
diff --git a/arch/arm/boot/dts/qcom/msm8926-v1-320p-w-mtp.dts b/arch/arm/boot/dts/qcom/msm8926-v1-320p-w-mtp.dts
index 9cee43c..3070f93 100644
--- a/arch/arm/boot/dts/qcom/msm8926-v1-320p-w-mtp.dts
+++ b/arch/arm/boot/dts/qcom/msm8926-v1-320p-w-mtp.dts
@@ -29,6 +29,7 @@
 	i2c@f9927000 { /* BLSP1 QUP5 */
 		synaptics@20 {
 			synaptics,display-coords = <0 0 319 239>;
+			synaptics,is_wake;
 		};
 	};
 };
@@ -49,3 +50,17 @@
 &pm8x26_rtc {
 	qcom,qpnp-rtc-write = <1>;
 };
+
+&sdhc_2 {
+	status = "disabled";
+};
+
+&pm8226_l18 {
+	qcom,init-enable = <0>;
+	qcom,send-defaults;
+};
+
+&pm8226_l21 {
+	qcom,init-enable = <0>;
+	qcom,send-defaults;
+};
diff --git a/arch/arm/boot/dts/qcom/msm8926-w-memory.dtsi b/arch/arm/boot/dts/qcom/msm8926-w-memory.dtsi
index 09b802c..77fac7b 100644
--- a/arch/arm/boot/dts/qcom/msm8926-w-memory.dtsi
+++ b/arch/arm/boot/dts/qcom/msm8926-w-memory.dtsi
@@ -43,19 +43,19 @@
 			label = "external_image_mem";
 		};
 
-		adsp_pil_mem: adsp_region@1e00000 {
+		adsp_pil_mem: adsp_region@1d00000 {
 			linux,reserve-contiguous-region;
 			linux,reserve-region;
 			linux,remove-completely;
-			reg = <0x01e00000 0x1100000>;
+			reg = <0x01d00000 0x1200000>;
 			label = "adsp_pil_mem";
 		};
 
-		peripheral_mem: peripheral_region@1900000 {
+		peripheral_mem: peripheral_region@1800000 {
 			linux,reserve-contiguous-region;
 			linux,reserve-region;
 			linux,remove-completely;
-			reg = <0x01900000 0x500000>;
+			reg = <0x01800000 0x500000>;
 			label = "peripheral_mem";
 		};
 
@@ -67,11 +67,11 @@
 			label = "modem_mem";
 		};
 
-		modem_efs: modem_efs_region@1700000 {
+		modem_efs: modem_efs_region@1600000 {
 			linux,reserve-contiguous-region;
 			linux,reserve-region;
 			linux,remove-completely;
-			reg = <0x01700000 0x200000>;
+			reg = <0x01600000 0x200000>;
 			label = "modem_efs";
 		};
 
diff --git a/arch/arm/boot/dts/qcom/msm8926-w-sharedmem.dtsi b/arch/arm/boot/dts/qcom/msm8926-w-sharedmem.dtsi
index a8e8c37..681c9b6 100644
--- a/arch/arm/boot/dts/qcom/msm8926-w-sharedmem.dtsi
+++ b/arch/arm/boot/dts/qcom/msm8926-w-sharedmem.dtsi
@@ -12,9 +12,9 @@
 
 / {
 
-	qcom,rmtfs_sharedmem@01700000 {
+	qcom,rmtfs_sharedmem@01600000 {
 		compatible = "qcom,sharedmem-uio";
-		reg = <0x01700000 0x200000>;
+		reg = <0x01600000 0x200000>;
 		reg-names = "rmtfs";
 		qcom,client-id = <0x00000001>;
 	};
diff --git a/arch/arm/boot/dts/qcom/msm8926.dtsi b/arch/arm/boot/dts/qcom/msm8926.dtsi
index e6fc5cf..2cb6e1f 100644
--- a/arch/arm/boot/dts/qcom/msm8926.dtsi
+++ b/arch/arm/boot/dts/qcom/msm8926.dtsi
@@ -1,4 +1,4 @@
-/* Copyright (c) 2013-2014, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2013-2015, The Linux Foundation. All rights reserved.
  *
  * This 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,7 +201,3 @@
 	hsic,data-gpio = <&msmgpio 120 0x00>;
 };
 
-&usb_otg {
-	/delete-property/ qcom,hsusb-otg-disable-reset;
-	qcom,ahb-async-bridge-bypass;
-};
diff --git a/arch/arm/configs/apq8026-lw-perf_defconfig b/arch/arm/configs/apq8026-lw-perf_defconfig
index a1257bb..13ca8c3 100644
--- a/arch/arm/configs/apq8026-lw-perf_defconfig
+++ b/arch/arm/configs/apq8026-lw-perf_defconfig
@@ -17,6 +17,8 @@
 # CONFIG_UTS_NS is not set
 # CONFIG_IPC_NS is not set
 # CONFIG_PID_NS is not set
+# CONFIG_DEVMEM is not set
+# CONFIG_DEVKMEM is not set
 CONFIG_RELAY=y
 CONFIG_BLK_DEV_INITRD=y
 CONFIG_RD_BZIP2=y
@@ -112,6 +114,7 @@
 CONFIG_NETFILTER_XT_TARGET_CONNMARK=y
 CONFIG_NETFILTER_XT_TARGET_CONNSECMARK=y
 CONFIG_NETFILTER_XT_TARGET_LOG=y
+CONFIG_NETFILTER_XT_TARGET_NFLOG=y
 CONFIG_NETFILTER_XT_TARGET_MARK=y
 CONFIG_NETFILTER_XT_TARGET_NFQUEUE=y
 CONFIG_NETFILTER_XT_TARGET_NOTRACK=y
@@ -458,5 +461,6 @@
 CONFIG_CRYPTO_DEV_QCRYPTO=m
 CONFIG_CRYPTO_DEV_QCE=y
 CONFIG_CRYPTO_DEV_QCEDEV=m
+CONFIG_SECCOMP=y
 CONFIG_BUILD_ARM_APPENDED_DTB_IMAGE=y
 CONFIG_NETFILTER_XT_TARGET_IDLETIMER=y
diff --git a/arch/arm/configs/apq8026-lw_defconfig b/arch/arm/configs/apq8026-lw_defconfig
index 86271c2..d300f7f 100644
--- a/arch/arm/configs/apq8026-lw_defconfig
+++ b/arch/arm/configs/apq8026-lw_defconfig
@@ -17,6 +17,8 @@
 # CONFIG_UTS_NS is not set
 # CONFIG_IPC_NS is not set
 # CONFIG_PID_NS is not set
+# CONFIG_DEVMEM is not set
+# CONFIG_DEVKMEM is not set
 CONFIG_RELAY=y
 CONFIG_BLK_DEV_INITRD=y
 CONFIG_RD_BZIP2=y
@@ -111,6 +113,7 @@
 CONFIG_NETFILTER_XT_TARGET_CONNMARK=y
 CONFIG_NETFILTER_XT_TARGET_CONNSECMARK=y
 CONFIG_NETFILTER_XT_TARGET_LOG=y
+CONFIG_NETFILTER_XT_TARGET_NFLOG=y
 CONFIG_NETFILTER_XT_TARGET_MARK=y
 CONFIG_NETFILTER_XT_TARGET_NFQUEUE=y
 CONFIG_NETFILTER_XT_TARGET_NOTRACK=y
@@ -498,5 +501,6 @@
 CONFIG_CRYPTO_DEV_QCRYPTO=m
 CONFIG_CRYPTO_DEV_QCE=y
 CONFIG_CRYPTO_DEV_QCEDEV=m
+CONFIG_SECCOMP=y
 CONFIG_BUILD_ARM_APPENDED_DTB_IMAGE=y
 CONFIG_NETFILTER_XT_TARGET_IDLETIMER=y
diff --git a/arch/arm/include/uapi/asm/unistd.h b/arch/arm/include/uapi/asm/unistd.h
index fad66d8..eafa35e 100644
--- a/arch/arm/include/uapi/asm/unistd.h
+++ b/arch/arm/include/uapi/asm/unistd.h
@@ -408,7 +408,10 @@
 #define __NR_finit_module		(__NR_SYSCALL_BASE+379)
 #define __NR_sched_setattr		(__NR_SYSCALL_BASE+380)
 #define __NR_sched_getattr		(__NR_SYSCALL_BASE+381)
-#define __NR_seccomp			(__NR_SYSCALL_BASE+383)
+/* Backporting seccomp, skip a few ...
+ #define __NR_renameat2                 (__NR_SYSCALL_BASE+382)
+ */
+#define __NR_seccomp                    (__NR_SYSCALL_BASE+383)
 
 /*
  * This may need to be greater than __NR_last_syscall+1 in order to
diff --git a/arch/arm/kernel/calls.S b/arch/arm/kernel/calls.S
index e4df5b6..6f675b8 100644
--- a/arch/arm/kernel/calls.S
+++ b/arch/arm/kernel/calls.S
@@ -391,8 +391,8 @@
 		CALL(sys_finit_module)
 /* 380 */	CALL(sys_sched_setattr)
 		CALL(sys_sched_getattr)
-		CALL(sys_ni_syscall)
-		CALL(sys_seccomp)
+                CALL(sys_ni_syscall)       /* reserved sys_renameat2 */
+                CALL(sys_seccomp)
 #ifndef syscalls_counted
 .equ syscalls_padding, ((NR_syscalls + 3) & ~3) - NR_syscalls
 #define syscalls_counted
diff --git a/arch/arm/kernel/perf_event_msm_krait.c b/arch/arm/kernel/perf_event_msm_krait.c
index 49aae5a..34f9b4e 100644
--- a/arch/arm/kernel/perf_event_msm_krait.c
+++ b/arch/arm/kernel/perf_event_msm_krait.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011-2014, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2011-2014, 2016 The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -208,9 +208,6 @@
 	code = (krait_evt_type & 0x00FF0) >> 4;
 	group = krait_evt_type & 0x0000F;
 
-	if ((group > 3) || (reg > KRAIT_MAX_L1_REG))
-		return -EINVAL;
-
 	if (prefix != KRAIT_EVT_PREFIX && prefix != KRAIT_VENUMEVT_PREFIX)
 		return -EINVAL;
 
@@ -221,6 +218,9 @@
 			reg += VENUM_BASE_OFFSET;
 	}
 
+	if ((group > 3) || (reg > KRAIT_MAX_L1_REG))
+		return -EINVAL;
+
 	evtinfo->group_setval = 0x80000000 | (code << (group * 8));
 	evtinfo->groupcode = reg;
 	evtinfo->armv7_evt_type = evt_type_base[reg] | group;
diff --git a/arch/arm/mach-msm/Kconfig b/arch/arm/mach-msm/Kconfig
index 60bfd03..1f6c68b 100644
--- a/arch/arm/mach-msm/Kconfig
+++ b/arch/arm/mach-msm/Kconfig
@@ -767,16 +767,6 @@
 	  to secure execution in the fsm9xxx and msm8x26 targets. This module
 	  utilizes Ion for buffer management.
 
-config MSM_BUSPM_DEV
-	tristate "MSM Bus Performance Monitor Kernel Module"
-	depends on MSM_BUS_SCALING
-	default n
-	help
-	  This kernel module is used to mmap() hardware registers for the
-	  performance monitors, counters, etc. The module can also be used to
-	  allocate physical memory which is used by bus performance hardware to
-	  dump performance data.
-
 config MSM_DIRECT_SCLK_ACCESS
 	bool "Direct access to the SCLK timer"
 	default n
diff --git a/arch/arm/mach-msm/Makefile b/arch/arm/mach-msm/Makefile
index feca7b7..edb053b 100644
--- a/arch/arm/mach-msm/Makefile
+++ b/arch/arm/mach-msm/Makefile
@@ -46,8 +46,6 @@
 CFLAGS_msm_vibrator.o += -Idrivers/staging/android
 
 obj-$(CONFIG_MSM_LPM_TEST) += test-lpm.o
-obj-$(CONFIG_MSM_BUSPM_DEV) += msm-buspm-dev.o
-
 
 obj-$(CONFIG_ARCH_MSM8974) += gpiomux-v2.o gpiomux.o
 obj-$(CONFIG_ARCH_MDM9630) += gpiomux-v2.o gpiomux.o
diff --git a/arch/arm/mach-msm/msm-buspm-dev.c b/arch/arm/mach-msm/msm-buspm-dev.c
deleted file mode 100644
index 5862e05..0000000
--- a/arch/arm/mach-msm/msm-buspm-dev.c
+++ /dev/null
@@ -1,335 +0,0 @@
-/* Copyright (c) 2011-2014, The Linux Foundation. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 and
- * only version 2 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- */
-
-/* #define DEBUG */
-
-#include <linux/module.h>
-#include <linux/fs.h>
-#include <linux/mm.h>
-#include <linux/err.h>
-#include <linux/slab.h>
-#include <linux/errno.h>
-#include <linux/device.h>
-#include <linux/uaccess.h>
-#include <linux/miscdevice.h>
-#include <linux/dma-mapping.h>
-#include <soc/qcom/rpm-smd.h>
-#include "msm-buspm-dev.h"
-
-#define MSM_BUSPM_DRV_NAME "msm-buspm-dev"
-
-enum msm_buspm_spdm_res {
-	SPDM_RES_ID = 0,
-	SPDM_RES_TYPE = 0x63707362,
-	SPDM_KEY = 0x00006e65,
-	SPDM_SIZE = 4,
-};
-/*
- * Allocate kernel buffer.
- * Currently limited to one buffer per file descriptor.  If alloc() is
- * called twice for the same descriptor, the original buffer is freed.
- * There is also no locking protection so the same descriptor can not be shared.
- */
-
-static inline void *msm_buspm_dev_get_vaddr(struct file *filp)
-{
-	struct msm_buspm_map_dev *dev = filp->private_data;
-
-	return (dev) ? dev->vaddr : NULL;
-}
-
-static inline unsigned int msm_buspm_dev_get_buflen(struct file *filp)
-{
-	struct msm_buspm_map_dev *dev = filp->private_data;
-
-	return dev ? dev->buflen : 0;
-}
-
-static inline unsigned long msm_buspm_dev_get_paddr(struct file *filp)
-{
-	struct msm_buspm_map_dev *dev = filp->private_data;
-
-	return (dev) ? dev->paddr : 0L;
-}
-
-static void msm_buspm_dev_free(struct file *filp)
-{
-	struct msm_buspm_map_dev *dev = filp->private_data;
-
-	if (dev && dev->vaddr) {
-		pr_debug("freeing memory at 0x%p\n", dev->vaddr);
-		dma_free_coherent(NULL, dev->buflen, dev->vaddr, dev->paddr);
-		dev->paddr = 0L;
-		dev->vaddr = NULL;
-	}
-}
-
-static int msm_buspm_dev_open(struct inode *inode, struct file *filp)
-{
-	struct msm_buspm_map_dev *dev;
-
-	if (capable(CAP_SYS_ADMIN)) {
-		dev = kzalloc(sizeof(*dev), GFP_KERNEL);
-		if (dev)
-			filp->private_data = dev;
-		else
-			return -ENOMEM;
-	} else {
-		return -EPERM;
-	}
-
-	return 0;
-}
-
-static int
-msm_buspm_dev_alloc(struct file *filp, struct buspm_alloc_params data)
-{
-	dma_addr_t paddr;
-	void *vaddr;
-	struct msm_buspm_map_dev *dev = filp->private_data;
-
-	/* If buffer already allocated, then free it */
-	if (dev->vaddr)
-		msm_buspm_dev_free(filp);
-
-	/* Allocate uncached memory */
-	vaddr = dma_alloc_coherent(NULL, data.size, &paddr, GFP_KERNEL);
-
-	if (vaddr == NULL) {
-		pr_err("allocation of 0x%x bytes failed", data.size);
-		return -ENOMEM;
-	}
-
-	dev->vaddr = vaddr;
-	dev->paddr = paddr;
-	dev->buflen = data.size;
-	filp->f_pos = 0;
-	pr_debug("virt addr = 0x%p\n", dev->vaddr);
-	pr_debug("phys addr = 0x%lx\n", dev->paddr);
-
-	return 0;
-}
-
-static int msm_bus_rpm_req(u32 rsc_type, u32 key, u32 hwid,
-	int ctx, u32 val)
-{
-	struct msm_rpm_request *rpm_req;
-	int ret, msg_id;
-
-	rpm_req = msm_rpm_create_request(ctx, rsc_type, SPDM_RES_ID, 1);
-	if (rpm_req == NULL) {
-		pr_err("RPM: Couldn't create RPM Request\n");
-		return -ENXIO;
-	}
-
-	ret = msm_rpm_add_kvp_data(rpm_req, key, (const uint8_t *)&val,
-		(int)(sizeof(uint32_t)));
-	if (ret) {
-		pr_err("RPM: Add KVP failed for RPM Req:%u\n",
-			rsc_type);
-		goto err;
-	}
-
-	pr_debug("Added Key: %d, Val: %u, size: %d\n", key,
-		(uint32_t)val, sizeof(uint32_t));
-	msg_id = msm_rpm_send_request(rpm_req);
-	if (!msg_id) {
-		pr_err("RPM: No message ID for req\n");
-		ret = -ENXIO;
-		goto err;
-	}
-
-	ret = msm_rpm_wait_for_ack(msg_id);
-	if (ret) {
-		pr_err("RPM: Ack failed\n");
-		goto err;
-	}
-
-err:
-	msm_rpm_free_request(rpm_req);
-	return ret;
-}
-
-static int msm_buspm_ioc_cmds(uint32_t arg)
-{
-	switch (arg) {
-	case MSM_BUSPM_SPDM_CLK_DIS:
-	case MSM_BUSPM_SPDM_CLK_EN:
-		return msm_bus_rpm_req(SPDM_RES_TYPE, SPDM_KEY, 0,
-				MSM_RPM_CTX_ACTIVE_SET, arg);
-	default:
-		pr_warn("Unsupported ioctl command: %d\n", arg);
-		return -EINVAL;
-	}
-}
-
-
-
-static long
-msm_buspm_dev_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
-{
-	struct buspm_xfer_req xfer;
-	struct buspm_alloc_params alloc_data;
-	unsigned long paddr;
-	int retval = 0;
-	void *buf = msm_buspm_dev_get_vaddr(filp);
-	unsigned int buflen = msm_buspm_dev_get_buflen(filp);
-	unsigned char *dbgbuf = buf;
-
-	if (_IOC_TYPE(cmd) != MSM_BUSPM_IOC_MAGIC) {
-		pr_err("Wrong IOC_MAGIC.Exiting\n");
-		return -ENOTTY;
-	}
-
-	switch (cmd) {
-	case MSM_BUSPM_IOC_FREE:
-		pr_debug("cmd = 0x%x (FREE)\n", cmd);
-		msm_buspm_dev_free(filp);
-		break;
-
-	case MSM_BUSPM_IOC_ALLOC:
-		pr_debug("cmd = 0x%x (ALLOC)\n", cmd);
-		retval = __get_user(alloc_data.size, (size_t __user *)arg);
-
-		if (retval == 0)
-			retval = msm_buspm_dev_alloc(filp, alloc_data);
-		break;
-
-	case MSM_BUSPM_IOC_RD_PHYS_ADDR:
-		pr_debug("Read Physical Address\n");
-		paddr = msm_buspm_dev_get_paddr(filp);
-		if (paddr == 0L) {
-			retval = -EINVAL;
-		} else {
-			pr_debug("phys addr = 0x%lx\n", paddr);
-			retval = __put_user(paddr,
-				(unsigned long __user *)arg);
-		}
-		break;
-
-	case MSM_BUSPM_IOC_RDBUF:
-		pr_debug("Read Buffer: 0x%x%x%x%x\n",
-				dbgbuf[0], dbgbuf[1], dbgbuf[2], dbgbuf[3]);
-
-		if (!buf) {
-			retval = -EINVAL;
-			break;
-		}
-
-		if (copy_from_user(&xfer, (void __user *)arg, sizeof(xfer))) {
-			retval = -EFAULT;
-			break;
-		}
-
-		if ((xfer.size <= buflen) &&
-			(copy_to_user((void __user *)xfer.data, buf,
-					xfer.size))) {
-			retval = -EFAULT;
-			break;
-		}
-		break;
-
-	case MSM_BUSPM_IOC_WRBUF:
-		pr_debug("Write Buffer\n");
-
-		if (!buf) {
-			retval = -EINVAL;
-			break;
-		}
-
-		if (copy_from_user(&xfer, (void __user *)arg, sizeof(xfer))) {
-			retval = -EFAULT;
-			break;
-		}
-
-		if ((buflen <= xfer.size) &&
-			(copy_from_user(buf, (void __user *)xfer.data,
-			xfer.size))) {
-			retval = -EFAULT;
-			break;
-		}
-		break;
-
-	case MSM_BUSPM_IOC_CMD:
-		pr_debug("IOCTL command: cmd: %d arg: %lu\n", cmd, arg);
-		retval = msm_buspm_ioc_cmds(arg);
-		break;
-
-	default:
-		pr_debug("Unknown command 0x%x\n", cmd);
-		retval = -EINVAL;
-		break;
-	}
-
-	return retval;
-}
-
-static int msm_buspm_dev_release(struct inode *inode, struct file *filp)
-{
-	struct msm_buspm_map_dev *dev = filp->private_data;
-
-	msm_buspm_dev_free(filp);
-	kfree(dev);
-	filp->private_data = NULL;
-
-	return 0;
-}
-
-static int msm_buspm_dev_mmap(struct file *filp, struct vm_area_struct *vma)
-{
-	pr_debug("vma = 0x%p\n", vma);
-
-	/* Mappings are uncached */
-	vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
-	if (remap_pfn_range(vma, vma->vm_start, vma->vm_pgoff,
-		vma->vm_end - vma->vm_start, vma->vm_page_prot))
-		return -EFAULT;
-
-	return 0;
-}
-
-static const struct file_operations msm_buspm_dev_fops = {
-	.owner		= THIS_MODULE,
-	.mmap		= msm_buspm_dev_mmap,
-	.open		= msm_buspm_dev_open,
-	.unlocked_ioctl	= msm_buspm_dev_ioctl,
-	.llseek		= noop_llseek,
-	.release	= msm_buspm_dev_release,
-};
-
-struct miscdevice msm_buspm_misc = {
-	.minor	= MISC_DYNAMIC_MINOR,
-	.name	= MSM_BUSPM_DRV_NAME,
-	.fops	= &msm_buspm_dev_fops,
-};
-
-static int __init msm_buspm_dev_init(void)
-{
-	int ret = 0;
-
-	ret = misc_register(&msm_buspm_misc);
-	if (ret < 0)
-		pr_err("%s: Cannot register misc device\n", __func__);
-
-	return ret;
-}
-
-static void __exit msm_buspm_dev_exit(void)
-{
-	misc_deregister(&msm_buspm_misc);
-}
-module_init(msm_buspm_dev_init);
-module_exit(msm_buspm_dev_exit);
-
-MODULE_LICENSE("GPL v2");
-MODULE_VERSION("1.0");
-MODULE_ALIAS("platform:"MSM_BUSPM_DRV_NAME);
diff --git a/arch/arm/mach-msm/msm-buspm-dev.h b/arch/arm/mach-msm/msm-buspm-dev.h
deleted file mode 100644
index 9c428fb..0000000
--- a/arch/arm/mach-msm/msm-buspm-dev.h
+++ /dev/null
@@ -1,58 +0,0 @@
-/* Copyright (c) 2011,2014, The Linux Foundation. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 and
- * only version 2 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY 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_BUSPM_DEV_H__
-#define __MSM_BUSPM_DEV_H__
-
-#include <linux/ioctl.h>
-
-struct msm_buspm_map_dev {
-	void            *vaddr;
-	unsigned long   paddr;
-	size_t          buflen;
-};
-
-/* Read/write data into kernel buffer */
-struct buspm_xfer_req {
-	unsigned int  size;		/* Size of this request, in bytes */
-	void *data;		/* Data buffer to transfer data to/from */
-};
-
-struct buspm_alloc_params {
-	size_t  size;
-};
-
-enum msm_buspm_ioc_cmds {
-	MSM_BUSPM_SPDM_CLK_DIS = 0,
-	MSM_BUSPM_SPDM_CLK_EN,
-};
-
-#define MSM_BUSPM_IOC_MAGIC	'p'
-
-#define MSM_BUSPM_IOC_FREE	\
-	_IOW(MSM_BUSPM_IOC_MAGIC, 0, void *)
-
-#define MSM_BUSPM_IOC_ALLOC	\
-	_IOW(MSM_BUSPM_IOC_MAGIC, 1, size_t)
-
-#define MSM_BUSPM_IOC_RDBUF	\
-	_IOW(MSM_BUSPM_IOC_MAGIC, 2, struct buspm_xfer_req)
-
-#define MSM_BUSPM_IOC_WRBUF	\
-	_IOW(MSM_BUSPM_IOC_MAGIC, 3, struct buspm_xfer_req)
-
-#define MSM_BUSPM_IOC_RD_PHYS_ADDR	\
-	_IOR(MSM_BUSPM_IOC_MAGIC, 4, unsigned long)
-
-#define MSM_BUSPM_IOC_CMD	\
-	_IOR(MSM_BUSPM_IOC_MAGIC, 5, uint32_t)
-#endif
diff --git a/drivers/char/diag/diag_masks.c b/drivers/char/diag/diag_masks.c
index 2a82b88..fa1b3f8 100644
--- a/drivers/char/diag/diag_masks.c
+++ b/drivers/char/diag/diag_masks.c
@@ -277,13 +277,15 @@
 	}
 
 	for (i = 0; i < driver->msg_mask_tbl_count; i++, mask++) {
-		if (((first < mask->ssid_first) || (last > mask->ssid_last)) &&
-							first != ALL_SSID) {
+		if (((first < mask->ssid_first) ||
+		     (last > mask->ssid_last_tools)) && first != ALL_SSID) {
 			continue;
 		}
 
+		mutex_lock(&mask->lock);
 		if (msg_mask.status == DIAG_CTRL_MASK_VALID) {
-			mask_size = mask->ssid_last - mask->ssid_first + 1;
+			mask_size =
+				mask->ssid_last_tools - mask->ssid_first + 1;
 			temp_len = mask_size * sizeof(uint32_t);
 			if (temp_len + header_len <= msg_mask.update_buf_len)
 				goto proceed;
@@ -307,13 +309,14 @@
 		header.stream_id = 1;
 		header.msg_mode = 0;
 		header.ssid_first = mask->ssid_first;
-		header.ssid_last = mask->ssid_last;
+		header.ssid_last = mask->ssid_last_tools;
 		header.msg_mask_size = mask_size;
 		mask_size *= sizeof(uint32_t);
 		header.data_len = MSG_MASK_CTRL_HEADER_LEN + mask_size;
 		memcpy(buf, &header, header_len);
 		if (mask_size > 0)
 			memcpy(buf + header_len, mask->ptr, mask_size);
+		mutex_unlock(&mask->lock);
 
 		err = diag_smd_write(smd_info, buf, header_len + mask_size);
 		if (err) {
@@ -409,7 +412,7 @@
 			break;
 		}
 		ssid_range.ssid_first = mask_ptr->ssid_first;
-		ssid_range.ssid_last = mask_ptr->ssid_last;
+		ssid_range.ssid_last = mask_ptr->ssid_last_tools;
 		memcpy(dest_buf + write_len, &ssid_range, sizeof(ssid_range));
 		write_len += sizeof(ssid_range);
 	}
@@ -501,7 +504,7 @@
 	mask = (struct diag_msg_mask_t *)msg_mask.ptr;
 	for (i = 0; i < driver->msg_mask_tbl_count; i++, mask++) {
 		if ((req->ssid_first < mask->ssid_first) ||
-		    (req->ssid_first > mask->ssid_last)) {
+		    (req->ssid_first > mask->ssid_last_tools)) {
 			continue;
 		}
 		mask_size = mask->range * sizeof(uint32_t);
@@ -531,6 +534,7 @@
 	struct diag_msg_mask_t *mask = NULL;
 	struct diag_msg_build_mask_t *req = NULL;
 	struct diag_msg_build_mask_t rsp;
+	uint32_t *temp = NULL;
 
 	if (!src_buf || !dest_buf || src_len <= 0 || dest_len <= 0) {
 		pr_err("diag: Invalid input in %s, src_buf: %p, src_len: %d, dest_buf: %p, dest_len: %d",
@@ -544,30 +548,51 @@
 	mask = (struct diag_msg_mask_t *)msg_mask.ptr;
 	for (i = 0; i < driver->msg_mask_tbl_count; i++, mask++) {
 		if ((req->ssid_first < mask->ssid_first) ||
-		    (req->ssid_first > mask->ssid_last)) {
+		    (req->ssid_first > (mask->ssid_first +
+					MAX_SSID_PER_RANGE))) {
 			continue;
 		}
 		found = 1;
-		if (req->ssid_last > mask->ssid_last) {
-			pr_debug("diag: Msg SSID range mismatch\n");
-			mask->ssid_last = req->ssid_last;
-		}
+		mutex_lock(&mask->lock);
 		mask_size = req->ssid_last - req->ssid_first + 1;
-		if (mask_size > mask->range) {
+		if (mask_size > MAX_SSID_PER_RANGE) {
 			pr_warn("diag: In %s, truncating ssid range, %d-%d to max allowed: %d\n",
 				__func__, mask->ssid_first, mask->ssid_last,
-				mask->range);
-			mask_size = mask->range;
-			mask->ssid_last = mask->ssid_first + mask->range;
+				MAX_SSID_PER_RANGE);
+			mask_size = MAX_SSID_PER_RANGE;
+			mask->range_tools = MAX_SSID_PER_RANGE;
+			mask->ssid_last_tools =
+				mask->ssid_first + mask->range_tools;
 		}
+		if (req->ssid_last > mask->ssid_last_tools) {
+			pr_debug("diag: Msg SSID range mismatch\n");
+			if (mask_size != MAX_SSID_PER_RANGE)
+				mask->ssid_last_tools = req->ssid_last;
+			mask->range_tools =
+				mask->ssid_last_tools - mask->ssid_first + 1;
+			temp = krealloc(mask->ptr,
+					mask->range_tools * sizeof(uint32_t),
+					GFP_KERNEL);
+			if (!temp) {
+				pr_err_ratelimited("diag: In %s, unable to allocate memory for msg mask ptr, mask_size: %d\n",
+						   __func__, mask_size);
+				mutex_unlock(&mask->lock);
+				mutex_unlock(&msg_mask.lock);
+				return -ENOMEM;
+			}
+			mask->ptr = temp;
+		}
+
 		offset = req->ssid_first - mask->ssid_first;
-		if (offset + mask_size > mask->range) {
-			pr_err("diag: In %s, Not enough space for msg mask, mask_size: %d\n",
-			       __func__, mask_size);
+		if (offset + mask_size > mask->range_tools) {
+			pr_err("diag: In %s, Not in msg mask range, mask_size: %d, offset: %d\n",
+			       __func__, mask_size, offset);
+			mutex_unlock(&mask->lock);
 			break;
 		}
 		mask_size = mask_size * sizeof(uint32_t);
 		memcpy(mask->ptr + offset, src_buf + header_len, mask_size);
+		mutex_unlock(&mask->lock);
 		msg_mask.status = DIAG_CTRL_MASK_VALID;
 		break;
 	}
@@ -1039,9 +1064,12 @@
 		return -EINVAL;
 	msg_mask->ssid_first = range->ssid_first;
 	msg_mask->ssid_last = range->ssid_last;
+	msg_mask->ssid_last_tools = range->ssid_last;
 	msg_mask->range = msg_mask->ssid_last - msg_mask->ssid_first + 1;
 	if (msg_mask->range < MAX_SSID_PER_RANGE)
 		msg_mask->range = MAX_SSID_PER_RANGE;
+	msg_mask->range_tools = msg_mask->range;
+	mutex_init(&msg_mask->lock);
 	if (msg_mask->range > 0) {
 		msg_mask->ptr = kzalloc(msg_mask->range * sizeof(uint32_t),
 					GFP_KERNEL);
@@ -1393,19 +1421,23 @@
 	for (i = 0; i < driver->msg_mask_tbl_count; i++, mask++) {
 		ptr = msg_mask.update_buf;
 		len = 0;
+		mutex_lock(&mask->lock);
 		header.ssid_first = mask->ssid_first;
-		header.ssid_last = mask->ssid_last;
-		header.range = mask->range;
+		header.ssid_last = mask->ssid_last_tools;
+		header.range = mask->range_tools;
 		memcpy(ptr, &header, sizeof(header));
 		len += sizeof(header);
-		copy_len = (sizeof(uint32_t) * mask->range);
+		copy_len = (sizeof(uint32_t) * mask->range_tools);
 		if ((len + copy_len) > msg_mask.update_buf_len) {
 			pr_err("diag: In %s, no space to update msg mask, first: %d, last: %d\n",
-			       __func__, mask->ssid_first, mask->ssid_last);
+			       __func__, mask->ssid_first,
+			       mask->ssid_last_tools);
+			mutex_unlock(&mask->lock);
 			continue;
 		}
 		memcpy(ptr + len, mask->ptr, copy_len);
 		len += copy_len;
+		mutex_unlock(&mask->lock);
 		/* + sizeof(int) to account for data_type already in buf */
 		if (total_len + sizeof(int) + len > count) {
 			pr_err("diag: In %s, unable to send msg masks to user space, total_len: %d, count: %zu\n",
diff --git a/drivers/char/diag/diag_masks.h b/drivers/char/diag/diag_masks.h
index 08023c4..877875d 100644
--- a/drivers/char/diag/diag_masks.h
+++ b/drivers/char/diag/diag_masks.h
@@ -30,7 +30,10 @@
 struct diag_msg_mask_t {
 	uint32_t ssid_first;
 	uint32_t ssid_last;
+	uint32_t ssid_last_tools;
 	uint32_t range;
+	uint32_t range_tools;
+	struct mutex lock;
 	uint32_t *ptr;
 } __packed;
 
diff --git a/drivers/char/diag/diagfwd_cntl.c b/drivers/char/diag/diagfwd_cntl.c
index 84b324e..5df3aa1 100644
--- a/drivers/char/diag/diagfwd_cntl.c
+++ b/drivers/char/diag/diagfwd_cntl.c
@@ -337,7 +337,6 @@
 				     struct diag_ssid_range_t *range)
 {
 	uint32_t temp_range;
-	uint32_t *temp = NULL;
 
 	if (!mask || !range)
 		return -EIO;
@@ -348,11 +347,6 @@
 	}
 	if (range->ssid_last >= mask->ssid_last) {
 		temp_range = range->ssid_last - mask->ssid_first + 1;
-		temp = krealloc(mask->ptr, temp_range * sizeof(uint32_t),
-				GFP_KERNEL);
-		if (!temp)
-			return -ENOMEM;
-		mask->ptr = temp;
 		mask->ssid_last = range->ssid_last;
 		mask->range = temp_range;
 	}
diff --git a/drivers/devfreq/Makefile b/drivers/devfreq/Makefile
index 445fc6d..8ff3477 100644
--- a/drivers/devfreq/Makefile
+++ b/drivers/devfreq/Makefile
@@ -1,3 +1,5 @@
+CFLAGS_devfreq_trace.o		:= -I$(src)
+
 obj-$(CONFIG_PM_DEVFREQ)	+= devfreq.o
 obj-$(CONFIG_PM_DEVFREQ)	+= devfreq_trace.o
 obj-$(CONFIG_DEVFREQ_GOV_SIMPLE_ONDEMAND)	+= governor_simpleondemand.o
diff --git a/drivers/gpu/msm/adreno.c b/drivers/gpu/msm/adreno.c
index e91377e..f87a014 100644
--- a/drivers/gpu/msm/adreno.c
+++ b/drivers/gpu/msm/adreno.c
@@ -517,7 +517,7 @@
 		return 0;
 	}
 
-	t = min_t(int, group->reg_count, count);
+	t = min_t(unsigned int, group->reg_count, count);
 
 	buf = kmalloc(t * sizeof(unsigned int), GFP_KERNEL);
 	if (buf == NULL) {
diff --git a/drivers/gpu/msm/kgsl.c b/drivers/gpu/msm/kgsl.c
index 370b2f2..8cfc20b 100644
--- a/drivers/gpu/msm/kgsl.c
+++ b/drivers/gpu/msm/kgsl.c
@@ -2624,6 +2624,20 @@
 }
 #endif
 
+static int check_vma_flags(struct vm_area_struct *vma,
+		unsigned int flags)
+{
+	unsigned long flags_requested = (VM_READ | VM_WRITE);
+
+	if (flags & KGSL_MEMFLAGS_GPUREADONLY)
+		flags_requested &= ~VM_WRITE;
+
+	if ((vma->vm_flags & flags_requested) == flags_requested)
+		return 0;
+
+	return -EFAULT;
+}
+
 static int check_vma(struct vm_area_struct *vma, struct file *vmfile,
 		struct kgsl_memdesc *memdesc)
 {
@@ -2637,7 +2651,7 @@
 	if (vma->vm_start != memdesc->useraddr ||
 		(memdesc->useraddr + memdesc->size) != vma->vm_end)
 		return -EINVAL;
-	return 0;
+	return check_vma_flags(vma, memdesc->flags);
 }
 
 static int memdesc_sg_virt(struct kgsl_memdesc *memdesc, struct file *vmfile)
@@ -2646,7 +2660,7 @@
 	long npages = 0, i;
 	unsigned long sglen = memdesc->size / PAGE_SIZE;
 	struct page **pages = NULL;
-	int write = (memdesc->flags & KGSL_MEMFLAGS_GPUREADONLY) != 0;
+	int write = ((memdesc->flags & KGSL_MEMFLAGS_GPUREADONLY) ? 0 : 1);
 
 	if (sglen == 0 || sglen >= LONG_MAX)
 		return -EINVAL;
@@ -2716,6 +2730,7 @@
 	struct kgsl_map_user_mem *param = data;
 	struct dma_buf *dmabuf = NULL;
 	struct vm_area_struct *vma = NULL;
+	int ret;
 
 	if (param->offset != 0 || param->hostptr == 0
 		|| !KGSL_IS_PAGE_ALIGNED(param->hostptr)
@@ -2732,6 +2747,12 @@
 	if (vma && vma->vm_file) {
 		int fd;
 
+		ret = check_vma_flags(vma, entry->memdesc.flags);
+		if (ret) {
+			up_read(&current->mm->mmap_sem);
+			return ret;
+		}
+
 		/*
 		 * Check to see that this isn't our own memory that we have
 		 * already mapped
@@ -2750,7 +2771,7 @@
 	up_read(&current->mm->mmap_sem);
 
 	if (!IS_ERR_OR_NULL(dmabuf)) {
-		int ret = kgsl_setup_dma_buf(entry, pagetable, device, dmabuf);
+		ret = kgsl_setup_dma_buf(entry, pagetable, device, dmabuf);
 		if (ret)
 			dma_buf_put(dmabuf);
 		return ret;
diff --git a/drivers/gpu/msm/kgsl_sharedmem.c b/drivers/gpu/msm/kgsl_sharedmem.c
index b62c3a3..13006f9 100644
--- a/drivers/gpu/msm/kgsl_sharedmem.c
+++ b/drivers/gpu/msm/kgsl_sharedmem.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2002,2007-2014, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2002,2007-2014,2016, The Linux Foundation. All rights reserved.
  *
  * This 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,10 @@
 	unsigned int align;
 	int step = ((VMALLOC_END - VMALLOC_START)/8) >> PAGE_SHIFT;
 
+	size = PAGE_ALIGN(size);
+	if (size == 0 || size > UINT_MAX)
+		return -EINVAL;
+
 	align = (memdesc->flags & KGSL_MEMALIGN_MASK) >> KGSL_MEMALIGN_SHIFT;
 
 	page_size = get_page_size(size, align);
diff --git a/drivers/input/touchscreen/it7258_ts_i2c.c b/drivers/input/touchscreen/it7258_ts_i2c.c
index c1415f2..87db92e 100644
--- a/drivers/input/touchscreen/it7258_ts_i2c.c
+++ b/drivers/input/touchscreen/it7258_ts_i2c.c
@@ -1585,11 +1585,11 @@
 		return -EBUSY;
 	}
 
-	/* put the device in low power idle mode */
-	IT7260_ts_chipLowPowerMode(PWR_CTL_LOW_POWER_MODE);
-
 	if (device_may_wakeup(dev)) {
 		if (!gl_ts->device_needs_wakeup) {
+			/* put the device in low power idle mode */
+			IT7260_ts_chipLowPowerMode(PWR_CTL_LOW_POWER_MODE);
+
 			gl_ts->device_needs_wakeup = true;
 			enable_irq_wake(gl_ts->client->irq);
 		}
diff --git a/drivers/media/platform/msm/broadcast/Makefile b/drivers/media/platform/msm/broadcast/Makefile
index 1233d6d..5e72b0d 100644
--- a/drivers/media/platform/msm/broadcast/Makefile
+++ b/drivers/media/platform/msm/broadcast/Makefile
@@ -3,9 +3,7 @@
 #
 
 obj-$(CONFIG_TSPP) += tspp.o
-obj-$(CONFIG_TSPP2) += tspp2.o
 obj-$(CONFIG_CI_BRIDGE_SPI) += ci-bridge-spi.o
-obj-$(CONFIG_TSC) += tsc.o
 obj-$(CONFIG_ENSIGMA_UCCP_330) += ensigma_uccp330.o
 obj-$(CONFIG_DEMOD_WRAPPER) += demod_wrapper.o
 
diff --git a/drivers/media/platform/msm/broadcast/tsc.c b/drivers/media/platform/msm/broadcast/tsc.c
deleted file mode 100644
index ec3142e..0000000
--- a/drivers/media/platform/msm/broadcast/tsc.c
+++ /dev/null
@@ -1,3450 +0,0 @@
-/* Copyright (c) 2013-2014, The Linux Foundation. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 and
- * only version 2 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- */
-
-#include <linux/tsc.h>
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/device.h>        /* Device drivers need this */
-#include <linux/cdev.h>		/* Char device drivers need that */
-#include <linux/kernel.h>        /* for KERN_INFO */
-#include <linux/fs.h>
-#include <linux/completion.h>	/* for completion signaling after interrupts */
-#include <linux/uaccess.h>	/* for copy from/to user in the ioctls */
-#include <linux/msm_iommu_domains.h>
-#include <linux/mutex.h>
-#include <linux/of.h>		/* parsing device tree data */
-#include <linux/of_gpio.h>
-#include <linux/of_irq.h>
-#include <mach/gpio.h>		/* gpios definitions */
-#include <linux/pinctrl/consumer.h> /* pinctrl API */
-#include <linux/clk.h>
-#include <linux/wait.h>          /* wait() macros, sleeping */
-#include <linux/sched.h>         /* Externally defined globals */
-#include <linux/poll.h>          /* poll() file op */
-#include <linux/io.h>            /* IO macros */
-#include <linux/bitops.h>
-#include <linux/msm_ion.h>	/* ion_map_iommu */
-#include <linux/iommu.h>
-#include <linux/platform_device.h>
-#include <linux/slab.h>          /* kfree, kzalloc */
-#include <linux/debugfs.h>	/* debugfs support */
-#include <linux/pm_runtime.h>	/* debugfs support */
-#include <linux/pm_wakeup.h>	/* debugfs support */
-#include <linux/regulator/consumer.h> /* gdsc */
-#include <linux/msm-bus.h>	/* bus client */
-#include <linux/delay.h>	/* usleep function */
-/* TODO: include <linux/mpq_standby_if.h> after MCU is mainlined */
-
-/*
- * General defines
- */
-#define TEST_BIT(pos, number) (number & (1 << pos))
-#define CLEAR_BIT(pos, number) (number &= ~(1 << pos))
-#define SET_BIT(pos, number) (number |= 1 << pos)
-
-/*
- * extract bits [@b0:@b1] (inclusive) from the value @x
- * it should be @b0 <= @b1, or result is incorrect
- */
-static inline u32 GETL_BITS(u32 x, int b0, int b1)
-{
-	return (x >> b0) & ((1 << (b1 - b0 + 1)) - 1);
-}
-
-/* Bypass VBIF/IOMMU for debug and bring-up purposes */
-static int tsc_iommu_bypass; /* defualt=0 using iommu */
-module_param(tsc_iommu_bypass, int, S_IRUGO | S_IWUSR | S_IWGRP);
-
-/* The rate of the clock that control TS from TSC to the CAM */
-#define CICAM_CLK_RATE_12MHZ		12000000
-#define CICAM_CLK_RATE_9MHZ		8971962
-#define CICAM_CLK_RATE_7MHZ		7218045
-/* Rates for TSC serial and parallel clocks */
-#define TSC_SER_CLK_RATE		192000000
-#define TSC_PAR_CLK_RATE		24000000
-
-/* CICAM address space according to CI specification */
-#define CICAM_MAX_ADDRESS		3
-
-/*
- * TSC register offsets
- */
-#define TSC_HW_VERSION			(0x0)
-#define TSC_MUX_CFG			(0x4)	/* Muxs config */
-#define TSC_IN_IFC_EXT			(0x8)	/* External demods tsifs */
-#define TSC_IN_IFC_CFG_INT		(0xc)	/* internal demods and
-						cicam tsif config */
-#define TSC_FSM_STATE			(0x50)	/* Read FSM state */
-#define TSC_FSM_STATE_MASK		(0x54)	/* Config FSM state */
-#define TSC_CAM_CMD			(0x1000)/* Config cam commands */
-#define TSC_CAM_RD_DATA			(0x1004)/* read data for single-mode
-							byte */
-#define TSC_STAT			(0x1008)/* Interrupts status */
-#define TSC_IRQ_ENA			(0x100C)/* Enable interrupts */
-#define TSC_IRQ_CLR			(0x1010)/* Clear interrupts */
-#define TSC_CIP_CFG			(0x1014)/* Enable HW polling */
-#define TSC_CD_STAT			(0x1020)/* Card pins status */
-#define TSC_RD_BUFF_ADDR		(0x1024)/* Vbif address for read
-						buffer */
-#define TSC_WR_BUFF_ADDR		(0x1028)/* Vbif address for write
-						buffer */
-#define TSC_FALSE_CD			(0x102C)/* Counter of false card
-						detection */
-#define TSC_FALSE_CD_CLR		(0x1030)/* Clear false cd counter */
-#define TSC_RESP_ERR			(0x1034)/* State of read/write buffer
-						error */
-#define TSC_CICAM_TSIF			(0x1038)/* Enable tsif (tsc->cam) */
-
-
-/*
- * Registers structure definitions
- */
-
-/* TSC_MUX_CFG */
-#define MUX_EXTERNAL_DEMOD_0			0
-#define MUX_EXTERNAL_DEMOD_1			1
-#define MUX_INTERNAL_DEMOD			2
-#define MUX_CICAM				3
-#define MUX0_OFFS				0
-#define MUX1_OFFS				2
-#define MUX_CAM_OFFS				4
-
-/* TSC_IN_IFC_EXT and TSC_IN_IFC_CFG_INT*/
-#define TSIF_INPUT_ENABLE			0
-#define TSIF_INPUT_DISABLE			1
-
-#define TSIF_CLK_POL_OFFS			0
-#define TSIF_DATA_POL_OFFS			1
-#define TSIF_START_POL_OFFS			2
-#define TSIF_VALID_POL_OFFS			3
-#define TSIF_ERROR_POL_OFFS			4
-#define TSIF_SER_PAR_OFFS			5
-#define TSIF_REC_MODE_OFFS			6
-#define TSIF_DATA_SWAP_OFFS			8
-#define TSIF_DISABLE_OFFS			9
-#define TSIF_ERR_INSERT_OFFS			10
-
-/* TSC_FSM_STATE and TSC_FSM_STATE_MASK*/
-#define FSM_STATE_BUFFER_BEG			0
-#define FSM_STATE_BUFFER_END			3
-#define FSM_STATE_POLL_BEG			8
-#define FSM_STATE_POLL_END			10
-#define FSM_STATE_BYTE_BEG			12
-#define FSM_STATE_BYTE_END			13
-#define FSM_STATE_MEM_WR_BEG			16
-#define FSM_STATE_MEM_WR_END			17
-#define FSM_STATE_MEM_RD_BEG			20
-#define FSM_STATE_MEM_RD_END			21
-#define FSM_STATE_IO_RD_BEG			24
-#define FSM_STATE_IO_RD_END			25
-#define FSM_STATE_IO_WR_BEG			28
-#define FSM_STATE_IO_WR_END			29
-
-/* TSC_CAM_CMD */
-#define MEMORY_TRANSACTION			0
-#define IO_TRANSACTION				1
-#define WRITE_TRANSACTION			0
-#define READ_TRANSACTION			1
-#define SINGLE_BYTE_MODE			0
-#define BUFFER_MODE				1
-
-#define CAM_CMD_ADDR_SIZE_OFFS			0
-#define CAM_CMD_WR_DATA_OFFS			16
-#define CAM_CMD_IO_MEM_OFFS			24
-#define CAM_CMD_RD_WR_OFFS			25
-#define CAM_CMD_BUFF_MODE_OFFS			26
-#define CAM_CMD_ABORT				27
-
-/* TSC_STAT, TSC_IRQ_ENA and TSC_IRQ_CLR */
-#define CAM_IRQ_EOT_OFFS			0
-#define CAM_IRQ_POLL_OFFS			1
-#define CAM_IRQ_RATE_MISMATCH_OFFS		2
-#define CAM_IRQ_ERR_OFFS			3
-#define CAM_IRQ_ABORTED_OFFS			4
-
-/* TSC_CD_STAT */
-#define TSC_CD_STAT_INSERT			0x00
-#define TSC_CD_STAT_ERROR1			0x01
-#define TSC_CD_STAT_ERROR2			0x02
-#define TSC_CD_STAT_REMOVE			0x03
-
-#define TSC_CD_BEG				0
-#define TSC_CD_END				1
-
-/* TSC_CICAM_TSIF */
-#define TSC_CICAM_TSIF_OE_OFFS			0
-
-/* Data structures */
-
-/**
- * enum transaction_state - states for the transacation interrupt reason
- */
-enum transaction_state {
-	BEFORE_TRANSACTION = 0,
-	TRANSACTION_SUCCESS = 1,
-	TRANSACTION_ERROR = -1,
-	TRANSACTION_CARD_REMOVED = -2
-};
-
-/**
-* enum pcmcia_state - states for the pcmcia pinctrl states
-* Note: the numbers here corresponds to the numbers of enum tsc_cam_personality
-* in tsc.h file.
-*/
-enum pcmcia_state {
-	PCMCIA_STATE_DISABLE = 0,
-	PCMCIA_STATE_CI_CARD = 1,
-	PCMCIA_STATE_CI_PLUS = 2,
-	PCMCIA_STATE_PC_CARD = 3
-};
-
-/**
- * struct iommu_info - manage all the iommu information
- *
- * @group:		TSC IOMMU group.
- * @domain:		TSC IOMMU domain.
- * @domain_num:		TSC IOMMU domain number.
- * @partition_num:	TSC iommu partition number.
- * @ion_client:		TSC IOMMU client.
- * @iommu_group_name	TSC IOMMU group name.
- */
-struct iommu_info {
-	struct iommu_group *group;
-	struct iommu_domain *domain;
-	int domain_num;
-	int partition_num;
-	struct ion_client *ion_client;
-	const char *iommu_group_name;
-};
-
-/**
- * struct pinctrl_current_state - represent which TLMM pins currently active
- *
- * @ts0:		true if TS-in 0 is active, false otherwise.
- * @ts1:		true if TS-in 1 is active, false otherwise.
- * @pcmcia_state:	Represent the pcmcia pins state.
- */
-struct pinctrl_current_state {
-	bool ts0;
-	bool ts1;
-	enum pcmcia_state pcmcia_state;
-};
-/**
- * struct pinctrl_info - manage all the pinctrl information
- *
- * @pinctrl:		TSC pinctrl state holder.
- * @disable:		pinctrl state to disable all the pins.
- * @ts0:		pinctrl state to activate TS-in 0 alone.
- * @ts1:		pinctrl state to activate TS-in 1 alone.
- * @dual_ts:		pinctrl state to activate both TS-in.
- * @pc_card:		pinctrl state to activate pcmcia upon card insertion.
- * @ci_card:		pinctrl state to activate pcmcia after personality
- *			change to CI card.
- * @ci_plus:		pinctrl state to activate pcmcia after personality
- *			change to CI+ card.
- * @ts0_pc_card:	pinctrl state to activate TS-in 0 and pcmcia upon card
- *			insertion.
- * @ts0_ci_card:	pinctrl state to activate TS-in 0 and pcmcia after
- *			personality change to CI card.
- * @ts0_ci_plus:	pinctrl state to activate TS-in 0 and pcmcia after
- *			personality change to CI+ card.
- * @ts1_pc_card:	pinctrl state to activate TS-in 1 and pcmcia upon card
- *			insertion.
- * @ts1_ci_card:	pinctrl state to activate TS-in 1 and pcmcia after
- *			personality change to CI card.
- * @ts1_ci_plus:	pinctrl state to activate TS-in 1 and pcmcia after
- *			personality change to CI+ card.
- * @dual_ts_pc_card:	pinctrl state to activate both TS-in and pcmcia upon
- *			card insertion.
- * @dual_ts_ci_card:	pinctrl state to activate both TS-in and pcmcia after
- *			personality change to CI card.
- * @dual_ts_ci_plus:	pinctrl state to activate both TS-in and pcmcia after
- *			personality change to CI+ card.
- * @is_ts0:		true if ts0 pinctrl states exist in device tree, false
- *			otherwise.
- * @is_ts1:		true if ts1 pinctrl states exist in device tree, false
- *			otherwise.
- * @is_pcmcia:		true if pcmcia pinctrl states exist in device tree,
- *			false otherwise.
- * @curr_state:		the current state of the TLMM pins.
- */
-struct pinctrl_info {
-	struct pinctrl *pinctrl;
-	struct pinctrl_state *disable;
-	struct pinctrl_state *ts0;
-	struct pinctrl_state *ts1;
-	struct pinctrl_state *dual_ts;
-	struct pinctrl_state *pc_card;
-	struct pinctrl_state *ci_card;
-	struct pinctrl_state *ci_plus;
-	struct pinctrl_state *ts0_pc_card;
-	struct pinctrl_state *ts0_ci_card;
-	struct pinctrl_state *ts0_ci_plus;
-	struct pinctrl_state *ts1_pc_card;
-	struct pinctrl_state *ts1_ci_card;
-	struct pinctrl_state *ts1_ci_plus;
-	struct pinctrl_state *dual_ts_pc_card;
-	struct pinctrl_state *dual_ts_ci_card;
-	struct pinctrl_state *dual_ts_ci_plus;
-	bool is_ts0;
-	bool is_ts1;
-	bool is_pcmcia;
-	struct pinctrl_current_state curr_state;
-};
-
-/**
- * struct tsc_mux_chdev - TSC Mux character device
- *
- * @cdev:		TSC Mux cdev.
- * @mutex:		A mutex for mutual exclusion between Mux API calls.
- * @poll_queue:		Waiting queue for rate mismatch interrupt.
- * @spinlock:	        A spinlock to protect accesses to
- *			data structures that happen from APIs and ISRs.
- * @rate_interrupt:	A flag indicating if rate mismatch interrupt received.
- */
-struct tsc_mux_chdev {
-	struct cdev cdev;
-	struct mutex mutex;
-	wait_queue_head_t poll_queue;
-	spinlock_t spinlock;
-	bool rate_interrupt;
-};
-
-/**
- * struct tsc_ci_chdev - TSC CI character device
- *
- * @cdev:		TSC CI cdev.
- * @mutex:		A mutex for mutual exclusion between CI API calls.
- * @poll_queue:		Waiting queue for card detection interrupt.
- * @spinlock:	        A spinlock to protect accesses to data structures that
- *			happen from APIs and ISRs.
- * @transaction_complete: A completion struct indicating end of data
- *			transaction.
- * @transaction_finish: A completion struct indicating data transaction func
- *                      has finished.
- * @transaction_state:	flag indicating the reason for transaction end.
- * @ci_card_status:	The last card status received by the upper layer.
- * @data_busy:          true when the device is in the middle of data
- *                      transaction operation, false otherwise.
- */
-struct tsc_ci_chdev {
-	struct cdev cdev;
-	struct mutex mutex;
-	wait_queue_head_t poll_queue;
-	spinlock_t spinlock;
-	struct completion transaction_complete;
-	struct completion transaction_finish;
-	enum transaction_state transaction_state;
-	enum tsc_card_status card_status;
-	bool data_busy;
-};
-
-/**
- * struct tsc_device - TSC device
- *
- * @pdev:		TSC platform device.
- * @device_mux:		Mux device for sysfs and /dev entry.
- * @device_ci:		CI device for sysfs and /dev entry.
- * @mux_chdev:		TSC Mux character device instance.
- * @ci_chdev:		TSC CI character device instance.
- * @mux_device_number:	TSC Mux major number.
- * @ci_device_number:	TSC CI major number.
- * @num_mux_opened:	A counter to ensure 1 TSC Mux character device.
- * @num_ci_opened:	A counter to ensure 1 TSC CI character device.
- * @num_device_open:	A counter to synch init of power and bus voting.
- * @mutex:              Global mutex to to synch init of power and bus voting.
- * @base:		Base memory address for the TSC registers.
- * @card_detection_irq:	Interrupt No. of the card detection interrupt.
- * @cam_cmd_irq:	Interrupt No. of the cam cmd interrupt.
- * @iommu_info:		TSC IOMMU parameters.
- * @ahb_clk:		The clock for accessing the TSC registers.
- * @ci_clk:		The clock for TSC internal logic.
- * @ser_clk:		The clock for synchronizing serial TS input.
- * @par_clk:		The clock for synchronizing parallel TS input.
- * @cicam_ts_clk:	The clock for pushing TS data into the cicam.
- * @tspp2_core_clk:	The clock for enabling the TSPP2.
- * @vbif_tspp2_clk:	The clock for accessing the VBIF.
- * @vbif_ahb_clk:	The clock for VBIF AHB.
- * @vbif_axi_clk:	The clock for VBIF AXI.
- * @gdsc:               The Broadcast GDSC.
- * @bus_client:         The TSC bus client.
- * @pinctrl_info:	TSC pinctrl parameters.
- * @reset_cam_gpio:	GPIO No. for CAM HW reset.
- * @hw_card_status:	The card status as reflected by the HW registers.
- * @card_power:		True if the card is powered up, false otherwise.
- * @debugfs_entry:      TSC device debugfs entry.
- */
-struct tsc_device {
-	struct platform_device *pdev;
-	struct device *device_mux;
-	struct device *device_ci;
-	struct tsc_mux_chdev mux_chdev;
-	struct tsc_ci_chdev ci_chdev;
-	dev_t mux_device_number;
-	dev_t ci_device_number;
-	int num_mux_opened;
-	int num_ci_opened;
-	int num_device_open;
-	struct mutex mutex;
-	void __iomem *base;
-	unsigned int card_detection_irq;
-	unsigned int cam_cmd_irq;
-	struct iommu_info iommu_info;
-	struct clk *ahb_clk;
-	struct clk *ci_clk;
-	struct clk *ser_clk;
-	struct clk *par_clk;
-	struct clk *cicam_ts_clk;
-	struct clk *tspp2_core_clk;
-	struct clk *vbif_tspp2_clk;
-	struct clk *vbif_ahb_clk;
-	struct clk *vbif_axi_clk;
-	struct regulator *gdsc;
-	uint32_t bus_client;
-	struct pinctrl_info pinctrl_info;
-	int reset_cam_gpio;
-	enum tsc_card_status hw_card_status;
-	bool card_power;
-	struct dentry *debugfs_entry;
-};
-
-/* Global TSC device class */
-static struct class *tsc_class;
-
-/* Global TSC device database */
-static struct tsc_device *tsc_device;
-
-/************************** Debugfs Support **************************/
-/* debugfs entries */
-#define TSC_S_RW	(S_IRUGO | S_IWUSR)
-
-struct debugfs_entry {
-	const char *name;
-	mode_t mode;
-	int offset;
-};
-
-static const struct debugfs_entry tsc_regs_32[] = {
-		{"tsc_hw_version", S_IRUGO, TSC_HW_VERSION},
-		{"tsc_mux", TSC_S_RW, TSC_MUX_CFG},
-		{"tsif_external_demods", TSC_S_RW, TSC_IN_IFC_EXT},
-		{"tsif_internal_demod_cam", TSC_S_RW, TSC_IN_IFC_CFG_INT},
-		{"tsc_fsm_state", S_IRUGO, TSC_FSM_STATE},
-		{"tsc_fsm_state_mask", TSC_S_RW, TSC_FSM_STATE_MASK},
-		{"tsc_cam_cmd", TSC_S_RW, TSC_CAM_CMD},
-		{"tsc_rd_buff_addr", TSC_S_RW, TSC_RD_BUFF_ADDR},
-		{"tsc_wr_buff_addr", TSC_S_RW, TSC_WR_BUFF_ADDR},
-};
-
-static const struct debugfs_entry tsc_regs_16[] = {
-		{"tsc_false_cd_counter", S_IRUGO, TSC_FALSE_CD},
-		{"tsc_cicam_tsif", TSC_S_RW, TSC_CICAM_TSIF},
-};
-
-static const struct debugfs_entry tsc_regs_8[] = {
-		{"tsc_cam_rd_data", S_IRUGO, TSC_CAM_RD_DATA},
-		{"tsc_irq_stat", S_IRUGO, TSC_STAT},
-		{"tsc_irq_ena", TSC_S_RW, TSC_IRQ_ENA},
-		{"tsc_irq_clr", TSC_S_RW, TSC_IRQ_CLR},
-		{"tsc_ena_hw_poll", TSC_S_RW, TSC_CIP_CFG},
-		{"tsc_card_stat", TSC_S_RW, TSC_CD_STAT},
-		{"tsc_false_cd_counter_clr", TSC_S_RW, TSC_FALSE_CD_CLR},
-		{"tsc_last_error_resp", S_IRUGO, TSC_RESP_ERR},
-};
-
-/* debugfs settings */
-static int debugfs_iomem_set(void *data, u64 val)
-{
-	if (mutex_lock_interruptible(&tsc_device->mutex))
-		return -ERESTARTSYS;
-
-	if (!tsc_device->num_device_open) {
-		mutex_unlock(&tsc_device->mutex);
-		return -ENXIO;
-	}
-
-	mutex_unlock(&tsc_device->mutex);
-
-	writel_relaxed(val, data);
-	wmb();
-
-	return 0;
-}
-
-static int debugfs_iomem_get(void *data, u64 *val)
-{
-	if (mutex_lock_interruptible(&tsc_device->mutex))
-		return -ERESTARTSYS;
-
-	if (!tsc_device->num_device_open) {
-		mutex_unlock(&tsc_device->mutex);
-		return -ENXIO;
-	}
-
-	mutex_unlock(&tsc_device->mutex);
-
-	*val = readl_relaxed(data);
-
-	return 0;
-}
-
-DEFINE_SIMPLE_ATTRIBUTE(fops_iomem_x32, debugfs_iomem_get,
-			debugfs_iomem_set, "0x%08llX");
-DEFINE_SIMPLE_ATTRIBUTE(fops_iomem_x16, debugfs_iomem_get,
-			debugfs_iomem_set, "0x%04llX");
-DEFINE_SIMPLE_ATTRIBUTE(fops_iomem_x8, debugfs_iomem_get,
-			debugfs_iomem_set, "0x%02llX");
-
-/**
- * tsc_debugfs_init() - TSC device debugfs initialization.
- */
-static void tsc_debugfs_init(void)
-{
-	int i;
-	struct dentry *dentry;
-	void __iomem *base = tsc_device->base;
-
-	tsc_device->debugfs_entry = debugfs_create_dir("tsc", NULL);
-	if (!tsc_device->debugfs_entry)
-			return;
-	dentry = debugfs_create_dir("regs", tsc_device->debugfs_entry);
-	if (dentry) {
-		for (i = 0; i < ARRAY_SIZE(tsc_regs_32); i++) {
-			debugfs_create_file(
-					tsc_regs_32[i].name,
-					tsc_regs_32[i].mode,
-					dentry,
-					base + tsc_regs_32[i].offset,
-					&fops_iomem_x32);
-		}
-		for (i = 0; i < ARRAY_SIZE(tsc_regs_16); i++) {
-			debugfs_create_file(
-					tsc_regs_16[i].name,
-					tsc_regs_16[i].mode,
-					dentry,
-					base + tsc_regs_16[i].offset,
-					&fops_iomem_x16);
-		}
-		for (i = 0; i < ARRAY_SIZE(tsc_regs_8); i++) {
-			debugfs_create_file(
-					tsc_regs_8[i].name,
-					tsc_regs_8[i].mode,
-					dentry,
-					base + tsc_regs_8[i].offset,
-					&fops_iomem_x8);
-		}
-	}
-}
-
-/**
- * tsc_debugfs_exit() - TSC device debugfs teardown.
- */
-static void tsc_debugfs_exit(void)
-{
-	debugfs_remove_recursive(tsc_device->debugfs_entry);
-	tsc_device->debugfs_entry = NULL;
-}
-
-/**
- * tsc_update_hw_card_status() - Update the hw_status according to the HW reg.
- *
- * Read the register indicating the card status (inserted, removed, error) and
- * update the tsc_device->hw_card_status accordingly.
- */
-static void tsc_update_hw_card_status(void)
-{
-	u32 cd_reg, card_status = 0;
-
-	cd_reg = readl_relaxed(tsc_device->base + TSC_CD_STAT);
-	card_status = GETL_BITS(cd_reg, TSC_CD_BEG, TSC_CD_END);
-	switch (card_status) {
-	case TSC_CD_STAT_INSERT:
-		tsc_device->hw_card_status = TSC_CARD_STATUS_DETECTED;
-		break;
-	case TSC_CD_STAT_ERROR1:
-	case TSC_CD_STAT_ERROR2:
-		tsc_device->hw_card_status = TSC_CARD_STATUS_FAILURE;
-		break;
-	case TSC_CD_STAT_REMOVE:
-		tsc_device->hw_card_status = TSC_CARD_STATUS_NOT_DETECTED;
-		break;
-	}
-}
-
-/**
- * tsc_card_power_down() - power down card interface upon removal.
- *
- * Power down the card by disable VPP, disable pins in the TLMM, assert the
- * reset line and disable the level-shifters. This function assumes the spinlock
- * of ci device is already taken.
- *
- * Return 0 on finish, error value if interrupted while acquiring a mutex.
- */
-static int tsc_card_power_down(void)
-{
-	int ret = 0;
-	struct pinctrl_info *ppinctrl = &tsc_device->pinctrl_info;
-	struct pinctrl_current_state *pcurr_state = &ppinctrl->curr_state;
-	int reset_gpio = tsc_device->reset_cam_gpio;
-	u32 reg = 0;
-
-	/* Clearing CAM TSIF OE to disable I/O CAM transactions */
-	CLEAR_BIT(TSC_CICAM_TSIF_OE_OFFS, reg);
-	writel_relaxed(reg, tsc_device->base + TSC_CICAM_TSIF);
-
-	/* Assert the reset line */
-	ret = gpio_direction_output(reset_gpio, 1); /* assert */
-	if (ret != 0)
-		pr_err("%s: Failed to assert the reset CAM GPIO\n", __func__);
-
-	/* Disable all the level-shifters */
-	/* TODO: call mpq_standby_pcmcia_master0_set(0) after MCU mainlined */
-	if (ret != 0)
-		pr_err("%s: error disable master0 level-shifters. ret value = %d\n",
-				__func__, ret);
-	/* TODO: call mpq_standby_pcmcia_master1_set(1) after MCU mainlined */
-	if (ret != 0)
-		pr_err("%s: error disable master1 level-shifters. ret value = %d\n",
-				__func__, ret);
-
-	/* Power-down the card */
-	/* TODO: call mpq_standby_pcmcia_vpp_set(1) after MCU mainlined */
-	if (ret != 0)
-		pr_err("%s: error disabling VPP. ret value = %d\n", __func__,
-				ret);
-	/* Wait 10msec until VPP become stable */
-	usleep(10000);
-
-	/* Disable pins in the TLMM */
-	if (mutex_lock_interruptible(&tsc_device->mutex))
-		return -ERESTARTSYS;
-
-	if (pcurr_state->ts0 && pcurr_state->ts1)
-		ret = pinctrl_select_state(ppinctrl->pinctrl,
-				ppinctrl->dual_ts);
-	else if (pcurr_state->ts0 && !pcurr_state->ts1)
-		ret = pinctrl_select_state(ppinctrl->pinctrl,
-				ppinctrl->ts0);
-	else if (!pcurr_state->ts0 && pcurr_state->ts1)
-		ret = pinctrl_select_state(ppinctrl->pinctrl,
-				ppinctrl->ts1);
-	else
-		ret = pinctrl_select_state(ppinctrl->pinctrl,
-				ppinctrl->disable);
-	if (ret != 0)
-		pr_err("%s: error changing PCMCIA pins upon card removal. ret value = %d\n",
-					__func__, ret);
-	else
-		pcurr_state->pcmcia_state = PCMCIA_STATE_DISABLE;
-
-	mutex_unlock(&tsc_device->mutex);
-
-	return 0;
-}
-
-/**
- * tsc_card_power_up() - power up card interface upon insertion.
- *
- * Power up the card by open VPP, enable pins in the TLMM, deassert the reset
- * line and enable the level-shifters. This function assumes the spinlock of ci
- * device is already taken.
- *
- * Return 0 on success, error value otherwise.
- */
-static int tsc_card_power_up(void)
-{
-	int ret = 0;
-	struct pinctrl_info *ppinctrl = &tsc_device->pinctrl_info;
-	struct pinctrl_current_state *pcurr_state = &ppinctrl->curr_state;
-	int reset_gpio = tsc_device->reset_cam_gpio;
-
-	/* Power-up the card */
-	/* TODO: call mpq_standby_pcmcia_vpp_set(1) after MCU mainlined */
-	if (ret != 0) {
-		pr_err("%s: error setting VPP. ret value = %d\n", __func__,
-				ret);
-		return ret;
-	}
-	/* Wait 10msec until VPP become stable */
-	usleep(10000);
-
-	/* Enable pins in the TLMM */
-	if (mutex_lock_interruptible(&tsc_device->mutex))
-		return -ERESTARTSYS;
-
-	if (pcurr_state->ts0 && pcurr_state->ts1)
-		ret = pinctrl_select_state(ppinctrl->pinctrl,
-				ppinctrl->dual_ts_pc_card);
-	else if (pcurr_state->ts0 && !pcurr_state->ts1)
-		ret = pinctrl_select_state(ppinctrl->pinctrl,
-				ppinctrl->ts0_pc_card);
-	else if (!pcurr_state->ts0 && pcurr_state->ts1)
-		ret = pinctrl_select_state(ppinctrl->pinctrl,
-				ppinctrl->ts1_pc_card);
-	else
-		ret = pinctrl_select_state(ppinctrl->pinctrl,
-				ppinctrl->pc_card);
-	if (ret != 0) {
-		pr_err("%s: error changing PCMCIA pins upon card insertion. ret value = %d\n",
-					__func__, ret);
-		mutex_unlock(&tsc_device->mutex);
-		goto err;
-	} else {
-		pcurr_state->pcmcia_state = PCMCIA_STATE_PC_CARD;
-	}
-	mutex_unlock(&tsc_device->mutex);
-
-	/* Release the reset line */
-	ret = gpio_direction_output(reset_gpio, 0); /* Deassert */
-	if (ret != 0) {
-		pr_err("%s: Failed to deassert the reset CAM GPIO\n", __func__);
-		goto err;
-	}
-
-	/* Enable level-shifters for all pins */
-	/* TODO: call mpq_standby_pcmcia_master0_set(0) after MCU mainlined */
-	if (ret != 0) {
-		pr_err("%s: error setting master0 level-shifters. ret value = %d\n",
-				__func__, ret);
-		goto err;
-	}
-	/* TODO: call mpq_standby_pcmcia_master1_set(0) after MCU mainlined */
-	if (ret != 0) {
-		pr_err("%s: error setting master1 level-shifters. ret value = %d\n",
-				__func__, ret);
-		goto err;
-	}
-
-	/* Wait 20msec at the end of the power-up sequence */
-	usleep(20000);
-
-	return ret;
-
-err:
-	tsc_card_power_down();
-	return ret;
-}
-
-/************************** Interrupt handlers **************************/
-/**
- * tsc_card_detect_irq_thread_handler() - TSC card detect interrupt handler.
- *
- * @irq:	Interrupt number.
- * @dev:	TSC device.
- *
- * The handler is executed on a thread context, not in the interrupt context
- * (can take a mutex and sleep).
- * Read the card detection status from the register and initiate a power-up/down
- * sequence accordingly. The sequence will occur only if a change is needed in
- * the current power state.
- *
- */
-static irqreturn_t tsc_card_detect_irq_thread_handler(int irq, void *dev)
-{
-	int ret = 0;
-	struct tsc_ci_chdev *tsc_ci;
-	unsigned long flags = 0;
-
-	tsc_ci = &tsc_device->ci_chdev;
-
-	mutex_lock(&tsc_ci->mutex);
-
-	tsc_update_hw_card_status();
-
-	/* waking-up ci poll queue */
-	wake_up_interruptible(&tsc_ci->poll_queue);
-
-	/* If in the middle of a data transaction- aborting the transaction */
-	if (tsc_ci->data_busy && tsc_device->hw_card_status ==
-			TSC_CARD_STATUS_NOT_DETECTED) {
-		spin_lock_irqsave(&tsc_ci->spinlock, flags);
-		tsc_ci->transaction_state = TRANSACTION_CARD_REMOVED;
-		spin_unlock_irqrestore(&tsc_ci->spinlock, flags);
-		complete_all(&tsc_ci->transaction_complete);
-	}
-
-	if (tsc_device->hw_card_status == TSC_CARD_STATUS_DETECTED &&
-			!tsc_device->card_power) {
-		ret = tsc_card_power_up();
-		if (ret != 0)
-			pr_err("%s: card power-up failed\n", __func__);
-		else
-			tsc_device->card_power = true;
-	} else if (tsc_device->hw_card_status == TSC_CARD_STATUS_NOT_DETECTED &&
-			tsc_device->card_power) {
-		tsc_card_power_down();
-		/*
-		 * In case something failed during the power down, the sequence
-		 * continue and the status of the card power is considered as
-		 * powered down.
-		 */
-		tsc_device->card_power = false;
-	}
-
-	mutex_unlock(&tsc_ci->mutex);
-
-	return IRQ_HANDLED;
-}
-
-/**
- * tsc_cam_cmd_irq_handler() - TSC CAM interrupt handler.
- *
- * @irq:	Interrupt number.
- * @dev:	TSC device.
- *
- * Handle TSC CAM HW interrupt. Handle the CAM transaction interrupts by waking
- * up the completion sync object, handle rate mismatch interrupt by waking-up
- * the TSC Mux poll wait-queue and clear the interrupts received.
- *
- * Return IRQ_HANDLED.
- */
-static irqreturn_t tsc_cam_cmd_irq_handler(int irq, void *dev)
-{
-	struct tsc_ci_chdev *tsc_ci;
-	struct tsc_mux_chdev *tsc_mux;
-	unsigned long flags;
-	u32 stat_reg, ena_reg;
-
-	tsc_ci = &tsc_device->ci_chdev;
-	tsc_mux = &tsc_device->mux_chdev;
-
-	stat_reg = readl_relaxed(tsc_device->base + TSC_STAT);
-
-	/* Handling transaction interrupts */
-	if (TEST_BIT(CAM_IRQ_ERR_OFFS, stat_reg) ||
-			TEST_BIT(CAM_IRQ_EOT_OFFS, stat_reg)) {
-		spin_lock_irqsave(&tsc_ci->spinlock, flags);
-
-		if (TEST_BIT(CAM_IRQ_EOT_OFFS, stat_reg))
-			tsc_ci->transaction_state = TRANSACTION_SUCCESS;
-		else
-			tsc_ci->transaction_state = TRANSACTION_ERROR;
-
-		spin_unlock_irqrestore(&tsc_ci->spinlock, flags);
-		complete_all(&tsc_ci->transaction_complete);
-	}
-
-	/* Handling rate mismatch interrupt */
-	if (TEST_BIT(CAM_IRQ_RATE_MISMATCH_OFFS, stat_reg)) {
-		spin_lock_irqsave(&tsc_mux->spinlock, flags);
-
-		/* Disabling rate mismatch interrupt */
-		ena_reg = readl_relaxed(tsc_device->base + TSC_IRQ_ENA);
-		CLEAR_BIT(CAM_IRQ_RATE_MISMATCH_OFFS, ena_reg);
-		writel_relaxed(ena_reg, tsc_device->base + TSC_IRQ_ENA);
-
-		/* Setting internal flag for poll */
-		tsc_mux->rate_interrupt = true;
-
-		spin_unlock_irqrestore(&tsc_mux->spinlock, flags);
-		/* waking-up mux poll queue */
-		wake_up_interruptible(&tsc_mux->poll_queue);
-	}
-
-	/* Clearing all the interrupts received */
-	writel_relaxed(stat_reg, tsc_device->base + TSC_IRQ_CLR);
-
-	/*
-	 * Before returning IRQ_HANDLED to the generic interrupt handling
-	 * framework need to make sure all operations including clearing of
-	 * interrupt status registers in the hardware is performed.
-	 * Thus a barrier after clearing the interrupt status register
-	 * is required to guarantee that the interrupt status register has
-	 * really been cleared by the time we return from this handler.
-	 */
-	wmb();
-
-	return IRQ_HANDLED;
-}
-
-/************************** Internal functions **************************/
-
-/**
- * tsc_set_cicam_clk() - Setting the rate of the TS from the TSC to the CAM
- *
- * @arg:	The argument received from the user-space via set rate IOCTL.
- *		It is the value of the requested rate in MHz.
- *
- * Setting the rate of the cicam_ts_clk clock, with one of the valid clock
- * frequencies. The arg value given is rounded to the nearest frequency.
- *
- * Return 0 on success, error value otherwise.
- */
-static int tsc_set_cicam_clk(unsigned long arg)
-{
-	int ret;
-
-	if (arg <= 8)
-		ret = clk_set_rate(tsc_device->cicam_ts_clk,
-				CICAM_CLK_RATE_7MHZ);
-	else if (arg <= 11)
-		ret = clk_set_rate(tsc_device->cicam_ts_clk,
-				CICAM_CLK_RATE_9MHZ);
-	else
-		ret = clk_set_rate(tsc_device->cicam_ts_clk,
-				CICAM_CLK_RATE_12MHZ);
-	return ret;
-}
-
-/**
- * tsc_enable_rate_irq() - Enabling the rate mismatch interrupt.
- *
- * @tsc_mux:		TSC Mux device.
- *
- * Setting the bit of this interrupt in the register that controls which
- * interrupts are enabled.
- */
-static void tsc_enable_rate_irq(struct tsc_mux_chdev *tsc_mux)
-{
-	unsigned long flags;
-	u32 ena_reg = 0;
-
-	spin_lock_irqsave(&tsc_mux->spinlock, flags);
-
-	/* Setting the bit to start receiving rate mismatch interrupt again */
-	ena_reg = readl_relaxed(tsc_device->base + TSC_IRQ_ENA);
-	SET_BIT(CAM_IRQ_RATE_MISMATCH_OFFS, ena_reg);
-	writel_relaxed(ena_reg, tsc_device->base + TSC_IRQ_ENA);
-
-	spin_unlock_irqrestore(&tsc_mux->spinlock, flags);
-}
-
-/**
- * tsc_config_tsif() - Modifying TSIF configuration.
- *
- * @tsc_mux:		TSC Mux device.
- * @tsif_params:	TSIF parameters received from the user-space via IOCTL.
- *
- * Update the specified TSIF parameters according to the values in tsif_params.
- * The update is done by modifying a HW register.
- *
- * Return 0 on success, error value otherwise.
- */
-static int tsc_config_tsif(struct tsc_mux_chdev *tsc_mux,
-		struct tsc_tsif_params *tsif_params)
-{
-	int ret = 0;
-	u32 reg;
-	int reg_internal_offs;
-	u32 reg_addr_offs;
-
-	switch (tsif_params->source) {
-	case TSC_SOURCE_EXTERNAL0:
-		reg_internal_offs = 0;
-		reg_addr_offs = TSC_IN_IFC_EXT;
-		break;
-	case TSC_SOURCE_EXTERNAL1:
-		reg_internal_offs = 16;
-		reg_addr_offs = TSC_IN_IFC_EXT;
-		break;
-	case TSC_SOURCE_INTERNAL:
-		reg_internal_offs = 0;
-		reg_addr_offs = TSC_IN_IFC_CFG_INT;
-		break;
-	case TSC_SOURCE_CICAM:
-		reg_internal_offs = 16;
-		reg_addr_offs = TSC_IN_IFC_CFG_INT;
-		break;
-	default:
-		pr_err("%s: unidentified source parameter\n", __func__);
-		ret = -EINVAL;
-		goto err;
-	}
-
-
-	reg = readl_relaxed(tsc_device->base + reg_addr_offs);
-
-	/* Modifying TSIF settings in the register value */
-	(tsif_params->clock_polarity ?
-		SET_BIT((reg_internal_offs + TSIF_CLK_POL_OFFS), reg) :
-		CLEAR_BIT((reg_internal_offs + TSIF_CLK_POL_OFFS), reg));
-	(tsif_params->data_polarity ?
-		SET_BIT(((reg_internal_offs + TSIF_DATA_POL_OFFS)), reg) :
-		CLEAR_BIT((reg_internal_offs + TSIF_DATA_POL_OFFS), reg));
-	(tsif_params->start_polarity ?
-		SET_BIT((reg_internal_offs + TSIF_START_POL_OFFS), reg) :
-		CLEAR_BIT((reg_internal_offs + TSIF_START_POL_OFFS), reg));
-	(tsif_params->valid_polarity ?
-		SET_BIT((reg_internal_offs + TSIF_VALID_POL_OFFS), reg) :
-		CLEAR_BIT((reg_internal_offs + TSIF_VALID_POL_OFFS), reg));
-	(tsif_params->error_polarity ?
-		SET_BIT((reg_internal_offs + TSIF_ERROR_POL_OFFS), reg) :
-		CLEAR_BIT((reg_internal_offs + TSIF_ERROR_POL_OFFS), reg));
-	(tsif_params->data_type ?
-		SET_BIT((reg_internal_offs + TSIF_SER_PAR_OFFS), reg) :
-		CLEAR_BIT((reg_internal_offs + TSIF_SER_PAR_OFFS), reg));
-	reg &= ~(0x3 << TSIF_REC_MODE_OFFS);
-	reg |= (tsif_params->receive_mode << TSIF_REC_MODE_OFFS);
-	(tsif_params->data_swap ?
-		SET_BIT((reg_internal_offs + TSIF_DATA_SWAP_OFFS), reg) :
-		CLEAR_BIT((reg_internal_offs + TSIF_DATA_SWAP_OFFS), reg));
-	(tsif_params->set_error ?
-		SET_BIT((reg_internal_offs + TSIF_ERR_INSERT_OFFS), reg) :
-		CLEAR_BIT((reg_internal_offs + TSIF_ERR_INSERT_OFFS), reg));
-
-	/* Writing the new settings to the register */
-	writel_relaxed(reg, tsc_device->base + reg_addr_offs);
-
-err:
-	return ret;
-}
-
-/**
- * tsc_suspend_ts_pins() - Suspend TS-in pins
- *
- * @source:     The TSIF to configure.
- *
- * Config the TLMM pins of a TSIF as TS-in pins in sleep state according to
- * the current pinctrl configuration of the other pins.
- *
- * Return 0 on success, error value otherwise.
- */
-static int tsc_suspend_ts_pins(enum tsc_source source)
-{
-	int ret = 0;
-	struct pinctrl_info *ppinctrl = &tsc_device->pinctrl_info;
-	struct pinctrl_current_state *pcurr_state = &ppinctrl->curr_state;
-
-	if (mutex_lock_interruptible(&tsc_device->mutex))
-		return -ERESTARTSYS;
-
-	if (source == TSC_SOURCE_EXTERNAL0) {
-		if (!ppinctrl->is_ts0) {
-			pr_err("%s: No TS0-in pinctrl definitions were found in the TSC devicetree\n",
-					__func__);
-			mutex_unlock(&tsc_device->mutex);
-			return -EPERM;
-		}
-
-		/* Transition from current pinctrl state to curr + ts0 sleep */
-		switch (pcurr_state->pcmcia_state) {
-		case PCMCIA_STATE_DISABLE:
-			if (pcurr_state->ts1)
-				ret = pinctrl_select_state(ppinctrl->pinctrl,
-						ppinctrl->ts1);
-			else
-				ret = pinctrl_select_state(ppinctrl->pinctrl,
-						ppinctrl->disable);
-			break;
-		case PCMCIA_STATE_PC_CARD:
-			if (pcurr_state->ts1)
-				ret = pinctrl_select_state(ppinctrl->pinctrl,
-					ppinctrl->ts1_pc_card);
-			else
-				ret = pinctrl_select_state(ppinctrl->pinctrl,
-					ppinctrl->pc_card);
-			break;
-		case PCMCIA_STATE_CI_CARD:
-			if (pcurr_state->ts1)
-				ret = pinctrl_select_state(ppinctrl->pinctrl,
-					ppinctrl->ts1_ci_card);
-			else
-				ret = pinctrl_select_state(ppinctrl->pinctrl,
-					ppinctrl->ci_card);
-			break;
-		case PCMCIA_STATE_CI_PLUS:
-			if (pcurr_state->ts1)
-				ret = pinctrl_select_state(ppinctrl->pinctrl,
-					ppinctrl->ts1_ci_plus);
-			else
-				ret = pinctrl_select_state(ppinctrl->pinctrl,
-					ppinctrl->ci_plus);
-			break;
-		}
-	} else  { /* source == TSC_SOURCE_EXTERNAL1 */
-		if (!ppinctrl->is_ts1) {
-			pr_err("%s: No TS1-in pinctrl definitions were found in the TSC devicetree\n",
-					__func__);
-			mutex_unlock(&tsc_device->mutex);
-			return -EPERM;
-		}
-
-		/* Transition from current pinctrl state to curr + ts1 sleep */
-		switch (pcurr_state->pcmcia_state) {
-		case PCMCIA_STATE_DISABLE:
-			if (pcurr_state->ts0)
-				ret = pinctrl_select_state(ppinctrl->pinctrl,
-					ppinctrl->ts0);
-			else
-				ret = pinctrl_select_state(ppinctrl->pinctrl,
-					ppinctrl->disable);
-			break;
-		case PCMCIA_STATE_PC_CARD:
-			if (pcurr_state->ts0)
-				ret = pinctrl_select_state(ppinctrl->pinctrl,
-					ppinctrl->ts0_pc_card);
-			else
-				ret = pinctrl_select_state(ppinctrl->pinctrl,
-					ppinctrl->pc_card);
-			break;
-		case PCMCIA_STATE_CI_CARD:
-			if (pcurr_state->ts0)
-				ret = pinctrl_select_state(ppinctrl->pinctrl,
-					ppinctrl->ts0_ci_card);
-			else
-				ret = pinctrl_select_state(ppinctrl->pinctrl,
-					ppinctrl->ci_card);
-			break;
-		case PCMCIA_STATE_CI_PLUS:
-			if (pcurr_state->ts0)
-				ret = pinctrl_select_state(ppinctrl->pinctrl,
-					ppinctrl->ts0_ci_plus);
-			else
-				ret = pinctrl_select_state(ppinctrl->pinctrl,
-					ppinctrl->ci_plus);
-			break;
-		}
-	}
-
-	if (ret != 0) {
-		pr_err("%s: error disabling TS-in pins. ret value = %d\n",
-			__func__, ret);
-		mutex_unlock(&tsc_device->mutex);
-		return -EINVAL;
-	}
-
-	/* Update the current pinctrl state in the internal struct */
-	if (source == TSC_SOURCE_EXTERNAL0)
-		pcurr_state->ts0 = false;
-	else
-		pcurr_state->ts1 = false;
-
-	mutex_unlock(&tsc_device->mutex);
-
-	return 0;
-}
-
-/**
- * tsc_activate_ts_pins() - Activate TS-in pins
- *
- * @source:	The TSIF to configure.
- *
- * Config the TLMM pins of a TSIF as TS-in pins in active state according to
- * the current pinctrl configuration of the other pins
- *
- * Return 0 on success, error value otherwise.
- */
-static int tsc_activate_ts_pins(enum tsc_source source)
-{
-	int ret = 0;
-	struct pinctrl_info *ppinctrl = &tsc_device->pinctrl_info;
-	struct pinctrl_current_state *pcurr_state = &ppinctrl->curr_state;
-
-	if (mutex_lock_interruptible(&tsc_device->mutex))
-		return -ERESTARTSYS;
-
-	if (source == TSC_SOURCE_EXTERNAL0) {
-		if (!ppinctrl->is_ts0) {
-			pr_err("%s: No TS0-in pinctrl definitions were found in the TSC devicetree\n",
-					__func__);
-			mutex_unlock(&tsc_device->mutex);
-			return -EPERM;
-		}
-
-		/* Transition from current pinctrl state to curr + ts0 active */
-		switch (pcurr_state->pcmcia_state) {
-		case PCMCIA_STATE_DISABLE:
-			if (pcurr_state->ts1)
-				ret = pinctrl_select_state(ppinctrl->pinctrl,
-						ppinctrl->dual_ts);
-			else
-				ret = pinctrl_select_state(ppinctrl->pinctrl,
-						ppinctrl->ts0);
-			break;
-		case PCMCIA_STATE_PC_CARD:
-			if (pcurr_state->ts1)
-				ret = pinctrl_select_state(ppinctrl->pinctrl,
-					ppinctrl->dual_ts_pc_card);
-			else
-				ret = pinctrl_select_state(ppinctrl->pinctrl,
-					ppinctrl->ts0_pc_card);
-			break;
-		case PCMCIA_STATE_CI_CARD:
-			if (pcurr_state->ts1)
-				ret = pinctrl_select_state(ppinctrl->pinctrl,
-					ppinctrl->dual_ts_ci_card);
-			else
-				ret = pinctrl_select_state(ppinctrl->pinctrl,
-					ppinctrl->ts0_ci_card);
-			break;
-		case PCMCIA_STATE_CI_PLUS:
-			if (pcurr_state->ts1)
-				ret = pinctrl_select_state(ppinctrl->pinctrl,
-					ppinctrl->dual_ts_ci_plus);
-			else
-				ret = pinctrl_select_state(ppinctrl->pinctrl,
-					ppinctrl->ts0_ci_plus);
-			break;
-		}
-	} else  { /* source == TSC_SOURCE_EXTERNAL1 */
-		if (!ppinctrl->is_ts1) {
-			pr_err("%s: No TS1-in pinctrl definitions were found in the TSC devicetree\n",
-					__func__);
-			mutex_unlock(&tsc_device->mutex);
-			return -EPERM;
-		}
-
-		/* Transition from current pinctrl state to curr + ts1 active */
-		switch (pcurr_state->pcmcia_state) {
-		case PCMCIA_STATE_DISABLE:
-			if (pcurr_state->ts0)
-				ret = pinctrl_select_state(ppinctrl->pinctrl,
-					ppinctrl->dual_ts);
-			else
-				ret = pinctrl_select_state(ppinctrl->pinctrl,
-					ppinctrl->ts1);
-			break;
-		case PCMCIA_STATE_PC_CARD:
-			if (pcurr_state->ts0)
-				ret = pinctrl_select_state(ppinctrl->pinctrl,
-					ppinctrl->dual_ts_pc_card);
-			else
-				ret = pinctrl_select_state(ppinctrl->pinctrl,
-					ppinctrl->ts1_pc_card);
-			break;
-		case PCMCIA_STATE_CI_CARD:
-			if (pcurr_state->ts0)
-				ret = pinctrl_select_state(ppinctrl->pinctrl,
-					ppinctrl->dual_ts_ci_card);
-			else
-				ret = pinctrl_select_state(ppinctrl->pinctrl,
-					ppinctrl->ts1_ci_card);
-			break;
-		case PCMCIA_STATE_CI_PLUS:
-			if (pcurr_state->ts0)
-				ret = pinctrl_select_state(ppinctrl->pinctrl,
-					ppinctrl->dual_ts_ci_plus);
-			else
-				ret = pinctrl_select_state(ppinctrl->pinctrl,
-					ppinctrl->ts1_ci_plus);
-			break;
-		}
-	}
-
-	if (ret != 0) {
-		pr_err("%s: error activating TS-in pins. ret value = %d\n",
-			__func__, ret);
-		mutex_unlock(&tsc_device->mutex);
-		return -EINVAL;
-	}
-
-	/* Update the current pinctrl state in the internal struct */
-	if (source == TSC_SOURCE_EXTERNAL0)
-		pcurr_state->ts0 = true;
-	else
-		pcurr_state->ts1 = true;
-
-	mutex_unlock(&tsc_device->mutex);
-
-	return 0;
-}
-
-/**
- * tsc_enable_disable_tsif() - Enable/disable a TSIF.
- *
- * @tsc_mux:	TSC Mux device.
- * @source:	The TSIF to enable or disable.
- * @operation:	The operation to perform: 0- enable, 1- disable.
- *
- * Enable or disable the specified TSIF, which consequently will block the TS
- * flowing through this TSIF. The update is done by modifying a HW register.
- *
- * Return 0 on success, error value otherwise.
- */
-static int tsc_enable_disable_tsif(struct tsc_mux_chdev *tsc_mux,
-		enum tsc_source source, int operation)
-{
-	int ret = 0;
-	u32 reg;
-	u32 addr_offs;
-	int reg_offs;
-	int curr_disable_state;
-
-	switch (source) {
-	case TSC_SOURCE_EXTERNAL0:
-		reg_offs = 0;
-		addr_offs = TSC_IN_IFC_EXT;
-		break;
-	case TSC_SOURCE_EXTERNAL1:
-		reg_offs = 16;
-		addr_offs = TSC_IN_IFC_EXT;
-		break;
-	case TSC_SOURCE_INTERNAL:
-		reg_offs = 0;
-		addr_offs = TSC_IN_IFC_CFG_INT;
-		break;
-	case TSC_SOURCE_CICAM:
-		reg_offs = 16;
-		addr_offs = TSC_IN_IFC_CFG_INT;
-		break;
-	default:
-		pr_err("%s: unidentified source parameter\n", __func__);
-		ret = -EINVAL;
-		return ret;
-	}
-
-	/* Reading the current enable/disable state from the register */
-	reg = readl_relaxed(tsc_device->base + addr_offs);
-	curr_disable_state = GETL_BITS(reg, TSIF_DISABLE_OFFS + reg_offs,
-			TSIF_DISABLE_OFFS + reg_offs);
-	/* If the current state equals the new state- return success */
-	if (curr_disable_state == operation)
-		return ret;
-
-	if (operation == TSIF_INPUT_DISABLE) {
-		if (source == TSC_SOURCE_EXTERNAL0 ||
-				source == TSC_SOURCE_EXTERNAL1) {
-			/* Disabling the TS-in pins in the TLMM */
-			ret = tsc_suspend_ts_pins(source);
-			if (ret != 0) {
-				pr_err("%s: Error suspending TS-in pins",
-						__func__);
-				return ret;
-			}
-		}
-		SET_BIT((reg_offs + TSIF_DISABLE_OFFS), reg);
-	} else {
-		if (source == TSC_SOURCE_EXTERNAL0 ||
-				source == TSC_SOURCE_EXTERNAL1) {
-			/* Enabling the TS-in pins in the TLMM */
-			ret = tsc_activate_ts_pins(source);
-			if (ret != 0) {
-				pr_err("%s: Error activating TS-in pins",
-						__func__);
-				return ret;
-			}
-		}
-		CLEAR_BIT((reg_offs + TSIF_DISABLE_OFFS), reg);
-	}
-
-	/* Writing back to the reg the enable/disable of the TSIF */
-	writel_relaxed(reg, tsc_device->base + addr_offs);
-
-	return ret;
-}
-
-/**
- * tsc_route_mux() - Configuring one of the TSC muxes.
- *
- * @tsc_mux:	TSC Mux device.
- * @source:	The requested TS source to be selected by the mux.
- * @dest:	The requested mux.
- *
- * Configuring the specified mux to pass the TS indicated by the src parameter.
- * The update is done by modifying a HW register.
- *
- * Return 0 on success, error value otherwise.
- */
-static int tsc_route_mux(struct tsc_mux_chdev *tsc_mux, enum tsc_source source,
-		enum tsc_dest dest)
-{
-	int ret = 0;
-	u32 mux_cfg_reg;
-	int src_val;
-
-	switch (source) {
-	case TSC_SOURCE_EXTERNAL0:
-		src_val = MUX_EXTERNAL_DEMOD_0;
-		break;
-	case TSC_SOURCE_EXTERNAL1:
-		src_val = MUX_EXTERNAL_DEMOD_1;
-		break;
-	case TSC_SOURCE_INTERNAL:
-		src_val = MUX_INTERNAL_DEMOD;
-		break;
-	case TSC_SOURCE_CICAM:
-		src_val = MUX_CICAM;
-		break;
-	default:
-		pr_err("%s: unidentified source parameter\n", __func__);
-		ret = -EINVAL;
-		goto err;
-	}
-
-	/* Reading the current muxes state, to change only the requested mux */
-	mux_cfg_reg = readl_relaxed(tsc_device->base + TSC_MUX_CFG);
-
-	switch (dest) {
-	case TSC_DEST_TSPP0:
-		mux_cfg_reg &= ~(0x3 << MUX0_OFFS);
-		mux_cfg_reg |= (src_val << MUX0_OFFS);
-		break;
-	case TSC_DEST_TSPP1:
-		mux_cfg_reg &= ~(0x3 << MUX1_OFFS);
-		mux_cfg_reg |= (src_val << MUX1_OFFS);
-		break;
-	case TSC_DEST_CICAM:
-		if (src_val == TSC_SOURCE_CICAM) {
-			pr_err("%s: Error: CICAM cannot be source and dest\n",
-					__func__);
-			ret = -EINVAL;
-			goto err;
-		}
-		mux_cfg_reg &= ~(0x3 << MUX_CAM_OFFS);
-		mux_cfg_reg |= (src_val << MUX_CAM_OFFS);
-		break;
-	default:
-		pr_err("%s: unidentified dest parameter\n", __func__);
-		ret = -EINVAL;
-		goto err;
-	}
-
-	writel_relaxed(mux_cfg_reg, tsc_device->base + TSC_MUX_CFG);
-
-err:
-	return ret;
-}
-
-/**
- * is_tsc_idle() - Checking if TSC is idle.
- *
- * @tsc_ci:		TSC CI device.
- *
- * Reading the TSC state-machine register and checking if the TSC is busy in
- * one of the operations reflected by this register.
- *
- * Return true if the TSC is idle and false if it's busy.
- */
-static bool is_tsc_idle(struct tsc_ci_chdev *tsc_ci)
-{
-	u32 fsm_reg;
-
-	fsm_reg = readl_relaxed(tsc_device->base + TSC_FSM_STATE);
-	if (GETL_BITS(fsm_reg, FSM_STATE_BUFFER_BEG, FSM_STATE_BUFFER_END) ||
-		GETL_BITS(fsm_reg, FSM_STATE_POLL_BEG, FSM_STATE_POLL_END) ||
-		GETL_BITS(fsm_reg, FSM_STATE_BYTE_BEG, FSM_STATE_BYTE_END) ||
-		GETL_BITS(fsm_reg, FSM_STATE_MEM_WR_BEG,
-				FSM_STATE_MEM_WR_END) ||
-		GETL_BITS(fsm_reg, FSM_STATE_MEM_RD_BEG,
-				FSM_STATE_MEM_RD_END) ||
-		GETL_BITS(fsm_reg, FSM_STATE_IO_RD_BEG, FSM_STATE_IO_RD_END) ||
-		GETL_BITS(fsm_reg, FSM_STATE_IO_WR_BEG, FSM_STATE_IO_WR_END) ||
-			tsc_ci->data_busy)
-		return false;
-
-	tsc_ci->data_busy = true;
-
-	return true;
-}
-
-
-/**
- * tsc_power_on_buff_mode_clocks() - power-on the TSPP2 and VBIF clocks.
- *
- * Power-on the TSPP2 and the VBIF clocks required for buffer mode transaction.
- *
- * Return 0 on success, error value otherwise.
- */
-static int tsc_power_on_buff_mode_clocks(void)
-{
-	int ret = 0;
-
-	ret = clk_prepare_enable(tsc_device->tspp2_core_clk);
-	if (ret != 0) {
-		pr_err("%s: Can't start tspp2_core_clk", __func__);
-		goto err_tspp2;
-	}
-	ret = clk_prepare_enable(tsc_device->vbif_tspp2_clk);
-	if (ret != 0) {
-		pr_err("%s: Can't start vbif_tspp2_clk", __func__);
-		goto err_vbif_tspp2;
-	}
-	ret = clk_prepare_enable(tsc_device->vbif_ahb_clk);
-	if (ret != 0) {
-		pr_err("%s: Can't start vbif_ahb_clk", __func__);
-		goto err_vbif_ahb;
-	}
-	ret = clk_prepare_enable(tsc_device->vbif_axi_clk);
-	if (ret != 0) {
-		pr_err("%s: Can't start vbif_axi_clk", __func__);
-		goto err_vbif_axi;
-	}
-
-	return ret;
-
-err_vbif_axi:
-	clk_disable_unprepare(tsc_device->vbif_ahb_clk);
-err_vbif_ahb:
-	clk_disable_unprepare(tsc_device->vbif_tspp2_clk);
-err_vbif_tspp2:
-	clk_disable_unprepare(tsc_device->tspp2_core_clk);
-err_tspp2:
-	return ret;
-}
-
-/**
- * tsc_power_off_buff_mode_clocks() - power-off the SPP2 and VBIF clocks.
- *
- * Power-off the TSPP2 and the VBIF clocks required for buffer mode transaction.
- */
-static void tsc_power_off_buff_mode_clocks(void)
-{
-	clk_disable_unprepare(tsc_device->vbif_axi_clk);
-	clk_disable_unprepare(tsc_device->vbif_ahb_clk);
-	clk_disable_unprepare(tsc_device->tspp2_core_clk);
-	clk_disable_unprepare(tsc_device->vbif_tspp2_clk);
-}
-
-/**
- * tsc_config_cam_data_transaction() - Configuring a new data transaction.
- *
- * @addr_size:	The value for the address_size register field- address when
- *		using single byte-mode, and size when using buffer mode.
- * @wr_data:	the value for the wr_data register field- data to write to the
- *		cam when using single byte mode.
- * @io_mem:	The value for the io_mem register field- 1 for IO transaction,
- *		0 for memory transaction.
- * @read_write:	The value for the read_write register field- 1 for read
- *		transaction, 0 for write transaction.
- * @buff_mode:	The value for the buff_mode register field- 1 for buffer mode,
- *		0 for single byte mode.
- *
- * Configuring the cam cmd register with the specified parameters, to initiate
- * data transaction with the cam.
- */
-static void tsc_config_cam_data_transaction(u16 addr_size,
-		u8 wr_data,
-		uint io_mem,
-		uint read_write,
-		uint buff_mode)
-{
-	u32 cam_cmd_reg = 0;
-
-	cam_cmd_reg |= (addr_size << CAM_CMD_ADDR_SIZE_OFFS);
-	cam_cmd_reg |= (wr_data << CAM_CMD_WR_DATA_OFFS);
-	cam_cmd_reg |= (io_mem << CAM_CMD_IO_MEM_OFFS);
-	cam_cmd_reg |= (read_write << CAM_CMD_RD_WR_OFFS);
-	cam_cmd_reg |= (buff_mode << CAM_CMD_BUFF_MODE_OFFS);
-	writel_relaxed(cam_cmd_reg, tsc_device->base + TSC_CAM_CMD);
-}
-
-/**
- * tsc_data_transaction() - Blocking function that manage the data transactions.
- *
- * @tsc_ci:	TSC CI device.
- * @io_mem:	The value for the io_mem register field- 1 for IO transaction,
- *		0 for memory transaction.
- * @read_write:	The value for the read_write register field- 1 for read
- *		transaction, 0 for write transaction.
- * @buff_mode:	The value for the buff_mode register field- 1 for buffer mode,
- *		0 for single byte mode.
- * @arg:	The argument received from the user-space via a data transaction
- *		IOCTL. It is from one of the two following types:
- *		"struct tsc_single_byte_mode" and "struct tsc_buffer_mode".
- *
- * Receiving the transaction paramters from the user-space. Configure the HW
- * registers to initiate a data transaction with the cam. Wait for an
- * interrupt indicating the transaction is over and return the the data read
- * from the cam in case of single-byte read transaction.
- *
- * Return 0 on success, error value otherwise.
- */
-static int tsc_data_transaction(struct tsc_ci_chdev *tsc_ci, uint io_mem,
-		uint read_write, uint buff_mode, unsigned long arg)
-{
-	struct tsc_single_byte_mode arg_byte;
-	struct tsc_buffer_mode arg_buff;
-	u16 addr_size;
-	u8 wr_data;
-	uint timeout;
-	u32 cam_cmd_reg;
-	struct ion_handle *ion_handle = NULL;
-	ion_phys_addr_t iova = 0;
-	unsigned long buffer_size = 0;
-	unsigned long flags = 0;
-	int ret = 0;
-
-	if (!arg)
-		return -EINVAL;
-
-	/* make sure the tsc is in idle state before configuring the cam */
-	if (!is_tsc_idle(tsc_ci)) {
-		ret =  -EBUSY;
-		goto finish;
-	}
-
-	INIT_COMPLETION(tsc_ci->transaction_finish);
-
-	/* copying data from the ioctl parameter */
-	if (buff_mode == SINGLE_BYTE_MODE) {
-		if (copy_from_user(&arg_byte, (void *)arg,
-				sizeof(struct tsc_single_byte_mode))) {
-			ret = -EFAULT;
-			goto err_copy_arg;
-		}
-		addr_size = arg_byte.address;
-		if (IO_TRANSACTION == io_mem &&
-				addr_size > CICAM_MAX_ADDRESS) {
-			pr_err("%s: wrong address parameter: %d\n", __func__,
-					addr_size);
-			ret = -EFAULT;
-			goto err_copy_arg;
-		}
-		wr_data = arg_byte.data;
-		timeout = arg_byte.timeout;
-	} else {
-		if (copy_from_user(&arg_buff, (void *)arg,
-				sizeof(struct tsc_buffer_mode))) {
-			ret =  -EFAULT;
-			goto err_copy_arg;
-		}
-		addr_size = arg_buff.buffer_size;
-		if (!addr_size) {
-			pr_err("%s: size parameter is 0\n", __func__);
-			ret =  -EFAULT;
-			goto err_copy_arg;
-		}
-		wr_data = 0;
-		timeout = arg_buff.timeout;
-
-		/* import ion handle from the ion fd passed from user-space */
-		ion_handle = ion_import_dma_buf
-			(tsc_device->iommu_info.ion_client, arg_buff.buffer_fd);
-		if (IS_ERR_OR_NULL(ion_handle)) {
-			pr_err("%s: get_ION_handle failed\n", __func__);
-			ret =  -EIO;
-			goto err_ion_handle;
-		}
-
-		/*
-		 * mapping the ion handle to the VBIF and get the virtual
-		 * address
-		 */
-		ret = ion_map_iommu(tsc_device->iommu_info.ion_client,
-				ion_handle, tsc_device->iommu_info.domain_num,
-				tsc_device->iommu_info.partition_num, SZ_4K,
-				0, &iova, &buffer_size, 0, 0);
-
-		if (ret != 0) {
-			pr_err("%s: get_ION_kernel physical addr fail\n",
-					__func__);
-			goto err_ion_map;
-		}
-
-		/*
-		 * writing the buffer virtual address to the register for buffer
-		 * address of buffer mode
-		 */
-		if (read_write == READ_TRANSACTION)
-			writel_relaxed(iova,
-					tsc_device->base + TSC_RD_BUFF_ADDR);
-		else   /* write transaction */
-			writel_relaxed(iova,
-					tsc_device->base + TSC_WR_BUFF_ADDR);
-	}
-
-	/* configuring the cam command register */
-	tsc_config_cam_data_transaction(addr_size, wr_data, io_mem, read_write,
-			buff_mode);
-
-	/*
-	 * This function assume the mutex is locked before calling the function,
-	 * so mutex has to be unlocked before going to sleep when waiting for
-	 * the transaction.
-	 */
-	mutex_unlock(&tsc_ci->mutex);
-	/* waiting for EOT interrupt or timeout */
-	if (!wait_for_completion_timeout(&tsc_ci->transaction_complete,
-			msecs_to_jiffies(timeout))) {
-		pr_err("%s: Error: wait for transaction timed-out\n", __func__);
-		ret =  -ETIMEDOUT;
-		mutex_lock(&tsc_ci->mutex);
-		/* Aborting the transaction if it's buffer mode */
-		if (buff_mode) {
-			cam_cmd_reg = readl_relaxed(tsc_device->base +
-					TSC_CAM_CMD);
-			SET_BIT(CAM_CMD_ABORT, cam_cmd_reg);
-			writel_relaxed(cam_cmd_reg, tsc_device->base +
-					TSC_CAM_CMD);
-		}
-		goto finish;
-	}
-	mutex_lock(&tsc_ci->mutex);
-
-	/* Checking if transaction ended with error */
-	spin_lock_irqsave(&tsc_ci->spinlock, flags);
-	if (tsc_ci->transaction_state == TRANSACTION_ERROR) {
-		tsc_ci->transaction_state = BEFORE_TRANSACTION;
-		spin_unlock_irqrestore(&tsc_ci->spinlock, flags);
-		pr_err("%s: Transaction error\n", __func__);
-		ret =  -EBADE; /* Invalid exchange error code */
-		goto finish;
-	} else if (tsc_ci->transaction_state == TRANSACTION_CARD_REMOVED) {
-		tsc_ci->transaction_state = BEFORE_TRANSACTION;
-		spin_unlock_irqrestore(&tsc_ci->spinlock, flags);
-		pr_err("%s: Card was removed during the transaction. Aborting\n",
-				__func__);
-		ret = -ECONNABORTED;
-		/* Aborting the transaction if it's buffer mode */
-		if (buff_mode) {
-			cam_cmd_reg = readl_relaxed(tsc_device->base +
-					TSC_CAM_CMD);
-			SET_BIT(CAM_CMD_ABORT, cam_cmd_reg);
-			writel_relaxed(cam_cmd_reg, tsc_device->base +
-					TSC_CAM_CMD);
-		}
-		goto finish;
-	}
-
-	/* reseting the argument after reading the interrupt type */
-	tsc_ci->transaction_state = BEFORE_TRANSACTION;
-	spin_unlock_irqrestore(&tsc_ci->spinlock, flags);
-
-	/*
-	 * Only on case of read single byte operation, we need to copy the data
-	 * to the arg data field
-	 */
-	if (buff_mode == SINGLE_BYTE_MODE && read_write == READ_TRANSACTION)
-		ret = put_user(readl_relaxed(tsc_device->base +
-				TSC_CAM_RD_DATA),
-				&((struct tsc_single_byte_mode *)arg)->data);
-
-finish:
-	if (iova != 0)
-		ion_unmap_iommu(tsc_device->iommu_info.ion_client, ion_handle,
-			tsc_device->iommu_info.domain_num,
-			tsc_device->iommu_info.partition_num);
-err_ion_map:
-	if (!IS_ERR_OR_NULL(ion_handle))
-		ion_free(tsc_device->iommu_info.ion_client, ion_handle);
-err_ion_handle:
-err_copy_arg:
-	tsc_ci->data_busy = false;
-	INIT_COMPLETION(tsc_ci->transaction_complete);
-	complete_all(&tsc_ci->transaction_finish);
-	return ret;
-}
-
-/**
- * tsc_personality_change() - change the PCMCIA pins state.
- *
- * @pcmcia_state:	The new state of the PCMCIA pins.
- *
- * Configure the TLMM pins of the PCMCIA according to received state and
- * the current pinctrl configuration of the other pins. This function assums the
- * PCMCIA pinctrl definitions were successfully parsed from the devicetree (this
- * check is done at open device).
- *
- * Return 0 on success, error value otherwise.
- */
-static int tsc_personality_change(enum tsc_cam_personality pcmcia_state)
-{
-	int ret = 0;
-	struct pinctrl_info *ppinctrl = &tsc_device->pinctrl_info;
-	struct pinctrl_current_state *pcurr_state = &ppinctrl->curr_state;
-	u32 reg = 0;
-
-	if (mutex_lock_interruptible(&tsc_device->mutex))
-		return -ERESTARTSYS;
-
-	if (pcmcia_state == (enum tsc_cam_personality)pcurr_state->pcmcia_state)
-		goto exit;
-
-	/* Transition from current pinctrl state to curr + new pcmcia state */
-	switch (pcmcia_state) {
-	case TSC_CICAM_PERSONALITY_CI:
-		if (pcurr_state->ts0 && pcurr_state->ts1)
-			ret = pinctrl_select_state(ppinctrl->pinctrl,
-					ppinctrl->dual_ts_ci_card);
-		else if (pcurr_state->ts0 && !pcurr_state->ts1)
-			ret = pinctrl_select_state(ppinctrl->pinctrl,
-					ppinctrl->ts0_ci_card);
-		else if (!pcurr_state->ts0 && pcurr_state->ts1)
-			ret = pinctrl_select_state(ppinctrl->pinctrl,
-					ppinctrl->ts1_ci_card);
-		else
-			ret = pinctrl_select_state(ppinctrl->pinctrl,
-					ppinctrl->ci_card);
-		break;
-	case TSC_CICAM_PERSONALITY_CIPLUS:
-		if (pcurr_state->ts0 && pcurr_state->ts1)
-			ret = pinctrl_select_state(ppinctrl->pinctrl,
-					ppinctrl->dual_ts_ci_plus);
-		else if (pcurr_state->ts0 && !pcurr_state->ts1)
-			ret = pinctrl_select_state(ppinctrl->pinctrl,
-					ppinctrl->ts0_ci_plus);
-		else if (!pcurr_state->ts0 && pcurr_state->ts1)
-			ret = pinctrl_select_state(ppinctrl->pinctrl,
-					ppinctrl->ts1_ci_plus);
-		else
-			ret = pinctrl_select_state(ppinctrl->pinctrl,
-					ppinctrl->ci_plus);
-		break;
-	case TSC_CICAM_PERSONALITY_DISABLE:
-		if (pcurr_state->ts0 && pcurr_state->ts1)
-			ret = pinctrl_select_state(ppinctrl->pinctrl,
-					ppinctrl->dual_ts);
-		else if (pcurr_state->ts0 && !pcurr_state->ts1)
-			ret = pinctrl_select_state(ppinctrl->pinctrl,
-					ppinctrl->ts0);
-		else if (!pcurr_state->ts0 && pcurr_state->ts1)
-			ret = pinctrl_select_state(ppinctrl->pinctrl,
-					ppinctrl->ts1);
-		else
-			ret = pinctrl_select_state(ppinctrl->pinctrl,
-					ppinctrl->disable);
-		break;
-	default:
-		pr_err("%s: Wrong personality parameter\n", __func__);
-		ret = -EINVAL;
-		goto exit;
-	}
-
-	if (ret != 0) {
-		pr_err("%s: error changing PCMCIA pins. ret value = %d\n",
-			__func__, ret);
-		ret = -EINVAL;
-		goto exit;
-	}
-
-	/* Update the current pcmcia state in the internal struct */
-	pcurr_state->pcmcia_state = (enum pcmcia_state)pcmcia_state;
-
-	/*
-	 * Setting CAM TSIF OE to enable I/O transactions for CI/+ cards
-	 * or clearing it when moving to disable state
-	 */
-	if (TSC_CICAM_PERSONALITY_CI == pcmcia_state ||
-			TSC_CICAM_PERSONALITY_CIPLUS == pcmcia_state) {
-		SET_BIT(TSC_CICAM_TSIF_OE_OFFS, reg);
-		writel_relaxed(reg, tsc_device->base + TSC_CICAM_TSIF);
-	} else {
-		CLEAR_BIT(TSC_CICAM_TSIF_OE_OFFS, reg);
-		writel_relaxed(reg, tsc_device->base + TSC_CICAM_TSIF);
-	}
-
-exit:
-	mutex_unlock(&tsc_device->mutex);
-	return ret;
-}
-
-/**
- * tsc_reset_cam() - HW reset to the CAM.
- *
- * Toggle the reset pin of the pcmcia to make a HW reset.
- * This function assumes that pinctrl_select_state was already called on the
- * reset pin with its active state (happens during personality change).
- *
- * Return 0 on success, error value otherwise.
- */
-static int tsc_reset_cam(void)
-{
-	int ret;
-	int reset_gpio = tsc_device->reset_cam_gpio;
-
-	/* Toggle the GPIO to create a reset pulse */
-	ret = gpio_direction_output(reset_gpio, 0); /* Make sure it's 0 */
-	if (ret != 0)
-		goto err;
-
-	ret = gpio_direction_output(reset_gpio, 1); /* Assert */
-	if (ret != 0)
-		goto err;
-
-	/*
-	 * Waiting to enable the CAM to process the assertion before the
-	 * deassertion. 1ms is needed for this processing.
-	 */
-	usleep(1000);
-
-	ret = gpio_direction_output(reset_gpio, 0); /* Deassert */
-	if (ret != 0)
-		goto err;
-
-	return 0;
-err:
-	pr_err("%s: Failed writing to reset cam GPIO\n", __func__);
-	return ret;
-}
-
-/**
- * tsc_reset_registers() - Reset the TSC registers.
- *
- * Write specific reset values to the TSC registers, managed by the driver.
- */
-static void tsc_reset_registers(void)
-{
-	/* Reset state - all mux transfer ext. demod 0 */
-	writel_relaxed(0x00000000, tsc_device->base + TSC_MUX_CFG);
-
-	/* Disabling TSIFs inputs, putting polarity to normal, data as serial */
-	writel_relaxed(0x02000200, tsc_device->base + TSC_IN_IFC_EXT);
-	writel_relaxed(0x02000200, tsc_device->base + TSC_IN_IFC_CFG_INT);
-
-	/* Reseting TSC_FSM_STATE_MASK to represent all the states but poll */
-	writel_relaxed(0x3333300F, tsc_device->base + TSC_FSM_STATE_MASK);
-
-	/* Clearing all the CAM interrupt */
-	writel_relaxed(0x1F, tsc_device->base + TSC_IRQ_CLR);
-
-	/* Disabling all cam interrupts (enable is done at - open) */
-	writel_relaxed(0x00, tsc_device->base + TSC_IRQ_ENA);
-
-	/* Disabling HW polling */
-	writel_relaxed(0x00, tsc_device->base + TSC_CIP_CFG);
-
-	/* Reset state - address for read/write buffer */
-	writel_relaxed(0x00000000, tsc_device->base + TSC_RD_BUFF_ADDR);
-	writel_relaxed(0x00000000, tsc_device->base + TSC_WR_BUFF_ADDR);
-
-	/* Clearing false cd counter */
-	writel_relaxed(0x01, tsc_device->base + TSC_FALSE_CD_CLR);
-	writel_relaxed(0x00, tsc_device->base + TSC_FALSE_CD_CLR);
-
-	/* Disabling TSIF out to cicam and IO read/write with the CAM */
-	writel_relaxed(0x00000000, tsc_device->base + TSC_CICAM_TSIF);
-}
-
-/**
- * tsc_disable_tsifs() - Disable all the TSC Tsifs.
- *
- * Disable the TSIFs of the ext. demods, the int. demod and the cam on both
- * directions.
- */
-static void tsc_disable_tsifs(void)
-{
-	u32 reg;
-
-	/* Ext. TSIFs */
-	reg = readl_relaxed(tsc_device->base + TSC_IN_IFC_EXT);
-	SET_BIT(TSIF_DISABLE_OFFS, reg);
-	SET_BIT((TSIF_DISABLE_OFFS + 16), reg);
-	writel_relaxed(reg, tsc_device->base + TSC_IN_IFC_EXT);
-
-	/* Int. TSIF and TSIF-in from the CAM */
-	reg = readl_relaxed(tsc_device->base + TSC_IN_IFC_CFG_INT);
-	SET_BIT(TSIF_DISABLE_OFFS, reg);
-	SET_BIT((TSIF_DISABLE_OFFS + 16), reg);
-	writel_relaxed(reg, tsc_device->base + TSC_IN_IFC_CFG_INT);
-}
-
-/**
- * tsc_power_on_clocks() - power-on the TSC clocks.
- *
- * Power-on the TSC clocks required for Mux and/or CI operations.
- *
- * Return 0 on success, error value otherwise.
- */
-static int tsc_power_on_clocks(void)
-{
-	int ret = 0;
-	unsigned long rate_in_hz = 0;
-
-	/* Enabling the clocks */
-	ret = clk_prepare_enable(tsc_device->ahb_clk);
-	if (ret != 0) {
-		pr_err("%s: Can't start tsc_ahb_clk", __func__);
-		return ret;
-	}
-
-	/* We need to set the rate of ci clock before enabling it */
-	rate_in_hz = clk_round_rate(tsc_device->ci_clk, 1);
-	if (clk_set_rate(tsc_device->ci_clk, rate_in_hz)) {
-		pr_err("%s: Failed to set rate to tsc_ci clock\n", __func__);
-		goto err;
-	}
-
-	ret = clk_prepare_enable(tsc_device->ci_clk);
-	if (ret != 0) {
-		pr_err("%s: Can't start tsc_ci_clk", __func__);
-		goto err;
-	}
-
-	return ret;
-err:
-	clk_disable_unprepare(tsc_device->ahb_clk);
-	return ret;
-}
-
-/**
- * tsc_power_off_clocks() - power-off the TSC clocks.
- *
- * Power-off the TSC clocks required for Mux and/or CI operations.
- */
-static void tsc_power_off_clocks(void)
-{
-	clk_disable_unprepare(tsc_device->ahb_clk);
-	clk_disable_unprepare(tsc_device->ci_clk);
-}
-
-/**
- * tsc_mux_power_on_clocks() - power-on the TSC Mux clocks.
- *
- * Power-on the TSC clocks required only for Mux operations, and not for CI.
- *
- * Return 0 on success, error value otherwise.
- */
-static int tsc_mux_power_on_clocks(void)
-{
-	int ret = 0;
-
-	/* Setting the cicam clock rate */
-	ret = clk_set_rate(tsc_device->cicam_ts_clk, CICAM_CLK_RATE_7MHZ);
-	if (ret != 0) {
-		pr_err("%s: Can't set rate for tsc_cicam_ts_clk", __func__);
-		goto err_set_rate;
-	}
-
-	/* Setting the TSC serial clock rate */
-	ret = clk_set_rate(tsc_device->ser_clk, TSC_SER_CLK_RATE);
-	if (ret != 0) {
-		pr_err("%s: Can't set rate for tsc serial clock", __func__);
-		goto err_set_rate;
-	}
-
-	/* Setting the TSC parallel clock rate */
-	ret = clk_set_rate(tsc_device->par_clk, TSC_PAR_CLK_RATE);
-	if (ret != 0) {
-		pr_err("%s: Can't set rate for tsc parallel clock", __func__);
-		goto err_set_rate;
-	}
-
-	/* Enabling the clocks */
-	ret = clk_prepare_enable(tsc_device->ser_clk);
-	if (ret != 0) {
-		pr_err("%s: Can't start tsc_ser_clk", __func__);
-		goto err_ser_clk;
-	}
-	ret = clk_prepare_enable(tsc_device->par_clk);
-	if (ret != 0) {
-		pr_err("%s: Can't start tsc_par_clk", __func__);
-		goto err_par_clk;
-	}
-	ret = clk_prepare_enable(tsc_device->cicam_ts_clk);
-	if (ret != 0) {
-		pr_err("%s: Can't start tsc_cicam_ts_clk", __func__);
-		goto err_cicam_ts_clk;
-	}
-
-	return ret;
-
-err_cicam_ts_clk:
-	clk_disable_unprepare(tsc_device->par_clk);
-err_par_clk:
-	clk_disable_unprepare(tsc_device->ser_clk);
-err_ser_clk:
-err_set_rate:
-	return ret;
-}
-
-/**
- * tsc_mux_power_off_clocks() - power-off the TSC Mux clocks.
- *
- * Power-off the TSC clocks required only for Mux operations, and not for CI.
- */
-static void tsc_mux_power_off_clocks(void)
-{
-	clk_disable_unprepare(tsc_device->ser_clk);
-	clk_disable_unprepare(tsc_device->par_clk);
-	clk_disable_unprepare(tsc_device->cicam_ts_clk);
-}
-
-/**
- * tsc_device_power_up() - Power init done by the first device opened.
- *
- * Check if it's the first device and enable the GDSC,power-on the TSC clocks
- * required for both Mux and CI, Vote for the bus and reset the registers to a
- * known default values.
- *
- * Return 0 on success, error value otherwise.
- */
-static int tsc_device_power_up(void)
-{
-	int ret = 0;
-
-	if (mutex_lock_interruptible(&tsc_device->mutex))
-		return -ERESTARTSYS;
-
-	if (tsc_device->num_device_open > 0)
-		goto not_first_device;
-
-	/* Enable the GDSC */
-	ret = regulator_enable(tsc_device->gdsc);
-	if (ret != 0) {
-		pr_err("%s: Failed to enable regulator\n", __func__);
-		goto err_regulator;
-	}
-
-	/* Power-on the clocks needed by Mux and CI */
-	ret = tsc_power_on_clocks();
-	if (ret != 0)
-		goto err_power_clocks;
-
-	/* Voting for bus bandwidth */
-	if (tsc_device->bus_client) {
-		ret = msm_bus_scale_client_update_request
-				(tsc_device->bus_client, 1);
-		if (ret) {
-			pr_err("%s: Can't enable bus\n", __func__);
-			goto err_bus;
-		}
-	}
-
-	/* Reset the TSC TLMM pins to a default state */
-	ret = pinctrl_select_state(tsc_device->pinctrl_info.pinctrl,
-			tsc_device->pinctrl_info.disable);
-	if (ret != 0) {
-		pr_err("%s: Failed to disable the TLMM pins\n", __func__);
-		goto err_pinctrl;
-	}
-	/* Update the current pinctrl state in the internal struct */
-	tsc_device->pinctrl_info.curr_state.ts0 = false;
-	tsc_device->pinctrl_info.curr_state.ts1 = false;
-	tsc_device->pinctrl_info.curr_state.pcmcia_state =
-			TSC_CICAM_PERSONALITY_DISABLE;
-
-	/* Reset TSC registers to a default known state */
-	tsc_reset_registers();
-
-not_first_device:
-	tsc_device->num_device_open++;
-	mutex_unlock(&tsc_device->mutex);
-	return ret;
-
-err_pinctrl:
-	if (tsc_device->bus_client)
-		msm_bus_scale_client_update_request(tsc_device->bus_client, 0);
-err_bus:
-	tsc_power_off_clocks();
-err_power_clocks:
-	regulator_disable(tsc_device->gdsc);
-err_regulator:
-	mutex_unlock(&tsc_device->mutex);
-	return ret;
-}
-
-/**
- * tsc_device_power_off() - Power off done by the last device closed.
- *
- * Check if it's the last device and unvote the bus, power-off the TSC clocks
- * required for both Mux and CI, disable the TLMM pins and disable the GDSC.
- */
-static void tsc_device_power_off(void)
-{
-	mutex_lock(&tsc_device->mutex);
-
-	if (tsc_device->num_device_open > 1)
-		goto not_last_device;
-
-	pinctrl_select_state(tsc_device->pinctrl_info.pinctrl,
-			tsc_device->pinctrl_info.disable);
-	if (tsc_device->bus_client)
-		msm_bus_scale_client_update_request(tsc_device->bus_client, 0);
-
-	tsc_power_off_clocks();
-	regulator_disable(tsc_device->gdsc);
-
-not_last_device:
-	tsc_device->num_device_open--;
-	mutex_unlock(&tsc_device->mutex);
-}
-
-
-/************************** TSC file operations **************************/
-/**
- * tsc_mux_open() - init the TSC Mux char device.
- *
- * @inode:	The inode associated with the TSC Mux device.
- * @flip:	The file pointer associated with the TSC Mux device.
- *
- * Enables only one open Mux device.
- * Init all the data structures and vote for all the power resources needed.
- * Manage reference counters for initiating resources upon first open.
- *
- * Return 0 on success, error value otherwise.
- */
-static int tsc_mux_open(struct inode *inode, struct file *filp)
-{
-	struct tsc_mux_chdev *tsc_mux;
-	int ret = 0;
-	u32 ena_reg;
-
-	if (mutex_lock_interruptible(&tsc_device->mux_chdev.mutex))
-		return -ERESTARTSYS;
-
-	if (tsc_device->num_mux_opened > 0) {
-		pr_err("%s: Too many devices open\n", __func__);
-		mutex_unlock(&tsc_device->mux_chdev.mutex);
-		return -EMFILE;
-	}
-	tsc_device->num_mux_opened++;
-
-	tsc_mux = container_of(inode->i_cdev, struct tsc_mux_chdev, cdev);
-	filp->private_data = tsc_mux;
-
-	/* Init all resources if it's the first device (checked inside) */
-	ret = tsc_device_power_up();
-	if (ret != 0)
-		goto err_first_device;
-
-	/* Power-on the Mux clocks */
-	ret = tsc_mux_power_on_clocks();
-	if (ret != 0)
-		goto err_mux_clocks;
-
-	/* Init TSC Mux args */
-	spin_lock_init(&tsc_mux->spinlock);
-	init_waitqueue_head(&tsc_mux->poll_queue);
-	tsc_mux->rate_interrupt = false;
-
-	/* Enabling TSC Mux cam interrupt of rate mismatch */
-	ena_reg = readl_relaxed(tsc_device->base + TSC_IRQ_ENA);
-	SET_BIT(CAM_IRQ_RATE_MISMATCH_OFFS, ena_reg);
-	writel_relaxed(ena_reg, tsc_device->base + TSC_IRQ_ENA);
-
-	mutex_unlock(&tsc_device->mux_chdev.mutex);
-
-	return ret;
-
-err_mux_clocks:
-	/* De-init all resources if it's the only device (checked inside) */
-	tsc_device_power_off();
-err_first_device:
-	tsc_device->num_mux_opened--;
-	mutex_unlock(&tsc_device->mux_chdev.mutex);
-	return ret;
-}
-
-/**
- * tsc_ci_open() - init the TSC CI char device.
- *
- * @inode:	The inode associated with the TSC Mux device.
- * @flip:	The file pointer associated with the TSC Mux device.
- *
- * Enables only one open CI device.
- * Init all the data structures and vote for all the power resources needed.
- * Manage reference counters for initiating resources upon first open.
- *
- * Return 0 on success, error value otherwise.
- */
-static int tsc_ci_open(struct inode *inode, struct file *filp)
-{
-	struct tsc_ci_chdev *tsc_ci;
-	int ret = 0;
-	u32 ena_reg;
-
-	if (mutex_lock_interruptible(&tsc_device->ci_chdev.mutex))
-		return -ERESTARTSYS;
-
-	if (tsc_device->num_ci_opened > 0) {
-		pr_err("%s: Too many devices open\n", __func__);
-		mutex_unlock(&tsc_device->ci_chdev.mutex);
-		return -EMFILE;
-	}
-
-	if (!tsc_device->pinctrl_info.is_pcmcia) {
-		pr_err("%s: No pcmcia pinctrl definitions were found in the TSC devicetree\n",
-				__func__);
-		mutex_unlock(&tsc_device->ci_chdev.mutex);
-		return -EPERM;
-	}
-
-	tsc_device->num_ci_opened++;
-
-	tsc_ci = container_of(inode->i_cdev, struct tsc_ci_chdev, cdev);
-	filp->private_data = tsc_ci;
-
-	/* Init all resources if it's the first device (checked inside) */
-	ret = tsc_device_power_up();
-	if (ret != 0)
-		goto err_first_device;
-
-	/* powering-up the tspp2 and VBIF clocks */
-	ret = tsc_power_on_buff_mode_clocks();
-	if (ret != 0)
-		goto err_buff_clocks;
-
-	/* Request reset CAM GPIO */
-	ret = gpio_request(tsc_device->reset_cam_gpio, "tsc_ci_reset");
-	if (ret != 0) {
-		pr_err("%s: Failed to request reset CAM GPIO\n", __func__);
-		goto err_gpio_req;
-	}
-
-	/* Set the reset line to default "no card" state */
-	ret = gpio_direction_output(tsc_device->reset_cam_gpio, 1);
-	if (ret != 0) {
-		pr_err("%s: Failed to assert the reset CAM GPIO\n", __func__);
-		goto err_assert;
-	}
-
-	/* Attach the iommu group to support the required memory mapping */
-	if (!tsc_iommu_bypass) {
-		ret = iommu_attach_group(tsc_device->iommu_info.domain,
-				tsc_device->iommu_info.group);
-		if (ret != 0) {
-			pr_err("%s: iommu_attach_group failed\n", __func__);
-			goto err_iommu_attach;
-		}
-	}
-
-	/* Init TSC CI args */
-	spin_lock_init(&tsc_ci->spinlock);
-	init_waitqueue_head(&tsc_ci->poll_queue);
-	tsc_ci->transaction_state = BEFORE_TRANSACTION;
-	tsc_ci->data_busy = false;
-	tsc_device->card_power = false;
-
-	/*
-	 * Init hw card status flag according to the pins' state.
-	 * No need to protect from interrupt because the handler is not
-	 * registred yet.
-	 */
-	tsc_update_hw_card_status();
-	tsc_ci->card_status = tsc_device->hw_card_status;
-
-	/* If a card is already inserted - need to power up the card */
-	if (tsc_device->hw_card_status == TSC_CARD_STATUS_DETECTED) {
-		ret = tsc_card_power_up();
-		if (ret != 0)
-			pr_err("%s: card power-up failed\n", __func__);
-		else
-			tsc_device->card_power = true;
-	}
-
-	/* Enabling the TSC CI cam interrupts: EOT and Err */
-	ena_reg = readl_relaxed(tsc_device->base + TSC_IRQ_ENA);
-	SET_BIT(CAM_IRQ_EOT_OFFS, ena_reg);
-	SET_BIT(CAM_IRQ_ERR_OFFS, ena_reg);
-	writel_relaxed(ena_reg, tsc_device->base + TSC_IRQ_ENA);
-
-	/* Registering the CAM cmd interrupt handler */
-	ret = request_irq(tsc_device->cam_cmd_irq, tsc_cam_cmd_irq_handler,
-			IRQF_SHARED, dev_name(&tsc_device->pdev->dev),
-			tsc_device);
-	if (ret) {
-		pr_err("%s: failed to request TSC IRQ %d : %d",
-				__func__, tsc_device->cam_cmd_irq, ret);
-		goto err_cam_irq;
-	}
-
-	/*
-	 * Registering the card detect interrupt handler (this interrupt is
-	 * enabled by default, right after this registration)
-	 */
-	ret = request_threaded_irq(tsc_device->card_detection_irq,
-			NULL, tsc_card_detect_irq_thread_handler,
-			IRQF_ONESHOT | IRQF_TRIGGER_RISING,
-			dev_name(&tsc_device->pdev->dev), tsc_device);
-	if (ret) {
-		pr_err("%s: failed to request TSC IRQ %d : %d",
-				__func__, tsc_device->card_detection_irq, ret);
-		goto err_card_irq;
-	}
-
-	mutex_unlock(&tsc_device->ci_chdev.mutex);
-
-	return ret;
-
-err_card_irq:
-	free_irq(tsc_device->cam_cmd_irq, tsc_device);
-err_cam_irq:
-	if (!tsc_iommu_bypass)
-		iommu_detach_group(tsc_device->iommu_info.domain,
-				tsc_device->iommu_info.group);
-err_iommu_attach:
-	gpio_free(tsc_device->reset_cam_gpio);
-err_assert:
-err_gpio_req:
-	tsc_power_off_buff_mode_clocks();
-err_buff_clocks:
-	/* De-init all resources if it's the only device (checked inside) */
-	tsc_device_power_off();
-err_first_device:
-	tsc_device->num_ci_opened--;
-	mutex_unlock(&tsc_device->ci_chdev.mutex);
-	return ret;
-}
-
-/**
- * tsc_mux_release() - Release and close the TSC Mux char device.
- *
- * @inode:	The inode associated with the TSC Mux device.
- * @flip:	The file pointer associated with the TSC Mux device.
- *
- * Release all the resources allocated for the Mux device and unvote power
- * resources.
- *
- * Return 0 on success, error value otherwise.
- */
-static int tsc_mux_release(struct inode *inode, struct file *filp)
-{
-	struct tsc_mux_chdev *tsc_mux;
-	u32 ena_reg;
-
-	tsc_mux = filp->private_data;
-	if (!tsc_mux)
-		return -EINVAL;
-
-	mutex_lock(&tsc_mux->mutex);
-
-	tsc_mux_power_off_clocks();
-
-	/* Disable the TSIFs */
-	tsc_disable_tsifs();
-	/* Disabling rate mismatch interrupt */
-	ena_reg = readl_relaxed(tsc_device->base + TSC_IRQ_ENA);
-	CLEAR_BIT(CAM_IRQ_RATE_MISMATCH_OFFS, ena_reg);
-	writel_relaxed(ena_reg, tsc_device->base + TSC_IRQ_ENA);
-
-	tsc_device_power_off();
-
-	tsc_device->num_mux_opened--;
-	mutex_unlock(&tsc_mux->mutex);
-
-	return 0;
-}
-
-/**
- * tsc_ci_release() - Release and close the TSC CI char device.
- *
- * @inode:	The inode associated with the TSC CI device.
- * @flip:	The file pointer associated with the TSC CI device.
- *
- * Release all the resources allocated for the CI device and unvote power
- * resources.
- *
- * Return 0 on success, error value otherwise.
- */
-static int tsc_ci_release(struct inode *inode, struct file *filp)
-{
-	struct tsc_ci_chdev *tsc_ci;
-	u32 ena_reg;
-	int ret;
-
-	tsc_ci = filp->private_data;
-	if (!tsc_ci)
-		return -EINVAL;
-
-	mutex_lock(&tsc_ci->mutex);
-
-	/* If in the middle of a data transaction- wake-up completion */
-	if (tsc_ci->data_busy) {
-		/* Closing the device is similar in behavior to card removal */
-		tsc_ci->transaction_state = TRANSACTION_CARD_REMOVED;
-		mutex_unlock(&tsc_ci->mutex);
-		complete_all(&tsc_ci->transaction_complete);
-		wait_for_completion(&tsc_ci->transaction_finish);
-		mutex_lock(&tsc_ci->mutex);
-	}
-
-	/* clearing EOT and ERR interrupts */
-	ena_reg = readl_relaxed(tsc_device->base + TSC_IRQ_ENA);
-	CLEAR_BIT(CAM_IRQ_EOT_OFFS, ena_reg);
-	CLEAR_BIT(CAM_IRQ_ERR_OFFS, ena_reg);
-	writel_relaxed(ena_reg, tsc_device->base + TSC_IRQ_ENA);
-
-	/* Cancel the  interrupt handlers registration */
-	free_irq(tsc_device->card_detection_irq, tsc_device);
-	free_irq(tsc_device->cam_cmd_irq, tsc_device);
-
-	/* power down the card interface if it's currently powered up */
-	if (tsc_device->hw_card_status == TSC_CARD_STATUS_DETECTED &&
-			tsc_device->card_power) {
-		ret = tsc_card_power_down();
-		if (ret != 0)
-			pr_err("%s: card power-down failed\n", __func__);
-	}
-
-	if (!tsc_iommu_bypass)
-		iommu_detach_group(tsc_device->iommu_info.domain,
-				tsc_device->iommu_info.group);
-
-	gpio_free(tsc_device->reset_cam_gpio);
-
-	tsc_power_off_buff_mode_clocks();
-	tsc_device_power_off();
-
-	tsc_device->num_ci_opened--;
-	mutex_unlock(&tsc_ci->mutex);
-
-	return 0;
-}
-
-/**
- * tsc_mux_poll() - Perform polling on a designated wait-queue.
- *
- * @flip:	The file pointer associated with the TSC Mux device.
- * @p:		The poll-table struct of the kernel.
- *
- * Add the TSC Mux wait-queue to the poll-table. Poll until a rate mismatch
- * interrupt is received.
- *
- * Return 0 on success, error value otherwise.
- */
-static unsigned int tsc_mux_poll(struct file *filp, struct poll_table_struct *p)
-{
-	unsigned long flags;
-	unsigned int mask = 0;
-	struct tsc_mux_chdev *tsc_mux;
-
-	tsc_mux = filp->private_data;
-	if (!tsc_mux)
-		return -EINVAL;
-
-	/* register the wait queue for rate mismatch interrupt */
-	poll_wait(filp, &tsc_mux->poll_queue, p);
-
-	/* Setting the mask upon rate mismatch irq and clearing the flag */
-	spin_lock_irqsave(&tsc_mux->spinlock, flags);
-	if (tsc_mux->rate_interrupt) {
-		mask = POLLPRI;
-		tsc_mux->rate_interrupt = false;
-	}
-	spin_unlock_irqrestore(&tsc_mux->spinlock, flags);
-
-	return mask;
-}
-
-/**
- * tsc_ci_poll() - Perform polling on a designated wait-queue.
- *
- * @flip:	The file pointer associated with the TSC CI device.
- * @p:		The poll-table struct of the kernel.
- *
- * Add the TSC Mux wait-queue to the poll-table. Poll until a card detection
- * interrupt is received.
- *
- * Return 0 on success, error value otherwise.
- */
-static unsigned int tsc_ci_poll(struct file *filp, struct poll_table_struct *p)
-{
-	unsigned int mask = 0;
-
-	struct tsc_ci_chdev *tsc_ci = filp->private_data;
-	if (!tsc_ci)
-		return -EINVAL;
-
-	/* Register the wait queue for card detection interrupt */
-	poll_wait(filp, &tsc_ci->poll_queue, p);
-
-	/* Setting the mask upon card detect irq and update ci card state */
-	if (mutex_lock_interruptible(&tsc_ci->mutex))
-		return -ERESTARTSYS;
-	if (tsc_ci->card_status != tsc_device->hw_card_status) {
-		mask = POLLPRI;
-		tsc_ci->card_status = tsc_device->hw_card_status;
-	}
-	mutex_unlock(&tsc_ci->mutex);
-
-	return mask;
-}
-
-/**
- * tsc_mux_ioctl() - Handle IOCTLs sent from user-space application.
- *
- * @flip:	The file pointer associated with the TSC Mux device.
- * @cmd:	The IOCTL code sent
- * @arg:	The IOCTL argument (if the IOCTL receives an argument)
- *
- * Verify the validity of the IOCTL sent and handle it by updating the
- * appropriate register or calling a function that handle the IOCTL operation.
- *
- * Return 0 on success, error value otherwise.
- */
-static long tsc_mux_ioctl(struct file *filp,
-		unsigned int cmd,
-		unsigned long arg)
-{
-	int ret = 0;
-	struct tsc_mux_chdev *tsc_mux;
-	struct tsc_route tsc_route;
-	struct tsc_tsif_params tsif_params;
-
-	tsc_mux = filp->private_data;
-	if (!tsc_mux)
-		return -EINVAL;
-
-	if (mutex_lock_interruptible(&tsc_mux->mutex))
-		return -ERESTARTSYS;
-
-	switch (cmd) {
-	case TSC_CONFIG_ROUTE:
-		if (!arg || copy_from_user(&tsc_route, (void *)arg,
-				sizeof(struct tsc_route))) {
-			ret = -EFAULT;
-			goto err;
-		}
-		ret = tsc_route_mux(tsc_mux, tsc_route.source, tsc_route.dest);
-		break;
-	case TSC_ENABLE_INPUT:
-		ret = tsc_enable_disable_tsif(tsc_mux, arg, TSIF_INPUT_ENABLE);
-		break;
-	case TSC_DISABLE_INPUT:
-		ret = tsc_enable_disable_tsif(tsc_mux, arg, TSIF_INPUT_DISABLE);
-		break;
-	case TSC_SET_TSIF_CONFIG:
-		if (!arg || copy_from_user(&tsif_params, (void *)arg,
-				sizeof(struct tsc_tsif_params))) {
-			ret = -EFAULT;
-			goto err;
-		}
-		ret = tsc_config_tsif(tsc_mux, &tsif_params);
-		break;
-	case TSC_CLEAR_RATE_MISMATCH_IRQ:
-		tsc_enable_rate_irq(tsc_mux);
-		break;
-	case TSC_CICAM_SET_CLOCK:
-		ret = tsc_set_cicam_clk(arg);
-		break;
-	default:
-		ret = -EINVAL;
-		pr_err("%s: Unknown ioctl %i", __func__, cmd);
-	}
-
-err:
-	mutex_unlock(&tsc_mux->mutex);
-	return ret;
-}
-
-/**
- * tsc_ci_ioctl() - Handle IOCTLs sent from user-space application.
- *
- * @flip:	The file pointer associated with the TSC CI device.
- * @cmd:	The IOCTL code sent
- * @arg:	The IOCTL argument (if the IOCTL receives an argument)
- *
- * Verify the validity of the IOCTL sent and handle it by updating the
- * appropriate register or calling a function that handle the IOCTL operation.
- *
- * Return 0 on success, error value otherwise.
- */
-static long tsc_ci_ioctl(struct file *filp,
-		unsigned int cmd,
-		unsigned long arg)
-{
-	int ret = 0;
-	struct tsc_ci_chdev *tsc_ci;
-	unsigned long flags;
-
-	tsc_ci = filp->private_data;
-	if (!tsc_ci)
-		return -EINVAL;
-
-	if (mutex_lock_interruptible(&tsc_ci->mutex))
-		return -ERESTARTSYS;
-
-	switch (cmd) {
-
-	case TSC_CAM_RESET:
-		ret = tsc_reset_cam();
-		break;
-	case TSC_CICAM_PERSONALITY_CHANGE:
-		ret = tsc_personality_change(arg);
-		break;
-	case TSC_GET_CARD_STATUS:
-		spin_lock_irqsave(&tsc_ci->spinlock, flags);
-		tsc_ci->card_status = tsc_device->hw_card_status;
-		ret = __put_user(tsc_ci->card_status,
-				(enum tsc_card_status __user *)arg);
-		spin_unlock_irqrestore(&tsc_ci->spinlock, flags);
-		break;
-	case TSC_READ_CAM_MEMORY:
-		ret = tsc_data_transaction(tsc_ci, MEMORY_TRANSACTION,
-				READ_TRANSACTION, SINGLE_BYTE_MODE, arg);
-		break;
-	case TSC_WRITE_CAM_MEMORY:
-		ret = tsc_data_transaction(tsc_ci, MEMORY_TRANSACTION,
-				WRITE_TRANSACTION, SINGLE_BYTE_MODE, arg);
-		break;
-	case TSC_READ_CAM_IO:
-		ret = tsc_data_transaction(tsc_ci, IO_TRANSACTION,
-				READ_TRANSACTION, SINGLE_BYTE_MODE, arg);
-		break;
-	case TSC_WRITE_CAM_IO:
-		ret = tsc_data_transaction(tsc_ci, IO_TRANSACTION,
-				WRITE_TRANSACTION, SINGLE_BYTE_MODE, arg);
-		break;
-	case TSC_READ_CAM_BUFFER:
-		ret = tsc_data_transaction(tsc_ci, IO_TRANSACTION,
-				READ_TRANSACTION, BUFFER_MODE, arg);
-		break;
-	case TSC_WRITE_CAM_BUFFER:
-		ret = tsc_data_transaction(tsc_ci, IO_TRANSACTION,
-				WRITE_TRANSACTION, BUFFER_MODE, arg);
-		break;
-	default:
-		ret = -EINVAL;
-		pr_err("%s: Unknown ioctl %i\n", __func__, cmd);
-	}
-
-	mutex_unlock(&tsc_ci->mutex);
-	return ret;
-}
-
-/************************** Probe helper-functions **************************/
-/**
- * tsc_init_char_driver() - Initialize a character driver.
- *
- * @pcdev:		A pointer to the cdev structure to initialize.
- * @pfops:		A pointer to the file_operations for this device.
- * @device_number:	A pointer that will store the device number.
- * @device:		A pointer that will store the new device upon success.
- * @name:		A string for the device's name.
- *
- * Create a new character device driver inside the TSC class. The new device
- * is created under "/dev/<name>0".
- *
- * Return 0 on success, error value otherwise.
- */
-static int tsc_init_char_driver(struct cdev *pcdev,
-		const struct file_operations *pfops,
-		dev_t *pdevice_number,
-		struct device *pdevice,
-		const char *name)
-{
-	int ret = 0;
-
-	/* Allocate device number for the char device driver */
-	ret = alloc_chrdev_region(pdevice_number, 0, 1, name);
-	if (ret) {
-		pr_err("%s: alloc_chrdev_region failed: %d\n",  name, ret);
-		goto err_devrgn;
-	}
-
-	/* initializing the char device structures with file operations */
-	cdev_init(pcdev, pfops);
-	pcdev->owner = THIS_MODULE;
-
-	/* adding the char device structures to the VFS */
-	ret = cdev_add(pcdev, *pdevice_number, 1);
-	if (ret != 0) {
-		pr_err("%s%d: cdev_add failed\n", name, MINOR(*pdevice_number));
-		goto err_cdev_add;
-	}
-
-	/* create the char devices under "/dev/" and register them to sysfs */
-	pdevice = device_create(tsc_class, NULL, pcdev->dev, NULL, "%s%d", name,
-			MINOR(*pdevice_number));
-	if (IS_ERR(pdevice)) {
-		pr_err("%s%d device_create failed\n", name,
-				MINOR(*pdevice_number));
-		ret = PTR_ERR(pdevice); /* PTR_ERR return -ENOMEM */
-		goto err_device_create;
-	}
-
-	return  ret;
-
-err_device_create:
-	cdev_del(pcdev);
-err_cdev_add:
-	unregister_chrdev_region(*pdevice_number, 1);
-err_devrgn:
-	return ret;
-}
-
-/**
- * tsc_get_pinctrl() - Get the TSC pinctrl definitions.
- *
- * @pdev:	A pointer to the TSC platform device.
- *
- * Get the pinctrl states' handles from the device tree. The function doesn't
- * enforce wrong pinctrl definitions, i.e. it's the client's responsibility to
- * define all the necessary states for the board being used.
- *
- * Return 0 on success, error value otherwise.
- */
-static int tsc_get_pinctrl(struct platform_device *pdev)
-{
-	struct pinctrl *pinctrl;
-
-	pinctrl = devm_pinctrl_get(&pdev->dev);
-	if (IS_ERR(pinctrl)) {
-		pr_err("%s: Unable to get pinctrl handle\n", __func__);
-		return -EINVAL;
-	}
-	tsc_device->pinctrl_info.pinctrl = pinctrl;
-
-	/* get all the states handles */
-	tsc_device->pinctrl_info.disable =
-			pinctrl_lookup_state(pinctrl, "disable");
-	tsc_device->pinctrl_info.ts0 =
-			pinctrl_lookup_state(pinctrl, "ts-in-0");
-	tsc_device->pinctrl_info.ts1 =
-			pinctrl_lookup_state(pinctrl, "ts-in-1");
-	tsc_device->pinctrl_info.dual_ts =
-			pinctrl_lookup_state(pinctrl, "dual-ts");
-	tsc_device->pinctrl_info.pc_card =
-			pinctrl_lookup_state(pinctrl, "pc-card");
-	tsc_device->pinctrl_info.ci_card =
-			pinctrl_lookup_state(pinctrl, "ci-card");
-	tsc_device->pinctrl_info.ci_plus =
-			pinctrl_lookup_state(pinctrl, "ci-plus");
-	tsc_device->pinctrl_info.ts0_pc_card =
-			pinctrl_lookup_state(pinctrl, "ts-in-0-pc-card");
-	tsc_device->pinctrl_info.ts0_ci_card =
-			pinctrl_lookup_state(pinctrl, "ts-in-0-ci-card");
-	tsc_device->pinctrl_info.ts0_ci_plus =
-			pinctrl_lookup_state(pinctrl, "ts-in-0-ci-plus");
-	tsc_device->pinctrl_info.ts1_pc_card =
-			pinctrl_lookup_state(pinctrl, "ts-in-1-pc-card");
-	tsc_device->pinctrl_info.ts1_ci_card =
-			pinctrl_lookup_state(pinctrl, "ts-in-1-ci-card");
-	tsc_device->pinctrl_info.ts1_ci_plus =
-			pinctrl_lookup_state(pinctrl, "ts-in-1-ci-plus");
-	tsc_device->pinctrl_info.dual_ts_pc_card =
-			pinctrl_lookup_state(pinctrl, "dual-ts-pc-card");
-	tsc_device->pinctrl_info.dual_ts_ci_card =
-			pinctrl_lookup_state(pinctrl, "dual-ts-ci-card");
-	tsc_device->pinctrl_info.dual_ts_ci_plus =
-			pinctrl_lookup_state(pinctrl, "dual-ts-ci-plus");
-
-	if (IS_ERR(tsc_device->pinctrl_info.disable)) {
-		pr_err("%s: Unable to get pinctrl disable state handle\n",
-				__func__);
-		return -EINVAL;
-	}
-
-	/* Basic checks to inquire what pinctrl states are available */
-	if (IS_ERR(tsc_device->pinctrl_info.ts0))
-		tsc_device->pinctrl_info.is_ts0 = false;
-	else
-		tsc_device->pinctrl_info.is_ts0 = true;
-
-	if (IS_ERR(tsc_device->pinctrl_info.ts1))
-		tsc_device->pinctrl_info.is_ts1 = false;
-	else
-		tsc_device->pinctrl_info.is_ts1 = true;
-
-	if (IS_ERR(tsc_device->pinctrl_info.pc_card) ||
-			IS_ERR(tsc_device->pinctrl_info.ci_card) ||
-			IS_ERR(tsc_device->pinctrl_info.ci_plus))
-		tsc_device->pinctrl_info.is_pcmcia = false;
-	else
-		tsc_device->pinctrl_info.is_pcmcia = true;
-
-	return 0;
-}
-
-/**
- * tsc_get_regulator_bus() - Get the TSC regulator and register the bus client.
- *
- * @pdev:	A pointer to the TSC platform device.
- *
- * Return 0 on success, error value otherwise.
- */
-static int tsc_get_regulator_bus(struct platform_device *pdev)
-{
-	struct msm_bus_scale_pdata *tsc_bus_pdata = NULL;
-
-	/* Reading the GDSC info */
-	tsc_device->gdsc = devm_regulator_get(&pdev->dev, "vdd");
-	if (IS_ERR(tsc_device->gdsc)) {
-		dev_err(&pdev->dev, "%s: Failed to get vdd power regulator\n",
-				__func__);
-		return PTR_ERR(tsc_device->gdsc);
-	}
-
-	/* Reading the bus platform data */
-	tsc_bus_pdata = msm_bus_cl_get_pdata(pdev);
-	if (tsc_bus_pdata == NULL) {
-		dev_err(&pdev->dev, "%s: Could not find the bus property. Continue anyway...\n",
-				__func__);
-	}
-
-	/* Register the bus client */
-	if (tsc_bus_pdata) {
-		tsc_device->bus_client =
-				msm_bus_scale_register_client(tsc_bus_pdata);
-		if (!tsc_device->bus_client) {
-			dev_err(&pdev->dev, "%s: Unable to register bus client\n",
-					__func__);
-			goto err;
-		}
-	}
-
-	return 0;
-err:
-	devm_regulator_put(tsc_device->gdsc);
-	return -EINVAL;
-}
-
-/**
- * tsc_get_irqs() - Get the TSC IRQ numbers and map the cam irq.
- *
- * @pdev:	A pointer to the TSC platform device.
- *
- * Read the irq numbers from the platform device information.
- *
- * Return 0 on success, error value otherwise.
- */
-static int tsc_get_irqs(struct platform_device *pdev)
-{
-	int irq;
-
-	irq = platform_get_irq_byname(pdev, "cam-cmd");
-	if (irq > 0) {
-		tsc_device->cam_cmd_irq = irq;
-	} else {
-		dev_err(&pdev->dev, "%s: Failed to get CAM_CMD IRQ = %d",
-				__func__, irq);
-		goto err;
-	}
-
-	irq = platform_get_irq_byname(pdev, "card-detect");
-	if (irq > 0) {
-		tsc_device->card_detection_irq = irq;
-	} else {
-		dev_err(&pdev->dev, "%s: Failed to get CARD_DETECT IRQ = %d",
-				__func__, irq);
-		goto err;
-	}
-
-	return 0;
-err:
-	tsc_device->cam_cmd_irq = 0;
-	tsc_device->card_detection_irq = 0;
-
-	return -EINVAL;
-}
-
-/**
- * tsc_map_io_memory() - Map memory resources to kernel space.
- *
- * @pdev:	A pointer to the TSC platform device.
- *
- * Return 0 on success, error value otherwise.
- */
-static int tsc_map_io_memory(struct platform_device *pdev)
-{
-	struct resource *registers_mem;
-
-	/* Reading memory resources */
-	registers_mem = platform_get_resource_byname(pdev, IORESOURCE_MEM,
-			"tsc-base");
-	if (!registers_mem) {
-		dev_err(&pdev->dev, "%s: Missing tsc-base MEM resource",
-				__func__);
-		return -EINVAL;
-	}
-
-	tsc_device->base = ioremap(registers_mem->start,
-			resource_size(registers_mem));
-	if (!tsc_device->base) {
-		dev_err(&pdev->dev, "%s: ioremap failed", __func__);
-		return -ENXIO;
-	}
-
-	return 0;
-}
-
-/**
- * tsc_clocks_put() - Put the clocks
- */
-static void tsc_clocks_put(void)
-{
-	if (tsc_device->ahb_clk)
-		clk_put(tsc_device->ahb_clk);
-	if (tsc_device->ci_clk)
-		clk_put(tsc_device->ci_clk);
-	if (tsc_device->ser_clk)
-		clk_put(tsc_device->ser_clk);
-	if (tsc_device->par_clk)
-		clk_put(tsc_device->par_clk);
-	if (tsc_device->cicam_ts_clk)
-		clk_put(tsc_device->cicam_ts_clk);
-	if (tsc_device->tspp2_core_clk)
-		clk_put(tsc_device->tspp2_core_clk);
-	if (tsc_device->vbif_tspp2_clk)
-		clk_put(tsc_device->vbif_tspp2_clk);
-	if (tsc_device->vbif_ahb_clk)
-		clk_put(tsc_device->vbif_ahb_clk);
-	if (tsc_device->vbif_axi_clk)
-		clk_put(tsc_device->vbif_axi_clk);
-
-	tsc_device->ahb_clk = NULL;
-	tsc_device->ci_clk = NULL;
-	tsc_device->ser_clk = NULL;
-	tsc_device->par_clk = NULL;
-	tsc_device->cicam_ts_clk = NULL;
-	tsc_device->tspp2_core_clk = NULL;
-	tsc_device->vbif_tspp2_clk = NULL;
-	tsc_device->vbif_ahb_clk = NULL;
-	tsc_device->vbif_axi_clk = NULL;
-}
-
-/**
- * tsc_clocks_get() - Get the TSC clocks
- *
- * @pdev:	A pointer to the TSC platform device.
- *
- * Return 0 on success, error value otherwise.
- */
-static int tsc_clocks_get(struct platform_device *pdev)
-{
-	int ret = 0;
-
-	tsc_device->ahb_clk = clk_get(&pdev->dev, "bcc_tsc_ahb_clk");
-	if (IS_ERR(tsc_device->ahb_clk)) {
-		pr_err("%s: Failed to get bcc_tsc_ahb_clk\n", __func__);
-		ret = PTR_ERR(tsc_device->ahb_clk);
-		goto ahb_err;
-	}
-
-	tsc_device->ci_clk = clk_get(&pdev->dev, "bcc_tsc_ci_clk");
-	if (IS_ERR(tsc_device->ci_clk)) {
-		pr_err("%s: Failed to get bcc_tsc_ci_clk\n", __func__);
-		ret = PTR_ERR(tsc_device->ci_clk);
-		goto ci_err;
-	}
-
-	tsc_device->ser_clk = clk_get(&pdev->dev, "bcc_tsc_ser_clk");
-	if (IS_ERR(tsc_device->ser_clk)) {
-		pr_err("%s: Failed to get bcc_tsc_ser_clk\n", __func__);
-		ret = PTR_ERR(tsc_device->ser_clk);
-		goto ser_err;
-	}
-
-	tsc_device->par_clk = clk_get(&pdev->dev, "bcc_tsc_par_clk");
-	if (IS_ERR(tsc_device->par_clk)) {
-		pr_err("%s: Failed to get bcc_tsc_par_clk", __func__);
-		ret = PTR_ERR(tsc_device->par_clk);
-		goto par_err;
-	}
-
-	tsc_device->cicam_ts_clk = clk_get(&pdev->dev, "bcc_tsc_cicam_ts_clk");
-	if (IS_ERR(tsc_device->cicam_ts_clk)) {
-		pr_err("%s: Failed to get bcc_tsc_cicam_ts_clk", __func__);
-		ret = PTR_ERR(tsc_device->cicam_ts_clk);
-		goto cicam_err;
-	}
-
-	tsc_device->tspp2_core_clk = clk_get(&pdev->dev, "bcc_tspp2_core_clk");
-	if (IS_ERR(tsc_device->tspp2_core_clk)) {
-		pr_err("%s: Failed to get bcc_tspp2_core_clk", __func__);
-		ret = PTR_ERR(tsc_device->tspp2_core_clk);
-		goto tspp2_err;
-	}
-
-	tsc_device->vbif_tspp2_clk = clk_get(&pdev->dev, "bcc_vbif_tspp2_clk");
-	if (IS_ERR(tsc_device->vbif_tspp2_clk)) {
-		pr_err("%s: Failed to get bcc_vbif_tspp2_clk", __func__);
-		ret = PTR_ERR(tsc_device->vbif_tspp2_clk);
-		goto vbif_tspp2_err;
-	}
-
-	tsc_device->vbif_ahb_clk = clk_get(&pdev->dev, "iface_vbif_clk");
-	if (IS_ERR(tsc_device->vbif_ahb_clk)) {
-		pr_err("%s: Failed to get bcc_vbif_ahb_clk", __func__);
-		ret = PTR_ERR(tsc_device->vbif_ahb_clk);
-		goto vbif_ahb_err;
-	}
-
-	tsc_device->vbif_axi_clk = clk_get(&pdev->dev, "vbif_core_clk");
-	if (IS_ERR(tsc_device->vbif_axi_clk)) {
-		pr_err("%s: Failed to get bcc_vbif_axi_clk", __func__);
-		ret = PTR_ERR(tsc_device->vbif_axi_clk);
-		goto vbif_axi_err;
-	}
-
-	return ret;
-
-vbif_axi_err:
-	tsc_device->vbif_axi_clk = NULL;
-	clk_put(tsc_device->vbif_ahb_clk);
-vbif_ahb_err:
-	tsc_device->vbif_ahb_clk = NULL;
-	clk_put(tsc_device->vbif_tspp2_clk);
-vbif_tspp2_err:
-	tsc_device->vbif_tspp2_clk = NULL;
-	clk_put(tsc_device->tspp2_core_clk);
-tspp2_err:
-	tsc_device->tspp2_core_clk = NULL;
-	clk_put(tsc_device->cicam_ts_clk);
-cicam_err:
-	tsc_device->cicam_ts_clk = NULL;
-	clk_put(tsc_device->par_clk);
-par_err:
-	tsc_device->par_clk = NULL;
-	clk_put(tsc_device->ser_clk);
-ser_err:
-	tsc_device->ser_clk = NULL;
-	clk_put(tsc_device->ci_clk);
-ci_err:
-	tsc_device->ci_clk = NULL;
-	clk_put(tsc_device->ahb_clk);
-ahb_err:
-	tsc_device->ahb_clk = NULL;
-	return ret;
-}
-
-/**
- * tsc_free_iommu_info() - Free IOMMU information.
- */
-static void tsc_free_iommu_info(void)
-{
-	if (tsc_device->iommu_info.group)  {
-		iommu_group_put(tsc_device->iommu_info.group);
-		tsc_device->iommu_info.group = NULL;
-	}
-
-	if (tsc_device->iommu_info.ion_client) {
-		ion_client_destroy(tsc_device->iommu_info.ion_client);
-		tsc_device->iommu_info.ion_client = NULL;
-	}
-
-	tsc_device->iommu_info.domain = NULL;
-	tsc_device->iommu_info.domain_num = -1;
-	tsc_device->iommu_info.partition_num = -1;
-}
-
-/**
- * tsc_get_iommu_info() - Get IOMMU information.
- *
- * @pdev:	A pointer to the TSC platform device.
- *
- * Return 0 on success, error value otherwise.
- */
-static int tsc_get_iommu_info(struct platform_device *pdev)
-{
-	int ret = 0;
-
-	/* Create a new ION client used by tsc ci to allocate memory */
-	tsc_device->iommu_info.ion_client = msm_ion_client_create("tsc_client");
-	if (IS_ERR_OR_NULL(tsc_device->iommu_info.ion_client)) {
-		pr_err("%s: error in ion_client_create", __func__);
-		ret = PTR_ERR(tsc_device->iommu_info.ion_client);
-		if (!ret)
-			ret = -ENOMEM;
-		tsc_device->iommu_info.ion_client = NULL;
-		goto err_client;
-	}
-
-	/* Find the iommu group by the name obtained from the device tree */
-	tsc_device->iommu_info.group =
-		iommu_group_find(tsc_device->iommu_info.iommu_group_name);
-	if (!tsc_device->iommu_info.group) {
-		pr_err("%s: error in iommu_group_find", __func__);
-		ret = -EINVAL;
-		goto err_group;
-	}
-
-	/* Get the domain associated with the iommu group */
-	tsc_device->iommu_info.domain =
-			iommu_group_get_iommudata(tsc_device->iommu_info.group);
-	if (IS_ERR_OR_NULL(tsc_device->iommu_info.domain)) {
-		pr_err("%s: iommu_group_get_iommudata failed", __func__);
-		ret = -EINVAL;
-		goto err_domain;
-	}
-
-	/* Get the domain number */
-	tsc_device->iommu_info.domain_num =
-			msm_find_domain_no(tsc_device->iommu_info.domain);
-
-	return ret;
-
-err_domain:
-	iommu_group_put(tsc_device->iommu_info.group);
-	tsc_device->iommu_info.group = NULL;
-err_group:
-	ion_client_destroy(tsc_device->iommu_info.ion_client);
-	tsc_device->iommu_info.ion_client = NULL;
-err_client:
-	return ret;
-}
-
-/**
- * tsc_parse_dt() - Parse device-tree data and save it.
- *
- * @pdev:	A pointer to the TSC platform device.
- *
- * Return 0 on success, error value otherwise.
- */
-static int tsc_parse_dt(struct platform_device *pdev)
-{
-	struct device_node *node = pdev->dev.of_node;
-	struct device_node *iommu_pnode;
-	int ret;
-
-	/* Check that power regulator property exist  */
-	if (!of_get_property(node, "vdd-supply", NULL)) {
-		dev_err(&pdev->dev, "%s: Could not find vdd-supply property\n",
-				__func__);
-		return -EINVAL;
-	}
-
-	/* Reading IOMMU group label by obtaining the group's phandle */
-	iommu_pnode = of_parse_phandle(node, "qcom,iommu-group", 0);
-	if (!iommu_pnode) {
-		dev_err(&pdev->dev, "%s: Couldn't find iommu-group property\n",
-				__func__);
-		return -EINVAL;
-	}
-	ret = of_property_read_string(iommu_pnode, "label",
-			&tsc_device->iommu_info.iommu_group_name);
-	of_node_put(iommu_pnode);
-	if (ret) {
-		dev_err(&pdev->dev, "%s: Couldn't find label property of the IOMMU group, err=%d\n",
-				__func__, ret);
-		return -EINVAL;
-	}
-
-	/* Reading IOMMU partition */
-	ret = of_property_read_u32(node, "qcom,iommu-partition",
-			&tsc_device->iommu_info.partition_num);
-	if (ret) {
-		dev_err(&pdev->dev, "%s: Couldn't find iommu-partition property, err=%d\n",
-				__func__, ret);
-		return -EINVAL;
-	}
-
-	/* Reading reset cam gpio */
-	tsc_device->reset_cam_gpio = of_get_named_gpio(node,
-			"qcom,tsc-reset-cam-gpio", 0);
-	if (tsc_device->reset_cam_gpio < 0) {
-		dev_err(&pdev->dev, "%s: Couldn't find qcom,tsc-reset-cam-gpio property\n",
-				__func__);
-		return -EINVAL;
-	}
-
-	return 0;
-}
-
-/* TSC Mux file operations */
-static const struct file_operations tsc_mux_fops = {
-		.owner   = THIS_MODULE,
-		.open    = tsc_mux_open,
-		.poll    = tsc_mux_poll,
-		.release = tsc_mux_release,
-		.unlocked_ioctl   = tsc_mux_ioctl,
-};
-
-/* TSC CI file operations */
-static const struct file_operations tsc_ci_fops = {
-		.owner   = THIS_MODULE,
-		.open    = tsc_ci_open,
-		.poll    = tsc_ci_poll,
-		.release = tsc_ci_release,
-		.unlocked_ioctl   = tsc_ci_ioctl,
-};
-
-
-/************************ Device driver probe function ************************/
-static int msm_tsc_probe(struct platform_device *pdev)
-{
-	int ret;
-
-	tsc_device = kzalloc(sizeof(struct tsc_device), GFP_KERNEL);
-	if (!tsc_device) {
-		pr_err("%s: Unable to allocate memory for struct\n", __func__);
-		return -ENOMEM;
-	}
-
-	/* get information from device tree */
-	if (pdev->dev.of_node) {
-		ret = tsc_parse_dt(pdev);
-		if (ret != 0) {
-			pr_err("%s: devicetree data not available", __func__);
-			ret =  -EINVAL;
-			goto err_dt;
-		}
-	} else { /* else - devicetree is not found */
-		pr_err("%s: devicetree data is missing", __func__);
-		ret =  -EINVAL;
-		goto err_dt;
-	}
-
-	/* set up references */
-	tsc_device->pdev = pdev;
-	platform_set_drvdata(pdev, tsc_device);
-
-	/* init iommu client, group and domain */
-	if (!tsc_iommu_bypass) {
-		ret = tsc_get_iommu_info(pdev);
-		if (ret != 0)
-			return ret;
-	}
-
-	/* Map clocks */
-	ret = tsc_clocks_get(pdev);
-	if (ret != 0)
-		goto err_clocks_get;
-
-	/* map registers memory */
-	ret = tsc_map_io_memory(pdev);
-	if (ret != 0)
-		goto err_map_io;
-
-	/* map irqs */
-	ret = tsc_get_irqs(pdev);
-	if (ret != 0)
-		goto err_map_irqs;
-
-	/* get regulators and bus */
-	ret = tsc_get_regulator_bus(pdev);
-	if (ret != 0)
-		goto err_get_regulator_bus;
-
-	/* get pinctrl */
-	ret = tsc_get_pinctrl(pdev);
-	if (ret != 0)
-		goto err_pinctrl;
-
-	/* creating the tsc device's class */
-	tsc_class = class_create(THIS_MODULE, "tsc");
-	if (IS_ERR(tsc_class)) {
-		ret = PTR_ERR(tsc_class);
-		pr_err("%s: Error creating class: %d\n", __func__, ret);
-		goto err_class;
-	}
-
-	/* Initialize and register mux char device driver */
-	ret = tsc_init_char_driver(&tsc_device->mux_chdev.cdev, &tsc_mux_fops,
-			&tsc_device->mux_device_number, tsc_device->device_mux,
-			"tsc_mux");
-	if (ret != 0)
-		goto err_chdev_mux;
-
-	/* Initialize and register ci char device drivers */
-	ret = tsc_init_char_driver(&tsc_device->ci_chdev.cdev, &tsc_ci_fops,
-			&tsc_device->ci_device_number, tsc_device->device_ci,
-			"tsc_ci");
-	if (ret != 0)
-		goto err_chdev_ci;
-
-	/* Init char device counters */
-	tsc_device->num_device_open = 0;
-	tsc_device->num_mux_opened = 0;
-	tsc_device->num_ci_opened = 0;
-
-	/* Init char device mutexes and completion structs */
-	mutex_init(&tsc_device->mux_chdev.mutex);
-	mutex_init(&tsc_device->ci_chdev.mutex);
-	mutex_init(&tsc_device->mutex);
-	init_completion(&tsc_device->ci_chdev.transaction_complete);
-	init_completion(&tsc_device->ci_chdev.transaction_finish);
-
-	/* Init debugfs support */
-	tsc_debugfs_init();
-
-	return ret;
-
-err_chdev_ci:
-	device_destroy(tsc_class, tsc_device->mux_chdev.cdev.dev);
-	cdev_del(&tsc_device->mux_chdev.cdev);
-err_chdev_mux:
-	class_destroy(tsc_class);
-err_class:
-err_pinctrl:
-	if (tsc_device->bus_client)
-		msm_bus_scale_unregister_client(tsc_device->bus_client);
-
-	devm_regulator_put(tsc_device->gdsc);
-err_get_regulator_bus:
-err_map_irqs:
-	iounmap(tsc_device->base);
-err_map_io:
-	tsc_clocks_put();
-err_clocks_get:
-	tsc_free_iommu_info();
-err_dt:
-	kfree(tsc_device);
-
-	return ret;
-}
-
-/*********************** Device driver remove function ***********************/
-static int msm_tsc_remove(struct platform_device *pdev)
-{
-	/* Removing debugfs support */
-	tsc_debugfs_exit();
-
-	/* Destroying the char device mutexes */
-	mutex_destroy(&tsc_device->mux_chdev.mutex);
-	mutex_destroy(&tsc_device->ci_chdev.mutex);
-
-	/* unregistering and deleting the tsc-ci char device driver*/
-	device_destroy(tsc_class, tsc_device->ci_chdev.cdev.dev);
-	cdev_del(&tsc_device->ci_chdev.cdev);
-
-	/* unregistering and deleting the tsc-mux char device driver*/
-	device_destroy(tsc_class, tsc_device->mux_chdev.cdev.dev);
-	cdev_del(&tsc_device->mux_chdev.cdev);
-
-	/* Unregistering the char devices */
-	unregister_chrdev_region(tsc_device->ci_device_number, 1);
-	unregister_chrdev_region(tsc_device->mux_device_number, 1);
-
-	/* Removing the tsc class*/
-	class_destroy(tsc_class);
-
-	/* Unregister the bus client and the regulator */
-	if (tsc_device->bus_client)
-		msm_bus_scale_unregister_client(tsc_device->bus_client);
-
-	devm_regulator_put(tsc_device->gdsc);
-
-	/* Unmapping the io memory */
-	iounmap(tsc_device->base);
-
-	/* Releasing the clocks */
-	tsc_clocks_put();
-
-	/* Releasing the iommu info */
-	if (!tsc_iommu_bypass)
-		tsc_free_iommu_info();
-
-	/* Releasing the memory allocated for the TSC device struct */
-	kfree(tsc_device);
-
-	return 0;
-}
-
-/*********************** Platform driver information ***********************/
-static struct of_device_id msm_match_table[] = {
-		{.compatible = "qcom,msm-tsc"},
-		{}
-};
-
-static struct platform_driver msm_tsc_driver = {
-		.probe          = msm_tsc_probe,
-		.remove         = msm_tsc_remove,
-		.driver         = {
-		.name   = "msm_tsc",
-		.of_match_table = msm_match_table,
-	},
-};
-
-/**
- * tsc_init() - TSC driver module init function.
- *
- * Return 0 on success, error value otherwise.
- */
-static int __init tsc_init(void)
-{
-	int ret = 0;
-
-	/* register the driver, and check hardware */
-	ret = platform_driver_register(&msm_tsc_driver);
-	if (ret) {
-		pr_err("%s: platform_driver_register failed: %d\n", __func__,
-				ret);
-		return ret;
-	}
-
-	return ret;
-}
-
-/**
- * tsc_exit() - TSC driver module exit function.
- */
-static void __exit tsc_exit(void)
-{
-	platform_driver_unregister(&msm_tsc_driver);
-}
-
-module_init(tsc_init);
-module_exit(tsc_exit);
-
-MODULE_DESCRIPTION("TSC platform device and two char devs: mux and ci");
-MODULE_LICENSE("GPL v2");
diff --git a/drivers/media/platform/msm/broadcast/tspp2.c b/drivers/media/platform/msm/broadcast/tspp2.c
deleted file mode 100644
index 1f51dca..0000000
--- a/drivers/media/platform/msm/broadcast/tspp2.c
+++ /dev/null
@@ -1,8578 +0,0 @@
-/* Copyright (c) 2013-2014, The Linux Foundation. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 and
- * only version 2 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; 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/dma-mapping.h>
-#include <linux/debugfs.h>
-#include <linux/device.h>
-#include <linux/pm_runtime.h>
-#include <linux/pm_wakeup.h>
-#include <linux/platform_device.h>
-#include <linux/msm_ion.h>
-#include <linux/slab.h>
-#include <linux/delay.h>
-#include <linux/of.h>
-#include <linux/list.h>
-#include <linux/mutex.h>
-#include <linux/workqueue.h>
-#include <linux/iommu.h>
-#include <linux/qcom_iommu.h>
-#include <linux/msm_iommu_domains.h>
-#include <linux/msm-bus.h>
-#include <mach/msm_tspp2.h>
-#include <linux/clk/msm-clk.h>
-
-#define TSPP2_MODULUS_OP(val, mod)	((val) & ((mod) - 1))
-
-/* General definitions. Note we're reserving one batch. */
-#define TSPP2_NUM_ALL_INPUTS	(TSPP2_NUM_TSIF_INPUTS + TSPP2_NUM_MEM_INPUTS)
-#define TSPP2_NUM_CONTEXTS		128
-#define TSPP2_NUM_AVAIL_CONTEXTS	127
-#define TSPP2_NUM_HW_FILTERS		128
-#define TSPP2_NUM_BATCHES		15
-#define TSPP2_FILTERS_PER_BATCH		8
-#define TSPP2_NUM_AVAIL_FILTERS	(TSPP2_NUM_HW_FILTERS - TSPP2_FILTERS_PER_BATCH)
-#define TSPP2_NUM_KEYTABLES		32
-#define TSPP2_TSIF_DEF_TIME_LIMIT   15000 /* Number of tsif-ref-clock ticks */
-
-#define TSPP2_NUM_EVENT_WORK_ELEMENTS	256
-
-/*
- * Based on the hardware programming guide, HW requires we wait for up to 2ms
- * before closing the pipes used by the filter.
- * This is required to avoid unexpected pipe reset interrupts.
- */
-#define TSPP2_HW_DELAY_USEC		2000
-
-/*
- * Default source configuration:
- * Sync byte 0x47, check sync byte,
- * Do not monitor scrambling bits,
- * Discard packets with invalid AF,
- * Do not assume duplicates,
- * Do not ignore discontinuity indicator,
- * Check continuity of TS packets.
- */
-#define TSPP2_DEFAULT_SRC_CONFIG	0x47801E49
-
-/*
- * Default memory source configuration:
- * Use 16 batches,
- * Attach last batch to each memory source.
- */
-#define TSPP2_DEFAULT_MEM_SRC_CONFIG	0x80000010
-
-/* Bypass VBIF/IOMMU for debug and bring-up purposes */
-static int tspp2_iommu_bypass;
-module_param(tspp2_iommu_bypass, int, S_IRUGO);
-
-/* Enable Invalid Adaptation Field control bits event */
-static int tspp2_en_invalid_af_ctrl;
-module_param(tspp2_en_invalid_af_ctrl, int, S_IRUGO | S_IWUSR);
-
-/* Enable Invalid Adaptation Field length event */
-static int tspp2_en_invalid_af_length;
-module_param(tspp2_en_invalid_af_length, int, S_IRUGO | S_IWUSR);
-
-/* Enable PES No Sync event */
-static int tspp2_en_pes_no_sync;
-module_param(tspp2_en_pes_no_sync, int, S_IRUGO | S_IWUSR);
-
-/**
- * enum tspp2_operation_opcode - TSPP2 Operation opcode for TSPP2_OPCODE
- */
-enum tspp2_operation_opcode {
-	TSPP2_OPCODE_PES_ANALYSIS = 0x03,
-	TSPP2_OPCODE_RAW_TRANSMIT = 0x07,
-	TSPP2_OPCODE_PES_TRANSMIT = 0x00,
-	TSPP2_OPCODE_PCR_EXTRACTION = 0x05,
-	TSPP2_OPCODE_CIPHER = 0x01,
-	TSPP2_OPCODE_INDEXING = 0x09,
-	TSPP2_OPCODE_COPY_PACKET = 0x0B,
-	TSPP2_OPCODE_EXIT = 0x0F
-};
-
-/* TSIF Register definitions: */
-#define TSPP2_TSIF_STS_CTL		(0x0000)
-#define TSPP2_TSIF_TIME_LIMIT		(0x0004)
-#define TSPP2_TSIF_CLK_REF		(0x0008)
-#define TSPP2_TSIF_LPBK_FLAGS		(0x000C)
-#define TSPP2_TSIF_LPBK_DATA		(0x0010)
-#define TSPP2_TSIF_DATA_PORT		(0x0100)
-
-/* Bits for TSPP2_TSIF_STS_CTL register */
-#define TSIF_STS_CTL_PKT_WRITE_ERR	BIT(30)
-#define TSIF_STS_CTL_PKT_READ_ERR	BIT(29)
-#define TSIF_STS_CTL_EN_IRQ		BIT(28)
-#define TSIF_STS_CTL_PACK_AVAIL		BIT(27)
-#define TSIF_STS_CTL_1ST_PACKET		BIT(26)
-#define TSIF_STS_CTL_OVERFLOW		BIT(25)
-#define TSIF_STS_CTL_LOST_SYNC		BIT(24)
-#define TSIF_STS_CTL_TIMEOUT		BIT(23)
-#define TSIF_STS_CTL_INV_SYNC		BIT(21)
-#define TSIF_STS_CTL_INV_NULL		BIT(20)
-#define TSIF_STS_CTL_INV_ERROR		BIT(19)
-#define TSIF_STS_CTL_INV_ENABLE		BIT(18)
-#define TSIF_STS_CTL_INV_DATA		BIT(17)
-#define TSIF_STS_CTL_INV_CLOCK		BIT(16)
-#define TSIF_STS_CTL_PARALLEL		BIT(14)
-#define TSIF_STS_CTL_EN_NULL		BIT(11)
-#define TSIF_STS_CTL_EN_ERROR		BIT(10)
-#define TSIF_STS_CTL_LAST_BIT		BIT(9)
-#define TSIF_STS_CTL_EN_TIME_LIM	BIT(8)
-#define TSIF_STS_CTL_EN_TCR		BIT(7)
-#define TSIF_STS_CTL_TEST_MODE		BIT(6)
-#define TSIF_STS_CTL_MODE_2		BIT(5)
-#define TSIF_STS_CTL_EN_DM		BIT(4)
-#define TSIF_STS_CTL_STOP		BIT(3)
-#define TSIF_STS_CTL_START		BIT(0)
-
-/* Indexing Table Register definitions: id = 0..3, n = 0..25 */
-#define TSPP2_INDEX_TABLE_PREFIX(id)		(0x6000 + ((id) << 2))
-#define TSPP2_INDEX_TABLE_PREFIX_MASK(id)	(0x6010 + ((id) << 2))
-#define TSPP2_INDEX_TABLE_PATTEREN(id, n)	(0x3C00 + ((id) << 8) + \
-							((n) << 3))
-#define TSPP2_INDEX_TABLE_MASK(id, n)		(0x3C04 + ((id) << 8) + \
-							((n) << 3))
-#define TSPP2_INDEX_TABLE_PARAMS(id)		(0x6020 + ((id) << 2))
-
-/* Bits for TSPP2_INDEX_TABLE_PARAMS register */
-#define INDEX_TABLE_PARAMS_PREFIX_SIZE_OFFS	8
-#define INDEX_TABLE_PARAMS_NUM_PATTERNS_OFFS	0
-
-/* Source with memory input register definitions: n = 0..7 */
-#define TSPP2_MEM_INPUT_SRC_CONFIG(n)		(0x6040 + ((n) << 2))
-
-/* Bits for TSPP2_MEM_INPUT_SRC_CONFIG register */
-#define MEM_INPUT_SRC_CONFIG_BATCHES_OFFS	16
-#define MEM_INPUT_SRC_CONFIG_INPUT_PIPE_OFFS	8
-#define MEM_INPUT_SRC_CONFIG_16_BATCHES_OFFS	4
-#define MEM_INPUT_SRC_CONFIG_STAMP_SUFFIX_OFFS	2
-#define MEM_INPUT_SRC_CONFIG_STAMP_EN_OFFS	1
-#define MEM_INPUT_SRC_CONFIG_INPUT_EN_OFFS	0
-
-/* Source with TSIF input register definitions: n = 0..1 */
-#define TSPP2_TSIF_INPUT_SRC_CONFIG(n)		(0x6060 + ((n) << 2))
-#define TSIF_INPUT_SRC_CONFIG_16_BATCHES_OFFS	4
-
-/* Bits for TSPP2_TSIF_INPUT_SRC_CONFIG register */
-#define TSIF_INPUT_SRC_CONFIG_BATCHES_OFFS	16
-#define TSIF_INPUT_SRC_CONFIG_INPUT_EN_OFFS	0
-
-/* Source with any input register definitions: n = 0..9 */
-#define TSPP2_SRC_DEST_PIPES(n)			(0x6070 + ((n) << 2))
-#define TSPP2_SRC_CONFIG(n)			(0x6120 + ((n) << 2))
-#define TSPP2_SRC_TOTAL_TSP(n)			(0x6600 + ((n) << 2))
-#define TSPP2_SRC_FILTERED_OUT_TSP(n)		(0x6630 + ((n) << 2))
-
-/* Bits for TSPP2_SRC_CONFIG register */
-#define SRC_CONFIG_SYNC_BYTE_OFFS		24
-#define SRC_CONFIG_CHECK_SYNC_OFFS		23
-#define SRC_CONFIG_SCRAMBLING_MONITOR_OFFS	13
-#define SRC_CONFIG_VERIFY_PES_START_OFFS	12
-#define SRC_CONFIG_SCRAMBLING3_OFFS		10
-#define SRC_CONFIG_SCRAMBLING2_OFFS		8
-#define SRC_CONFIG_SCRAMBLING1_OFFS		6
-#define SRC_CONFIG_SCRAMBLING0_OFFS		4
-#define SRC_CONFIG_DISCARD_INVALID_AF_OFFS	3
-#define SRC_CONFIG_ASSUME_DUPLICATES_OFFS	2
-#define SRC_CONFIG_IGNORE_DISCONT_OFFS		1
-#define SRC_CONFIG_CHECK_CONT_OFFS		0
-
-/* Context register definitions: n = 0..127 */
-#define TSPP2_PES_CONTEXT0(n)		(0x0000 + ((n) << 4))
-#define TSPP2_PES_CONTEXT1(n)		(0x0004 + ((n) << 4))
-#define TSPP2_PES_CONTEXT2(n)		(0x0008 + ((n) << 4))
-#define TSPP2_PES_CONTEXT3(n)		(0x000C + ((n) << 4))
-#define TSPP2_INDEXING_CONTEXT0(n)	(0x0800 + ((n) << 3))
-#define TSPP2_INDEXING_CONTEXT1(n)	(0x0804 + ((n) << 3))
-#define TSPP2_TSP_CONTEXT(n)		(0x5600 + ((n) << 2))
-
-/* Bits for TSPP2_TSP_CONTEXT register */
-#define TSP_CONTEXT_TS_HEADER_SC_OFFS	6
-#define TSP_CONTEXT_PES_HEADER_SC_OFFS	8
-
-/* Operations register definitions: f_idx = 0..127, n = 0..15 */
-#define TSPP2_OPCODE(f_idx, n)	(0x1000 + \
-				((f_idx) * (TSPP2_MAX_OPS_PER_FILTER << 2)) + \
-				((n) << 2))
-
-/* Filter register definitions: n = 0..127 */
-#define TSPP2_FILTER_ENTRY0(n)		(0x5800 + ((n) << 3))
-#define TSPP2_FILTER_ENTRY1(n)		(0x5804 + ((n) << 3))
-
-/* Bits for TSPP2_FILTER_ENTRY0 register */
-#define FILTER_ENTRY0_PID_OFFS		0
-#define FILTER_ENTRY0_MASK_OFFS		13
-#define FILTER_ENTRY0_EN_OFFS		26
-#define FILTER_ENTRY0_CODEC_OFFS	27
-
-/* Bits for TSPP2_FILTER_ENTRY1 register */
-#define FILTER_ENTRY1_CONTEXT_OFFS	0
-
-/* Filter context-based counter register definitions: n = 0..127 */
-#define TSPP2_FILTER_TSP_SYNC_ERROR(n)		(0x4000 + ((n) << 2))
-#define TSPP2_FILTER_ERRED_TSP(n)		(0x4200 + ((n) << 2))
-#define TSPP2_FILTER_DISCONTINUITIES(n)		(0x4400 + ((n) << 2))
-#define TSPP2_FILTER_SCRAMBLING_BITS_DISCARD(n)	(0x4600 + ((n) << 2))
-#define TSPP2_FILTER_TSP_TOTAL_NUM(n)		(0x4800 + ((n) << 2))
-#define TSPP2_FILTER_DISCONT_INDICATOR(n)	(0x4A00 + ((n) << 2))
-#define TSPP2_FILTER_TSP_NO_PAYLOAD(n)		(0x4C00 + ((n) << 2))
-#define TSPP2_FILTER_TSP_DUPLICATE(n)		(0x4E00 + ((n) << 2))
-#define TSPP2_FILTER_KEY_FETCH_FAILURE(n)	(0x5000 + ((n) << 2))
-#define TSPP2_FILTER_DROPPED_PCR(n)		(0x5200 + ((n) << 2))
-#define TSPP2_FILTER_PES_ERRORS(n)		(0x5400 + ((n) << 2))
-
-/* Pipe register definitions: n = 0..30 */
-#define TSPP2_PIPE_THRESH_CONFIG(n)		(0x60A0 + ((n) << 2))
-#define TSPP2_PIPE_LAST_ADDRESS(n)		(0x6190 + ((n) << 2))
-#define TSPP2_PIPE_SECURITY			0x6150
-#define TSPP2_DATA_NOT_SENT_ON_PIPE(n)		(0x6660 + ((n) << 2))
-
-/* Global register definitions: */
-#define TSPP2_PCR_GLOBAL_CONFIG			0x6160
-#define TSPP2_CLK_TO_PCR_TIME_UNIT		0x6170
-#define TSPP2_DESC_WAIT_TIMEOUT			0x6180
-#define TSPP2_GLOBAL_IRQ_STATUS			0x6300
-#define TSPP2_GLOBAL_IRQ_CLEAR			0x6304
-#define TSPP2_GLOBAL_IRQ_ENABLE			0x6308
-#define TSPP2_KEY_NOT_READY_IRQ_STATUS		0x6310
-#define TSPP2_KEY_NOT_READY_IRQ_CLEAR		0x6314
-#define TSPP2_KEY_NOT_READY_IRQ_ENABLE		0x6318
-#define TSPP2_UNEXPECTED_RST_IRQ_STATUS		0x6320
-#define TSPP2_UNEXPECTED_RST_IRQ_CLEAR		0x6324
-#define TSPP2_UNEXPECTED_RST_IRQ_ENABLE		0x6328
-#define TSPP2_WRONG_PIPE_DIR_IRQ_STATUS		0x6330
-#define TSPP2_WRONG_PIPE_DIR_IRQ_CLEAR		0x6334
-#define TSPP2_WRONG_PIPE_DIR_IRQ_ENABLE		0x6338
-#define TSPP2_QSB_RESPONSE_ERROR_IRQ_STATUS	0x6340
-#define TSPP2_QSB_RESPONSE_ERROR_IRQ_CLEAR	0x6344
-#define TSPP2_QSB_RESPONSE_ERROR_IRQ_ENABLE	0x6348
-#define TSPP2_SRC_TOTAL_TSP_RESET		0x6710
-#define TSPP2_SRC_FILTERED_OUT_TSP_RESET	0x6714
-#define TSPP2_DATA_NOT_SENT_ON_PIPE_RESET	0x6718
-#define TSPP2_VERSION				0x6FFC
-
-/* Bits for TSPP2_GLOBAL_IRQ_CLEAR register */
-#define GLOBAL_IRQ_CLEAR_RESERVED_OFFS         4
-
-/* Bits for TSPP2_VERSION register */
-#define VERSION_MAJOR_OFFS			28
-#define VERSION_MINOR_OFFS			16
-#define VERSION_STEP_OFFS			0
-
-/* Bits for TSPP2_GLOBAL_IRQ_XXX registers */
-#define GLOBAL_IRQ_TSP_INVALID_AF_OFFS		0
-#define GLOBAL_IRQ_TSP_INVALID_LEN_OFFS		1
-#define GLOBAL_IRQ_PES_NO_SYNC_OFFS		2
-#define GLOBAL_IRQ_ENCRYPT_LEVEL_ERR_OFFS	3
-#define GLOBAL_IRQ_KEY_NOT_READY_OFFS		4
-#define GLOBAL_IRQ_UNEXPECTED_RESET_OFFS	5
-#define GLOBAL_IRQ_QSB_RESP_ERR_OFFS		6
-#define GLOBAL_IRQ_WRONG_PIPE_DIR_OFFS		7
-#define GLOBAL_IRQ_SC_GO_HIGH_OFFS		8
-#define GLOBAL_IRQ_SC_GO_LOW_OFFS		9
-#define GLOBAL_IRQ_READ_FAIL_OFFS		16
-#define GLOBAL_IRQ_FC_STALL_OFFS		24
-
-/* Bits for TSPP2_PCR_GLOBAL_CONFIG register */
-#define PCR_GLOBAL_CONFIG_PCR_ON_DISCONT_OFFS	10
-#define PCR_GLOBAL_CONFIG_STC_OFFSET_OFFS	8
-#define PCR_GLOBAL_CONFIG_PCR_INTERVAL_OFFS	0
-#define PCR_GLOBAL_CONFIG_PCR_ON_DISCONT	BIT(10)
-#define PCR_GLOBAL_CONFIG_STC_OFFSET		(BIT(8)|BIT(9))
-#define PCR_GLOBAL_CONFIG_PCR_INTERVAL		0xFF
-
-/* n = 0..3, each register handles 32 filters */
-#define TSPP2_SC_GO_HIGH_STATUS(n)		(0x6350 + ((n) << 2))
-#define TSPP2_SC_GO_HIGH_CLEAR(n)		(0x6360 + ((n) << 2))
-#define TSPP2_SC_GO_HIGH_ENABLE(n)		(0x6370 + ((n) << 2))
-#define TSPP2_SC_GO_LOW_STATUS(n)		(0x6390 + ((n) << 2))
-#define TSPP2_SC_GO_LOW_CLEAR(n)		(0x63A0 + ((n) << 2))
-#define TSPP2_SC_GO_LOW_ENABLE(n)		(0x63B0 + ((n) << 2))
-
-/* n = 0..3, each register handles 32 contexts */
-#define TSPP2_TSP_CONTEXT_RESET(n)		(0x6500 + ((n) << 2))
-#define TSPP2_PES_CONTEXT_RESET(n)		(0x6510 + ((n) << 2))
-#define TSPP2_INDEXING_CONTEXT_RESET(n)		(0x6520 + ((n) << 2))
-
-/* debugfs entries */
-
-#define TSPP2_S_RW	(S_IRUGO | S_IWUSR)
-
-struct debugfs_entry {
-	const char *name;
-	mode_t mode;
-	int offset;
-};
-
-static const struct debugfs_entry tsif_regs[] = {
-	{"sts_ctl",	TSPP2_S_RW,	TSPP2_TSIF_STS_CTL},
-	{"time_limit",	TSPP2_S_RW,	TSPP2_TSIF_TIME_LIMIT},
-	{"clk_ref",	TSPP2_S_RW,	TSPP2_TSIF_CLK_REF},
-	{"lpbk_flags",	TSPP2_S_RW,	TSPP2_TSIF_LPBK_FLAGS},
-	{"lpbk_data",	TSPP2_S_RW,	TSPP2_TSIF_LPBK_DATA},
-	{"data_port",	S_IRUGO,	TSPP2_TSIF_DATA_PORT},
-};
-
-static const struct debugfs_entry tspp2_regs[] = {
-	/* Memory input source configuration registers */
-	{"mem_input_src_config_0", TSPP2_S_RW, TSPP2_MEM_INPUT_SRC_CONFIG(0)},
-	{"mem_input_src_config_1", TSPP2_S_RW, TSPP2_MEM_INPUT_SRC_CONFIG(1)},
-	{"mem_input_src_config_2", TSPP2_S_RW, TSPP2_MEM_INPUT_SRC_CONFIG(2)},
-	{"mem_input_src_config_3", TSPP2_S_RW, TSPP2_MEM_INPUT_SRC_CONFIG(3)},
-	{"mem_input_src_config_4", TSPP2_S_RW, TSPP2_MEM_INPUT_SRC_CONFIG(4)},
-	{"mem_input_src_config_5", TSPP2_S_RW, TSPP2_MEM_INPUT_SRC_CONFIG(5)},
-	{"mem_input_src_config_6", TSPP2_S_RW, TSPP2_MEM_INPUT_SRC_CONFIG(6)},
-	{"mem_input_src_config_7", TSPP2_S_RW, TSPP2_MEM_INPUT_SRC_CONFIG(7)},
-	/* TSIF input source configuration registers */
-	{"tsif_input_src_config_0", TSPP2_S_RW, TSPP2_TSIF_INPUT_SRC_CONFIG(0)},
-	{"tsif_input_src_config_1", TSPP2_S_RW, TSPP2_TSIF_INPUT_SRC_CONFIG(1)},
-	/* Source destination pipes association registers */
-	{"src_dest_pipes_0", TSPP2_S_RW, TSPP2_SRC_DEST_PIPES(0)},
-	{"src_dest_pipes_1", TSPP2_S_RW, TSPP2_SRC_DEST_PIPES(1)},
-	{"src_dest_pipes_2", TSPP2_S_RW, TSPP2_SRC_DEST_PIPES(2)},
-	{"src_dest_pipes_3", TSPP2_S_RW, TSPP2_SRC_DEST_PIPES(3)},
-	{"src_dest_pipes_4", TSPP2_S_RW, TSPP2_SRC_DEST_PIPES(4)},
-	{"src_dest_pipes_5", TSPP2_S_RW, TSPP2_SRC_DEST_PIPES(5)},
-	{"src_dest_pipes_6", TSPP2_S_RW, TSPP2_SRC_DEST_PIPES(6)},
-	{"src_dest_pipes_7", TSPP2_S_RW, TSPP2_SRC_DEST_PIPES(7)},
-	{"src_dest_pipes_8", TSPP2_S_RW, TSPP2_SRC_DEST_PIPES(8)},
-	{"src_dest_pipes_9", TSPP2_S_RW, TSPP2_SRC_DEST_PIPES(9)},
-	/* Source configuration registers */
-	{"src_config_0", TSPP2_S_RW, TSPP2_SRC_CONFIG(0)},
-	{"src_config_1", TSPP2_S_RW, TSPP2_SRC_CONFIG(1)},
-	{"src_config_2", TSPP2_S_RW, TSPP2_SRC_CONFIG(2)},
-	{"src_config_3", TSPP2_S_RW, TSPP2_SRC_CONFIG(3)},
-	{"src_config_4", TSPP2_S_RW, TSPP2_SRC_CONFIG(4)},
-	{"src_config_5", TSPP2_S_RW, TSPP2_SRC_CONFIG(5)},
-	{"src_config_6", TSPP2_S_RW, TSPP2_SRC_CONFIG(6)},
-	{"src_config_7", TSPP2_S_RW, TSPP2_SRC_CONFIG(7)},
-	{"src_config_8", TSPP2_S_RW, TSPP2_SRC_CONFIG(8)},
-	{"src_config_9", TSPP2_S_RW, TSPP2_SRC_CONFIG(9)},
-	/* Source total TS packets counter registers */
-	{"src_total_tsp_0", S_IRUGO, TSPP2_SRC_TOTAL_TSP(0)},
-	{"src_total_tsp_1", S_IRUGO, TSPP2_SRC_TOTAL_TSP(1)},
-	{"src_total_tsp_2", S_IRUGO, TSPP2_SRC_TOTAL_TSP(2)},
-	{"src_total_tsp_3", S_IRUGO, TSPP2_SRC_TOTAL_TSP(3)},
-	{"src_total_tsp_4", S_IRUGO, TSPP2_SRC_TOTAL_TSP(4)},
-	{"src_total_tsp_5", S_IRUGO, TSPP2_SRC_TOTAL_TSP(5)},
-	{"src_total_tsp_6", S_IRUGO, TSPP2_SRC_TOTAL_TSP(6)},
-	{"src_total_tsp_7", S_IRUGO, TSPP2_SRC_TOTAL_TSP(7)},
-	{"src_total_tsp_8", S_IRUGO, TSPP2_SRC_TOTAL_TSP(8)},
-	{"src_total_tsp_9", S_IRUGO, TSPP2_SRC_TOTAL_TSP(9)},
-	/* Source total filtered out TS packets counter registers */
-	{"src_filtered_out_tsp_0", S_IRUGO, TSPP2_SRC_FILTERED_OUT_TSP(0)},
-	{"src_filtered_out_tsp_1", S_IRUGO, TSPP2_SRC_FILTERED_OUT_TSP(1)},
-	{"src_filtered_out_tsp_2", S_IRUGO, TSPP2_SRC_FILTERED_OUT_TSP(2)},
-	{"src_filtered_out_tsp_3", S_IRUGO, TSPP2_SRC_FILTERED_OUT_TSP(3)},
-	{"src_filtered_out_tsp_4", S_IRUGO, TSPP2_SRC_FILTERED_OUT_TSP(4)},
-	{"src_filtered_out_tsp_5", S_IRUGO, TSPP2_SRC_FILTERED_OUT_TSP(5)},
-	{"src_filtered_out_tsp_6", S_IRUGO, TSPP2_SRC_FILTERED_OUT_TSP(6)},
-	{"src_filtered_out_tsp_7", S_IRUGO, TSPP2_SRC_FILTERED_OUT_TSP(7)},
-	{"src_filtered_out_tsp_8", S_IRUGO, TSPP2_SRC_FILTERED_OUT_TSP(8)},
-	{"src_filtered_out_tsp_9", S_IRUGO, TSPP2_SRC_FILTERED_OUT_TSP(9)},
-	/* Global registers */
-	{"pipe_security", TSPP2_S_RW, TSPP2_PIPE_SECURITY},
-	{"pcr_global_config", TSPP2_S_RW, TSPP2_PCR_GLOBAL_CONFIG},
-	{"clk_to_pcr_time_unit", TSPP2_S_RW, TSPP2_CLK_TO_PCR_TIME_UNIT},
-	{"desc_wait_timeout", TSPP2_S_RW, TSPP2_DESC_WAIT_TIMEOUT},
-	{"global_irq_status", S_IRUGO, TSPP2_GLOBAL_IRQ_STATUS},
-	{"global_irq_clear", S_IWUSR, TSPP2_GLOBAL_IRQ_CLEAR},
-	{"global_irq_en", TSPP2_S_RW, TSPP2_GLOBAL_IRQ_ENABLE},
-	{"key_not_ready_irq_status", S_IRUGO, TSPP2_KEY_NOT_READY_IRQ_STATUS},
-	{"key_not_ready_irq_clear", S_IWUSR, TSPP2_KEY_NOT_READY_IRQ_CLEAR},
-	{"key_not_ready_irq_en", TSPP2_S_RW, TSPP2_KEY_NOT_READY_IRQ_ENABLE},
-	{"unexpected_rst_irq_status", S_IRUGO, TSPP2_UNEXPECTED_RST_IRQ_STATUS},
-	{"unexpected_rst_irq_clear", S_IWUSR, TSPP2_UNEXPECTED_RST_IRQ_CLEAR},
-	{"unexpected_rst_irq_en", TSPP2_S_RW, TSPP2_UNEXPECTED_RST_IRQ_ENABLE},
-	{"wrong_pipe_dir_irq_status", S_IRUGO, TSPP2_WRONG_PIPE_DIR_IRQ_STATUS},
-	{"wrong_pipe_dir_irq_clear", S_IWUSR, TSPP2_WRONG_PIPE_DIR_IRQ_CLEAR},
-	{"wrong_pipe_dir_irq_en", TSPP2_S_RW, TSPP2_WRONG_PIPE_DIR_IRQ_ENABLE},
-	{"qsb_response_error_irq_status", S_IRUGO,
-					TSPP2_QSB_RESPONSE_ERROR_IRQ_STATUS},
-	{"qsb_response_error_irq_clear", S_IWUSR,
-					TSPP2_QSB_RESPONSE_ERROR_IRQ_CLEAR},
-	{"qsb_response_error_irq_en", TSPP2_S_RW,
-					TSPP2_QSB_RESPONSE_ERROR_IRQ_ENABLE},
-	{"src_total_tsp_reset", S_IWUSR, TSPP2_SRC_TOTAL_TSP_RESET},
-	{"src_filtered_out_tsp_reset", S_IWUSR,
-					TSPP2_SRC_FILTERED_OUT_TSP_RESET},
-	{"data_not_sent_on_pipe_reset", S_IWUSR,
-					TSPP2_DATA_NOT_SENT_ON_PIPE_RESET},
-	{"version", S_IRUGO, TSPP2_VERSION},
-	/* Scrambling bits monitoring interrupt registers */
-	{"sc_go_high_status_0", S_IRUGO, TSPP2_SC_GO_HIGH_STATUS(0)},
-	{"sc_go_high_status_1", S_IRUGO, TSPP2_SC_GO_HIGH_STATUS(1)},
-	{"sc_go_high_status_2", S_IRUGO, TSPP2_SC_GO_HIGH_STATUS(2)},
-	{"sc_go_high_status_3", S_IRUGO, TSPP2_SC_GO_HIGH_STATUS(3)},
-	{"sc_go_high_clear_0", S_IWUSR, TSPP2_SC_GO_HIGH_CLEAR(0)},
-	{"sc_go_high_clear_1", S_IWUSR, TSPP2_SC_GO_HIGH_CLEAR(1)},
-	{"sc_go_high_clear_2", S_IWUSR, TSPP2_SC_GO_HIGH_CLEAR(2)},
-	{"sc_go_high_clear_3", S_IWUSR, TSPP2_SC_GO_HIGH_CLEAR(3)},
-	{"sc_go_high_en_0", TSPP2_S_RW, TSPP2_SC_GO_HIGH_ENABLE(0)},
-	{"sc_go_high_en_1", TSPP2_S_RW, TSPP2_SC_GO_HIGH_ENABLE(1)},
-	{"sc_go_high_en_2", TSPP2_S_RW, TSPP2_SC_GO_HIGH_ENABLE(2)},
-	{"sc_go_high_en_3", TSPP2_S_RW, TSPP2_SC_GO_HIGH_ENABLE(3)},
-	{"sc_go_low_status_0", S_IRUGO, TSPP2_SC_GO_LOW_STATUS(0)},
-	{"sc_go_low_status_1", S_IRUGO, TSPP2_SC_GO_LOW_STATUS(1)},
-	{"sc_go_low_status_2", S_IRUGO, TSPP2_SC_GO_LOW_STATUS(2)},
-	{"sc_go_low_status_3", S_IRUGO, TSPP2_SC_GO_LOW_STATUS(3)},
-	{"sc_go_low_clear_0", S_IWUSR, TSPP2_SC_GO_LOW_CLEAR(0)},
-	{"sc_go_low_clear_1", S_IWUSR, TSPP2_SC_GO_LOW_CLEAR(1)},
-	{"sc_go_low_clear_2", S_IWUSR, TSPP2_SC_GO_LOW_CLEAR(2)},
-	{"sc_go_low_clear_3", S_IWUSR, TSPP2_SC_GO_LOW_CLEAR(3)},
-	{"sc_go_low_en_0", TSPP2_S_RW, TSPP2_SC_GO_LOW_ENABLE(0)},
-	{"sc_go_low_en_1", TSPP2_S_RW, TSPP2_SC_GO_LOW_ENABLE(1)},
-	{"sc_go_low_en_2", TSPP2_S_RW, TSPP2_SC_GO_LOW_ENABLE(2)},
-	{"sc_go_low_en_3", TSPP2_S_RW, TSPP2_SC_GO_LOW_ENABLE(3)},
-};
-
-/* Data structures */
-
-/**
- * struct tspp2_tsif_device - TSIF device
- *
- * @base:		TSIF device memory base address.
- * @hw_index:		TSIF device HW index (0 .. (TSPP2_NUM_TSIF_INPUTS - 1)).
- * @dev:		Back pointer to the TSPP2 device.
- * @time_limit:		TSIF device time limit
- *			(maximum time allowed between each TS packet).
- * @ref_count:		TSIF device reference count.
- * @tsif_irq:		TSIF device IRQ number.
- * @mode:		TSIF mode of operation.
- * @clock_inverse:	Invert input clock signal.
- * @data_inverse:	Invert input data signal.
- * @sync_inverse:	Invert input sync signal.
- * @enable_inverse:	Invert input enable signal.
- * @debugfs_entrys:	TSIF device debugfs entry.
- * @stat_pkt_write_err:	TSIF device packet write error statistics.
- * @stat__pkt_read_err: TSIF device packet read error statistics.
- * @stat_overflow:	TSIF device overflow statistics.
- * @stat_lost_sync:	TSIF device lost sync statistics.
- * @stat_timeout:	TSIF device timeout statistics.
- */
-struct tspp2_tsif_device {
-	void __iomem *base;
-	u32 hw_index;
-	struct tspp2_device *dev;
-	u32 time_limit;
-	u32 ref_count;
-	u32 tsif_irq;
-	enum tspp2_tsif_mode mode;
-	int clock_inverse;
-	int data_inverse;
-	int sync_inverse;
-	int enable_inverse;
-	struct dentry *debugfs_entry;
-	u32 stat_pkt_write_err;
-	u32 stat_pkt_read_err;
-	u32 stat_overflow;
-	u32 stat_lost_sync;
-	u32 stat_timeout;
-};
-
-/**
- * struct tspp2_indexing_table - Indexing table
- *
- * @prefix_value:	4-byte common prefix value.
- * @prefix_mask:	4-byte prefix mask.
- * @entry_value:	An array of 4-byte pattern values.
- * @entry_mask:		An array of corresponding 4-byte pattern masks.
- * @num_valid_entries:	Number of valid entries in the arrays.
- */
-struct tspp2_indexing_table {
-	u32 prefix_value;
-	u32 prefix_mask;
-	u32 entry_value[TSPP2_NUM_INDEXING_PATTERNS];
-	u32 entry_mask[TSPP2_NUM_INDEXING_PATTERNS];
-	u16 num_valid_entries;
-};
-
-/**
- * struct tspp2_event_work - Event work information
- *
- * @device:		TSPP2 device back-pointer.
- * @callback:		Callback to invoke.
- * @cookie:		Cookie to pass to the callback.
- * @event_bitmask:	A bit mask of events to pass to the callback.
- * @work:		The work structure to queue.
- * @link:		A list element.
- */
-struct tspp2_event_work {
-	struct tspp2_device *device;
-	void (*callback)(void *cookie, u32 event_bitmask);
-	void *cookie;
-	u32 event_bitmask;
-	struct work_struct work;
-	struct list_head link;
-};
-
-/**
- * struct tspp2_filter - Filter object
- *
- * @opened:			A flag to indicate whether the filter is open.
- * @device:			Back-pointer to the TSPP2 device the filter
- *				belongs to.
- * @batch:			The filter batch this filter belongs to.
- * @src:			Back-pointer to the source the filter is
- *				associated with.
- * @hw_index:			The filter's HW index.
- * @pid_value:			The filter's 13-bit PID value.
- * @mask:			The corresponding 13-bit bitmask.
- * @context:			The filter's context ID.
- * @indexing_table_id:		The ID of the indexing table this filter uses
- *				in case an indexing operation is set.
- * @operations:			An array of user-defined operations.
- * @num_user_operations:	The number of user-defined operations.
- * @indexing_op_set:		A flag to indicate an indexing operation
- *				has been set.
- * @raw_op_with_indexing:	A flag to indicate a Raw Transmit operation
- *				with support_indexing parameter has been set.
- * @pes_analysis_op_set:	A flag to indicate a PES Analysis operation
- *				has been set.
- * @raw_op_set:			A flag to indicate a Raw Transmit operation
- *				has been set.
- * @pes_tx_op_set:		A flag to indicate a PES Transmit operation
- *				has been set.
- * @event_callback:		A user callback to invoke when a filter event
- *				occurs.
- * @event_cookie:		A user cookie to provide to the callback.
- * @event_bitmask:		A bit mask of filter events
- *				TSPP2_FILTER_EVENT_XXX.
- * @enabled:			A flag to indicate whether the filter
- *				is enabled.
- * @link:			A list element. When the filter is associated
- *				with a source, it is added to the source's
- *				list of filters.
- */
-struct tspp2_filter {
-	int opened;
-	struct tspp2_device *device;
-	struct tspp2_filter_batch *batch;
-	struct tspp2_src *src;
-	u16 hw_index;
-	u16 pid_value;
-	u16 mask;
-	u16 context;
-	u8 indexing_table_id;
-	struct tspp2_operation operations[TSPP2_MAX_OPS_PER_FILTER];
-	u8 num_user_operations;
-	int indexing_op_set;
-	int raw_op_with_indexing;
-	int pes_analysis_op_set;
-	int raw_op_set;
-	int pes_tx_op_set;
-	void (*event_callback)(void *cookie, u32 event_bitmask);
-	void *event_cookie;
-	u32 event_bitmask;
-	int enabled;
-	struct list_head link;
-};
-
-/**
- * struct tspp2_pipe - Pipe object
- *
- * @opened:		A flag to indicate whether the pipe is open.
- * @device:		Back-pointer to the TSPP2 device the pipe belongs to.
- * @cfg:		Pipe configuration parameters.
- * @sps_pipe:		The BAM SPS pipe.
- * @sps_connect_cfg:	SPS pipe connection configuration.
- * @sps_event:		SPS pipe event registration parameters.
- * @desc_ion_handle:	ION handle for the SPS pipe descriptors.
- * @iova:		TSPP2 IOMMU-mapped virtual address of the
- *			data buffer provided by the user.
- * @hw_index:		The pipe's HW index (for register access).
- * @threshold:		Pipe threshold.
- * @ref_cnt:		Pipe reference count. Incremented when pipe
- *			is attached to a source, decremented when it
- *			is detached from a source.
- */
-struct tspp2_pipe {
-	int opened;
-	struct tspp2_device *device;
-	struct tspp2_pipe_config_params cfg;
-	struct sps_pipe *sps_pipe;
-	struct sps_connect sps_connect_cfg;
-	struct sps_register_event sps_event;
-	struct ion_handle *desc_ion_handle;
-	ion_phys_addr_t iova;
-	u32 hw_index;
-	u16 threshold;
-	u32 ref_cnt;
-};
-
-/**
- * struct tspp2_output_pipe - Output pipe element to add to a source's list
- *
- * @pipe:	A pointer to an output pipe object.
- * @link:	A list element. When an output pipe is attached to a source,
- *		it is added to the source's output pipe list. Note the same pipe
- *		can be attached to multiple sources, so we allocate an output
- *		pipe element to add to the list - we don't add the actual pipe.
- */
-struct tspp2_output_pipe {
-	struct tspp2_pipe *pipe;
-	struct list_head link;
-};
-
-/**
- * struct tspp2_filter_batch - Filter batch object
- *
- * @batch_id:	Filter batch ID.
- * @hw_filters:	An array of HW filters that belong to this batch. When set, this
- *		indicates the filter is used. The actual HW index of a filter is
- *		calculated according to the index in this array along with the
- *		batch ID.
- * @src:	Back-pointer to the source the batch is associated with. This is
- *		also used to indicate this batch is "taken".
- * @link:	A list element. When the batch is associated with a source, it
- *		is added to the source's list of filter batches.
- */
-struct tspp2_filter_batch {
-	u8 batch_id;
-	int hw_filters[TSPP2_FILTERS_PER_BATCH];
-	struct tspp2_src *src;
-	struct list_head link;
-};
-
-/**
- * struct tspp2_src - Source object
- *
- * @opened:			A flag to indicate whether the source is open.
- * @device:			Back-pointer to the TSPP2 device the source
- *				belongs to.
- * @hw_index:			The source's HW index. This is used when writing
- *				to HW registers relevant for this source.
- *				There are registers specific to TSIF or memory
- *				sources, and there are registers common to all
- *				sources.
- * @input:			Source input type (TSIF / memory).
- * @pkt_format:			Input packet size and format for this source.
- * @scrambling_bits_monitoring:	Scrambling bits monitoring mode.
- * @batches_list:		A list of associated filter batches.
- * @filters_list:		A list of associated filters.
- * @input_pipe:			A pointer to the source's input pipe, if exists.
- * @output_pipe_list:		A list of output pipes attached to the source.
- *				For each pipe we also save whether it is
- *				stalling for this source.
- * @num_associated_batches:	Number of associated filter batches.
- * @num_associated_pipes:	Number of associated pipes.
- * @num_associated_filters:	Number of associated filters.
- * @reserved_filter_hw_index:	A HW filter index reserved for updating an
- *				active filter's operations.
- * @event_callback:		A user callback to invoke when a source event
- *				occurs.
- * @event_cookie:		A user cookie to provide to the callback.
- * @event_bitmask:		A bit mask of source events
- *				TSPP2_SRC_EVENT_XXX.
- * @enabled:			A flag to indicate whether the source
- *				is enabled.
- */
-struct tspp2_src {
-	int opened;
-	struct tspp2_device *device;
-	u8 hw_index;
-	enum tspp2_src_input input;
-	enum tspp2_packet_format pkt_format;
-	enum tspp2_src_scrambling_monitoring scrambling_bits_monitoring;
-	struct list_head batches_list;
-	struct list_head filters_list;
-	struct tspp2_pipe *input_pipe;
-	struct list_head output_pipe_list;
-	u8 num_associated_batches;
-	u8 num_associated_pipes;
-	u32 num_associated_filters;
-	u16 reserved_filter_hw_index;
-	void (*event_callback)(void *cookie, u32 event_bitmask);
-	void *event_cookie;
-	u32 event_bitmask;
-	int enabled;
-};
-
-/**
- * struct tspp2_global_irq_stats - Global interrupt statistics counters
- *
- * @tsp_invalid_af_control:	Invalid adaptation field control bit.
- * @tsp_invalid_length:		Invalid adaptation field length.
- * @pes_no_sync:		PES sync sequence not found.
- * @encrypt_level_err:		Cipher operation configuration error.
- */
-struct tspp2_global_irq_stats {
-	u32 tsp_invalid_af_control;
-	u32 tsp_invalid_length;
-	u32 pes_no_sync;
-	u32 encrypt_level_err;
-};
-
-/**
- * struct tspp2_src_irq_stats - Memory source interrupt statistics counters
- *
- * @read_failure:	Failure to read from memory input.
- * @flow_control_stall:	Input is stalled due to flow control.
- */
-struct tspp2_src_irq_stats {
-	u32 read_failure;
-	u32 flow_control_stall;
-};
-
-/**
- * struct tspp2_keytable_irq_stats - Key table interrupt statistics counters
- *
- * @key_not_ready:	Ciphering keys are not ready in the key table.
- */
-struct tspp2_keytable_irq_stats {
-	u32 key_not_ready;
-};
-
-/**
- * struct tspp2_pipe_irq_stats - Pipe interrupt statistics counters
- *
- * @unexpected_reset:		SW reset the pipe before all operations on this
- *				pipe ended.
- * @qsb_response_error:		TX operation ends with QSB error.
- * @wrong_pipe_direction:	Trying to use a pipe in the wrong direction.
- */
-struct tspp2_pipe_irq_stats {
-	u32 unexpected_reset;
-	u32 qsb_response_error;
-	u32 wrong_pipe_direction;
-};
-
-/**
- * struct tspp2_filter_context_irq_stats - Filter interrupt statistics counters
- *
- * @sc_go_high:	Scrambling bits change from clear to encrypted.
- * @sc_go_low:	Scrambling bits change from encrypted to clear.
- */
-struct tspp2_filter_context_irq_stats {
-	u32 sc_go_high;
-	u32 sc_go_low;
-};
-
-/**
- * struct tspp2_irq_stats - Interrupt statistics counters
- *
- * @global:	Global interrupt statistics counters
- * @src:	Memory source interrupt statistics counters
- * @kt:		Key table interrupt statistics counters
- * @pipe:	Pipe interrupt statistics counters
- * @ctx:	Filter context interrupt statistics counters
- */
-struct tspp2_irq_stats {
-	struct tspp2_global_irq_stats global;
-	struct tspp2_src_irq_stats src[TSPP2_NUM_MEM_INPUTS];
-	struct tspp2_keytable_irq_stats kt[TSPP2_NUM_KEYTABLES];
-	struct tspp2_pipe_irq_stats pipe[TSPP2_NUM_PIPES];
-	struct tspp2_filter_context_irq_stats ctx[TSPP2_NUM_CONTEXTS];
-};
-
-/**
- * struct tspp2_iommu_info - TSPP2 IOMMU information
- *
- * @hlos_group:		TSPP2 IOMMU HLOS (Non-Secure) group.
- * @cpz_group:		TSPP2 IOMMU HLOS (Secure) group.
- * @hlos_domain:	TSPP2 IOMMU HLOS (Non-Secure) domain.
- * @cpz_domain:		TSPP2 IOMMU CPZ (Secure) domain.
- * @hlos_domain_num:	TSPP2 IOMMU HLOS (Non-Secure) domain number.
- * @cpz_domain_num:	TSPP2 IOMMU CPZ (Secure) domain number.
- * @hlos_partition:	TSPP2 IOMMU HLOS partition number.
- * @cpz_partition:	TSPP2 IOMMU CPZ partition number.
- */
-struct tspp2_iommu_info {
-	struct iommu_group *hlos_group;
-	struct iommu_group *cpz_group;
-	struct iommu_domain *hlos_domain;
-	struct iommu_domain *cpz_domain;
-	int hlos_domain_num;
-	int cpz_domain_num;
-	int hlos_partition;
-	int cpz_partition;
-};
-
-/**
- * struct tspp2_device - TSPP2 device
- *
- * @dev_id:			TSPP2 device ID.
- * @opened:			A flag to indicate whether the device is open.
- * @pdev:			Platform device.
- * @dev:			Device structure, used for driver prints.
- * @base:			TSPP2 Device memory base address.
- * @tspp2_irq:			TSPP2 Device IRQ number.
- * @bam_handle:			BAM handle.
- * @bam_irq:			BAM IRQ number.
- * @bam_props:			BAM properties.
- * @iommu_info:			IOMMU information.
- * @wakeup_src:			A wakeup source to keep CPU awake when needed.
- * @spinlock:			A spinlock to protect accesses to
- *				data structures that happen from APIs and ISRs.
- * @mutex:			A mutex for mutual exclusion between API calls.
- * @tsif_devices:		An array of TSIF devices.
- * @gdsc:			GDSC power regulator.
- * @bus_client:			Client for bus bandwidth voting.
- * @tspp2_ahb_clk:		TSPP2 AHB clock.
- * @tspp2_core_clk:		TSPP2 core clock.
- * @tspp2_vbif_clk:		TSPP2 VBIF clock.
- * @vbif_ahb_clk:               VBIF AHB clock.
- * @vbif_axi_clk:               VBIF AXI clock.
- * @tspp2_klm_ahb_clk:		TSPP2 KLM AHB clock.
- * @tsif_ref_clk:		TSIF reference clock.
- * @batches:			An array of filter batch objects.
- * @contexts:			An array of context indexes. The index in this
- *				array represents the context's HW index, while
- *				the value represents whether it is used by a
- *				filter or free.
- * @indexing_tables:		An array of indexing tables.
- * @tsif_sources:		An array of source objects for TSIF input.
- * @mem_sources:		An array of source objects for memory input.
- * @filters:			An array of filter objects.
- * @pipes:			An array of pipe objects.
- * @num_secured_opened_pipes:	Number of secured opened pipes.
- * @num_non_secured_opened_pipes:	Number of non-secured opened pipes.
- * @num_enabled_sources:	Number of enabled sources.
- * @work_queue:			A work queue for invoking user callbacks.
- * @event_callback:		A user callback to invoke when a global event
- *				occurs.
- * @event_cookie:		A user cookie to provide to the callback.
- * @event_bitmask:		A bit mask of global events
- *				TSPP2_GLOBAL_EVENT_XXX.
- * @debugfs_entry:		TSPP2 device debugfs entry.
- * @irq_stats:			TSPP2 IRQ statistics.
- * @free_work_list:		A list of available work elements.
- * @work_pool:			A pool of work elements.
- */
-struct tspp2_device {
-	u32 dev_id;
-	int opened;
-	struct platform_device *pdev;
-	struct device *dev;
-	void __iomem *base;
-	u32 tspp2_irq;
-	unsigned long bam_handle;
-	u32 bam_irq;
-	struct sps_bam_props bam_props;
-	struct tspp2_iommu_info iommu_info;
-	struct wakeup_source wakeup_src;
-	spinlock_t spinlock;
-	struct mutex mutex;
-	struct tspp2_tsif_device tsif_devices[TSPP2_NUM_TSIF_INPUTS];
-	struct regulator *gdsc;
-	uint32_t bus_client;
-	struct clk *tspp2_ahb_clk;
-	struct clk *tspp2_core_clk;
-	struct clk *tspp2_vbif_clk;
-	struct clk *vbif_ahb_clk;
-	struct clk *vbif_axi_clk;
-	struct clk *tspp2_klm_ahb_clk;
-	struct clk *tsif_ref_clk;
-	struct tspp2_filter_batch batches[TSPP2_NUM_BATCHES];
-	int contexts[TSPP2_NUM_AVAIL_CONTEXTS];
-	struct tspp2_indexing_table indexing_tables[TSPP2_NUM_INDEXING_TABLES];
-	struct tspp2_src tsif_sources[TSPP2_NUM_TSIF_INPUTS];
-	struct tspp2_src mem_sources[TSPP2_NUM_MEM_INPUTS];
-	struct tspp2_filter filters[TSPP2_NUM_AVAIL_FILTERS];
-	struct tspp2_pipe pipes[TSPP2_NUM_PIPES];
-	u8 num_secured_opened_pipes;
-	u8 num_non_secured_opened_pipes;
-	u8 num_enabled_sources;
-	struct workqueue_struct *work_queue;
-	void (*event_callback)(void *cookie, u32 event_bitmask);
-	void *event_cookie;
-	u32 event_bitmask;
-	struct dentry *debugfs_entry;
-	struct tspp2_irq_stats irq_stats;
-	struct list_head free_work_list;
-	struct tspp2_event_work work_pool[TSPP2_NUM_EVENT_WORK_ELEMENTS];
-};
-
-/* Global TSPP2 devices database */
-static struct tspp2_device *tspp2_devices[TSPP2_NUM_DEVICES];
-
-/* debugfs support */
-
-static int debugfs_iomem_x32_set(void *data, u64 val)
-{
-	int ret;
-	struct tspp2_device *device = tspp2_devices[0]; /* Assuming device 0 */
-
-	if (!device->opened)
-		return -ENODEV;
-
-	ret = pm_runtime_get_sync(device->dev);
-	if (ret < 0)
-		return ret;
-
-	writel_relaxed(val, data);
-	wmb();
-
-	pm_runtime_mark_last_busy(device->dev);
-	pm_runtime_put_autosuspend(device->dev);
-
-	return 0;
-}
-
-static int debugfs_iomem_x32_get(void *data, u64 *val)
-{
-	int ret;
-	struct tspp2_device *device = tspp2_devices[0]; /* Assuming device 0 */
-
-	if (!device->opened)
-		return -ENODEV;
-
-	ret = pm_runtime_get_sync(device->dev);
-	if (ret < 0)
-		return ret;
-
-	*val = readl_relaxed(data);
-
-	pm_runtime_mark_last_busy(device->dev);
-	pm_runtime_put_autosuspend(device->dev);
-
-	return 0;
-}
-
-DEFINE_SIMPLE_ATTRIBUTE(fops_iomem_x32, debugfs_iomem_x32_get,
-			debugfs_iomem_x32_set, "0x%08llX");
-
-static int debugfs_dev_open_set(void *data, u64 val)
-{
-	int ret = 0;
-
-	/* Assuming device 0 */
-	if (val == 1)
-		ret = tspp2_device_open(0);
-	else
-		ret = tspp2_device_close(0);
-
-	return ret;
-}
-
-static int debugfs_dev_open_get(void *data, u64 *val)
-{
-	struct tspp2_device *device = tspp2_devices[0]; /* Assuming device 0 */
-
-	*val = device->opened;
-
-	return 0;
-}
-
-DEFINE_SIMPLE_ATTRIBUTE(fops_device_open, debugfs_dev_open_get,
-			debugfs_dev_open_set, "0x%08llX");
-
-/**
- * tspp2_tsif_debugfs_init() - TSIF device debugfs initialization.
- *
- * @tsif_device:	TSIF device.
- */
-static void tspp2_tsif_debugfs_init(struct tspp2_tsif_device *tsif_device)
-{
-	int i;
-	char name[10];
-	struct dentry *dentry;
-	void __iomem *base = tsif_device->base;
-
-	snprintf(name, 10, "tsif%i", tsif_device->hw_index);
-	tsif_device->debugfs_entry = debugfs_create_dir(name, NULL);
-
-	if (!tsif_device->debugfs_entry)
-		return;
-
-	dentry = tsif_device->debugfs_entry;
-	if (dentry) {
-		for (i = 0; i < ARRAY_SIZE(tsif_regs); i++) {
-			debugfs_create_file(
-				tsif_regs[i].name,
-				tsif_regs[i].mode,
-				dentry,
-				base + tsif_regs[i].offset,
-				&fops_iomem_x32);
-		}
-	}
-
-	dentry = debugfs_create_dir("statistics", tsif_device->debugfs_entry);
-	if (dentry) {
-		debugfs_create_u32(
-			"stat_pkt_write_err",
-			S_IRUGO | S_IWUSR | S_IWGRP,
-			dentry,
-			&tsif_device->stat_pkt_write_err);
-
-		debugfs_create_u32(
-			"stat_pkt_read_err",
-			S_IRUGO | S_IWUSR | S_IWGRP,
-			dentry,
-			&tsif_device->stat_pkt_read_err);
-
-		debugfs_create_u32(
-			"stat_overflow",
-			S_IRUGO | S_IWUSR | S_IWGRP,
-			dentry,
-			&tsif_device->stat_overflow);
-
-		debugfs_create_u32(
-			"stat_lost_sync",
-			S_IRUGO | S_IWUSR | S_IWGRP,
-			dentry,
-			&tsif_device->stat_lost_sync);
-
-		debugfs_create_u32(
-			"stat_timeout",
-			S_IRUGO | S_IWUSR | S_IWGRP,
-			dentry,
-			&tsif_device->stat_timeout);
-	}
-}
-
-static char *op_to_string(enum tspp2_operation_type op)
-{
-	switch (op) {
-	case TSPP2_OP_PES_ANALYSIS:
-		return "TSPP2_OP_PES_ANALYSIS";
-	case TSPP2_OP_RAW_TRANSMIT:
-		return "TSPP2_OP_RAW_TRANSMIT";
-	case TSPP2_OP_PES_TRANSMIT:
-		return "TSPP2_OP_PES_TRANSMIT";
-	case TSPP2_OP_PCR_EXTRACTION:
-		return "TSPP2_OP_PCR_EXTRACTION";
-	case TSPP2_OP_CIPHER:
-		return "TSPP2_OP_CIPHER";
-	case TSPP2_OP_INDEXING:
-		return "TSPP2_OP_INDEXING";
-	case TSPP2_OP_COPY_PACKET:
-		return "TSPP2_OP_COPY_PACKET";
-	default:
-		return "Invalid Operation";
-	}
-}
-
-static char *src_input_to_string(enum tspp2_src_input src_input)
-{
-	switch (src_input) {
-	case TSPP2_INPUT_TSIF0:
-		return "TSPP2_INPUT_TSIF0";
-	case TSPP2_INPUT_TSIF1:
-		return "TSPP2_INPUT_TSIF1";
-	case TSPP2_INPUT_MEMORY:
-		return "TSPP2_INPUT_MEMORY";
-	default:
-		return "Unknown source input type";
-	}
-}
-
-static char *pkt_format_to_string(enum tspp2_packet_format pkt_format)
-{
-	switch (pkt_format) {
-	case TSPP2_PACKET_FORMAT_188_RAW:
-		return "TSPP2_PACKET_FORMAT_188_RAW";
-	case TSPP2_PACKET_FORMAT_192_HEAD:
-		return "TSPP2_PACKET_FORMAT_192_HEAD";
-	case TSPP2_PACKET_FORMAT_192_TAIL:
-		return "TSPP2_PACKET_FORMAT_192_TAIL";
-	default:
-		return "Unknown packet format";
-	}
-}
-
-/**
- * debugfs service to print device information.
- */
-static int tspp2_device_debugfs_print(struct seq_file *s, void *p)
-{
-	int count;
-	int exist_flag = 0;
-	struct tspp2_device *device = (struct tspp2_device *)s->private;
-
-	seq_printf(s, "dev_id: %d\n", device->dev_id);
-	seq_puts(s, "Enabled filters:");
-	for (count = 0; count < TSPP2_NUM_AVAIL_FILTERS; count++)
-		if (device->filters[count].enabled) {
-			seq_printf(s, "\n\tfilter%3d", count);
-			exist_flag = 1;
-		}
-	if (!exist_flag)
-		seq_puts(s, " none\n");
-	else
-		seq_puts(s, "\n");
-
-	exist_flag = 0;
-	seq_puts(s, "Opened filters:");
-	for (count = 0; count < TSPP2_NUM_AVAIL_FILTERS; count++)
-		if (device->filters[count].opened) {
-			seq_printf(s, "\n\tfilter%3d", count);
-			exist_flag = 1;
-		}
-	if (!exist_flag)
-		seq_puts(s, " none\n");
-	else
-		seq_puts(s, "\n");
-
-	exist_flag = 0;
-	seq_puts(s, "Opened pipes:\n");
-	for (count = 0; count < TSPP2_NUM_PIPES; count++)
-		if (device->pipes[count].opened) {
-			seq_printf(s, "\tpipe%2d\n", count);
-			exist_flag = 1;
-		}
-	if (!exist_flag)
-		seq_puts(s, " none\n");
-	else
-		seq_puts(s, "\n");
-
-	return 0;
-}
-
-/**
- * debugfs service to print source information.
- */
-static int tspp2_src_debugfs_print(struct seq_file *s, void *p)
-{
-	struct tspp2_filter_batch *batch;
-	struct tspp2_filter *filter;
-	struct tspp2_output_pipe *output_pipe;
-	struct tspp2_src *src = (struct tspp2_src *)s->private;
-
-	if (!src) {
-		seq_puts(s, "error\n");
-		return 1;
-	}
-	seq_printf(s, "Status: %s\n", src->enabled ? "enabled" : "disabled");
-	seq_printf(s, "hw_index: %d\n", src->hw_index);
-	seq_printf(s, "event_bitmask: 0x%08X\n", src->event_bitmask);
-	if (src->input_pipe)
-		seq_printf(s, "input_pipe hw_index: %d\n",
-				src->input_pipe->hw_index);
-	seq_printf(s, "tspp2_src_input: %s\n", src_input_to_string(src->input));
-	seq_printf(s, "pkt_format: %s\n",
-			pkt_format_to_string(src->pkt_format));
-	seq_printf(s, "num_associated_batches: %d\n",
-			src->num_associated_batches);
-
-	if (src->num_associated_batches) {
-		seq_puts(s, "batch_ids: ");
-		list_for_each_entry(batch, &src->batches_list, link)
-			seq_printf(s, "%d  ", batch->batch_id);
-		seq_puts(s, "\n");
-	}
-
-	seq_printf(s, "num_associated_pipes: %d\n", src->num_associated_pipes);
-	if (src->num_associated_pipes) {
-		seq_puts(s, "pipes_hw_idxs: ");
-		list_for_each_entry(output_pipe, &src->output_pipe_list, link) {
-			seq_printf(s, "%d  ", output_pipe->pipe->hw_index);
-		}
-		seq_puts(s, "\n");
-	}
-
-	seq_printf(s, "reserved_filter_hw_index: %d\n",
-			src->reserved_filter_hw_index);
-
-	seq_printf(s, "num_associated_filters: %d\n",
-			src->num_associated_filters);
-	if (src->num_associated_filters) {
-		int i;
-		seq_puts(s, "Open filters:\n");
-		list_for_each_entry(filter, &src->filters_list, link) {
-			if (!filter->opened)
-				continue;
-			seq_printf(s, "\thw_index: %d\n",
-					filter->hw_index);
-			seq_printf(s, "\tStatus: %s\n",
-					filter->enabled ? "enabled"
-							: "disabled");
-			seq_printf(s, "\tpid_value: 0x%08X\n",
-					filter->pid_value);
-			seq_printf(s, "\tmask: 0x%08X\n", filter->mask);
-			seq_printf(s, "\tnum_user_operations: %d\n",
-					filter->num_user_operations);
-			if (filter->num_user_operations) {
-				seq_puts(
-					s, "\tTypes of operations:\n");
-				for (i = 0;
-					i < filter->num_user_operations; i++) {
-					seq_printf(s, "\t\t%s\n", op_to_string(
-						filter->operations[i].type));
-				}
-			}
-		}
-
-	} else {
-		seq_puts(s, "no filters\n");
-	}
-
-	return 0;
-}
-
-/**
- * debugfs service to print filter information.
- */
-static int filter_debugfs_print(struct seq_file *s, void *p)
-{
-	int i;
-	struct tspp2_filter *filter = (struct tspp2_filter *)s->private;
-
-	seq_printf(s, "Status: %s\n", filter->opened ? "opened" : "closed");
-	if (filter->batch)
-		seq_printf(s, "Located in batch %d\n", filter->batch->batch_id);
-	if (filter->src)
-		seq_printf(s, "Associated with src %d\n",
-				filter->src->hw_index);
-	seq_printf(s, "hw_index: %d\n", filter->hw_index);
-	seq_printf(s, "pid_value: 0x%08X\n", filter->pid_value);
-	seq_printf(s, "mask: 0x%08X\n", filter->mask);
-	seq_printf(s, "context: %d\n", filter->context);
-	seq_printf(s, "indexing_table_id: %d\n", filter->indexing_table_id);
-	seq_printf(s, "num_user_operations: %d\n", filter->num_user_operations);
-	seq_puts(s, "Types of operations:\n");
-	for (i = 0; i < filter->num_user_operations; i++)
-		seq_printf(s, "\t%s\n", op_to_string(
-				filter->operations[i].type));
-	seq_printf(s, "indexing_op_set: %d\n", filter->indexing_op_set);
-	seq_printf(s, "raw_op_with_indexing: %d\n",
-			filter->raw_op_with_indexing);
-	seq_printf(s, "pes_analysis_op_set: %d\n", filter->pes_analysis_op_set);
-	seq_printf(s, "raw_op_set: %d\n", filter->raw_op_set);
-	seq_printf(s, "pes_tx_op_set: %d\n", filter->pes_tx_op_set);
-	seq_printf(s, "Status: %s\n", filter->enabled ? "enabled" : "disabled");
-
-	if (filter->enabled) {
-		seq_printf(s, "Filter context-based counters, context %d\n",
-				filter->context);
-		seq_printf(s, "filter_tsp_sync_err = 0x%08X\n",
-			readl_relaxed(filter->device->base +
-			TSPP2_FILTER_TSP_SYNC_ERROR(filter->context)));
-		seq_printf(s, "filter_erred_tsp = 0x%08X\n",
-			readl_relaxed(filter->device->base +
-			TSPP2_FILTER_ERRED_TSP(filter->context)));
-		seq_printf(s, "filter_discontinuities = 0x%08X\n",
-			readl_relaxed(filter->device->base +
-			TSPP2_FILTER_DISCONTINUITIES(filter->context)));
-		seq_printf(s, "filter_sc_bits_discard = 0x%08X\n",
-			readl_relaxed(filter->device->base +
-			TSPP2_FILTER_SCRAMBLING_BITS_DISCARD(filter->context)));
-		seq_printf(s, "filter_tsp_total_num = 0x%08X\n",
-			readl_relaxed(filter->device->base +
-			TSPP2_FILTER_TSP_TOTAL_NUM(filter->context)));
-		seq_printf(s, "filter_discont_indicator = 0x%08X\n",
-			readl_relaxed(filter->device->base +
-			TSPP2_FILTER_DISCONT_INDICATOR(filter->context)));
-		seq_printf(s, "filter_tsp_no_payload = 0x%08X\n",
-			readl_relaxed(filter->device->base +
-			TSPP2_FILTER_TSP_NO_PAYLOAD(filter->context)));
-		seq_printf(s, "filter_tsp_duplicate = 0x%08X\n",
-			readl_relaxed(filter->device->base +
-			TSPP2_FILTER_TSP_DUPLICATE(filter->context)));
-		seq_printf(s, "filter_key_fetch_fail = 0x%08X\n",
-			readl_relaxed(filter->device->base +
-			TSPP2_FILTER_KEY_FETCH_FAILURE(filter->context)));
-		seq_printf(s, "filter_dropped_pcr = 0x%08X\n",
-			readl_relaxed(filter->device->base +
-			TSPP2_FILTER_DROPPED_PCR(filter->context)));
-		seq_printf(s, "filter_pes_errors = 0x%08X\n",
-			readl_relaxed(filter->device->base +
-			TSPP2_FILTER_PES_ERRORS(filter->context)));
-	}
-
-	return 0;
-}
-
-/**
- * debugfs service to print pipe information.
- */
-static int pipe_debugfs_print(struct seq_file *s, void *p)
-{
-	struct tspp2_pipe *pipe = (struct tspp2_pipe *)s->private;
-	seq_printf(s, "hw_index: %d\n", pipe->hw_index);
-	seq_printf(s, "iova: 0x%08X\n", pipe->iova);
-	seq_printf(s, "threshold: %d\n", pipe->threshold);
-	seq_printf(s, "Status: %s\n", pipe->opened ? "opened" : "closed");
-	seq_printf(s, "ref_cnt: %d\n", pipe->ref_cnt);
-	return 0;
-}
-
-static int tspp2_dev_dbgfs_open(struct inode *inode, struct file *file)
-{
-	return single_open(file, tspp2_device_debugfs_print,
-			inode->i_private);
-}
-
-static int tspp2_filter_dbgfs_open(struct inode *inode, struct file *file)
-{
-	return single_open(file, filter_debugfs_print, inode->i_private);
-}
-
-static int tspp2_pipe_dbgfs_open(struct inode *inode, struct file *file)
-{
-	return single_open(file, pipe_debugfs_print, inode->i_private);
-}
-
-static int tspp2_src_dbgfs_open(struct inode *inode, struct file *file)
-{
-	return single_open(file, tspp2_src_debugfs_print, inode->i_private);
-}
-
-static const struct file_operations dbgfs_tspp2_device_fops = {
-	.open = tspp2_dev_dbgfs_open,
-	.read = seq_read,
-	.llseek = seq_lseek,
-	.release = single_release,
-	.owner = THIS_MODULE,
-};
-
-static const struct file_operations dbgfs_filter_fops = {
-	.open = tspp2_filter_dbgfs_open,
-	.read = seq_read,
-	.llseek = seq_lseek,
-	.release = single_release,
-	.owner = THIS_MODULE,
-};
-
-static const struct file_operations dbgfs_pipe_fops = {
-	.open = tspp2_pipe_dbgfs_open,
-	.read = seq_read,
-	.llseek = seq_lseek,
-	.release = single_release,
-	.owner = THIS_MODULE,
-};
-
-static const struct file_operations dbgfs_src_fops = {
-	.open = tspp2_src_dbgfs_open,
-	.read = seq_read,
-	.llseek = seq_lseek,
-	.release = single_release,
-	.owner = THIS_MODULE,
-};
-
-/**
- * tspp2_tsif_debugfs_exit() - TSIF device debugfs teardown.
- *
- * @tsif_device:	TSIF device.
- */
-static void tspp2_tsif_debugfs_exit(struct tspp2_tsif_device *tsif_device)
-{
-	debugfs_remove_recursive(tsif_device->debugfs_entry);
-	tsif_device->debugfs_entry = NULL;
-}
-
-/**
- * tspp2_debugfs_init() - TSPP2 device debugfs initialization.
- *
- * @device:	TSPP2 device.
- */
-static void tspp2_debugfs_init(struct tspp2_device *device)
-{
-	int i, j;
-	char name[80];
-	struct dentry *dentry;
-	struct dentry *dir;
-	void __iomem *base = device->base;
-
-	snprintf(name, 80, "tspp2_%i", device->dev_id);
-	device->debugfs_entry = debugfs_create_dir(name, NULL);
-
-	if (!device->debugfs_entry)
-		return;
-
-	/* Support device open/close */
-	debugfs_create_file("open", TSPP2_S_RW, device->debugfs_entry,
-				NULL, &fops_device_open);
-
-	dentry = debugfs_create_dir("regs", device->debugfs_entry);
-	if (dentry) {
-		for (i = 0; i < ARRAY_SIZE(tspp2_regs); i++) {
-			debugfs_create_file(
-				tspp2_regs[i].name,
-				tspp2_regs[i].mode,
-				dentry,
-				base + tspp2_regs[i].offset,
-				&fops_iomem_x32);
-		}
-	}
-
-	dentry = debugfs_create_dir("statistics", device->debugfs_entry);
-	if (dentry) {
-		debugfs_create_u32(
-			"stat_tsp_invalid_af_control",
-			S_IRUGO | S_IWUSR | S_IWGRP,
-			dentry,
-			&device->irq_stats.global.tsp_invalid_af_control);
-
-		debugfs_create_u32(
-			"stat_tsp_invalid_length",
-			S_IRUGO | S_IWUSR | S_IWGRP,
-			dentry,
-			&device->irq_stats.global.tsp_invalid_length);
-
-		debugfs_create_u32(
-			"stat_pes_no_sync",
-			S_IRUGO | S_IWUSR | S_IWGRP,
-			dentry,
-			&device->irq_stats.global.pes_no_sync);
-
-		debugfs_create_u32(
-			"stat_encrypt_level_err",
-			S_IRUGO | S_IWUSR | S_IWGRP,
-			dentry,
-			&device->irq_stats.global.encrypt_level_err);
-	}
-
-	dir = debugfs_create_dir("counters", device->debugfs_entry);
-	for (i = 0; i < TSPP2_NUM_CONTEXTS; i++) {
-		snprintf(name, 80, "context%03i", i);
-		dentry = debugfs_create_dir(name, dir);
-		if (dentry) {
-			debugfs_create_file("filter_tsp_sync_err",
-				TSPP2_S_RW,
-				dentry,
-				base + TSPP2_FILTER_TSP_SYNC_ERROR(i),
-				&fops_iomem_x32);
-
-			debugfs_create_file("filter_erred_tsp",
-				TSPP2_S_RW,
-				dentry,
-				base + TSPP2_FILTER_ERRED_TSP(i),
-				&fops_iomem_x32);
-
-			debugfs_create_file("filter_discontinuities",
-				TSPP2_S_RW,
-				dentry,
-				base + TSPP2_FILTER_DISCONTINUITIES(i),
-				&fops_iomem_x32);
-
-			debugfs_create_file("filter_sc_bits_discard",
-				TSPP2_S_RW,
-				dentry,
-				base + TSPP2_FILTER_SCRAMBLING_BITS_DISCARD(i),
-				&fops_iomem_x32);
-
-			debugfs_create_file("filter_tsp_total_num",
-				TSPP2_S_RW,
-				dentry,
-				base + TSPP2_FILTER_TSP_TOTAL_NUM(i),
-				&fops_iomem_x32);
-
-			debugfs_create_file("filter_discont_indicator",
-				TSPP2_S_RW,
-				dentry,
-				base + TSPP2_FILTER_DISCONT_INDICATOR(i),
-				&fops_iomem_x32);
-
-			debugfs_create_file("filter_tsp_no_payload",
-				TSPP2_S_RW,
-				dentry,
-				base + TSPP2_FILTER_TSP_NO_PAYLOAD(i),
-				&fops_iomem_x32);
-
-			debugfs_create_file("filter_tsp_duplicate",
-				TSPP2_S_RW,
-				dentry,
-				base + TSPP2_FILTER_TSP_DUPLICATE(i),
-				&fops_iomem_x32);
-
-			debugfs_create_file("filter_key_fetch_fail",
-				TSPP2_S_RW,
-				dentry,
-				base + TSPP2_FILTER_KEY_FETCH_FAILURE(i),
-				&fops_iomem_x32);
-
-			debugfs_create_file("filter_dropped_pcr",
-				TSPP2_S_RW,
-				dentry,
-				base + TSPP2_FILTER_DROPPED_PCR(i),
-				&fops_iomem_x32);
-
-			debugfs_create_file("filter_pes_errors",
-				TSPP2_S_RW,
-				dentry,
-				base + TSPP2_FILTER_PES_ERRORS(i),
-				&fops_iomem_x32);
-
-			debugfs_create_u32(
-				"stat_sc_go_high",
-				S_IRUGO | S_IWUSR | S_IWGRP,
-				dentry,
-				&device->irq_stats.ctx[i].sc_go_high);
-
-			debugfs_create_u32(
-				"stat_sc_go_low",
-				S_IRUGO | S_IWUSR | S_IWGRP,
-				dentry,
-				&device->irq_stats.ctx[i].sc_go_low);
-		}
-	}
-
-	dir = debugfs_create_dir("filters", device->debugfs_entry);
-	for (i = 0; i < TSPP2_NUM_HW_FILTERS; i++) {
-		snprintf(name, 80, "filter%03i", i);
-		dentry = debugfs_create_dir(name, dir);
-		if (dentry) {
-			debugfs_create_file("filter_entry0",
-				TSPP2_S_RW,
-				dentry,
-				base + TSPP2_FILTER_ENTRY0(i),
-				&fops_iomem_x32);
-
-			debugfs_create_file("filter_entry1",
-				TSPP2_S_RW,
-				dentry,
-				base + TSPP2_FILTER_ENTRY1(i),
-				&fops_iomem_x32);
-
-			for (j = 0; j < TSPP2_MAX_OPS_PER_FILTER; j++) {
-				snprintf(name, 80, "opcode%02i", j);
-				debugfs_create_file(name,
-					TSPP2_S_RW,
-					dentry,
-					base + TSPP2_OPCODE(i, j),
-					&fops_iomem_x32);
-			}
-		}
-	}
-
-	dir = debugfs_create_dir("mem_sources", device->debugfs_entry);
-	for (i = 0; i < TSPP2_NUM_MEM_INPUTS; i++) {
-		snprintf(name, 80, "mem_src%i", i);
-		dentry = debugfs_create_dir(name, dir);
-		if (dentry) {
-			debugfs_create_u32(
-				"stat_read_failure",
-				S_IRUGO | S_IWUSR | S_IWGRP,
-				dentry,
-				&device->irq_stats.src[i].read_failure);
-
-			debugfs_create_u32(
-				"stat_flow_control_stall",
-				S_IRUGO | S_IWUSR | S_IWGRP,
-				dentry,
-				&device->irq_stats.src[i].flow_control_stall);
-		}
-	}
-
-	dir = debugfs_create_dir("key_tables", device->debugfs_entry);
-	for (i = 0; i < TSPP2_NUM_KEYTABLES; i++) {
-		snprintf(name, 80, "key_table%02i", i);
-		dentry = debugfs_create_dir(name, dir);
-		if (dentry) {
-			debugfs_create_u32(
-				"stat_key_not_ready",
-				S_IRUGO | S_IWUSR | S_IWGRP,
-				dentry,
-				&device->irq_stats.kt[i].key_not_ready);
-		}
-	}
-
-	dir = debugfs_create_dir("pipes", device->debugfs_entry);
-	for (i = 0; i < TSPP2_NUM_PIPES; i++) {
-		snprintf(name, 80, "pipe%02i", i);
-		dentry = debugfs_create_dir(name, dir);
-		if (dentry) {
-			debugfs_create_file("threshold",
-				TSPP2_S_RW,
-				dentry,
-				base + TSPP2_PIPE_THRESH_CONFIG(i),
-				&fops_iomem_x32);
-
-			debugfs_create_file("last_address",
-				S_IRUGO,
-				dentry,
-				base + TSPP2_PIPE_LAST_ADDRESS(i),
-				&fops_iomem_x32);
-
-			debugfs_create_file("data_not_sent",
-				S_IRUGO,
-				dentry,
-				base + TSPP2_DATA_NOT_SENT_ON_PIPE(i),
-				&fops_iomem_x32);
-
-			debugfs_create_u32(
-				"stat_unexpected_reset",
-				S_IRUGO | S_IWUSR | S_IWGRP,
-				dentry,
-				&device->irq_stats.pipe[i].unexpected_reset);
-
-			debugfs_create_u32(
-				"stat_qsb_response_error",
-				S_IRUGO | S_IWUSR | S_IWGRP,
-				dentry,
-				&device->irq_stats.pipe[i].qsb_response_error);
-
-			debugfs_create_u32(
-				"stat_wrong_pipe_direction",
-				S_IRUGO | S_IWUSR | S_IWGRP,
-				dentry,
-				&device->irq_stats.pipe[i].
-							wrong_pipe_direction);
-		}
-	}
-
-	dir = debugfs_create_dir("indexing_tables", device->debugfs_entry);
-	for (i = 0; i < TSPP2_NUM_INDEXING_TABLES; i++) {
-		snprintf(name, 80, "indexing_table%i", i);
-		dentry = debugfs_create_dir(name, dir);
-		if (dentry) {
-			debugfs_create_file("prefix",
-				TSPP2_S_RW,
-				dentry,
-				base + TSPP2_INDEX_TABLE_PREFIX(i),
-				&fops_iomem_x32);
-
-			debugfs_create_file("mask",
-				TSPP2_S_RW,
-				dentry,
-				base + TSPP2_INDEX_TABLE_PREFIX_MASK(i),
-				&fops_iomem_x32);
-
-			debugfs_create_file("parameters",
-				TSPP2_S_RW,
-				dentry,
-				base + TSPP2_INDEX_TABLE_PARAMS(i),
-				&fops_iomem_x32);
-
-			for (j = 0; j < TSPP2_NUM_INDEXING_PATTERNS; j++) {
-				snprintf(name, 80, "pattern_%02i", j);
-				debugfs_create_file(name,
-					TSPP2_S_RW,
-					dentry,
-					base + TSPP2_INDEX_TABLE_PATTEREN(i, j),
-					&fops_iomem_x32);
-
-				snprintf(name, 80, "mask_%02i", j);
-				debugfs_create_file(name,
-					TSPP2_S_RW,
-					dentry,
-					base + TSPP2_INDEX_TABLE_MASK(i, j),
-					&fops_iomem_x32);
-			}
-		}
-	}
-	dir = debugfs_create_dir("software", device->debugfs_entry);
-	debugfs_create_file("device", S_IRUGO, dir, device,
-					&dbgfs_tspp2_device_fops);
-
-	dentry = debugfs_create_dir("filters", dir);
-	if (dentry) {
-		for (i = 0; i < TSPP2_NUM_AVAIL_FILTERS; i++) {
-			snprintf(name, 20, "filter%03i", i);
-			debugfs_create_file(name, S_IRUGO, dentry,
-				&(device->filters[i]), &dbgfs_filter_fops);
-		}
-	}
-
-	dentry = debugfs_create_dir("pipes", dir);
-	if (dentry) {
-		for (i = 0; i < TSPP2_NUM_PIPES; i++) {
-			snprintf(name, 20, "pipe%02i", i);
-			debugfs_create_file(name, S_IRUGO, dentry,
-					&(device->pipes[i]), &dbgfs_pipe_fops);
-		}
-	}
-
-	dentry = debugfs_create_dir("sources", dir);
-	if (dentry) {
-		for (i = 0; i < TSPP2_NUM_TSIF_INPUTS; i++) {
-			snprintf(name, 20, "tsif%d", i);
-			debugfs_create_file(name, S_IRUGO, dentry,
-				&(device->tsif_sources[i]), &dbgfs_src_fops);
-		}
-		for (i = 0; i < TSPP2_NUM_MEM_INPUTS; i++) {
-			snprintf(name, 20, "mem%d", i);
-			debugfs_create_file(name, S_IRUGO, dentry,
-				&(device->mem_sources[i]), &dbgfs_src_fops);
-		}
-	}
-}
-
-/**
- * tspp2_debugfs_exit() - TSPP2 device debugfs teardown.
- *
- * @device:	TSPP2 device.
- */
-static void tspp2_debugfs_exit(struct tspp2_device *device)
-{
-	debugfs_remove_recursive(device->debugfs_entry);
-	device->debugfs_entry = NULL;
-}
-
-/**
- *  tspp2_tsif_start() - Start TSIF device HW.
- *
- * @tsif_device:	TSIF device.
- *
- * Return 0 on success, error value otherwise.
- */
-static int tspp2_tsif_start(struct tspp2_tsif_device *tsif_device)
-{
-	u32 ctl;
-
-	if (tsif_device->ref_count > 0)
-		return 0;
-
-	ctl = (TSIF_STS_CTL_EN_IRQ | TSIF_STS_CTL_EN_DM |
-		TSIF_STS_CTL_PACK_AVAIL | TSIF_STS_CTL_OVERFLOW |
-		TSIF_STS_CTL_LOST_SYNC | TSIF_STS_CTL_TIMEOUT |
-		TSIF_STS_CTL_PARALLEL);
-
-	if (tsif_device->clock_inverse)
-		ctl |= TSIF_STS_CTL_INV_CLOCK;
-
-	if (tsif_device->data_inverse)
-		ctl |= TSIF_STS_CTL_INV_DATA;
-
-	if (tsif_device->sync_inverse)
-		ctl |= TSIF_STS_CTL_INV_SYNC;
-
-	if (tsif_device->enable_inverse)
-		ctl |= TSIF_STS_CTL_INV_ENABLE;
-
-	switch (tsif_device->mode) {
-	case TSPP2_TSIF_MODE_LOOPBACK:
-		ctl |= TSIF_STS_CTL_EN_NULL		|
-				TSIF_STS_CTL_EN_ERROR	|
-				TSIF_STS_CTL_TEST_MODE;
-		break;
-	case TSPP2_TSIF_MODE_1:
-		ctl |= TSIF_STS_CTL_EN_TIME_LIM | TSIF_STS_CTL_EN_TCR;
-		break;
-	case TSPP2_TSIF_MODE_2:
-		ctl |= TSIF_STS_CTL_EN_TIME_LIM		|
-				TSIF_STS_CTL_EN_TCR	|
-				TSIF_STS_CTL_MODE_2;
-		break;
-	default:
-		pr_warn("%s: Unknown TSIF mode %d, setting to TSPP2_TSIF_MODE_2\n",
-			__func__, tsif_device->mode);
-		ctl |= TSIF_STS_CTL_EN_TIME_LIM		|
-				TSIF_STS_CTL_EN_TCR	|
-				TSIF_STS_CTL_MODE_2;
-		break;
-	}
-
-	writel_relaxed(ctl, tsif_device->base + TSPP2_TSIF_STS_CTL);
-	writel_relaxed(tsif_device->time_limit,
-		  tsif_device->base + TSPP2_TSIF_TIME_LIMIT);
-	wmb();
-	writel_relaxed(ctl | TSIF_STS_CTL_START,
-		  tsif_device->base + TSPP2_TSIF_STS_CTL);
-	wmb();
-
-	ctl = readl_relaxed(tsif_device->base + TSPP2_TSIF_STS_CTL);
-	if (ctl & TSIF_STS_CTL_START)
-		tsif_device->ref_count++;
-
-	return (ctl & TSIF_STS_CTL_START) ? 0 : -EBUSY;
-}
-
-
-static int tspp2_vbif_clock_start(struct tspp2_device *device)
-{
-	int ret;
-
-	if (device->tspp2_vbif_clk) {
-		ret = clk_prepare_enable(device->tspp2_vbif_clk);
-		if (ret) {
-			pr_err("%s: Can't start tspp2_vbif_clk\n", __func__);
-			return ret;
-		}
-	}
-
-	if (device->vbif_ahb_clk) {
-		ret = clk_prepare_enable(device->vbif_ahb_clk);
-		if (ret) {
-			pr_err("%s: Can't start vbif_ahb_clk\n", __func__);
-			goto disable_vbif_tspp2;
-		}
-	}
-	if (device->vbif_axi_clk) {
-		ret = clk_prepare_enable(device->vbif_axi_clk);
-		if (ret) {
-			pr_err("%s: Can't start vbif_ahb_clk\n", __func__);
-			goto disable_vbif_ahb;
-		}
-	}
-
-	return 0;
-
-disable_vbif_ahb:
-	if (device->vbif_ahb_clk)
-		clk_disable_unprepare(device->vbif_ahb_clk);
-disable_vbif_tspp2:
-	if (device->tspp2_vbif_clk)
-		clk_disable_unprepare(device->tspp2_vbif_clk);
-
-	return ret;
-}
-
-static void tspp2_vbif_clock_stop(struct tspp2_device *device)
-{
-	if (device->tspp2_vbif_clk)
-		clk_disable_unprepare(device->tspp2_vbif_clk);
-
-	if (device->vbif_ahb_clk)
-		clk_disable_unprepare(device->vbif_ahb_clk);
-
-	if (device->vbif_axi_clk)
-		clk_disable_unprepare(device->vbif_axi_clk);
-}
-
-/**
- * tspp2_tsif_stop() - Stop TSIF device HW.
- *
- * @tsif_device:	TSIF device.
- */
-static void tspp2_tsif_stop(struct tspp2_tsif_device *tsif_device)
-{
-	if (tsif_device->ref_count == 0)
-		return;
-
-	tsif_device->ref_count--;
-
-	if (tsif_device->ref_count == 0) {
-		writel_relaxed(TSIF_STS_CTL_STOP,
-			tsif_device->base + TSPP2_TSIF_STS_CTL);
-		/*
-		 * The driver assumes that after this point the TSIF is stopped,
-		 * so a memory barrier is required to allow
-		 * further register writes.
-		 */
-		wmb();
-	}
-}
-
-/* Clock functions */
-
-static int tspp2_reg_clock_start(struct tspp2_device *device)
-{
-	int rc;
-
-	if (device->tspp2_ahb_clk &&
-		clk_prepare_enable(device->tspp2_ahb_clk) != 0) {
-		pr_err("%s: Can't start tspp2_ahb_clk\n", __func__);
-		return -EBUSY;
-	}
-
-	if (device->tspp2_core_clk &&
-		clk_prepare_enable(device->tspp2_core_clk) != 0) {
-		pr_err("%s: Can't start tspp2_core_clk\n", __func__);
-		if (device->tspp2_ahb_clk)
-			clk_disable_unprepare(device->tspp2_ahb_clk);
-		return -EBUSY;
-	}
-
-	/* Request minimal bandwidth on the bus, required for register access */
-	if (device->bus_client) {
-		rc = msm_bus_scale_client_update_request(device->bus_client, 1);
-		if (rc) {
-			pr_err("%s: Can't enable bus\n", __func__);
-			if (device->tspp2_core_clk)
-				clk_disable_unprepare(device->tspp2_core_clk);
-			if (device->tspp2_ahb_clk)
-				clk_disable_unprepare(device->tspp2_ahb_clk);
-			return -EBUSY;
-		}
-	}
-
-	return 0;
-}
-
-static int tspp2_reg_clock_stop(struct tspp2_device *device)
-{
-	/* Minimize bandwidth bus voting */
-	if (device->bus_client)
-		msm_bus_scale_client_update_request(device->bus_client, 0);
-
-	if (device->tspp2_core_clk)
-		clk_disable_unprepare(device->tspp2_core_clk);
-
-	if (device->tspp2_ahb_clk)
-		clk_disable_unprepare(device->tspp2_ahb_clk);
-
-	return 0;
-}
-
-/**
- * tspp2_clock_start() - Enable the required TSPP2 clocks
- *
- * @device:	The TSPP2 device.
- *
- * Return 0 on success, error value otherwise.
- */
-static int tspp2_clock_start(struct tspp2_device *device)
-{
-	int tspp2_ahb_clk = 0;
-	int tspp2_core_clk = 0;
-	int tspp2_vbif_clk = 0;
-	int tspp2_klm_ahb_clk = 0;
-	int tsif_ref_clk = 0;
-
-	if (device == NULL) {
-		pr_err("%s: Can't start clocks, invalid device\n", __func__);
-		return -EINVAL;
-	}
-
-	if (device->tspp2_ahb_clk) {
-		if (clk_prepare_enable(device->tspp2_ahb_clk) != 0) {
-			pr_err("%s: Can't start tspp2_ahb_clk\n", __func__);
-			goto err_clocks;
-		}
-		tspp2_ahb_clk = 1;
-	}
-
-	if (device->tspp2_core_clk) {
-		if (clk_prepare_enable(device->tspp2_core_clk) != 0) {
-			pr_err("%s: Can't start tspp2_core_clk\n", __func__);
-			goto err_clocks;
-		}
-		tspp2_core_clk = 1;
-	}
-
-	if (device->tspp2_klm_ahb_clk) {
-		if (clk_prepare_enable(device->tspp2_klm_ahb_clk) != 0) {
-			pr_err("%s: Can't start tspp2_klm_ahb_clk\n", __func__);
-			goto err_clocks;
-		}
-		tspp2_klm_ahb_clk = 1;
-	}
-
-	if (device->tsif_ref_clk) {
-		if (clk_prepare_enable(device->tsif_ref_clk) != 0) {
-			pr_err("%s: Can't start tsif_ref_clk\n", __func__);
-			goto err_clocks;
-		}
-		tsif_ref_clk = 1;
-	}
-
-	/* Request Max bandwidth on the bus, required for full operation */
-	if (device->bus_client &&
-		msm_bus_scale_client_update_request(device->bus_client, 2)) {
-			pr_err("%s: Can't enable bus\n", __func__);
-			goto err_clocks;
-	}
-
-	return 0;
-
-err_clocks:
-	if (tspp2_ahb_clk)
-		clk_disable_unprepare(device->tspp2_ahb_clk);
-
-	if (tspp2_core_clk)
-		clk_disable_unprepare(device->tspp2_core_clk);
-
-	if (tspp2_vbif_clk)
-		clk_disable_unprepare(device->tspp2_vbif_clk);
-
-	if (tspp2_klm_ahb_clk)
-		clk_disable_unprepare(device->tspp2_klm_ahb_clk);
-
-	if (tsif_ref_clk)
-		clk_disable_unprepare(device->tsif_ref_clk);
-
-	return -EBUSY;
-}
-
-/**
- * tspp2_clock_stop() - Disable TSPP2 clocks
- *
- * @device:	The TSPP2 device.
- */
-static void tspp2_clock_stop(struct tspp2_device *device)
-{
-	if (device == NULL) {
-		pr_err("%s: Can't stop clocks, invalid device\n", __func__);
-		return;
-	}
-
-	/* Minimize bandwidth bus voting */
-	if (device->bus_client)
-		msm_bus_scale_client_update_request(device->bus_client, 0);
-
-	if (device->tsif_ref_clk)
-		clk_disable_unprepare(device->tsif_ref_clk);
-
-	if (device->tspp2_klm_ahb_clk)
-		clk_disable_unprepare(device->tspp2_klm_ahb_clk);
-
-	if (device->tspp2_core_clk)
-		clk_disable_unprepare(device->tspp2_core_clk);
-
-	if (device->tspp2_ahb_clk)
-		clk_disable_unprepare(device->tspp2_ahb_clk);
-}
-
-/**
- * tspp2_filter_counters_reset() - Reset a filter's HW counters.
- *
- * @device:	TSPP2 device.
- * @index:	Filter context index. Note counters are based on the context
- *		index and not on the filter HW index.
- */
-static void tspp2_filter_counters_reset(struct tspp2_device *device, u32 index)
-{
-	/* Reset filter counters */
-	writel_relaxed(0, device->base + TSPP2_FILTER_TSP_SYNC_ERROR(index));
-	writel_relaxed(0, device->base + TSPP2_FILTER_ERRED_TSP(index));
-	writel_relaxed(0, device->base + TSPP2_FILTER_DISCONTINUITIES(index));
-	writel_relaxed(0,
-		device->base + TSPP2_FILTER_SCRAMBLING_BITS_DISCARD(index));
-	writel_relaxed(0, device->base + TSPP2_FILTER_TSP_TOTAL_NUM(index));
-	writel_relaxed(0, device->base + TSPP2_FILTER_DISCONT_INDICATOR(index));
-	writel_relaxed(0, device->base + TSPP2_FILTER_TSP_NO_PAYLOAD(index));
-	writel_relaxed(0, device->base + TSPP2_FILTER_TSP_DUPLICATE(index));
-	writel_relaxed(0, device->base + TSPP2_FILTER_KEY_FETCH_FAILURE(index));
-	writel_relaxed(0, device->base + TSPP2_FILTER_DROPPED_PCR(index));
-	writel_relaxed(0, device->base + TSPP2_FILTER_PES_ERRORS(index));
-}
-
-/**
- * tspp2_global_hw_reset() - Reset TSPP2 device registers to a default state.
- *
- * @device:		TSPP2 device.
- * @enable_intr:	Enable specific interrupts or disable them.
- *
- * A helper function called from probe() and remove(), this function resets both
- * TSIF devices' SW structures and verifies the TSIF HW is stopped. It resets
- * TSPP2 registers to appropriate default values and makes sure to disable
- * all sources, filters etc. Finally, it clears all interrupts and unmasks
- * the "important" interrupts.
- *
- * Return 0 on success, error value otherwise.
- */
-static int tspp2_global_hw_reset(struct tspp2_device *device,
-				int enable_intr)
-{
-	int i, n;
-	unsigned long rate_in_hz = 0;
-	u32 global_irq_en = 0;
-
-	if (!device) {
-		pr_err("%s: NULL device\n", __func__);
-		return -ENODEV;
-	}
-
-	/* Stop TSIF devices */
-	for (i = 0; i < TSPP2_NUM_TSIF_INPUTS; i++) {
-		device->tsif_devices[i].hw_index = i;
-		device->tsif_devices[i].dev = device;
-		device->tsif_devices[i].mode = TSPP2_TSIF_MODE_2;
-		device->tsif_devices[i].clock_inverse = 0;
-		device->tsif_devices[i].data_inverse = 0;
-		device->tsif_devices[i].sync_inverse = 0;
-		device->tsif_devices[i].enable_inverse = 0;
-		device->tsif_devices[i].stat_pkt_write_err = 0;
-		device->tsif_devices[i].stat_pkt_read_err = 0;
-		device->tsif_devices[i].stat_overflow = 0;
-		device->tsif_devices[i].stat_lost_sync = 0;
-		device->tsif_devices[i].stat_timeout = 0;
-		device->tsif_devices[i].time_limit = TSPP2_TSIF_DEF_TIME_LIMIT;
-		/* Set ref_count to 1 to allow stopping HW */
-		device->tsif_devices[i].ref_count = 1;
-		/* This will reset ref_count to 0 */
-		tspp2_tsif_stop(&device->tsif_devices[i]);
-	}
-
-	/* Reset indexing table registers */
-	for (i = 0; i < TSPP2_NUM_INDEXING_TABLES; i++) {
-		writel_relaxed(0, device->base + TSPP2_INDEX_TABLE_PREFIX(i));
-		writel_relaxed(0,
-			device->base + TSPP2_INDEX_TABLE_PREFIX_MASK(i));
-		for (n = 0; n < TSPP2_NUM_INDEXING_PATTERNS; n++) {
-			writel_relaxed(0, device->base +
-					TSPP2_INDEX_TABLE_PATTEREN(i, n));
-			writel_relaxed(0,
-				device->base + TSPP2_INDEX_TABLE_MASK(i, n));
-		}
-		/* Set number of patterns to 0, prefix size to 4 by default */
-		writel_relaxed(0x00000400,
-			device->base + TSPP2_INDEX_TABLE_PARAMS(i));
-	}
-
-	/* Disable TSIF inputs. Set mode of operation to 16 batches */
-	for (i = 0; i < TSPP2_NUM_TSIF_INPUTS; i++)
-		writel_relaxed((0x1 << TSIF_INPUT_SRC_CONFIG_16_BATCHES_OFFS),
-			device->base + TSPP2_TSIF_INPUT_SRC_CONFIG(i));
-
-	/* Reset source related registers and performance counters */
-	for (i = 0; i < TSPP2_NUM_ALL_INPUTS; i++) {
-		writel_relaxed(0, device->base + TSPP2_SRC_DEST_PIPES(i));
-
-		/* Set source configuration to default values */
-		writel_relaxed(TSPP2_DEFAULT_SRC_CONFIG,
-			device->base + TSPP2_SRC_CONFIG(i));
-	}
-	writel_relaxed(0x000003FF, device->base + TSPP2_SRC_TOTAL_TSP_RESET);
-	writel_relaxed(0x000003FF,
-		device->base + TSPP2_SRC_FILTERED_OUT_TSP_RESET);
-
-	/* Reset all contexts, each register handles 32 contexts */
-	for (i = 0; i < 4; i++) {
-		writel_relaxed(0xFFFFFFFF,
-			device->base + TSPP2_TSP_CONTEXT_RESET(i));
-		writel_relaxed(0xFFFFFFFF,
-			device->base + TSPP2_PES_CONTEXT_RESET(i));
-		writel_relaxed(0xFFFFFFFF,
-			device->base + TSPP2_INDEXING_CONTEXT_RESET(i));
-	}
-
-	for (i = 0; i < TSPP2_NUM_HW_FILTERS; i++) {
-		/*
-		 * Reset operations: put exit operation in all filter operations
-		 */
-		for (n = 0; n < TSPP2_MAX_OPS_PER_FILTER; n++) {
-			writel_relaxed(TSPP2_OPCODE_EXIT,
-				device->base + TSPP2_OPCODE(i, n));
-		}
-		/* Disable all HW filters */
-		writel_relaxed(0, device->base + TSPP2_FILTER_ENTRY0(i));
-		writel_relaxed(0, device->base + TSPP2_FILTER_ENTRY1(i));
-	}
-
-	for (i = 0; i < TSPP2_NUM_CONTEXTS; i++) {
-		/* Reset filter context-based counters */
-		tspp2_filter_counters_reset(device, i);
-	}
-
-	/*
-	 * Disable memory inputs. Set mode of operation to 16 batches.
-	 * Configure last batch to be associated with all memory input sources,
-	 * and add a filter to match all PIDs and drop the TS packets in the
-	 * last HW filter entry. Use the last context for this filter.
-	 */
-	for (i = 0; i < TSPP2_NUM_MEM_INPUTS; i++)
-		writel_relaxed(TSPP2_DEFAULT_MEM_SRC_CONFIG,
-			device->base + TSPP2_MEM_INPUT_SRC_CONFIG(i));
-
-	writel_relaxed(((TSPP2_NUM_CONTEXTS - 1) << FILTER_ENTRY1_CONTEXT_OFFS),
-		device->base + TSPP2_FILTER_ENTRY1((TSPP2_NUM_HW_FILTERS - 1)));
-	writel_relaxed((0x1 << FILTER_ENTRY0_EN_OFFS),
-		device->base + TSPP2_FILTER_ENTRY0((TSPP2_NUM_HW_FILTERS - 1)));
-
-	/* Reset pipe registers */
-	for (i = 0; i < TSPP2_NUM_PIPES; i++)
-		writel_relaxed(0xFFFF,
-			device->base + TSPP2_PIPE_THRESH_CONFIG(i));
-
-	writel_relaxed(0, device->base + TSPP2_PIPE_SECURITY);
-	writel_relaxed(0x7FFFFFFF,
-		device->base + TSPP2_DATA_NOT_SENT_ON_PIPE_RESET);
-
-	/* Set global configuration to default values */
-
-	/*
-	 * Default: minimum time between PCRs = 50msec, STC offset is 0,
-	 * transmit PCR on discontinuity.
-	 */
-	writel_relaxed(0x00000432, device->base + TSPP2_PCR_GLOBAL_CONFIG);
-
-	/* Set correct value according to TSPP2 clock: */
-	if (device->tspp2_core_clk) {
-		rate_in_hz = clk_get_rate(device->tspp2_core_clk);
-		writel_relaxed((rate_in_hz / MSEC_PER_SEC),
-			device->base + TSPP2_CLK_TO_PCR_TIME_UNIT);
-	} else {
-		writel_relaxed(0x00000000,
-			device->base + TSPP2_CLK_TO_PCR_TIME_UNIT);
-	}
-
-	writel_relaxed(0x00000000, device->base + TSPP2_DESC_WAIT_TIMEOUT);
-
-	/* Clear all global interrupts */
-	writel_relaxed(0xFFFF000F, device->base + TSPP2_GLOBAL_IRQ_CLEAR);
-	writel_relaxed(0x7FFFFFFF,
-			device->base + TSPP2_UNEXPECTED_RST_IRQ_CLEAR);
-	writel_relaxed(0x7FFFFFFF,
-			device->base + TSPP2_WRONG_PIPE_DIR_IRQ_CLEAR);
-	writel_relaxed(0x7FFFFFFF,
-			device->base + TSPP2_QSB_RESPONSE_ERROR_IRQ_CLEAR);
-	writel_relaxed(0xFFFFFFFF,
-			device->base + TSPP2_KEY_NOT_READY_IRQ_CLEAR);
-
-	/*
-	 * Global interrupts configuration:
-	 * Flow Control (per memory source):	Disabled
-	 * Read Failure (per memory source):	Enabled
-	 * SC_GO_LOW (aggregate):		Enabled
-	 * SC_GO_HIGH (aggregate):		Enabled
-	 * Wrong Pipe Direction (aggregate):	Enabled
-	 * QSB Response Error (aggregate):	Enabled
-	 * Unexpected Reset (aggregate):	Enabled
-	 * Key Not Ready (aggregate):		Disabled
-	 * Op Encrypt Level Error:		Enabled
-	 * PES No Sync:				Disabled (module parameter)
-	 * TSP Invalid Length:			Disabled (module parameter)
-	 * TSP Invalid AF Control:		Disabled (module parameter)
-	 */
-	global_irq_en = 0x00FF03E8;
-	if (tspp2_en_invalid_af_ctrl)
-		global_irq_en |=
-			(0x1 << GLOBAL_IRQ_TSP_INVALID_AF_OFFS);
-	if (tspp2_en_invalid_af_length)
-		global_irq_en |= (0x1 << GLOBAL_IRQ_TSP_INVALID_LEN_OFFS);
-	if (tspp2_en_pes_no_sync)
-		global_irq_en |= (0x1 << GLOBAL_IRQ_PES_NO_SYNC_OFFS);
-
-	if (enable_intr)
-		writel_relaxed(global_irq_en,
-			device->base + TSPP2_GLOBAL_IRQ_ENABLE);
-	else
-		writel_relaxed(0, device->base + TSPP2_GLOBAL_IRQ_ENABLE);
-
-	if (enable_intr) {
-		/* Enable all pipe related interrupts */
-		writel_relaxed(0x7FFFFFFF,
-			device->base + TSPP2_UNEXPECTED_RST_IRQ_ENABLE);
-		writel_relaxed(0x7FFFFFFF,
-			device->base + TSPP2_WRONG_PIPE_DIR_IRQ_ENABLE);
-		writel_relaxed(0x7FFFFFFF,
-			device->base + TSPP2_QSB_RESPONSE_ERROR_IRQ_ENABLE);
-	} else {
-		/* Disable all pipe related interrupts */
-		writel_relaxed(0,
-			device->base + TSPP2_UNEXPECTED_RST_IRQ_ENABLE);
-		writel_relaxed(0,
-			device->base + TSPP2_WRONG_PIPE_DIR_IRQ_ENABLE);
-		writel_relaxed(0,
-			device->base + TSPP2_QSB_RESPONSE_ERROR_IRQ_ENABLE);
-	}
-
-	/* Disable Key Ladder interrupts */
-	writel_relaxed(0, device->base + TSPP2_KEY_NOT_READY_IRQ_ENABLE);
-
-	/*
-	 * Clear and disable scrambling control interrupts.
-	 * Each register handles 32 filters.
-	 */
-	for (i = 0; i < 4; i++) {
-		writel_relaxed(0xFFFFFFFF,
-			device->base + TSPP2_SC_GO_HIGH_CLEAR(i));
-		writel_relaxed(0, device->base + TSPP2_SC_GO_HIGH_ENABLE(i));
-		writel_relaxed(0xFFFFFFFF,
-			device->base + TSPP2_SC_GO_LOW_CLEAR(i));
-		writel_relaxed(0, device->base + TSPP2_SC_GO_LOW_ENABLE(i));
-	}
-
-	dev_dbg(device->dev, "%s: successful\n", __func__);
-
-	return 0;
-}
-
-/**
- * tspp2_event_work_handler - Handle the work - invoke the user callback.
- *
- * @work:	The work information.
- */
-static void tspp2_event_work_handler(struct work_struct *work)
-{
-	struct tspp2_event_work *event_work =
-		container_of(work, struct tspp2_event_work, work);
-	struct tspp2_event_work cb_info = *event_work;
-
-	if (mutex_lock_interruptible(&event_work->device->mutex))
-		return;
-
-	list_add_tail(&event_work->link, &event_work->device->free_work_list);
-
-	mutex_unlock(&event_work->device->mutex);
-
-	/*
-	 * Must run callback with tspp2 device mutex unlocked,
-	 * as callback might call tspp2 driver API and cause a deadlock.
-	 */
-	if (cb_info.callback)
-		cb_info.callback(cb_info.cookie, cb_info.event_bitmask);
-}
-
-/**
- * tspp2_device_initialize() - Initialize TSPP2 device SW structures.
- *
- * @device:	TSPP2 device
- *
- * Initialize the required SW structures and fields in the TSPP2 device,
- * including ION client creation, BAM registration, debugfs initialization etc.
- *
- * Return 0 on success, error value otherwise.
- */
-static int tspp2_device_initialize(struct tspp2_device *device)
-{
-	int i, ret;
-
-	if (!device) {
-		pr_err("%s: NULL device\n", __func__);
-		return -ENODEV;
-	}
-
-	/* Register BAM */
-	device->bam_props.summing_threshold = 0x10;
-	device->bam_props.irq = device->bam_irq;
-	device->bam_props.manage = SPS_BAM_MGR_LOCAL;
-
-	ret = sps_register_bam_device(&device->bam_props, &device->bam_handle);
-	if (ret) {
-		pr_err("%s: failed to register BAM\n", __func__);
-		return ret;
-	}
-	ret = sps_device_reset(device->bam_handle);
-	if (ret) {
-		sps_deregister_bam_device(device->bam_handle);
-		pr_err("%s: error resetting BAM\n", __func__);
-		return ret;
-	}
-
-	spin_lock_init(&device->spinlock);
-	wakeup_source_init(&device->wakeup_src, dev_name(&device->pdev->dev));
-
-	for (i = 0; i < TSPP2_NUM_TSIF_INPUTS; i++)
-		tspp2_tsif_debugfs_init(&device->tsif_devices[i]);
-
-	/*
-	 * The device structure was allocated using devm_kzalloc() so
-	 * the memory was initialized to zero. We don't need to specifically set
-	 * fields to zero, then. We only set the fields we need to, such as
-	 * batch_id.
-	 */
-
-	for (i = 0; i < TSPP2_NUM_BATCHES; i++) {
-		device->batches[i].batch_id = i;
-		device->batches[i].src = NULL;
-		INIT_LIST_HEAD(&device->batches[i].link);
-	}
-
-	/*
-	 * We set the device back-pointer in the sources, filters and pipes
-	 * databases here, so that back-pointer is always valid (instead of
-	 * setting it when opening a source, filter or pipe).
-	 */
-	for (i = 0; i < TSPP2_NUM_TSIF_INPUTS; i++)
-		device->tsif_sources[i].device = device;
-
-	for (i = 0; i < TSPP2_NUM_MEM_INPUTS; i++)
-		device->mem_sources[i].device = device;
-
-	for (i = 0; i < TSPP2_NUM_AVAIL_FILTERS; i++)
-		device->filters[i].device = device;
-
-	for (i = 0; i < TSPP2_NUM_PIPES; i++)
-		device->pipes[i].device = device;
-
-	/*
-	 * Note: tsif_devices are initialized as part of tspp2_global_hw_reset()
-	 */
-
-	device->work_queue =
-			create_singlethread_workqueue(dev_name(device->dev));
-	INIT_LIST_HEAD(&device->free_work_list);
-	for (i = 0; i < TSPP2_NUM_EVENT_WORK_ELEMENTS; i++) {
-		device->work_pool[i].device = device;
-		device->work_pool[i].callback = 0;
-		device->work_pool[i].cookie = 0;
-		device->work_pool[i].event_bitmask = 0;
-		INIT_LIST_HEAD(&device->work_pool[i].link);
-		INIT_WORK(&device->work_pool[i].work,
-			tspp2_event_work_handler);
-
-		list_add_tail(&device->work_pool[i].link,
-			&device->free_work_list);
-	}
-
-	device->event_callback = NULL;
-	device->event_cookie = NULL;
-
-	dev_dbg(device->dev, "%s: successful\n", __func__);
-
-	return 0;
-}
-
-/**
- * tspp2_device_uninitialize() - TSPP2 device teardown and cleanup.
- *
- * @device:	TSPP2 device
- *
- * TSPP2 device teardown: debugfs removal, BAM de-registration etc.
- * Return 0 on success, error value otherwise.
- */
-static int tspp2_device_uninitialize(struct tspp2_device *device)
-{
-	int i;
-
-	if (!device) {
-		pr_err("%s: NULL device\n", __func__);
-		return -ENODEV;
-	}
-
-	destroy_workqueue(device->work_queue);
-
-	for (i = 0; i < TSPP2_NUM_TSIF_INPUTS; i++)
-		tspp2_tsif_debugfs_exit(&device->tsif_devices[i]);
-
-	/* Need to start clocks for BAM de-registration */
-	if (pm_runtime_get_sync(device->dev) >= 0) {
-		sps_deregister_bam_device(device->bam_handle);
-		pm_runtime_mark_last_busy(device->dev);
-		pm_runtime_put_autosuspend(device->dev);
-	}
-
-	wakeup_source_trash(&device->wakeup_src);
-
-	dev_dbg(device->dev, "%s: successful\n", __func__);
-
-	return 0;
-}
-
-/**
- * tspp2_src_disable_internal() - Helper function to disable a source.
- *
- * @src: Source to disable.
- *
- * Return 0 on success, error value otherwise.
- */
-static int tspp2_src_disable_internal(struct tspp2_src *src)
-{
-	u32 reg;
-
-	if (!src) {
-		pr_err("%s: Invalid source handle\n", __func__);
-		return -EINVAL;
-	}
-
-	if (!src->opened) {
-		pr_err("%s: Source not opened\n", __func__);
-		return -EINVAL;
-	}
-
-	if (!src->enabled) {
-		pr_warn("%s: Source already disabled\n", __func__);
-		return 0;
-	}
-
-	if ((src->input == TSPP2_INPUT_TSIF0) ||
-		(src->input == TSPP2_INPUT_TSIF1)) {
-		reg = readl_relaxed(src->device->base +
-			TSPP2_TSIF_INPUT_SRC_CONFIG(src->input));
-		reg &= ~(0x1 << TSIF_INPUT_SRC_CONFIG_INPUT_EN_OFFS);
-		writel_relaxed(reg, src->device->base +
-			TSPP2_TSIF_INPUT_SRC_CONFIG(src->input));
-
-		tspp2_tsif_stop(&src->device->tsif_devices[src->input]);
-	} else {
-		reg = readl_relaxed(src->device->base +
-			TSPP2_MEM_INPUT_SRC_CONFIG(src->hw_index));
-		reg &= ~(0x1 << MEM_INPUT_SRC_CONFIG_INPUT_EN_OFFS);
-		writel_relaxed(reg, src->device->base +
-			TSPP2_MEM_INPUT_SRC_CONFIG(src->hw_index));
-	}
-
-	/*
-	 * HW requires we wait for up to 2ms here before closing the pipes
-	 * attached to (and used by) this source
-	 */
-	udelay(TSPP2_HW_DELAY_USEC);
-
-	src->enabled = 0;
-	src->device->num_enabled_sources--;
-
-	if (src->device->num_enabled_sources == 0) {
-		__pm_relax(&src->device->wakeup_src);
-		tspp2_clock_stop(src->device);
-	}
-
-	return 0;
-}
-
-/* TSPP2 device open / close API */
-
-/**
- * tspp2_device_open() - Open a TSPP2 device for use.
- *
- * @dev_id:	TSPP2 device ID.
- *
- * Return 0 on success, error value otherwise.
- */
-int tspp2_device_open(u32 dev_id)
-{
-	int rc;
-	u32 reg = 0;
-	struct tspp2_device *device;
-
-	if (dev_id >= TSPP2_NUM_DEVICES) {
-		pr_err("%s: Invalid device ID %d\n", __func__, dev_id);
-		return -ENODEV;
-	}
-
-	device = tspp2_devices[dev_id];
-	if (!device) {
-		pr_err("%s: Invalid device\n", __func__);
-		return -ENODEV;
-	}
-
-	if (mutex_lock_interruptible(&device->mutex))
-		return -ERESTARTSYS;
-
-	if (device->opened) {
-		pr_err("%s: Device already opened\n", __func__);
-		mutex_unlock(&device->mutex);
-		return -EPERM;
-	}
-
-	/* Enable power regulator */
-	rc = regulator_enable(device->gdsc);
-	if (rc)
-		goto err_mutex_unlock;
-
-	/* Reset TSPP2 core */
-	clk_reset(device->tspp2_core_clk, CLK_RESET_ASSERT);
-	udelay(10);
-	clk_reset(device->tspp2_core_clk, CLK_RESET_DEASSERT);
-
-	/* Start HW clocks before accessing registers */
-	rc = tspp2_reg_clock_start(device);
-	if (rc)
-		goto err_regulator_disable;
-
-	rc = tspp2_global_hw_reset(device, 1);
-	if (rc)
-		goto err_stop_clocks;
-
-	rc = tspp2_device_initialize(device);
-	if (rc)
-		goto err_stop_clocks;
-
-	reg = readl_relaxed(device->base + TSPP2_VERSION);
-	pr_info("TSPP2 HW Version: Major = %d, Minor = %d, Step = %d\n",
-		((reg & 0xF0000000) >> VERSION_MAJOR_OFFS),
-		((reg & 0x0FFF0000) >> VERSION_MINOR_OFFS),
-		((reg & 0x0000FFFF) >> VERSION_STEP_OFFS));
-
-	/* Stop HW clocks to save power */
-	tspp2_reg_clock_stop(device);
-
-	/* Enable runtime power management */
-	pm_runtime_set_autosuspend_delay(device->dev, MSEC_PER_SEC);
-	pm_runtime_use_autosuspend(device->dev);
-	pm_runtime_enable(device->dev);
-
-	device->opened = 1;
-
-	mutex_unlock(&device->mutex);
-
-	dev_dbg(device->dev, "%s: successful\n", __func__);
-
-	return 0;
-
-err_stop_clocks:
-	tspp2_reg_clock_stop(device);
-err_regulator_disable:
-	regulator_disable(device->gdsc);
-err_mutex_unlock:
-	mutex_unlock(&device->mutex);
-
-	return rc;
-}
-EXPORT_SYMBOL(tspp2_device_open);
-
-/**
- * tspp2_device_close() - Close a TSPP2 device.
- *
- * @dev_id:	TSPP2 device ID.
- *
- * Return 0 on success, error value otherwise.
- */
-int tspp2_device_close(u32 dev_id)
-{
-	int i;
-	int ret = 0;
-	struct tspp2_device *device;
-
-	if (dev_id >= TSPP2_NUM_DEVICES) {
-		pr_err("%s: Invalid device ID %d\n", __func__, dev_id);
-		return -ENODEV;
-	}
-
-	device = tspp2_devices[dev_id];
-	if (!device) {
-		pr_err("%s: Invalid device\n", __func__);
-		return -ENODEV;
-	}
-
-	ret = pm_runtime_get_sync(device->dev);
-	if (ret < 0)
-		return ret;
-
-	mutex_lock(&device->mutex);
-
-	if (!device->opened) {
-		pr_err("%s: Device already closed\n", __func__);
-		mutex_unlock(&device->mutex);
-		pm_runtime_mark_last_busy(device->dev);
-		pm_runtime_put_autosuspend(device->dev);
-		return -EPERM;
-	}
-	device->opened = 0;
-
-	/*
-	 * In case the user has not disabled all the enabled sources, we need
-	 * to disable them here, specifically in order to call tspp2_clock_stop,
-	 * because the calls to enable and disable the clocks should be
-	 * symmetrical (otherwise we cannot put the clocks).
-	 */
-	for (i = 0; i < TSPP2_NUM_TSIF_INPUTS; i++) {
-		if (device->tsif_sources[i].enabled)
-			tspp2_src_disable_internal(&device->tsif_sources[i]);
-	}
-	for (i = 0; i < TSPP2_NUM_MEM_INPUTS; i++) {
-		if (device->mem_sources[i].enabled)
-			tspp2_src_disable_internal(&device->mem_sources[i]);
-	}
-
-	/* bring HW registers back to a known state */
-	tspp2_global_hw_reset(device, 0);
-
-	tspp2_device_uninitialize(device);
-
-	pm_runtime_mark_last_busy(device->dev);
-	pm_runtime_put_autosuspend(device->dev);
-
-	/* Disable runtime power management */
-	pm_runtime_disable(device->dev);
-	pm_runtime_set_suspended(device->dev);
-
-	if (regulator_disable(device->gdsc))
-		pr_err("%s: Error disabling power regulator\n", __func__);
-
-	mutex_unlock(&device->mutex);
-
-	dev_dbg(device->dev, "%s: successful\n", __func__);
-
-	return 0;
-}
-EXPORT_SYMBOL(tspp2_device_close);
-
-/* Global configuration API */
-
-/**
- * tspp2_config_set() - Set device global configuration.
- *
- * @dev_id:	TSPP2 device ID.
- * @cfg:	TSPP2 global configuration parameters to set.
- *
- * Return 0 on success, error value otherwise.
- */
-int tspp2_config_set(u32 dev_id, const struct tspp2_config *cfg)
-{
-	int ret;
-	u32 reg = 0;
-	struct tspp2_device *device;
-
-	if (dev_id >= TSPP2_NUM_DEVICES) {
-		pr_err("%s: Invalid device ID %d\n", __func__, dev_id);
-		return -ENODEV;
-	}
-	if (!cfg) {
-		pr_err("%s: NULL configuration\n", __func__);
-		return -EINVAL;
-	}
-	if (cfg->stc_byte_offset > 3) {
-		pr_err("%s: Invalid stc_byte_offset %d, valid values are 0 - 3\n",
-			__func__, cfg->stc_byte_offset);
-		return -EINVAL;
-	}
-
-	device = tspp2_devices[dev_id];
-	if (!device) {
-		pr_err("%s: Invalid device\n", __func__);
-		return -ENODEV;
-	}
-
-	ret = pm_runtime_get_sync(device->dev);
-	if (ret < 0)
-		return ret;
-
-	if (mutex_lock_interruptible(&device->mutex)) {
-		pm_runtime_mark_last_busy(device->dev);
-		pm_runtime_put_autosuspend(device->dev);
-		return -ERESTARTSYS;
-	}
-
-	if (!device->opened) {
-		pr_err("%s: Device must be opened first\n", __func__);
-		mutex_unlock(&device->mutex);
-		pm_runtime_mark_last_busy(device->dev);
-		pm_runtime_put_autosuspend(device->dev);
-		return -EPERM;
-	}
-
-	if (cfg->pcr_on_discontinuity)
-		reg |= (0x1 << PCR_GLOBAL_CONFIG_PCR_ON_DISCONT_OFFS);
-
-	reg |= (cfg->stc_byte_offset << PCR_GLOBAL_CONFIG_STC_OFFSET_OFFS);
-	reg |= (cfg->min_pcr_interval << PCR_GLOBAL_CONFIG_PCR_INTERVAL_OFFS);
-
-	writel_relaxed(reg, device->base + TSPP2_PCR_GLOBAL_CONFIG);
-
-	mutex_unlock(&device->mutex);
-
-	pm_runtime_mark_last_busy(device->dev);
-	pm_runtime_put_autosuspend(device->dev);
-
-	dev_dbg(device->dev, "%s: successful\n", __func__);
-
-	return 0;
-}
-EXPORT_SYMBOL(tspp2_config_set);
-
-/**
- * tspp2_config_get() - Get current global configuration.
- *
- * @dev_id:	TSPP2 device ID.
- * @cfg:	TSPP2 global configuration parameters.
- *
- * Return 0 on success, error value otherwise.
- */
-int tspp2_config_get(u32 dev_id, struct tspp2_config *cfg)
-{
-	int ret;
-	u32 reg = 0;
-	struct tspp2_device *device;
-
-	if (dev_id >= TSPP2_NUM_DEVICES) {
-		pr_err("%s: Invalid device ID %d\n", __func__, dev_id);
-		return -ENODEV;
-	}
-	if (!cfg) {
-		pr_err("%s: NULL configuration\n", __func__);
-		return -EINVAL;
-	}
-
-	device = tspp2_devices[dev_id];
-	if (!device) {
-		pr_err("%s: Invalid device\n", __func__);
-		return -ENODEV;
-	}
-
-	ret = pm_runtime_get_sync(device->dev);
-	if (ret < 0)
-		return ret;
-
-	if (mutex_lock_interruptible(&device->mutex)) {
-		pm_runtime_mark_last_busy(device->dev);
-		pm_runtime_put_autosuspend(device->dev);
-		return -ERESTARTSYS;
-	}
-
-	if (!device->opened) {
-		pr_err("%s: Device must be opened first\n", __func__);
-		mutex_unlock(&device->mutex);
-		pm_runtime_mark_last_busy(device->dev);
-		pm_runtime_put_autosuspend(device->dev);
-		return -EPERM;
-	}
-
-	reg = readl_relaxed(device->base + TSPP2_PCR_GLOBAL_CONFIG);
-
-	cfg->pcr_on_discontinuity = ((reg & PCR_GLOBAL_CONFIG_PCR_ON_DISCONT) >>
-					PCR_GLOBAL_CONFIG_PCR_ON_DISCONT_OFFS);
-	cfg->stc_byte_offset = ((reg & PCR_GLOBAL_CONFIG_STC_OFFSET) >>
-					PCR_GLOBAL_CONFIG_STC_OFFSET_OFFS);
-	cfg->min_pcr_interval = ((reg & PCR_GLOBAL_CONFIG_PCR_INTERVAL) >>
-					PCR_GLOBAL_CONFIG_PCR_INTERVAL_OFFS);
-
-	mutex_unlock(&device->mutex);
-
-	pm_runtime_mark_last_busy(device->dev);
-	pm_runtime_put_autosuspend(device->dev);
-
-	dev_dbg(device->dev, "%s: successful\n", __func__);
-
-	return 0;
-}
-EXPORT_SYMBOL(tspp2_config_get);
-
-/* Indexing tables API functions */
-
-/**
- * tspp2_indexing_prefix_set() - Set prefix value and mask of an indexing table.
- *
- * @dev_id:	TSPP2 device ID.
- * @table_id:	Indexing table ID.
- * @value:	Prefix 4-byte value.
- * @mask:	Prefix 4-byte mask.
- *
- * Return 0 on success, error value otherwise.
- */
-int tspp2_indexing_prefix_set(u32 dev_id,
-				u8 table_id,
-				u32 value,
-				u32 mask)
-{
-	int ret;
-	u32 reg;
-	u8 size = 0;
-	int i;
-	struct tspp2_device *device;
-	struct tspp2_indexing_table *table;
-
-	if (dev_id >= TSPP2_NUM_DEVICES) {
-		pr_err("%s: Invalid device ID %d\n", __func__, dev_id);
-		return -ENODEV;
-	}
-	if (table_id >= TSPP2_NUM_INDEXING_TABLES) {
-		pr_err("%s: Invalid table ID %d\n", __func__, table_id);
-		return -EINVAL;
-	}
-
-	device = tspp2_devices[dev_id];
-	if (!device) {
-		pr_err("%s: Invalid device\n", __func__);
-		return -ENODEV;
-	}
-
-	ret = pm_runtime_get_sync(device->dev);
-	if (ret < 0)
-		return ret;
-
-	if (mutex_lock_interruptible(&device->mutex)) {
-		pm_runtime_mark_last_busy(device->dev);
-		pm_runtime_put_autosuspend(device->dev);
-		return -ERESTARTSYS;
-	}
-
-	if (!device->opened) {
-		pr_err("%s: Device must be opened first\n", __func__);
-		mutex_unlock(&device->mutex);
-		pm_runtime_mark_last_busy(device->dev);
-		pm_runtime_put_autosuspend(device->dev);
-		return -EPERM;
-	}
-
-	table = &device->indexing_tables[table_id];
-	table->prefix_value = value;
-	table->prefix_mask = mask;
-
-	/* HW expects values/masks to be written in Big Endian format */
-	writel_relaxed(cpu_to_be32(value),
-		device->base + TSPP2_INDEX_TABLE_PREFIX(table_id));
-	writel_relaxed(cpu_to_be32(mask),
-		device->base + TSPP2_INDEX_TABLE_PREFIX_MASK(table_id));
-
-	/* Find the actual size of the prefix and set to HW */
-	reg = readl_relaxed(device->base + TSPP2_INDEX_TABLE_PARAMS(table_id));
-	for (i = 0; i < 32; i += 8) {
-		if (mask & (0x000000FF << i))
-			size++;
-	}
-	reg &= ~(0x7 << INDEX_TABLE_PARAMS_PREFIX_SIZE_OFFS);
-	reg |= (size << INDEX_TABLE_PARAMS_PREFIX_SIZE_OFFS);
-	writel_relaxed(reg, device->base + TSPP2_INDEX_TABLE_PARAMS(table_id));
-
-	mutex_unlock(&device->mutex);
-
-	pm_runtime_mark_last_busy(device->dev);
-	pm_runtime_put_autosuspend(device->dev);
-
-	dev_dbg(device->dev, "%s: successful\n", __func__);
-
-	return 0;
-}
-EXPORT_SYMBOL(tspp2_indexing_prefix_set);
-
-/**
- * tspp2_indexing_patterns_add() - Add patterns to an indexing table.
- *
- * @dev_id:		TSPP2 device ID.
- * @table_id:		Indexing table ID.
- * @values:		An array of 4-byte pattern values.
- * @masks:		An array of corresponding 4-byte masks.
- * @patterns_num:	Number of patterns in the values / masks arrays.
- *			Up to TSPP2_NUM_INDEXING_PATTERNS.
- *
- * Return 0 on success, error value otherwise.
- */
-int tspp2_indexing_patterns_add(u32 dev_id,
-				u8 table_id,
-				const u32 *values,
-				const u32 *masks,
-				u8 patterns_num)
-{
-	int ret;
-	int i;
-	u16 offs = 0;
-	u32 reg;
-	struct tspp2_device *device;
-	struct tspp2_indexing_table *table;
-
-	if (dev_id >= TSPP2_NUM_DEVICES) {
-		pr_err("%s: Invalid device ID %d\n", __func__, dev_id);
-		return -ENODEV;
-	}
-	if (table_id >= TSPP2_NUM_INDEXING_TABLES) {
-		pr_err("%s: Invalid table ID %d\n", __func__, table_id);
-		return -EINVAL;
-	}
-	if (!values || !masks) {
-		pr_err("%s: NULL values or masks array\n", __func__);
-		return -EINVAL;
-	}
-
-	device = tspp2_devices[dev_id];
-	if (!device) {
-		pr_err("%s: Invalid device\n", __func__);
-		return -ENODEV;
-	}
-
-	ret = pm_runtime_get_sync(device->dev);
-	if (ret < 0)
-		return ret;
-
-	if (mutex_lock_interruptible(&device->mutex)) {
-		pm_runtime_mark_last_busy(device->dev);
-		pm_runtime_put_autosuspend(device->dev);
-		return -ERESTARTSYS;
-	}
-
-	if (!device->opened) {
-		pr_err("%s: Device must be opened first\n", __func__);
-		mutex_unlock(&device->mutex);
-		pm_runtime_mark_last_busy(device->dev);
-		pm_runtime_put_autosuspend(device->dev);
-		return -EPERM;
-	}
-
-	table = &device->indexing_tables[table_id];
-
-	if ((table->num_valid_entries + patterns_num) >
-			TSPP2_NUM_INDEXING_PATTERNS) {
-		pr_err("%s: Trying to add too many patterns: current number %d, trying to add %d, maximum allowed %d\n",
-			__func__, table->num_valid_entries, patterns_num,
-			TSPP2_NUM_INDEXING_PATTERNS);
-		mutex_unlock(&device->mutex);
-		pm_runtime_mark_last_busy(device->dev);
-		pm_runtime_put_autosuspend(device->dev);
-		return -EINVAL;
-	}
-
-	/* There's enough room to add all the requested patterns */
-	offs = table->num_valid_entries;
-	for (i = 0; i < patterns_num; i++) {
-		table->entry_value[offs + i] = values[i];
-		table->entry_mask[offs + i] = masks[i];
-		writel_relaxed(cpu_to_be32(values[i]),
-			device->base +
-				TSPP2_INDEX_TABLE_PATTEREN(table_id, offs + i));
-		writel_relaxed(cpu_to_be32(masks[i]), device->base +
-				TSPP2_INDEX_TABLE_MASK(table_id, offs + i));
-	}
-	table->num_valid_entries += patterns_num;
-	reg = readl_relaxed(device->base + TSPP2_INDEX_TABLE_PARAMS(table_id));
-	reg &= ~(0x1F << INDEX_TABLE_PARAMS_NUM_PATTERNS_OFFS);
-	reg |= (table->num_valid_entries <<
-			INDEX_TABLE_PARAMS_NUM_PATTERNS_OFFS);
-	writel_relaxed(reg, device->base + TSPP2_INDEX_TABLE_PARAMS(table_id));
-
-	mutex_unlock(&device->mutex);
-
-	pm_runtime_mark_last_busy(device->dev);
-	pm_runtime_put_autosuspend(device->dev);
-
-	dev_dbg(device->dev, "%s: successful\n", __func__);
-
-	return 0;
-}
-EXPORT_SYMBOL(tspp2_indexing_patterns_add);
-
-/**
- * tspp2_indexing_patterns_clear() - Clear all patterns of an indexing table.
- *
- * @dev_id:	TSPP2 device ID.
- * @table_id:	Indexing table ID.
- *
- * Return 0 on success, error value otherwise.
- */
-int tspp2_indexing_patterns_clear(u32 dev_id,
-				u8 table_id)
-{
-	int ret;
-	int i;
-	u32 reg;
-	struct tspp2_device *device;
-	struct tspp2_indexing_table *table;
-
-	if (dev_id >= TSPP2_NUM_DEVICES) {
-		pr_err("%s: Invalid device ID %d\n", __func__, dev_id);
-		return -ENODEV;
-	}
-	if (table_id >= TSPP2_NUM_INDEXING_TABLES) {
-		pr_err("%s: Invalid table ID %d\n", __func__, table_id);
-		return -EINVAL;
-	}
-
-	device = tspp2_devices[dev_id];
-	if (!device) {
-		pr_err("%s: Invalid device\n", __func__);
-		return -ENODEV;
-	}
-
-	ret = pm_runtime_get_sync(device->dev);
-	if (ret < 0)
-		return ret;
-
-	if (mutex_lock_interruptible(&device->mutex)) {
-		pm_runtime_mark_last_busy(device->dev);
-		pm_runtime_put_autosuspend(device->dev);
-		return -ERESTARTSYS;
-	}
-
-	if (!device->opened) {
-		pr_err("%s: Device must be opened first\n", __func__);
-		mutex_unlock(&device->mutex);
-		pm_runtime_mark_last_busy(device->dev);
-		pm_runtime_put_autosuspend(device->dev);
-		return -EPERM;
-	}
-
-	table = &device->indexing_tables[table_id];
-
-	for (i = 0; i < table->num_valid_entries; i++) {
-		table->entry_value[i] = 0;
-		table->entry_mask[i] = 0;
-		writel_relaxed(0, device->base +
-				TSPP2_INDEX_TABLE_PATTEREN(table_id, i));
-		writel_relaxed(0, device->base +
-				TSPP2_INDEX_TABLE_MASK(table_id, i));
-
-	}
-	table->num_valid_entries = 0;
-	reg = readl_relaxed(device->base + TSPP2_INDEX_TABLE_PARAMS(table_id));
-	reg &= ~(0x1F << INDEX_TABLE_PARAMS_NUM_PATTERNS_OFFS);
-	writel_relaxed(reg, device->base + TSPP2_INDEX_TABLE_PARAMS(table_id));
-
-	mutex_unlock(&device->mutex);
-
-	pm_runtime_mark_last_busy(device->dev);
-	pm_runtime_put_autosuspend(device->dev);
-
-	dev_dbg(device->dev, "%s: successful\n", __func__);
-
-	return 0;
-}
-EXPORT_SYMBOL(tspp2_indexing_patterns_clear);
-
-/* Pipe API functions */
-
-/**
- * tspp2_pipe_memory_init() - Initialize pipe memory helper function.
- *
- * @pipe:	The pipe to work on.
- *
- * The user is responsible for allocating the pipe's memory buffer via ION.
- * This helper function maps the given buffer to TSPP2 IOMMU memory space,
- * and sets the pipe's secure bit.
- *
- * Return 0 on success, error value otherwise.
- */
-static int tspp2_pipe_memory_init(struct tspp2_pipe *pipe)
-{
-	int ret = 0;
-	u32 reg;
-	size_t align;
-	unsigned long dummy_size = 0;
-	size_t len = 0;
-	int domain = 0;
-	int partition = 0;
-	int hlos_group_attached = 0;
-	int cpz_group_attached = 0;
-	int vbif_clk_started = 0;
-
-	if (pipe->cfg.is_secure) {
-		domain = pipe->device->iommu_info.cpz_domain_num;
-		partition = pipe->device->iommu_info.cpz_partition;
-		align = SZ_1M;
-	} else {
-		domain = pipe->device->iommu_info.hlos_domain_num;
-		partition = pipe->device->iommu_info.hlos_partition;
-		align = SZ_4K;
-	}
-
-	if (tspp2_iommu_bypass) {
-		ret = ion_phys(pipe->cfg.ion_client,
-				pipe->cfg.buffer_handle, &pipe->iova, &len);
-
-		dummy_size = 0;
-
-		if (ret) {
-			pr_err("%s: Failed to get buffer physical address, ret = %d\n",
-				__func__, ret);
-			return ret;
-		}
-
-		if ((pipe->device->num_secured_opened_pipes +
-			pipe->device->num_non_secured_opened_pipes) == 0) {
-			ret = tspp2_vbif_clock_start(pipe->device);
-			if (ret) {
-				pr_err(
-					"%s: tspp2_vbif_clock_start failed, ret=%d\n",
-					__func__, ret);
-				return ret;
-			}
-			vbif_clk_started = 1;
-		}
-	} else {
-		/*
-		 * We need to attach the group to enable the IOMMU and support
-		 * the required memory mapping. This needs to be done before
-		 * the first mapping is performed, so the number of opened pipes
-		 * (of each type: secure or non-secure) is used as a
-		 * reference count. Note that since the pipe descriptors are
-		 * always allocated from HLOS domain, the HLOS group must be
-		 * attached regardless of the pipe's security configuration.
-		 * The mutex is taken at this point so there is no problem with
-		 * synchronization.
-		 */
-		if ((pipe->device->num_secured_opened_pipes +
-			pipe->device->num_non_secured_opened_pipes) == 0) {
-			ret = tspp2_vbif_clock_start(pipe->device);
-			if (ret) {
-				pr_err("%s: tspp2_vbif_clock_start failed, ret=%d\n",
-					__func__, ret);
-				goto err_out;
-			}
-			vbif_clk_started = 1;
-
-			pr_debug("%s: attaching HLOS group\n", __func__);
-			ret = iommu_attach_group(
-				pipe->device->iommu_info.hlos_domain,
-				pipe->device->iommu_info.hlos_group);
-
-			if (ret) {
-				pr_err("%s: Failed attaching IOMMU HLOS group, %d\n",
-					__func__, ret);
-				goto err_out;
-			}
-			hlos_group_attached = 1;
-		}
-
-		if (pipe->cfg.is_secure &&
-			(pipe->device->num_secured_opened_pipes == 0)) {
-			pr_debug("%s: attaching CPZ group\n", __func__);
-			ret = iommu_attach_group(
-				pipe->device->iommu_info.cpz_domain,
-				pipe->device->iommu_info.cpz_group);
-
-			if (ret) {
-				pr_err("%s: Failed attaching IOMMU CPZ group, %d\n",
-					__func__, ret);
-				goto err_out;
-			}
-			cpz_group_attached = 1;
-		}
-
-		/* Map to TSPP2 IOMMU */
-		ret = ion_map_iommu(pipe->cfg.ion_client,
-				pipe->cfg.buffer_handle,
-				domain,
-				partition,
-				align, 0, &pipe->iova,
-				&dummy_size, 0, 0); /* Uncached mapping */
-
-		if (ret) {
-			pr_err("%s: Failed mapping buffer to TSPP2, %d\n",
-				__func__, ret);
-			goto err_out;
-		}
-	}
-
-	if (pipe->cfg.is_secure) {
-		reg = readl_relaxed(pipe->device->base + TSPP2_PIPE_SECURITY);
-		reg |= (0x1 << pipe->hw_index);
-		writel_relaxed(reg, pipe->device->base + TSPP2_PIPE_SECURITY);
-	}
-
-	dev_dbg(pipe->device->dev, "%s: successful\n", __func__);
-
-	return 0;
-
-err_out:
-	if (hlos_group_attached) {
-		iommu_detach_group(pipe->device->iommu_info.hlos_domain,
-				pipe->device->iommu_info.hlos_group);
-	}
-
-	if (cpz_group_attached) {
-		iommu_detach_group(pipe->device->iommu_info.cpz_domain,
-				pipe->device->iommu_info.cpz_group);
-	}
-
-	if (vbif_clk_started)
-		tspp2_vbif_clock_stop(pipe->device);
-
-	return ret;
-}
-
-/**
- * tspp2_pipe_memory_terminate() - Unmap pipe memory.
- *
- * @pipe:	The pipe to work on.
- *
- * Unmap the pipe's memory and clear the pipe's secure bit.
- */
-static void tspp2_pipe_memory_terminate(struct tspp2_pipe *pipe)
-{
-	u32 reg;
-	int domain = 0;
-	int partition = 0;
-
-	if (pipe->cfg.is_secure) {
-		domain = pipe->device->iommu_info.cpz_domain_num;
-		partition = pipe->device->iommu_info.cpz_partition;
-	} else {
-		domain = pipe->device->iommu_info.hlos_domain_num;
-		partition = pipe->device->iommu_info.hlos_partition;
-	}
-
-	if (!tspp2_iommu_bypass) {
-		ion_unmap_iommu(pipe->cfg.ion_client,
-				pipe->cfg.buffer_handle,
-				domain,
-				partition);
-
-		/*
-		 * Opposite to what is done in tspp2_pipe_memory_init(),
-		 * here we detach the IOMMU group when it is no longer in use.
-		 */
-		if (pipe->cfg.is_secure &&
-			(pipe->device->num_secured_opened_pipes == 0)) {
-			pr_debug("%s: detaching CPZ group\n", __func__);
-			iommu_detach_group(
-				pipe->device->iommu_info.cpz_domain,
-				pipe->device->iommu_info.cpz_group);
-		}
-
-		if ((pipe->device->num_secured_opened_pipes +
-			pipe->device->num_non_secured_opened_pipes) == 0) {
-			pr_debug("%s: detaching HLOS group\n", __func__);
-			iommu_detach_group(
-				pipe->device->iommu_info.hlos_domain,
-				pipe->device->iommu_info.hlos_group);
-			tspp2_vbif_clock_stop(pipe->device);
-		}
-	} else if ((pipe->device->num_secured_opened_pipes +
-		pipe->device->num_non_secured_opened_pipes) == 0) {
-		tspp2_vbif_clock_stop(pipe->device);
-	}
-
-	pipe->iova = 0;
-
-	if (pipe->cfg.is_secure) {
-		reg = readl_relaxed(pipe->device->base + TSPP2_PIPE_SECURITY);
-		reg &= ~(0x1 << pipe->hw_index);
-		writel_relaxed(reg, pipe->device->base + TSPP2_PIPE_SECURITY);
-	}
-
-	dev_dbg(pipe->device->dev, "%s: successful\n", __func__);
-}
-
-/**
- * tspp2_sps_pipe_init() - BAM SPS pipe configuration and initialization
- *
- * @pipe:	The pipe to work on.
- *
- * Return 0 on success, error value otherwise.
- */
-static int tspp2_sps_pipe_init(struct tspp2_pipe *pipe)
-{
-	u32 descriptors_num;
-	unsigned long dummy_size = 0;
-	int ret = 0;
-	int iommu_mapped = 0;
-
-	if (pipe->cfg.buffer_size % pipe->cfg.sps_cfg.descriptor_size) {
-		pr_err(
-			"%s: Buffer size %d is not aligned to descriptor size %d\n",
-			__func__, pipe->cfg.buffer_size,
-			pipe->cfg.sps_cfg.descriptor_size);
-		return -EINVAL;
-	}
-
-	pipe->sps_pipe = sps_alloc_endpoint();
-	if (!pipe->sps_pipe) {
-		pr_err("%s: Failed to allocate BAM pipe\n", __func__);
-		return -ENOMEM;
-	}
-
-	/* get default configuration */
-	sps_get_config(pipe->sps_pipe, &pipe->sps_connect_cfg);
-	if (pipe->cfg.pipe_mode == TSPP2_SRC_PIPE_INPUT) {
-		pipe->sps_connect_cfg.mode = SPS_MODE_DEST;
-		pipe->sps_connect_cfg.source = SPS_DEV_HANDLE_MEM;
-		pipe->sps_connect_cfg.destination = pipe->device->bam_handle;
-		pipe->sps_connect_cfg.dest_pipe_index = pipe->hw_index;
-	} else {
-		pipe->sps_connect_cfg.mode = SPS_MODE_SRC;
-		pipe->sps_connect_cfg.source = pipe->device->bam_handle;
-		pipe->sps_connect_cfg.destination = SPS_DEV_HANDLE_MEM;
-		pipe->sps_connect_cfg.src_pipe_index = pipe->hw_index;
-	}
-	pipe->sps_connect_cfg.desc.base = NULL;
-	pipe->sps_connect_cfg.options = pipe->cfg.sps_cfg.setting;
-	descriptors_num = (pipe->cfg.buffer_size /
-				pipe->cfg.sps_cfg.descriptor_size);
-
-	/*
-	 * If size of descriptors FIFO can hold N descriptors, we can submit
-	 * (N-1) descriptors only, therefore we allocate extra descriptor
-	 */
-	descriptors_num++;
-	pipe->sps_connect_cfg.desc.size = (descriptors_num *
-					sizeof(struct sps_iovec));
-
-	if (tspp2_iommu_bypass) {
-		pipe->sps_connect_cfg.desc.base = dma_alloc_coherent(NULL,
-					pipe->sps_connect_cfg.desc.size,
-					&pipe->sps_connect_cfg.desc.phys_base,
-					GFP_KERNEL);
-
-		if (!pipe->sps_connect_cfg.desc.base) {
-			pr_err("%s: Failed to allocate descriptor FIFO\n",
-				__func__);
-			ret = -ENOMEM;
-			goto init_sps_failed_free_endpoint;
-		}
-	} else {
-		pipe->desc_ion_handle = ion_alloc(pipe->cfg.ion_client,
-					pipe->sps_connect_cfg.desc.size,
-					SZ_4K, ION_HEAP(ION_IOMMU_HEAP_ID), 0);
-
-		if (!pipe->desc_ion_handle) {
-			pr_err("%s: Failed to allocate descriptors via ION\n",
-				__func__);
-			ret = -ENOMEM;
-			goto init_sps_failed_free_endpoint;
-		}
-
-		ret = ion_map_iommu(pipe->cfg.ion_client,
-			pipe->desc_ion_handle,
-			pipe->device->iommu_info.hlos_domain_num,
-			pipe->device->iommu_info.hlos_partition,
-			SZ_4K, 0,
-			&pipe->sps_connect_cfg.desc.phys_base,
-			&dummy_size, 0, 0); /* Uncached mapping */
-
-		if (ret) {
-			pr_err("%s: Failed mapping descriptors to IOMMU\n",
-				__func__);
-			goto init_sps_failed_free_mem;
-		}
-
-		iommu_mapped = 1;
-
-		pipe->sps_connect_cfg.desc.base =
-			ion_map_kernel(pipe->cfg.ion_client,
-			pipe->desc_ion_handle);
-
-		if (!pipe->sps_connect_cfg.desc.base) {
-			pr_err("%s: Failed mapping descriptors to kernel\n",
-				__func__);
-			ret = -ENOMEM;
-			goto init_sps_failed_free_mem;
-		}
-	}
-
-	ret = sps_connect(pipe->sps_pipe, &pipe->sps_connect_cfg);
-	if (ret) {
-		pr_err("%s: Failed to connect BAM, %d\n", __func__, ret);
-		goto init_sps_failed_free_mem;
-	}
-
-	pipe->sps_event.options = pipe->cfg.sps_cfg.wakeup_events;
-	if (pipe->sps_event.options) {
-		pipe->sps_event.mode = SPS_TRIGGER_CALLBACK;
-		pipe->sps_event.callback = pipe->cfg.sps_cfg.callback;
-		pipe->sps_event.xfer_done = NULL;
-		pipe->sps_event.user = pipe->cfg.sps_cfg.user_info;
-
-		ret = sps_register_event(pipe->sps_pipe, &pipe->sps_event);
-		if (ret) {
-			pr_err("%s: Failed to register pipe event, %d\n",
-					__func__, ret);
-			goto init_sps_failed_free_connection;
-		}
-	}
-
-	dev_dbg(pipe->device->dev, "%s: successful\n", __func__);
-
-	return 0;
-
-init_sps_failed_free_connection:
-	sps_disconnect(pipe->sps_pipe);
-init_sps_failed_free_mem:
-	if (tspp2_iommu_bypass) {
-		dma_free_coherent(NULL, pipe->sps_connect_cfg.desc.size,
-					pipe->sps_connect_cfg.desc.base,
-					pipe->sps_connect_cfg.desc.phys_base);
-	} else {
-		if (pipe->sps_connect_cfg.desc.base)
-			ion_unmap_kernel(pipe->cfg.ion_client,
-				pipe->desc_ion_handle);
-
-		if (iommu_mapped) {
-			ion_unmap_iommu(pipe->cfg.ion_client,
-				pipe->desc_ion_handle,
-				pipe->device->iommu_info.hlos_domain_num,
-				pipe->device->iommu_info.hlos_partition);
-		}
-
-		ion_free(pipe->cfg.ion_client, pipe->desc_ion_handle);
-	}
-init_sps_failed_free_endpoint:
-	sps_free_endpoint(pipe->sps_pipe);
-
-	return ret;
-}
-
-/**
- * tspp2_sps_queue_descriptors() - Queue BAM SPS descriptors
- *
- * @pipe:	The pipe to work on.
- *
- * Return 0 on success, error value otherwise.
- */
-static int tspp2_sps_queue_descriptors(struct tspp2_pipe *pipe)
-{
-	int ret = 0;
-	u32 data_offset = 0;
-	u32 desc_length = pipe->cfg.sps_cfg.descriptor_size;
-	u32 desc_flags = pipe->cfg.sps_cfg.descriptor_flags;
-	u32 data_length = pipe->cfg.buffer_size;
-
-	while (data_length > 0) {
-		ret = sps_transfer_one(pipe->sps_pipe,
-				pipe->iova + data_offset,
-				desc_length,
-				pipe->cfg.sps_cfg.user_info,
-				desc_flags);
-
-		if (ret) {
-			pr_err("%s: sps_transfer_one failed, %d\n",
-				__func__, ret);
-			return ret;
-		}
-
-		data_offset += desc_length;
-		data_length -= desc_length;
-	}
-
-	return 0;
-}
-
-/**
- * tspp2_sps_pipe_terminate() - Disconnect and terminate SPS BAM pipe
- *
- * @pipe:	The pipe to work on.
- *
- * Return 0 on success, error value otherwise.
- */
-static int tspp2_sps_pipe_terminate(struct tspp2_pipe *pipe)
-{
-	int ret;
-
-	ret = sps_disconnect(pipe->sps_pipe);
-	if (ret) {
-		pr_err("%s: failed to disconnect BAM pipe, %d\n",
-			__func__, ret);
-		return ret;
-	}
-	if (tspp2_iommu_bypass) {
-		dma_free_coherent(NULL, pipe->sps_connect_cfg.desc.size,
-					pipe->sps_connect_cfg.desc.base,
-					pipe->sps_connect_cfg.desc.phys_base);
-	} else {
-		ion_unmap_kernel(pipe->cfg.ion_client,
-				pipe->desc_ion_handle);
-
-		ion_unmap_iommu(pipe->cfg.ion_client,
-				pipe->desc_ion_handle,
-				pipe->device->iommu_info.hlos_domain_num,
-				pipe->device->iommu_info.hlos_partition);
-
-		ion_free(pipe->cfg.ion_client, pipe->desc_ion_handle);
-	}
-	pipe->sps_connect_cfg.desc.base = NULL;
-
-	ret = sps_free_endpoint(pipe->sps_pipe);
-	if (ret) {
-		pr_err("%s: failed to release BAM end-point, %d\n",
-			__func__, ret);
-		return ret;
-	}
-
-	return 0;
-}
-
-/**
- * tspp2_pipe_open() - Open a pipe for use.
- *
- * @dev_id:		TSPP2 device ID.
- * @cfg:		Pipe configuration parameters.
- * @iova:		TSPP2 IOMMU virtual address of the pipe's buffer.
- * @pipe_handle:	Opened pipe handle.
- *
- * Return 0 on success, error value otherwise.
- */
-int tspp2_pipe_open(u32 dev_id,
-			const struct tspp2_pipe_config_params *cfg,
-			ion_phys_addr_t *iova,
-			u32 *pipe_handle)
-{
-	struct tspp2_device *device;
-	struct tspp2_pipe *pipe;
-	int i;
-	int ret = 0;
-
-	if (dev_id >= TSPP2_NUM_DEVICES) {
-		pr_err("%s: Invalid device ID %d\n", __func__, dev_id);
-		return -ENODEV;
-	}
-
-	if (!cfg || !iova || !pipe_handle) {
-		pr_err("%s: Invalid parameters\n", __func__);
-		return -EINVAL;
-	}
-
-	/* Some minimal sanity tests on the pipe configuration: */
-	if (!cfg->ion_client || !cfg->buffer_handle) {
-		pr_err("%s: Invalid parameters\n", __func__);
-		return -EINVAL;
-	}
-
-	device = tspp2_devices[dev_id];
-	if (!device) {
-		pr_err("%s: Invalid device\n", __func__);
-		return -ENODEV;
-	}
-
-	ret = pm_runtime_get_sync(device->dev);
-	if (ret < 0)
-		return ret;
-
-	if (mutex_lock_interruptible(&device->mutex)) {
-		pm_runtime_mark_last_busy(device->dev);
-		pm_runtime_put_autosuspend(device->dev);
-		return -ERESTARTSYS;
-	}
-
-	if (!device->opened) {
-		pr_err("%s: Device must be opened first\n", __func__);
-		mutex_unlock(&device->mutex);
-		pm_runtime_mark_last_busy(device->dev);
-		pm_runtime_put_autosuspend(device->dev);
-		return -EPERM;
-	}
-
-	/* Find a free pipe */
-	for (i = 0; i < TSPP2_NUM_PIPES; i++) {
-		pipe = &device->pipes[i];
-		if (!pipe->opened)
-			break;
-	}
-	if (i == TSPP2_NUM_PIPES) {
-		pr_err("%s: No available pipes\n", __func__);
-		mutex_unlock(&device->mutex);
-		pm_runtime_mark_last_busy(device->dev);
-		pm_runtime_put_autosuspend(device->dev);
-		return -ENOMEM;
-	}
-
-	pipe->hw_index = i;
-	/* Actual pipe threshold is set when the pipe is attached to a source */
-	pipe->threshold = 0;
-	pipe->cfg = *cfg;
-	pipe->ref_cnt = 0;
-	/* device back-pointer is already initialized, always remains valid */
-
-	ret = tspp2_pipe_memory_init(pipe);
-	if (ret) {
-		pr_err("%s: Error initializing pipe memory\n", __func__);
-		mutex_unlock(&device->mutex);
-		pm_runtime_mark_last_busy(device->dev);
-		pm_runtime_put_autosuspend(device->dev);
-		return ret;
-	}
-	ret = tspp2_sps_pipe_init(pipe);
-	if (ret) {
-		pr_err("%s: Error initializing BAM pipe\n", __func__);
-		tspp2_pipe_memory_terminate(pipe);
-		mutex_unlock(&device->mutex);
-		pm_runtime_mark_last_busy(device->dev);
-		pm_runtime_put_autosuspend(device->dev);
-		return ret;
-	}
-
-	/* For output pipes, we queue BAM descriptors here so they are ready */
-	if (pipe->cfg.pipe_mode == TSPP2_SRC_PIPE_OUTPUT) {
-		ret = tspp2_sps_queue_descriptors(pipe);
-		if (ret) {
-			pr_err("%s: Error queuing BAM pipe descriptors\n",
-				__func__);
-			tspp2_sps_pipe_terminate(pipe);
-			tspp2_pipe_memory_terminate(pipe);
-			mutex_unlock(&device->mutex);
-			pm_runtime_mark_last_busy(device->dev);
-			pm_runtime_put_autosuspend(device->dev);
-			return ret;
-		}
-	}
-
-	/* Reset counter */
-	writel_relaxed((0x1 << pipe->hw_index),
-		device->base + TSPP2_DATA_NOT_SENT_ON_PIPE_RESET);
-
-	/* Return handle to the caller */
-	*pipe_handle = (u32)pipe;
-	*iova = pipe->iova;
-
-	pipe->opened = 1;
-	if (pipe->cfg.is_secure)
-		device->num_secured_opened_pipes++;
-	else
-		device->num_non_secured_opened_pipes++;
-
-	mutex_unlock(&device->mutex);
-
-	pm_runtime_mark_last_busy(device->dev);
-	pm_runtime_put_autosuspend(device->dev);
-
-	dev_dbg(device->dev, "%s: successful\n", __func__);
-
-	return 0;
-}
-EXPORT_SYMBOL(tspp2_pipe_open);
-
-/**
- * tspp2_pipe_close() - Close an opened pipe.
- *
- * @pipe_handle:	Pipe to be closed.
- *
- * Return 0 on success, error value otherwise.
- */
-int tspp2_pipe_close(u32 pipe_handle)
-{
-	int ret;
-	struct tspp2_pipe *pipe = (struct tspp2_pipe *)pipe_handle;
-
-	if (!pipe) {
-		pr_err("%s: Invalid pipe handle\n", __func__);
-		return -EINVAL;
-	}
-
-	ret = pm_runtime_get_sync(pipe->device->dev);
-	if (ret < 0)
-		return ret;
-
-	mutex_lock(&pipe->device->mutex);
-
-	if (!pipe->device->opened) {
-		pr_err("%s: Device must be opened first\n", __func__);
-		mutex_unlock(&pipe->device->mutex);
-		pm_runtime_mark_last_busy(pipe->device->dev);
-		pm_runtime_put_autosuspend(pipe->device->dev);
-		return -EPERM;
-	}
-
-	if (!pipe->opened) {
-		pr_err("%s: Pipe already closed\n", __func__);
-		mutex_unlock(&pipe->device->mutex);
-		pm_runtime_mark_last_busy(pipe->device->dev);
-		pm_runtime_put_autosuspend(pipe->device->dev);
-		return -EINVAL;
-	}
-
-	if (pipe->ref_cnt > 0) {
-		pr_err("%s: Pipe %u is still attached to a source\n",
-			__func__, pipe_handle);
-		mutex_unlock(&pipe->device->mutex);
-		pm_runtime_mark_last_busy(pipe->device->dev);
-		pm_runtime_put_autosuspend(pipe->device->dev);
-		return -EPERM;
-	}
-
-	/*
-	 * Note: need to decrement the pipe reference count here, before
-	 * calling tspp2_pipe_memory_terminate().
-	 */
-	if (pipe->cfg.is_secure)
-		pipe->device->num_secured_opened_pipes--;
-	else
-		pipe->device->num_non_secured_opened_pipes--;
-
-	tspp2_sps_pipe_terminate(pipe);
-	tspp2_pipe_memory_terminate(pipe);
-
-	pipe->iova = 0;
-	pipe->opened = 0;
-
-	mutex_unlock(&pipe->device->mutex);
-
-	pm_runtime_mark_last_busy(pipe->device->dev);
-	pm_runtime_put_autosuspend(pipe->device->dev);
-
-	dev_dbg(pipe->device->dev, "%s: successful\n", __func__);
-
-	return 0;
-}
-EXPORT_SYMBOL(tspp2_pipe_close);
-
-/* Source API functions */
-
-/**
- * tspp2_src_open() - Open a new source for use.
- *
- * @dev_id:	TSPP2 device ID.
- * @cfg:	Source configuration parameters.
- * @src_handle:	Opened source handle.
- *
- * Return 0 on success, error value otherwise.
- */
-int tspp2_src_open(u32 dev_id,
-			struct tspp2_src_cfg *cfg,
-			u32 *src_handle)
-{
-	int ret;
-	int i;
-	struct tspp2_device *device;
-	struct tspp2_src *src;
-	enum tspp2_src_input input;
-
-	if (dev_id >= TSPP2_NUM_DEVICES) {
-		pr_err("%s: Invalid device ID %d\n", __func__, dev_id);
-		return -ENODEV;
-	}
-	if (!src_handle) {
-		pr_err("%s: Invalid source handle pointer\n", __func__);
-		return -EINVAL;
-	}
-	if (!cfg) {
-		pr_err("%s: Invalid configuration parameters\n", __func__);
-		return -EINVAL;
-	}
-
-	device = tspp2_devices[dev_id];
-	if (!device) {
-		pr_err("%s: Invalid device\n", __func__);
-		return -ENODEV;
-	}
-
-	ret = pm_runtime_get_sync(device->dev);
-	if (ret < 0)
-		return ret;
-
-	if (mutex_lock_interruptible(&device->mutex)) {
-		pm_runtime_mark_last_busy(device->dev);
-		pm_runtime_put_autosuspend(device->dev);
-		return -ERESTARTSYS;
-	}
-
-	if (!device->opened) {
-		pr_err("%s: Device must be opened first\n", __func__);
-		mutex_unlock(&device->mutex);
-		pm_runtime_mark_last_busy(device->dev);
-		pm_runtime_put_autosuspend(device->dev);
-		return -EPERM;
-	}
-
-	input = cfg->input;
-	if ((input == TSPP2_INPUT_TSIF0) || (input == TSPP2_INPUT_TSIF1)) {
-		/* Input from TSIF */
-		if (device->tsif_sources[input].opened) {
-			pr_err("%s: TSIF input %d already opened\n",
-				__func__, input);
-			mutex_unlock(&device->mutex);
-			pm_runtime_mark_last_busy(device->dev);
-			pm_runtime_put_autosuspend(device->dev);
-			return -EINVAL;
-		}
-		src = &device->tsif_sources[input];
-
-		/*
-		 * When writing to HW registers that are relevant to sources
-		 * of both TSIF and memory input types, the register offsets
-		 * for the TSIF-related registers come after the memory-related
-		 * registers. For example: for TSPP2_SRC_CONFIG(n), n=[0..9],
-		 * indexes 0..7 are for memory inputs, and indexes 8, 9 are
-		 * for TSIF inputs.
-		 */
-		src->hw_index = TSPP2_NUM_MEM_INPUTS + input;
-
-		/* Save TSIF source parameters in TSIF device */
-		device->tsif_devices[input].mode =
-			cfg->params.tsif_params.tsif_mode;
-		device->tsif_devices[input].clock_inverse =
-			cfg->params.tsif_params.clock_inverse;
-		device->tsif_devices[input].data_inverse =
-			cfg->params.tsif_params.data_inverse;
-		device->tsif_devices[input].sync_inverse =
-			cfg->params.tsif_params.sync_inverse;
-		device->tsif_devices[input].enable_inverse =
-			cfg->params.tsif_params.enable_inverse;
-	} else {
-		/* Input from memory */
-		for (i = 0; i < TSPP2_NUM_MEM_INPUTS; i++) {
-			if (!device->mem_sources[i].opened)
-				break;
-		}
-		if (i == TSPP2_NUM_MEM_INPUTS) {
-			pr_err("%s: No memory inputs available\n", __func__);
-			mutex_unlock(&device->mutex);
-			pm_runtime_mark_last_busy(device->dev);
-			pm_runtime_put_autosuspend(device->dev);
-			return -ENOMEM;
-		}
-
-		src = &device->mem_sources[i];
-		src->hw_index = i;
-	}
-
-	src->opened = 1;
-	src->input = input;
-	src->pkt_format = TSPP2_PACKET_FORMAT_188_RAW; /* default value */
-	src->scrambling_bits_monitoring = TSPP2_SRC_SCRAMBLING_MONITOR_NONE;
-	INIT_LIST_HEAD(&src->batches_list);
-	INIT_LIST_HEAD(&src->filters_list);
-	src->input_pipe = NULL;
-	INIT_LIST_HEAD(&src->output_pipe_list);
-	src->num_associated_batches = 0;
-	src->num_associated_pipes = 0;
-	src->num_associated_filters = 0;
-	src->reserved_filter_hw_index = 0;
-	src->event_callback = NULL;
-	src->event_cookie = NULL;
-	src->event_bitmask = 0;
-	src->enabled = 0;
-	/* device back-pointer is already initialized, always remains valid */
-
-	/* Reset source-related registers */
-	if ((input == TSPP2_INPUT_TSIF0) || (input == TSPP2_INPUT_TSIF1)) {
-		writel_relaxed((0x1 << TSIF_INPUT_SRC_CONFIG_16_BATCHES_OFFS),
-			device->base +
-			TSPP2_TSIF_INPUT_SRC_CONFIG(src->input));
-	} else {
-		/*
-		 * Disable memory inputs. Set mode of operation to 16 batches.
-		 * Configure last batch to be associated with this source.
-		 */
-		writel_relaxed(TSPP2_DEFAULT_MEM_SRC_CONFIG,
-			device->base +
-			TSPP2_MEM_INPUT_SRC_CONFIG(src->hw_index));
-	}
-	writel_relaxed(0, device->base +
-				TSPP2_SRC_DEST_PIPES(src->hw_index));
-	writel_relaxed(TSPP2_DEFAULT_SRC_CONFIG, device->base +
-				TSPP2_SRC_CONFIG(src->hw_index));
-	writel_relaxed((0x1 << src->hw_index),
-		device->base + TSPP2_SRC_TOTAL_TSP_RESET);
-	writel_relaxed((0x1 << src->hw_index),
-		device->base + TSPP2_SRC_FILTERED_OUT_TSP_RESET);
-
-	/* Return handle to the caller */
-	*src_handle = (u32)src;
-
-	mutex_unlock(&device->mutex);
-
-	pm_runtime_mark_last_busy(device->dev);
-	pm_runtime_put_autosuspend(device->dev);
-
-	dev_dbg(device->dev, "%s: successful\n", __func__);
-
-	return 0;
-}
-EXPORT_SYMBOL(tspp2_src_open);
-
-/**
- * tspp2_src_close() - Close an opened source.
- *
- * @src_handle:	Source to be closed.
- *
- * Return 0 on success, error value otherwise.
- */
-int tspp2_src_close(u32 src_handle)
-{
-	unsigned long flags;
-	struct tspp2_src *src = (struct tspp2_src *)src_handle;
-
-	if (!src) {
-		pr_err("%s: Invalid source handle\n", __func__);
-		return -EINVAL;
-	}
-
-	mutex_lock(&src->device->mutex);
-
-	if (!src->device->opened) {
-		pr_err("%s: Device must be opened first\n", __func__);
-		mutex_unlock(&src->device->mutex);
-		return -EPERM;
-	}
-
-	if (!src->opened) {
-		pr_err("%s: Source already closed\n", __func__);
-		mutex_unlock(&src->device->mutex);
-		return -EINVAL;
-	}
-
-	if (src->enabled) {
-		pr_err("%s: Source needs to be disabled before it can be closed\n",
-			__func__);
-		mutex_unlock(&src->device->mutex);
-		return -EPERM;
-	}
-
-	/* Verify resources have been released by the caller */
-	if ((src->num_associated_batches > 0) ||
-		(src->num_associated_pipes > 0) ||
-		(src->num_associated_filters > 0)) {
-		pr_err("%s: Source's resources need to be removed before it can be closed\n",
-			__func__);
-		mutex_unlock(&src->device->mutex);
-		return -EPERM;
-	}
-
-	/*
-	 * Most fields are reset to default values when opening a source, so
-	 * there is no need to reset them all here. We only need to mark the
-	 * source as closed.
-	 */
-	src->opened = 0;
-	spin_lock_irqsave(&src->device->spinlock, flags);
-	src->event_callback = NULL;
-	src->event_cookie = NULL;
-	src->event_bitmask = 0;
-	spin_unlock_irqrestore(&src->device->spinlock, flags);
-	src->enabled = 0;
-
-	/*
-	 * Source-related HW registers are reset when opening a source, so
-	 * we don't reser them here. Note that a source is disabled before
-	 * it is closed, so no need to disable it here either.
-	 */
-
-	mutex_unlock(&src->device->mutex);
-
-	dev_dbg(src->device->dev, "%s: successful\n", __func__);
-
-	return 0;
-}
-EXPORT_SYMBOL(tspp2_src_close);
-
-/**
- * tspp2_src_parsing_option_set() - Set source parsing configuration option.
- *
- * @src_handle:	Source to configure.
- * @option:	Parsing configuration option to enable / disable.
- * @enable:	Enable / disable option.
- *
- * Return 0 on success, error value otherwise.
- */
-int tspp2_src_parsing_option_set(u32 src_handle,
-			enum tspp2_src_parsing_option option,
-			int enable)
-{
-	int ret;
-	u32 reg = 0;
-	struct tspp2_src *src = (struct tspp2_src *)src_handle;
-
-	if (!src) {
-		pr_err("%s: Invalid source handle\n", __func__);
-		return -EINVAL;
-	}
-
-	ret = pm_runtime_get_sync(src->device->dev);
-	if (ret < 0)
-		return ret;
-
-	if (mutex_lock_interruptible(&src->device->mutex)) {
-		pm_runtime_mark_last_busy(src->device->dev);
-		pm_runtime_put_autosuspend(src->device->dev);
-		return -ERESTARTSYS;
-	}
-
-	if (!src->device->opened) {
-		pr_err("%s: Device must be opened first\n", __func__);
-		mutex_unlock(&src->device->mutex);
-		pm_runtime_mark_last_busy(src->device->dev);
-		pm_runtime_put_autosuspend(src->device->dev);
-		return -EPERM;
-	}
-
-	if (!src->opened) {
-		pr_err("%s: Source not opened\n", __func__);
-		mutex_unlock(&src->device->mutex);
-		pm_runtime_mark_last_busy(src->device->dev);
-		pm_runtime_put_autosuspend(src->device->dev);
-		return -EINVAL;
-	}
-
-	reg = readl_relaxed(src->device->base +
-			TSPP2_SRC_CONFIG(src->hw_index));
-
-	switch (option) {
-	case TSPP2_SRC_PARSING_OPT_CHECK_CONTINUITY:
-		if (enable)
-			reg |= (0x1 << SRC_CONFIG_CHECK_CONT_OFFS);
-		else
-			reg &= ~(0x1 << SRC_CONFIG_CHECK_CONT_OFFS);
-		break;
-	case TSPP2_SRC_PARSING_OPT_IGNORE_DISCONTINUITY:
-		if (enable)
-			reg |= (0x1 << SRC_CONFIG_IGNORE_DISCONT_OFFS);
-		else
-			reg &= ~(0x1 << SRC_CONFIG_IGNORE_DISCONT_OFFS);
-		break;
-	case TSPP2_SRC_PARSING_OPT_ASSUME_DUPLICATE_PACKETS:
-		if (enable)
-			reg |= (0x1 << SRC_CONFIG_ASSUME_DUPLICATES_OFFS);
-		else
-			reg &= ~(0x1 << SRC_CONFIG_ASSUME_DUPLICATES_OFFS);
-		break;
-	case TSPP2_SRC_PARSING_OPT_DISCARD_INVALID_AF_PACKETS:
-		if (enable)
-			reg |= (0x1 << SRC_CONFIG_DISCARD_INVALID_AF_OFFS);
-		else
-			reg &= ~(0x1 << SRC_CONFIG_DISCARD_INVALID_AF_OFFS);
-		break;
-	case TSPP2_SRC_PARSING_OPT_VERIFY_PES_START:
-		if (enable)
-			reg |= (0x1 << SRC_CONFIG_VERIFY_PES_START_OFFS);
-		else
-			reg &= ~(0x1 << SRC_CONFIG_VERIFY_PES_START_OFFS);
-		break;
-	default:
-		pr_err("%s: Invalid option %d\n", __func__, option);
-		mutex_unlock(&src->device->mutex);
-		pm_runtime_mark_last_busy(src->device->dev);
-		pm_runtime_put_autosuspend(src->device->dev);
-		return -EINVAL;
-	}
-
-	writel_relaxed(reg, src->device->base +
-			TSPP2_SRC_CONFIG(src->hw_index));
-
-	mutex_unlock(&src->device->mutex);
-
-	pm_runtime_mark_last_busy(src->device->dev);
-	pm_runtime_put_autosuspend(src->device->dev);
-
-	dev_dbg(src->device->dev, "%s: successful\n", __func__);
-
-	return 0;
-}
-EXPORT_SYMBOL(tspp2_src_parsing_option_set);
-
-/**
- * tspp2_src_parsing_option_get() - Get source parsing configuration option.
- *
- * @src_handle:	Source handle.
- * @option:	Parsing configuration option to get.
- * @enable:	Option's enable / disable indication.
- *
- * Return 0 on success, error value otherwise.
- */
-int tspp2_src_parsing_option_get(u32 src_handle,
-			enum tspp2_src_parsing_option option,
-			int *enable)
-{
-	int ret;
-	u32 reg = 0;
-	struct tspp2_src *src = (struct tspp2_src *)src_handle;
-
-	if (!src) {
-		pr_err("%s: Invalid source handle\n", __func__);
-		return -EINVAL;
-	}
-	if (!enable) {
-		pr_err("%s: NULL pointer\n", __func__);
-		return -EINVAL;
-	}
-
-	ret = pm_runtime_get_sync(src->device->dev);
-	if (ret < 0)
-		return ret;
-
-	if (mutex_lock_interruptible(&src->device->mutex)) {
-		pm_runtime_mark_last_busy(src->device->dev);
-		pm_runtime_put_autosuspend(src->device->dev);
-		return -ERESTARTSYS;
-	}
-
-	if (!src->device->opened) {
-		pr_err("%s: Device must be opened first\n", __func__);
-		mutex_unlock(&src->device->mutex);
-		pm_runtime_mark_last_busy(src->device->dev);
-		pm_runtime_put_autosuspend(src->device->dev);
-		return -EPERM;
-	}
-
-	if (!src->opened) {
-		pr_err("%s: Source not opened\n", __func__);
-		mutex_unlock(&src->device->mutex);
-		pm_runtime_mark_last_busy(src->device->dev);
-		pm_runtime_put_autosuspend(src->device->dev);
-		return -EINVAL;
-	}
-
-	reg = readl_relaxed(src->device->base +
-			TSPP2_SRC_CONFIG(src->hw_index));
-
-	switch (option) {
-	case TSPP2_SRC_PARSING_OPT_CHECK_CONTINUITY:
-		*enable = ((reg >> SRC_CONFIG_CHECK_CONT_OFFS) & 0x1);
-		break;
-	case TSPP2_SRC_PARSING_OPT_IGNORE_DISCONTINUITY:
-		*enable = ((reg >> SRC_CONFIG_IGNORE_DISCONT_OFFS) & 0x1);
-		break;
-	case TSPP2_SRC_PARSING_OPT_ASSUME_DUPLICATE_PACKETS:
-		*enable = ((reg >> SRC_CONFIG_ASSUME_DUPLICATES_OFFS) & 0x1);
-		break;
-	case TSPP2_SRC_PARSING_OPT_DISCARD_INVALID_AF_PACKETS:
-		*enable = ((reg >> SRC_CONFIG_DISCARD_INVALID_AF_OFFS) & 0x1);
-		break;
-	case TSPP2_SRC_PARSING_OPT_VERIFY_PES_START:
-		*enable = ((reg >> SRC_CONFIG_VERIFY_PES_START_OFFS) & 0x1);
-		break;
-	default:
-		pr_err("%s: Invalid option %d\n", __func__, option);
-		mutex_unlock(&src->device->mutex);
-		pm_runtime_mark_last_busy(src->device->dev);
-		pm_runtime_put_autosuspend(src->device->dev);
-		return -EINVAL;
-	}
-
-	mutex_unlock(&src->device->mutex);
-
-	pm_runtime_mark_last_busy(src->device->dev);
-	pm_runtime_put_autosuspend(src->device->dev);
-
-	dev_dbg(src->device->dev, "%s: successful\n", __func__);
-
-	return 0;
-}
-EXPORT_SYMBOL(tspp2_src_parsing_option_get);
-
-/**
- * tspp2_src_sync_byte_config_set() - Set source sync byte configuration.
- *
- * @src_handle:		Source to configure.
- * @check_sync_byte:	Check TS packet sync byte.
- * @sync_byte_value:	Sync byte value to check (e.g., 0x47).
- *
- * Return 0 on success, error value otherwise.
- */
-int tspp2_src_sync_byte_config_set(u32 src_handle,
-			int check_sync_byte,
-			u8 sync_byte_value)
-{
-	int ret;
-	u32 reg = 0;
-	struct tspp2_src *src = (struct tspp2_src *)src_handle;
-
-	if (!src) {
-		pr_err("%s: Invalid source handle\n", __func__);
-		return -EINVAL;
-	}
-
-	ret = pm_runtime_get_sync(src->device->dev);
-	if (ret < 0)
-		return ret;
-
-	if (mutex_lock_interruptible(&src->device->mutex)) {
-		pm_runtime_mark_last_busy(src->device->dev);
-		pm_runtime_put_autosuspend(src->device->dev);
-		return -ERESTARTSYS;
-	}
-
-	if (!src->device->opened) {
-		pr_err("%s: Device must be opened first\n", __func__);
-		mutex_unlock(&src->device->mutex);
-		pm_runtime_mark_last_busy(src->device->dev);
-		pm_runtime_put_autosuspend(src->device->dev);
-		return -EPERM;
-	}
-
-	if (!src->opened) {
-		pr_err("%s: Source not opened\n", __func__);
-		mutex_unlock(&src->device->mutex);
-		pm_runtime_mark_last_busy(src->device->dev);
-		pm_runtime_put_autosuspend(src->device->dev);
-		return -EINVAL;
-	}
-
-	reg = readl_relaxed(src->device->base +
-			TSPP2_SRC_CONFIG(src->hw_index));
-
-	if (check_sync_byte)
-		reg |= (0x1 << SRC_CONFIG_CHECK_SYNC_OFFS);
-	else
-		reg &= ~(0x1 << SRC_CONFIG_CHECK_SYNC_OFFS);
-
-	reg &= ~(0xFF << SRC_CONFIG_SYNC_BYTE_OFFS);
-	reg |= (sync_byte_value << SRC_CONFIG_SYNC_BYTE_OFFS);
-
-	writel_relaxed(reg, src->device->base +
-			TSPP2_SRC_CONFIG(src->hw_index));
-
-	mutex_unlock(&src->device->mutex);
-
-	pm_runtime_mark_last_busy(src->device->dev);
-	pm_runtime_put_autosuspend(src->device->dev);
-
-	dev_dbg(src->device->dev, "%s: successful\n", __func__);
-
-	return 0;
-}
-EXPORT_SYMBOL(tspp2_src_sync_byte_config_set);
-
-/**
- * tspp2_src_sync_byte_config_get() - Get source sync byte configuration.
- *
- * @src_handle:		Source handle.
- * @check_sync_byte:	Check TS packet sync byte indication.
- * @sync_byte_value:	Sync byte value.
- *
- * Return 0 on success, error value otherwise.
- */
-int tspp2_src_sync_byte_config_get(u32 src_handle,
-			int *check_sync_byte,
-			u8 *sync_byte_value)
-{
-	int ret;
-	u32 reg = 0;
-	struct tspp2_src *src = (struct tspp2_src *)src_handle;
-
-	if (!src) {
-		pr_err("%s: Invalid source handle\n", __func__);
-		return -EINVAL;
-	}
-	if (!check_sync_byte || !sync_byte_value) {
-		pr_err("%s: NULL pointer\n", __func__);
-		return -EINVAL;
-	}
-
-	ret = pm_runtime_get_sync(src->device->dev);
-	if (ret < 0)
-		return ret;
-
-	if (mutex_lock_interruptible(&src->device->mutex)) {
-		pm_runtime_mark_last_busy(src->device->dev);
-		pm_runtime_put_autosuspend(src->device->dev);
-		return -ERESTARTSYS;
-	}
-
-	if (!src->device->opened) {
-		pr_err("%s: Device must be opened first\n", __func__);
-		mutex_unlock(&src->device->mutex);
-		pm_runtime_mark_last_busy(src->device->dev);
-		pm_runtime_put_autosuspend(src->device->dev);
-		return -EPERM;
-	}
-
-	if (!src->opened) {
-		pr_err("%s: Source not opened\n", __func__);
-		mutex_unlock(&src->device->mutex);
-		pm_runtime_mark_last_busy(src->device->dev);
-		pm_runtime_put_autosuspend(src->device->dev);
-		return -EINVAL;
-	}
-
-	reg = readl_relaxed(src->device->base +
-			TSPP2_SRC_CONFIG(src->hw_index));
-
-	*check_sync_byte = (reg >> SRC_CONFIG_CHECK_SYNC_OFFS) & 0x1;
-	*sync_byte_value = (reg >> SRC_CONFIG_SYNC_BYTE_OFFS) & 0xFF;
-
-	mutex_unlock(&src->device->mutex);
-
-	pm_runtime_mark_last_busy(src->device->dev);
-	pm_runtime_put_autosuspend(src->device->dev);
-
-	dev_dbg(src->device->dev, "%s: successful\n", __func__);
-
-	return 0;
-}
-EXPORT_SYMBOL(tspp2_src_sync_byte_config_get);
-
-/**
- * tspp2_src_scrambling_config_set() - Set source scrambling configuration.
- *
- * @src_handle:	Source to configure.
- * @cfg:	Scrambling configuration to set.
- *
- * Return 0 on success, error value otherwise.
- */
-int tspp2_src_scrambling_config_set(u32 src_handle,
-			const struct tspp2_src_scrambling_config *cfg)
-{
-	int ret;
-	u32 reg = 0;
-	struct tspp2_src *src = (struct tspp2_src *)src_handle;
-
-	if (!src) {
-		pr_err("%s: Invalid source handle\n", __func__);
-		return -EINVAL;
-	}
-	if (!cfg) {
-		pr_err("%s: NULL pointer\n", __func__);
-		return -EINVAL;
-	}
-
-	ret = pm_runtime_get_sync(src->device->dev);
-	if (ret < 0)
-		return ret;
-
-	if (mutex_lock_interruptible(&src->device->mutex)) {
-		pm_runtime_mark_last_busy(src->device->dev);
-		pm_runtime_put_autosuspend(src->device->dev);
-		return -ERESTARTSYS;
-	}
-
-	if (!src->device->opened) {
-		pr_err("%s: Device must be opened first\n", __func__);
-		mutex_unlock(&src->device->mutex);
-		pm_runtime_mark_last_busy(src->device->dev);
-		pm_runtime_put_autosuspend(src->device->dev);
-		return -EPERM;
-	}
-
-	if (!src->opened) {
-		pr_err("%s: Source not opened\n", __func__);
-		mutex_unlock(&src->device->mutex);
-		pm_runtime_mark_last_busy(src->device->dev);
-		pm_runtime_put_autosuspend(src->device->dev);
-		return -EINVAL;
-	}
-
-	reg = readl_relaxed(src->device->base +
-			TSPP2_SRC_CONFIG(src->hw_index));
-
-	/* Clear all scrambling configuration bits before setting them */
-	reg &= ~(0x3 << SRC_CONFIG_SCRAMBLING0_OFFS);
-	reg &= ~(0x3 << SRC_CONFIG_SCRAMBLING1_OFFS);
-	reg &= ~(0x3 << SRC_CONFIG_SCRAMBLING2_OFFS);
-	reg &= ~(0x3 << SRC_CONFIG_SCRAMBLING3_OFFS);
-	reg &= ~(0x3 << SRC_CONFIG_SCRAMBLING_MONITOR_OFFS);
-
-	reg |= (cfg->scrambling_0_ctrl << SRC_CONFIG_SCRAMBLING0_OFFS);
-	reg |= (cfg->scrambling_1_ctrl << SRC_CONFIG_SCRAMBLING1_OFFS);
-	reg |= (cfg->scrambling_2_ctrl << SRC_CONFIG_SCRAMBLING2_OFFS);
-	reg |= (cfg->scrambling_3_ctrl << SRC_CONFIG_SCRAMBLING3_OFFS);
-	reg |= (cfg->scrambling_bits_monitoring <<
-					SRC_CONFIG_SCRAMBLING_MONITOR_OFFS);
-
-	writel_relaxed(reg, src->device->base +
-			TSPP2_SRC_CONFIG(src->hw_index));
-
-	src->scrambling_bits_monitoring = cfg->scrambling_bits_monitoring;
-
-	mutex_unlock(&src->device->mutex);
-
-	pm_runtime_mark_last_busy(src->device->dev);
-	pm_runtime_put_autosuspend(src->device->dev);
-
-	dev_dbg(src->device->dev, "%s: successful\n", __func__);
-
-	return 0;
-}
-EXPORT_SYMBOL(tspp2_src_scrambling_config_set);
-
-/**
- * tspp2_src_scrambling_config_get() - Get source scrambling configuration.
- *
- * @src_handle:	Source handle.
- * @cfg:	Scrambling configuration.
- *
- * Return 0 on success, error value otherwise.
- */
-int tspp2_src_scrambling_config_get(u32 src_handle,
-			struct tspp2_src_scrambling_config *cfg)
-{
-	int ret;
-	u32 reg = 0;
-	struct tspp2_src *src = (struct tspp2_src *)src_handle;
-
-	if (!src) {
-		pr_err("%s: Invalid source handle\n", __func__);
-		return -EINVAL;
-	}
-	if (!cfg) {
-		pr_err("%s: NULL pointer\n", __func__);
-		return -EINVAL;
-	}
-
-	ret = pm_runtime_get_sync(src->device->dev);
-	if (ret < 0)
-		return ret;
-
-	if (mutex_lock_interruptible(&src->device->mutex)) {
-		pm_runtime_mark_last_busy(src->device->dev);
-		pm_runtime_put_autosuspend(src->device->dev);
-		return -ERESTARTSYS;
-	}
-
-	if (!src->device->opened) {
-		pr_err("%s: Device must be opened first\n", __func__);
-		mutex_unlock(&src->device->mutex);
-		pm_runtime_mark_last_busy(src->device->dev);
-		pm_runtime_put_autosuspend(src->device->dev);
-		return -EPERM;
-	}
-
-	if (!src->opened) {
-		pr_err("%s: Source not opened\n", __func__);
-		mutex_unlock(&src->device->mutex);
-		pm_runtime_mark_last_busy(src->device->dev);
-		pm_runtime_put_autosuspend(src->device->dev);
-		return -EINVAL;
-	}
-
-	reg = readl_relaxed(src->device->base +
-			TSPP2_SRC_CONFIG(src->hw_index));
-
-	cfg->scrambling_0_ctrl = ((reg >> SRC_CONFIG_SCRAMBLING0_OFFS) & 0x3);
-	cfg->scrambling_1_ctrl = ((reg >> SRC_CONFIG_SCRAMBLING1_OFFS) & 0x3);
-	cfg->scrambling_2_ctrl = ((reg >> SRC_CONFIG_SCRAMBLING2_OFFS) & 0x3);
-	cfg->scrambling_3_ctrl = ((reg >> SRC_CONFIG_SCRAMBLING3_OFFS) & 0x3);
-	cfg->scrambling_bits_monitoring =
-			((reg >> SRC_CONFIG_SCRAMBLING_MONITOR_OFFS) & 0x3);
-
-	mutex_unlock(&src->device->mutex);
-
-	pm_runtime_mark_last_busy(src->device->dev);
-	pm_runtime_put_autosuspend(src->device->dev);
-
-	dev_dbg(src->device->dev, "%s: successful\n", __func__);
-
-	return 0;
-}
-EXPORT_SYMBOL(tspp2_src_scrambling_config_get);
-
-/**
- * tspp2_src_packet_format_set() - Set source packet size and format.
- *
- * @src_handle:	Source to configure.
- * @format:	Packet format.
- *
- * Return 0 on success, error value otherwise.
- */
-int tspp2_src_packet_format_set(u32 src_handle,
-				enum tspp2_packet_format format)
-{
-	int ret;
-	u32 reg = 0;
-	struct tspp2_src *src = (struct tspp2_src *)src_handle;
-
-	if (!src) {
-		pr_err("%s: Invalid source handle\n", __func__);
-		return -EINVAL;
-	}
-
-	ret = pm_runtime_get_sync(src->device->dev);
-	if (ret < 0)
-		return ret;
-
-	if (mutex_lock_interruptible(&src->device->mutex)) {
-		pm_runtime_mark_last_busy(src->device->dev);
-		pm_runtime_put_autosuspend(src->device->dev);
-		return -ERESTARTSYS;
-	}
-
-	if (!src->device->opened) {
-		pr_err("%s: Device must be opened first\n", __func__);
-		mutex_unlock(&src->device->mutex);
-		pm_runtime_mark_last_busy(src->device->dev);
-		pm_runtime_put_autosuspend(src->device->dev);
-		return -EPERM;
-	}
-
-	if (!src->opened) {
-		pr_err("%s: Source not opened\n", __func__);
-		mutex_unlock(&src->device->mutex);
-		pm_runtime_mark_last_busy(src->device->dev);
-		pm_runtime_put_autosuspend(src->device->dev);
-		return -EINVAL;
-	}
-
-	if (src->input == TSPP2_INPUT_MEMORY) {
-		reg = readl_relaxed(src->device->base +
-			TSPP2_MEM_INPUT_SRC_CONFIG(src->hw_index));
-
-		reg &= ~(0x1 << MEM_INPUT_SRC_CONFIG_STAMP_SUFFIX_OFFS);
-		reg &= ~(0x1 << MEM_INPUT_SRC_CONFIG_STAMP_EN_OFFS);
-
-		switch (format) {
-		case TSPP2_PACKET_FORMAT_188_RAW:
-			/* We do not need to set any bit */
-			break;
-		case TSPP2_PACKET_FORMAT_192_HEAD:
-			reg |= (0x1 << MEM_INPUT_SRC_CONFIG_STAMP_EN_OFFS);
-			break;
-		case TSPP2_PACKET_FORMAT_192_TAIL:
-			reg |= (0x1 << MEM_INPUT_SRC_CONFIG_STAMP_EN_OFFS);
-			reg |= (0x1 << MEM_INPUT_SRC_CONFIG_STAMP_SUFFIX_OFFS);
-			break;
-		default:
-			pr_err("%s: Unknown packet format\n", __func__);
-			mutex_unlock(&src->device->mutex);
-			pm_runtime_mark_last_busy(src->device->dev);
-			pm_runtime_put_autosuspend(src->device->dev);
-			return -EINVAL;
-		}
-		writel_relaxed(reg, src->device->base +
-			TSPP2_MEM_INPUT_SRC_CONFIG(src->hw_index));
-	}
-	src->pkt_format = format;
-
-	/* Update source's input pipe threshold if needed */
-	if (src->input_pipe) {
-		if (src->pkt_format == TSPP2_PACKET_FORMAT_188_RAW)
-			src->input_pipe->threshold = 188;
-		else
-			src->input_pipe->threshold = 192;
-
-		writel_relaxed(src->input_pipe->threshold,
-			src->input_pipe->device->base +
-			TSPP2_PIPE_THRESH_CONFIG(src->input_pipe->hw_index));
-	}
-
-	mutex_unlock(&src->device->mutex);
-
-	pm_runtime_mark_last_busy(src->device->dev);
-	pm_runtime_put_autosuspend(src->device->dev);
-
-	dev_dbg(src->device->dev, "%s: successful\n", __func__);
-
-	return 0;
-}
-EXPORT_SYMBOL(tspp2_src_packet_format_set);
-
-/**
- * tspp2_src_pipe_attach() - Attach a pipe to a source.
- *
- * @src_handle:		Source to attach the pipe to.
- * @pipe_handle:	Pipe to attach to the source.
- * @cfg:		For output pipes - the pipe's pull mode parameters.
- *			It is not allowed to pass NULL for output pipes.
- *			For input pipes this is irrelevant and the caller can
- *			pass NULL.
- *
- * This function attaches a given pipe to a given source.
- * The pipe's mode (input or output) was set when the pipe was opened.
- * An input pipe can be attached to a single source (with memory input).
- * A source can have multiple output pipes attached, and an output pipe can
- * be attached to multiple sources.
- *
- * Return 0 on success, error value otherwise.
- */
-int tspp2_src_pipe_attach(u32 src_handle,
-				u32 pipe_handle,
-				const struct tspp2_pipe_pull_mode_params *cfg)
-{
-	int ret;
-	struct tspp2_src *src = (struct tspp2_src *)src_handle;
-	struct tspp2_pipe *pipe = (struct tspp2_pipe *)pipe_handle;
-	struct tspp2_output_pipe *output_pipe = NULL;
-	u32 reg;
-
-	if (!src || !pipe) {
-		pr_err("%s: Invalid source or pipe handle\n", __func__);
-		return -EINVAL;
-	}
-
-	ret = pm_runtime_get_sync(src->device->dev);
-	if (ret < 0)
-		return ret;
-
-	if (mutex_lock_interruptible(&src->device->mutex)) {
-		pm_runtime_mark_last_busy(src->device->dev);
-		pm_runtime_put_autosuspend(src->device->dev);
-		return -ERESTARTSYS;
-	}
-
-	if (!src->device->opened) {
-		pr_err("%s: Device must be opened first\n", __func__);
-		mutex_unlock(&src->device->mutex);
-		pm_runtime_mark_last_busy(src->device->dev);
-		pm_runtime_put_autosuspend(src->device->dev);
-		return -EPERM;
-	}
-
-	if (!src->opened) {
-		pr_err("%s: Source not opened\n", __func__);
-		goto err_inval;
-	}
-
-	if (!pipe->opened) {
-		pr_err("%s: Pipe not opened\n", __func__);
-		goto err_inval;
-	}
-	if ((pipe->cfg.pipe_mode == TSPP2_SRC_PIPE_OUTPUT) && (cfg == NULL)) {
-		pr_err("%s: Invalid pull mode parameters\n", __func__);
-		goto err_inval;
-	}
-
-	if (pipe->cfg.pipe_mode == TSPP2_SRC_PIPE_INPUT) {
-		if (src->input_pipe != NULL) {
-			pr_err("%s: Source already has an input pipe attached\n",
-				__func__);
-			goto err_inval;
-		}
-		if (pipe->ref_cnt > 0) {
-			pr_err(
-				"%s: Pipe %u is already attached to a source. An input pipe can only be attached once\n",
-				__func__, pipe_handle);
-			goto err_inval;
-		}
-		/*
-		 * Input pipe threshold is determined according to the
-		 * source's packet size.
-		 */
-		if (src->pkt_format == TSPP2_PACKET_FORMAT_188_RAW)
-			pipe->threshold = 188;
-		else
-			pipe->threshold = 192;
-
-		src->input_pipe = pipe;
-
-		reg = readl_relaxed(src->device->base +
-			TSPP2_MEM_INPUT_SRC_CONFIG(src->hw_index));
-		reg &= ~(0x1F << MEM_INPUT_SRC_CONFIG_INPUT_PIPE_OFFS);
-		reg |= (pipe->hw_index << MEM_INPUT_SRC_CONFIG_INPUT_PIPE_OFFS);
-		writel_relaxed(reg, src->device->base +
-			TSPP2_MEM_INPUT_SRC_CONFIG(src->hw_index));
-	} else {
-		list_for_each_entry(output_pipe,
-				&src->output_pipe_list, link) {
-			if (output_pipe->pipe == pipe) {
-				pr_err(
-				"%s: Output pipe %u is already attached to source %u\n",
-					__func__, pipe_handle, src_handle);
-				goto err_inval;
-			}
-		}
-		output_pipe = kmalloc(sizeof(struct tspp2_output_pipe),
-				GFP_KERNEL);
-		if (!output_pipe) {
-			pr_err("%s: No memory to save output pipe\n", __func__);
-			mutex_unlock(&src->device->mutex);
-			pm_runtime_mark_last_busy(src->device->dev);
-			pm_runtime_put_autosuspend(src->device->dev);
-			return -ENOMEM;
-		}
-		output_pipe->pipe = pipe;
-		pipe->threshold = (cfg->threshold & 0xFFFF);
-		list_add_tail(&output_pipe->link, &src->output_pipe_list);
-
-		reg = readl_relaxed(src->device->base +
-			TSPP2_SRC_DEST_PIPES(src->hw_index));
-		if (cfg->is_stalling)
-			reg |= (0x1 << pipe->hw_index);
-		else
-			reg &= ~(0x1 << pipe->hw_index);
-		writel_relaxed(reg, src->device->base +
-			TSPP2_SRC_DEST_PIPES(src->hw_index));
-	}
-
-	reg = readl_relaxed(pipe->device->base +
-			TSPP2_PIPE_THRESH_CONFIG(pipe->hw_index));
-	if ((pipe->cfg.pipe_mode == TSPP2_SRC_PIPE_OUTPUT) &&
-		(pipe->ref_cnt > 0) && (pipe->threshold != (reg & 0xFFFF))) {
-		pr_warn("%s: overwriting output pipe threshold\n", __func__);
-	}
-
-	writel_relaxed(pipe->threshold, pipe->device->base +
-			TSPP2_PIPE_THRESH_CONFIG(pipe->hw_index));
-
-	pipe->ref_cnt++;
-	src->num_associated_pipes++;
-
-	mutex_unlock(&src->device->mutex);
-
-	pm_runtime_mark_last_busy(src->device->dev);
-	pm_runtime_put_autosuspend(src->device->dev);
-
-	dev_dbg(src->device->dev, "%s: successful\n", __func__);
-
-	return 0;
-
-err_inval:
-	mutex_unlock(&src->device->mutex);
-	pm_runtime_mark_last_busy(src->device->dev);
-	pm_runtime_put_autosuspend(src->device->dev);
-
-	return -EINVAL;
-}
-EXPORT_SYMBOL(tspp2_src_pipe_attach);
-
-/**
- * tspp2_src_pipe_detach() - Detach a pipe from a source.
- *
- * @src_handle:		Source to detach the pipe from.
- * @pipe_handle:	Pipe to detach from the source.
- *
- * Detaches a pipe from a source. The given pipe should have been previously
- * attached to this source as either an input pipe or an output pipe.
- * Note: there is no checking if this pipe is currently defined as the output
- * pipe of any operation!
- *
- * Return 0 on success, error value otherwise.
- */
-int tspp2_src_pipe_detach(u32 src_handle, u32 pipe_handle)
-{
-	int ret;
-	struct tspp2_src *src = (struct tspp2_src *)src_handle;
-	struct tspp2_pipe *pipe = (struct tspp2_pipe *)pipe_handle;
-	struct tspp2_output_pipe *output_pipe = NULL;
-	int found = 0;
-	u32 reg;
-
-	if (!src || !pipe) {
-		pr_err("%s: Invalid source or pipe handle\n", __func__);
-		return -EINVAL;
-	}
-
-	ret = pm_runtime_get_sync(src->device->dev);
-	if (ret < 0)
-		return ret;
-
-	mutex_lock(&src->device->mutex);
-
-	if (!src->device->opened) {
-		pr_err("%s: Device must be opened first\n", __func__);
-		mutex_unlock(&src->device->mutex);
-		pm_runtime_mark_last_busy(src->device->dev);
-		pm_runtime_put_autosuspend(src->device->dev);
-		return -EPERM;
-	}
-
-	if (!src->opened) {
-		pr_err("%s: Source not opened\n", __func__);
-		goto err_inval;
-	}
-
-	if (!pipe->opened) {
-		pr_err("%s: Pipe not opened\n", __func__);
-		goto err_inval;
-	}
-
-	if (pipe->cfg.pipe_mode == TSPP2_SRC_PIPE_INPUT) {
-		if (src->input_pipe != pipe) {
-			pr_err(
-				"%s: Input pipe %u is not attached to source %u\n",
-				__func__, pipe_handle, src_handle);
-			goto err_inval;
-		}
-
-		writel_relaxed(0xFFFF,	src->input_pipe->device->base +
-			TSPP2_PIPE_THRESH_CONFIG(src->input_pipe->hw_index));
-
-		if (src->enabled) {
-			pr_warn("%s: Detaching input pipe from an active memory source\n",
-				__func__);
-		}
-		/*
-		 * Note: not updating TSPP2_MEM_INPUT_SRC_CONFIG to reflect
-		 * this pipe is detached, since there is no invalid value we
-		 * can write instead. tspp2_src_pipe_attach() already takes
-		 * care of zeroing the relevant bit-field before writing the
-		 * new pipe nummber.
-		 */
-
-		src->input_pipe = NULL;
-	} else {
-		list_for_each_entry(output_pipe,
-				&src->output_pipe_list, link) {
-			if (output_pipe->pipe == pipe) {
-				found = 1;
-				break;
-			}
-		}
-		if (found) {
-			list_del(&output_pipe->link);
-			kfree(output_pipe);
-			reg = readl_relaxed(src->device->base +
-				TSPP2_SRC_DEST_PIPES(src->hw_index));
-			reg &= ~(0x1 << pipe->hw_index);
-			writel_relaxed(reg, src->device->base +
-				TSPP2_SRC_DEST_PIPES(src->hw_index));
-			if (pipe->ref_cnt == 1) {
-				writel_relaxed(0xFFFF,	pipe->device->base +
-					TSPP2_PIPE_THRESH_CONFIG(
-							pipe->hw_index));
-			}
-		} else {
-			pr_err("%s: Output pipe %u is not attached to source %u\n",
-				__func__, pipe_handle, src_handle);
-			goto err_inval;
-		}
-	}
-	pipe->ref_cnt--;
-	src->num_associated_pipes--;
-
-	mutex_unlock(&src->device->mutex);
-
-	pm_runtime_mark_last_busy(src->device->dev);
-	pm_runtime_put_autosuspend(src->device->dev);
-
-	dev_dbg(src->device->dev, "%s: successful\n", __func__);
-
-	return 0;
-
-err_inval:
-	mutex_unlock(&src->device->mutex);
-	pm_runtime_mark_last_busy(src->device->dev);
-	pm_runtime_put_autosuspend(src->device->dev);
-
-	return -EINVAL;
-}
-EXPORT_SYMBOL(tspp2_src_pipe_detach);
-
-/**
- * tspp2_src_enable() - Enable source.
- *
- * @src_handle:	Source to enable.
- *
- * Return 0 on success, error value otherwise.
- */
-int tspp2_src_enable(u32 src_handle)
-{
-	struct tspp2_src *src = (struct tspp2_src *)src_handle;
-	u32 reg;
-	int ret;
-
-	if (!src) {
-		pr_err("%s: Invalid source handle\n", __func__);
-		return -EINVAL;
-	}
-
-	ret = pm_runtime_get_sync(src->device->dev);
-	if (ret < 0)
-		return ret;
-
-	if (mutex_lock_interruptible(&src->device->mutex)) {
-		pm_runtime_mark_last_busy(src->device->dev);
-		pm_runtime_put_autosuspend(src->device->dev);
-		return -ERESTARTSYS;
-	}
-
-	if (!src->device->opened) {
-		pr_err("%s: Device must be opened first\n", __func__);
-		mutex_unlock(&src->device->mutex);
-		pm_runtime_mark_last_busy(src->device->dev);
-		pm_runtime_put_autosuspend(src->device->dev);
-		return -EPERM;
-	}
-
-	if (!src->opened) {
-		pr_err("%s: Source not opened\n", __func__);
-		mutex_unlock(&src->device->mutex);
-		pm_runtime_mark_last_busy(src->device->dev);
-		pm_runtime_put_autosuspend(src->device->dev);
-		return -EINVAL;
-	}
-
-	if (src->enabled) {
-		pr_warn("%s: Source already enabled\n", __func__);
-		mutex_unlock(&src->device->mutex);
-		pm_runtime_mark_last_busy(src->device->dev);
-		pm_runtime_put_autosuspend(src->device->dev);
-		return 0;
-	}
-
-	/*
-	 * Memory sources require their input pipe to be configured
-	 * before enabling the source.
-	 */
-	if ((src->input == TSPP2_INPUT_MEMORY) && (src->input_pipe == NULL)) {
-		pr_err("%s: A memory source must have an input pipe attached before enabling the source",
-			__func__);
-		mutex_unlock(&src->device->mutex);
-		pm_runtime_mark_last_busy(src->device->dev);
-		pm_runtime_put_autosuspend(src->device->dev);
-		return -EINVAL;
-	}
-
-	if (src->device->num_enabled_sources == 0) {
-		ret = tspp2_clock_start(src->device);
-		if (ret) {
-			mutex_unlock(&src->device->mutex);
-			pm_runtime_mark_last_busy(src->device->dev);
-			pm_runtime_put_autosuspend(src->device->dev);
-			return ret;
-		}
-		__pm_stay_awake(&src->device->wakeup_src);
-	}
-
-	if ((src->input == TSPP2_INPUT_TSIF0) ||
-		(src->input == TSPP2_INPUT_TSIF1)) {
-		tspp2_tsif_start(&src->device->tsif_devices[src->input]);
-
-		reg = readl_relaxed(src->device->base +
-			TSPP2_TSIF_INPUT_SRC_CONFIG(src->input));
-		reg |= (0x1 << TSIF_INPUT_SRC_CONFIG_INPUT_EN_OFFS);
-		writel_relaxed(reg, src->device->base +
-			TSPP2_TSIF_INPUT_SRC_CONFIG(src->input));
-	} else {
-		reg = readl_relaxed(src->device->base +
-			TSPP2_MEM_INPUT_SRC_CONFIG(src->hw_index));
-		reg |= (0x1 << MEM_INPUT_SRC_CONFIG_INPUT_EN_OFFS);
-		writel_relaxed(reg, src->device->base +
-			TSPP2_MEM_INPUT_SRC_CONFIG(src->hw_index));
-	}
-
-	src->enabled = 1;
-	src->device->num_enabled_sources++;
-
-	mutex_unlock(&src->device->mutex);
-
-	pm_runtime_mark_last_busy(src->device->dev);
-	pm_runtime_put_autosuspend(src->device->dev);
-
-	dev_dbg(src->device->dev, "%s: successful\n", __func__);
-
-	return 0;
-}
-EXPORT_SYMBOL(tspp2_src_enable);
-
-/**
- * tspp2_src_disable() - Disable source.
- *
- * @src_handle:	Source to disable.
- *
- * Return 0 on success, error value otherwise.
- */
-int tspp2_src_disable(u32 src_handle)
-{
-	struct tspp2_src *src = (struct tspp2_src *)src_handle;
-	int ret;
-
-	if (!src) {
-		pr_err("%s: Invalid source handle\n", __func__);
-		return -EINVAL;
-	}
-
-	ret = pm_runtime_get_sync(src->device->dev);
-	if (ret < 0)
-		return ret;
-
-	mutex_lock(&src->device->mutex);
-
-	if (!src->device->opened) {
-		pr_err("%s: Device must be opened first\n", __func__);
-		mutex_unlock(&src->device->mutex);
-		pm_runtime_mark_last_busy(src->device->dev);
-		pm_runtime_put_autosuspend(src->device->dev);
-		return -EPERM;
-	}
-
-	ret = tspp2_src_disable_internal(src);
-
-	mutex_unlock(&src->device->mutex);
-
-	pm_runtime_mark_last_busy(src->device->dev);
-	pm_runtime_put_autosuspend(src->device->dev);
-
-	if (!ret)
-		dev_dbg(src->device->dev, "%s: successful\n", __func__);
-
-	return ret;
-}
-EXPORT_SYMBOL(tspp2_src_disable);
-
-/**
- *  tspp2_filter_ops_clear() - Clear filter operations database and HW
- *
- * @filter:	The filter to work on.
- */
-static void tspp2_filter_ops_clear(struct tspp2_filter *filter)
-{
-	int i;
-
-	/* Set all filter operations in HW to Exit operation */
-	for (i = 0; i < TSPP2_MAX_OPS_PER_FILTER; i++) {
-		writel_relaxed(TSPP2_OPCODE_EXIT, filter->device->base +
-					TSPP2_OPCODE(filter->hw_index, i));
-	}
-	memset(filter->operations, 0,
-		(sizeof(struct tspp2_operation) * TSPP2_MAX_OPS_PER_FILTER));
-	filter->num_user_operations = 0;
-	filter->indexing_op_set = 0;
-	filter->raw_op_with_indexing = 0;
-	filter->pes_analysis_op_set = 0;
-	filter->raw_op_set = 0;
-	filter->pes_tx_op_set = 0;
-}
-
-/**
- * tspp2_filter_context_reset() - Reset filter context and release it.
- *
- * @filter:	The filter to work on.
- */
-static void tspp2_filter_context_reset(struct tspp2_filter *filter)
-{
-	/* Reset this filter's context. Each register handles 32 contexts */
-	writel_relaxed((0x1 << TSPP2_MODULUS_OP(filter->context, 32)),
-		filter->device->base +
-			TSPP2_TSP_CONTEXT_RESET(filter->context >> 5));
-	writel_relaxed((0x1 << TSPP2_MODULUS_OP(filter->context, 32)),
-		filter->device->base +
-			TSPP2_PES_CONTEXT_RESET(filter->context >> 5));
-	writel_relaxed((0x1 << TSPP2_MODULUS_OP(filter->context, 32)),
-		filter->device->base +
-			TSPP2_INDEXING_CONTEXT_RESET(filter->context >> 5));
-
-	writel_relaxed(0, filter->device->base +
-		TSPP2_FILTER_ENTRY1(filter->hw_index));
-
-	/* Release context */
-	filter->device->contexts[filter->context] = 0;
-}
-
-/**
- * tspp2_filter_sw_reset() - Reset filter SW fields helper function.
- *
- * @filter:	The filter to work on.
- */
-static void tspp2_filter_sw_reset(struct tspp2_filter *filter)
-{
-	unsigned long flags;
-	/*
-	 * All fields are cleared when opening a filter. Still it is important
-	 * to reset some of the fields here, specifically to set opened to 0 and
-	 * also to set the callback to NULL.
-	 */
-	filter->opened = 0;
-	filter->src = NULL;
-	filter->batch = NULL;
-	filter->context = 0;
-	filter->hw_index = 0;
-	filter->pid_value = 0;
-	filter->mask = 0;
-	spin_lock_irqsave(&filter->device->spinlock, flags);
-	filter->event_callback = NULL;
-	filter->event_cookie = NULL;
-	filter->event_bitmask = 0;
-	spin_unlock_irqrestore(&filter->device->spinlock, flags);
-	filter->enabled = 0;
-}
-
-/**
- * tspp2_src_batch_set() - Set/clear a filter batch to/from a source.
- *
- * @src:	The source to work on.
- * @batch_id:	The batch to set/clear.
- * @set:	Set/clear flag.
- */
-static void tspp2_src_batch_set(struct tspp2_src *src, u8 batch_id, int set)
-{
-	u32 reg = 0;
-
-	if (src->input == TSPP2_INPUT_MEMORY) {
-		reg = readl_relaxed(src->device->base +
-			TSPP2_MEM_INPUT_SRC_CONFIG(src->hw_index));
-		if (set)
-			reg |= ((1 << batch_id) <<
-				MEM_INPUT_SRC_CONFIG_BATCHES_OFFS);
-		else
-			reg &= ~((1 << batch_id) <<
-				MEM_INPUT_SRC_CONFIG_BATCHES_OFFS);
-		writel_relaxed(reg, src->device->base +
-			TSPP2_MEM_INPUT_SRC_CONFIG(src->hw_index));
-	} else {
-		reg = readl_relaxed(src->device->base +
-			TSPP2_TSIF_INPUT_SRC_CONFIG(src->input));
-		if (set)
-			reg |= ((1 << batch_id) <<
-				TSIF_INPUT_SRC_CONFIG_BATCHES_OFFS);
-		else
-			reg &= ~((1 << batch_id) <<
-				TSIF_INPUT_SRC_CONFIG_BATCHES_OFFS);
-		writel_relaxed(reg, src->device->base +
-			TSPP2_TSIF_INPUT_SRC_CONFIG(src->input));
-	}
-}
-
-/**
- * tspp2_src_filters_clear() - Clear all filters from a source.
- *
- * @src_handle:	Source to clear all filters from.
- *
- * Return 0 on success, error value otherwise.
- */
-int tspp2_src_filters_clear(u32 src_handle)
-{
-	int ret;
-	int i;
-	struct tspp2_filter *filter = NULL;
-	struct tspp2_filter *tmp_filter;
-	struct tspp2_filter_batch *batch = NULL;
-	struct tspp2_filter_batch *tmp_batch;
-	struct tspp2_src *src = (struct tspp2_src *)src_handle;
-
-	if (!src) {
-		pr_err("%s: Invalid source handle\n", __func__);
-		return -EINVAL;
-	}
-
-	ret = pm_runtime_get_sync(src->device->dev);
-	if (ret < 0)
-		return ret;
-
-	mutex_lock(&src->device->mutex);
-
-	if (!src->device->opened) {
-		pr_err("%s: Device must be opened first\n", __func__);
-		mutex_unlock(&src->device->mutex);
-		pm_runtime_mark_last_busy(src->device->dev);
-		pm_runtime_put_autosuspend(src->device->dev);
-		return -EPERM;
-	}
-
-	if (!src->opened) {
-		pr_err("%s: Source not opened\n", __func__);
-		mutex_unlock(&src->device->mutex);
-		pm_runtime_mark_last_busy(src->device->dev);
-		pm_runtime_put_autosuspend(src->device->dev);
-		return -EINVAL;
-	}
-
-	/* Go over filters in source, disable them, clear their operations,
-	 * "close" them (similar to tspp2_filter_close function but simpler).
-	 * No need to worry about cases of reserved filter, so just clear
-	 * filters HW- and SW-wise. Then update source's filters and batches
-	 * lists and numbers. Simple :)
-	 */
-	list_for_each_entry_safe(filter, tmp_filter, &src->filters_list, link) {
-		/* Disable filter */
-		writel_relaxed(0, filter->device->base +
-			TSPP2_FILTER_ENTRY0(filter->hw_index));
-		/* Clear filter operations in HW as well as related SW fields */
-		tspp2_filter_ops_clear(filter);
-		/* Reset filter context-based counters */
-		tspp2_filter_counters_reset(filter->device, filter->context);
-		/* Reset filter context and release it back to the device */
-		tspp2_filter_context_reset(filter);
-		/* Reset filter SW fields */
-		tspp2_filter_sw_reset(filter);
-
-		list_del(&filter->link);
-	}
-
-	list_for_each_entry_safe(batch, tmp_batch, &src->batches_list, link) {
-		tspp2_src_batch_set(src, batch->batch_id, 0);
-		for (i = 0; i < TSPP2_FILTERS_PER_BATCH; i++)
-			batch->hw_filters[i] = 0;
-		batch->src = NULL;
-		list_del(&batch->link);
-	}
-
-	src->num_associated_batches = 0;
-	src->num_associated_filters = 0;
-	src->reserved_filter_hw_index = 0;
-
-	mutex_unlock(&src->device->mutex);
-
-	pm_runtime_mark_last_busy(src->device->dev);
-	pm_runtime_put_autosuspend(src->device->dev);
-
-	dev_dbg(src->device->dev, "%s: successful\n", __func__);
-
-	return 0;
-}
-EXPORT_SYMBOL(tspp2_src_filters_clear);
-
-/* Filters and Operations API functions */
-
-/**
- * tspp2_filter_open() - Open a new filter and add it to a source.
- *
- * @src_handle:		Source to add the new filter to.
- * @pid:		Filter's 13-bit PID value.
- * @mask:		Filter's 13-bit mask. Note it is highly recommended
- *			to use a full bit mask of 0x1FFF, so the filter
- *			operates on a unique PID.
- * @filter_handle:	Opened filter handle.
- *
- * Return 0 on success, error value otherwise.
- */
-int tspp2_filter_open(u32 src_handle, u16 pid, u16 mask, u32 *filter_handle)
-{
-	struct tspp2_src *src = (struct tspp2_src *)src_handle;
-	struct tspp2_filter_batch *batch;
-	struct tspp2_filter *filter = NULL;
-	u16 hw_idx;
-	int i;
-	u32 reg = 0;
-	int found = 0;
-	int ret;
-
-	if (!src) {
-		pr_err("%s: Invalid source handle\n", __func__);
-		return -EINVAL;
-	}
-	if (!filter_handle) {
-		pr_err("%s: Invalid filter handle pointer\n", __func__);
-		return -EINVAL;
-	}
-
-	if ((pid & ~0x1FFF) || (mask & ~0x1FFF)) {
-		pr_err("%s: Invalid PID or mask values (13 bits available)\n",
-			__func__);
-		return -EINVAL;
-	}
-
-	ret = pm_runtime_get_sync(src->device->dev);
-	if (ret < 0)
-		return ret;
-
-	if (mutex_lock_interruptible(&src->device->mutex)) {
-		pm_runtime_mark_last_busy(src->device->dev);
-		pm_runtime_put_autosuspend(src->device->dev);
-		return -ERESTARTSYS;
-	}
-
-	if (!src->device->opened) {
-		pr_err("%s: Device must be opened first\n", __func__);
-		mutex_unlock(&src->device->mutex);
-		pm_runtime_mark_last_busy(src->device->dev);
-		pm_runtime_put_autosuspend(src->device->dev);
-		return -EPERM;
-	}
-
-	if (!src->opened) {
-		pr_err("%s: Source not opened\n", __func__);
-		mutex_unlock(&src->device->mutex);
-		pm_runtime_mark_last_busy(src->device->dev);
-		pm_runtime_put_autosuspend(src->device->dev);
-		return -EINVAL;
-	}
-
-	/* Find an available filter object in the device's filters database */
-	for (i = 0; i < TSPP2_NUM_AVAIL_FILTERS; i++)
-		if (!src->device->filters[i].opened)
-			break;
-	if (i == TSPP2_NUM_AVAIL_FILTERS) {
-		pr_err("%s: No available filters\n", __func__);
-		mutex_unlock(&src->device->mutex);
-		pm_runtime_mark_last_busy(src->device->dev);
-		pm_runtime_put_autosuspend(src->device->dev);
-		return -ENOMEM;
-	}
-	filter = &src->device->filters[i];
-
-	/* Find an available context. Each new filter needs a unique context */
-	for (i = 0; i < TSPP2_NUM_AVAIL_CONTEXTS; i++)
-		if (!src->device->contexts[i])
-			break;
-	if (i == TSPP2_NUM_AVAIL_CONTEXTS) {
-		pr_err("%s: No available filters\n", __func__);
-		mutex_unlock(&src->device->mutex);
-		pm_runtime_mark_last_busy(src->device->dev);
-		pm_runtime_put_autosuspend(src->device->dev);
-		return -ENOMEM;
-	}
-	src->device->contexts[i] = 1;
-	filter->context = i;
-
-	if (src->num_associated_batches) {
-		/*
-		 * Look for an available HW filter among the batches
-		 * already associated with this source.
-		 */
-		list_for_each_entry(batch, &src->batches_list, link) {
-			for (i = 0; i < TSPP2_FILTERS_PER_BATCH; i++) {
-				hw_idx = (batch->batch_id *
-						TSPP2_FILTERS_PER_BATCH) + i;
-				if ((hw_idx != src->reserved_filter_hw_index) &&
-					(batch->hw_filters[i] == 0))
-					break;
-			}
-			if (i < TSPP2_FILTERS_PER_BATCH) {
-				/* Found an available HW filter */
-				batch->hw_filters[i] = 1;
-				found = 1;
-				break;
-			}
-		}
-	}
-
-	if (!found) {
-		/* Either the source did not have any associated batches,
-		 * or we could not find an available HW filter in any of
-		 * the source's batches. In any case, we need to find a new
-		 * batch. Then we use the first filter in this batch.
-		 */
-		for (i = 0; i < TSPP2_NUM_BATCHES; i++) {
-			if (!src->device->batches[i].src) {
-				src->device->batches[i].src = src;
-				batch = &src->device->batches[i];
-				batch->hw_filters[0] = 1;
-				hw_idx = (batch->batch_id *
-						TSPP2_FILTERS_PER_BATCH);
-				break;
-			}
-		}
-		if (i == TSPP2_NUM_BATCHES) {
-			pr_err("%s: No available filters\n", __func__);
-			src->device->contexts[filter->context] = 0;
-			filter->context = 0;
-			mutex_unlock(&src->device->mutex);
-			pm_runtime_mark_last_busy(src->device->dev);
-			pm_runtime_put_autosuspend(src->device->dev);
-			return -ENOMEM;
-		}
-
-		tspp2_src_batch_set(src, batch->batch_id, 1);
-
-		list_add_tail(&batch->link, &src->batches_list);
-
-		/* Update reserved filter index only when needed */
-		if (src->num_associated_batches == 0) {
-			src->reserved_filter_hw_index =
-				(batch->batch_id * TSPP2_FILTERS_PER_BATCH) +
-					TSPP2_FILTERS_PER_BATCH - 1;
-		}
-		src->num_associated_batches++;
-	}
-
-	filter->opened = 1;
-	filter->src = src;
-	filter->batch = batch;
-	filter->hw_index = hw_idx;
-	filter->pid_value = pid;
-	filter->mask = mask;
-	filter->indexing_table_id = 0;
-	tspp2_filter_ops_clear(filter);
-	filter->event_callback = NULL;
-	filter->event_cookie = NULL;
-	filter->event_bitmask = 0;
-	filter->enabled = 0;
-	/* device back-pointer is already initialized, always remains valid */
-
-	list_add_tail(&filter->link, &src->filters_list);
-	src->num_associated_filters++;
-
-	/* Reset filter context-based counters */
-	tspp2_filter_counters_reset(filter->device, filter->context);
-
-	/* Reset this filter's context */
-	writel_relaxed((0x1 << TSPP2_MODULUS_OP(filter->context, 32)),
-		filter->device->base +
-		TSPP2_TSP_CONTEXT_RESET(filter->context >> 5));
-	writel_relaxed((0x1 << TSPP2_MODULUS_OP(filter->context, 32)),
-		filter->device->base +
-		TSPP2_PES_CONTEXT_RESET(filter->context >> 5));
-	writel_relaxed((0x1 << TSPP2_MODULUS_OP(filter->context, 32)),
-		filter->device->base +
-		TSPP2_INDEXING_CONTEXT_RESET(filter->context >> 5));
-
-	/* Write PID and mask */
-	reg = ((pid << FILTER_ENTRY0_PID_OFFS) |
-		(mask << FILTER_ENTRY0_MASK_OFFS));
-	writel_relaxed(reg, filter->device->base +
-		TSPP2_FILTER_ENTRY0(filter->hw_index));
-
-	writel_relaxed((filter->context << FILTER_ENTRY1_CONTEXT_OFFS),
-		filter->device->base + TSPP2_FILTER_ENTRY1(filter->hw_index));
-
-	*filter_handle = (u32)filter;
-
-	mutex_unlock(&src->device->mutex);
-
-	pm_runtime_mark_last_busy(src->device->dev);
-	pm_runtime_put_autosuspend(src->device->dev);
-
-	dev_dbg(src->device->dev, "%s: successful\n", __func__);
-
-	return 0;
-}
-EXPORT_SYMBOL(tspp2_filter_open);
-
-/**
- * tspp2_hw_filters_in_batch() - Check for used HW filters in a batch.
- *
- * @batch:	The filter batch to check.
- *
- * Helper function to check if there are any HW filters used on this batch.
- *
- * Return 1 if found a used filter in this batch, 0 otherwise.
- */
-static inline int tspp2_hw_filters_in_batch(struct tspp2_filter_batch *batch)
-{
-	int i;
-
-	for (i = 0; i < TSPP2_FILTERS_PER_BATCH; i++)
-		if (batch->hw_filters[i] == 1)
-			return 1;
-
-	return 0;
-}
-
-/**
- * tspp2_filter_close() - Close a filter.
- *
- * @filter_handle:	Filter to close.
- *
- * Return 0 on success, error value otherwise.
- */
-int tspp2_filter_close(u32 filter_handle)
-{
-	int i;
-	int ret;
-	struct tspp2_device *device;
-	struct tspp2_src *src = NULL;
-	struct tspp2_filter_batch *batch = NULL;
-	struct tspp2_filter_batch *tmp_batch;
-	struct tspp2_filter *filter = (struct tspp2_filter *)filter_handle;
-
-	if (!filter) {
-		pr_err("%s: Invalid filter handle\n", __func__);
-		return -EINVAL;
-	}
-
-	device = filter->device;
-
-	ret = pm_runtime_get_sync(device->dev);
-	if (ret < 0)
-		return ret;
-
-	mutex_lock(&device->mutex);
-
-	if (!device->opened) {
-		pr_err("%s: Device must be opened first\n", __func__);
-		mutex_unlock(&device->mutex);
-		pm_runtime_mark_last_busy(device->dev);
-		pm_runtime_put_autosuspend(device->dev);
-		return -EPERM;
-	}
-
-	if (!filter->opened) {
-		pr_err("%s: Filter already closed\n", __func__);
-		mutex_unlock(&device->mutex);
-		pm_runtime_mark_last_busy(device->dev);
-		pm_runtime_put_autosuspend(device->dev);
-		return -EINVAL;
-	}
-
-	if (filter->num_user_operations)
-		pr_warn("%s: Closing filters that has %d operations\n",
-			__func__, filter->num_user_operations);
-
-	/* Disable filter */
-	writel_relaxed(0, device->base +
-		TSPP2_FILTER_ENTRY0(filter->hw_index));
-
-	/* Clear filter operations in HW as well as related SW fields */
-	tspp2_filter_ops_clear(filter);
-
-	/* Reset filter context-based counters */
-	tspp2_filter_counters_reset(device, filter->context);
-
-	/* Reset filter context and release it back to the device */
-	tspp2_filter_context_reset(filter);
-
-	/* Mark filter as unused in batch */
-	filter->batch->hw_filters[(filter->hw_index -
-		(filter->batch->batch_id * TSPP2_FILTERS_PER_BATCH))] = 0;
-
-	/* Remove filter from source */
-	list_del(&filter->link);
-	filter->src->num_associated_filters--;
-
-	/* We may need to update the reserved filter for this source.
-	 * Cases to handle:
-	 * 1. This is the last filter on this source.
-	 * 2. This is the last filter on this batch + reserved filter is not on
-	 * this batch.
-	 * 3. This is the last filter on this batch + reserved filter is on this
-	 * batch. Can possibly move reserved filter to another batch if space is
-	 * available.
-	 * 4. This is not the last filter on this batch. The reserved filter may
-	 * be the only one taking another batch and may be moved to this batch
-	 * to save space.
-	 */
-
-	src = filter->src;
-	/*
-	 * Case #1: this could be the last filter associated with this source.
-	 * If this is the case, we can release the batch too. We don't care
-	 * about the reserved HW filter index, since there are no more filters.
-	 */
-	if (src->num_associated_filters == 0) {
-		filter->batch->src = NULL;
-		list_del(&filter->batch->link);
-		src->num_associated_batches--;
-		tspp2_src_batch_set(src, filter->batch->batch_id, 0);
-		src->reserved_filter_hw_index = 0;
-		goto filter_clear;
-	}
-
-	/*
-	 * If this is the last filter that was used in this batch, we may be
-	 * able to release this entire batch. However, we have to make sure the
-	 * reserved filter is not in this batch. If it is, we may find a place
-	 * for it in another batch in this source.
-	 */
-	if (!tspp2_hw_filters_in_batch(filter->batch)) {
-		/* There are no more used filters on this batch */
-		if ((src->reserved_filter_hw_index <
-			(filter->batch->batch_id * TSPP2_FILTERS_PER_BATCH)) ||
-			(src->reserved_filter_hw_index >=
-			((filter->batch->batch_id * TSPP2_FILTERS_PER_BATCH) +
-				TSPP2_FILTERS_PER_BATCH))) {
-			/* Case #2: the reserved filter is not on this batch */
-			filter->batch->src = NULL;
-			list_del(&filter->batch->link);
-			src->num_associated_batches--;
-			tspp2_src_batch_set(src, filter->batch->batch_id, 0);
-		} else {
-			/*
-			 * Case #3: see if we can "move" the reserved filter to
-			 * a different batch.
-			 */
-			list_for_each_entry_safe(batch, tmp_batch,
-					&src->batches_list, link) {
-				if (batch == filter->batch)
-					continue;
-
-				for (i = 0; i < TSPP2_FILTERS_PER_BATCH; i++) {
-					if (batch->hw_filters[i] == 0) {
-						src->reserved_filter_hw_index =
-							(batch->batch_id *
-							TSPP2_FILTERS_PER_BATCH)
-							+ i;
-
-						filter->batch->src = NULL;
-						list_del(&filter->batch->link);
-						src->num_associated_batches--;
-						tspp2_src_batch_set(src,
-							filter->batch->batch_id,
-							0);
-						goto filter_clear;
-					}
-				}
-			}
-		}
-	} else {
-		/* Case #4: whenever we remove a filter, there is always a
-		 * chance that the reserved filter was the only filter used on a
-		 * different batch. So now this is a good opportunity to check
-		 * if we can release that batch and use the index of the filter
-		 * we're freeing instead.
-		 */
-		list_for_each_entry_safe(batch, tmp_batch,
-				&src->batches_list, link) {
-			if (((src->reserved_filter_hw_index >=
-				(batch->batch_id * TSPP2_FILTERS_PER_BATCH)) &&
-				(src->reserved_filter_hw_index <
-				(batch->batch_id * TSPP2_FILTERS_PER_BATCH +
-				TSPP2_FILTERS_PER_BATCH))) &&
-				!tspp2_hw_filters_in_batch(batch)) {
-				src->reserved_filter_hw_index =
-					filter->hw_index;
-				batch->src = NULL;
-				list_del(&batch->link);
-				src->num_associated_batches--;
-				tspp2_src_batch_set(src, batch->batch_id, 0);
-				break;
-			}
-		}
-	}
-
-filter_clear:
-	tspp2_filter_sw_reset(filter);
-
-	mutex_unlock(&device->mutex);
-
-	pm_runtime_mark_last_busy(device->dev);
-	pm_runtime_put_autosuspend(device->dev);
-
-	dev_dbg(device->dev, "%s: successful\n", __func__);
-
-	return 0;
-}
-EXPORT_SYMBOL(tspp2_filter_close);
-
-/**
- * tspp2_filter_enable() - Enable a filter.
- *
- * @filter_handle:	Filter to enable.
- *
- * Return 0 on success, error value otherwise.
- */
-int tspp2_filter_enable(u32 filter_handle)
-{
-	struct tspp2_filter *filter = (struct tspp2_filter *)filter_handle;
-	u32 reg;
-	int ret;
-
-	if (!filter) {
-		pr_err("%s: Invalid filter handle\n", __func__);
-		return -EINVAL;
-	}
-
-	ret = pm_runtime_get_sync(filter->device->dev);
-	if (ret < 0)
-		return ret;
-
-	if (mutex_lock_interruptible(&filter->device->mutex)) {
-		pm_runtime_mark_last_busy(filter->device->dev);
-		pm_runtime_put_autosuspend(filter->device->dev);
-		return -ERESTARTSYS;
-	}
-
-	if (!filter->device->opened) {
-		pr_err("%s: Device must be opened first\n", __func__);
-		mutex_unlock(&filter->device->mutex);
-		pm_runtime_mark_last_busy(filter->device->dev);
-		pm_runtime_put_autosuspend(filter->device->dev);
-		return -EPERM;
-	}
-
-	if (!filter->opened) {
-		pr_err("%s: Filter not opened\n", __func__);
-		mutex_unlock(&filter->device->mutex);
-		pm_runtime_mark_last_busy(filter->device->dev);
-		pm_runtime_put_autosuspend(filter->device->dev);
-		return -EINVAL;
-	}
-
-	if (filter->enabled) {
-		pr_warn("%s: Filter already enabled\n", __func__);
-		mutex_unlock(&filter->device->mutex);
-		pm_runtime_mark_last_busy(filter->device->dev);
-		pm_runtime_put_autosuspend(filter->device->dev);
-		return 0;
-	}
-
-	reg = readl_relaxed(filter->device->base +
-		TSPP2_FILTER_ENTRY0(filter->hw_index));
-	reg |= (0x1 << FILTER_ENTRY0_EN_OFFS);
-	writel_relaxed(reg, filter->device->base +
-		TSPP2_FILTER_ENTRY0(filter->hw_index));
-
-	filter->enabled = 1;
-
-	mutex_unlock(&filter->device->mutex);
-
-	pm_runtime_mark_last_busy(filter->device->dev);
-	pm_runtime_put_autosuspend(filter->device->dev);
-
-	dev_dbg(filter->device->dev, "%s: successful\n", __func__);
-
-	return 0;
-}
-EXPORT_SYMBOL(tspp2_filter_enable);
-
-/**
- * tspp2_filter_disable() - Disable a filter.
- *
- * @filter_handle:	Filter to disable.
- *
- * Return 0 on success, error value otherwise.
- */
-int tspp2_filter_disable(u32 filter_handle)
-{
-	struct tspp2_filter *filter = (struct tspp2_filter *)filter_handle;
-	u32 reg;
-	int ret;
-
-	if (!filter) {
-		pr_err("%s: Invalid filter handle\n", __func__);
-		return -EINVAL;
-	}
-
-	ret = pm_runtime_get_sync(filter->device->dev);
-	if (ret < 0)
-		return ret;
-
-	mutex_lock(&filter->device->mutex);
-
-	if (!filter->device->opened) {
-		pr_err("%s: Device must be opened first\n", __func__);
-		mutex_unlock(&filter->device->mutex);
-		pm_runtime_mark_last_busy(filter->device->dev);
-		pm_runtime_put_autosuspend(filter->device->dev);
-		return -EPERM;
-	}
-
-	if (!filter->opened) {
-		pr_err("%s: Filter not opened\n", __func__);
-		mutex_unlock(&filter->device->mutex);
-		pm_runtime_mark_last_busy(filter->device->dev);
-		pm_runtime_put_autosuspend(filter->device->dev);
-		return -EINVAL;
-	}
-
-	if (!filter->enabled) {
-		pr_warn("%s: Filter already disabled\n", __func__);
-		mutex_unlock(&filter->device->mutex);
-		pm_runtime_mark_last_busy(filter->device->dev);
-		pm_runtime_put_autosuspend(filter->device->dev);
-		return 0;
-	}
-
-	reg = readl_relaxed(filter->device->base +
-		TSPP2_FILTER_ENTRY0(filter->hw_index));
-	reg &= ~(0x1 << FILTER_ENTRY0_EN_OFFS);
-	writel_relaxed(reg, filter->device->base +
-		TSPP2_FILTER_ENTRY0(filter->hw_index));
-
-	/*
-	 * HW requires we wait for up to 2ms here before closing the pipes
-	 * used by this filter
-	 */
-	udelay(TSPP2_HW_DELAY_USEC);
-
-	filter->enabled = 0;
-
-	mutex_unlock(&filter->device->mutex);
-
-	pm_runtime_mark_last_busy(filter->device->dev);
-	pm_runtime_put_autosuspend(filter->device->dev);
-
-	dev_dbg(filter->device->dev, "%s: successful\n", __func__);
-
-	return 0;
-}
-EXPORT_SYMBOL(tspp2_filter_disable);
-
-/**
- * tspp2_pes_analysis_op_write() - Write a PES Analysis operation.
- *
- * @filter:	The filter to set the operation to.
- * @op:		The operation.
- * @op_index:	The operation's index in this filter.
- *
- * Return 0 on success, error value otherwise.
- */
-static int tspp2_pes_analysis_op_write(struct tspp2_filter *filter,
-				const struct tspp2_operation *op,
-				u8 op_index)
-{
-	u32 reg = 0;
-
-	if (filter->mask != TSPP2_UNIQUE_PID_MASK) {
-		pr_err(
-			"%s: A filter with a PES Analysis operation must handle a unique PID\n",
-			__func__);
-		return -EINVAL;
-	}
-
-	/*
-	 * Bits[19:6] = 0, Bit[5] = Source,
-	 * Bit[4] = Skip, Bits[3:0] = Opcode
-	 */
-	reg |= TSPP2_OPCODE_PES_ANALYSIS;
-	if (op->params.pes_analysis.skip_ts_errs)
-		reg |= (0x1 << 4);
-
-	if (op->params.pes_analysis.input == TSPP2_OP_BUFFER_B)
-		reg |= (0x1 << 5);
-
-	filter->pes_analysis_op_set = 1;
-
-	writel_relaxed(reg, filter->device->base +
-				TSPP2_OPCODE(filter->hw_index, op_index));
-
-	dev_dbg(filter->device->dev, "%s: successful\n", __func__);
-
-	return 0;
-}
-
-/**
- * tspp2_raw_tx_op_write() - Write a RAW Transmit operation.
- *
- * @filter:	The filter to set the operation to.
- * @op:		The operation.
- * @op_index:	The operation's index in this filter.
- *
- * Return 0 on success, error value otherwise.
- */
-static int tspp2_raw_tx_op_write(struct tspp2_filter *filter,
-				const struct tspp2_operation *op,
-				u8 op_index)
-{
-	u32 reg = 0;
-	int timestamp = 0;
-	struct tspp2_pipe *pipe = (struct tspp2_pipe *)
-			op->params.raw_transmit.output_pipe_handle;
-
-	if (!pipe || !pipe->opened) {
-		pr_err("%s: Invalid pipe handle\n", __func__);
-		return -EINVAL;
-	}
-
-	/*
-	 * Bits[19:16] = 0, Bit[15] = Support Indexing,
-	 * Bit[14] = Timestamp position,
-	 * Bits[13:12] = Timestamp mode,
-	 * Bits[11:6] = Output pipe, Bit[5] = Source,
-	 * Bit[4] = Skip, Bits[3:0] = Opcode
-	 */
-	reg |= TSPP2_OPCODE_RAW_TRANSMIT;
-	if (op->params.raw_transmit.skip_ts_errs)
-		reg |= (0x1 << 4);
-
-	if (op->params.raw_transmit.input == TSPP2_OP_BUFFER_B)
-		reg |= (0x1 << 5);
-
-	reg |= ((pipe->hw_index & 0x3F) << 6);
-
-	switch (op->params.raw_transmit.timestamp_mode) {
-	case TSPP2_OP_TIMESTAMP_NONE:
-		/* nothing to do, keep bits value as 0 */
-		break;
-	case TSPP2_OP_TIMESTAMP_ZERO:
-		reg |= (0x1 << 12);
-		timestamp = 1;
-		break;
-	case TSPP2_OP_TIMESTAMP_STC:
-		reg |= (0x2 << 12);
-		timestamp = 1;
-		break;
-	default:
-		pr_err("%s: Invalid timestamp mode\n", __func__);
-		return -EINVAL;
-	}
-
-	if (timestamp && op->params.raw_transmit.timestamp_position ==
-					TSPP2_PACKET_FORMAT_188_RAW) {
-		pr_err("%s: Invalid timestamp position\n", __func__);
-		return -EINVAL;
-	}
-
-	if (op->params.raw_transmit.timestamp_position ==
-				TSPP2_PACKET_FORMAT_192_TAIL)
-		reg |= (0x1 << 14);
-
-	if (op->params.raw_transmit.support_indexing) {
-		if (filter->raw_op_with_indexing) {
-			pr_err(
-				"%s: Only one Raw Transmit operation per filter can support HW indexing\n",
-				__func__);
-			return -EINVAL;
-		}
-		filter->raw_op_with_indexing = 1;
-		reg |= (0x1 << 15);
-	}
-
-	filter->raw_op_set = 1;
-
-	writel_relaxed(reg, filter->device->base +
-				TSPP2_OPCODE(filter->hw_index, op_index));
-
-	dev_dbg(filter->device->dev, "%s: successful\n", __func__);
-
-	return 0;
-}
-
-/**
- * tspp2_pes_tx_op_write() - Write a PES Transmit operation.
- *
- * @filter:	The filter to set the operation to.
- * @op:		The operation.
- * @op_index:	The operation's index in this filter.
- *
- * Return 0 on success, error value otherwise.
- */
-static int tspp2_pes_tx_op_write(struct tspp2_filter *filter,
-				const struct tspp2_operation *op,
-				u8 op_index)
-{
-	u32 reg = 0;
-	struct tspp2_pipe *payload_pipe = (struct tspp2_pipe *)
-		op->params.pes_transmit.output_pipe_handle;
-	struct tspp2_pipe *header_pipe;
-
-	if (!payload_pipe || !payload_pipe->opened) {
-		pr_err("%s: Invalid payload pipe handle\n", __func__);
-		return -EINVAL;
-	}
-
-	if (!filter->pes_analysis_op_set) {
-		pr_err(
-			"%s: PES Analysys operation must precede any PES Transmit operation\n",
-			__func__);
-		return -EINVAL;
-	}
-
-	/*
-	 * Bits[19:18] = 0, Bits[17:12] = PES Header output pipe,
-	 * Bits[11:6] = Output pipe, Bit[5] = Source,
-	 * Bit[4] = Attach STC and flags,
-	 * Bit[3] = Disable TX on PES discontinuity,
-	 * Bit[2] = Enable SW indexing, Bit[1] = Mode, Bit[0] = 0
-	 */
-
-	if (op->params.pes_transmit.mode == TSPP2_OP_PES_TRANSMIT_FULL) {
-		reg |= (0x1 << 1);
-	} else {
-		/* Separated PES mode requires another pipe */
-		header_pipe = (struct tspp2_pipe *)
-			op->params.pes_transmit.header_output_pipe_handle;
-
-		if (!header_pipe || !header_pipe->opened) {
-			pr_err("%s: Invalid header pipe handle\n", __func__);
-			return -EINVAL;
-		}
-
-		reg |= ((header_pipe->hw_index & 0x3F) << 12);
-	}
-
-	if (op->params.pes_transmit.enable_sw_indexing) {
-		if (!filter->raw_op_set) {
-			pr_err(
-				"%s: PES Transmit operation with SW indexing must be preceded by a Raw Transmit operation\n",
-				__func__);
-			return -EINVAL;
-		}
-		reg |= (0x1 << 2);
-	}
-
-	if (op->params.pes_transmit.disable_tx_on_pes_discontinuity)
-		reg |= (0x1 << 3);
-
-	if (op->params.pes_transmit.attach_stc_flags)
-		reg |= (0x1 << 4);
-
-	if (op->params.pes_transmit.input == TSPP2_OP_BUFFER_B)
-		reg |= (0x1 << 5);
-
-	reg |= ((payload_pipe->hw_index & 0x3F) << 6);
-
-	filter->pes_tx_op_set = 1;
-
-	writel_relaxed(reg, filter->device->base +
-				TSPP2_OPCODE(filter->hw_index, op_index));
-
-	dev_dbg(filter->device->dev, "%s: successful\n", __func__);
-
-	return 0;
-}
-
-/**
- * tspp2_pcr_op_write() - Write a PCR Extraction operation.
- *
- * @filter:	The filter to set the operation to.
- * @op:		The operation.
- * @op_index:	The operation's index in this filter.
- *
- * Return 0 on success, error value otherwise.
- */
-static int tspp2_pcr_op_write(struct tspp2_filter *filter,
-				const struct tspp2_operation *op,
-				u8 op_index)
-{
-	u32 reg = 0;
-	struct tspp2_pipe *pipe = (struct tspp2_pipe *)
-			op->params.pcr_extraction.output_pipe_handle;
-
-	if (!pipe || !pipe->opened) {
-		pr_err("%s: Invalid pipe handle\n", __func__);
-		return -EINVAL;
-	}
-
-	if (!op->params.pcr_extraction.extract_pcr &&
-		!op->params.pcr_extraction.extract_opcr &&
-		!op->params.pcr_extraction.extract_splicing_point &&
-		!op->params.pcr_extraction.extract_transport_private_data &&
-		!op->params.pcr_extraction.extract_af_extension &&
-		!op->params.pcr_extraction.extract_all_af) {
-		pr_err("%s: Invalid extraction parameters\n", __func__);
-		return -EINVAL;
-	}
-
-	/*
-	 * Bits[19:18] = 0, Bit[17] = All AF, Bit[16] = AF Extension,
-	 * Bit[15] = Transport Priave Data, Bit[14] = Splicing Point,
-	 * Bit[13] = OPCR, Bit[12] = PCR, Bits[11:6] = Output pipe,
-	 * Bit[5] = Source, Bit[4] = Skip, Bits[3:0] = Opcode
-	 */
-	reg |= TSPP2_OPCODE_PCR_EXTRACTION;
-	if (op->params.pcr_extraction.skip_ts_errs)
-		reg |= (0x1 << 4);
-
-	if (op->params.pcr_extraction.input == TSPP2_OP_BUFFER_B)
-		reg |= (0x1 << 5);
-
-	reg |= ((pipe->hw_index & 0x3F) << 6);
-
-	if (op->params.pcr_extraction.extract_pcr)
-		reg |= (0x1 << 12);
-
-	if (op->params.pcr_extraction.extract_opcr)
-		reg |= (0x1 << 13);
-
-	if (op->params.pcr_extraction.extract_splicing_point)
-		reg |= (0x1 << 14);
-
-	if (op->params.pcr_extraction.extract_transport_private_data)
-		reg |= (0x1 << 15);
-
-	if (op->params.pcr_extraction.extract_af_extension)
-		reg |= (0x1 << 16);
-
-	if (op->params.pcr_extraction.extract_all_af)
-		reg |= (0x1 << 17);
-
-	writel_relaxed(reg, filter->device->base +
-				TSPP2_OPCODE(filter->hw_index, op_index));
-
-	dev_dbg(filter->device->dev, "%s: successful\n", __func__);
-
-	return 0;
-}
-
-/**
- * tspp2_cipher_op_write() - Write a Cipher operation.
- *
- * @filter:	The filter to set the operation to.
- * @op:		The operation.
- * @op_index:	The operation's index in this filter.
- *
- * Return 0 on success, error value otherwise.
- */
-static int tspp2_cipher_op_write(struct tspp2_filter *filter,
-				const struct tspp2_operation *op,
-				u8 op_index)
-{
-	u32 reg = 0;
-
-	/*
-	 * Bits[19:18] = 0, Bits[17:15] = Scrambling related,
-	 * Bit[14] = Mode, Bit[13] = Decrypt PES header,
-	 * Bits[12:7] = Key ladder index, Bit[6] = Destination,
-	 * Bit[5] = Source, Bit[4] = Skip, Bits[3:0] = Opcode
-	 */
-
-	reg |= TSPP2_OPCODE_CIPHER;
-	if (op->params.cipher.skip_ts_errs)
-		reg |= (0x1 << 4);
-
-	if (op->params.cipher.input == TSPP2_OP_BUFFER_B)
-		reg |= (0x1 << 5);
-
-	if (op->params.cipher.output == TSPP2_OP_BUFFER_B)
-		reg |= (0x1 << 6);
-
-	reg |= ((op->params.cipher.key_ladder_index & 0x3F) << 7);
-
-	if (op->params.cipher.mode == TSPP2_OP_CIPHER_ENCRYPT &&
-		op->params.cipher.decrypt_pes_header) {
-		pr_err("%s: Invalid parameters\n", __func__);
-		return -EINVAL;
-	}
-
-	if (op->params.cipher.decrypt_pes_header)
-		reg |= (0x1 << 13);
-
-	if (op->params.cipher.mode == TSPP2_OP_CIPHER_ENCRYPT)
-		reg |= (0x1 << 14);
-
-	switch (op->params.cipher.scrambling_mode) {
-	case TSPP2_OP_CIPHER_AS_IS:
-		reg |= (0x1 << 15);
-		break;
-	case TSPP2_OP_CIPHER_SET_SCRAMBLING_0:
-		/* nothing to do, keep bits[17:16] as 0 */
-		break;
-	case TSPP2_OP_CIPHER_SET_SCRAMBLING_1:
-		reg |= (0x1 << 16);
-		break;
-	case TSPP2_OP_CIPHER_SET_SCRAMBLING_2:
-		reg |= (0x2 << 16);
-		break;
-	case TSPP2_OP_CIPHER_SET_SCRAMBLING_3:
-		reg |= (0x3 << 16);
-		break;
-	default:
-		pr_err("%s: Invalid scrambling mode\n", __func__);
-		return -EINVAL;
-	}
-
-	writel_relaxed(reg, filter->device->base +
-				TSPP2_OPCODE(filter->hw_index, op_index));
-
-	dev_dbg(filter->device->dev, "%s: successful\n", __func__);
-
-	return 0;
-}
-
-/**
- * tspp2_index_op_write() - Write an Indexing operation.
- *
- * @filter:	The filter to set the operation to.
- * @op:		The operation.
- * @op_index:	The operation's index in this filter.
- *
- * Return 0 on success, error value otherwise.
- */
-static int tspp2_index_op_write(struct tspp2_filter *filter,
-				const struct tspp2_operation *op,
-				u8 op_index)
-{
-	u32 reg = 0;
-	u32 filter_reg = 0;
-	struct tspp2_pipe *pipe = (struct tspp2_pipe *)
-			op->params.indexing.output_pipe_handle;
-
-	if (!pipe || !pipe->opened) {
-		pr_err("%s: Invalid pipe handle\n", __func__);
-		return -EINVAL;
-	}
-
-	/* Enforce Indexing related HW restrictions */
-	if (filter->indexing_op_set) {
-		pr_err(
-			"%s: Only one indexing operation supported per filter\n",
-			__func__);
-		return -EINVAL;
-	}
-	if (!filter->raw_op_with_indexing) {
-		pr_err(
-			"%s: Raw Transmit operation with indexing support must be configured before the Indexing operation\n",
-			__func__);
-		return -EINVAL;
-	}
-
-	if (!filter->pes_analysis_op_set) {
-		pr_err(
-			"%s: PES Analysis operation must precede Indexing operation\n",
-			__func__);
-		return -EINVAL;
-	}
-
-	/*
-	 * Bits [19:15] = 0, Bit[14] = Index by RAI,
-	 * Bits[13:12] = 0,
-	 * Bits[11:6] = Output pipe, Bit[5] = Source,
-	 * Bit[4] = Skip, Bits[3:0] = Opcode
-	 */
-
-	reg |= TSPP2_OPCODE_INDEXING;
-	if (op->params.indexing.skip_ts_errs)
-		reg |= (0x1 << 4);
-
-	if (op->params.indexing.input == TSPP2_OP_BUFFER_B)
-		reg |= (0x1 << 5);
-
-	reg |= ((pipe->hw_index & 0x3F) << 6);
-
-	if (op->params.indexing.random_access_indicator_indexing)
-		reg |= (0x1 << 14);
-
-	/* Indexing table ID is set in the filter and not in the operation */
-	filter->indexing_table_id = op->params.indexing.indexing_table_id;
-	filter_reg = readl_relaxed(filter->device->base +
-				TSPP2_FILTER_ENTRY0(filter->hw_index));
-	filter_reg &= ~(0x3 << FILTER_ENTRY0_CODEC_OFFS);
-	filter_reg |= (filter->indexing_table_id << FILTER_ENTRY0_CODEC_OFFS);
-	writel_relaxed(filter_reg, filter->device->base +
-			TSPP2_FILTER_ENTRY0(filter->hw_index));
-
-	filter->indexing_op_set = 1;
-
-	writel_relaxed(reg, filter->device->base +
-				TSPP2_OPCODE(filter->hw_index, op_index));
-
-	dev_dbg(filter->device->dev, "%s: successful\n", __func__);
-
-	return 0;
-}
-
-/**
- * tspp2_copy_op_write() - Write an Copy operation.
- *
- * @filter:	The filter to set the operation to.
- * @op:		The operation.
- * @op_index:	The operation's index in this filter.
- *
- * Return 0 on success, error value otherwise.
- */
-static int tspp2_copy_op_write(struct tspp2_filter *filter,
-				const struct tspp2_operation *op,
-				u8 op_index)
-{
-	u32 reg = 0;
-
-	/* Bits[19:6] = 0, Bit[5] = Source, Bit[4] = 0, Bits[3:0] = Opcode */
-	reg |= TSPP2_OPCODE_COPY_PACKET;
-	if (op->params.copy_packet.input == TSPP2_OP_BUFFER_B)
-		reg |= (0x1 << 5);
-
-	writel_relaxed(reg, filter->device->base +
-				TSPP2_OPCODE(filter->hw_index, op_index));
-
-	dev_dbg(filter->device->dev, "%s: successful\n", __func__);
-
-	return 0;
-}
-
-/**
- * tspp2_op_write() - Write an operation of any type.
- *
- * @filter:	The filter to set the operation to.
- * @op:		The operation.
- * @op_index:	The operation's index in this filter.
- *
- * Return 0 on success, error value otherwise.
- */
-static int tspp2_op_write(struct tspp2_filter *filter,
-				const struct tspp2_operation *op,
-				u8 op_index)
-{
-	switch (op->type) {
-	case TSPP2_OP_PES_ANALYSIS:
-		return tspp2_pes_analysis_op_write(filter, op, op_index);
-	case TSPP2_OP_RAW_TRANSMIT:
-		return tspp2_raw_tx_op_write(filter, op, op_index);
-	case TSPP2_OP_PES_TRANSMIT:
-		return tspp2_pes_tx_op_write(filter, op, op_index);
-	case TSPP2_OP_PCR_EXTRACTION:
-		return tspp2_pcr_op_write(filter, op, op_index);
-	case TSPP2_OP_CIPHER:
-		return tspp2_cipher_op_write(filter, op, op_index);
-	case TSPP2_OP_INDEXING:
-		return tspp2_index_op_write(filter, op, op_index);
-	case TSPP2_OP_COPY_PACKET:
-		return tspp2_copy_op_write(filter, op, op_index);
-	default:
-		pr_warn("%s: Unknown operation type\n", __func__);
-		return -EINVAL;
-	}
-}
-
-/**
- * tspp2_filter_ops_add() - Set the operations of a disabled filter.
- *
- * @filter:	The filter to work on.
- * @op:		The new operations array.
- * @op_index:	The number of operations in the array.
- *
- * Return 0 on success, error value otherwise.
- */
-static int tspp2_filter_ops_add(struct tspp2_filter *filter,
-				const struct tspp2_operation *ops,
-				u8 operations_num)
-{
-	int i;
-	int ret = 0;
-
-	/* User parameter validity checks were already performed */
-
-	/*
-	 * We want to start with a clean slate here. The user may call us to
-	 * set operations several times, so need to make sure only the last call
-	 * counts.
-	 */
-	tspp2_filter_ops_clear(filter);
-
-	/* Save user operations in filter's database */
-	for (i = 0; i < operations_num; i++)
-		filter->operations[i] = ops[i];
-
-	/* Write user operations to HW */
-	for (i = 0; i < operations_num; i++) {
-		ret = tspp2_op_write(filter, &ops[i], i);
-		if (ret)
-			goto ops_cleanup;
-	}
-
-	/*
-	 * Here we want to add the Exit operation implicitly if required, that
-	 * is, if the user provided less than TSPP2_MAX_OPS_PER_FILTER
-	 * operations. However, we already called tspp2_filter_ops_clear()
-	 * which set all the operations in HW to Exit, before writing the
-	 * actual user operations. So, no need to do it again here.
-	 * Also, if someone calls this function with operations_num == 0,
-	 * it is similar to calling tspp2_filter_operations_clear().
-	 */
-
-	filter->num_user_operations = operations_num;
-
-	dev_dbg(filter->device->dev, "%s: successful\n", __func__);
-
-	return 0;
-
-ops_cleanup:
-	pr_err("%s: Failed to set operations to filter, clearing all\n",
-		__func__);
-
-	tspp2_filter_ops_clear(filter);
-
-	return ret;
-}
-
-/**
- * tspp2_filter_ops_update() - Update the operations of an enabled filter.
- *
- * This function updates the operations of an enabled filter. In fact, it is
- * not possible to update an existing filter without disabling it, clearing
- * the existing operations and setting new ones. However, if we do that,
- * we'll miss TS packets and not handle the stream properly, so a smooth
- * transition is required.
- * The algorithm is as follows:
- * 1. Find a free temporary filter object.
- * 2. Set the new filter's HW index to the reserved HW index.
- * 3. Set the operations to the new filter. This sets the operations to
- * the correct HW registers, based on the new HW index, and also updates
- * the relevant information in the temporary filter object. Later we copy this
- * to the actual filter object.
- * 4. Use the same context as the old filter (to maintain HW state).
- * 5. Reset parts of the context if needed.
- * 6. Enable the new HW filter, then disable the old filter.
- * 7. Update the source's reserved filter HW index.
- * 8. Update the filter's batch, HW index and operations-related information.
- *
- * @filter:	The filter to work on.
- * @op:		The new operations array.
- * @op_index:	The number of operations in the array.
- *
- * Return 0 on success, error value otherwise.
- */
-static int tspp2_filter_ops_update(struct tspp2_filter *filter,
-				const struct tspp2_operation *ops,
-				u8 operations_num)
-{
-	int i;
-	int ret = 0;
-	int found = 0;
-	u32 reg = 0;
-	u16 hw_idx;
-	struct tspp2_filter_batch *batch;
-	struct tspp2_filter *tmp_filter = NULL;
-	struct tspp2_src *src = filter->src;
-
-	/*
-	 * Find an available temporary filter object in the device's
-	 * filters database.
-	 */
-	for (i = 0; i < TSPP2_NUM_AVAIL_FILTERS; i++)
-		if (!src->device->filters[i].opened)
-			break;
-	if (i == TSPP2_NUM_AVAIL_FILTERS) {
-		/* Should never happen */
-		pr_err("%s: No available filters\n", __func__);
-		return -ENOMEM;
-	}
-	tmp_filter = &src->device->filters[i];
-
-	/*
-	 * Set new filter operations. We do this relatively early
-	 * in the function to avoid cleanup operations if this fails.
-	 * Since this also writes to HW, we have to set the correct HW index.
-	 */
-	tmp_filter->hw_index = src->reserved_filter_hw_index;
-	/*
-	 * Need to set the mask properly to indicate if the filter handles
-	 * a unique PID.
-	 */
-	tmp_filter->mask = filter->mask;
-	ret = tspp2_filter_ops_add(tmp_filter, ops, operations_num);
-	if (ret) {
-		tmp_filter->hw_index = 0;
-		tmp_filter->mask = 0;
-		return ret;
-	}
-
-	/*
-	 * Mark new filter (in fact, the new filter HW index) as used in the
-	 * appropriate batch. The batch has to be one of the batches already
-	 * associated with the source.
-	 */
-	list_for_each_entry(batch, &src->batches_list, link) {
-		for (i = 0; i < TSPP2_FILTERS_PER_BATCH; i++) {
-			hw_idx = (batch->batch_id *
-					TSPP2_FILTERS_PER_BATCH) + i;
-			if (hw_idx == tmp_filter->hw_index) {
-				batch->hw_filters[i] = 1;
-				found = 1;
-				break;
-			}
-		}
-		if (found)
-			break;
-	}
-
-	if (!found) {
-		pr_err("%s: Could not find matching batch\n", __func__);
-		tspp2_filter_ops_clear(tmp_filter);
-		tmp_filter->hw_index = 0;
-		return -EINVAL;
-	}
-
-	/* Set the same context of the old filter to the new HW filter */
-	writel_relaxed((filter->context << FILTER_ENTRY1_CONTEXT_OFFS),
-		filter->device->base +
-		TSPP2_FILTER_ENTRY1(tmp_filter->hw_index));
-
-	/*
-	 * Reset partial context, if necessary. We want to reset a partial
-	 * context before we start using it, so if there's a new operation
-	 * that uses a context where before there was no operation that used it,
-	 * we reset that context. We need to do this before we start using the
-	 * new operation, so before we enable the new filter.
-	 * Note: there is no need to reset most of the filter's context-based
-	 * counters, because the filter keeps using the same context. The
-	 * exception is the PES error counters that we may want to reset when
-	 * resetting the entire PES context.
-	 */
-	if (!filter->pes_tx_op_set && tmp_filter->pes_tx_op_set) {
-		/* PES Tx operation added */
-		writel_relaxed(
-			(0x1 << TSPP2_MODULUS_OP(filter->context, 32)),
-			filter->device->base +
-			TSPP2_PES_CONTEXT_RESET(filter->context >> 5));
-		writel_relaxed(0, filter->device->base +
-			TSPP2_FILTER_PES_ERRORS(filter->context));
-	}
-
-	if (!filter->indexing_op_set && tmp_filter->indexing_op_set) {
-		/* Indexing operation added */
-		writel_relaxed(
-			(0x1 << TSPP2_MODULUS_OP(filter->context, 32)),
-			filter->device->base +
-			TSPP2_INDEXING_CONTEXT_RESET(filter->context >> 5));
-	}
-
-	/*
-	 * Write PID and mask to new filter HW registers and enable it.
-	 * Preserve filter indexing table ID.
-	 */
-	reg |= (0x1 << FILTER_ENTRY0_EN_OFFS);
-	reg |= ((filter->pid_value << FILTER_ENTRY0_PID_OFFS) |
-		(filter->mask << FILTER_ENTRY0_MASK_OFFS));
-	reg |= (tmp_filter->indexing_table_id << FILTER_ENTRY0_CODEC_OFFS);
-	writel_relaxed(reg, filter->device->base +
-		TSPP2_FILTER_ENTRY0(tmp_filter->hw_index));
-
-	/* Disable old HW filter */
-	writel_relaxed(0, filter->device->base +
-		TSPP2_FILTER_ENTRY0(filter->hw_index));
-
-	/*
-	 * HW requires we wait for up to 2ms here before removing the
-	 * operations used by this filter.
-	 */
-	udelay(TSPP2_HW_DELAY_USEC);
-
-	tspp2_filter_ops_clear(filter);
-
-	writel_relaxed(0, filter->device->base +
-		TSPP2_FILTER_ENTRY1(filter->hw_index));
-
-	/* Mark HW filter as unused in old batch */
-	filter->batch->hw_filters[(filter->hw_index -
-		(filter->batch->batch_id * TSPP2_FILTERS_PER_BATCH))] = 0;
-
-	/* The new HW filter may be in a new batch, so we need to update */
-	filter->batch = batch;
-
-	/*
-	 * Update source's reserved filter HW index, and also update the
-	 * new HW index in the filter object.
-	 */
-	src->reserved_filter_hw_index = filter->hw_index;
-	filter->hw_index = tmp_filter->hw_index;
-
-	/*
-	 * We've already set the new operations to HW, but we want to
-	 * update the filter object, too. tmp_filter contains all the
-	 * operations' related information we need (operations and flags).
-	 * Also, we make sure to update indexing_table_id based on the new
-	 * indexing operations.
-	 */
-	memcpy(filter->operations, tmp_filter->operations,
-		(sizeof(struct tspp2_operation) * TSPP2_MAX_OPS_PER_FILTER));
-	filter->num_user_operations = tmp_filter->num_user_operations;
-	filter->indexing_op_set = tmp_filter->indexing_op_set;
-	filter->raw_op_with_indexing = tmp_filter->raw_op_with_indexing;
-	filter->pes_analysis_op_set = tmp_filter->pes_analysis_op_set;
-	filter->raw_op_set = tmp_filter->raw_op_set;
-	filter->pes_tx_op_set = tmp_filter->pes_tx_op_set;
-	filter->indexing_table_id = tmp_filter->indexing_table_id;
-
-	/*
-	 * Now we can clean tmp_filter. This is really just to keep the filter
-	 * object clean. However, we don't want to use tspp2_filter_ops_clear()
-	 * because it clears the operations from HW too.
-	 */
-	memset(tmp_filter->operations, 0,
-		(sizeof(struct tspp2_operation) * TSPP2_MAX_OPS_PER_FILTER));
-	tmp_filter->num_user_operations = 0;
-	tmp_filter->indexing_op_set = 0;
-	tmp_filter->raw_op_with_indexing = 0;
-	tmp_filter->pes_analysis_op_set = 0;
-	tmp_filter->raw_op_set = 0;
-	tmp_filter->pes_tx_op_set = 0;
-	tmp_filter->indexing_table_id = 0;
-	tmp_filter->hw_index = 0;
-
-	dev_dbg(filter->device->dev, "%s: successful\n", __func__);
-
-	return 0;
-}
-
-/**
- * tspp2_filter_operations_set() - Set operations to a filter.
- *
- * @filter_handle:	Filter to set operations to.
- * @ops:		An array of up to TSPP2_MAX_OPS_PER_FILTER
- *			operations.
- * @operations_num:	Number of operations in the ops array.
- *
- * This function sets the required operations to a given filter. The filter
- * can either be disabled (in which case it may or may not already have some
- * operations set), or enabled (in which case it certainly has some oprations
- * set). In any case, the filter's previous operations are cleared, and the new
- * operations provided are set.
- *
- * In addition to some trivial parameter validity checks, the following
- * restrictions are enforced:
- * 1. A filter with a PES Analysis operation must handle a unique PID (i.e.,
- *    should have a mask that equals TSPP2_UNIQUE_PID_MASK).
- * 2. Only a single Raw Transmit operation per filter can support HW indexing
- *    (i.e., can have its support_indexing configuration parameter set).
- * 3. A PES Analysys operation must precede any PES Transmit operation.
- * 4. A PES Transmit operation with SW indexing (i.e., with its
- *    enable_sw_indexing parameter set) must be preceded by a Raw Transmit
- *    operation.
- * 5. Only a single indexing operation is supported per filter.
- * 6. A Raw Transmit operation with indexing support must be configured before
- *    the Indexing operation.
- * 7. A PES Analysis operation must precede the Indexing operation.
- *
- * Return 0 on success, error value otherwise.
- */
-int tspp2_filter_operations_set(u32 filter_handle,
-			const struct tspp2_operation *ops,
-			u8 operations_num)
-{
-	struct tspp2_filter *filter = (struct tspp2_filter *)filter_handle;
-	int ret = 0;
-
-	if (!filter) {
-		pr_err("%s: Invalid filter handle\n", __func__);
-		return -EINVAL;
-	}
-	if (!ops || operations_num > TSPP2_MAX_OPS_PER_FILTER ||
-			operations_num == 0) {
-		pr_err("%s: Invalid ops parameter\n", __func__);
-		return -EINVAL;
-	}
-
-	ret = pm_runtime_get_sync(filter->device->dev);
-	if (ret < 0)
-		return ret;
-
-	if (mutex_lock_interruptible(&filter->device->mutex)) {
-		pm_runtime_mark_last_busy(filter->device->dev);
-		pm_runtime_put_autosuspend(filter->device->dev);
-		return -ERESTARTSYS;
-	}
-
-	if (!filter->device->opened) {
-		pr_err("%s: Device must be opened first\n", __func__);
-		mutex_unlock(&filter->device->mutex);
-		pm_runtime_mark_last_busy(filter->device->dev);
-		pm_runtime_put_autosuspend(filter->device->dev);
-		return -EPERM;
-	}
-
-	if (!filter->opened) {
-		pr_err("%s: Filter not opened\n", __func__);
-		mutex_unlock(&filter->device->mutex);
-		pm_runtime_mark_last_busy(filter->device->dev);
-		pm_runtime_put_autosuspend(filter->device->dev);
-		return -EINVAL;
-	}
-
-	if (filter->enabled)
-		ret = tspp2_filter_ops_update(filter, ops, operations_num);
-	else
-		ret = tspp2_filter_ops_add(filter, ops, operations_num);
-
-	mutex_unlock(&filter->device->mutex);
-
-	pm_runtime_mark_last_busy(filter->device->dev);
-	pm_runtime_put_autosuspend(filter->device->dev);
-
-	return ret;
-}
-EXPORT_SYMBOL(tspp2_filter_operations_set);
-
-/**
- * tspp2_filter_operations_clear() - Clear all operations from a filter.
- *
- * @filter_handle:	Filter to clear all operations from.
- *
- * Return 0 on success, error value otherwise.
- */
-int tspp2_filter_operations_clear(u32 filter_handle)
-{
-	int ret;
-	struct tspp2_filter *filter = (struct tspp2_filter *)filter_handle;
-
-	if (!filter) {
-		pr_err("%s: Invalid filter handle\n", __func__);
-		return -EINVAL;
-	}
-
-	ret = pm_runtime_get_sync(filter->device->dev);
-	if (ret < 0)
-		return ret;
-
-	mutex_lock(&filter->device->mutex);
-
-	if (!filter->device->opened) {
-		pr_err("%s: Device must be opened first\n", __func__);
-		mutex_unlock(&filter->device->mutex);
-		pm_runtime_mark_last_busy(filter->device->dev);
-		pm_runtime_put_autosuspend(filter->device->dev);
-		return -EPERM;
-	}
-
-	if (!filter->opened) {
-		pr_err("%s: Filter not opened\n", __func__);
-		mutex_unlock(&filter->device->mutex);
-		pm_runtime_mark_last_busy(filter->device->dev);
-		pm_runtime_put_autosuspend(filter->device->dev);
-		return -EINVAL;
-	}
-
-	if (filter->num_user_operations == 0) {
-		pr_warn("%s: No operations to clear from filter\n", __func__);
-		mutex_unlock(&filter->device->mutex);
-		pm_runtime_mark_last_busy(filter->device->dev);
-		pm_runtime_put_autosuspend(filter->device->dev);
-		return 0;
-	}
-
-	tspp2_filter_ops_clear(filter);
-
-	mutex_unlock(&filter->device->mutex);
-
-	pm_runtime_mark_last_busy(filter->device->dev);
-	pm_runtime_put_autosuspend(filter->device->dev);
-
-	dev_dbg(filter->device->dev, "%s: successful\n", __func__);
-
-	return 0;
-}
-EXPORT_SYMBOL(tspp2_filter_operations_clear);
-
-/**
- * tspp2_filter_current_scrambling_bits_get() - Get the current scrambling bits.
- *
- * @filter_handle:		Filter to get the scrambling bits from.
- * @scrambling_bits_value:	The current value of the scrambling bits.
- *				This could be the value from the TS packet
- *				header, the value from the PES header, or a
- *				logical OR operation of both values, depending
- *				on the scrambling_bits_monitoring configuration
- *				of the source this filter belongs to.
- *
- * Return 0 on success, error value otherwise.
- */
-int tspp2_filter_current_scrambling_bits_get(u32 filter_handle,
-			u8 *scrambling_bits_value)
-{
-	struct tspp2_filter *filter = (struct tspp2_filter *)filter_handle;
-	u32 reg;
-	u32 ts_bits;
-	u32 pes_bits;
-	int ret;
-
-	if (!filter) {
-		pr_err("%s: Invalid filter handle\n", __func__);
-		return -EINVAL;
-	}
-	if (scrambling_bits_value == NULL) {
-		pr_err("%s: Invalid parameter\n", __func__);
-		return -EINVAL;
-	}
-
-	ret = pm_runtime_get_sync(filter->device->dev);
-	if (ret < 0)
-		return ret;
-
-	if (mutex_lock_interruptible(&filter->device->mutex)) {
-		pm_runtime_mark_last_busy(filter->device->dev);
-		pm_runtime_put_autosuspend(filter->device->dev);
-		return -ERESTARTSYS;
-	}
-
-	if (!filter->device->opened) {
-		pr_err("%s: Device must be opened first\n", __func__);
-		mutex_unlock(&filter->device->mutex);
-		pm_runtime_mark_last_busy(filter->device->dev);
-		pm_runtime_put_autosuspend(filter->device->dev);
-		return -EPERM;
-	}
-
-	if (!filter->opened) {
-		pr_err("%s: Filter not opened\n", __func__);
-		mutex_unlock(&filter->device->mutex);
-		pm_runtime_mark_last_busy(filter->device->dev);
-		pm_runtime_put_autosuspend(filter->device->dev);
-		return -EINVAL;
-	}
-
-	reg = readl_relaxed(filter->device->base +
-			TSPP2_TSP_CONTEXT(filter->context));
-
-	ts_bits = ((reg >> TSP_CONTEXT_TS_HEADER_SC_OFFS) & 0x3);
-	pes_bits = ((reg >> TSP_CONTEXT_PES_HEADER_SC_OFFS) & 0x3);
-
-	switch (filter->src->scrambling_bits_monitoring) {
-	case TSPP2_SRC_SCRAMBLING_MONITOR_PES_ONLY:
-		*scrambling_bits_value = pes_bits;
-		break;
-	case TSPP2_SRC_SCRAMBLING_MONITOR_TS_ONLY:
-		*scrambling_bits_value = ts_bits;
-		break;
-	case TSPP2_SRC_SCRAMBLING_MONITOR_PES_AND_TS:
-		*scrambling_bits_value = (pes_bits | ts_bits);
-		break;
-	case TSPP2_SRC_SCRAMBLING_MONITOR_NONE:
-		/* fall through to default case */
-	default:
-		pr_err("%s: Invalid scrambling bits mode\n", __func__);
-		mutex_unlock(&filter->device->mutex);
-		pm_runtime_mark_last_busy(filter->device->dev);
-		pm_runtime_put_autosuspend(filter->device->dev);
-		return -EINVAL;
-	}
-
-	mutex_unlock(&filter->device->mutex);
-
-	pm_runtime_mark_last_busy(filter->device->dev);
-	pm_runtime_put_autosuspend(filter->device->dev);
-
-	dev_dbg(filter->device->dev, "%s: successful\n", __func__);
-
-	return 0;
-}
-EXPORT_SYMBOL(tspp2_filter_current_scrambling_bits_get);
-
-/* Data-path API functions */
-
-/**
- * tspp2_pipe_descriptor_get() - Get a data descriptor from a pipe.
- *
- * @pipe_handle:	Pipe to get the descriptor from.
- * @desc:		Received pipe data descriptor.
- *
- * Return 0 on success, error value otherwise.
- */
-int tspp2_pipe_descriptor_get(u32 pipe_handle, struct sps_iovec *desc)
-{
-	int ret;
-	struct tspp2_pipe *pipe = (struct tspp2_pipe *)pipe_handle;
-
-	if (!pipe) {
-		pr_err("%s: Invalid pipe handle\n", __func__);
-		return -EINVAL;
-	}
-	if (!desc) {
-		pr_err("%s: Invalid descriptor pointer\n", __func__);
-		return -EINVAL;
-	}
-
-	/* Descriptor pointer validity is checked inside the SPS driver. */
-
-	ret = pm_runtime_get_sync(pipe->device->dev);
-	if (ret < 0)
-		return ret;
-
-	if (mutex_lock_interruptible(&pipe->device->mutex)) {
-		pm_runtime_mark_last_busy(pipe->device->dev);
-		pm_runtime_put_autosuspend(pipe->device->dev);
-		return -ERESTARTSYS;
-	}
-
-	if (!pipe->device->opened) {
-		pr_err("%s: Device must be opened first\n", __func__);
-		mutex_unlock(&pipe->device->mutex);
-		pm_runtime_mark_last_busy(pipe->device->dev);
-		pm_runtime_put_autosuspend(pipe->device->dev);
-		return -EPERM;
-	}
-
-	if (!pipe->opened) {
-		pr_err("%s: Pipe not opened\n", __func__);
-		mutex_unlock(&pipe->device->mutex);
-		pm_runtime_mark_last_busy(pipe->device->dev);
-		pm_runtime_put_autosuspend(pipe->device->dev);
-		return -EINVAL;
-	}
-
-	ret = sps_get_iovec(pipe->sps_pipe, desc);
-
-	mutex_unlock(&pipe->device->mutex);
-
-	pm_runtime_mark_last_busy(pipe->device->dev);
-	pm_runtime_put_autosuspend(pipe->device->dev);
-
-	dev_dbg(pipe->device->dev, "%s: successful\n", __func__);
-
-	return ret;
-
-}
-EXPORT_SYMBOL(tspp2_pipe_descriptor_get);
-
-/**
- * tspp2_pipe_descriptor_put() - Release a descriptor for reuse by the pipe.
- *
- * @pipe_handle:	Pipe to release the descriptor to.
- * @addr:		Address to release for reuse.
- * @size:		Size to release.
- * @flags:		Descriptor flags.
- *
- * Return 0 on success, error value otherwise.
- */
-int tspp2_pipe_descriptor_put(u32 pipe_handle, u32 addr, u32 size, u32 flags)
-{
-	int ret;
-	struct tspp2_pipe *pipe = (struct tspp2_pipe *)pipe_handle;
-
-	if (!pipe) {
-		pr_err("%s: Invalid pipe handle\n", __func__);
-		return -EINVAL;
-	}
-
-	ret = pm_runtime_get_sync(pipe->device->dev);
-	if (ret < 0)
-		return ret;
-
-	if (mutex_lock_interruptible(&pipe->device->mutex)) {
-		pm_runtime_mark_last_busy(pipe->device->dev);
-		pm_runtime_put_autosuspend(pipe->device->dev);
-		return -ERESTARTSYS;
-	}
-
-	if (!pipe->device->opened) {
-		pr_err("%s: Device must be opened first\n", __func__);
-		mutex_unlock(&pipe->device->mutex);
-		pm_runtime_mark_last_busy(pipe->device->dev);
-		pm_runtime_put_autosuspend(pipe->device->dev);
-		return -EPERM;
-	}
-
-	if (!pipe->opened) {
-		pr_err("%s: Pipe not opened\n", __func__);
-		mutex_unlock(&pipe->device->mutex);
-		pm_runtime_mark_last_busy(pipe->device->dev);
-		pm_runtime_put_autosuspend(pipe->device->dev);
-		return -EINVAL;
-	}
-
-	ret = sps_transfer_one(pipe->sps_pipe, addr, size, NULL, flags);
-
-	mutex_unlock(&pipe->device->mutex);
-
-	pm_runtime_mark_last_busy(pipe->device->dev);
-	pm_runtime_put_autosuspend(pipe->device->dev);
-
-	dev_dbg(pipe->device->dev, "%s: successful\n", __func__);
-
-	return ret;
-}
-EXPORT_SYMBOL(tspp2_pipe_descriptor_put);
-
-/**
- * tspp2_pipe_last_address_used_get() - Get the last address the TSPP2 used.
- *
- * @pipe_handle:	Pipe to get the address from.
- * @address:		The last (virtual) address TSPP2 wrote data to.
- *
- * Return 0 on success, error value otherwise.
- */
-int tspp2_pipe_last_address_used_get(u32 pipe_handle, u32 *address)
-{
-	int ret;
-	struct tspp2_pipe *pipe = (struct tspp2_pipe *)pipe_handle;
-
-	if (!pipe) {
-		pr_err("%s: Invalid pipe handle\n", __func__);
-		return -EINVAL;
-	}
-	if (!address) {
-		pr_err("%s: Invalid address pointer\n", __func__);
-		return -EINVAL;
-	}
-
-	ret = pm_runtime_get_sync(pipe->device->dev);
-	if (ret < 0)
-		return ret;
-
-	if (mutex_lock_interruptible(&pipe->device->mutex)) {
-		pm_runtime_mark_last_busy(pipe->device->dev);
-		pm_runtime_put_autosuspend(pipe->device->dev);
-		return -ERESTARTSYS;
-	}
-
-	if (!pipe->device->opened) {
-		pr_err("%s: Device must be opened first\n", __func__);
-		mutex_unlock(&pipe->device->mutex);
-		pm_runtime_mark_last_busy(pipe->device->dev);
-		pm_runtime_put_autosuspend(pipe->device->dev);
-		return -EPERM;
-	}
-
-	if (!pipe->opened) {
-		pr_err("%s: Pipe not opened\n", __func__);
-		mutex_unlock(&pipe->device->mutex);
-		pm_runtime_mark_last_busy(pipe->device->dev);
-		pm_runtime_put_autosuspend(pipe->device->dev);
-		return -EINVAL;
-	}
-
-	*address = readl_relaxed(pipe->device->base +
-		TSPP2_PIPE_LAST_ADDRESS(pipe->hw_index));
-
-	mutex_unlock(&pipe->device->mutex);
-
-	pm_runtime_mark_last_busy(pipe->device->dev);
-	pm_runtime_put_autosuspend(pipe->device->dev);
-
-	*address = be32_to_cpu(*address);
-
-	dev_dbg(pipe->device->dev, "%s: successful\n", __func__);
-
-	return 0;
-}
-EXPORT_SYMBOL(tspp2_pipe_last_address_used_get);
-
-/**
- * tspp2_data_write() - Write (feed) data to a source.
- *
- * @src_handle:	Source to feed data to.
- * @offset:	Offset in the source's input pipe buffer.
- * @size:	Size of data to write, in bytes.
- *
- * Schedule BAM transfers to feed data from the source's input pipe
- * to TSPP2 for processing. Note that the user is responsible for opening
- * an input pipe with the appropriate configuration parameters, and attaching
- * this pipe as an input pipe to the source. Pipe configuration validity is not
- * verified by this function.
- *
- * Return 0 on success, error value otherwise.
- */
-int tspp2_data_write(u32 src_handle, u32 offset, u32 size)
-{
-	int ret;
-	u32 desc_length;
-	u32 desc_flags;
-	u32 data_length = size;
-	u32 data_offset = offset;
-	struct tspp2_pipe *pipe;
-	struct tspp2_src *src = (struct tspp2_src *)src_handle;
-
-	if (!src) {
-		pr_err("%s: Invalid source handle\n", __func__);
-		return -EINVAL;
-	}
-
-	ret = pm_runtime_get_sync(src->device->dev);
-	if (ret < 0)
-		return ret;
-
-	if (mutex_lock_interruptible(&src->device->mutex)) {
-		pm_runtime_mark_last_busy(src->device->dev);
-		pm_runtime_put_autosuspend(src->device->dev);
-		return -ERESTARTSYS;
-	}
-
-	if (!src->device->opened) {
-		pr_err("%s: Device must be opened first\n", __func__);
-		mutex_unlock(&src->device->mutex);
-		pm_runtime_mark_last_busy(src->device->dev);
-		pm_runtime_put_autosuspend(src->device->dev);
-		return -EPERM;
-	}
-
-	if (!src->opened) {
-		pr_err("%s: Source not opened\n", __func__);
-		goto err_inval;
-	}
-
-	if (!src->enabled) {
-		pr_err("%s: Source not enabled\n", __func__);
-		goto err_inval;
-	}
-
-	if ((src->input != TSPP2_INPUT_MEMORY) || !src->input_pipe) {
-		pr_err("%s: Invalid source input or no input pipe\n", __func__);
-		goto err_inval;
-	}
-
-	pipe = src->input_pipe;
-
-	if (offset + size > pipe->cfg.buffer_size) {
-		pr_err("%s: offset + size > buffer size\n", __func__);
-		goto err_inval;
-	}
-
-	while (data_length) {
-		if (data_length > pipe->cfg.sps_cfg.descriptor_size) {
-			desc_length = pipe->cfg.sps_cfg.descriptor_size;
-			desc_flags = 0;
-		} else {
-			/* last descriptor */
-			desc_length = data_length;
-			desc_flags = SPS_IOVEC_FLAG_EOT;
-		}
-
-		ret = sps_transfer_one(pipe->sps_pipe,
-				pipe->iova + data_offset,
-				desc_length,
-				pipe->cfg.sps_cfg.user_info,
-				desc_flags);
-
-		if (ret) {
-			pr_err("%s: sps_transfer_one failed, %d\n",
-				__func__, ret);
-			mutex_unlock(&src->device->mutex);
-			pm_runtime_mark_last_busy(src->device->dev);
-			pm_runtime_put_autosuspend(src->device->dev);
-			return ret;
-		}
-
-		data_offset += desc_length;
-		data_length -= desc_length;
-	}
-
-	mutex_unlock(&src->device->mutex);
-
-	pm_runtime_mark_last_busy(src->device->dev);
-	pm_runtime_put_autosuspend(src->device->dev);
-
-	dev_dbg(src->device->dev, "%s: successful\n", __func__);
-
-	return 0;
-
-err_inval:
-	mutex_unlock(&src->device->mutex);
-	pm_runtime_mark_last_busy(src->device->dev);
-	pm_runtime_put_autosuspend(src->device->dev);
-
-	return -EINVAL;
-}
-EXPORT_SYMBOL(tspp2_data_write);
-
-/**
- * tspp2_tsif_data_write() - Write (feed) data to a TSIF source via Loopback.
- *
- * @src_handle:	Source to feed data to.
- * @data:	data buffer containing one TS packet of size 188 Bytes.
- *
- * Write one TS packet of size 188 bytes to the TSIF loopback interface.
- *
- * Return 0 on success, error value otherwise.
- */
-int tspp2_tsif_data_write(u32 src_handle, u32 *data)
-{
-	int i;
-	int ret;
-	struct tspp2_src *src = (struct tspp2_src *)src_handle;
-	struct tspp2_tsif_device *tsif_device;
-	const unsigned int loopback_flags[3] = {0x01000000, 0, 0x02000000};
-
-	if (data == NULL) {
-		pr_err("%s: NULL data\n", __func__);
-		return -EINVAL;
-	}
-
-	if (!src) {
-		pr_err("%s: Invalid source handle\n", __func__);
-		return -EINVAL;
-	}
-
-	ret = pm_runtime_get_sync(src->device->dev);
-	if (ret < 0)
-		return ret;
-
-	if (mutex_lock_interruptible(&src->device->mutex)) {
-		pm_runtime_mark_last_busy(src->device->dev);
-		pm_runtime_put_autosuspend(src->device->dev);
-		return -ERESTARTSYS;
-	}
-
-	if (!src->device->opened) {
-		pr_err("%s: Device must be opened first\n", __func__);
-		mutex_unlock(&src->device->mutex);
-		pm_runtime_mark_last_busy(src->device->dev);
-		pm_runtime_put_autosuspend(src->device->dev);
-		return -EPERM;
-	}
-
-	if (!src->opened) {
-		pr_err("%s: Source not opened\n", __func__);
-		goto err_inval;
-	}
-
-	if (!src->enabled) {
-		pr_err("%s: Source not enabled\n", __func__);
-		goto err_inval;
-	}
-
-	if ((src->input != TSPP2_INPUT_TSIF0)
-		&& (src->input != TSPP2_INPUT_TSIF1)) {
-		pr_err("%s: Invalid source input\n", __func__);
-		goto err_inval;
-	}
-
-	tsif_device = &src->device->tsif_devices[src->input];
-
-	/* lpbk_flags : start && !last */
-	writel_relaxed(loopback_flags[0],
-		tsif_device->base + TSPP2_TSIF_LPBK_FLAGS);
-
-	/* 1-st dword of data */
-	writel_relaxed(data[0],
-		tsif_device->base + TSPP2_TSIF_LPBK_DATA);
-
-	/* Clear start bit */
-	writel_relaxed(loopback_flags[1],
-		tsif_device->base + TSPP2_TSIF_LPBK_FLAGS);
-
-	/* 45 more dwords */
-	for (i = 1; i < 46; i++)
-		writel_relaxed(data[i],
-			tsif_device->base + TSPP2_TSIF_LPBK_DATA);
-
-	/* Set last bit */
-	writel_relaxed(loopback_flags[2],
-		tsif_device->base + TSPP2_TSIF_LPBK_FLAGS);
-
-	/* Last data dword */
-	writel_relaxed(data[46], tsif_device->base + TSPP2_TSIF_LPBK_DATA);
-
-	mutex_unlock(&src->device->mutex);
-
-	pm_runtime_mark_last_busy(src->device->dev);
-	pm_runtime_put_autosuspend(src->device->dev);
-
-	dev_dbg(src->device->dev, "%s: successful\n", __func__);
-
-	return 0;
-
-err_inval:
-	mutex_unlock(&src->device->mutex);
-	pm_runtime_mark_last_busy(src->device->dev);
-	pm_runtime_put_autosuspend(src->device->dev);
-
-	return -EINVAL;
-}
-EXPORT_SYMBOL(tspp2_tsif_data_write);
-
-/* Event notification API functions */
-
-/**
- * tspp2_global_event_notification_register() - Get notified on a global event.
- *
- * @dev_id:			TSPP2 device ID.
- * @global_event_bitmask:	A bitmask of global events,
- *				TSPP2_GLOBAL_EVENT_XXX.
- * @callback:			User callback function.
- * @cookie:			User information passed to the callback.
- *
- * Register a user callback which will be invoked when certain global
- * events occur. Note the values (mask, callback and cookie) are overwritten
- * when calling this function multiple times. Therefore it is possible to
- * "unregister" a callback by calling this function with the bitmask set to 0
- * and with NULL callback and cookie.
- *
- * Return 0 on success, error value otherwise.
- */
-int tspp2_global_event_notification_register(u32 dev_id,
-			u32 global_event_bitmask,
-			void (*callback)(void *cookie, u32 event_bitmask),
-			void *cookie)
-{
-	struct tspp2_device *device;
-	unsigned long flags;
-	u32 reg = 0;
-
-	if (dev_id >= TSPP2_NUM_DEVICES) {
-		pr_err("%s: Invalid device ID %d\n", __func__, dev_id);
-		return -ENODEV;
-	}
-
-	device = tspp2_devices[dev_id];
-	if (!device) {
-		pr_err("%s: Invalid device\n", __func__);
-		return -ENODEV;
-	}
-
-	if (mutex_lock_interruptible(&device->mutex))
-		return -ERESTARTSYS;
-
-	if (!device->opened) {
-		pr_err("%s: Device must be opened first\n", __func__);
-		mutex_unlock(&device->mutex);
-		return -EPERM;
-	}
-
-	/*
-	 * Some of the interrupts that are generated when these events occur
-	 * may be disabled due to module parameters. So we make sure to enable
-	 * them here, depending on which event was requested. If some events
-	 * were requested before and now this function is called again with
-	 * other events, though, we want to restore the interrupt configuration
-	 * to the default state according to the module parameters.
-	 */
-	reg = readl_relaxed(device->base + TSPP2_GLOBAL_IRQ_ENABLE);
-	if (global_event_bitmask & TSPP2_GLOBAL_EVENT_INVALID_AF_CTRL) {
-		reg |= (0x1 << GLOBAL_IRQ_TSP_INVALID_AF_OFFS);
-	} else {
-		if (tspp2_en_invalid_af_ctrl)
-			reg |= (0x1 << GLOBAL_IRQ_TSP_INVALID_AF_OFFS);
-		else
-			reg &= ~(0x1 << GLOBAL_IRQ_TSP_INVALID_AF_OFFS);
-	}
-
-	if (global_event_bitmask & TSPP2_GLOBAL_EVENT_INVALID_AF_LENGTH) {
-		reg |= (0x1 << GLOBAL_IRQ_TSP_INVALID_LEN_OFFS);
-	} else {
-		if (tspp2_en_invalid_af_length)
-			reg |= (0x1 << GLOBAL_IRQ_TSP_INVALID_LEN_OFFS);
-		else
-			reg &= ~(0x1 << GLOBAL_IRQ_TSP_INVALID_LEN_OFFS);
-	}
-
-	if (global_event_bitmask & TSPP2_GLOBAL_EVENT_PES_NO_SYNC) {
-		reg |= (0x1 << GLOBAL_IRQ_PES_NO_SYNC_OFFS);
-	} else {
-		if (tspp2_en_pes_no_sync)
-			reg |= (0x1 << GLOBAL_IRQ_PES_NO_SYNC_OFFS);
-		else
-			reg &= ~(0x1 << GLOBAL_IRQ_PES_NO_SYNC_OFFS);
-	}
-
-	writel_relaxed(reg, device->base + TSPP2_GLOBAL_IRQ_ENABLE);
-
-	spin_lock_irqsave(&device->spinlock, flags);
-	device->event_callback = callback;
-	device->event_cookie = cookie;
-	device->event_bitmask = global_event_bitmask;
-	spin_unlock_irqrestore(&device->spinlock, flags);
-
-	mutex_unlock(&device->mutex);
-
-	dev_dbg(device->dev, "%s: successful\n", __func__);
-
-	return 0;
-}
-EXPORT_SYMBOL(tspp2_global_event_notification_register);
-
-/**
- * tspp2_src_event_notification_register() - Get notified on a source event.
- *
- * @src_handle:		Source handle.
- * @src_event_bitmask:	A bitmask of source events,
- *			TSPP2_SRC_EVENT_XXX.
- * @callback:		User callback function.
- * @cookie:		User information passed to the callback.
- *
- * Register a user callback which will be invoked when certain source
- * events occur. Note the values (mask, callback and cookie) are overwritten
- * when calling this function multiple times. Therefore it is possible to
- * "unregister" a callback by calling this function with the bitmask set to 0
- * and with NULL callback and cookie.
- *
- * Return 0 on success, error value otherwise.
- */
-int tspp2_src_event_notification_register(u32 src_handle,
-			u32 src_event_bitmask,
-			void (*callback)(void *cookie, u32 event_bitmask),
-			void *cookie)
-{
-	int ret;
-	u32 reg;
-	unsigned long flags;
-	struct tspp2_src *src = (struct tspp2_src *)src_handle;
-
-	if (!src) {
-		pr_err("%s: Invalid source handle\n", __func__);
-		return -EINVAL;
-	}
-
-	ret = pm_runtime_get_sync(src->device->dev);
-	if (ret < 0)
-		return ret;
-
-	if (mutex_lock_interruptible(&src->device->mutex)) {
-		pm_runtime_mark_last_busy(src->device->dev);
-		pm_runtime_put_autosuspend(src->device->dev);
-		return -ERESTARTSYS;
-	}
-
-	if (!src->device->opened) {
-		pr_err("%s: Device must be opened first\n", __func__);
-		mutex_unlock(&src->device->mutex);
-		pm_runtime_mark_last_busy(src->device->dev);
-		pm_runtime_put_autosuspend(src->device->dev);
-		return -EPERM;
-	}
-
-	if (!src->opened) {
-		pr_err("%s: Source not opened\n", __func__);
-		goto err_inval;
-	}
-
-	if (((src->input == TSPP2_INPUT_TSIF0) ||
-		(src->input == TSPP2_INPUT_TSIF1)) &&
-		((src_event_bitmask & TSPP2_SRC_EVENT_MEMORY_READ_ERROR) ||
-		(src_event_bitmask & TSPP2_SRC_EVENT_FLOW_CTRL_STALL))) {
-		pr_err("%s: Invalid event bitmask for a source with TSIF input\n",
-				__func__);
-		goto err_inval;
-	}
-
-	if ((src->input == TSPP2_INPUT_MEMORY) &&
-		((src_event_bitmask & TSPP2_SRC_EVENT_TSIF_LOST_SYNC) ||
-		(src_event_bitmask & TSPP2_SRC_EVENT_TSIF_TIMEOUT) ||
-		(src_event_bitmask & TSPP2_SRC_EVENT_TSIF_OVERFLOW) ||
-		(src_event_bitmask & TSPP2_SRC_EVENT_TSIF_PKT_READ_ERROR) ||
-		(src_event_bitmask & TSPP2_SRC_EVENT_TSIF_PKT_WRITE_ERROR))) {
-		pr_err("%s: Invalid event bitmask for a source with memory input\n",
-			__func__);
-		goto err_inval;
-	}
-
-	spin_lock_irqsave(&src->device->spinlock, flags);
-	src->event_callback = callback;
-	src->event_cookie = cookie;
-	src->event_bitmask = src_event_bitmask;
-	spin_unlock_irqrestore(&src->device->spinlock, flags);
-
-	/* Enable/disable flow control stall interrupt on the source */
-	reg = readl_relaxed(src->device->base + TSPP2_GLOBAL_IRQ_ENABLE);
-	if (callback && (src_event_bitmask & TSPP2_SRC_EVENT_FLOW_CTRL_STALL)) {
-		reg |= ((0x1 << src->hw_index) <<
-			GLOBAL_IRQ_FC_STALL_OFFS);
-	} else {
-		reg &= ~((0x1 << src->hw_index) <<
-			GLOBAL_IRQ_FC_STALL_OFFS);
-	}
-	writel_relaxed(reg, src->device->base + TSPP2_GLOBAL_IRQ_ENABLE);
-
-	mutex_unlock(&src->device->mutex);
-
-	pm_runtime_mark_last_busy(src->device->dev);
-	pm_runtime_put_autosuspend(src->device->dev);
-
-	dev_dbg(src->device->dev, "%s: successful\n", __func__);
-
-	return 0;
-
-err_inval:
-	mutex_unlock(&src->device->mutex);
-	pm_runtime_mark_last_busy(src->device->dev);
-	pm_runtime_put_autosuspend(src->device->dev);
-
-	return -EINVAL;
-}
-EXPORT_SYMBOL(tspp2_src_event_notification_register);
-
-/**
- * tspp2_filter_event_notification_register() - Get notified on a filter event.
- *
- * @filter_handle:		Filter handle.
- * @filter_event_bitmask:	A bitmask of filter events,
- *				TSPP2_FILTER_EVENT_XXX.
- * @callback:			User callback function.
- * @cookie:			User information passed to the callback.
- *
- * Register a user callback which will be invoked when certain filter
- * events occur. Note the values (mask, callback and cookie) are overwritten
- * when calling this function multiple times. Therefore it is possible to
- * "unregister" a callback by calling this function with the bitmask set to 0
- * and with NULL callback and cookie.
- *
- * Return 0 on success, error value otherwise.
- */
-int tspp2_filter_event_notification_register(u32 filter_handle,
-			u32 filter_event_bitmask,
-			void (*callback)(void *cookie, u32 event_bitmask),
-			void *cookie)
-{
-	int ret;
-	int idx;
-	u32 reg;
-	unsigned long flags;
-	struct tspp2_filter *filter = (struct tspp2_filter *)filter_handle;
-
-	if (!filter) {
-		pr_err("%s: Invalid filter handle\n", __func__);
-		return -EINVAL;
-	}
-
-	ret = pm_runtime_get_sync(filter->device->dev);
-	if (ret < 0)
-		return ret;
-
-	if (mutex_lock_interruptible(&filter->device->mutex)) {
-		pm_runtime_mark_last_busy(filter->device->dev);
-		pm_runtime_put_autosuspend(filter->device->dev);
-		return -ERESTARTSYS;
-	}
-
-	if (!filter->device->opened) {
-		pr_err("%s: Device must be opened first\n", __func__);
-		mutex_unlock(&filter->device->mutex);
-		pm_runtime_mark_last_busy(filter->device->dev);
-		pm_runtime_put_autosuspend(filter->device->dev);
-		return -EPERM;
-	}
-
-	if (!filter->opened) {
-		pr_err("%s: Filter not opened\n", __func__);
-		mutex_unlock(&filter->device->mutex);
-		pm_runtime_mark_last_busy(filter->device->dev);
-		pm_runtime_put_autosuspend(filter->device->dev);
-		return -EINVAL;
-	}
-
-	spin_lock_irqsave(&filter->device->spinlock, flags);
-	filter->event_callback = callback;
-	filter->event_cookie = cookie;
-	filter->event_bitmask = filter_event_bitmask;
-	spin_unlock_irqrestore(&filter->device->spinlock, flags);
-
-	/* Enable/disable SC high/low interrupts per filter as requested */
-	idx = (filter->context >> 5);
-	reg = readl_relaxed(filter->device->base +
-		TSPP2_SC_GO_HIGH_ENABLE(idx));
-	if (callback &&
-		(filter_event_bitmask & TSPP2_FILTER_EVENT_SCRAMBLING_HIGH)) {
-		reg |= (0x1 << TSPP2_MODULUS_OP(filter->context, 32));
-	} else {
-		reg &= ~(0x1 << TSPP2_MODULUS_OP(filter->context, 32));
-	}
-	writel_relaxed(reg, filter->device->base +
-		TSPP2_SC_GO_HIGH_ENABLE(idx));
-
-	reg = readl_relaxed(filter->device->base +
-		TSPP2_SC_GO_LOW_ENABLE(idx));
-	if (callback &&
-		(filter_event_bitmask & TSPP2_FILTER_EVENT_SCRAMBLING_LOW)) {
-		reg |= (0x1 << TSPP2_MODULUS_OP(filter->context, 32));
-	} else {
-		reg &= ~(0x1 << TSPP2_MODULUS_OP(filter->context, 32));
-	}
-	writel_relaxed(reg, filter->device->base +
-		TSPP2_SC_GO_LOW_ENABLE(idx));
-
-	mutex_unlock(&filter->device->mutex);
-
-	pm_runtime_mark_last_busy(filter->device->dev);
-	pm_runtime_put_autosuspend(filter->device->dev);
-
-	dev_dbg(filter->device->dev, "%s: successful\n", __func__);
-
-	return 0;
-}
-EXPORT_SYMBOL(tspp2_filter_event_notification_register);
-
-/**
- * tspp2_get_filter_hw_index() - Get a filter's hardware index.
- *
- * @filter_handle:		Filter handle.
- *
- * This is an helper function to support tspp2 auto-testing.
- *
- * Return the filter's hardware index on success, error value otherwise.
- */
-int tspp2_get_filter_hw_index(u32 filter_handle)
-{
-	struct tspp2_filter *filter = (struct tspp2_filter *)filter_handle;
-	if (!filter_handle)
-		return -EINVAL;
-	return filter->hw_index;
-}
-EXPORT_SYMBOL(tspp2_get_filter_hw_index);
-
-/**
- * tspp2_get_reserved_hw_index() - Get a source's reserved hardware index.
- *
- * @src_handle:		Source handle.
- *
- * This is an helper function to support tspp2 auto-testing.
- *
- * Return the source's reserved hardware index on success,
- * error value otherwise.
- */
-int tspp2_get_reserved_hw_index(u32 src_handle)
-{
-	struct tspp2_src *src = (struct tspp2_src *)src_handle;
-	if (!src_handle)
-		return -EINVAL;
-	return src->reserved_filter_hw_index;
-}
-EXPORT_SYMBOL(tspp2_get_reserved_hw_index);
-
-/**
- * tspp2_get_ops_array() - Get filter's operations.
- *
- * @filter_handle:		Filter handle.
- * @ops_array:			The filter's operations.
- * @num_of_ops:			The filter's number of operations.
- *
- * This is an helper function to support tspp2 auto-testing.
- *
- * Return 0 on success, error value otherwise.
- */
-int tspp2_get_ops_array(u32 filter_handle,
-		struct tspp2_operation ops_array[TSPP2_MAX_OPS_PER_FILTER],
-		u8 *num_of_ops)
-{
-	int i;
-	struct tspp2_filter *filter = (struct tspp2_filter *)filter_handle;
-	if (!filter_handle || !num_of_ops)
-		return -EINVAL;
-	*num_of_ops = filter->num_user_operations;
-	for (i = 0; i < *num_of_ops; i++)
-		ops_array[i] = filter->operations[i];
-	return 0;
-}
-EXPORT_SYMBOL(tspp2_get_ops_array);
-
-/* Platform driver related functions: */
-
-/**
- * msm_tspp2_dt_to_pdata() - Copy device-tree data to platfrom data structure.
- *
- * @pdev:	Platform device.
- *
- * Return pointer to allocated platform data on success, NULL on failure.
- */
-static struct msm_tspp2_platform_data *
-msm_tspp2_dt_to_pdata(struct platform_device *pdev)
-{
-	struct device_node *node = pdev->dev.of_node;
-	struct msm_tspp2_platform_data *data;
-	int rc;
-
-	/* Note: memory allocated by devm_kzalloc is freed automatically */
-	data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL);
-	if (!data) {
-		pr_err("%s: Unable to allocate platform data\n", __func__);
-		return NULL;
-	}
-
-	/* Get power regulator */
-	if (!of_get_property(node, "vdd-supply", NULL)) {
-		pr_err("%s: Could not find vdd-supply property\n", __func__);
-		return NULL;
-	}
-
-	/* Get IOMMU information */
-	rc = of_property_read_string(node, "qcom,iommu-hlos-group",
-					&data->hlos_group);
-	if (rc) {
-		pr_err("%s: Could not find iommu-hlos-group property, err = %d\n",
-			__func__, rc);
-		return NULL;
-	}
-	rc = of_property_read_string(node, "qcom,iommu-cpz-group",
-					&data->cpz_group);
-	if (rc) {
-		pr_err("%s: Could not find iommu-cpz-group property, err = %d\n",
-			__func__, rc);
-		return NULL;
-	}
-	rc = of_property_read_u32(node, "qcom,iommu-hlos-partition",
-					&data->hlos_partition);
-	if (rc) {
-		pr_err("%s: Could not find iommu-hlos-partition property, err = %d\n",
-			__func__, rc);
-		return NULL;
-	}
-	rc = of_property_read_u32(node, "qcom,iommu-cpz-partition",
-					&data->cpz_partition);
-	if (rc) {
-		pr_err("%s: Could not find iommu-cpz-partition property, err = %d\n",
-			__func__, rc);
-		return NULL;
-	}
-
-	return data;
-}
-
-static void msm_tspp2_iommu_info_free(struct tspp2_device *device)
-{
-	if (device->iommu_info.hlos_group) {
-		iommu_group_put(device->iommu_info.hlos_group);
-		device->iommu_info.hlos_group = NULL;
-	}
-
-	if (device->iommu_info.cpz_group) {
-		iommu_group_put(device->iommu_info.cpz_group);
-		device->iommu_info.cpz_group = NULL;
-	}
-
-	device->iommu_info.hlos_domain = NULL;
-	device->iommu_info.cpz_domain = NULL;
-	device->iommu_info.hlos_domain_num = -1;
-	device->iommu_info.cpz_domain_num = -1;
-	device->iommu_info.hlos_partition = -1;
-	device->iommu_info.cpz_partition = -1;
-}
-
-/**
- * msm_tspp2_iommu_info_get() - Get IOMMU information.
- *
- * @pdev:	Platform device, containing platform information.
- * @device:	TSPP2 device.
- *
- * Return 0 on success, error value otherwise.
- */
-static int msm_tspp2_iommu_info_get(struct platform_device *pdev,
-						struct tspp2_device *device)
-{
-	int ret = 0;
-	struct msm_tspp2_platform_data *data = pdev->dev.platform_data;
-
-	device->iommu_info.hlos_group = NULL;
-	device->iommu_info.cpz_group = NULL;
-	device->iommu_info.hlos_domain = NULL;
-	device->iommu_info.cpz_domain = NULL;
-	device->iommu_info.hlos_domain_num = -1;
-	device->iommu_info.cpz_domain_num = -1;
-	device->iommu_info.hlos_partition = -1;
-	device->iommu_info.cpz_partition = -1;
-
-	device->iommu_info.hlos_group = iommu_group_find(data->hlos_group);
-	if (!device->iommu_info.hlos_group) {
-		dev_err(&pdev->dev, "%s: Cannot find IOMMU HLOS group",
-			__func__);
-		ret = -EINVAL;
-		goto err_out;
-	}
-	device->iommu_info.cpz_group = iommu_group_find(data->cpz_group);
-	if (!device->iommu_info.cpz_group) {
-		dev_err(&pdev->dev, "%s: Cannot find IOMMU CPZ group",
-			__func__);
-		ret = -EINVAL;
-		goto err_out;
-	}
-
-	device->iommu_info.hlos_domain =
-		iommu_group_get_iommudata(device->iommu_info.hlos_group);
-	if (IS_ERR_OR_NULL(device->iommu_info.hlos_domain)) {
-		dev_err(&pdev->dev, "%s: iommu_group_get_iommudata failed",
-			__func__);
-		ret = -EINVAL;
-		goto err_out;
-	}
-
-	device->iommu_info.cpz_domain =
-		iommu_group_get_iommudata(device->iommu_info.cpz_group);
-	if (IS_ERR_OR_NULL(device->iommu_info.cpz_domain)) {
-		device->iommu_info.hlos_domain = NULL;
-		dev_err(&pdev->dev, "%s: iommu_group_get_iommudata failed",
-			__func__);
-		ret = -EINVAL;
-		goto err_out;
-	}
-
-	device->iommu_info.hlos_domain_num =
-			msm_find_domain_no(device->iommu_info.hlos_domain);
-	device->iommu_info.cpz_domain_num =
-			msm_find_domain_no(device->iommu_info.cpz_domain);
-	device->iommu_info.hlos_partition = data->hlos_partition;
-	device->iommu_info.cpz_partition = data->cpz_partition;
-
-	return 0;
-
-err_out:
-	msm_tspp2_iommu_info_free(device);
-
-	return ret;
-}
-
-/**
- * tspp2_clocks_put() - Put clocks and disable regulator.
- *
- * @device:	TSPP2 device.
- */
-static void tspp2_clocks_put(struct tspp2_device *device)
-{
-	if (device->tsif_ref_clk)
-		clk_put(device->tsif_ref_clk);
-
-	if (device->tspp2_klm_ahb_clk)
-		clk_put(device->tspp2_klm_ahb_clk);
-
-	if (device->tspp2_vbif_clk)
-		clk_put(device->tspp2_vbif_clk);
-
-	if (device->vbif_ahb_clk)
-		clk_put(device->vbif_ahb_clk);
-
-	if (device->vbif_axi_clk)
-		clk_put(device->vbif_axi_clk);
-
-	if (device->tspp2_core_clk)
-		clk_put(device->tspp2_core_clk);
-
-	if (device->tspp2_ahb_clk)
-		clk_put(device->tspp2_ahb_clk);
-
-	device->tspp2_ahb_clk = NULL;
-	device->tspp2_core_clk = NULL;
-	device->tspp2_vbif_clk = NULL;
-	device->vbif_ahb_clk = NULL;
-	device->vbif_axi_clk = NULL;
-	device->tspp2_klm_ahb_clk = NULL;
-	device->tsif_ref_clk = NULL;
-}
-
-/**
- * msm_tspp2_clocks_setup() - Get clocks and set their rate, enable regulator.
- *
- * @pdev:	Platform device, containing platform information.
- * @device:	TSPP2 device.
- *
- * Return 0 on success, error value otherwise.
- */
-static int msm_tspp2_clocks_setup(struct platform_device *pdev,
-						struct tspp2_device *device)
-{
-	int ret = 0;
-	unsigned long rate_in_hz = 0;
-	struct clk *tspp2_core_clk_src = NULL;
-
-	/* Get power regulator (GDSC) */
-	device->gdsc = devm_regulator_get(&pdev->dev, "vdd");
-	if (IS_ERR(device->gdsc)) {
-		pr_err("%s: Failed to get vdd power regulator\n", __func__);
-		ret = PTR_ERR(device->gdsc);
-		device->gdsc = NULL;
-		return ret;
-	}
-
-	device->tspp2_ahb_clk = NULL;
-	device->tspp2_core_clk = NULL;
-	device->tspp2_vbif_clk = NULL;
-	device->vbif_ahb_clk = NULL;
-	device->vbif_axi_clk = NULL;
-	device->tspp2_klm_ahb_clk = NULL;
-	device->tsif_ref_clk = NULL;
-
-	device->tspp2_ahb_clk = clk_get(&pdev->dev, "bcc_tspp2_ahb_clk");
-	if (IS_ERR(device->tspp2_ahb_clk)) {
-		pr_err("%s: Failed to get %s", __func__, "bcc_tspp2_ahb_clk");
-		ret = PTR_ERR(device->tspp2_ahb_clk);
-		device->tspp2_ahb_clk = NULL;
-		goto err_clocks;
-	}
-
-	device->tspp2_core_clk = clk_get(&pdev->dev, "bcc_tspp2_core_clk");
-	if (IS_ERR(device->tspp2_core_clk)) {
-		pr_err("%s: Failed to get %s", __func__, "bcc_tspp2_core_clk");
-		ret = PTR_ERR(device->tspp2_core_clk);
-		device->tspp2_core_clk = NULL;
-		goto err_clocks;
-	}
-
-	device->tspp2_vbif_clk = clk_get(&pdev->dev, "bcc_vbif_tspp2_clk");
-	if (IS_ERR(device->tspp2_vbif_clk)) {
-		pr_err("%s: Failed to get %s", __func__, "bcc_vbif_tspp2_clk");
-		ret = PTR_ERR(device->tspp2_vbif_clk);
-		device->tspp2_vbif_clk = NULL;
-		goto err_clocks;
-	}
-
-	device->vbif_ahb_clk = clk_get(&pdev->dev, "iface_vbif_clk");
-	if (IS_ERR(device->vbif_ahb_clk)) {
-		pr_err("%s: Failed to get %s", __func__, "iface_vbif_clk");
-		ret = PTR_ERR(device->vbif_ahb_clk);
-		device->vbif_ahb_clk = NULL;
-		goto err_clocks;
-	}
-
-	device->vbif_axi_clk = clk_get(&pdev->dev, "vbif_core_clk");
-	if (IS_ERR(device->vbif_axi_clk)) {
-		pr_err("%s: Failed to get %s", __func__, "vbif_core_clk");
-		ret = PTR_ERR(device->vbif_axi_clk);
-		device->vbif_axi_clk = NULL;
-		goto err_clocks;
-	}
-
-	device->tspp2_klm_ahb_clk = clk_get(&pdev->dev, "bcc_klm_ahb_clk");
-	if (IS_ERR(device->tspp2_klm_ahb_clk)) {
-		pr_err("%s: Failed to get %s", __func__, "bcc_klm_ahb_clk");
-		ret = PTR_ERR(device->tspp2_klm_ahb_clk);
-		device->tspp2_klm_ahb_clk = NULL;
-		goto err_clocks;
-	}
-
-	device->tsif_ref_clk = clk_get(&pdev->dev, "gcc_tsif_ref_clk");
-	if (IS_ERR(device->tsif_ref_clk)) {
-		pr_err("%s: Failed to get %s", __func__, "gcc_tsif_ref_clk");
-		ret = PTR_ERR(device->tsif_ref_clk);
-		device->tsif_ref_clk = NULL;
-		goto err_clocks;
-	}
-
-	/* Set relevant clock rates */
-	rate_in_hz = clk_round_rate(device->tsif_ref_clk, 1);
-	if (clk_set_rate(device->tsif_ref_clk, rate_in_hz)) {
-		pr_err("%s: Failed to set rate %lu to %s\n", __func__,
-			rate_in_hz, "gcc_tsif_ref_clk");
-		goto err_clocks;
-	}
-
-	/* We need to set the rate of tspp2_core_clk_src */
-	tspp2_core_clk_src = clk_get_parent(device->tspp2_core_clk);
-	if (tspp2_core_clk_src) {
-		rate_in_hz = clk_round_rate(tspp2_core_clk_src, 1);
-		if (clk_set_rate(tspp2_core_clk_src, rate_in_hz)) {
-			pr_err("%s: Failed to set rate %lu to tspp2_core_clk_src\n",
-				__func__, rate_in_hz);
-			goto err_clocks;
-		}
-	} else {
-		pr_err("%s: Failed to get tspp2_core_clk parent\n", __func__);
-		goto err_clocks;
-	}
-
-	return 0;
-
-err_clocks:
-	tspp2_clocks_put(device);
-
-	return ret;
-}
-
-/**
- * msm_tspp2_map_io_memory() - Map memory resources to kernel space.
- *
- * @pdev:	Platform device, containing platform information.
- * @device:	TSPP2 device.
- *
- * Return 0 on success, error value otherwise.
- */
-static int msm_tspp2_map_io_memory(struct platform_device *pdev,
-						struct tspp2_device *device)
-{
-	struct resource *mem_tsif0;
-	struct resource *mem_tsif1;
-	struct resource *mem_tspp2;
-	struct resource *mem_bam;
-
-	/* Get memory resources */
-	mem_tsif0 = platform_get_resource_byname(pdev,
-				IORESOURCE_MEM, "MSM_TSIF0");
-	if (!mem_tsif0) {
-		dev_err(&pdev->dev, "%s: Missing TSIF0 MEM resource", __func__);
-		return -ENXIO;
-	}
-
-	mem_tsif1 = platform_get_resource_byname(pdev,
-				IORESOURCE_MEM, "MSM_TSIF1");
-	if (!mem_tsif1) {
-		dev_err(&pdev->dev, "%s: Missing TSIF1 MEM resource", __func__);
-		return -ENXIO;
-	}
-
-	mem_tspp2 = platform_get_resource_byname(pdev,
-				IORESOURCE_MEM, "MSM_TSPP2");
-	if (!mem_tspp2) {
-		dev_err(&pdev->dev, "%s: Missing TSPP2 MEM resource", __func__);
-		return -ENXIO;
-	}
-
-	mem_bam = platform_get_resource_byname(pdev,
-				IORESOURCE_MEM, "MSM_TSPP2_BAM");
-	if (!mem_bam) {
-		dev_err(&pdev->dev, "%s: Missing BAM MEM resource", __func__);
-		return -ENXIO;
-	}
-
-	/* Map memory physical addresses to kernel space */
-	device->tsif_devices[0].base = ioremap(mem_tsif0->start,
-		resource_size(mem_tsif0));
-	if (!device->tsif_devices[0].base) {
-		dev_err(&pdev->dev, "%s: ioremap failed", __func__);
-		goto err_map_tsif0;
-	}
-
-	device->tsif_devices[1].base = ioremap(mem_tsif1->start,
-		resource_size(mem_tsif1));
-	if (!device->tsif_devices[1].base) {
-		dev_err(&pdev->dev, "%s: ioremap failed", __func__);
-		goto err_map_tsif1;
-	}
-
-	device->base = ioremap(mem_tspp2->start, resource_size(mem_tspp2));
-	if (!device->base) {
-		dev_err(&pdev->dev, "%s: ioremap failed", __func__);
-		goto err_map_dev;
-	}
-
-	memset(&device->bam_props, 0, sizeof(device->bam_props));
-	device->bam_props.phys_addr = mem_bam->start;
-	device->bam_props.virt_addr = ioremap(mem_bam->start,
-		resource_size(mem_bam));
-	if (!device->bam_props.virt_addr) {
-		dev_err(&pdev->dev, "%s: ioremap failed", __func__);
-		goto err_map_bam;
-	}
-
-	return 0;
-
-err_map_bam:
-	iounmap(device->base);
-
-err_map_dev:
-	iounmap(device->tsif_devices[1].base);
-
-err_map_tsif1:
-	iounmap(device->tsif_devices[0].base);
-
-err_map_tsif0:
-	return -ENXIO;
-}
-
-/**
- * tspp2_event_work_prepare() - Prepare and queue a work element.
- *
- * @device:		TSPP2 device.
- * @callback:		User callback to invoke.
- * @cookie:		User cookie.
- * @event_bitmask:	Event bitmask
- *
- * Get a free work element from the pool, prepare it and queue it
- * to the work queue. When scheduled, the work will invoke the user callback
- * for the event that the HW reported.
- */
-static void tspp2_event_work_prepare(struct tspp2_device *device,
-			void (*callback)(void *cookie, u32 event_bitmask),
-			void *cookie,
-			u32 event_bitmask)
-{
-	struct tspp2_event_work *work = NULL;
-
-	if (!list_empty(&device->free_work_list)) {
-		work = list_first_entry(&device->free_work_list,
-			struct tspp2_event_work, link);
-		list_del(&work->link);
-		work->callback = callback;
-		work->cookie = cookie;
-		work->event_bitmask = event_bitmask;
-		queue_work(device->work_queue, &work->work);
-	} else {
-		pr_warn("%s: No available work element\n", __func__);
-	}
-}
-
-/**
- * tspp2_isr() - TSPP2 interrupt handler.
- *
- * @irq:	Interrupt number.
- * @dev:	TSPP2 device.
- *
- * Handle TSPP2 HW interrupt. Collect relevant statistics and invoke
- * user registered callbacks for global, source or filter events.
- *
- * Return IRQ_HANDLED.
- */
-static irqreturn_t tspp2_isr(int irq, void *dev)
-{
-	struct tspp2_device *device = dev;
-	struct tspp2_src *src = NULL;
-	struct tspp2_filter *f = NULL;
-	unsigned long ext_reg = 0;
-	unsigned long val = 0;
-	unsigned long flags;
-	u32 i = 0, j = 0;
-	u32 global_bitmask = 0;
-	u32 src_bitmask[TSPP2_NUM_MEM_INPUTS] = {0};
-	u32 filter_bitmask[TSPP2_NUM_CONTEXTS] = {0};
-	u32 reg = 0;
-
-	reg = readl_relaxed(device->base + TSPP2_GLOBAL_IRQ_STATUS);
-
-	if (reg & (0x1 << GLOBAL_IRQ_TSP_INVALID_AF_OFFS)) {
-		device->irq_stats.global.tsp_invalid_af_control++;
-		global_bitmask |= TSPP2_GLOBAL_EVENT_INVALID_AF_CTRL;
-	}
-
-	if (reg & (0x1 << GLOBAL_IRQ_TSP_INVALID_LEN_OFFS)) {
-		device->irq_stats.global.tsp_invalid_length++;
-		global_bitmask |= TSPP2_GLOBAL_EVENT_INVALID_AF_LENGTH;
-	}
-
-	if (reg & (0x1 << GLOBAL_IRQ_PES_NO_SYNC_OFFS)) {
-		device->irq_stats.global.pes_no_sync++;
-		global_bitmask |= TSPP2_GLOBAL_EVENT_PES_NO_SYNC;
-	}
-
-	if (reg & (0x1 << GLOBAL_IRQ_ENCRYPT_LEVEL_ERR_OFFS))
-		device->irq_stats.global.encrypt_level_err++;
-
-	if (reg & (0x1 << GLOBAL_IRQ_KEY_NOT_READY_OFFS)) {
-		ext_reg = readl_relaxed(device->base +
-				TSPP2_KEY_NOT_READY_IRQ_STATUS);
-		for_each_set_bit(i, &ext_reg, TSPP2_NUM_KEYTABLES)
-			device->irq_stats.kt[i].key_not_ready++;
-		writel_relaxed(ext_reg, device->base +
-			TSPP2_KEY_NOT_READY_IRQ_CLEAR);
-	}
-
-	if (reg & (0x1 << GLOBAL_IRQ_UNEXPECTED_RESET_OFFS)) {
-		ext_reg = readl_relaxed(device->base +
-				TSPP2_UNEXPECTED_RST_IRQ_STATUS);
-		for_each_set_bit(i, &ext_reg, TSPP2_NUM_PIPES)
-			device->irq_stats.pipe[i].unexpected_reset++;
-		writel_relaxed(ext_reg, device->base +
-			TSPP2_UNEXPECTED_RST_IRQ_CLEAR);
-	}
-
-	if (reg & (0x1 << GLOBAL_IRQ_WRONG_PIPE_DIR_OFFS)) {
-		ext_reg = readl_relaxed(device->base +
-				TSPP2_WRONG_PIPE_DIR_IRQ_STATUS);
-		for_each_set_bit(i, &ext_reg, TSPP2_NUM_PIPES)
-			device->irq_stats.pipe[i].wrong_pipe_direction++;
-		writel_relaxed(ext_reg, device->base +
-			TSPP2_WRONG_PIPE_DIR_IRQ_CLEAR);
-	}
-
-	if (reg & (0x1 << GLOBAL_IRQ_QSB_RESP_ERR_OFFS)) {
-		global_bitmask |= TSPP2_GLOBAL_EVENT_TX_FAIL;
-		ext_reg = readl_relaxed(device->base +
-				TSPP2_QSB_RESPONSE_ERROR_IRQ_STATUS);
-		for_each_set_bit(i, &ext_reg, TSPP2_NUM_PIPES)
-			device->irq_stats.pipe[i].qsb_response_error++;
-		writel_relaxed(ext_reg, device->base +
-			TSPP2_QSB_RESPONSE_ERROR_IRQ_CLEAR);
-	}
-
-	if (reg & (0x1 << GLOBAL_IRQ_SC_GO_HIGH_OFFS)) {
-		for (j = 0; j < 3; j++) {
-			ext_reg = readl_relaxed(device->base +
-					TSPP2_SC_GO_HIGH_STATUS(j));
-			for_each_set_bit(i, &ext_reg, 32) {
-				filter_bitmask[j*32 + i] |=
-					TSPP2_FILTER_EVENT_SCRAMBLING_HIGH;
-				device->irq_stats.ctx[j*32 + i].sc_go_high++;
-			}
-			writel_relaxed(ext_reg, device->base +
-					TSPP2_SC_GO_HIGH_CLEAR(j));
-		}
-	}
-
-	if (reg & (0x1 << GLOBAL_IRQ_SC_GO_LOW_OFFS)) {
-		for (j = 0; j < 3; j++) {
-			ext_reg = readl_relaxed(device->base +
-					TSPP2_SC_GO_LOW_STATUS(j));
-			for_each_set_bit(i, &ext_reg, 32) {
-				filter_bitmask[j*32 + i] |=
-					TSPP2_FILTER_EVENT_SCRAMBLING_LOW;
-				device->irq_stats.ctx[j*32 + i].sc_go_low++;
-			}
-			writel_relaxed(ext_reg, device->base +
-					TSPP2_SC_GO_LOW_CLEAR(j));
-		}
-	}
-
-	if (reg & (0xFF << GLOBAL_IRQ_READ_FAIL_OFFS)) {
-		val = ((reg & (0xFF << GLOBAL_IRQ_READ_FAIL_OFFS)) >>
-			GLOBAL_IRQ_READ_FAIL_OFFS);
-		for_each_set_bit(i, &val, TSPP2_NUM_MEM_INPUTS) {
-			src_bitmask[i] |= TSPP2_SRC_EVENT_MEMORY_READ_ERROR;
-			device->irq_stats.src[i].read_failure++;
-		}
-	}
-
-	if (reg & (0xFF << GLOBAL_IRQ_FC_STALL_OFFS)) {
-		val = ((reg & (0xFF << GLOBAL_IRQ_FC_STALL_OFFS)) >>
-			GLOBAL_IRQ_FC_STALL_OFFS);
-		for_each_set_bit(i, &val, TSPP2_NUM_MEM_INPUTS) {
-			src_bitmask[i] |= TSPP2_SRC_EVENT_FLOW_CTRL_STALL;
-			device->irq_stats.src[i].flow_control_stall++;
-		}
-	}
-
-	spin_lock_irqsave(&device->spinlock, flags);
-
-	/* Invoke user callback for global events */
-	if (device->event_callback && (global_bitmask & device->event_bitmask))
-		tspp2_event_work_prepare(device, device->event_callback,
-			device->event_cookie,
-			(global_bitmask & device->event_bitmask));
-
-	/* Invoke user callbacks on memory source events */
-	for (i = 0; i < TSPP2_NUM_MEM_INPUTS; i++) {
-		src = &device->mem_sources[i];
-		if (src->event_callback &&
-			(src_bitmask[src->hw_index] & src->event_bitmask))
-			tspp2_event_work_prepare(device,
-				src->event_callback,
-				src->event_cookie,
-				(src_bitmask[src->hw_index] &
-					src->event_bitmask));
-	}
-
-	/* Invoke user callbacks on filter events */
-	for (i = 0; i < TSPP2_NUM_AVAIL_FILTERS; i++) {
-		f = &device->filters[i];
-		if (f->event_callback &&
-			(f->event_bitmask & filter_bitmask[f->context]))
-			tspp2_event_work_prepare(device,
-				f->event_callback,
-				f->event_cookie,
-				(f->event_bitmask &
-					filter_bitmask[f->context]));
-	}
-
-	spin_unlock_irqrestore(&device->spinlock, flags);
-
-	/*
-	 * Clear global interrupts. Note bits [9:4] are an aggregation of
-	 * other IRQs, and are reserved in the TSPP2_GLOBAL_IRQ_CLEAR register.
-	 */
-	reg &= ~(0x0FFF << GLOBAL_IRQ_CLEAR_RESERVED_OFFS);
-	writel_relaxed(reg, device->base + TSPP2_GLOBAL_IRQ_CLEAR);
-	/*
-	 * Before returning IRQ_HANDLED to the generic interrupt handling
-	 * framework, we need to make sure all operations, including clearing of
-	 * interrupt status registers in the hardware, are performed.
-	 * Thus a barrier after clearing the interrupt status register
-	 * is required to guarantee that the interrupt status register has
-	 * really been cleared by the time we return from this handler.
-	 */
-	wmb();
-
-	return IRQ_HANDLED;
-}
-
-/**
- * tsif_isr() - TSIF interrupt handler.
- *
- * @irq:	Interrupt number.
- * @dev:	TSIF device that generated the interrupt.
- *
- * Handle TSIF HW interrupt. Collect HW statistics and, if the user registered
- * a relevant source callback, invoke it.
- *
- * Return IRQ_HANDLED on success, IRQ_NONE on irrelevant interrupts.
- */
-static irqreturn_t tsif_isr(int irq, void *dev)
-{
-	u32 src_bitmask = 0;
-	unsigned long flags;
-	struct tspp2_src *src = NULL;
-	struct tspp2_tsif_device *tsif_device = dev;
-	u32 sts_ctl = 0;
-
-	sts_ctl = readl_relaxed(tsif_device->base + TSPP2_TSIF_STS_CTL);
-
-	if (!(sts_ctl & (TSIF_STS_CTL_PACK_AVAIL	|
-			TSIF_STS_CTL_PKT_WRITE_ERR	|
-			TSIF_STS_CTL_PKT_READ_ERR	|
-			TSIF_STS_CTL_OVERFLOW		|
-			TSIF_STS_CTL_LOST_SYNC		|
-			TSIF_STS_CTL_TIMEOUT))) {
-		return IRQ_NONE;
-	}
-
-	if (sts_ctl & TSIF_STS_CTL_PKT_WRITE_ERR) {
-		src_bitmask |= TSPP2_SRC_EVENT_TSIF_PKT_WRITE_ERROR;
-		tsif_device->stat_pkt_write_err++;
-	}
-
-	if (sts_ctl & TSIF_STS_CTL_PKT_READ_ERR) {
-		src_bitmask |= TSPP2_SRC_EVENT_TSIF_PKT_READ_ERROR;
-		tsif_device->stat_pkt_read_err++;
-	}
-
-	if (sts_ctl & TSIF_STS_CTL_OVERFLOW) {
-		src_bitmask |= TSPP2_SRC_EVENT_TSIF_OVERFLOW;
-		tsif_device->stat_overflow++;
-	}
-
-	if (sts_ctl & TSIF_STS_CTL_LOST_SYNC) {
-		src_bitmask |= TSPP2_SRC_EVENT_TSIF_LOST_SYNC;
-		tsif_device->stat_lost_sync++;
-	}
-
-	if (sts_ctl & TSIF_STS_CTL_TIMEOUT) {
-		src_bitmask |= TSPP2_SRC_EVENT_TSIF_TIMEOUT;
-		tsif_device->stat_timeout++;
-	}
-
-	/* Invoke user TSIF source callbacks if registered for these events */
-	src = &tsif_device->dev->tsif_sources[tsif_device->hw_index];
-
-	spin_lock_irqsave(&src->device->spinlock, flags);
-
-	if (src->event_callback && (src->event_bitmask & src_bitmask))
-		tspp2_event_work_prepare(tsif_device->dev, src->event_callback,
-			src->event_cookie, (src->event_bitmask & src_bitmask));
-
-	spin_unlock_irqrestore(&src->device->spinlock, flags);
-
-	writel_relaxed(sts_ctl, tsif_device->base + TSPP2_TSIF_STS_CTL);
-	/*
-	 * Before returning IRQ_HANDLED to the generic interrupt handling
-	 * framework, we need to make sure all operations, including clearing of
-	 * interrupt status registers in the hardware, are performed.
-	 * Thus a barrier after clearing the interrupt status register
-	 * is required to guarantee that the interrupt status register has
-	 * really been cleared by the time we return from this handler.
-	 */
-	wmb();
-
-	return IRQ_HANDLED;
-}
-
-/**
- * msm_tspp2_map_irqs() - Get and request IRQs.
- *
- * @pdev:	Platform device, containing platform information.
- * @device:	TSPP2 device.
- *
- * Helper function to get IRQ numbers from the platform device and request
- * the IRQs (i.e., set interrupt handlers) for the TSPP2 and TSIF interrupts.
- *
- * Return 0 on success, error value otherwise.
- */
-static int msm_tspp2_map_irqs(struct platform_device *pdev,
-				struct tspp2_device *device)
-{
-	int rc;
-	int i;
-
-	/* get IRQ numbers from platform information */
-
-	rc = platform_get_irq_byname(pdev, "TSPP2");
-	if (rc > 0) {
-		device->tspp2_irq = rc;
-	} else {
-		dev_err(&pdev->dev, "%s: Failed to get TSPP2 IRQ", __func__);
-		return -EINVAL;
-	}
-
-	rc = platform_get_irq_byname(pdev, "TSIF0");
-	if (rc > 0) {
-		device->tsif_devices[0].tsif_irq = rc;
-	} else {
-		dev_err(&pdev->dev, "%s: Failed to get TSIF0 IRQ", __func__);
-		return -EINVAL;
-	}
-
-	rc = platform_get_irq_byname(pdev, "TSIF1");
-	if (rc > 0) {
-		device->tsif_devices[1].tsif_irq = rc;
-	} else {
-		dev_err(&pdev->dev, "%s: Failed to get TSIF1 IRQ", __func__);
-		return -EINVAL;
-	}
-
-	rc = platform_get_irq_byname(pdev, "TSPP2_BAM");
-	if (rc > 0) {
-		device->bam_irq = rc;
-	} else {
-		dev_err(&pdev->dev,
-			"%s: Failed to get TSPP2 BAM IRQ", __func__);
-		return -EINVAL;
-	}
-
-	rc = request_irq(device->tspp2_irq, tspp2_isr, IRQF_SHARED,
-			 dev_name(&pdev->dev), device);
-	if (rc) {
-		dev_err(&pdev->dev,
-			"%s: Failed to request TSPP2 IRQ %d : %d",
-			__func__, device->tspp2_irq, rc);
-		goto request_irq_err;
-	}
-
-	for (i = 0; i < TSPP2_NUM_TSIF_INPUTS; i++) {
-		rc = request_irq(device->tsif_devices[i].tsif_irq,
-				tsif_isr, IRQF_SHARED,
-				dev_name(&pdev->dev), &device->tsif_devices[i]);
-		if (rc) {
-			dev_warn(&pdev->dev,
-				"%s: Failed to request TSIF%d IRQ: %d",
-				__func__, i, rc);
-			device->tsif_devices[i].tsif_irq = 0;
-		}
-	}
-
-	return 0;
-
-request_irq_err:
-	device->tspp2_irq = 0;
-	device->tsif_devices[0].tsif_irq = 0;
-	device->tsif_devices[1].tsif_irq = 0;
-	device->bam_irq = 0;
-
-	return -EINVAL;
-}
-
-/* Device driver probe function */
-static int msm_tspp2_probe(struct platform_device *pdev)
-{
-	int rc = 0;
-	struct msm_tspp2_platform_data *data;
-	struct tspp2_device *device;
-	struct msm_bus_scale_pdata *tspp2_bus_pdata = NULL;
-
-	if (pdev->dev.of_node) {
-		/* Get information from device tree */
-		data = msm_tspp2_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;
-
-		tspp2_bus_pdata = msm_bus_cl_get_pdata(pdev);
-		pdev->dev.platform_data = data;
-	} else {
-		/* Get information from platform data */
-		data = pdev->dev.platform_data;
-	}
-	if (!data) {
-		pr_err("%s: Platform data not available\n", __func__);
-		return -EINVAL;
-	}
-
-	/* Verify device id is valid */
-	if ((pdev->id < 0) || (pdev->id >= TSPP2_NUM_DEVICES)) {
-		pr_err("%s: Invalid device ID %d\n", __func__, pdev->id);
-		return -EINVAL;
-	}
-
-	device = devm_kzalloc(&pdev->dev,
-				sizeof(struct tspp2_device),
-				GFP_KERNEL);
-	if (!device) {
-		pr_err("%s: Failed to allocate memory for device\n", __func__);
-		return -ENOMEM;
-	}
-	platform_set_drvdata(pdev, device);
-	device->pdev = pdev;
-	device->dev = &pdev->dev;
-	device->dev_id = pdev->id;
-	device->opened = 0;
-
-	/* Register bus client */
-	if (tspp2_bus_pdata) {
-		device->bus_client =
-			msm_bus_scale_register_client(tspp2_bus_pdata);
-		if (!device->bus_client)
-			pr_err("%s: Unable to register bus client\n", __func__);
-	} else {
-		pr_err("%s: Platform bus client data not available. Continue anyway...\n",
-			__func__);
-	}
-
-	rc = msm_tspp2_iommu_info_get(pdev, device);
-	if (rc) {
-		pr_err("%s: Failed to get IOMMU information\n", __func__);
-		goto err_bus_client;
-	}
-
-	rc = msm_tspp2_clocks_setup(pdev, device);
-	if (rc)
-		goto err_clocks_setup;
-
-	rc = msm_tspp2_map_io_memory(pdev, device);
-	if (rc)
-		goto err_map_io_memory;
-
-	rc = msm_tspp2_map_irqs(pdev, device);
-	if (rc)
-		goto err_map_irq;
-
-	mutex_init(&device->mutex);
-
-	tspp2_devices[pdev->id] = device;
-
-	tspp2_debugfs_init(device);
-
-	return rc;
-
-err_map_irq:
-	iounmap(device->base);
-	iounmap(device->tsif_devices[0].base);
-	iounmap(device->tsif_devices[1].base);
-	iounmap(device->bam_props.virt_addr);
-
-err_map_io_memory:
-	tspp2_clocks_put(device);
-
-err_clocks_setup:
-	msm_tspp2_iommu_info_free(device);
-
-err_bus_client:
-	if (device->bus_client)
-		msm_bus_scale_unregister_client(device->bus_client);
-
-	return rc;
-}
-
-/* Device driver remove function */
-static int msm_tspp2_remove(struct platform_device *pdev)
-{
-	int i;
-	int rc = 0;
-	struct tspp2_device *device = platform_get_drvdata(pdev);
-
-	tspp2_debugfs_exit(device);
-
-	if (device->tspp2_irq)
-		free_irq(device->tspp2_irq, device);
-
-	for (i = 0; i < TSPP2_NUM_TSIF_INPUTS; i++)
-		if (device->tsif_devices[i].tsif_irq)
-			free_irq(device->tsif_devices[i].tsif_irq,
-				&device->tsif_devices[i]);
-
-	/* Unmap memory */
-	iounmap(device->base);
-	iounmap(device->tsif_devices[0].base);
-	iounmap(device->tsif_devices[1].base);
-	iounmap(device->bam_props.virt_addr);
-
-	msm_tspp2_iommu_info_free(device);
-
-	if (device->bus_client)
-		msm_bus_scale_unregister_client(device->bus_client);
-
-	mutex_destroy(&device->mutex);
-
-	tspp2_clocks_put(device);
-
-	return rc;
-}
-
-/* Power Management */
-
-static int tspp2_runtime_suspend(struct device *dev)
-{
-	int ret = 0;
-	struct tspp2_device *device;
-	struct platform_device *pdev;
-
-	/*
-	 * HW manages power collapse automatically.
-	 * Disabling AHB and Core clocsk and "cancelling" bus bandwidth voting.
-	 */
-
-	pdev = container_of(dev, struct platform_device, dev);
-	device = platform_get_drvdata(pdev);
-
-	mutex_lock(&device->mutex);
-
-	if (!device->opened)
-		ret = -EPERM;
-	else
-		ret = tspp2_reg_clock_stop(device);
-
-	mutex_unlock(&device->mutex);
-
-	dev_dbg(dev, "%s\n", __func__);
-
-	return ret;
-}
-
-static int tspp2_runtime_resume(struct device *dev)
-{
-	int ret = 0;
-	struct tspp2_device *device;
-	struct platform_device *pdev;
-
-	/*
-	 * HW manages power collapse automatically.
-	 * Enabling AHB and Core clocks to allow access to unit registers,
-	 * and voting for the required bus bandwidth for register access.
-	 */
-
-	pdev = container_of(dev, struct platform_device, dev);
-	device = platform_get_drvdata(pdev);
-
-	mutex_lock(&device->mutex);
-
-	if (!device->opened)
-		ret = -EPERM;
-	else
-		ret = tspp2_reg_clock_start(device);
-
-	mutex_unlock(&device->mutex);
-
-	dev_dbg(dev, "%s\n", __func__);
-
-	return ret;
-}
-
-static const struct dev_pm_ops tspp2_dev_pm_ops = {
-	.runtime_suspend = tspp2_runtime_suspend,
-	.runtime_resume = tspp2_runtime_resume,
-};
-
-/* Platform driver information */
-
-static struct of_device_id msm_tspp2_match_table[] = {
-	{.compatible = "qcom,msm_tspp2"},
-	{}
-};
-
-static struct platform_driver msm_tspp2_driver = {
-	.probe          = msm_tspp2_probe,
-	.remove         = msm_tspp2_remove,
-	.driver         = {
-		.name   = "msm_tspp2",
-		.pm     = &tspp2_dev_pm_ops,
-		.of_match_table = msm_tspp2_match_table,
-	},
-};
-
-/**
- * tspp2_module_init() - TSPP2 driver module init function.
- *
- * Return 0 on success, error value otherwise.
- */
-static int __init tspp2_module_init(void)
-{
-	int rc;
-
-	rc = platform_driver_register(&msm_tspp2_driver);
-	if (rc)
-		pr_err("%s: platform_driver_register failed: %d\n",
-			__func__, rc);
-
-	return rc;
-}
-
-/**
- * tspp2_module_exit() - TSPP2 driver module exit function.
- */
-static void __exit tspp2_module_exit(void)
-{
-	platform_driver_unregister(&msm_tspp2_driver);
-}
-
-module_init(tspp2_module_init);
-module_exit(tspp2_module_exit);
-
-MODULE_DESCRIPTION("TSPP2 (Transport Stream Packet Processor v2) platform device driver");
-MODULE_LICENSE("GPL v2");
diff --git a/drivers/media/platform/msm/camera_v2/isp/msm_buf_mgr.c b/drivers/media/platform/msm/camera_v2/isp/msm_buf_mgr.c
index 48e5027..a36856b 100644
--- a/drivers/media/platform/msm/camera_v2/isp/msm_buf_mgr.c
+++ b/drivers/media/platform/msm/camera_v2/isp/msm_buf_mgr.c
@@ -43,8 +43,12 @@
 {
 	struct msm_isp_bufq *bufq = NULL;
 	uint32_t bufq_index = bufq_handle & 0xFF;
-	if (bufq_index > buf_mgr->num_buf_q)
-		return bufq;
+
+	/* bufq_handle cannot be 0 */
+	if ((bufq_handle == 0) ||
+		bufq_index >= BUF_MGR_NUM_BUF_Q ||
+		(bufq_index > buf_mgr->num_buf_q))
+		return NULL;
 
 	bufq = &buf_mgr->bufq[bufq_index];
 	if (bufq->bufq_handle == bufq_handle)
diff --git a/drivers/media/platform/msm/camera_v2/isp/msm_isp_axi_util.c b/drivers/media/platform/msm/camera_v2/isp/msm_isp_axi_util.c
index a8d8eb5..9a0e911 100644
--- a/drivers/media/platform/msm/camera_v2/isp/msm_isp_axi_util.c
+++ b/drivers/media/platform/msm/camera_v2/isp/msm_isp_axi_util.c
@@ -24,15 +24,12 @@
 	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;
-	}
+	uint32_t i = stream_cfg_cmd->stream_src;
 
-	if (i == MAX_NUM_STREAM) {
-		pr_err("%s: No free stream\n", __func__);
-		return rc;
+	if (i >= VFE_AXI_SRC_MAX) {
+		pr_err("%s:%d invalid stream_src %d\n", __func__, __LINE__,
+			stream_cfg_cmd->stream_src);
+		return -EINVAL;
 	}
 
 	if ((axi_data->stream_handle_cnt << 8) == 0)
diff --git a/drivers/media/platform/msm/camera_v2/isp/msm_isp_util.c b/drivers/media/platform/msm/camera_v2/isp/msm_isp_util.c
index a9a9c72..680a8a6 100644
--- a/drivers/media/platform/msm/camera_v2/isp/msm_isp_util.c
+++ b/drivers/media/platform/msm/camera_v2/isp/msm_isp_util.c
@@ -639,12 +639,12 @@
 		break;
 	case VIDIOC_MSM_ISP_AXI_RESET:
 		mutex_lock(&vfe_dev->core_mutex);
-		rc = msm_isp_axi_reset(vfe_dev, arg);
+			rc = msm_isp_axi_reset(vfe_dev, arg);
 		mutex_unlock(&vfe_dev->core_mutex);
 		break;
 	case VIDIOC_MSM_ISP_AXI_RESTART:
 		mutex_lock(&vfe_dev->core_mutex);
-		rc = msm_isp_axi_restart(vfe_dev, arg);
+			rc = msm_isp_axi_restart(vfe_dev, arg);
 		mutex_unlock(&vfe_dev->core_mutex);
 		break;
 	case VIDIOC_MSM_ISP_INPUT_CFG:
@@ -1293,8 +1293,6 @@
 {
 	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)
@@ -1390,6 +1388,7 @@
 		*irq_status0 = 0;
 		*irq_status1 = 0;
 
+			memset(&error_event, 0, sizeof(error_event));
 		error_event.frame_id =
 			vfe_dev->axi_data.src_info[VFE_PIX_0].frame_id;
 		error_event.u.error_info.error_mask = 1 << ISP_WM_BUS_OVERFLOW;
@@ -1406,8 +1405,7 @@
 		stream_info->stream_type != BURST_STREAM) {
 		return;
 	}
-	if (stream_info->stream_type == BURST_STREAM &&
-		stream_info->num_burst_capture != 0) {
+	if (stream_info->num_burst_capture != 0) {
 		stream_cfg_cmd.burst_count =
 			stream_info->num_burst_capture;
 		stream_cfg_cmd.frame_skip_pattern =
@@ -1419,7 +1417,6 @@
 		msm_isp_reset_framedrop(vfe_dev, stream_info);
 	}
 }
-
 irqreturn_t msm_isp_process_irq(int irq_num, void *data)
 {
 	unsigned long flags;
diff --git a/drivers/media/platform/msm/camera_v2/ispif/msm_ispif.c b/drivers/media/platform/msm/camera_v2/ispif/msm_ispif.c
index 9e35513..0eac216 100644
--- a/drivers/media/platform/msm/camera_v2/ispif/msm_ispif.c
+++ b/drivers/media/platform/msm/camera_v2/ispif/msm_ispif.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2013-2015, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2013-2016, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -363,23 +363,23 @@
 	switch (intftype) {
 	case PIX0:
 		data &= ~(BIT(1) | BIT(0));
-		data |= csid;
+		data |= (uint32_t) csid;
 		break;
 	case RDI0:
 		data &= ~(BIT(5) | BIT(4));
-		data |= (csid << 4);
+		data |= ((uint32_t) csid) << 4;
 		break;
 	case PIX1:
 		data &= ~(BIT(9) | BIT(8));
-		data |= (csid << 8);
+		data |= ((uint32_t) csid) << 8;
 		break;
 	case RDI1:
 		data &= ~(BIT(13) | BIT(12));
-		data |= (csid << 12);
+		data |= ((uint32_t) csid) << 12;
 		break;
 	case RDI2:
 		data &= ~(BIT(21) | BIT(20));
-		data |= (csid << 20);
+		data |= ((uint32_t) csid) << 20;
 		break;
 	}
 
@@ -455,9 +455,9 @@
 
 	data = msm_camera_io_r(ispif->base + intf_addr);
 	if (enable)
-		data |= cid_mask;
+		data |=  (uint32_t) cid_mask;
 	else
-		data &= ~cid_mask;
+		data &= ~((uint32_t) cid_mask);
 	msm_camera_io_w_mb(data, ispif->base + intf_addr);
 }
 
@@ -1136,9 +1136,15 @@
 static int msm_ispif_set_vfe_info(struct ispif_device *ispif,
 	struct msm_ispif_vfe_info *vfe_info)
 {
-	memcpy(&ispif->vfe_info, vfe_info, sizeof(struct msm_ispif_vfe_info));
-	if (ispif->vfe_info.num_vfe > ispif->hw_num_isps)
+	if (!vfe_info || (vfe_info->num_vfe <= 0) ||
+		((uint32_t)(vfe_info->num_vfe) > ispif->hw_num_isps)) {
+		pr_err("Invalid VFE info: %p %d\n", vfe_info,
+			   (vfe_info ? vfe_info->num_vfe:0));
 		return -EINVAL;
+	}
+
+	memcpy(&ispif->vfe_info, vfe_info, sizeof(struct msm_ispif_vfe_info));
+
 	return 0;
 }
 
diff --git a/drivers/media/platform/msm/camera_v2/pproc/cpp/msm_cpp.c b/drivers/media/platform/msm/camera_v2/pproc/cpp/msm_cpp.c
index 1ff4941..2214a8d 100644
--- a/drivers/media/platform/msm/camera_v2/pproc/cpp/msm_cpp.c
+++ b/drivers/media/platform/msm/camera_v2/pproc/cpp/msm_cpp.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2013-2014, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2013-2014, 2016 The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -1695,6 +1695,11 @@
 	struct msm_camera_v4l2_ioctl_t *ioctl_ptr)
 {
 	int ret;
+	if ((ioctl_ptr->ioctl_ptr == NULL) || (ioctl_ptr->len == 0)) {
+		pr_err("%s: Wrong ioctl_ptr %p / len %zu\n", __func__,
+			ioctl_ptr, ioctl_ptr->len);
+		return -EINVAL;
+	}
 
 	/* For compat task, source ptr is in kernel space */
 	if (is_compat_task()) {
@@ -1714,6 +1719,12 @@
 {
 	int ret;
 
+	if ((ioctl_ptr->ioctl_ptr == NULL) || (ioctl_ptr->len == 0)) {
+		pr_err("%s: Wrong ioctl_ptr %p / len %zu\n", __func__,
+			ioctl_ptr, ioctl_ptr->len);
+		return -EINVAL;
+	}
+
 	ret = copy_from_user(dst_ptr,
 		(void __user *)ioctl_ptr->ioctl_ptr, ioctl_ptr->len);
 	if (ret)
@@ -2046,6 +2057,10 @@
 		struct msm_pproc_queue_buf_info queue_buf_info;
 		CPP_DBG("VIDIOC_MSM_CPP_QUEUE_BUF\n");
 
+		if (ioctl_ptr->len != sizeof(struct msm_pproc_queue_buf_info)) {
+			pr_err("%s: Not valid ioctl_ptr->len\n", __func__);
+			return -EINVAL;
+		}
 		rc = msm_cpp_copy_from_ioctl_ptr(&queue_buf_info, ioctl_ptr);
 		if (rc) {
 			ERR_COPY_FROM_USER();
diff --git a/drivers/media/platform/msm/camera_v2/sensor/actuator/msm_actuator.c b/drivers/media/platform/msm/camera_v2/sensor/actuator/msm_actuator.c
index 007411b..1092b45 100644
--- a/drivers/media/platform/msm/camera_v2/sensor/actuator/msm_actuator.c
+++ b/drivers/media/platform/msm/camera_v2/sensor/actuator/msm_actuator.c
@@ -421,12 +421,18 @@
 {
 	int16_t code_per_step = 0;
 	int16_t cur_code = 0;
-	int16_t step_index = 0, region_index = 0;
+	uint16_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");
 
+	/* validate the actuator state */
+	if (a_ctrl->actuator_state != ACTUATOR_POWER_UP) {
+		pr_err("%s:%d invalid actuator_state %d\n"
+			, __func__, __LINE__, a_ctrl->actuator_state);
+		return -EINVAL;
+	}
 	for (; data_size > 0; data_size--)
 		max_code_size *= 2;
 
@@ -458,6 +464,15 @@
 		step_boundary =
 			a_ctrl->region_params[region_index].
 			step_bound[MOVE_NEAR];
+		if (step_boundary >
+			set_info->af_tuning_params.total_steps) {
+			pr_err("invalid step_boundary = %d, max_val = %d",
+				step_boundary,
+				set_info->af_tuning_params.total_steps);
+			kfree(a_ctrl->step_position_table);
+			a_ctrl->step_position_table = NULL;
+			return -EINVAL;
+		}
 		for (; step_index <= step_boundary;
 			step_index++) {
 			cur_code += code_per_step;
diff --git a/drivers/media/platform/msm/vidc/msm_vidc.c b/drivers/media/platform/msm/vidc/msm_vidc.c
index 7470b77..0666523 100644
--- a/drivers/media/platform/msm/vidc/msm_vidc.c
+++ b/drivers/media/platform/msm/vidc/msm_vidc.c
@@ -714,11 +714,23 @@
 	return 0;
 }
 
+static bool valid_v4l2_buffer(struct v4l2_buffer *b,
+		struct msm_vidc_inst *inst) {
+	enum vidc_ports port =
+		!V4L2_TYPE_IS_MULTIPLANAR(b->type) ? MAX_PORT_NUM :
+		b->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE ? CAPTURE_PORT :
+		b->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE ? OUTPUT_PORT :
+								MAX_PORT_NUM;
+
+	return port != MAX_PORT_NUM &&
+		inst->fmts[port]->num_planes == b->length;
+}
+
 int msm_vidc_prepare_buf(void *instance, struct v4l2_buffer *b)
 {
 	struct msm_vidc_inst *inst = instance;
 
-	if (!inst || !b)
+	if (!inst || !b || !valid_v4l2_buffer(b, inst))
 		return -EINVAL;
 
 	if (!V4L2_TYPE_IS_MULTIPLANAR(b->type) || !b->length ||
@@ -879,7 +891,7 @@
 	int rc = 0;
 	int i;
 
-	if (!inst || !b)
+	if (!inst || !b || !valid_v4l2_buffer(b, inst))
 		return -EINVAL;
 
 	if (!V4L2_TYPE_IS_MULTIPLANAR(b->type) || !b->length ||
@@ -963,7 +975,7 @@
 	struct buffer_info *buffer_info = NULL;
 	int i = 0, rc = 0;
 
-	if (!inst || !b)
+	if (!inst || !b || !valid_v4l2_buffer(b, inst))
 		return -EINVAL;
 
 	if (!V4L2_TYPE_IS_MULTIPLANAR(b->type) || !b->length ||
@@ -971,7 +983,6 @@
 		dprintk(VIDC_ERR, "%s: wrong input params\n",
 				__func__);
 		return -EINVAL;
-	}
 
 	if (inst->session_type == MSM_VIDC_DECODER)
 		rc = msm_vdec_dqbuf(instance, b);
diff --git a/drivers/misc/qseecom.c b/drivers/misc/qseecom.c
index 13930a1..9e1f222 100644
--- a/drivers/misc/qseecom.c
+++ b/drivers/misc/qseecom.c
@@ -121,6 +121,7 @@
 	struct list_head                 list;
 	u32  app_id;
 	u32  ref_cnt;
+	char app_name[MAX_APP_NAME_SIZE];
 };
 
 struct qseecom_registered_kclient_list {
@@ -182,6 +183,7 @@
 	struct cdev cdev;
 	bool timer_running;
 	bool no_clock_support;
+	bool appsbl_qseecom_support;
 };
 
 struct qseecom_client_handle {
@@ -191,6 +193,7 @@
 	unsigned long user_virt_sb_base;
 	size_t sb_length;
 	struct ion_handle *ihandle;		/* Retrieve phy addr */
+	char app_name[MAX_APP_NAME_SIZE];
 };
 
 struct qseecom_listener_handle {
@@ -215,7 +218,7 @@
 };
 
 struct qseecom_sg_entry {
-	phys_addr_t phys_addr;
+	uint32_t phys_addr;
 	uint32_t len;
 };
 
@@ -353,7 +356,6 @@
 		return -EFAULT;
 
 	data->listener.id = 0;
-	data->type = QSEECOM_LISTENER_SERVICE;
 	if (!__qseecom_is_svc_unique(data, &rcvd_lstnr)) {
 		pr_err("Service is not unique and is already registered\n");
 		data->released = true;
@@ -1049,7 +1051,8 @@
 		}
 		entry->app_id = app_id;
 		entry->ref_cnt = 1;
-
+		strlcpy(entry->app_name, load_img_req.img_name,
+					MAX_APP_NAME_SIZE);
 		/* Deallocate the handle */
 		if (!IS_ERR_OR_NULL(ihandle))
 			ion_free(qseecom.ion_clnt, ihandle);
@@ -1063,6 +1066,8 @@
 		(char *)(load_img_req.img_name));
 	}
 	data->client.app_id = app_id;
+	strlcpy(data->client.app_name, load_img_req.img_name,
+					MAX_APP_NAME_SIZE);
 	load_img_req.app_id = app_id;
 	if (copy_to_user(argp, &load_img_req, sizeof(load_img_req))) {
 		pr_err("copy_to_user failed\n");
@@ -1107,50 +1112,60 @@
 	return ret;
 }
 
-static int qseecom_unload_app(struct qseecom_dev_handle *data)
+static int qseecom_unload_app(struct qseecom_dev_handle *data,
+				bool app_crash)
 {
 	unsigned long flags;
+	unsigned long flags1;
 	int ret = 0;
 	struct qseecom_command_scm_resp resp;
-	struct qseecom_registered_app_list *ptr_app;
+	struct qseecom_registered_app_list *ptr_app = NULL;
 	bool unload = false;
 	bool found_app = false;
+	bool found_dead_app = false;
+
+	if (!memcmp(data->client.app_name, "keymaste", strlen("keymaste"))) {
+		pr_debug("Do not unload keymaster app from tz\n");
+		goto unload_exit;
+	}
 
 	if (data->client.app_id > 0) {
 		spin_lock_irqsave(&qseecom.registered_app_list_lock, flags);
 		list_for_each_entry(ptr_app, &qseecom.registered_app_list_head,
-								list) {
+									list) {
 			if (ptr_app->app_id == data->client.app_id) {
-				found_app = true;
-				if (ptr_app->ref_cnt == 1) {
-					unload = true;
+				if (!memcmp((void *)ptr_app->app_name,
+					(void *)data->client.app_name,
+					strlen(data->client.app_name))) {
+					found_app = true;
+					if (app_crash || ptr_app->ref_cnt == 1)
+						unload = true;
 					break;
 				} else {
-					ptr_app->ref_cnt--;
-					pr_debug("Can't unload app(%d) inuse\n",
-							ptr_app->app_id);
+					found_dead_app = true;
 					break;
 				}
 			}
 		}
 		spin_unlock_irqrestore(&qseecom.registered_app_list_lock,
 								flags);
-		if (found_app == false) {
-			pr_err("Cannot find app with id = %d\n",
-						data->client.app_id);
+		if (found_app == false && found_dead_app == false) {
+			pr_err("Cannot find app with id = %d (%s)\n",
+				data->client.app_id,
+				(char *)data->client.app_name);
 			return -EINVAL;
 		}
 	}
 
+	if (found_dead_app) {
+		pr_warn("cleanup app_id %d(%s)\n", data->client.app_id,
+			(char *)data->client.app_name);
+		__qseecom_cleanup_app(data);
+	}
+
 	if (unload) {
 		struct qseecom_unload_app_ireq req;
 
-		__qseecom_cleanup_app(data);
-		spin_lock_irqsave(&qseecom.registered_app_list_lock, flags);
-		list_del(&ptr_app->list);
-		kzfree(ptr_app);
-		spin_unlock_irqrestore(&qseecom.registered_app_list_lock,
-								flags);
 		/* Populate the structure for sending scm call to load image */
 		req.qsee_cmd_id = QSEOS_APP_SHUTDOWN_COMMAND;
 		req.app_id = data->client.app_id;
@@ -1161,20 +1176,54 @@
 				&resp, sizeof(resp));
 		if (ret) {
 			pr_err("scm_call to unload app (id = %d) failed\n",
-							req.app_id);
+								req.app_id);
 			return -EFAULT;
 		} else {
 			pr_warn("App id %d now unloaded\n", req.app_id);
 		}
+
+		if (resp.result == QSEOS_RESULT_FAILURE) {
+			pr_err("app (%d) unload_failed!!\n",
+					data->client.app_id);
+			return -EFAULT;
+		}
+		if (resp.result == QSEOS_RESULT_SUCCESS)
+			pr_debug("App (%d) is unloaded!!\n",
+					data->client.app_id);
+		__qseecom_cleanup_app(data);
 		if (resp.result == QSEOS_RESULT_INCOMPLETE) {
 			ret = __qseecom_process_incomplete_cmd(data, &resp);
 			if (ret) {
 				pr_err("process_incomplete_cmd fail err: %d\n",
-						ret);
+									ret);
 				return ret;
 			}
 		}
 	}
+
+	if (found_app) {
+		spin_lock_irqsave(&qseecom.registered_app_list_lock, flags1);
+		if (app_crash) {
+			ptr_app->ref_cnt = 0;
+			pr_debug("app_crash: ref_count = 0\n");
+		} else {
+			if (ptr_app->ref_cnt == 1) {
+				ptr_app->ref_cnt = 0;
+				pr_debug("ref_count set to 0\n");
+			} else {
+				ptr_app->ref_cnt--;
+				pr_debug("Can't unload app(%d) inuse\n",
+					ptr_app->app_id);
+			}
+		}
+		if (unload) {
+			list_del(&ptr_app->list);
+			kzfree(ptr_app);
+		}
+		spin_unlock_irqrestore(&qseecom.registered_app_list_lock,
+								flags1);
+	}
+unload_exit:
 	qseecom_unmap_ion_allocated_memory(data);
 	data->released = true;
 	return ret;
@@ -1525,6 +1574,32 @@
 	u32 reqd_len_sb_in = 0;
 	struct qseecom_client_send_data_ireq send_data_req;
 	struct qseecom_command_scm_resp resp;
+	unsigned long flags;
+	struct qseecom_registered_app_list *ptr_app;
+	bool found_app = false;
+	int name_len = 0;
+
+	reqd_len_sb_in = req->cmd_req_len + req->resp_len;
+	/* find app_id & img_name from list */
+	spin_lock_irqsave(&qseecom.registered_app_list_lock, flags);
+	list_for_each_entry(ptr_app, &qseecom.registered_app_list_head,
+							list) {
+		name_len = min(strlen(data->client.app_name),
+				strlen(ptr_app->app_name));
+		if ((ptr_app->app_id == data->client.app_id) &&
+			 (!memcmp(ptr_app->app_name,
+				data->client.app_name, name_len))) {
+			found_app = true;
+			break;
+		}
+	}
+	spin_unlock_irqrestore(&qseecom.registered_app_list_lock, flags);
+
+	if (!found_app) {
+		pr_err("app_id %d (%s) is not found\n", data->client.app_id,
+			(char *)data->client.app_name);
+		return -EINVAL;
+	}
 
 	send_data_req.qsee_cmd_id = QSEOS_CLIENT_SEND_DATA_COMMAND;
 	send_data_req.app_id = data->client.app_id;
@@ -2283,6 +2358,16 @@
 	size_t len;
 	ion_phys_addr_t pa;
 
+	if (!app_name) {
+		pr_err("failed to get the app name\n");
+		return -EINVAL;
+	}
+	if (strlen(app_name) >= MAX_APP_NAME_SIZE) {
+		pr_err("The app_name (%s) with length %zu is not valid\n",
+			app_name, strlen(app_name));
+		return -EINVAL;
+	}
+
 	*handle = kzalloc(sizeof(struct qseecom_handle), GFP_KERNEL);
 	if (!(*handle)) {
 		pr_err("failed to allocate memory for kernel client handle\n");
@@ -2363,6 +2448,7 @@
 		if (ret < 0)
 			goto err;
 		data->client.app_id = ret;
+		strlcpy(data->client.app_name, app_name, MAX_APP_NAME_SIZE);
 	}
 	if (!found_app) {
 		entry = kmalloc(sizeof(*entry), GFP_KERNEL);
@@ -2373,6 +2459,7 @@
 		}
 		entry->app_id = ret;
 		entry->ref_cnt = 1;
+		strlcpy(entry->app_name, app_name, MAX_APP_NAME_SIZE);
 
 		spin_lock_irqsave(&qseecom.registered_app_list_lock, flags);
 		list_add_tail(&entry->list, &qseecom.registered_app_list_head);
@@ -2436,6 +2523,9 @@
 		return -EINVAL;
 	}
 	data =	(struct qseecom_dev_handle *) ((*handle)->dev);
+	mutex_lock(&app_access_lock);
+	atomic_inc(&data->ioctl_count);
+
 	spin_lock_irqsave(&qseecom.registered_kclient_list_lock, flags);
 	list_for_each_entry(kclient, &qseecom.registered_kclient_list_head,
 				list) {
@@ -2449,7 +2539,7 @@
 	if (!found_handle)
 		pr_err("Unable to find the handle, exiting\n");
 	else
-		ret = qseecom_unload_app(data);
+		ret = qseecom_unload_app(data, false);
 
 	if (qseecom.support_bus_scaling) {
 		mutex_lock(&qsee_bw_mutex);
@@ -2468,12 +2558,16 @@
 		if (data->perf_enabled == true)
 			qsee_disable_clock_vote(data, CLK_DFAB);
 	}
+
+	atomic_dec(&data->ioctl_count);
+	mutex_unlock(&app_access_lock);
 	if (ret == 0) {
 		kzfree(data);
 		kzfree(*handle);
 		kzfree(kclient);
 		*handle = NULL;
 	}
+
 	return ret;
 }
 EXPORT_SYMBOL(qseecom_shutdown_app);
@@ -2632,7 +2726,7 @@
 	}
 	resp.resp_buf_ptr = this_lstnr->sb_virt +
 		(uintptr_t)(resp.resp_buf_ptr - this_lstnr->user_virt_sb_base);
-	__qseecom_update_cmd_buf(&resp, false, data, true);
+	__qseecom_update_cmd_buf(&resp, false, data, false);
 	qseecom.send_resp_flag = 1;
 	wake_up_interruptible(&qseecom.send_resp_wq);
 	return 0;
@@ -2659,16 +2753,19 @@
 static int __qseecom_enable_clk(enum qseecom_ce_hw_instance ce)
 {
 	int rc = 0;
-	struct qseecom_clk *qclk;
+	struct qseecom_clk *qclk = NULL;
 
 	if (qseecom.no_clock_support)
 		return 0;
 
 	if (ce == CLK_QSEE)
 		qclk = &qseecom.qsee;
-	else
+	if (ce == CLK_CE_DRV)
 		qclk = &qseecom.ce_drv;
-
+	if (qclk == NULL) {
+		pr_err("CLK type not supported\n");
+		return -EINVAL;
+	}
 	mutex_lock(&clk_access_lock);
 
 	if (qclk->clk_access_cnt == ULONG_MAX)
@@ -2681,31 +2778,39 @@
 	}
 
 	/* Enable CE core clk */
-	rc = clk_prepare_enable(qclk->ce_core_clk);
-	if (rc) {
-		pr_err("Unable to enable/prepare CE core clk\n");
-		goto err;
+	if (qclk->ce_core_clk != NULL) {
+		rc = clk_prepare_enable(qclk->ce_core_clk);
+		if (rc) {
+			pr_err("Unable to enable/prepare CE core clk\n");
+			goto err;
+		}
 	}
 	/* Enable CE clk */
-	rc = clk_prepare_enable(qclk->ce_clk);
-	if (rc) {
-		pr_err("Unable to enable/prepare CE iface clk\n");
-		goto ce_clk_err;
+	if (qclk->ce_clk != NULL) {
+		rc = clk_prepare_enable(qclk->ce_clk);
+		if (rc) {
+			pr_err("Unable to enable/prepare CE iface clk\n");
+			goto ce_clk_err;
+		}
 	}
 	/* Enable AXI clk */
-	rc = clk_prepare_enable(qclk->ce_bus_clk);
-	if (rc) {
-		pr_err("Unable to enable/prepare CE bus clk\n");
-		goto ce_bus_clk_err;
+	if (qclk->ce_bus_clk != NULL) {
+		rc = clk_prepare_enable(qclk->ce_bus_clk);
+		if (rc) {
+			pr_err("Unable to enable/prepare CE bus clk\n");
+			goto ce_bus_clk_err;
+		}
 	}
 	qclk->clk_access_cnt++;
 	mutex_unlock(&clk_access_lock);
 	return 0;
 
 ce_bus_clk_err:
-	clk_disable_unprepare(qclk->ce_clk);
+	if (qclk->ce_clk != NULL)
+		clk_disable_unprepare(qclk->ce_clk);
 ce_clk_err:
-	clk_disable_unprepare(qclk->ce_core_clk);
+	if (qclk->ce_core_clk != NULL)
+		clk_disable_unprepare(qclk->ce_core_clk);
 err:
 	mutex_unlock(&clk_access_lock);
 	return -EIO;
@@ -3103,6 +3208,7 @@
 	struct qseecom_check_app_ireq req;
 	struct qseecom_registered_app_list *entry = NULL;
 	unsigned long flags = 0;
+	bool found_app = false;
 
 	/* Copy the relevant information needed for loading the image */
 	if (copy_from_user(&query_req,
@@ -3129,6 +3235,7 @@
 				&qseecom.registered_app_list_head, list){
 			if (entry->app_id == ret) {
 				entry->ref_cnt++;
+				found_app = true;
 				break;
 			}
 		}
@@ -3136,7 +3243,31 @@
 				&qseecom.registered_app_list_lock, flags);
 		data->client.app_id = ret;
 		query_req.app_id = ret;
-
+		strlcpy(data->client.app_name, query_req.app_name,
+				MAX_APP_NAME_SIZE);
+		/*
+		 * If app was loaded by appsbl or kernel client before
+		 * and was not registered, regiser this app now.
+		 */
+		if (!found_app) {
+			pr_debug("Register app %d [%s] which was loaded before\n",
+					ret, (char *)query_req.app_name);
+			entry = kmalloc(sizeof(*entry), GFP_KERNEL);
+			if (!entry) {
+				pr_err("kmalloc for app entry failed\n");
+				return  -ENOMEM;
+			}
+			entry->app_id = ret;
+			entry->ref_cnt = 1;
+			strlcpy(entry->app_name, data->client.app_name,
+				MAX_APP_NAME_SIZE);
+			spin_lock_irqsave(&qseecom.registered_app_list_lock,
+				flags);
+			list_add_tail(&entry->list,
+				&qseecom.registered_app_list_head);
+			spin_unlock_irqrestore(
+				&qseecom.registered_app_list_lock, flags);
+		}
 		if (copy_to_user(argp, &query_req, sizeof(query_req))) {
 			pr_err("copy_to_user failed\n");
 			return -EFAULT;
@@ -4141,7 +4272,7 @@
 		pr_debug("UNLOAD_APP: qseecom_addr = 0x%p\n", data);
 		mutex_lock(&app_access_lock);
 		atomic_inc(&data->ioctl_count);
-		ret = qseecom_unload_app(data);
+		ret = qseecom_unload_app(data, false);
 		atomic_dec(&data->ioctl_count);
 		mutex_unlock(&app_access_lock);
 		if (ret)
@@ -4497,6 +4628,7 @@
 	data->abort = 0;
 	data->type = QSEECOM_GENERIC;
 	data->released = false;
+	memset((void *)data->client.app_name, 0, MAX_APP_NAME_SIZE);
 	data->mode = INACTIVE;
 	init_waitqueue_head(&data->abort_wq);
 	atomic_set(&data->ioctl_count, 0);
@@ -4517,13 +4649,13 @@
 			ret = qseecom_unregister_listener(data);
 			break;
 		case QSEECOM_CLIENT_APP:
-			ret = qseecom_unload_app(data);
+			ret = qseecom_unload_app(data, true);
 			break;
 		case QSEECOM_SECURE_SERVICE:
 		case QSEECOM_GENERIC:
 			ret = qseecom_unmap_ion_allocated_memory(data);
 			if (ret)
-				pr_err("Close failed\n");
+				pr_err("Ion Unmap failed\n");
 			break;
 		case QSEECOM_UNAVAILABLE_CLIENT_APP:
 			break;
@@ -4599,6 +4731,15 @@
 		pr_err("Invalid ce hw instance: %d!\n", ce);
 		return -EIO;
 	}
+
+	if (qseecom.no_clock_support) {
+		qclk->ce_core_clk = NULL;
+		qclk->ce_clk = NULL;
+		qclk->ce_bus_clk = NULL;
+		qclk->ce_core_src_clk = NULL;
+		return 0;
+	}
+
 	pdev = qseecom.pdev;
 
 	/* Get CE3 src core clk. */
@@ -4608,6 +4749,7 @@
 		rc = clk_set_rate(qclk->ce_core_src_clk, QSEE_CE_CLK_100MHZ);
 		if (rc) {
 			clk_put(qclk->ce_core_src_clk);
+			qclk->ce_core_src_clk = NULL;
 			pr_err("Unable to set the core src clk @100Mhz.\n");
 			return -EIO;
 		}
@@ -4615,8 +4757,6 @@
 		pr_warn("Unable to get CE core src clk, set to NULL\n");
 		qclk->ce_core_src_clk = NULL;
 	}
-	if (qseecom.no_clock_support)
-		return 0;
 	/* Get CE core clk */
 	qclk->ce_core_clk = clk_get(pdev, core_clk);
 	if (IS_ERR(qclk->ce_core_clk)) {
@@ -4649,6 +4789,7 @@
 		clk_put(qclk->ce_clk);
 		return -EIO;
 	}
+
 	return rc;
 }
 
@@ -4849,6 +4990,12 @@
 			qseecom.ce_info.qsee_ce_hw_instance);
 		}
 
+		qseecom.appsbl_qseecom_support =
+				of_property_read_bool((&pdev->dev)->of_node,
+						"qcom,appsbl-qseecom-support");
+		pr_info("qseecom.appsbl_qseecom_support = 0x%x",
+				qseecom.appsbl_qseecom_support);
+
 		qseecom.no_clock_support =
 				of_property_read_bool((&pdev->dev)->of_node,
 						"qcom,no-clock-support");
@@ -4885,7 +5032,8 @@
 
 		qseecom_platform_support = (struct msm_bus_scale_pdata *)
 						msm_bus_cl_get_pdata(pdev);
-		if (qseecom.qsee_version >= (QSEE_VERSION_02)) {
+		if (qseecom.qsee_version >= (QSEE_VERSION_02) &&
+			!qseecom.appsbl_qseecom_support) {
 			struct resource *resource = NULL;
 			struct qsee_apps_region_info_ireq req;
 			struct qseecom_command_scm_resp resp;
@@ -4912,6 +5060,8 @@
 				goto exit_destroy_ion_client;
 			}
 		}
+		if(qseecom.appsbl_qseecom_support)
+			qseecom.commonlib_loaded = true;
 	} else {
 		qseecom_platform_support = (struct msm_bus_scale_pdata *)
 						pdev->dev.platform_data;
@@ -4965,7 +5115,7 @@
 			goto exit_free_kc_handle;
 
 		list_del(&kclient->list);
-		ret = qseecom_unload_app(kclient->handle->dev);
+		ret = qseecom_unload_app(kclient->handle->dev, false);
 		if (!ret) {
 			kzfree(kclient->handle->dev);
 			kzfree(kclient->handle);
@@ -5080,26 +5230,29 @@
 	}
 
 	if (qclk->clk_access_cnt) {
-
-		ret = clk_prepare_enable(qclk->ce_core_clk);
-		if (ret) {
-			pr_err("Unable to enable/prepare CE core clk\n");
-			qclk->clk_access_cnt = 0;
-			goto err;
+		if (qclk->ce_core_clk != NULL) {
+			ret = clk_prepare_enable(qclk->ce_core_clk);
+			if (ret) {
+				pr_err("Unable to enable/prep CE core clk\n");
+				qclk->clk_access_cnt = 0;
+				goto err;
+			}
 		}
-
-		ret = clk_prepare_enable(qclk->ce_clk);
-		if (ret) {
-			pr_err("Unable to enable/prepare CE iface clk\n");
-			qclk->clk_access_cnt = 0;
-			goto ce_clk_err;
+		if (qclk->ce_clk != NULL) {
+			ret = clk_prepare_enable(qclk->ce_clk);
+			if (ret) {
+				pr_err("Unable to enable/prep CE iface clk\n");
+				qclk->clk_access_cnt = 0;
+				goto ce_clk_err;
+			}
 		}
-
-		ret = clk_prepare_enable(qclk->ce_bus_clk);
-		if (ret) {
-			pr_err("Unable to enable/prepare CE bus clk\n");
-			qclk->clk_access_cnt = 0;
-			goto ce_bus_clk_err;
+		if (qclk->ce_bus_clk != NULL) {
+			ret = clk_prepare_enable(qclk->ce_bus_clk);
+			if (ret) {
+				pr_err("Unable to enable/prep CE bus clk\n");
+				qclk->clk_access_cnt = 0;
+				goto ce_bus_clk_err;
+			}
 		}
 	}
 
diff --git a/drivers/platform/msm/ipa/rmnet_ipa.c b/drivers/platform/msm/ipa/rmnet_ipa.c
index 5d02833..ba48b94 100644
--- a/drivers/platform/msm/ipa/rmnet_ipa.c
+++ b/drivers/platform/msm/ipa/rmnet_ipa.c
@@ -1175,6 +1175,11 @@
 					rmnet_mux_val.mux_id);
 				return rc;
 			}
+			if (rmnet_index >= MAX_NUM_OF_MUX_CHANNEL) {
+				IPAWANERR("Exceed mux_channel limit(%d)\n",
+				rmnet_index);
+				return -EFAULT;
+			}
 			IPAWANDBG("ADD_MUX_CHANNEL(%d, name: %s)\n",
 			extend_ioctl_data.u.rmnet_mux_val.mux_id,
 			extend_ioctl_data.u.rmnet_mux_val.vchannel_name);
diff --git a/drivers/platform/msm/msm_bus/msm_buspm_coresight_adhoc.c b/drivers/platform/msm/msm_bus/msm_buspm_coresight_adhoc.c
index c154878..61a4e27 100644
--- a/drivers/platform/msm/msm_bus/msm_buspm_coresight_adhoc.c
+++ b/drivers/platform/msm/msm_bus/msm_buspm_coresight_adhoc.c
@@ -135,6 +135,7 @@
 		return PTR_ERR(pdata);
 
 	drvdata = platform_get_drvdata(pdev);
+	dev_dbg(dev, "info: removed buspm module from kernel space\n");
 	if (IS_ERR_OR_NULL(drvdata)) {
 		drvdata = devm_kzalloc(dev, sizeof(*drvdata), GFP_KERNEL);
 		if (!drvdata) {
diff --git a/drivers/regulator/rpm-smd-regulator.c b/drivers/regulator/rpm-smd-regulator.c
index 3067a0b..f4d9cf2 100644
--- a/drivers/regulator/rpm-smd-regulator.c
+++ b/drivers/regulator/rpm-smd-regulator.c
@@ -893,6 +893,19 @@
 	return reg->rpm_vreg->enable_time;
 }
 
+static int rpm_vreg_send_defaults(struct rpm_regulator *reg)
+{
+	int rc;
+
+	rpm_vreg_lock(reg->rpm_vreg);
+	rc = rpm_vreg_aggregate_requests(reg);
+	if (rc)
+		vreg_err(reg, "RPM request failed, rc=%d", rc);
+	rpm_vreg_unlock(reg->rpm_vreg);
+
+	return rc;
+}
+
 /**
  * rpm_regulator_get() - lookup and obtain a handle to an RPM regulator
  * @dev: device for regulator consumer
@@ -1500,6 +1513,14 @@
 	list_add(&reg->list, &rpm_vreg->reg_list);
 	rpm_vreg_unlock(rpm_vreg);
 
+	if (of_property_read_bool(node, "qcom,send-defaults")) {
+		rc = rpm_vreg_send_defaults(reg);
+		if (rc) {
+			vreg_err(reg, "could not send defaults, rc=%d\n", rc);
+			goto fail_remove_from_list;
+		}
+	}
+
 	reg_config.dev = dev;
 	reg_config.init_data = init_data;
 	reg_config.of_node = node;
diff --git a/drivers/soc/qcom/bam_dmux.c b/drivers/soc/qcom/bam_dmux.c
index b183334..1654bdb 100644
--- a/drivers/soc/qcom/bam_dmux.c
+++ b/drivers/soc/qcom/bam_dmux.c
@@ -271,7 +271,6 @@
 static DEFINE_MUTEX(smsm_cb_lock);
 static DEFINE_MUTEX(delayed_ul_vote_lock);
 static int need_delayed_ul_vote;
-static int in_ssr;
 static int ssr_skipped_disconnect;
 static struct completion shutdown_completion;
 
@@ -1952,8 +1951,11 @@
 {
 	int i;
 
-	in_global_reset = 0;
-	in_ssr = 0;
+	if (in_global_reset) {
+		BAM_DMUX_LOG("%s: skipping due to SSR\n", __func__);
+		return;
+	}
+
 	vote_dfab();
 
 	if (ssr_skipped_disconnect) {
@@ -2029,8 +2031,8 @@
 	/* tear down BAM connection */
 	INIT_COMPLETION(bam_connection_completion);
 
-	/* in_ssr documentation/assumptions found in restart_notifier_cb */
-	if (likely(!in_ssr)) {
+	/* documentation/assumptions found in restart_notifier_cb */
+	if (likely(!in_global_reset)) {
 		BAM_DMUX_LOG("%s: disconnect tx\n", __func__);
 		bam_ops->sps_disconnect_ptr(bam_tx_pipe);
 		BAM_DMUX_LOG("%s: disconnect rx\n", __func__);
@@ -2164,12 +2166,13 @@
 	if (code == SUBSYS_BEFORE_SHUTDOWN) {
 		BAM_DMUX_LOG("%s: begin\n", __func__);
 		in_global_reset = 1;
-		in_ssr = 1;
-		/* wait till all bam_dmux writes completes */
+		/* sync to ensure the driver sees SSR */
 		synchronize_srcu(&bam_dmux_srcu);
 		BAM_DMUX_LOG("%s: ssr signaling complete\n", __func__);
 		flush_workqueue(bam_mux_rx_workqueue);
 	}
+	if (code == SUBSYS_BEFORE_POWERUP)
+		in_global_reset = 0;
 	if (code != SUBSYS_AFTER_SHUTDOWN)
 		return NOTIFY_DONE;
 
@@ -2242,6 +2245,7 @@
 	void *a2_virt_addr;
 	int skip_iounmap = 0;
 
+	in_global_reset = 0;
 	vote_dfab();
 	/* init BAM */
 	a2_virt_addr = ioremap_nocache(a2_phys_base, a2_phys_size);
@@ -2431,7 +2435,9 @@
 static void bam_dmux_smsm_cb(void *priv, uint32_t old_state, uint32_t new_state)
 {
 	static int last_processed_state;
+	int rcu_id;
 
+	rcu_id = srcu_read_lock(&bam_dmux_srcu);
 	mutex_lock(&smsm_cb_lock);
 	bam_dmux_power_state = new_state & SMSM_A2_POWER_CONTROL ? 1 : 0;
 	DBG_INC_A2_POWER_CONTROL_IN_CNT();
@@ -2440,6 +2446,7 @@
 	if (last_processed_state == (new_state & SMSM_A2_POWER_CONTROL)) {
 		BAM_DMUX_LOG("%s: already processed this state\n", __func__);
 		mutex_unlock(&smsm_cb_lock);
+		srcu_read_unlock(&bam_dmux_srcu, rcu_id);
 		return;
 	}
 
@@ -2463,16 +2470,20 @@
 		pr_err("%s: unsupported state change\n", __func__);
 	}
 	mutex_unlock(&smsm_cb_lock);
-
+	srcu_read_unlock(&bam_dmux_srcu, rcu_id);
 }
 
 static void bam_dmux_smsm_ack_cb(void *priv, uint32_t old_state,
 						uint32_t new_state)
 {
+	int rcu_id;
+
+	rcu_id = srcu_read_lock(&bam_dmux_srcu);
 	DBG_INC_ACK_IN_CNT();
 	BAM_DMUX_LOG("%s: 0x%08x -> 0x%08x\n", __func__, old_state,
 			new_state);
 	complete_all(&ul_wakeup_ack_completion);
+	srcu_read_unlock(&bam_dmux_srcu, rcu_id);
 }
 
 /**
@@ -2501,8 +2512,9 @@
 {
 	restart_notifier_cb(NULL, SUBSYS_BEFORE_SHUTDOWN, NULL);
 	restart_notifier_cb(NULL, SUBSYS_AFTER_SHUTDOWN, NULL);
+	restart_notifier_cb(NULL, SUBSYS_BEFORE_POWERUP, NULL);
+	restart_notifier_cb(NULL, SUBSYS_AFTER_POWERUP, NULL);
 	in_global_reset = 0;
-	in_ssr = 0;
 }
 EXPORT_SYMBOL(msm_bam_dmux_deinit);
 
diff --git a/drivers/soc/qcom/socinfo.c b/drivers/soc/qcom/socinfo.c
index a7fa903..68f692f 100644
--- a/drivers/soc/qcom/socinfo.c
+++ b/drivers/soc/qcom/socinfo.c
@@ -111,6 +111,7 @@
 	PLATFORM_SUBTYPE_STRANGE_2A = 0x3,
 	PLATFORM_SUBTYPE_QVGA = 0x4,
 	PLATFORM_SUBTYPE_G_QVGA = 0x5,
+	PLATFORM_SUBTYPE_JDI_QVGA = 0x6,
 	PLATFORM_SUBTYPE_INVALID,
 };
 
@@ -121,6 +122,7 @@
 	[PLATFORM_SUBTYPE_STRANGE_2A] = "strange_2a,",
 	[PLATFORM_SUBTYPE_QVGA] = "qvga",
 	[PLATFORM_SUBTYPE_G_QVGA] = "qvga_g",
+	[PLATFORM_SUBTYPE_JDI_QVGA] = "jdi_qvga",
 };
 
 /* Used to parse shared memory.  Must match the modem. */
diff --git a/drivers/thermal/msm_thermal-dev.c b/drivers/thermal/msm_thermal-dev.c
index 0acde30..6328cd7 100644
--- a/drivers/thermal/msm_thermal-dev.c
+++ b/drivers/thermal/msm_thermal-dev.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2013-2014, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2013-2014, 2016 The Linux Foundation. All rights reserved.
  *
  * This program is free software; 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/composite.c b/drivers/usb/gadget/composite.c
index eaa87cf..e2f63a2 100644
--- a/drivers/usb/gadget/composite.c
+++ b/drivers/usb/gadget/composite.c
@@ -430,7 +430,7 @@
 			func->name ? func->name : "");
 		func->func_wakeup_pending = true;
 		ret = 0;
-	} else if (ret < 0) {
+	} else if (ret < 0 && ret != -ENOTSUPP) {
 		ERROR(func->config->cdev,
 			"Failed to wake function %s from suspend state. ret=%d. Canceling USB request.\n",
 			func->name ? func->name : "", ret);
@@ -1915,7 +1915,7 @@
 						"Function wakeup for %s could not complete due to suspend state.\n",
 						f->name ? f->name : "");
 					break;
-				} else {
+				} else if (ret != -ENOTSUPP) {
 					ERROR(f->config->cdev,
 						"Failed to wake function %s from suspend state. ret=%d. Canceling USB request.\n",
 						f->name ? f->name : "",
diff --git a/drivers/usb/gadget/f_serial.c b/drivers/usb/gadget/f_serial.c
index 7190194..c51c5b8 100644
--- a/drivers/usb/gadget/f_serial.c
+++ b/drivers/usb/gadget/f_serial.c
@@ -1358,6 +1358,13 @@
 		smd_port_num =
 			gserial_ports[gser->port_num].client_port_num;
 
+		if (smd_write_arg.size > GSERIAL_BUF_LEN) {
+			pr_err("%s: Invalid size:%u, max: %u", __func__,
+				smd_write_arg.size, GSERIAL_BUF_LEN);
+			ret = -EINVAL;
+			break;
+		}
+
 		pr_debug("%s: Copying %d bytes from user buffer to local\n",
 			__func__, smd_write_arg.size);
 
diff --git a/drivers/video/msm/mdss/Makefile b/drivers/video/msm/mdss/Makefile
index 0c14e8b..de19866 100644
--- a/drivers/video/msm/mdss/Makefile
+++ b/drivers/video/msm/mdss/Makefile
@@ -1,3 +1,5 @@
+ccflags-y += -I$(src)
+
 mdss-mdp3-objs = mdp3.o mdp3_dma.o mdp3_ctrl.o dsi_status_v2.o
 mdss-mdp3-objs += mdp3_ppp.o mdp3_ppp_hwio.o mdp3_ppp_data.o
 obj-$(CONFIG_FB_MSM_MDSS_MDP3) += mdss-mdp3.o
diff --git a/drivers/video/msm/mdss/dsi_status_6g.c b/drivers/video/msm/mdss/dsi_status_6g.c
index bb16d8f..6d9986c 100644
--- a/drivers/video/msm/mdss/dsi_status_6g.c
+++ b/drivers/video/msm/mdss/dsi_status_6g.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2013-2014, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2013-2015, The Linux Foundation. All rights reserved.
  *
  * This program is free software; 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/dsi_v2.c b/drivers/video/msm/mdss/dsi_v2.c
index e364859..ea20432 100644
--- a/drivers/video/msm/mdss/dsi_v2.c
+++ b/drivers/video/msm/mdss/dsi_v2.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012-2014, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2012-2015, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -333,7 +333,7 @@
 				__func__, rc);
 			goto error;
 		}
-		mp->vreg_config[i].enable_load = tmp;
+		mp->vreg_config[i].load[DSS_REG_MODE_ENABLE] = tmp;
 
 		/* disable-load */
 		rc = of_property_read_u32(supply_node,
@@ -343,7 +343,7 @@
 				__func__, rc);
 			goto error;
 		}
-		mp->vreg_config[i].disable_load = tmp;
+		mp->vreg_config[i].load[DSS_REG_MODE_DISABLE] = tmp;
 
 		/* pre-sleep */
 		rc = of_property_read_u32(supply_node,
@@ -392,8 +392,8 @@
 			mp->vreg_config[i].vreg_name,
 			mp->vreg_config[i].min_voltage,
 			mp->vreg_config[i].max_voltage,
-			mp->vreg_config[i].enable_load,
-			mp->vreg_config[i].disable_load,
+			mp->vreg_config[i].load[DSS_REG_MODE_ENABLE],
+			mp->vreg_config[i].load[DSS_REG_MODE_DISABLE],
 			mp->vreg_config[i].pre_on_sleep,
 			mp->vreg_config[i].post_on_sleep,
 			mp->vreg_config[i].pre_off_sleep,
diff --git a/drivers/video/msm/mdss/mdss_debug.c b/drivers/video/msm/mdss/mdss_debug.c
index 8778aff..dabc726 100644
--- a/drivers/video/msm/mdss/mdss_debug.c
+++ b/drivers/video/msm/mdss/mdss_debug.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2009-2015, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2009-2016, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -90,7 +90,7 @@
 {
 	struct mdss_debug_base *dbg = file->private_data;
 	int len = 0;
-	char buf[24];
+	char buf[24] = {'\0'};
 
 	if (!dbg)
 		return -ENODEV;
@@ -99,10 +99,10 @@
 		return 0;	/* the end */
 
 	len = snprintf(buf, sizeof(buf), "0x%08zx %zx\n", dbg->off, dbg->cnt);
-	if (len < 0)
+	if (len < 0 || len >= sizeof(buf))
 		return 0;
 
-	if (copy_to_user(buff, buf, len))
+	if ((count < sizeof(buf)) || copy_to_user(buff, buf, len))
 		return -EFAULT;
 
 	*ppos += len;	/* increase offset */
@@ -333,7 +333,7 @@
 {
 	struct mdss_fudge_factor *factor = file->private_data;
 	int len = 0;
-	char buf[32];
+	char buf[32] = {'\0'};
 
 	if (!factor)
 		return -ENODEV;
@@ -343,10 +343,10 @@
 
 	len = snprintf(buf, sizeof(buf), "%d/%d\n",
 			factor->numer, factor->denom);
-	if (len < 0)
+	if (len < 0 || len >= sizeof(buf))
 		return 0;
 
-	if (copy_to_user(buff, buf, len))
+	if ((count < sizeof(buf)) || copy_to_user(buff, buf, len))
 		return -EFAULT;
 
 	*ppos += len;	/* increase offset */
@@ -377,6 +377,8 @@
 	if (copy_from_user(buf, user_buf, count))
 		return -EFAULT;
 
+	buf[count] = 0;	/* end of string */
+
 	if (sscanf(buf, "%d", &perf_mode) != 1)
 		return -EFAULT;
 
@@ -397,7 +399,7 @@
 {
 	struct mdss_perf_tune *perf_tune = file->private_data;
 	int len = 0;
-	char buf[40];
+	char buf[40] = {'\0'};
 
 	if (!perf_tune)
 		return -ENODEV;
@@ -405,14 +407,12 @@
 	if (*ppos)
 		return 0;	/* the end */
 
-	buf[count] = 0;
-
 	len = snprintf(buf, sizeof(buf), "min_mdp_clk %lu min_bus_vote %llu\n",
 	perf_tune->min_mdp_clk, perf_tune->min_bus_vote);
-	if (len < 0)
+	if (len < 0 || len >= sizeof(buf))
 		return 0;
 
-	if (copy_to_user(buff, buf, len))
+	if ((count < sizeof(buf)) || copy_to_user(buff, buf, len))
 		return -EFAULT;
 
 	*ppos += len;   /* increase offset */
@@ -432,7 +432,7 @@
 {
 	struct mdss_data_type *mdata = file->private_data;
 	int len = 0;
-	char buf[40];
+	char buf[40] = {'\0'};
 
 	if (!mdata)
 		return -ENODEV;
@@ -442,10 +442,10 @@
 
 	len = snprintf(buf, sizeof(buf), "%d\n",
 		!mdata->has_panic_ctrl);
-	if (len < 0)
+	if (len < 0 || len >= sizeof(buf))
 		return 0;
 
-	if (copy_to_user(buff, buf, len))
+	if ((count < sizeof(buf)) || copy_to_user(buff, buf, len))
 		return -EFAULT;
 
 	*ppos += len;   /* increase offset */
@@ -508,9 +508,14 @@
 	if (!mdata)
 		return -EFAULT;
 
+	if (count >= sizeof(buf))
+		return -EFAULT;
+
 	if (copy_from_user(buf, user_buf, count))
 		return -EFAULT;
 
+	buf[count] = 0;	/* end of string */
+
 	if (sscanf(buf, "%d", &disable_panic) != 1)
 		return -EFAULT;
 
diff --git a/drivers/video/msm/mdss/mdss_dsi.c b/drivers/video/msm/mdss/mdss_dsi.c
index b8a49dd..c12a52e 100644
--- a/drivers/video/msm/mdss/mdss_dsi.c
+++ b/drivers/video/msm/mdss/mdss_dsi.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012-2014, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2012-2015, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -192,11 +192,56 @@
 	return 0;
 }
 
-static int mdss_dsi_panel_power_ctrl(struct mdss_panel_data *pdata,
-	int power_state)
+static int mdss_dsi_panel_power_ulp(struct mdss_panel_data *pdata,
+	int enable)
+{
+	int ret = 0, i;
+	struct mdss_dsi_ctrl_pdata *ctrl_pdata = NULL;
+	u32 mode = enable ? DSS_REG_MODE_ULP : DSS_REG_MODE_ENABLE;
+
+	pr_debug("%s: +\n", __func__);
+	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);
+
+	for (i = 0; i < DSI_MAX_PM; i++) {
+		/*
+		 * Core power module need to be controlled along with
+		 * DSI core clocks.
+		 */
+		if (DSI_CORE_PM == i)
+			continue;
+		ret = msm_dss_config_vreg_opt_mode(
+			ctrl_pdata->power_data[i].vreg_config,
+			ctrl_pdata->power_data[i].num_vreg, mode);
+		if (ret) {
+			pr_err("%s: failed to config lp opt mode for %s.rc=%d\n",
+				__func__, __mdss_dsi_pm_name(i), ret);
+			goto error;
+		}
+	}
+
+error:
+	if (ret) {
+		mode = enable ? DSS_REG_MODE_ENABLE : DSS_REG_MODE_ULP;
+		for (; i >= 0; i--)
+			msm_dss_config_vreg_opt_mode(
+				ctrl_pdata->power_data[i].vreg_config,
+				ctrl_pdata->power_data[i].num_vreg, mode);
+	}
+	pr_debug("%s: -\n", __func__);
+	return ret;
+}
+
+int mdss_dsi_panel_power_ctrl(struct mdss_panel_data *pdata, int power_state)
 {
 	int ret;
 	struct mdss_panel_info *pinfo;
+	struct mdss_dsi_ctrl_pdata *ctrl_pdata = NULL;
 
 	if (pdata == NULL) {
 		pr_err("%s: Invalid input data\n", __func__);
@@ -204,7 +249,8 @@
 	}
 
 	pinfo = &pdata->panel_info;
-	pr_debug("%s: cur_power_state=%d req_power_state=%d\n", __func__,
+	pr_debug("%pS-->%s: cur_power_state=%d req_power_state=%d\n",
+		__builtin_return_address(0), __func__,
 		pinfo->panel_power_state, power_state);
 
 	if (pinfo->panel_power_state == power_state) {
@@ -212,6 +258,9 @@
 		return 0;
 	}
 
+	ctrl_pdata = container_of(pdata, struct mdss_dsi_ctrl_pdata,
+				panel_data);
+
 	/*
 	 * If a dynamic mode switch is pending, the regulators should not
 	 * be turned off or on.
@@ -224,14 +273,29 @@
 		ret = mdss_dsi_panel_power_off(pdata);
 		break;
 	case MDSS_PANEL_POWER_ON:
-		if (mdss_dsi_is_panel_on_lp(pdata))
+		if (mdss_dsi_is_panel_on_ulp(pdata))
+			ret = mdss_dsi_panel_power_ulp(pdata, false);
+		else if (mdss_dsi_is_panel_on_lp(pdata))
 			ret = mdss_dsi_panel_power_lp(pdata, false);
 		else
 			ret = mdss_dsi_panel_power_on(pdata);
 		break;
 	case MDSS_PANEL_POWER_LP1:
+		if (mdss_dsi_is_panel_on_ulp(pdata))
+			ret = mdss_dsi_panel_power_ulp(pdata, false);
+		else
+			ret = mdss_dsi_panel_power_lp(pdata, true);
+		/*
+		 * temp workaround until framework issues pertaining to LP2
+		 * power state transitions are fixed. For now, we internally
+		 * transition to LP2 state whenever core power is turned off
+		 * in LP1 state
+		 */
 	case MDSS_PANEL_POWER_LP2:
-		ret = mdss_dsi_panel_power_lp(pdata, true);
+		if (!ctrl_pdata->core_power) {
+			power_state = MDSS_PANEL_POWER_LP2;
+			ret = mdss_dsi_panel_power_ulp(pdata, true);
+		}
 		break;
 	default:
 		pr_err("%s: unknown panel power state requested (%d)\n",
@@ -344,7 +408,7 @@
 				__func__, rc);
 			goto error;
 		}
-		mp->vreg_config[i].enable_load = tmp;
+		mp->vreg_config[i].load[DSS_REG_MODE_ENABLE] = tmp;
 
 		/* disable-load */
 		rc = of_property_read_u32(supply_node,
@@ -354,7 +418,20 @@
 				__func__, rc);
 			goto error;
 		}
-		mp->vreg_config[i].disable_load = tmp;
+		mp->vreg_config[i].load[DSS_REG_MODE_DISABLE] = tmp;
+
+		/* ulp-load */
+		rc = of_property_read_u32(supply_node,
+			"qcom,supply-ulp-load", &tmp);
+		if (rc) {
+			pr_debug("%s: error reading disable load. rc=%d\n",
+				__func__, rc);
+			rc = 0;
+		} else {
+			pr_debug("%s: ulp_load for %s=%d\n", __func__,
+				mp->vreg_config[i].vreg_name, tmp);
+			mp->vreg_config[i].load[DSS_REG_MODE_ULP] = tmp;
+		}
 
 		/* pre-sleep */
 		rc = of_property_read_u32(supply_node,
@@ -403,8 +480,8 @@
 			mp->vreg_config[i].vreg_name,
 			mp->vreg_config[i].min_voltage,
 			mp->vreg_config[i].max_voltage,
-			mp->vreg_config[i].enable_load,
-			mp->vreg_config[i].disable_load,
+			mp->vreg_config[i].load[DSS_REG_MODE_ENABLE],
+			mp->vreg_config[i].load[DSS_REG_MODE_DISABLE],
 			mp->vreg_config[i].pre_on_sleep,
 			mp->vreg_config[i].post_on_sleep,
 			mp->vreg_config[i].pre_off_sleep,
diff --git a/drivers/video/msm/mdss/mdss_dsi.h b/drivers/video/msm/mdss/mdss_dsi.h
index 794c7aa6..b1c5b38 100644
--- a/drivers/video/msm/mdss/mdss_dsi.h
+++ b/drivers/video/msm/mdss/mdss_dsi.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012-2014, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2012-2015, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -467,6 +467,7 @@
 bool __mdss_dsi_clk_enabled(struct mdss_dsi_ctrl_pdata *ctrl, u8 clk_type);
 void mdss_dsi_ctrl_setup(struct mdss_dsi_ctrl_pdata *ctrl);
 void mdss_dsi_dln0_phy_err(struct mdss_dsi_ctrl_pdata *ctrl);
+int mdss_dsi_panel_power_ctrl(struct mdss_panel_data *pdata, int power_state);
 
 int mdss_dsi_panel_init(struct device_node *node,
 		struct mdss_dsi_ctrl_pdata *ctrl_pdata,
@@ -560,6 +561,11 @@
 	return mdss_panel_is_power_on_lp(pdata->panel_info.panel_power_state);
 }
 
+static inline bool mdss_dsi_is_panel_on_ulp(struct mdss_panel_data *pdata)
+{
+	return mdss_panel_is_power_on_ulp(pdata->panel_info.panel_power_state);
+}
+
 static inline bool mdss_dsi_ulps_feature_enabled(
 	struct mdss_panel_data *pdata)
 {
diff --git a/drivers/video/msm/mdss/mdss_hdmi_tx.c b/drivers/video/msm/mdss/mdss_hdmi_tx.c
index 5146e4d..c73941a 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-2014, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2010-2015, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -3743,7 +3743,7 @@
 				__func__, hdmi_tx_pm_name(module_type), rc);
 			goto error;
 		}
-		mp->vreg_config[j].enable_load = val_array[i];
+		mp->vreg_config[j].load[DSS_REG_MODE_ENABLE] = val_array[i];
 
 		memset(val_array, 0, sizeof(u32) * dt_vreg_total);
 		rc = of_property_read_u32_array(of_node,
@@ -3754,15 +3754,15 @@
 				__func__, hdmi_tx_pm_name(module_type), rc);
 			goto error;
 		}
-		mp->vreg_config[j].disable_load = val_array[i];
+		mp->vreg_config[j].load[DSS_REG_MODE_DISABLE] = val_array[i];
 
 		DEV_DBG("%s: %s min=%d, max=%d, enable=%d disable=%d\n",
 			__func__,
 			mp->vreg_config[j].vreg_name,
 			mp->vreg_config[j].min_voltage,
 			mp->vreg_config[j].max_voltage,
-			mp->vreg_config[j].enable_load,
-			mp->vreg_config[j].disable_load);
+			mp->vreg_config[j].load[DSS_REG_MODE_ENABLE],
+			mp->vreg_config[j].load[DSS_REG_MODE_DISABLE]);
 
 		ndx_mask >>= 1;
 		j++;
diff --git a/drivers/video/msm/mdss/mdss_io_util.c b/drivers/video/msm/mdss/mdss_io_util.c
index 849bf1d3..084bc64 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-2014, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2012-2015, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -208,6 +208,52 @@
 } /* msm_dss_config_vreg */
 EXPORT_SYMBOL(msm_dss_config_vreg);
 
+int msm_dss_config_vreg_opt_mode(struct dss_vreg *in_vreg, int num_vreg,
+	enum dss_vreg_mode mode)
+{
+	int i = 0, rc = 0;
+
+	if (mode >= DSS_REG_MODE_MAX) {
+		pr_err("%pS->%s: invalid mode %d\n",
+			__builtin_return_address(0), __func__, mode);
+		rc = -EINVAL;
+		goto error;
+	}
+
+	for (i = 0; i < num_vreg; i++) {
+		rc = PTR_RET(in_vreg[i].vreg);
+		if (rc) {
+			DEV_ERR("%pS->%s: %s regulator error. rc=%d\n",
+				__builtin_return_address(0), __func__,
+				in_vreg[i].vreg_name, rc);
+			goto error;
+		}
+
+		DEV_DBG("%s: Setting optimum mode %d for %s (load=%d)\n",
+			__func__, mode, in_vreg[i].vreg_name,
+			in_vreg[i].load[mode]);
+		rc = regulator_set_optimum_mode(in_vreg[i].vreg,
+			in_vreg[i].load[mode]);
+		if (rc < 0) {
+			DEV_ERR("%pS->%s: %s set opt mode failed. rc=%d\n",
+				__builtin_return_address(0), __func__,
+				in_vreg[i].vreg_name, rc);
+			goto error;
+		} else {
+			/*
+			 * regulator_set_optimum_mode can return non-zero
+			 * value for success. However, this API is expected
+			 * to return 0 for success.
+			 */
+			rc = 0;
+		}
+	}
+
+error:
+	return rc;
+}
+EXPORT_SYMBOL(msm_dss_config_vreg_opt_mode);
+
 int msm_dss_enable_vreg(struct dss_vreg *in_vreg, int num_vreg, int enable)
 {
 	int i = 0, rc = 0;
@@ -223,7 +269,7 @@
 			if (in_vreg[i].pre_on_sleep)
 				msleep(in_vreg[i].pre_on_sleep);
 			rc = regulator_set_optimum_mode(in_vreg[i].vreg,
-				in_vreg[i].enable_load);
+				in_vreg[i].load[DSS_REG_MODE_ENABLE]);
 			if (rc < 0) {
 				DEV_ERR("%pS->%s: %s set opt m fail\n",
 					__builtin_return_address(0), __func__,
@@ -246,7 +292,7 @@
 				if (in_vreg[i].pre_off_sleep)
 					msleep(in_vreg[i].pre_off_sleep);
 				regulator_set_optimum_mode(in_vreg[i].vreg,
-					in_vreg[i].disable_load);
+					in_vreg[i].load[DSS_REG_MODE_DISABLE]);
 				regulator_disable(in_vreg[i].vreg);
 				if (in_vreg[i].post_off_sleep)
 					msleep(in_vreg[i].post_off_sleep);
@@ -255,14 +301,15 @@
 	return rc;
 
 disable_vreg:
-	regulator_set_optimum_mode(in_vreg[i].vreg, in_vreg[i].disable_load);
+	regulator_set_optimum_mode(in_vreg[i].vreg,
+		in_vreg[i].load[DSS_REG_MODE_DISABLE]);
 
 vreg_set_opt_mode_fail:
 	for (i--; i >= 0; i--) {
 		if (in_vreg[i].pre_off_sleep)
 			msleep(in_vreg[i].pre_off_sleep);
 		regulator_set_optimum_mode(in_vreg[i].vreg,
-			in_vreg[i].disable_load);
+			in_vreg[i].load[DSS_REG_MODE_DISABLE]);
 		regulator_disable(in_vreg[i].vreg);
 		if (in_vreg[i].post_off_sleep)
 			msleep(in_vreg[i].post_off_sleep);
diff --git a/drivers/video/msm/mdss/mdss_mdp_intf_cmd.c b/drivers/video/msm/mdss/mdss_mdp_intf_cmd.c
index 2940604..c68a5d4 100644
--- a/drivers/video/msm/mdss/mdss_mdp_intf_cmd.c
+++ b/drivers/video/msm/mdss/mdss_mdp_intf_cmd.c
@@ -324,6 +324,7 @@
 {
 	struct mdss_mdp_cmd_ctx *ctx = data;
 	unsigned long flags;
+	bool notify_frame_timeout = false;
 
 	if (!data) {
 		pr_err("%s: invalid ctx\n", __func__);
@@ -341,8 +342,12 @@
 		mdss_mdp_irq_disable_nosync(MDSS_MDP_IRQ_PING_PONG_COMP,
 						ctx->pp_num);
 		complete_all(&ctx->pp_comp);
+		notify_frame_timeout = true;
 	}
 	spin_unlock_irqrestore(&ctx->koff_lock, flags);
+
+	if (notify_frame_timeout)
+		mdss_mdp_ctl_notify(ctx->ctl, MDP_NOTIFY_FRAME_TIMEOUT);
 }
 
 static void mdss_mdp_cmd_pingpong_done(void *arg)
diff --git a/drivers/video/msm/mdss/mdss_mdp_overlay.c b/drivers/video/msm/mdss/mdss_mdp_overlay.c
index 6b44afc..7240021 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-2014, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2012-2016, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -2040,18 +2040,27 @@
 
 int mdss_mdp_overlay_vsync_ctrl(struct msm_fb_data_type *mfd, int en)
 {
+	struct mdss_overlay_private *mdp5_data = mfd_to_mdp5_data(mfd);
 	struct mdss_mdp_ctl *ctl = mfd_to_ctl(mfd);
 	int rc;
 
 	if (!ctl)
 		return -ENODEV;
-	if (!ctl->add_vsync_handler || !ctl->remove_vsync_handler)
-		return -EOPNOTSUPP;
+
+	mutex_lock(&mdp5_data->ov_lock);
+	if (!ctl->add_vsync_handler || !ctl->remove_vsync_handler) {
+		rc = -EOPNOTSUPP;
+		pr_err_once("fb%d vsync handlers are not registered\n",
+			mfd->index);
+		goto end;
+	}
+
 	if (!ctl->panel_data->panel_info.cont_splash_enabled
 			&& !mdss_mdp_ctl_is_power_on(ctl)) {
-		pr_debug("fb%d vsync pending first update en=%d\n",
-				mfd->index, en);
-		return -EPERM;
+		pr_debug("fb%d vsync pending first update en=%d, ctl power state:%d\n",
+				mfd->index, en, ctl->power_state);
+		rc = -EPERM;
+		goto end;
 	}
 
 	pr_debug("fb%d vsync en=%d\n", mfd->index, en);
@@ -2063,6 +2072,8 @@
 		rc = ctl->remove_vsync_handler(ctl, &ctl->vsync_handler);
 	mdss_mdp_clk_ctrl(MDP_BLOCK_POWER_OFF);
 
+end:
+	mutex_unlock(&mdp5_data->ov_lock);
 	return rc;
 }
 
diff --git a/drivers/video/msm/mdss/msm_mdss_io_8974.c b/drivers/video/msm/mdss/msm_mdss_io_8974.c
index 668f2cb..8ab4b3e 100644
--- a/drivers/video/msm/mdss/msm_mdss_io_8974.c
+++ b/drivers/video/msm/mdss/msm_mdss_io_8974.c
@@ -1098,6 +1098,15 @@
 			ctrl->core_power = true;
 		}
 
+		/*
+		 * temp workaround until framework issues pertaining to LP2
+		 * power state transitions are fixed. For now, if we intend to
+		 * send a frame update when in LP1, we have to explicitly exit
+		 * LP2 state here
+		 */
+		if (mdss_dsi_is_panel_on_ulp(pdata))
+			mdss_dsi_panel_power_ctrl(pdata, MDSS_PANEL_POWER_LP1);
+
 		rc = mdss_dsi_bus_clk_start(ctrl);
 		if (rc) {
 			pr_err("%s: Failed to start bus clocks. rc=%d\n",
@@ -1184,6 +1193,15 @@
 				ctrl->core_power = false;
 			}
 		}
+
+		/*
+		 * temp workaround until framework issues pertaining to LP2
+		 * power state transitions are fixed. For now, we internally
+		 * transition to LP2 state whenever core power is turned off
+		 * in LP1 state
+		 */
+		if (mdss_dsi_is_panel_on_lp(pdata))
+			mdss_dsi_panel_power_ctrl(pdata, MDSS_PANEL_POWER_LP2);
 	}
 	return rc;
 
diff --git a/drivers/video/msm/vidc/common/dec/vdec.c b/drivers/video/msm/vidc/common/dec/vdec.c
new file mode 100755
index 0000000..0958e07
--- /dev/null
+++ b/drivers/video/msm/vidc/common/dec/vdec.c
@@ -0,0 +1,2709 @@
+/* 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
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; 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/module.h>
+#include <linux/platform_device.h>
+#include <linux/sched.h>
+#include <linux/uaccess.h>
+#include <linux/wait.h>
+#include <linux/workqueue.h>
+
+#include <linux/clk.h>
+#include <linux/timer.h>
+#include <media/msm/vidc_type.h>
+#include <media/msm/vcd_api.h>
+#include <media/msm/vidc_init.h>
+#include <mach/iommu_domains.h>
+#include "vcd_res_tracker_api.h"
+#include "vdec_internal.h"
+
+
+
+#define DBG(x...) pr_debug(x)
+#define INFO(x...) pr_info(x)
+#define ERR(x...) pr_err(x)
+
+#define VID_DEC_NAME "msm_vidc_dec"
+#ifdef KW_TAINT_ANALYSIS	51
+	extern void * get_tainted_stuff();
+#endif
+static char *node_name[2] = {"", "_sec"};
+static struct vid_dec_dev *vid_dec_device_p;
+static dev_t vid_dec_dev_num;
+static struct class *vid_dec_class;
+
+static s32 vid_dec_get_empty_client_index(void)
+{
+	u32 i, found = false;
+
+	for (i = 0; i < VIDC_MAX_NUM_CLIENTS; i++) {
+		if (!vid_dec_device_p->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;
+	}
+}
+
+u32 vid_dec_get_status(u32 status)
+{
+	u32 vdec_status;
+
+	switch (status) {
+	case VCD_ERR_SEQHDR_PARSE_FAIL:
+	case VCD_ERR_BITSTREAM_ERR:
+		vdec_status = VDEC_S_INPUT_BITSTREAM_ERR;
+		break;
+	case VCD_S_SUCCESS:
+		vdec_status = VDEC_S_SUCCESS;
+		break;
+	case VCD_ERR_FAIL:
+		vdec_status = VDEC_S_EFAIL;
+		break;
+	case VCD_ERR_ALLOC_FAIL:
+		vdec_status = VDEC_S_ENOSWRES;
+		break;
+	case VCD_ERR_ILLEGAL_OP:
+		vdec_status = VDEC_S_EINVALCMD;
+		break;
+	case VCD_ERR_ILLEGAL_PARM:
+		vdec_status = VDEC_S_EBADPARAM;
+		break;
+	case VCD_ERR_BAD_POINTER:
+	case VCD_ERR_BAD_HANDLE:
+		vdec_status = VDEC_S_EFATAL;
+		break;
+	case VCD_ERR_NOT_SUPPORTED:
+		vdec_status = VDEC_S_ENOTSUPP;
+		break;
+	case VCD_ERR_BAD_STATE:
+		vdec_status = VDEC_S_EINVALSTATE;
+		break;
+	case VCD_ERR_BUSY:
+		vdec_status = VDEC_S_BUSY;
+		break;
+	case VCD_ERR_MAX_CLIENT:
+		vdec_status = VDEC_S_ENOHWRES;
+		break;
+	default:
+		vdec_status = VDEC_S_EFAIL;
+		break;
+	}
+
+	return vdec_status;
+}
+
+static void vid_dec_notify_client(struct video_client_ctx *client_ctx)
+{
+	if (client_ctx)
+		complete(&client_ctx->event);
+}
+
+void vid_dec_vcd_open_done(struct video_client_ctx *client_ctx,
+			   struct vcd_handle_container *handle_container)
+{
+	DBG("vid_dec_vcd_open_done\n");
+
+	if (client_ctx) {
+		if (handle_container)
+			client_ctx->vcd_handle = handle_container->handle;
+		else
+			ERR("%s(): ERROR. handle_container is NULL\n",
+			    __func__);
+
+		vid_dec_notify_client(client_ctx);
+	} else
+		ERR("%s(): ERROR. client_ctx is NULL\n", __func__);
+}
+
+static void 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) {
+		ERR("%s() NULL pointer\n", __func__);
+		return;
+	}
+
+	vdec_msg = kzalloc(sizeof(struct vid_dec_msg), GFP_KERNEL);
+	if (!vdec_msg) {
+		ERR("%s(): cannot allocate vid_dec_msg "
+			" buffer\n", __func__);
+		return;
+	}
+	vdec_msg->vdec_msg_info.status_code = 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 {
+		ERR("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 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;
+
+	if (!client_ctx || !vcd_frame_data) {
+		ERR("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;
+
+	vdec_msg = kzalloc(sizeof(struct vid_dec_msg), GFP_KERNEL);
+	if (!vdec_msg) {
+		ERR("vid_dec_input_frame_done(): cannot allocate vid_dec_msg "
+		    " buffer\n");
+		return;
+	}
+
+	vdec_msg->vdec_msg_info.status_code = 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 {
+		ERR("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);
+}
+
+static void 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) {
+		ERR("vid_dec_input_frame_done() NULL pointer\n");
+		return;
+	}
+
+	vdec_msg = kzalloc(sizeof(struct vid_dec_msg), GFP_KERNEL);
+	if (!vdec_msg) {
+		ERR("vid_dec_input_frame_done(): cannot allocate vid_dec_msg "
+		    " buffer\n");
+		return;
+	}
+
+	vdec_msg->vdec_msg_info.status_code = 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 {
+		ERR("QVD: 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)) {
+
+		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;
+		/* 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 {
+		ERR("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) {
+			DBG("%s: Cache invalidate: vaddr (%p), "\
+				"size %u\n", __func__,
+				(void *)kernel_vaddr,
+				vcd_frame_data->alloc_len);
+			msm_ion_do_cache_op(client_ctx->user_ion_client,
+					buff_handle,
+					(unsigned long *) kernel_vaddr,
+					(unsigned long)vcd_frame_data->\
+					alloc_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 vid_dec_lean_event(struct video_client_ctx *client_ctx,
+			       u32 event, u32 status)
+{
+	struct vid_dec_msg *vdec_msg;
+
+	if (!client_ctx) {
+		ERR("%s(): !client_ctx pointer\n", __func__);
+		return;
+	}
+
+	vdec_msg = kzalloc(sizeof(struct vid_dec_msg), GFP_KERNEL);
+	if (!vdec_msg) {
+		ERR("%s(): cannot allocate vid_dec_msg buffer\n", __func__);
+		return;
+	}
+
+	vdec_msg->vdec_msg_info.status_code = 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:
+		ERR("%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);
+}
+
+
+void 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 =
+	    (struct video_client_ctx *)client_data;
+
+	DBG("Entering %s()\n", __func__);
+
+	if (!client_ctx) {
+		ERR("%s(): client_ctx is NULL\n", __func__);
+		return;
+	}
+
+	client_ctx->event_status = status;
+
+	switch (event) {
+	case VCD_EVT_RESP_OPEN:
+		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:
+		vid_dec_input_frame_done(client_ctx, event, status,
+					 (struct vcd_frame_data *)info);
+		break;
+	case VCD_EVT_IND_INFO_FIELD_DROPPED:
+		if (info)
+			vid_dec_handle_field_drop(client_ctx, event,
+			status,	*((int64_t *)info));
+		else
+			pr_err("Wrong Payload for Field dropped\n");
+		break;
+	case VCD_EVT_RESP_OUTPUT_DONE:
+	case VCD_EVT_RESP_OUTPUT_FLUSHED:
+		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:
+		vid_dec_lean_event(client_ctx, event, status);
+		break;
+	case VCD_EVT_RESP_START:
+		if (!client_ctx->seq_header_set)
+			vid_dec_lean_event(client_ctx, event, status);
+		else
+			vid_dec_notify_client(client_ctx);
+		break;
+	default:
+		ERR("%s() :  Error - Invalid event type =%u\n", __func__,
+		    event);
+		break;
+	}
+}
+
+static u32 vid_dec_set_codec(struct video_client_ctx *client_ctx,
+			     enum vdec_codec *vdec_codec)
+{
+	u32 result = true;
+	struct vcd_property_hdr vcd_property_hdr;
+	struct vcd_property_codec codec;
+	u32 vcd_status = VCD_ERR_FAIL;
+
+	if (!client_ctx || !vdec_codec)
+		return false;
+
+	vcd_property_hdr.prop_id = VCD_I_CODEC;
+	vcd_property_hdr.sz = sizeof(struct vcd_property_codec);
+
+	switch (*vdec_codec) {
+	case VDEC_CODECTYPE_MPEG4:
+		codec.codec = VCD_CODEC_MPEG4;
+		break;
+	case VDEC_CODECTYPE_H264:
+		codec.codec = VCD_CODEC_H264;
+		break;
+	case VDEC_CODECTYPE_DIVX_3:
+		codec.codec = VCD_CODEC_DIVX_3;
+		break;
+	case VDEC_CODECTYPE_DIVX_4:
+		codec.codec = VCD_CODEC_DIVX_4;
+		break;
+	case VDEC_CODECTYPE_DIVX_5:
+		codec.codec = VCD_CODEC_DIVX_5;
+		break;
+	case VDEC_CODECTYPE_DIVX_6:
+		codec.codec = VCD_CODEC_DIVX_6;
+		break;
+	case VDEC_CODECTYPE_XVID:
+		codec.codec = VCD_CODEC_XVID;
+		break;
+	case VDEC_CODECTYPE_H263:
+		codec.codec = VCD_CODEC_H263;
+		break;
+	case VDEC_CODECTYPE_MPEG2:
+		codec.codec = VCD_CODEC_MPEG2;
+		break;
+	case VDEC_CODECTYPE_VC1:
+		codec.codec = VCD_CODEC_VC1;
+		break;
+	case VDEC_CODECTYPE_VC1_RCV:
+		codec.codec = VCD_CODEC_VC1_RCV;
+		break;
+	default:
+		result = false;
+		break;
+	}
+
+	if (result) {
+		vcd_status = vcd_set_property(client_ctx->vcd_handle,
+					      &vcd_property_hdr, &codec);
+		if (vcd_status)
+			result = false;
+	}
+	return result;
+}
+
+static u32 vid_dec_set_output_format(struct video_client_ctx *client_ctx,
+				     enum vdec_output_fromat *output_format)
+{
+	u32 result = true;
+	struct vcd_property_hdr vcd_property_hdr;
+	struct vcd_property_buffer_format vcd_prop_buffer_format;
+	u32 vcd_status = VCD_ERR_FAIL;
+
+	if (!client_ctx || !output_format)
+		return false;
+
+	vcd_property_hdr.prop_id = VCD_I_BUFFER_FORMAT;;
+	vcd_property_hdr.sz =
+	    sizeof(struct vcd_property_buffer_format);
+
+	switch (*output_format) {
+	case VDEC_YUV_FORMAT_NV12:
+		vcd_prop_buffer_format.buffer_format = VCD_BUFFER_FORMAT_NV12;
+		break;
+	case VDEC_YUV_FORMAT_TILE_4x2:
+		vcd_prop_buffer_format.buffer_format =
+		    VCD_BUFFER_FORMAT_TILE_4x2;
+		break;
+	default:
+		result = false;
+		break;
+	}
+
+	if (result)
+		vcd_status = vcd_set_property(client_ctx->vcd_handle,
+					      &vcd_property_hdr,
+					      &vcd_prop_buffer_format);
+
+	if (vcd_status)
+		return false;
+	else
+		return true;
+}
+
+static u32 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 false;
+
+	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 false;
+	else
+		return true;
+}
+
+static u32 vid_dec_set_turbo_clk(struct video_client_ctx *client_ctx)
+{
+	struct vcd_property_hdr vcd_property_hdr;
+	u32 vcd_status = VCD_ERR_FAIL;
+	u32 dummy = 0;
+
+	if (!client_ctx)
+		return false;
+	vcd_property_hdr.prop_id = VCD_I_SET_TURBO_CLK;
+	vcd_property_hdr.sz = sizeof(struct vcd_property_frame_size);
+
+	vcd_status = vcd_set_property(client_ctx->vcd_handle,
+				      &vcd_property_hdr, &dummy);
+
+	if (vcd_status)
+		return false;
+	else
+		return true;
+}
+
+static u32 vid_dec_get_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 false;
+
+	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->frame_width = frame_resolution.width;
+	video_resoultion->frame_height = frame_resolution.height;
+	video_resoultion->scan_lines = frame_resolution.scan_lines;
+	video_resoultion->stride = frame_resolution.stride;
+
+	if (vcd_status)
+		return false;
+	else
+		return true;
+}
+
+static u32 vid_dec_get_progressive_only(struct video_client_ctx *client_ctx,
+					u32 *progressive_only)
+{
+	struct vcd_property_hdr vcd_property_hdr;
+	if (!client_ctx || !progressive_only)
+		return false;
+	vcd_property_hdr.prop_id = VCD_I_PROGRESSIVE_ONLY;
+	vcd_property_hdr.sz = sizeof(u32);
+	if (vcd_get_property(client_ctx->vcd_handle, &vcd_property_hdr,
+						 progressive_only))
+		return false;
+	else
+		return true;
+}
+
+static u32 vid_dec_get_disable_dmx_support(struct video_client_ctx *client_ctx,
+					   u32 *disable_dmx)
+{
+
+	struct vcd_property_hdr vcd_property_hdr;
+	if (!client_ctx || !disable_dmx)
+		return false;
+	vcd_property_hdr.prop_id = VCD_I_DISABLE_DMX_SUPPORT;
+	vcd_property_hdr.sz = sizeof(u32);
+	if (vcd_get_property(client_ctx->vcd_handle, &vcd_property_hdr,
+						 disable_dmx))
+		return false;
+	else
+		return true;
+}
+static u32 vid_dec_get_disable_dmx(struct video_client_ctx *client_ctx,
+					   u32 *disable_dmx)
+{
+
+	struct vcd_property_hdr vcd_property_hdr;
+	if (!client_ctx || !disable_dmx)
+		return false;
+	vcd_property_hdr.prop_id = VCD_I_DISABLE_DMX;
+	vcd_property_hdr.sz = sizeof(u32);
+	if (vcd_get_property(client_ctx->vcd_handle, &vcd_property_hdr,
+						 disable_dmx))
+		return false;
+	else
+		return true;
+}
+
+static u32 vid_dec_set_disable_dmx(struct video_client_ctx *client_ctx)
+{
+
+	struct vcd_property_hdr vcd_property_hdr;
+	u32 vcd_disable_dmx;
+	if (!client_ctx)
+		return false;
+	vcd_property_hdr.prop_id = VCD_I_DISABLE_DMX;
+	vcd_property_hdr.sz = sizeof(u32);
+	vcd_disable_dmx = true;
+	DBG("%s() : Setting Disable DMX: %d\n",
+		__func__, vcd_disable_dmx);
+
+	if (vcd_set_property(client_ctx->vcd_handle, &vcd_property_hdr,
+						 &vcd_disable_dmx))
+		return false;
+	else
+		return true;
+}
+
+static u32 vid_dec_set_picture_order(struct video_client_ctx *client_ctx,
+					u32 *picture_order)
+{
+	struct vcd_property_hdr vcd_property_hdr;
+	u32 vcd_status = VCD_ERR_FAIL, vcd_picture_order, ret = true;
+	if (!client_ctx || !picture_order)
+		return false;
+	vcd_property_hdr.prop_id = VCD_I_OUTPUT_ORDER;
+	vcd_property_hdr.sz = sizeof(u32);
+	if (*picture_order == VDEC_ORDER_DISPLAY)
+		vcd_picture_order = VCD_DEC_ORDER_DISPLAY;
+	else if (*picture_order == VDEC_ORDER_DECODE)
+		vcd_picture_order = VCD_DEC_ORDER_DECODE;
+	else
+		ret = false;
+	if (ret) {
+		DBG("%s() : Setting output picture order: %d\n",
+		    __func__, vcd_picture_order);
+		vcd_status = vcd_set_property(client_ctx->vcd_handle,
+				      &vcd_property_hdr, &vcd_picture_order);
+		if (vcd_status != VCD_S_SUCCESS)
+			ret = false;
+	}
+	return ret;
+}
+
+static u32 vid_dec_set_frame_rate(struct video_client_ctx *client_ctx,
+					struct vdec_framerate *frame_rate)
+{
+	struct vcd_property_hdr vcd_property_hdr;
+	struct vcd_property_frame_rate vcd_frame_rate;
+	u32 vcd_status = VCD_ERR_FAIL;
+
+	if (!client_ctx || !frame_rate)
+		return false;
+
+	vcd_property_hdr.prop_id = VCD_I_FRAME_RATE;
+	vcd_property_hdr.sz = sizeof(struct vcd_property_frame_rate);
+	vcd_frame_rate.fps_numerator = frame_rate->fps_numerator;
+	vcd_frame_rate.fps_denominator = frame_rate->fps_denominator;
+
+	vcd_status = vcd_set_property(client_ctx->vcd_handle,
+				      &vcd_property_hdr, &vcd_frame_rate);
+
+	if (vcd_status)
+		return false;
+	else
+		return true;
+}
+
+static u32 vid_dec_set_extradata(struct video_client_ctx *client_ctx,
+					u32 *extradata_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);
+	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)
+		return false;
+	else
+		return true;
+}
+
+static u32 vid_dec_set_idr_only_decoding(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 false;
+	vcd_property_hdr.prop_id = VCD_I_DEC_PICTYPE;
+	vcd_property_hdr.sz = sizeof(u32);
+	vcd_status = vcd_set_property(client_ctx->vcd_handle,
+			&vcd_property_hdr, &enable);
+	if (vcd_status)
+		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;
+	u32 vcd_status = VCD_ERR_FAIL;
+	u32 len = 0, len_iommu = 0, buf_size = 0;
+	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 (meta_buffers->count > MAX_META_BUFFERS) {
+		ERR("meta buffers maximum count reached, count = %d",
+			meta_buffers->count);
+		return false;
+	}
+
+	if (!vcd_get_ion_status()) {
+		pr_err("PMEM Not available\n");
+		return false;
+	} 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)
+{
+	struct vcd_property_hdr vcd_property_hdr;
+	struct vcd_property_h264_mv_buffer *vcd_h264_mv_buffer = NULL;
+	u32 vcd_status = VCD_ERR_FAIL;
+	u32 len = 0;
+	int rc = 0;
+	unsigned long ionflag = 0;
+	unsigned long buffer_size = 0;
+	unsigned long iova = 0;
+
+	if (!client_ctx || !mv_data)
+		return false;
+
+	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->pmem_fd;
+	vcd_h264_mv_buffer->offset = mv_data->offset;
+
+	if (mv_data->count > MAX_MV_BUFFERS) {
+		ERR("MV buffers maximum count reached, count = %d",
+			mv_data->count);
+		return false;
+	}
+
+	if (!vcd_get_ion_status()) {
+		pr_err("PMEM not available\n");
+		return false;
+	} 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)) {
+			ERR("%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) {
+			ERR("%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) {
+			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->h264_mv_ion_handle,
+				(unsigned long *) (&(vcd_h264_mv_buffer->
+				physical_addr)), &len);
+			if (rc) {
+				ERR("%s():get_ION_kernel physical addr fail\n",
+					__func__);
+				goto ion_map_error;
+			}
+			vcd_h264_mv_buffer->client_data = NULL;
+			vcd_h264_mv_buffer->dev_addr = (u8 *)
+				vcd_h264_mv_buffer->physical_addr;
+		} else {
+			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 || !iova) {
+				ERR(
+				"%s():get_ION_kernel physical addr fail, rc = %d iova = 0x%lx\n",
+					__func__, rc, iova);
+				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 false;
+	else
+		return true;
+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 false;
+}
+
+static u32 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 false;
+	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 false;
+	return true;
+}
+
+static u32 vid_dec_get_h264_mv_buffer_size(struct video_client_ctx *client_ctx,
+					struct vdec_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 false;
+
+	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 false;
+	else
+		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;
+
+	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;
+	struct vcd_property_buffer_size h264_mv_buffer_size;
+	u32 vcd_status = VCD_ERR_FAIL;
+
+	if (!client_ctx)
+		return false;
+
+	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);
+		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->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 false;
+	else
+		return true;
+}
+
+static u32 vid_dec_get_buffer_req(struct video_client_ctx *client_ctx,
+				  struct vdec_allocatorproperty *vdec_buf_req)
+{
+	u32 vcd_status = VCD_ERR_FAIL;
+	struct vcd_buffer_requirement vcd_buf_req;
+
+	if (!client_ctx || !vdec_buf_req)
+		return false;
+
+	if (vdec_buf_req->buffer_type == VDEC_BUFFER_TYPE_INPUT) {
+		vcd_status = vcd_get_buffer_requirements(client_ctx->vcd_handle,
+							 VCD_BUFFER_INPUT,
+							 &vcd_buf_req);
+	} else {
+		vcd_status = vcd_get_buffer_requirements(client_ctx->vcd_handle,
+							 VCD_BUFFER_OUTPUT,
+							 &vcd_buf_req);
+	}
+
+	if (vcd_status) {
+		return false;
+	} else {
+		vdec_buf_req->mincount = vcd_buf_req.min_count;
+		vdec_buf_req->maxcount = vcd_buf_req.max_count;
+		vdec_buf_req->actualcount = vcd_buf_req.actual_count;
+		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;
+	}
+}
+
+static u32 vid_dec_set_buffer(struct video_client_ctx *client_ctx,
+			      struct vdec_setbuffer_cmd *buffer_info)
+{
+	enum vcd_buffer_type buffer = VCD_BUFFER_INPUT;
+	enum buffer_dir dir_buffer = BUFFER_TYPE_INPUT;
+	u32 vcd_status = VCD_ERR_FAIL;
+	unsigned long kernel_vaddr, buf_adr_offset = 0, length;
+
+	if (!client_ctx || !buffer_info)
+		return false;
+
+	if (buffer_info->buffer_type == VDEC_BUFFER_TYPE_OUTPUT) {
+		dir_buffer = BUFFER_TYPE_OUTPUT;
+		buffer = VCD_BUFFER_OUTPUT;
+		buf_adr_offset = (unsigned long)buffer_info->buffer.offset;
+	}
+	length = buffer_info->buffer.buffer_len;
+	/*If buffer cannot be set, ignore */
+	if (!vidc_insert_addr_table(client_ctx, dir_buffer,
+		(unsigned long)buffer_info->buffer.bufferaddr,
+		&kernel_vaddr, buffer_info->buffer.pmem_fd,
+		buf_adr_offset, MAX_VIDEO_NUM_OF_BUFF, length)) {
+		DBG("%s() : user_virt_addr = %p cannot be set.",
+		    __func__, buffer_info->buffer.bufferaddr);
+		return false;
+	}
+	vcd_status = vcd_set_buffer(client_ctx->vcd_handle,
+		buffer, (u8 *) kernel_vaddr,
+		buffer_info->buffer.buffer_len);
+
+	if (!vcd_status)
+		return true;
+	else
+		return false;
+}
+
+
+static u32 vid_dec_free_buffer(struct video_client_ctx *client_ctx,
+			      struct vdec_setbuffer_cmd *buffer_info)
+{
+	enum vcd_buffer_type buffer = VCD_BUFFER_INPUT;
+	enum buffer_dir dir_buffer = BUFFER_TYPE_INPUT;
+	u32 vcd_status = VCD_ERR_FAIL;
+	unsigned long kernel_vaddr;
+
+	if (!client_ctx || !buffer_info)
+		return false;
+
+	if (buffer_info->buffer_type == VDEC_BUFFER_TYPE_OUTPUT) {
+		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)buffer_info->buffer.bufferaddr,
+				&kernel_vaddr)) {
+		DBG("%s() : user_virt_addr = %p has not been set.",
+		    __func__, buffer_info->buffer.bufferaddr);
+		return true;
+	}
+	vcd_status = vcd_free_buffer(client_ctx->vcd_handle, buffer,
+					 (u8 *)kernel_vaddr);
+
+	if (!vcd_status)
+		return true;
+	else
+		return false;
+}
+
+static u32 vid_dec_pause_resume(struct video_client_ctx *client_ctx, u32 pause)
+{
+  u32 vcd_status;
+
+	if (!client_ctx) {
+		ERR("\n %s(): Invalid client_ctx", __func__);
+		return false;
+	}
+
+	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 false;
+
+	return true;
+
+}
+
+static u32 vid_dec_start_stop(struct video_client_ctx *client_ctx, u32 start)
+{
+	struct vid_dec_msg *vdec_msg = NULL;
+	u32 vcd_status;
+
+	DBG("msm_vidc_dec: Inside %s()", __func__);
+	if (!client_ctx) {
+		ERR("\n Invalid client_ctx");
+		return false;
+	}
+
+	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) {
+				ERR("vid_dec_start_stop: cannot allocate"
+				    "buffer\n");
+				return false;
+			}
+			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) {
+				ERR("%s(): vcd_decode_start failed."
+				    " vcd_status = %u\n", __func__, vcd_status);
+				return false;
+			}
+		}
+	} else {
+		DBG("%s(): Calling vcd_stop()", __func__);
+		mutex_lock(&vid_dec_device_p->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) {
+			ERR("%s(): vcd_stop failed.  vcd_status = %u\n",
+				__func__, vcd_status);
+			mutex_unlock(&vid_dec_device_p->lock);
+			return false;
+		}
+		DBG("Send STOP_DONE message to client = %p\n", client_ctx);
+		mutex_unlock(&vid_dec_device_p->lock);
+	}
+	return true;
+}
+
+static u32 vid_dec_decode_frame(struct video_client_ctx *client_ctx,
+				struct vdec_input_frameinfo *input_frame_info,
+				u8 *desc_buf, u32 desc_size)
+{
+	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_info)
+		return false;
+
+	user_vaddr = (unsigned long)input_frame_info->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_info->pmem_offset);
+		vcd_input_buffer.offset = input_frame_info->offset;
+		vcd_input_buffer.frm_clnt_data =
+		    (u32) input_frame_info->client_data;
+		vcd_input_buffer.ip_frm_tag =
+		    (u32) input_frame_info->client_data;
+		vcd_input_buffer.data_len = input_frame_info->datalen;
+		vcd_input_buffer.time_stamp = input_frame_info->timestamp;
+		/* Rely on VCD using the same flags as OMX */
+		vcd_input_buffer.flags = input_frame_info->flags;
+		vcd_input_buffer.desc_buf = desc_buf;
+		vcd_input_buffer.desc_size = desc_size;
+		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 true;
+		else {
+			ERR("%s(): vcd_decode_frame failed = %u\n", __func__,
+			    vcd_status);
+			return false;
+		}
+
+	} else {
+		ERR("%s(): kernel_vaddr not found\n", __func__);
+		return false;
+	}
+}
+
+static u32 vid_dec_fill_output_buffer(struct video_client_ctx *client_ctx,
+		struct vdec_fillbuffer_cmd *fill_buffer_cmd)
+{
+	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_cmd)
+		return false;
+
+	user_vaddr = (unsigned long)fill_buffer_cmd->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_cmd->client_data;
+		vcd_frame.alloc_len = fill_buffer_cmd->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 true;
+		else {
+			ERR("%s(): vcd_fill_output_buffer failed = %u\n",
+			    __func__, vcd_status);
+			return false;
+		}
+	} else {
+		ERR("%s(): kernel_vaddr not found\n", __func__);
+		return false;
+	}
+}
+
+
+static u32 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) {
+		ERR("\n Invalid client_ctx");
+		return false;
+	}
+
+	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 false;
+		break;
+	}
+
+	if (!vcd_status)
+		return true;
+	else {
+		ERR("%s(): vcd_flush failed. vcd_status = %u "
+		    " flush_dir = %u\n", __func__, vcd_status, flush_dir);
+		return false;
+	}
+}
+
+static u32 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 vid_dec_get_next_msg(struct video_client_ctx *client_ctx,
+				struct vdec_msginfo *vdec_msg_info)
+{
+	int rc;
+	struct vid_dec_msg *vid_dec_msg = NULL;
+
+	if (!client_ctx)
+		return false;
+
+	rc = wait_event_interruptible(client_ctx->msg_wait,
+				      vid_dec_msg_pending(client_ctx));
+	if (rc < 0) {
+		DBG("rc = %d, stop_msg = %u\n", rc, client_ctx->stop_msg);
+		return rc;
+	} else if (client_ctx->stop_msg) {
+		DBG("rc = %d, stop_msg = %u\n", rc, client_ctx->stop_msg);
+		return -EIO;
+	}
+
+	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 long vid_dec_ioctl(struct file *file,
+			 unsigned cmd, unsigned long u_arg)
+{
+	struct video_client_ctx *client_ctx = NULL;
+	struct vdec_ioctl_msg vdec_msg;
+	u32 vcd_status;
+	unsigned long kernel_vaddr, phy_addr, len;
+	unsigned long ker_vaddr;
+	u32 result = true;
+	#ifdef KW_TAINT_ANALYSIS
+    void __user *arg = (void __user *) get_tainted_stuff();
+	#else
+	void __user *arg = (void __user *)u_arg;
+	#endif
+	int rc = 0;
+	size_t ion_len;
+
+	DBG("%s\n", __func__);
+	if (_IOC_TYPE(cmd) != VDEC_IOCTL_MAGIC)
+		return -ENOTTY;
+
+	client_ctx = (struct video_client_ctx *)file->private_data;
+	if (!client_ctx) {
+		ERR("!client_ctx. Cannot attach to device handle\n");
+		return -ENODEV;
+	}
+
+	switch (cmd) {
+	case VDEC_IOCTL_SET_CODEC:
+	{
+		enum vdec_codec vdec_codec;
+		DBG("VDEC_IOCTL_SET_CODEC\n");
+		if (copy_from_user(&vdec_msg, arg, sizeof(vdec_msg)))
+			return -EFAULT;
+		if (copy_from_user(&vdec_codec,	vdec_msg.in,
+						   sizeof(vdec_codec)))
+			return -EFAULT;
+		DBG("setting code type = %u\n", vdec_codec);
+		result = vid_dec_set_codec(client_ctx, &vdec_codec);
+		if (!result)
+			return -EIO;
+		break;
+	}
+	case VDEC_IOCTL_SET_OUTPUT_FORMAT:
+	{
+		enum vdec_output_fromat output_format;
+		DBG("VDEC_IOCTL_SET_OUTPUT_FORMAT\n");
+		if (copy_from_user(&vdec_msg, arg, sizeof(vdec_msg)))
+			return -EFAULT;
+		if (copy_from_user(&output_format, vdec_msg.in,
+						   sizeof(output_format)))
+			return -EFAULT;
+
+		result = vid_dec_set_output_format(client_ctx, &output_format);
+
+		if (!result)
+			return -EIO;
+		break;
+	}
+	case VDEC_IOCTL_SET_PICRES:
+	{
+		struct vdec_picsize video_resoultion;
+		DBG("VDEC_IOCTL_SET_PICRES\n");
+		if (copy_from_user(&vdec_msg, arg, sizeof(vdec_msg)))
+			return -EFAULT;
+		if (copy_from_user(&video_resoultion, vdec_msg.in,
+						   sizeof(video_resoultion)))
+			return -EFAULT;
+		result =
+		vid_dec_set_frame_resolution(client_ctx, &video_resoultion);
+		if (!result)
+			return -EIO;
+		break;
+	}
+	case VDEC_IOCTL_GET_PICRES:
+	{
+		struct vdec_picsize video_resoultion;
+		DBG("VDEC_IOCTL_GET_PICRES\n");
+		if (copy_from_user(&vdec_msg, arg, sizeof(vdec_msg)))
+			return -EFAULT;
+		if (copy_from_user(&video_resoultion, vdec_msg.out,
+						   sizeof(video_resoultion)))
+			return -EFAULT;
+
+		result = vid_dec_get_frame_resolution(client_ctx,
+					&video_resoultion);
+
+		if (result) {
+			if (copy_to_user(vdec_msg.out, &video_resoultion,
+					sizeof(video_resoultion)))
+				return -EFAULT;
+		} else
+			return -EIO;
+		break;
+	}
+	case VDEC_IOCTL_SET_BUFFER_REQ:
+	{
+		struct vdec_allocatorproperty vdec_buf_req;
+		struct vcd_buffer_requirement buffer_req;
+		DBG("VDEC_IOCTL_SET_BUFFER_REQ\n");
+		if (copy_from_user(&vdec_msg, arg, sizeof(vdec_msg)))
+			return -EFAULT;
+
+		if (copy_from_user(&vdec_buf_req, vdec_msg.in,
+				   sizeof(vdec_buf_req)))
+			return -EFAULT;
+
+		buffer_req.actual_count = vdec_buf_req.actualcount;
+		buffer_req.align = vdec_buf_req.alignment;
+		buffer_req.max_count = vdec_buf_req.maxcount;
+		buffer_req.min_count = vdec_buf_req.mincount;
+		buffer_req.sz = vdec_buf_req.buffer_size;
+
+		switch (vdec_buf_req.buffer_type) {
+		case VDEC_BUFFER_TYPE_INPUT:
+			vcd_status =
+			vcd_set_buffer_requirements(client_ctx->vcd_handle,
+				VCD_BUFFER_INPUT, &buffer_req);
+			break;
+		case VDEC_BUFFER_TYPE_OUTPUT:
+			vcd_status =
+			vcd_set_buffer_requirements(client_ctx->vcd_handle,
+				VCD_BUFFER_OUTPUT, &buffer_req);
+			break;
+		default:
+			vcd_status = VCD_ERR_BAD_POINTER;
+			break;
+		}
+
+		if (vcd_status)
+			return -EFAULT;
+		break;
+	}
+	case VDEC_IOCTL_GET_BUFFER_REQ:
+	{
+		struct vdec_allocatorproperty vdec_buf_req;
+		DBG("VDEC_IOCTL_GET_BUFFER_REQ\n");
+		if (copy_from_user(&vdec_msg, arg, sizeof(vdec_msg)))
+			return -EFAULT;
+		if (copy_from_user(&vdec_buf_req, vdec_msg.out,
+				   sizeof(vdec_buf_req)))
+			return -EFAULT;
+
+		result = vid_dec_get_buffer_req(client_ctx, &vdec_buf_req);
+
+		if (result) {
+			if (copy_to_user(vdec_msg.out, &vdec_buf_req,
+					sizeof(vdec_buf_req)))
+				return -EFAULT;
+		} else
+			return -EIO;
+		break;
+	}
+	case VDEC_IOCTL_SET_BUFFER:
+	{
+		struct vdec_setbuffer_cmd setbuffer;
+		DBG("VDEC_IOCTL_SET_BUFFER\n");
+		if (copy_from_user(&vdec_msg, arg, sizeof(vdec_msg)))
+			return -EFAULT;
+		if (copy_from_user(&setbuffer, vdec_msg.in,
+				sizeof(setbuffer)))
+			return -EFAULT;
+		result = vid_dec_set_buffer(client_ctx, &setbuffer);
+		if (!result)
+			return -EIO;
+		break;
+	}
+	case VDEC_IOCTL_FREE_BUFFER:
+	{
+		struct vdec_setbuffer_cmd setbuffer;
+		DBG("VDEC_IOCTL_FREE_BUFFER\n");
+		if (copy_from_user(&vdec_msg, arg, sizeof(vdec_msg)))
+			return -EFAULT;
+		if (copy_from_user(&setbuffer, vdec_msg.in,
+				sizeof(setbuffer)))
+			return -EFAULT;
+		result = vid_dec_free_buffer(client_ctx, &setbuffer);
+		if (!result)
+			return -EIO;
+		break;
+	}
+	case VDEC_IOCTL_CMD_START:
+	{
+		DBG(" VDEC_IOCTL_CMD_START\n");
+		result = vid_dec_start_stop(client_ctx, true);
+		if (!result)
+			return -EIO;
+		break;
+	}
+	case VDEC_IOCTL_CMD_STOP:
+	{
+		DBG("VDEC_IOCTL_CMD_STOP\n");
+		result = vid_dec_start_stop(client_ctx, false);
+		if (!result)
+			return -EIO;
+		break;
+	}
+	case VDEC_IOCTL_CMD_PAUSE:
+	{
+		result = vid_dec_pause_resume(client_ctx, true);
+		if (!result)
+			return -EIO;
+		break;
+	}
+	case VDEC_IOCTL_CMD_RESUME:
+	{
+		DBG("VDEC_IOCTL_CMD_PAUSE\n");
+		result = vid_dec_pause_resume(client_ctx, false);
+
+		if (!result)
+			return -EIO;
+		break;
+	}
+	case VDEC_IOCTL_DECODE_FRAME:
+	{
+		struct vdec_input_frameinfo input_frame_info;
+		u8 *desc_buf = NULL;
+		u32 desc_size = 0;
+		DBG("VDEC_IOCTL_DECODE_FRAME\n");
+		if (copy_from_user(&vdec_msg, arg, sizeof(vdec_msg)))
+			return -EFAULT;
+		if (copy_from_user(&input_frame_info, vdec_msg.in,
+				   sizeof(input_frame_info)))
+			return -EFAULT;
+		if (client_ctx->dmx_disable) {
+			if (input_frame_info.desc_addr) {
+				desc_size = input_frame_info.desc_size;
+				desc_buf = kzalloc(desc_size, GFP_KERNEL);
+				if (desc_buf) {
+					if (copy_from_user(desc_buf,
+						input_frame_info.desc_addr,
+							desc_size)) {
+						kfree(desc_buf);
+						desc_buf = NULL;
+						return -EFAULT;
+					}
+				}
+			} else
+				return -EINVAL;
+		}
+		result = vid_dec_decode_frame(client_ctx, &input_frame_info,
+					desc_buf, desc_size);
+
+		if (!result) {
+			kfree(desc_buf);
+			desc_buf = NULL;
+			return -EIO;
+		}
+		break;
+	}
+	case VDEC_IOCTL_SET_PERF_CLK:
+	{
+		vid_dec_set_turbo_clk(client_ctx);
+		break;
+	}
+	case VDEC_IOCTL_FILL_OUTPUT_BUFFER:
+	{
+		struct vdec_fillbuffer_cmd fill_buffer_cmd;
+		DBG("VDEC_IOCTL_FILL_OUTPUT_BUFFER\n");
+		if (copy_from_user(&vdec_msg, arg, sizeof(vdec_msg)))
+			return -EFAULT;
+		if (copy_from_user(&fill_buffer_cmd, vdec_msg.in,
+				   sizeof(fill_buffer_cmd)))
+			return -EFAULT;
+		result = vid_dec_fill_output_buffer(client_ctx,
+							&fill_buffer_cmd);
+		if (!result)
+			return -EIO;
+		break;
+	}
+	case VDEC_IOCTL_CMD_FLUSH:
+	{
+		enum vdec_bufferflush flush_dir;
+		DBG("VDEC_IOCTL_CMD_FLUSH\n");
+		if (copy_from_user(&vdec_msg, arg, sizeof(vdec_msg)))
+			return -EFAULT;
+		if (copy_from_user(&flush_dir, vdec_msg.in,
+				   sizeof(flush_dir)))
+			return -EFAULT;
+		result = vid_dec_flush(client_ctx, flush_dir);
+		if (!result)
+			return -EIO;
+		break;
+	}
+	case VDEC_IOCTL_GET_NEXT_MSG:
+	{
+		struct vdec_msginfo vdec_msg_info;
+		DBG("VDEC_IOCTL_GET_NEXT_MSG\n");
+		if (copy_from_user(&vdec_msg, arg, sizeof(vdec_msg)))
+			return -EFAULT;
+		result = vid_dec_get_next_msg(client_ctx, &vdec_msg_info);
+		if (result)
+			return result;
+		if (copy_to_user(vdec_msg.out, &vdec_msg_info,
+					sizeof(vdec_msg_info)))
+			return -EFAULT;
+		break;
+	}
+	case VDEC_IOCTL_STOP_NEXT_MSG:
+	{
+		DBG("VDEC_IOCTL_STOP_NEXT_MSG\n");
+		client_ctx->stop_msg = 1;
+		wake_up(&client_ctx->msg_wait);
+		break;
+	}
+	case VDEC_IOCTL_SET_SEQUENCE_HEADER:
+	{
+		struct vdec_seqheader seq_header;
+		struct vcd_sequence_hdr vcd_seq_hdr;
+		unsigned long ionflag;
+		DBG("VDEC_IOCTL_SET_SEQUENCE_HEADER\n");
+		if (copy_from_user(&vdec_msg, arg, sizeof(vdec_msg))) {
+			ERR("Copy from user vdec_msg failed\n");
+			return -EFAULT;
+		}
+		if (copy_from_user(&seq_header,	vdec_msg.in,
+				   sizeof(seq_header))) {
+			ERR("Copy from user seq_header failed\n");
+			return -EFAULT;
+		}
+		if (!seq_header.seq_header_len) {
+			ERR("Seq Len is Zero\n");
+			return -EFAULT;
+		}
+
+		if (!vcd_get_ion_status()) {
+			pr_err("PMEM Not available\n");
+			return -EINVAL;
+		} else {
+			client_ctx->seq_hdr_ion_handle = ion_import_dma_buf(
+				client_ctx->user_ion_client,
+				seq_header.pmem_fd);
+			if (!client_ctx->seq_hdr_ion_handle) {
+				ERR("%s(): get_ION_handle failed\n", __func__);
+				return false;
+			}
+			rc = ion_handle_get_flags(client_ctx->user_ion_client,
+						client_ctx->seq_hdr_ion_handle,
+						&ionflag);
+			if (rc) {
+				ERR("%s():get_ION_flags fail\n",
+							 __func__);
+				ion_free(client_ctx->user_ion_client,
+					client_ctx->seq_hdr_ion_handle);
+				return false;
+			}
+			ker_vaddr = (unsigned long) ion_map_kernel(
+				client_ctx->user_ion_client,
+				client_ctx->seq_hdr_ion_handle);
+			if (!ker_vaddr) {
+				ERR("%s():get_ION_kernel virtual addr fail\n",
+							 __func__);
+				ion_free(client_ctx->user_ion_client,
+					client_ctx->seq_hdr_ion_handle);
+				return false;
+			}
+			kernel_vaddr = ker_vaddr;
+			rc = ion_phys(client_ctx->user_ion_client,
+					client_ctx->seq_hdr_ion_handle,
+					&phy_addr, &ion_len);
+			if (rc) {
+				ERR("%s():get_ION_kernel physical addr fail\n",
+						 __func__);
+				ion_unmap_kernel(client_ctx->user_ion_client,
+					client_ctx->seq_hdr_ion_handle);
+				ion_free(client_ctx->user_ion_client,
+					client_ctx->seq_hdr_ion_handle);
+				return false;
+			}
+			len = ion_len;
+		}
+		vcd_seq_hdr.sequence_header_len = seq_header.seq_header_len;
+		kernel_vaddr += (unsigned long)seq_header.pmem_offset;
+		vcd_seq_hdr.sequence_header = (u8 *)kernel_vaddr;
+		if (!vcd_seq_hdr.sequence_header) {
+			ERR("Sequence Header pointer failed\n");
+			return -EFAULT;
+		}
+		client_ctx->seq_header_set = true;
+		if (vcd_decode_start(client_ctx->vcd_handle, &vcd_seq_hdr)) {
+			ERR("Decode start Failed\n");
+			client_ctx->seq_header_set = false;
+			return -EFAULT;
+		}
+		DBG("Wait Client completion Sequence Header\n");
+		wait_for_completion(&client_ctx->event);
+		vcd_seq_hdr.sequence_header = NULL;
+		if (client_ctx->event_status) {
+			ERR("Set Seq Header status is failed");
+			return -EFAULT;
+		}
+		if (vcd_get_ion_status()) {
+			if (client_ctx->seq_hdr_ion_handle) {
+				ion_unmap_kernel(client_ctx->user_ion_client,
+						client_ctx->seq_hdr_ion_handle);
+				ion_free(client_ctx->user_ion_client,
+					client_ctx->seq_hdr_ion_handle);
+			}
+		}
+		break;
+	}
+	case VDEC_IOCTL_GET_NUMBER_INSTANCES:
+	{
+		DBG("VDEC_IOCTL_GET_NUMBER_INSTANCES\n");
+		if (copy_from_user(&vdec_msg, arg, sizeof(vdec_msg)))
+			return -EFAULT;
+		if (copy_to_user(vdec_msg.out,
+			&vid_dec_device_p->num_clients, sizeof(u32)))
+			return -EFAULT;
+		break;
+	}
+	case VDEC_IOCTL_GET_INTERLACE_FORMAT:
+	{
+		u32 progressive_only, interlace_format;
+		DBG("VDEC_IOCTL_GET_INTERLACE_FORMAT\n");
+		if (copy_from_user(&vdec_msg, arg, sizeof(vdec_msg)))
+			return -EFAULT;
+		result = vid_dec_get_progressive_only(client_ctx,
+					&progressive_only);
+		if (result) {
+			interlace_format = progressive_only ?
+				VDEC_InterlaceFrameProgressive :
+				VDEC_InterlaceInterleaveFrameTopFieldFirst;
+			if (copy_to_user(vdec_msg.out, &interlace_format,
+					sizeof(u32)))
+				return -EFAULT;
+		} else
+			return -EIO;
+		break;
+	}
+
+	case VDEC_IOCTL_GET_DISABLE_DMX_SUPPORT:
+	{
+		u32 disable_dmx;
+		DBG("VDEC_IOCTL_GET_DISABLE_DMX_SUPPORT\n");
+		if (copy_from_user(&vdec_msg, arg, sizeof(vdec_msg)))
+			return -EFAULT;
+		result = vid_dec_get_disable_dmx_support(client_ctx,
+					&disable_dmx);
+		if (result) {
+			if (copy_to_user(vdec_msg.out, &disable_dmx,
+					sizeof(u32)))
+				return -EFAULT;
+		} else
+			return -EIO;
+		break;
+	}
+	case VDEC_IOCTL_GET_DISABLE_DMX:
+	{
+		u32 disable_dmx;
+		DBG("VDEC_IOCTL_GET_DISABLE_DMX\n");
+		if (copy_from_user(&vdec_msg, arg, sizeof(vdec_msg)))
+			return -EFAULT;
+		result = vid_dec_get_disable_dmx(client_ctx,
+					&disable_dmx);
+		if (result) {
+			if (copy_to_user(vdec_msg.out, &disable_dmx,
+					sizeof(u32)))
+				return -EFAULT;
+		} else
+			return -EIO;
+		break;
+	}
+	case VDEC_IOCTL_SET_DISABLE_DMX:
+	{
+		DBG("VDEC_IOCTL_SET_DISABLE_DMX\n");
+		result =  vid_dec_set_disable_dmx(client_ctx);
+		if (!result)
+			return -EIO;
+		client_ctx->dmx_disable = 1;
+		break;
+	}
+	case VDEC_IOCTL_SET_PICTURE_ORDER:
+	{
+		u32 picture_order;
+		DBG("VDEC_IOCTL_SET_PICTURE_ORDER\n");
+		if (copy_from_user(&vdec_msg, arg, sizeof(vdec_msg)))
+			return -EFAULT;
+		if (copy_from_user(&picture_order, vdec_msg.in,
+						   sizeof(u32)))
+			return -EFAULT;
+		result =  vid_dec_set_picture_order(client_ctx, &picture_order);
+		if (!result)
+			return -EIO;
+		break;
+	}
+	case VDEC_IOCTL_SET_FRAME_RATE:
+	{
+		struct vdec_framerate frame_rate;
+		DBG("VDEC_IOCTL_SET_FRAME_RATE\n");
+		if (copy_from_user(&vdec_msg, arg, sizeof(vdec_msg)))
+			return -EFAULT;
+		if (copy_from_user(&frame_rate, vdec_msg.in,
+						   sizeof(frame_rate)))
+			return -EFAULT;
+		result = vid_dec_set_frame_rate(client_ctx, &frame_rate);
+		if (!result)
+			return -EIO;
+		break;
+	}
+	case VDEC_IOCTL_SET_EXTRADATA:
+	{
+		u32 extradata_flag;
+		DBG("VDEC_IOCTL_SET_EXTRADATA\n");
+		if (copy_from_user(&vdec_msg, arg, sizeof(vdec_msg)))
+			return -EFAULT;
+		if (copy_from_user(&extradata_flag, vdec_msg.in,
+						   sizeof(u32)))
+			return -EFAULT;
+		result = vid_dec_set_extradata(client_ctx, &extradata_flag);
+		if (!result)
+			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;
+		DBG("VDEC_IOCTL_SET_H264_MV_BUFFER\n");
+		if (copy_from_user(&vdec_msg, arg, sizeof(vdec_msg)))
+			return -EFAULT;
+		if (copy_from_user(&mv_data, vdec_msg.in,
+						   sizeof(mv_data)))
+			return -EFAULT;
+		result = vid_dec_set_h264_mv_buffers(client_ctx, &mv_data);
+
+		if (!result)
+			return -EIO;
+		break;
+	}
+	case VDEC_IOCTL_FREE_H264_MV_BUFFER:
+	{
+		DBG("VDEC_IOCTL_FREE_H264_MV_BUFFER\n");
+		result = vid_dec_free_h264_mv_buffers(client_ctx);
+		if (!result)
+			return -EIO;
+		break;
+	}
+	case VDEC_IOCTL_GET_MV_BUFFER_SIZE:
+	{
+		struct vdec_mv_buff_size mv_buff;
+		DBG("VDEC_IOCTL_GET_MV_BUFFER_SIZE\n");
+		if (copy_from_user(&vdec_msg, arg, sizeof(vdec_msg)))
+			return -EFAULT;
+		if (copy_from_user(&mv_buff, vdec_msg.out,
+						   sizeof(mv_buff)))
+			return -EFAULT;
+		result = vid_dec_get_h264_mv_buffer_size(client_ctx, &mv_buff);
+		if (result) {
+			DBG(" Returning W: %d, H: %d, S: %d, A: %d",
+				mv_buff.width, mv_buff.height,
+				mv_buff.size, mv_buff.alignment);
+			if (copy_to_user(vdec_msg.out, &mv_buff,
+					sizeof(mv_buff)))
+				return -EFAULT;
+		} else
+			return -EIO;
+		break;
+	}
+	case VDEC_IOCTL_SET_IDR_ONLY_DECODING:
+	{
+		result = vid_dec_set_idr_only_decoding(client_ctx);
+		if (!result)
+			return -EIO;
+		break;
+	}
+	case VDEC_IOCTL_SET_CONT_ON_RECONFIG:
+	{
+		result = vid_dec_set_cont_on_reconfig(client_ctx);
+		if (!result)
+			return -EIO;
+		break;
+	}
+	default:
+		ERR("%s(): Unsupported ioctl\n", __func__);
+		return -ENOTTY;
+		break;
+	}
+
+	return 0;
+}
+
+static u32 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)) {
+		ERR("\n Invalid client_ctx");
+		return false;
+	}
+
+	mutex_lock(&vid_dec_device_p->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("\n Stuck at the stop call");
+		if (!vcd_status)
+			wait_for_completion(&client_ctx->event);
+		DBG("\n Came out of wait event");
+	}
+	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);
+
+	client_ctx->user_ion_client = NULL;
+	memset((void *)client_ctx, 0, sizeof(struct video_client_ctx));
+	vid_dec_device_p->num_clients--;
+	mutex_unlock(&vid_dec_device_p->lock);
+	return true;
+}
+
+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) {
+		ERR("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");
+		rc = -ENOMEM;
+		goto client_failure;
+	}
+
+	DBG(" Virtual Address of ioremap is %p\n", vid_dec_device_p->virt_base);
+	if (!vid_dec_device_p->num_clients) {
+		if (!vidc_load_firmware()) {
+			rc = -ENOMEM;
+			goto client_failure;
+		}
+	}
+
+	client_index = vid_dec_get_empty_client_index();
+	if (client_index < 0) {
+		ERR("%s() : No free clients client_index == -1\n", __func__);
+		rc = -ENOMEM;
+		goto client_failure;
+	}
+	client_ctx = &vid_dec_device_p->vdec_clients[client_index];
+	vid_dec_device_p->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(vid_dec_device_p->device_handle, true,
+				  vid_dec_vcd_cb, client_ctx, flags);
+	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);
+			rc = -ENODEV;
+			goto client_failure;
+		}
+	} else {
+		ERR("vcd_open returned error: %u", rc);
+		goto client_failure;
+	}
+	client_ctx->seq_header_set = false;
+	*vid_clnt_ctx = client_ctx;
+client_failure:
+	return rc;
+}
+
+static int vid_dec_open_secure(struct inode *inode, struct file *file)
+{
+	int rc = 0;
+	struct video_client_ctx *client_ctx;
+	mutex_lock(&vid_dec_device_p->lock);
+	rc = vid_dec_open_client(&client_ctx, VCD_CP_SESSION);
+	if (rc)
+		goto error;
+	if (!client_ctx) {
+		rc = -ENOMEM;
+		goto error;
+	}
+
+	file->private_data = client_ctx;
+	if (res_trk_open_secure_session()) {
+		ERR("Secure session operation failure\n");
+		rc = -EACCES;
+		goto error;
+	}
+	mutex_unlock(&vid_dec_device_p->lock);
+	return 0;
+error:
+	mutex_unlock(&vid_dec_device_p->lock);
+	return rc;
+}
+
+static int vid_dec_open(struct inode *inode, struct file *file)
+{
+	int rc = 0;
+	struct video_client_ctx *client_ctx;
+	INFO("msm_vidc_dec: Inside %s()", __func__);
+	mutex_lock(&vid_dec_device_p->lock);
+	rc = vid_dec_open_client(&client_ctx, 0);
+	if (rc) {
+		mutex_unlock(&vid_dec_device_p->lock);
+		return rc;
+	}
+	if (!client_ctx) {
+		mutex_unlock(&vid_dec_device_p->lock);
+		return -ENOMEM;
+	}
+
+	file->private_data = client_ctx;
+	mutex_unlock(&vid_dec_device_p->lock);
+	return rc;
+}
+
+static int vid_dec_release_secure(struct inode *inode, struct file *file)
+{
+	struct video_client_ctx *client_ctx = file->private_data;
+
+	INFO("msm_vidc_dec: Inside %s()", __func__);
+	vidc_cleanup_addr_table(client_ctx, BUFFER_TYPE_OUTPUT);
+	vidc_cleanup_addr_table(client_ctx, BUFFER_TYPE_INPUT);
+	vid_dec_close_client(client_ctx);
+	vidc_release_firmware();
+#ifndef USE_RES_TRACKER
+	vidc_disable_clk();
+#endif
+	INFO("msm_vidc_dec: Return from %s()", __func__);
+	return 0;
+}
+
+static int vid_dec_release(struct inode *inode, struct file *file)
+{
+	struct video_client_ctx *client_ctx = file->private_data;
+
+	INFO("msm_vidc_dec: Inside %s()", __func__);
+	vidc_cleanup_addr_table(client_ctx, BUFFER_TYPE_OUTPUT);
+	vidc_cleanup_addr_table(client_ctx, BUFFER_TYPE_INPUT);
+	vid_dec_close_client(client_ctx);
+	vidc_release_firmware();
+#ifndef USE_RES_TRACKER
+	vidc_disable_clk();
+#endif
+	INFO("msm_vidc_dec: Return from %s()", __func__);
+	return 0;
+}
+
+static const struct file_operations vid_dec_fops[2] = {
+	{
+		.owner = THIS_MODULE,
+		.open = vid_dec_open,
+		.release = vid_dec_release,
+		.unlocked_ioctl = vid_dec_ioctl,
+	},
+	{
+		.owner = THIS_MODULE,
+		.open = vid_dec_open_secure,
+		.release = vid_dec_release_secure,
+		.unlocked_ioctl = vid_dec_ioctl,
+	},
+
+};
+
+void vid_dec_interrupt_deregister(void)
+{
+}
+
+void vid_dec_interrupt_register(void *device_name)
+{
+}
+
+void vid_dec_interrupt_clear(void)
+{
+}
+
+void *vid_dec_map_dev_base_addr(void *device_name)
+{
+	return vid_dec_device_p->virt_base;
+}
+
+static 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__);
+	vid_dec_device_p->num_clients = 0;
+
+	for (i = 0; i < VIDC_MAX_NUM_CLIENTS; i++) {
+		memset((void *)&vid_dec_device_p->vdec_clients[i], 0,
+		       sizeof(vid_dec_device_p->vdec_clients[i]));
+	}
+
+	mutex_init(&vid_dec_device_p->lock);
+	vid_dec_device_p->virt_base = vidc_get_ioaddr();
+	DBG("%s() : base address for VIDC core %u\n", __func__, \
+		(int)vid_dec_device_p->virt_base);
+
+	if (!vid_dec_device_p->virt_base) {
+		ERR("%s() : ioremap failed\n", __func__);
+		return -ENOMEM;
+	}
+
+	vcd_init_config.device_name = "VIDC";
+	vcd_init_config.map_dev_base_addr = vid_dec_map_dev_base_addr;
+	vcd_init_config.interrupt_clr = vid_dec_interrupt_clear;
+	vcd_init_config.register_isr = vid_dec_interrupt_register;
+	vcd_init_config.deregister_isr = vid_dec_interrupt_deregister;
+	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, &vid_dec_device_p->device_handle);
+
+	if (rc) {
+		ERR("%s() : vcd_init failed\n", __func__);
+		return -ENODEV;
+	}
+	return 0;
+}
+
+static int __init vid_dec_init(void)
+{
+	int rc = 0, i = 0, j = 0;
+	struct device *class_devp;
+
+	DBG("msm_vidc_dec: Inside %s()", __func__);
+	vid_dec_device_p = kzalloc(sizeof(struct vid_dec_dev), GFP_KERNEL);
+	if (!vid_dec_device_p) {
+		ERR("%s Unable to allocate memory for vid_dec_dev\n",
+		       __func__);
+		return -ENOMEM;
+	}
+
+	rc = alloc_chrdev_region(&vid_dec_dev_num, 0, NUM_OF_DRIVER_NODES,
+		VID_DEC_NAME);
+	if (rc < 0) {
+		ERR("%s: alloc_chrdev_region Failed rc = %d\n",
+		       __func__, rc);
+		goto error_vid_dec_alloc_chrdev_region;
+	}
+
+	vid_dec_class = class_create(THIS_MODULE, VID_DEC_NAME);
+	if (IS_ERR(vid_dec_class)) {
+		rc = PTR_ERR(vid_dec_class);
+		ERR("%s: couldn't create vid_dec_class rc = %d\n",
+		       __func__, rc);
+
+		goto error_vid_dec_class_create;
+	}
+	for (i = 0; i < NUM_OF_DRIVER_NODES; i++) {
+		class_devp = device_create(vid_dec_class, NULL,
+						(vid_dec_dev_num + i),
+						NULL, VID_DEC_NAME "%s",
+						node_name[i]);
+
+		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_dec_class_device_create;
+			else
+				goto error_vid_dec_cdev_add;
+		}
+
+	  vid_dec_device_p->device[i] = class_devp;
+
+		cdev_init(&vid_dec_device_p->cdev[i], &vid_dec_fops[i]);
+		vid_dec_device_p->cdev[i].owner = THIS_MODULE;
+		rc = cdev_add(&(vid_dec_device_p->cdev[i]),
+				(vid_dec_dev_num+i), 1);
+
+		if (rc < 0) {
+			ERR("%s: cdev_add failed %d\n", __func__, rc);
+			goto error_vid_dec_cdev_add;
+		}
+	}
+	vid_dec_vcd_init();
+	return 0;
+
+error_vid_dec_cdev_add:
+	for (j = i-1; j >= 0; j--)
+		cdev_del(&(vid_dec_device_p->cdev[j]));
+	device_destroy(vid_dec_class, vid_dec_dev_num);
+error_vid_dec_class_device_create:
+	class_destroy(vid_dec_class);
+error_vid_dec_class_create:
+	unregister_chrdev_region(vid_dec_dev_num, NUM_OF_DRIVER_NODES);
+error_vid_dec_alloc_chrdev_region:
+	kfree(vid_dec_device_p);
+	return rc;
+}
+
+static void __exit vid_dec_exit(void)
+{
+	int i = 0;
+	INFO("msm_vidc_dec: Inside %s()", __func__);
+	for (i = 0; i < NUM_OF_DRIVER_NODES; i++)
+		cdev_del(&(vid_dec_device_p->cdev[i]));
+	device_destroy(vid_dec_class, vid_dec_dev_num);
+	class_destroy(vid_dec_class);
+	unregister_chrdev_region(vid_dec_dev_num, NUM_OF_DRIVER_NODES);
+	kfree(vid_dec_device_p);
+	DBG("msm_vidc_dec: Return from %s()", __func__);
+}
+
+MODULE_LICENSE("GPL v2");
+MODULE_DESCRIPTION("Video decoder driver");
+MODULE_VERSION("1.0");
+
+module_init(vid_dec_init);
+module_exit(vid_dec_exit);
diff --git a/include/linux/mdss_io_util.h b/include/linux/mdss_io_util.h
index ea88cf6..4f6ba44 100644
--- a/include/linux/mdss_io_util.h
+++ b/include/linux/mdss_io_util.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2012, 2015, The Linux Foundation. All rights reserved.
  *
  * This 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,20 @@
 	DSS_REG_VS,
 };
 
+enum dss_vreg_mode {
+	DSS_REG_MODE_ENABLE,
+	DSS_REG_MODE_DISABLE,
+	DSS_REG_MODE_LP,
+	DSS_REG_MODE_ULP,
+	DSS_REG_MODE_MAX,
+};
+
 struct dss_vreg {
 	struct regulator *vreg; /* vreg handle */
 	char vreg_name[32];
 	int min_voltage;
 	int max_voltage;
-	int enable_load;
-	int disable_load;
+	u32 load[DSS_REG_MODE_MAX];
 	int pre_on_sleep;
 	int post_on_sleep;
 	int pre_off_sleep;
@@ -99,6 +106,8 @@
 	int num_vreg, int config);
 int msm_dss_enable_vreg(struct dss_vreg *in_vreg, int num_vreg,	int enable);
 void msm_dss_set_vreg_idle(struct dss_vreg *in_vreg, int num_vreg, bool idle);
+int msm_dss_config_vreg_opt_mode(struct dss_vreg *in_vreg, int num_vreg,
+	enum dss_vreg_mode mode);
 
 int msm_dss_get_clk(struct device *dev, struct dss_clk *clk_arry, int num_clk);
 void msm_dss_put_clk(struct dss_clk *clk_arry, int num_clk);
diff --git a/include/media/msm/vidc_init.h b/include/media/msm/vidc_init.h
new file mode 100644
index 0000000..9c9a270
--- /dev/null
+++ b/include/media/msm/vidc_init.h
@@ -0,0 +1,112 @@
+/* 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 VIDC_INIT_H
+#define VIDC_INIT_H
+#include <linux/msm_ion.h>
+#include <media/msm/vidc_type.h>
+#include <media/msm/vcd_property.h>
+
+#define VIDC_MAX_NUM_CLIENTS 4
+#define MAX_VIDEO_NUM_OF_BUFF 100
+#define MAX_META_BUFFERS 32
+#define MAX_MV_BUFFERS 32
+
+enum buffer_dir {
+	BUFFER_TYPE_INPUT,
+	BUFFER_TYPE_OUTPUT
+};
+
+struct buf_addr_table {
+	unsigned long user_vaddr;
+	unsigned long kernel_vaddr;
+	unsigned long phy_addr;
+	unsigned long buff_ion_flag;
+	struct ion_handle *buff_ion_handle;
+	int pmem_fd;
+	struct file *file;
+	unsigned long dev_addr;
+	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;
+	u32 num_of_output_buffers;
+	struct buf_addr_table input_buf_addr_table[MAX_VIDEO_NUM_OF_BUFF];
+	struct buf_addr_table output_buf_addr_table[MAX_VIDEO_NUM_OF_BUFF];
+	struct list_head msg_queue;
+	struct mutex msg_queue_lock;
+	struct mutex enrty_queue_lock;
+	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);
+int vidc_load_firmware(void);
+void vidc_release_firmware(void);
+u32 vidc_get_fd_info(struct video_client_ctx *client_ctx,
+		enum buffer_dir buffer, int pmem_fd,
+		unsigned long kvaddr, int index,
+		struct ion_handle **buff_handle);
+u32 vidc_lookup_addr_table(struct video_client_ctx *client_ctx,
+	enum buffer_dir buffer, u32 search_with_user_vaddr,
+	unsigned long *user_vaddr, unsigned long *kernel_vaddr,
+	unsigned long *phy_addr, int *pmem_fd, struct file **file,
+	s32 *buffer_index);
+u32 vidc_insert_addr_table(struct video_client_ctx *client_ctx,
+	enum buffer_dir buffer, unsigned long user_vaddr,
+	unsigned long *kernel_vaddr, int pmem_fd,
+	unsigned long buffer_addr_offset,
+	unsigned int max_num_buffers, unsigned long length);
+u32 vidc_insert_addr_table_kernel(struct video_client_ctx *client_ctx,
+	enum buffer_dir buffer, unsigned long user_vaddr,
+	unsigned long kernel_vaddr, unsigned long phys_addr,
+	unsigned int max_num_buffers,
+	unsigned long length);
+u32 vidc_delete_addr_table(struct video_client_ctx *client_ctx,
+	enum buffer_dir buffer, unsigned long user_vaddr,
+	unsigned long *kernel_vaddr);
+void vidc_cleanup_addr_table(struct video_client_ctx *client_ctx,
+		enum buffer_dir buffer);
+
+u32 vidc_timer_create(void (*timer_handler)(void *),
+	void *user_data, void **timer_handle);
+void  vidc_timer_release(void *timer_handle);
+void  vidc_timer_start(void *timer_handle, u32 time_out);
+void  vidc_timer_stop(void *timer_handle);
+
+
+#endif
diff --git a/include/uapi/asm-generic/unistd.h b/include/uapi/asm-generic/unistd.h
index 56d3422..b422ad5 100644
--- a/include/uapi/asm-generic/unistd.h
+++ b/include/uapi/asm-generic/unistd.h
@@ -692,12 +692,14 @@
 __SYSCALL(__NR_kcmp, sys_kcmp)
 #define __NR_finit_module 273
 __SYSCALL(__NR_finit_module, sys_finit_module)
-#define __NR_sched_setattr 274
+/* Backporting seccomp, skip a few ...
+ * #define __NR_sched_setattr 274
 __SYSCALL(__NR_sched_setattr, sys_sched_setattr)
-#define __NR_sched_getattr 275
+ * #define __NR_sched_getattr 275
 __SYSCALL(__NR_sched_getattr, sys_sched_getattr)
-#define __NR_renameat2 276
+ * #define __NR_renameat2 276
 __SYSCALL(__NR_renameat2, sys_renameat2)
+ */
 #define __NR_seccomp 277
 __SYSCALL(__NR_seccomp, sys_seccomp)
 
diff --git a/kernel/sched/rt.c b/kernel/sched/rt.c
index 71dcc2a..b5da5a4 100644
--- a/kernel/sched/rt.c
+++ b/kernel/sched/rt.c
@@ -1423,6 +1423,15 @@
 		rt_rq = group_rt_rq(rt_se);
 	} while (rt_rq);
 
+	/*
+	 * Force update of rq->clock_task in case we failed to do so in
+	 * put_prev_task. A stale value can cause us to over-charge execution
+	 * time to real-time task, that could trigger throttling unnecessarily
+	 */
+	if (rq->skip_clock_update > 0) {
+		rq->skip_clock_update = 0;
+		update_rq_clock(rq);
+	}
 	p = rt_task_of(rt_se);
 	p->se.exec_start = rq->clock_task;
 
diff --git a/kernel/seccomp.c b/kernel/seccomp.c
index 13ed9d2..e60ae23 100644
--- a/kernel/seccomp.c
+++ b/kernel/seccomp.c
@@ -219,7 +219,6 @@
 	 */
 	for (; f; f = f->prev) {
 		u32 cur_ret = sk_run_filter(NULL, f->insns);
-
 		if ((cur_ret & SECCOMP_RET_ACTION) < (ret & SECCOMP_RET_ACTION))
 			ret = cur_ret;
 	}
@@ -774,7 +773,7 @@
 }
 
 SYSCALL_DEFINE3(seccomp, unsigned int, op, unsigned int, flags,
-		const char __user *, uargs)
+			 const char __user *, uargs)
 {
 	return do_seccomp(op, flags, uargs);
 }
diff --git a/kernel/sys.c b/kernel/sys.c
index 407abee..0b08c9f 100644
--- a/kernel/sys.c
+++ b/kernel/sys.c
@@ -2187,7 +2187,7 @@
 			tmp = end;
 
 		/* Here vma->vm_start <= start < tmp <= (end|vma->vm_end). */
-		error = prctl_update_vma_anon_name(vma, &prev, start, end,
+		error = prctl_update_vma_anon_name(vma, &prev, start, tmp,
 				(const char __user *)arg);
 		if (error)
 			return error;
diff --git a/kernel/trace/msm_rtb.c b/kernel/trace/msm_rtb.c
index 8d288c8..2033a17 100644
--- a/kernel/trace/msm_rtb.c
+++ b/kernel/trace/msm_rtb.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2013-2014, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -35,20 +35,22 @@
 #define RTB_COMPAT_STR	"qcom,msm-rtb"
 
 /* Write
- * 1) 11 bytes sentinel
+ * 1) 3 bytes sentinel
  * 2) 1 bytes of log type
  * 3) 8 bytes of where the caller came from
  * 4) 4 bytes index
  * 4) 8 bytes extra data from the caller
+ * 5) 8 bytes of timestamp
  *
  * Total = 32 bytes.
  */
 struct msm_rtb_layout {
-	unsigned char sentinel[11];
+	unsigned char sentinel[3];
 	unsigned char log_type;
 	uint32_t idx;
 	uint64_t caller;
 	uint64_t data;
+	uint64_t timestamp;
 } __attribute__ ((__packed__));
 
 
@@ -124,6 +126,11 @@
 	start->data = data;
 }
 
+static void msm_rtb_write_timestamp(struct msm_rtb_layout *start)
+{
+	start->timestamp = sched_clock();
+}
+
 static void uncached_logk_pc_idx(enum logk_event_type log_type, uint64_t caller,
 				 uint64_t data, int idx)
 {
@@ -136,6 +143,7 @@
 	msm_rtb_write_caller(caller, start);
 	msm_rtb_write_idx(idx, start);
 	msm_rtb_write_data(data, start);
+	msm_rtb_write_timestamp(start);
 	mb();
 
 	return;
diff --git a/net/core/neighbour.c b/net/core/neighbour.c
index cdd7716..2bc6c11 100644
--- a/net/core/neighbour.c
+++ b/net/core/neighbour.c
@@ -700,7 +700,7 @@
 	NEIGH_CACHE_STAT_INC(neigh->tbl, destroys);
 
 	if (!neigh->dead) {
-		pr_warn("Destroying alive neighbour %p\n", neigh);
+		pr_warn("Destroying alive neighbour %pK\n", neigh);
 		dump_stack();
 		return;
 	}
@@ -1317,7 +1317,7 @@
 out:
 	return rc;
 discard:
-	neigh_dbg(1, "%s: dst=%p neigh=%p\n", __func__, dst, neigh);
+	neigh_dbg(1, "%s: dst=%pK neigh=%pK\n", __func__, dst, neigh);
 out_kfree_skb:
 	rc = -EINVAL;
 	kfree_skb(skb);
diff --git a/net/ipc_router/ipc_router_core.c b/net/ipc_router/ipc_router_core.c
index f3c98f0..e181233 100644
--- a/net/ipc_router/ipc_router_core.c
+++ b/net/ipc_router/ipc_router_core.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2014, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2011-2014, 2016, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -2904,7 +2904,7 @@
 
 int msm_ipc_router_bind_control_port(struct msm_ipc_port *port_ptr)
 {
-	if (!port_ptr)
+	if (unlikely(!port_ptr || port_ptr->type != CLIENT_PORT))
 		return -EINVAL;
 
 	down_write(&local_ports_lock_lha2);
diff --git a/net/ipc_router/ipc_router_socket.c b/net/ipc_router/ipc_router_socket.c
index 9dbbe61..ea46fd5 100644
--- a/net/ipc_router/ipc_router_socket.c
+++ b/net/ipc_router/ipc_router_socket.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2014, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2011-2014, 2016, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -519,13 +519,18 @@
 
 		ret = copy_to_user((void *)arg, &server_arg,
 				   sizeof(server_arg));
-		if (srv_info_sz) {
+
+		n = min(server_arg.num_entries_found,
+			server_arg.num_entries_in_array);
+
+		if (ret == 0 && n) {
 			ret = copy_to_user((void *)(arg + sizeof(server_arg)),
-					   srv_info, srv_info_sz);
-			if (ret)
-				ret = -EFAULT;
-			kfree(srv_info);
+					   srv_info, n * sizeof(*srv_info));
 		}
+
+		if (ret)
+			ret = -EFAULT;
+		kfree(srv_info);
 		break;
 
 	case IPC_ROUTER_IOCTL_BIND_CONTROL_PORT:
diff --git a/net/rmnet_data/rmnet_data_handlers.c b/net/rmnet_data/rmnet_data_handlers.c
index b680637..72b26e3 100644
--- a/net/rmnet_data/rmnet_data_handlers.c
+++ b/net/rmnet_data/rmnet_data_handlers.c
@@ -103,9 +103,10 @@
 	if (!printlen)
 		return;
 
-	pr_err("[%s][%c] - PKT skb->len=%d skb->head=%p skb->data=%p skb->tail=%p skb->end=%p\n",
-		dev, dir, skb->len, (void *)skb->head, (void *)skb->data,
-		skb_tail_pointer(skb), skb_end_pointer(skb));
+	pr_err("[%s][%c] - PKT skb->len=%d skb->head=%pK skb->data=%pK\n",
+	       dev, dir, skb->len, (void *)skb->head, (void *)skb->data);
+	pr_err("[%s][%c] - PKT skb->tail=%pK skb->end=%pK\n",
+	       dev, dir, skb_tail_pointer(skb), skb_end_pointer(skb));
 
 	if (skb->len > 0)
 		len = skb->len;
diff --git a/net/rmnet_data/rmnet_data_trace.h b/net/rmnet_data/rmnet_data_trace.h
index 98a6ed5..dee46a0 100644
--- a/net/rmnet_data/rmnet_data_trace.h
+++ b/net/rmnet_data/rmnet_data_trace.h
@@ -39,8 +39,8 @@
 		__assign_str(name, skb->dev->name);
 	),
 
-	TP_printk("dev=%s skbaddr=%p len=%u",
-		__get_str(name), __entry->skbaddr, __entry->len)
+	TP_printk("dev=%s skbaddr=%pK len=%u",
+		  __get_str(name), __entry->skbaddr, __entry->len)
 )
 
 DEFINE_EVENT(rmnet_handler_template, rmnet_egress_handler,
@@ -128,8 +128,9 @@
 		__entry->num = num_agg_pakcets;
 	),
 
-	TP_printk("dev=%s skbaddr=%p len=%u agg_count: %d",
-		__get_str(name), __entry->skbaddr, __entry->len, __entry->num)
+	TP_printk("dev=%s skbaddr=%pK len=%u agg_count: %d",
+		  __get_str(name), __entry->skbaddr, __entry->len,
+		  __entry->num)
 )
 
 DEFINE_EVENT(rmnet_aggregation_template, rmnet_map_aggregate,
diff --git a/net/rmnet_data/rmnet_data_vnd.c b/net/rmnet_data/rmnet_data_vnd.c
index e9843c5a..7b75dd6 100644
--- a/net/rmnet_data/rmnet_data_vnd.c
+++ b/net/rmnet_data/rmnet_data_vnd.c
@@ -811,7 +811,7 @@
 				itm->tc_flow_valid[i] = 1;
 				itm->tc_flow_id[i] = tc_flow;
 				rc = RMNET_VND_UPDATE_FLOW_OK;
-				LOGD("{%p}->tc_flow_id[%d]=%08X",
+				LOGD("{%pK}->tc_flow_id[%d]=%08X",
 				     itm, i, tc_flow);
 				break;
 			}
@@ -827,7 +827,7 @@
 					itm->tc_flow_valid[i] = 0;
 					itm->tc_flow_id[i] = 0;
 					j++;
-					LOGD("{%p}->tc_flow_id[%d]=0", itm, i);
+					LOGD("{%pK}->tc_flow_id[%d]=0", itm, i);
 				}
 			} else {
 				j++;
@@ -972,7 +972,7 @@
 
 	if (r ==  RMNET_VND_UPDATE_FLOW_NO_VALID_LEFT) {
 		if (itm)
-			LOGD("Removed flow mapping [%s][0x%08X]@%p",
+			LOGD("Removed flow mapping [%s][0x%08X]@%pK",
 			     dev->name, itm->map_flow_id, itm);
 		kfree(itm);
 	}
diff --git a/sound/soc/msm/msm8226-wear.c b/sound/soc/msm/msm8226-wear.c
index d24c4df..952fa83 100644
--- a/sound/soc/msm/msm8226-wear.c
+++ b/sound/soc/msm/msm8226-wear.c
@@ -688,6 +688,10 @@
 	snd_soc_dapm_ignore_suspend(dapm, "Analog Mic4");
 	snd_soc_dapm_ignore_suspend(dapm, "AMIC3");
 	snd_soc_dapm_ignore_suspend(dapm, "AMIC4");
+	snd_soc_dapm_ignore_suspend(dapm, "SPK_OUT");
+	snd_soc_dapm_ignore_suspend(dapm, "BE_IN");
+	snd_soc_dapm_ignore_suspend(dapm, "BE_OUT");
+
 	snd_soc_dapm_sync(dapm);
 
 	codec_clk = clk_get(cpu_dai->dev, "osr_clk");
diff --git a/sound/soc/msm/msm8226.c b/sound/soc/msm/msm8226.c
index 19a5e1c..9111c35 100644
--- a/sound/soc/msm/msm8226.c
+++ b/sound/soc/msm/msm8226.c
@@ -1041,6 +1041,29 @@
 	snd_soc_dapm_new_controls(dapm, msm8226_dapm_widgets,
 				ARRAY_SIZE(msm8226_dapm_widgets));
 
+	snd_soc_dapm_ignore_suspend(dapm, "Handset Mic");
+	snd_soc_dapm_ignore_suspend(dapm, "Headset Mic");
+	snd_soc_dapm_ignore_suspend(dapm, "ANCRight Headset Mic");
+	snd_soc_dapm_ignore_suspend(dapm, "ANCLeft Headset Mic");
+	snd_soc_dapm_ignore_suspend(dapm, "Digital Mic1");
+	snd_soc_dapm_ignore_suspend(dapm, "Digital Mic2");
+	snd_soc_dapm_ignore_suspend(dapm, "Digital Mic3");
+	snd_soc_dapm_ignore_suspend(dapm, "Digital Mic4");
+	snd_soc_dapm_ignore_suspend(dapm, "DMIC1");
+	snd_soc_dapm_ignore_suspend(dapm, "DMIC2");
+	snd_soc_dapm_ignore_suspend(dapm, "DMIC3");
+	snd_soc_dapm_ignore_suspend(dapm, "DMIC4");
+	snd_soc_dapm_ignore_suspend(dapm, "Analog Mic3");
+	snd_soc_dapm_ignore_suspend(dapm, "Analog Mic4");
+	snd_soc_dapm_ignore_suspend(dapm, "AMIC1");
+	snd_soc_dapm_ignore_suspend(dapm, "AMIC2");
+	snd_soc_dapm_ignore_suspend(dapm, "AMIC3");
+	snd_soc_dapm_ignore_suspend(dapm, "AMIC4");
+	snd_soc_dapm_ignore_suspend(dapm, "AMIC5");
+	snd_soc_dapm_ignore_suspend(dapm, "SPK_OUT");
+	snd_soc_dapm_ignore_suspend(dapm, "BE_IN");
+	snd_soc_dapm_ignore_suspend(dapm, "BE_OUT");
+
 	snd_soc_dapm_sync(dapm);
 
 	codec_clk = clk_get(cpu_dai->dev, "osr_clk");
diff --git a/sound/soc/msm/qdsp6v2/msm-audio-effects-q6-v2.c b/sound/soc/msm/qdsp6v2/msm-audio-effects-q6-v2.c
index bd1feea..cf96e2c 100644
--- a/sound/soc/msm/qdsp6v2/msm-audio-effects-q6-v2.c
+++ b/sound/soc/msm/qdsp6v2/msm-audio-effects-q6-v2.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2013-2015, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2013-2016, The Linux Foundation. All rights reserved.
  *
  * This 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,19 +16,39 @@
 #include <sound/compress_params.h>
 #include "msm-audio-effects-q6-v2.h"
 
+#define MAX_ENABLE_CMD_SIZE 32
+
+#define GET_NEXT(ptr, upper_limit, rc)                                  \
+({                                                                      \
+	if (((ptr) + 1) > (upper_limit)) {                              \
+		pr_err("%s: param list out of boundary\n", __func__);   \
+		(rc) = -EINVAL;                                         \
+	}                                                               \
+	((rc) == 0) ? *(ptr)++ :  -EINVAL;                              \
+})
+
+#define CHECK_PARAM_LEN(len, max_len, tag, rc)                          \
+do {                                                                    \
+	if ((len) > (max_len)) {                                        \
+		pr_err("%s: params length overflows\n", (tag));         \
+		(rc) = -EINVAL;                                         \
+	}                                                               \
+} while (0)
+
 int msm_audio_effects_virtualizer_handler(struct audio_client *ac,
 				struct virtualizer_params *virtualizer,
 				long *values)
 {
-	int devices = *values++;
-	int num_commands = *values++;
-	char *params;
+	long *param_max_offset = values + MAX_PP_PARAMS_SZ - 1;
+	char *params = NULL;
+	int rc = 0;
+	int devices = GET_NEXT(values, param_max_offset, rc);
+	int num_commands = GET_NEXT(values, param_max_offset, rc);
 	int *updt_params, i, prev_enable_flag;
 	uint32_t params_length = (MAX_INBAND_PARAM_SZ);
-	int rc = 0;
 
 	pr_debug("%s\n", __func__);
-	if (!ac) {
+	if (!ac || (devices == -EINVAL) || (num_commands == -EINVAL)) {
 		pr_err("%s: cannot set audio effects\n", __func__);
 		return -EINVAL;
 	}
@@ -41,10 +61,14 @@
 	updt_params = (int *)params;
 	params_length = 0;
 	for (i = 0; i < num_commands; i++) {
-		uint32_t command_id = *values++;
-		uint32_t command_config_state = *values++;
-		uint32_t index_offset = *values++;
-		uint32_t length = *values++;
+		uint32_t command_id =
+			GET_NEXT(values, param_max_offset, rc);
+		uint32_t command_config_state =
+			GET_NEXT(values, param_max_offset, rc);
+		uint32_t index_offset =
+			GET_NEXT(values, param_max_offset, rc);
+		uint32_t length =
+			GET_NEXT(values, param_max_offset, rc);
 		switch (command_id) {
 		case VIRTUALIZER_ENABLE:
 			if (length != 1 || index_offset != 0) {
@@ -53,17 +77,26 @@
 				goto invalid_config;
 			}
 			prev_enable_flag = virtualizer->enable_flag;
-			virtualizer->enable_flag = *values++;
+			virtualizer->enable_flag =
+				GET_NEXT(values, param_max_offset, rc);
 			pr_debug("%s:VIRT ENABLE prev:%d, new:%d\n", __func__,
 				prev_enable_flag, virtualizer->enable_flag);
 			if (prev_enable_flag != virtualizer->enable_flag) {
-				*updt_params++ = AUDPROC_MODULE_ID_VIRTUALIZER;
-				*updt_params++ =
-					AUDPROC_PARAM_ID_VIRTUALIZER_ENABLE;
-				*updt_params++ = VIRTUALIZER_ENABLE_PARAM_SZ;
-				*updt_params++ = virtualizer->enable_flag;
 				params_length += COMMAND_PAYLOAD_SZ +
 					VIRTUALIZER_ENABLE_PARAM_SZ;
+				CHECK_PARAM_LEN(params_length,
+						MAX_INBAND_PARAM_SZ,
+						"VIRT ENABLE", rc);
+				if (rc != 0)
+					break;
+				*updt_params++ =
+				AUDPROC_MODULE_ID_VIRTUALIZER;
+				*updt_params++ =
+				AUDPROC_PARAM_ID_VIRTUALIZER_ENABLE;
+				*updt_params++ =
+				VIRTUALIZER_ENABLE_PARAM_SZ;
+				*updt_params++ =
+				virtualizer->enable_flag;
 			}
 			break;
 		case VIRTUALIZER_STRENGTH:
@@ -72,17 +105,26 @@
 				rc = -EINVAL;
 				goto invalid_config;
 			}
-			virtualizer->strength = *values++;
+			virtualizer->strength =
+				GET_NEXT(values, param_max_offset, rc);
 			pr_debug("%s: VIRT STRENGTH val: %d\n",
 					__func__, virtualizer->strength);
 			if (command_config_state == CONFIG_SET) {
-				*updt_params++ = AUDPROC_MODULE_ID_VIRTUALIZER;
-				*updt_params++ =
-					AUDPROC_PARAM_ID_VIRTUALIZER_STRENGTH;
-				*updt_params++ = VIRTUALIZER_STRENGTH_PARAM_SZ;
-				*updt_params++ = virtualizer->strength;
 				params_length += COMMAND_PAYLOAD_SZ +
 					VIRTUALIZER_STRENGTH_PARAM_SZ;
+				CHECK_PARAM_LEN(params_length,
+						MAX_INBAND_PARAM_SZ,
+						"VIRT STRENGTH", rc);
+				if (rc != 0)
+					break;
+				*updt_params++ =
+					AUDPROC_MODULE_ID_VIRTUALIZER;
+				*updt_params++ =
+					AUDPROC_PARAM_ID_VIRTUALIZER_STRENGTH;
+				*updt_params++ =
+					VIRTUALIZER_STRENGTH_PARAM_SZ;
+				*updt_params++ =
+					virtualizer->strength;
 			}
 			break;
 		case VIRTUALIZER_OUT_TYPE:
@@ -91,17 +133,26 @@
 				rc = -EINVAL;
 				goto invalid_config;
 			}
-			virtualizer->out_type = *values++;
+			virtualizer->out_type =
+				GET_NEXT(values, param_max_offset, rc);
 			pr_debug("%s: VIRT OUT_TYPE val:%d\n",
 				__func__, virtualizer->out_type);
 			if (command_config_state == CONFIG_SET) {
-				*updt_params++ = AUDPROC_MODULE_ID_VIRTUALIZER;
-				*updt_params++ =
-					AUDPROC_PARAM_ID_VIRTUALIZER_OUT_TYPE;
-				*updt_params++ = VIRTUALIZER_OUT_TYPE_PARAM_SZ;
-				*updt_params++ = virtualizer->out_type;
 				params_length += COMMAND_PAYLOAD_SZ +
 					VIRTUALIZER_OUT_TYPE_PARAM_SZ;
+				CHECK_PARAM_LEN(params_length,
+						MAX_INBAND_PARAM_SZ,
+						"VIRT OUT_TYPE", rc);
+				if (rc != 0)
+					break;
+				*updt_params++ =
+					AUDPROC_MODULE_ID_VIRTUALIZER;
+				*updt_params++ =
+					AUDPROC_PARAM_ID_VIRTUALIZER_OUT_TYPE;
+				*updt_params++ =
+					VIRTUALIZER_OUT_TYPE_PARAM_SZ;
+				*updt_params++ =
+					virtualizer->out_type;
 			}
 			break;
 		case VIRTUALIZER_GAIN_ADJUST:
@@ -110,18 +161,26 @@
 				rc = -EINVAL;
 				goto invalid_config;
 			}
-			virtualizer->gain_adjust = *values++;
+			virtualizer->gain_adjust =
+				GET_NEXT(values, param_max_offset, rc);
 			pr_debug("%s: VIRT GAIN_ADJUST val:%d\n",
 				__func__, virtualizer->gain_adjust);
 			if (command_config_state == CONFIG_SET) {
-				*updt_params++ = AUDPROC_MODULE_ID_VIRTUALIZER;
-				*updt_params++ =
-				       AUDPROC_PARAM_ID_VIRTUALIZER_GAIN_ADJUST;
-				*updt_params++ =
-					VIRTUALIZER_GAIN_ADJUST_PARAM_SZ;
-				*updt_params++ = virtualizer->gain_adjust;
 				params_length += COMMAND_PAYLOAD_SZ +
 					VIRTUALIZER_GAIN_ADJUST_PARAM_SZ;
+				CHECK_PARAM_LEN(params_length,
+						MAX_INBAND_PARAM_SZ,
+						"VIRT GAIN_ADJUST", rc);
+				if (rc != 0)
+					break;
+				*updt_params++ =
+				AUDPROC_MODULE_ID_VIRTUALIZER;
+				*updt_params++ =
+				AUDPROC_PARAM_ID_VIRTUALIZER_GAIN_ADJUST;
+				*updt_params++ =
+				VIRTUALIZER_GAIN_ADJUST_PARAM_SZ;
+				*updt_params++ =
+				virtualizer->gain_adjust;
 			}
 			break;
 		default:
@@ -129,7 +188,7 @@
 			break;
 		}
 	}
-	if (params_length)
+	if (params_length && (rc == 0))
 		q6asm_send_audio_effects_params(ac, params,
 						params_length);
 invalid_config:
@@ -141,15 +200,16 @@
 				     struct reverb_params *reverb,
 				     long *values)
 {
-	int devices = *values++;
-	int num_commands = *values++;
-	char *params;
+	long *param_max_offset = values + MAX_PP_PARAMS_SZ - 1;
+	char *params = NULL;
+	int rc = 0;
+	int devices = GET_NEXT(values, param_max_offset, rc);
+	int num_commands = GET_NEXT(values, param_max_offset, rc);
 	int *updt_params, i, prev_enable_flag;
 	uint32_t params_length = (MAX_INBAND_PARAM_SZ);
-	int rc = 0;
 
 	pr_debug("%s\n", __func__);
-	if (!ac) {
+	if (!ac || (devices == -EINVAL) || (num_commands == -EINVAL)) {
 		pr_err("%s: cannot set audio effects\n", __func__);
 		return -EINVAL;
 	}
@@ -162,10 +222,14 @@
 	updt_params = (int *)params;
 	params_length = 0;
 	for (i = 0; i < num_commands; i++) {
-		uint32_t command_id = *values++;
-		uint32_t command_config_state = *values++;
-		uint32_t index_offset = *values++;
-		uint32_t length = *values++;
+		uint32_t command_id =
+			GET_NEXT(values, param_max_offset, rc);
+		uint32_t command_config_state =
+			GET_NEXT(values, param_max_offset, rc);
+		uint32_t index_offset =
+			GET_NEXT(values, param_max_offset, rc);
+		uint32_t length =
+			GET_NEXT(values, param_max_offset, rc);
 		switch (command_id) {
 		case REVERB_ENABLE:
 			if (length != 1 || index_offset != 0) {
@@ -174,16 +238,26 @@
 				goto invalid_config;
 			}
 			prev_enable_flag = reverb->enable_flag;
-			reverb->enable_flag = *values++;
+			reverb->enable_flag =
+				GET_NEXT(values, param_max_offset, rc);
 			pr_debug("%s:REVERB_ENABLE prev:%d,new:%d\n", __func__,
 					prev_enable_flag, reverb->enable_flag);
 			if (prev_enable_flag != reverb->enable_flag) {
-				*updt_params++ = AUDPROC_MODULE_ID_REVERB;
-				*updt_params++ = AUDPROC_PARAM_ID_REVERB_ENABLE;
-				*updt_params++ = REVERB_ENABLE_PARAM_SZ;
-				*updt_params++ = reverb->enable_flag;
 				params_length += COMMAND_PAYLOAD_SZ +
 					REVERB_ENABLE_PARAM_SZ;
+				CHECK_PARAM_LEN(params_length,
+						MAX_INBAND_PARAM_SZ,
+						"REVERB_ENABLE", rc);
+				if (rc != 0)
+					break;
+				*updt_params++ =
+					AUDPROC_MODULE_ID_REVERB;
+				*updt_params++ =
+					AUDPROC_PARAM_ID_REVERB_ENABLE;
+				*updt_params++ =
+					REVERB_ENABLE_PARAM_SZ;
+				*updt_params++ =
+					reverb->enable_flag;
 			}
 			break;
 		case REVERB_MODE:
@@ -192,16 +266,26 @@
 				rc = -EINVAL;
 				goto invalid_config;
 			}
-			reverb->mode = *values++;
+			reverb->mode =
+				GET_NEXT(values, param_max_offset, rc);
 			pr_debug("%s: REVERB_MODE val:%d\n",
 				__func__, reverb->mode);
 			if (command_config_state == CONFIG_SET) {
-				*updt_params++ = AUDPROC_MODULE_ID_REVERB;
-				*updt_params++ = AUDPROC_PARAM_ID_REVERB_MODE;
-				*updt_params++ = REVERB_MODE_PARAM_SZ;
-				*updt_params++ = reverb->mode;
 				params_length += COMMAND_PAYLOAD_SZ +
 					REVERB_MODE_PARAM_SZ;
+				CHECK_PARAM_LEN(params_length,
+						MAX_INBAND_PARAM_SZ,
+						"REVERB_MODE", rc);
+				if (rc != 0)
+					break;
+				*updt_params++ =
+					AUDPROC_MODULE_ID_REVERB;
+				*updt_params++ =
+					AUDPROC_PARAM_ID_REVERB_MODE;
+				*updt_params++ =
+					REVERB_MODE_PARAM_SZ;
+				*updt_params++ =
+					reverb->mode;
 			}
 			break;
 		case REVERB_PRESET:
@@ -210,16 +294,26 @@
 				rc = -EINVAL;
 				goto invalid_config;
 			}
-			reverb->preset = *values++;
+			reverb->preset =
+				GET_NEXT(values, param_max_offset, rc);
 			pr_debug("%s: REVERB_PRESET val:%d\n",
 					__func__, reverb->preset);
 			if (command_config_state == CONFIG_SET) {
-				*updt_params++ = AUDPROC_MODULE_ID_REVERB;
-				*updt_params++ = AUDPROC_PARAM_ID_REVERB_PRESET;
-				*updt_params++ = REVERB_PRESET_PARAM_SZ;
-				*updt_params++ = reverb->preset;
 				params_length += COMMAND_PAYLOAD_SZ +
 					REVERB_PRESET_PARAM_SZ;
+				CHECK_PARAM_LEN(params_length,
+						MAX_INBAND_PARAM_SZ,
+						"REVERB_PRESET", rc);
+				if (rc != 0)
+					break;
+				*updt_params++ =
+					AUDPROC_MODULE_ID_REVERB;
+				*updt_params++ =
+					AUDPROC_PARAM_ID_REVERB_PRESET;
+				*updt_params++ =
+					REVERB_PRESET_PARAM_SZ;
+				*updt_params++ =
+					reverb->preset;
 			}
 			break;
 		case REVERB_WET_MIX:
@@ -228,17 +322,26 @@
 				rc = -EINVAL;
 				goto invalid_config;
 			}
-			reverb->wet_mix = *values++;
+			reverb->wet_mix =
+				GET_NEXT(values, param_max_offset, rc);
 			pr_debug("%s: REVERB_WET_MIX val:%d\n",
 				__func__, reverb->wet_mix);
 			if (command_config_state == CONFIG_SET) {
-				*updt_params++ = AUDPROC_MODULE_ID_REVERB;
-				*updt_params++ =
-					AUDPROC_PARAM_ID_REVERB_WET_MIX;
-				*updt_params++ = REVERB_WET_MIX_PARAM_SZ;
-				*updt_params++ = reverb->wet_mix;
 				params_length += COMMAND_PAYLOAD_SZ +
 					REVERB_WET_MIX_PARAM_SZ;
+				CHECK_PARAM_LEN(params_length,
+						MAX_INBAND_PARAM_SZ,
+						"REVERB_WET_MIX", rc);
+				if (rc != 0)
+					break;
+				*updt_params++ =
+					AUDPROC_MODULE_ID_REVERB;
+				*updt_params++ =
+					AUDPROC_PARAM_ID_REVERB_WET_MIX;
+				*updt_params++ =
+					REVERB_WET_MIX_PARAM_SZ;
+				*updt_params++ =
+					reverb->wet_mix;
 			}
 			break;
 		case REVERB_GAIN_ADJUST:
@@ -247,17 +350,26 @@
 				rc = -EINVAL;
 				goto invalid_config;
 			}
-			reverb->gain_adjust = *values++;
+			reverb->gain_adjust =
+				GET_NEXT(values, param_max_offset, rc);
 			pr_debug("%s: REVERB_GAIN_ADJUST val:%d\n",
 					__func__, reverb->gain_adjust);
 			if (command_config_state == CONFIG_SET) {
-				*updt_params++ = AUDPROC_MODULE_ID_REVERB;
-				*updt_params++ =
-					AUDPROC_PARAM_ID_REVERB_GAIN_ADJUST;
-				*updt_params++ = REVERB_GAIN_ADJUST_PARAM_SZ;
-				*updt_params++ = reverb->gain_adjust;
 				params_length += COMMAND_PAYLOAD_SZ +
 					REVERB_GAIN_ADJUST_PARAM_SZ;
+				CHECK_PARAM_LEN(params_length,
+						MAX_INBAND_PARAM_SZ,
+						"REVERB_GAIN_ADJUST", rc);
+				if (rc != 0)
+					break;
+				*updt_params++ =
+					AUDPROC_MODULE_ID_REVERB;
+				*updt_params++ =
+					AUDPROC_PARAM_ID_REVERB_GAIN_ADJUST;
+				*updt_params++ =
+					REVERB_GAIN_ADJUST_PARAM_SZ;
+				*updt_params++ =
+					reverb->gain_adjust;
 			}
 			break;
 		case REVERB_ROOM_LEVEL:
@@ -266,17 +378,26 @@
 				rc = -EINVAL;
 				goto invalid_config;
 			}
-			reverb->room_level = *values++;
+			reverb->room_level =
+				GET_NEXT(values, param_max_offset, rc);
 			pr_debug("%s: REVERB_ROOM_LEVEL val:%d\n",
 				__func__, reverb->room_level);
 			if (command_config_state == CONFIG_SET) {
-				*updt_params++ = AUDPROC_MODULE_ID_REVERB;
-				*updt_params++ =
-					AUDPROC_PARAM_ID_REVERB_ROOM_LEVEL;
-				*updt_params++ = REVERB_ROOM_LEVEL_PARAM_SZ;
-				*updt_params++ = reverb->room_level;
 				params_length += COMMAND_PAYLOAD_SZ +
 					REVERB_ROOM_LEVEL_PARAM_SZ;
+				CHECK_PARAM_LEN(params_length,
+						MAX_INBAND_PARAM_SZ,
+						"REVERB_ROOM_LEVEL", rc);
+				if (rc != 0)
+					break;
+				*updt_params++ =
+					AUDPROC_MODULE_ID_REVERB;
+				*updt_params++ =
+					AUDPROC_PARAM_ID_REVERB_ROOM_LEVEL;
+				*updt_params++ =
+					REVERB_ROOM_LEVEL_PARAM_SZ;
+				*updt_params++ =
+					reverb->room_level;
 			}
 			break;
 		case REVERB_ROOM_HF_LEVEL:
@@ -285,17 +406,26 @@
 				rc = -EINVAL;
 				goto invalid_config;
 			}
-			reverb->room_hf_level = *values++;
+			reverb->room_hf_level =
+				GET_NEXT(values, param_max_offset, rc);
 			pr_debug("%s: REVERB_ROOM_HF_LEVEL val%d\n",
 				__func__, reverb->room_hf_level);
 			if (command_config_state == CONFIG_SET) {
-				*updt_params++ = AUDPROC_MODULE_ID_REVERB;
-				*updt_params++ =
-					AUDPROC_PARAM_ID_REVERB_ROOM_HF_LEVEL;
-				*updt_params++ = REVERB_ROOM_HF_LEVEL_PARAM_SZ;
-				*updt_params++ = reverb->room_hf_level;
 				params_length += COMMAND_PAYLOAD_SZ +
 					REVERB_ROOM_HF_LEVEL_PARAM_SZ;
+				CHECK_PARAM_LEN(params_length,
+						MAX_INBAND_PARAM_SZ,
+						"REVERB_ROOM_HF_LEVEL", rc);
+				if (rc != 0)
+					break;
+				*updt_params++ =
+					AUDPROC_MODULE_ID_REVERB;
+				*updt_params++ =
+					AUDPROC_PARAM_ID_REVERB_ROOM_HF_LEVEL;
+				*updt_params++ =
+					REVERB_ROOM_HF_LEVEL_PARAM_SZ;
+				*updt_params++ =
+					reverb->room_hf_level;
 			}
 			break;
 		case REVERB_DECAY_TIME:
@@ -304,17 +434,26 @@
 				rc = -EINVAL;
 				goto invalid_config;
 			}
-			reverb->decay_time = *values++;
+			reverb->decay_time =
+				GET_NEXT(values, param_max_offset, rc);
 			pr_debug("%s: REVERB_DECAY_TIME val:%d\n",
 				__func__, reverb->decay_time);
 			if (command_config_state == CONFIG_SET) {
-				*updt_params++ = AUDPROC_MODULE_ID_REVERB;
-				*updt_params++ =
-					AUDPROC_PARAM_ID_REVERB_DECAY_TIME;
-				*updt_params++ = REVERB_DECAY_TIME_PARAM_SZ;
-				*updt_params++ = reverb->decay_time;
 				params_length += COMMAND_PAYLOAD_SZ +
 					REVERB_DECAY_TIME_PARAM_SZ;
+				CHECK_PARAM_LEN(params_length,
+						MAX_INBAND_PARAM_SZ,
+						"REVERB_DECAY_TIME", rc);
+				if (rc != 0)
+					break;
+				*updt_params++ =
+					AUDPROC_MODULE_ID_REVERB;
+				*updt_params++ =
+					AUDPROC_PARAM_ID_REVERB_DECAY_TIME;
+				*updt_params++ =
+					REVERB_DECAY_TIME_PARAM_SZ;
+				*updt_params++ =
+					reverb->decay_time;
 			}
 			break;
 		case REVERB_DECAY_HF_RATIO:
@@ -323,17 +462,26 @@
 				rc = -EINVAL;
 				goto invalid_config;
 			}
-			reverb->decay_hf_ratio = *values++;
+			reverb->decay_hf_ratio =
+				GET_NEXT(values, param_max_offset, rc);
 			pr_debug("%s: REVERB_DECAY_HF_RATIO val%d\n",
 				__func__, reverb->decay_hf_ratio);
 			if (command_config_state == CONFIG_SET) {
-				*updt_params++ = AUDPROC_MODULE_ID_REVERB;
-				*updt_params++ =
-					AUDPROC_PARAM_ID_REVERB_DECAY_HF_RATIO;
-				*updt_params++ = REVERB_DECAY_HF_RATIO_PARAM_SZ;
-				*updt_params++ = reverb->decay_hf_ratio;
 				params_length += COMMAND_PAYLOAD_SZ +
 					REVERB_DECAY_HF_RATIO_PARAM_SZ;
+				CHECK_PARAM_LEN(params_length,
+						MAX_INBAND_PARAM_SZ,
+						"REVERB_DECAY_HF_RATIO", rc);
+				if (rc != 0)
+					break;
+				*updt_params++ =
+					AUDPROC_MODULE_ID_REVERB;
+				*updt_params++ =
+					AUDPROC_PARAM_ID_REVERB_DECAY_HF_RATIO;
+				*updt_params++ =
+					REVERB_DECAY_HF_RATIO_PARAM_SZ;
+				*updt_params++ =
+					reverb->decay_hf_ratio;
 			}
 			break;
 		case REVERB_REFLECTIONS_LEVEL:
@@ -342,18 +490,26 @@
 				rc = -EINVAL;
 				goto invalid_config;
 			}
-			reverb->reflections_level = *values++;
+			reverb->reflections_level =
+				GET_NEXT(values, param_max_offset, rc);
 			pr_debug("%s: REVERB_REFLECTIONS_LEVEL val:%d\n",
 				__func__, reverb->reflections_level);
 			if (command_config_state == CONFIG_SET) {
-				*updt_params++ = AUDPROC_MODULE_ID_REVERB;
-				*updt_params++ =
-				      AUDPROC_PARAM_ID_REVERB_REFLECTIONS_LEVEL;
-				*updt_params++ =
-					REVERB_REFLECTIONS_LEVEL_PARAM_SZ;
-				*updt_params++ = reverb->reflections_level;
 				params_length += COMMAND_PAYLOAD_SZ +
 					REVERB_REFLECTIONS_LEVEL_PARAM_SZ;
+				CHECK_PARAM_LEN(params_length,
+						MAX_INBAND_PARAM_SZ,
+						"REVERB_REFLECTIONS_LEVEL", rc);
+				if (rc != 0)
+					break;
+				*updt_params++ =
+				AUDPROC_MODULE_ID_REVERB;
+				*updt_params++ =
+				AUDPROC_PARAM_ID_REVERB_REFLECTIONS_LEVEL;
+				*updt_params++ =
+				REVERB_REFLECTIONS_LEVEL_PARAM_SZ;
+				*updt_params++ =
+				reverb->reflections_level;
 			}
 			break;
 		case REVERB_REFLECTIONS_DELAY:
@@ -362,18 +518,26 @@
 				rc = -EINVAL;
 				goto invalid_config;
 			}
-			reverb->reflections_delay = *values++;
+			reverb->reflections_delay =
+				GET_NEXT(values, param_max_offset, rc);
 			pr_debug("%s: REVERB_REFLECTIONS_DELAY val:%d\n",
 				__func__, reverb->reflections_delay);
 			if (command_config_state == CONFIG_SET) {
-				*updt_params++ = AUDPROC_MODULE_ID_REVERB;
-				*updt_params++ =
-				      AUDPROC_PARAM_ID_REVERB_REFLECTIONS_DELAY;
-				*updt_params++ =
-					REVERB_REFLECTIONS_DELAY_PARAM_SZ;
-				*updt_params++ = reverb->reflections_delay;
 				params_length += COMMAND_PAYLOAD_SZ +
 					REVERB_REFLECTIONS_DELAY_PARAM_SZ;
+				CHECK_PARAM_LEN(params_length,
+						MAX_INBAND_PARAM_SZ,
+						"REVERB_REFLECTIONS_DELAY", rc);
+				if (rc != 0)
+					break;
+				*updt_params++ =
+				AUDPROC_MODULE_ID_REVERB;
+				*updt_params++ =
+				AUDPROC_PARAM_ID_REVERB_REFLECTIONS_DELAY;
+				*updt_params++ =
+				REVERB_REFLECTIONS_DELAY_PARAM_SZ;
+				*updt_params++ =
+				reverb->reflections_delay;
 			}
 			break;
 		case REVERB_LEVEL:
@@ -382,16 +546,26 @@
 				rc = -EINVAL;
 				goto invalid_config;
 			}
-			reverb->level = *values++;
+			reverb->level =
+				GET_NEXT(values, param_max_offset, rc);
 			pr_debug("%s: REVERB_LEVEL val:%d\n",
 				__func__, reverb->level);
 			if (command_config_state == CONFIG_SET) {
-				*updt_params++ = AUDPROC_MODULE_ID_REVERB;
-				*updt_params++ = AUDPROC_PARAM_ID_REVERB_LEVEL;
-				*updt_params++ = REVERB_LEVEL_PARAM_SZ;
-				*updt_params++ = reverb->level;
 				params_length += COMMAND_PAYLOAD_SZ +
 					REVERB_LEVEL_PARAM_SZ;
+				CHECK_PARAM_LEN(params_length,
+						MAX_INBAND_PARAM_SZ,
+						"REVERB_LEVEL", rc);
+				if (rc != 0)
+					break;
+				*updt_params++ =
+					AUDPROC_MODULE_ID_REVERB;
+				*updt_params++ =
+					AUDPROC_PARAM_ID_REVERB_LEVEL;
+				*updt_params++ =
+					REVERB_LEVEL_PARAM_SZ;
+				*updt_params++ =
+					reverb->level;
 			}
 			break;
 		case REVERB_DELAY:
@@ -400,16 +574,26 @@
 				rc = -EINVAL;
 				goto invalid_config;
 			}
-			reverb->delay = *values++;
+			reverb->delay =
+				GET_NEXT(values, param_max_offset, rc);
 			pr_debug("%s:REVERB_DELAY val:%d\n",
 					__func__, reverb->delay);
 			if (command_config_state == CONFIG_SET) {
-				*updt_params++ = AUDPROC_MODULE_ID_REVERB;
-				*updt_params++ = AUDPROC_PARAM_ID_REVERB_DELAY;
-				*updt_params++ = REVERB_DELAY_PARAM_SZ;
-				*updt_params++ = reverb->delay;
 				params_length += COMMAND_PAYLOAD_SZ +
 					REVERB_DELAY_PARAM_SZ;
+				CHECK_PARAM_LEN(params_length,
+						MAX_INBAND_PARAM_SZ,
+						"REVERB_DELAY", rc);
+				if (rc != 0)
+					break;
+				*updt_params++ =
+					AUDPROC_MODULE_ID_REVERB;
+				*updt_params++ =
+					AUDPROC_PARAM_ID_REVERB_DELAY;
+				*updt_params++ =
+					REVERB_DELAY_PARAM_SZ;
+				*updt_params++ =
+					reverb->delay;
 			}
 			break;
 		case REVERB_DIFFUSION:
@@ -418,17 +602,26 @@
 				rc = -EINVAL;
 				goto invalid_config;
 			}
-			reverb->diffusion = *values++;
+			reverb->diffusion =
+				GET_NEXT(values, param_max_offset, rc);
 			pr_debug("%s: REVERB_DIFFUSION val:%d\n",
 				__func__, reverb->diffusion);
 			if (command_config_state == CONFIG_SET) {
-				*updt_params++ = AUDPROC_MODULE_ID_REVERB;
-				*updt_params++ =
-					AUDPROC_PARAM_ID_REVERB_DIFFUSION;
-				*updt_params++ = REVERB_DIFFUSION_PARAM_SZ;
-				*updt_params++ = reverb->diffusion;
 				params_length += COMMAND_PAYLOAD_SZ +
 					REVERB_DIFFUSION_PARAM_SZ;
+				CHECK_PARAM_LEN(params_length,
+						MAX_INBAND_PARAM_SZ,
+						"REVERB_DIFFUSION", rc);
+				if (rc != 0)
+					break;
+				*updt_params++ =
+					AUDPROC_MODULE_ID_REVERB;
+				*updt_params++ =
+					AUDPROC_PARAM_ID_REVERB_DIFFUSION;
+				*updt_params++ =
+					REVERB_DIFFUSION_PARAM_SZ;
+				*updt_params++ =
+					reverb->diffusion;
 			}
 			break;
 		case REVERB_DENSITY:
@@ -437,17 +630,26 @@
 				rc = -EINVAL;
 				goto invalid_config;
 			}
-			reverb->density = *values++;
+			reverb->density =
+				GET_NEXT(values, param_max_offset, rc);
 			pr_debug("%s: REVERB_DENSITY val:%d\n",
 				__func__, reverb->density);
 			if (command_config_state == CONFIG_SET) {
-				*updt_params++ = AUDPROC_MODULE_ID_REVERB;
-				*updt_params++ =
-					AUDPROC_PARAM_ID_REVERB_DENSITY;
-				*updt_params++ = REVERB_DENSITY_PARAM_SZ;
-				*updt_params++ = reverb->density;
 				params_length += COMMAND_PAYLOAD_SZ +
 					REVERB_DENSITY_PARAM_SZ;
+				CHECK_PARAM_LEN(params_length,
+						MAX_INBAND_PARAM_SZ,
+						"REVERB_DENSITY", rc);
+				if (rc != 0)
+					break;
+				*updt_params++ =
+					AUDPROC_MODULE_ID_REVERB;
+				*updt_params++ =
+					AUDPROC_PARAM_ID_REVERB_DENSITY;
+				*updt_params++ =
+					REVERB_DENSITY_PARAM_SZ;
+				*updt_params++ =
+					reverb->density;
 			}
 			break;
 		default:
@@ -455,7 +657,7 @@
 			break;
 		}
 	}
-	if (params_length)
+	if (params_length && (rc == 0))
 		q6asm_send_audio_effects_params(ac, params,
 						params_length);
 invalid_config:
@@ -467,15 +669,16 @@
 					struct bass_boost_params *bass_boost,
 					long *values)
 {
-	int devices = *values++;
-	int num_commands = *values++;
-	char *params;
+	long *param_max_offset = values + MAX_PP_PARAMS_SZ - 1;
+	char *params = NULL;
+	int rc = 0;
+	int devices = GET_NEXT(values, param_max_offset, rc);
+	int num_commands = GET_NEXT(values, param_max_offset, rc);
 	int *updt_params, i, prev_enable_flag;
 	uint32_t params_length = (MAX_INBAND_PARAM_SZ);
-	int rc = 0;
 
 	pr_debug("%s\n", __func__);
-	if (!ac) {
+	if (!ac || (devices == -EINVAL) || (num_commands == -EINVAL)) {
 		pr_err("%s: cannot set audio effects\n", __func__);
 		return -EINVAL;
 	}
@@ -488,10 +691,14 @@
 	updt_params = (int *)params;
 	params_length = 0;
 	for (i = 0; i < num_commands; i++) {
-		uint32_t command_id = *values++;
-		uint32_t command_config_state = *values++;
-		uint32_t index_offset = *values++;
-		uint32_t length = *values++;
+		uint32_t command_id =
+			GET_NEXT(values, param_max_offset, rc);
+		uint32_t command_config_state =
+			GET_NEXT(values, param_max_offset, rc);
+		uint32_t index_offset =
+			GET_NEXT(values, param_max_offset, rc);
+		uint32_t length =
+			GET_NEXT(values, param_max_offset, rc);
 		switch (command_id) {
 		case BASS_BOOST_ENABLE:
 			if (length != 1 || index_offset != 0) {
@@ -500,18 +707,27 @@
 				goto invalid_config;
 			}
 			prev_enable_flag = bass_boost->enable_flag;
-			bass_boost->enable_flag = *values++;
+			bass_boost->enable_flag =
+				GET_NEXT(values, param_max_offset, rc);
 			pr_debug("%s: BASS_BOOST_ENABLE prev:%d new:%d\n",
 				__func__, prev_enable_flag,
 				bass_boost->enable_flag);
 			if (prev_enable_flag != bass_boost->enable_flag) {
-				*updt_params++ = AUDPROC_MODULE_ID_BASS_BOOST;
-				*updt_params++ =
-					AUDPROC_PARAM_ID_BASS_BOOST_ENABLE;
-				*updt_params++ = BASS_BOOST_ENABLE_PARAM_SZ;
-				*updt_params++ = bass_boost->enable_flag;
 				params_length += COMMAND_PAYLOAD_SZ +
 					BASS_BOOST_ENABLE_PARAM_SZ;
+				CHECK_PARAM_LEN(params_length,
+						MAX_INBAND_PARAM_SZ,
+						"BASS_BOOST_ENABLE", rc);
+				if (rc != 0)
+					break;
+				*updt_params++ =
+					AUDPROC_MODULE_ID_BASS_BOOST;
+				*updt_params++ =
+					AUDPROC_PARAM_ID_BASS_BOOST_ENABLE;
+				*updt_params++ =
+					BASS_BOOST_ENABLE_PARAM_SZ;
+				*updt_params++ =
+					bass_boost->enable_flag;
 			}
 			break;
 		case BASS_BOOST_MODE:
@@ -520,17 +736,26 @@
 				rc = -EINVAL;
 				goto invalid_config;
 			}
-			bass_boost->mode = *values++;
+			bass_boost->mode =
+				GET_NEXT(values, param_max_offset, rc);
 			pr_debug("%s: BASS_BOOST_MODE val:%d\n",
 				__func__, bass_boost->mode);
 			if (command_config_state == CONFIG_SET) {
-				*updt_params++ = AUDPROC_MODULE_ID_BASS_BOOST;
-				*updt_params++ =
-					AUDPROC_PARAM_ID_BASS_BOOST_MODE;
-				*updt_params++ = BASS_BOOST_MODE_PARAM_SZ;
-				*updt_params++ = bass_boost->mode;
 				params_length += COMMAND_PAYLOAD_SZ +
 					BASS_BOOST_MODE_PARAM_SZ;
+				CHECK_PARAM_LEN(params_length,
+						MAX_INBAND_PARAM_SZ,
+						"BASS_BOOST_MODE", rc);
+				if (rc != 0)
+					break;
+				*updt_params++ =
+					AUDPROC_MODULE_ID_BASS_BOOST;
+				*updt_params++ =
+					AUDPROC_PARAM_ID_BASS_BOOST_MODE;
+				*updt_params++ =
+					BASS_BOOST_MODE_PARAM_SZ;
+				*updt_params++ =
+					bass_boost->mode;
 			}
 			break;
 		case BASS_BOOST_STRENGTH:
@@ -539,17 +764,26 @@
 				rc = -EINVAL;
 				goto invalid_config;
 			}
-			bass_boost->strength = *values++;
-			pr_debug("%s: BASS_BOOST_STRENGTHi val:%d\n",
+			bass_boost->strength =
+				GET_NEXT(values, param_max_offset, rc);
+			pr_debug("%s: BASS_BOOST_STRENGTH val:%d\n",
 				__func__, bass_boost->strength);
 			if (command_config_state == CONFIG_SET) {
-				*updt_params++ = AUDPROC_MODULE_ID_BASS_BOOST;
-				*updt_params++ =
-					AUDPROC_PARAM_ID_BASS_BOOST_STRENGTH;
-				*updt_params++ = BASS_BOOST_STRENGTH_PARAM_SZ;
-				*updt_params++ = bass_boost->strength;
 				params_length += COMMAND_PAYLOAD_SZ +
 					BASS_BOOST_STRENGTH_PARAM_SZ;
+				CHECK_PARAM_LEN(params_length,
+						MAX_INBAND_PARAM_SZ,
+						"BASS_BOOST_STRENGTH", rc);
+				if (rc != 0)
+					break;
+				*updt_params++ =
+					AUDPROC_MODULE_ID_BASS_BOOST;
+				*updt_params++ =
+					AUDPROC_PARAM_ID_BASS_BOOST_STRENGTH;
+				*updt_params++ =
+					BASS_BOOST_STRENGTH_PARAM_SZ;
+				*updt_params++ =
+					bass_boost->strength;
 			}
 			break;
 		default:
@@ -557,9 +791,11 @@
 			break;
 		}
 	}
-	if (params_length)
+	if (params_length && (rc == 0))
 		q6asm_send_audio_effects_params(ac, params,
 						params_length);
+	else
+		pr_debug("%s: did not send pp params\n", __func__);
 invalid_config:
 	kfree(params);
 	return rc;
@@ -569,15 +805,16 @@
 					 struct eq_params *eq,
 					 long *values)
 {
-	int devices = *values++;
-	int num_commands = *values++;
-	char *params;
+	long *param_max_offset = values + MAX_PP_PARAMS_SZ - 1;
+	char *params = NULL;
+	int rc = 0;
+	int devices = GET_NEXT(values, param_max_offset, rc);
+	int num_commands = GET_NEXT(values, param_max_offset, rc);
 	int *updt_params, i, prev_enable_flag;
 	uint32_t params_length = (MAX_INBAND_PARAM_SZ);
-	int rc = 0;
 
 	pr_debug("%s\n", __func__);
-	if (!ac) {
+	if (!ac || (devices == -EINVAL) || (num_commands == -EINVAL)) {
 		pr_err("%s: cannot set audio effects\n", __func__);
 		return -EINVAL;
 	}
@@ -590,11 +827,16 @@
 	updt_params = (int *)params;
 	params_length = 0;
 	for (i = 0; i < num_commands; i++) {
-		uint32_t command_id = *values++;
-		uint32_t command_config_state = *values++;
-		uint32_t index_offset = *values++;
-		uint32_t length = *values++;
-		int idx, j;
+		uint32_t command_id =
+			GET_NEXT(values, param_max_offset, rc);
+		uint32_t command_config_state =
+			GET_NEXT(values, param_max_offset, rc);
+		uint32_t index_offset =
+			GET_NEXT(values, param_max_offset, rc);
+		uint32_t length =
+			GET_NEXT(values, param_max_offset, rc);
+		uint32_t idx;
+		int j;
 		switch (command_id) {
 		case EQ_ENABLE:
 			if (length != 1 || index_offset != 0) {
@@ -603,17 +845,26 @@
 				goto invalid_config;
 			}
 			prev_enable_flag = eq->enable_flag;
-			eq->enable_flag = *values++;
+			eq->enable_flag =
+				GET_NEXT(values, param_max_offset, rc);
 			pr_debug("%s: EQ_ENABLE prev:%d new:%d\n", __func__,
 				prev_enable_flag, eq->enable_flag);
 			if (prev_enable_flag != eq->enable_flag) {
-				*updt_params++ =
-					AUDPROC_MODULE_ID_POPLESS_EQUALIZER;
-				*updt_params++ = AUDPROC_PARAM_ID_EQ_ENABLE;
-				*updt_params++ = EQ_ENABLE_PARAM_SZ;
-				*updt_params++ = eq->enable_flag;
 				params_length += COMMAND_PAYLOAD_SZ +
 					EQ_ENABLE_PARAM_SZ;
+				CHECK_PARAM_LEN(params_length,
+						MAX_INBAND_PARAM_SZ,
+						"EQ_ENABLE", rc);
+				if (rc != 0)
+					break;
+				*updt_params++ =
+					AUDPROC_MODULE_ID_POPLESS_EQUALIZER;
+				*updt_params++ =
+					AUDPROC_PARAM_ID_EQ_ENABLE;
+				*updt_params++ =
+					EQ_ENABLE_PARAM_SZ;
+				*updt_params++ =
+					eq->enable_flag;
 			}
 			break;
 		case EQ_CONFIG:
@@ -627,9 +878,12 @@
 				eq->config.eq_pregain, eq->config.preset_id);
 			for (idx = 0; idx < MAX_EQ_BANDS; idx++)
 				eq->per_band_cfg[idx].band_idx = -1;
-			eq->config.eq_pregain = *values++;
-			eq->config.preset_id = *values++;
-			eq->config.num_bands = *values++;
+			eq->config.eq_pregain =
+				GET_NEXT(values, param_max_offset, rc);
+			eq->config.preset_id =
+				GET_NEXT(values, param_max_offset, rc);
+			eq->config.num_bands =
+				GET_NEXT(values, param_max_offset, rc);
 			if (eq->config.num_bands > MAX_EQ_BANDS) {
 				pr_err("EQ_CONFIG:invalid num of bands\n");
 				rc = -EINVAL;
@@ -644,48 +898,59 @@
 				goto invalid_config;
 			}
 			for (j = 0; j < eq->config.num_bands; j++) {
-				idx = *values++;
+				idx = GET_NEXT(values, param_max_offset, rc);
 				if (idx >= MAX_EQ_BANDS) {
 					pr_err("EQ_CONFIG:invalid band index\n");
 					rc = -EINVAL;
 					goto invalid_config;
 				}
 				eq->per_band_cfg[idx].band_idx = idx;
-				eq->per_band_cfg[idx].filter_type = *values++;
+				eq->per_band_cfg[idx].filter_type =
+					GET_NEXT(values, param_max_offset, rc);
 				eq->per_band_cfg[idx].freq_millihertz =
-								*values++;
+					GET_NEXT(values, param_max_offset, rc);
 				eq->per_band_cfg[idx].gain_millibels =
-								*values++;
+					GET_NEXT(values, param_max_offset, rc);
 				eq->per_band_cfg[idx].quality_factor =
-								*values++;
+					GET_NEXT(values, param_max_offset, rc);
 			}
 			if (command_config_state == CONFIG_SET) {
 				int config_param_length = EQ_CONFIG_PARAM_SZ +
 					(EQ_CONFIG_PER_BAND_PARAM_SZ*
 					 eq->config.num_bands);
+				params_length += COMMAND_PAYLOAD_SZ +
+						config_param_length;
+				CHECK_PARAM_LEN(params_length,
+						MAX_INBAND_PARAM_SZ,
+						"EQ_CONFIG", rc);
+				if (rc != 0)
+					break;
 				*updt_params++ =
 					AUDPROC_MODULE_ID_POPLESS_EQUALIZER;
-				*updt_params++ = AUDPROC_PARAM_ID_EQ_CONFIG;
-				*updt_params++ = config_param_length;
-				*updt_params++ = eq->config.eq_pregain;
-				*updt_params++ = eq->config.preset_id;
-				*updt_params++ = eq->config.num_bands;
+				*updt_params++ =
+					AUDPROC_PARAM_ID_EQ_CONFIG;
+				*updt_params++ =
+					config_param_length;
+				*updt_params++ =
+					eq->config.eq_pregain;
+				*updt_params++ =
+					eq->config.preset_id;
+				*updt_params++ =
+					eq->config.num_bands;
 				for (idx = 0; idx < MAX_EQ_BANDS; idx++) {
 					if (eq->per_band_cfg[idx].band_idx < 0)
 						continue;
 					*updt_params++ =
-					  eq->per_band_cfg[idx].filter_type;
+					eq->per_band_cfg[idx].filter_type;
 					*updt_params++ =
-					  eq->per_band_cfg[idx].freq_millihertz;
+					eq->per_band_cfg[idx].freq_millihertz;
 					*updt_params++ =
-					  eq->per_band_cfg[idx].gain_millibels;
+					eq->per_band_cfg[idx].gain_millibels;
 					*updt_params++ =
-					  eq->per_band_cfg[idx].quality_factor;
+					eq->per_band_cfg[idx].quality_factor;
 					*updt_params++ =
-					  eq->per_band_cfg[idx].band_idx;
+					eq->per_band_cfg[idx].band_idx;
 				}
-				params_length += COMMAND_PAYLOAD_SZ +
-						config_param_length;
 			}
 			break;
 		case EQ_BAND_INDEX:
@@ -694,7 +959,7 @@
 				rc = -EINVAL;
 				goto invalid_config;
 			}
-			idx = *values++;
+			idx = GET_NEXT(values, param_max_offset, rc);
 			if (idx > MAX_EQ_BANDS) {
 				pr_err("EQ_BAND_INDEX:invalid band index\n");
 				rc = -EINVAL;
@@ -704,14 +969,21 @@
 			pr_debug("%s: EQ_BAND_INDEX val:%d\n",
 				__func__, eq->band_index);
 			if (command_config_state == CONFIG_SET) {
+				params_length += COMMAND_PAYLOAD_SZ +
+					EQ_BAND_INDEX_PARAM_SZ;
+				CHECK_PARAM_LEN(params_length,
+						MAX_INBAND_PARAM_SZ,
+						"EQ_BAND_INDEX", rc);
+				if (rc != 0)
+					break;
 				*updt_params++ =
 					AUDPROC_MODULE_ID_POPLESS_EQUALIZER;
 				*updt_params++ =
 					AUDPROC_PARAM_ID_EQ_BAND_INDEX;
-				*updt_params++ = EQ_BAND_INDEX_PARAM_SZ;
-				*updt_params++ = eq->band_index;
-				params_length += COMMAND_PAYLOAD_SZ +
+				*updt_params++ =
 					EQ_BAND_INDEX_PARAM_SZ;
+				*updt_params++ =
+					eq->band_index;
 			}
 			break;
 		case EQ_SINGLE_BAND_FREQ:
@@ -724,18 +996,26 @@
 				pr_err("EQ_SINGLE_BAND_FREQ:invalid index\n");
 				break;
 			}
-			eq->freq_millihertz = *values++;
+			eq->freq_millihertz =
+				GET_NEXT(values, param_max_offset, rc);
 			pr_debug("%s: EQ_SINGLE_BAND_FREQ idx:%d, val:%d\n",
 				__func__, eq->band_index, eq->freq_millihertz);
 			if (command_config_state == CONFIG_SET) {
+				params_length += COMMAND_PAYLOAD_SZ +
+					EQ_SINGLE_BAND_FREQ_PARAM_SZ;
+				CHECK_PARAM_LEN(params_length,
+						MAX_INBAND_PARAM_SZ,
+						"EQ_SINGLE_BAND_FREQ", rc);
+				if (rc != 0)
+					break;
 				*updt_params++ =
 					AUDPROC_MODULE_ID_POPLESS_EQUALIZER;
 				*updt_params++ =
 					AUDPROC_PARAM_ID_EQ_SINGLE_BAND_FREQ;
-				*updt_params++ = EQ_SINGLE_BAND_FREQ_PARAM_SZ;
-				*updt_params++ = eq->freq_millihertz;
-				params_length += COMMAND_PAYLOAD_SZ +
+				*updt_params++ =
 					EQ_SINGLE_BAND_FREQ_PARAM_SZ;
+				*updt_params++ =
+					eq->freq_millihertz;
 			}
 			break;
 		default:
@@ -743,9 +1023,11 @@
 			break;
 		}
 	}
-	if (params_length)
+	if (params_length && (rc == 0))
 		q6asm_send_audio_effects_params(ac, params,
 						params_length);
+	else
+		pr_debug("%s: did not send pp params\n", __func__);
 invalid_config:
 	kfree(params);
 	return rc;
diff --git a/sound/soc/msm/qdsp6v2/msm-audio-effects-q6-v2.h b/sound/soc/msm/qdsp6v2/msm-audio-effects-q6-v2.h
index 3d2e6d4..64c92fb 100644
--- a/sound/soc/msm/qdsp6v2/msm-audio-effects-q6-v2.h
+++ b/sound/soc/msm/qdsp6v2/msm-audio-effects-q6-v2.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2013, 2016, The Linux Foundation. All rights reserved.
  *
  * This 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,8 @@
 
 #include <sound/audio_effects.h>
 
+#define MAX_PP_PARAMS_SZ   128
+
 int msm_audio_effects_reverb_handler(struct audio_client *ac,
 				     struct reverb_params *reverb,
 				     long *values);
diff --git a/sound/soc/msm/qdsp6v2/msm-compress-q6-v2.c b/sound/soc/msm/qdsp6v2/msm-compress-q6-v2.c
index 70f5f60..d549c49 100644
--- a/sound/soc/msm/qdsp6v2/msm-compress-q6-v2.c
+++ b/sound/soc/msm/qdsp6v2/msm-compress-q6-v2.c
@@ -2082,7 +2082,7 @@
 					       struct snd_ctl_elem_info *uinfo)
 {
 	uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
-	uinfo->count = 128;
+	uinfo->count = MAX_PP_PARAMS_SZ;
 	uinfo->value.integer.min = 0;
 	uinfo->value.integer.max = 0xFFFFFFFF;
 	return 0;
diff --git a/sound/soc/msm/qdsp6v2/msm-lsm-client.c b/sound/soc/msm/qdsp6v2/msm-lsm-client.c
index 83d5416..6c7bf4e 100644
--- a/sound/soc/msm/qdsp6v2/msm-lsm-client.c
+++ b/sound/soc/msm/qdsp6v2/msm-lsm-client.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013-2015, Linux Foundation. All rights reserved.
+ * Copyright (c) 2013-2016, Linux Foundation. All rights reserved.
  *
  * This 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 @@
 #include "msm-pcm-routing-v2.h"
 
 #define CAPTURE_MIN_NUM_PERIODS     2
-#define CAPTURE_MAX_NUM_PERIODS     8
+#define CAPTURE_MAX_NUM_PERIODS     32
 #define CAPTURE_MAX_PERIOD_SIZE     4096
 #define CAPTURE_MIN_PERIOD_SIZE     320
 #define LISTEN_MAX_STATUS_PAYLOAD_SIZE 256
@@ -589,6 +589,9 @@
 		dev_err(rtd->dev,
 			"%s: Failed to set det_mode param, err = %d\n",
 			__func__, rc);
+
+	q6lsm_snd_model_buf_free(prtd->lsm_client);
+
 	return rc;
 }
 
@@ -960,6 +963,7 @@
 			"%s: Stopping LSM client session\n",
 			__func__);
 		if (prtd->lsm_client->started) {
+			int i;
 			if (prtd->lsm_client->lab_enable) {
 				atomic_set(&prtd->read_abort, 1);
 				if (prtd->lsm_client->lab_started) {
@@ -969,6 +973,9 @@
 							"%s: stop lab failed ret %d\n",
 							__func__, ret);
 					prtd->lsm_client->lab_started = false;
+					for (i = 0; i < prtd->lsm_client->hw_params.period_count; i++)
+						memset(prtd->lsm_client->lab_buffer[i].data, 0,
+							prtd->lsm_client->lab_buffer[i].size);
 				}
 			}
 			ret = q6lsm_stop(prtd->lsm_client, true);
@@ -1032,6 +1039,7 @@
 		dev_dbg(rtd->dev, "%s: stopping LAB\n", __func__);
 		if (prtd->lsm_client->lab_enable &&
 			prtd->lsm_client->lab_started) {
+			int i;
 			atomic_set(&prtd->read_abort, 1);
 			rc = q6lsm_stop_lab(prtd->lsm_client);
 			if (rc)
@@ -1040,6 +1048,9 @@
 					__func__,
 					prtd->lsm_client->session, rc);
 			prtd->lsm_client->lab_started = false;
+			for (i = 0; i < prtd->lsm_client->hw_params.period_count; i++)
+				memset(prtd->lsm_client->lab_buffer[i].data, 0,
+					prtd->lsm_client->lab_buffer[i].size);
 		}
 	break;
 	default:
@@ -1872,7 +1883,7 @@
 		return 0;
 	}
 	rc = wait_event_timeout(prtd->period_wait,
-		(atomic_read(&prtd->buf_count) |
+		(atomic_read(&prtd->buf_count) ||
 		atomic_read(&prtd->read_abort)), (2 * HZ));
 	if (!rc) {
 		dev_err(rtd->dev,
diff --git a/sound/soc/msm/qdsp6v2/msm-pcm-loopback-v2.c b/sound/soc/msm/qdsp6v2/msm-pcm-loopback-v2.c
index 293b3a9..511476b 100644
--- a/sound/soc/msm/qdsp6v2/msm-pcm-loopback-v2.c
+++ b/sound/soc/msm/qdsp6v2/msm-pcm-loopback-v2.c
@@ -330,13 +330,12 @@
 
 	dev_dbg(rtd->platform->dev, "%s: ASM loopback\n", __func__);
 
-	return snd_pcm_lib_alloc_vmalloc_buffer(substream,
-		params_buffer_bytes(params));
+	return 0;
 }
 
 static int msm_pcm_hw_free(struct snd_pcm_substream *substream)
 {
-	return snd_pcm_lib_free_vmalloc_buffer(substream);
+	return 0;
 }
 
 static struct snd_pcm_ops msm_pcm_ops = {
diff --git a/sound/soc/msm/qdsp6v2/q6adm.c b/sound/soc/msm/qdsp6v2/q6adm.c
index 0f445ad..d8d71256 100644
--- a/sound/soc/msm/qdsp6v2/q6adm.c
+++ b/sound/soc/msm/qdsp6v2/q6adm.c
@@ -836,7 +836,7 @@
 		idx) &&
 		(ARRAY_SIZE(adm_get_parameters) >=
 		1+adm_get_parameters[idx]+idx) &&
-		(params_length/sizeof(int) >=
+		(params_length/sizeof(uint32_t) >=
 		adm_get_parameters[idx])) {
 		for (i = 0; i < adm_get_parameters[idx]; i++)
 			params_data[i] = adm_get_parameters[1+i+idx];
@@ -1070,17 +1070,23 @@
 			idx = ADM_GET_PARAMETER_LENGTH * copp_idx;
 			if ((payload[0] == 0) && (data->payload_size >
 				(4 * sizeof(*payload))) &&
-				(data->payload_size/sizeof(*payload)-4 >=
+				(data->payload_size - 4 >=
 				payload[3]) &&
 				(ARRAY_SIZE(adm_get_parameters) >
 				idx) &&
 				(ARRAY_SIZE(adm_get_parameters)-idx-1 >=
 				payload[3])) {
-				adm_get_parameters[idx] = payload[3];
+				adm_get_parameters[idx] = payload[3] /
+							sizeof(uint32_t);
+				/*
+				 * payload[3] is param_size which is
+				 * expressed in number of bytes
+				 */
 				pr_debug("%s: GET_PP PARAM:received parameter length: 0x%x\n",
 					__func__, adm_get_parameters[idx]);
 				/* storing param size then params */
-				for (i = 0; i < payload[3]; i++)
+				for (i = 0; i < payload[3] /
+						sizeof(uint32_t); i++)
 					adm_get_parameters[idx+1+i] =
 							payload[4+i];
 			} else {
diff --git a/sound/soc/msm/qdsp6v2/q6asm.c b/sound/soc/msm/qdsp6v2/q6asm.c
index 3e38e69..618efed 100644
--- a/sound/soc/msm/qdsp6v2/q6asm.c
+++ b/sound/soc/msm/qdsp6v2/q6asm.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012-2014, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2012-2014, 2016, The Linux Foundation. All rights reserved.
  * Author: Brian Swetland <swetland@google.com>
  *
  * This software is licensed under the terms of the GNU General Public
@@ -1141,6 +1141,12 @@
 
 	ac->port[dir].buf = buf;
 
+        /* check for integer overflow */
+        if ((bufcnt > 0) && ((INT_MAX / bufcnt) < bufsz)) {
+            pr_err("%s: integer overflow\n", __func__);
+            mutex_unlock(&ac->cmd_lock);
+            goto fail;
+        }
 	bytes_to_alloc = bufsz * bufcnt;
 
 	/* The size to allocate should be multiple of 4K bytes */