Merge remote-tracking branch 'codeaurora/kk_2.7_rb1.30' into cm-11.0

Conflicts:
	arch/arm/mach-msm/acpuclock-krait.c
	drivers/media/video/msm/actuators/msm_actuator.c
	drivers/media/video/msm/flash.c
	drivers/media/video/msm/msm_camera.c
	drivers/media/video/msm/server/msm_cam_server.c
	drivers/media/video/msm/vfe/msm_vfe32.c
	drivers/uio/uio.c
	drivers/video/au1100fb.c
	drivers/video/au1200fb.c
	include/media/msm_isp.h
	include/media/radio-iris.h
	net/ipv4/ping.c

Change-Id: Ic027f55c9667ecccaa35ee4a96ad77dbb1e8708f
diff --git a/arch/arm/configs/fsm9xxx-perf_defconfig b/arch/arm/configs/fsm9xxx-perf_defconfig
index 4ba55de..4084a90 100644
--- a/arch/arm/configs/fsm9xxx-perf_defconfig
+++ b/arch/arm/configs/fsm9xxx-perf_defconfig
@@ -186,3 +186,5 @@
 CONFIG_CRYPTO_DEV_QCE=y
 CONFIG_CRYPTO_DEV_OTA_CRYPTO=y
 CONFIG_CRC_CCITT=y
+CONFIG_DEVMEM=n
+CONFIG_DEVKMEM=n
diff --git a/arch/arm/configs/full_msm8960-perf_defconfig b/arch/arm/configs/full_msm8960-perf_defconfig
index 2b3fbd8..6011039 100644
--- a/arch/arm/configs/full_msm8960-perf_defconfig
+++ b/arch/arm/configs/full_msm8960-perf_defconfig
@@ -512,3 +512,5 @@
 CONFIG_PRIMA_WLAN_BTAMP=y
 CONFIG_PRIMA_WLAN_LFR=y
 CONFIG_PRIMA_WLAN_OKC=y
+CONFIG_DEVMEM=n
+CONFIG_DEVKMEM=n
diff --git a/arch/arm/configs/msm7627a-perf_defconfig b/arch/arm/configs/msm7627a-perf_defconfig
index a8abb30..9736680 100644
--- a/arch/arm/configs/msm7627a-perf_defconfig
+++ b/arch/arm/configs/msm7627a-perf_defconfig
@@ -346,3 +346,5 @@
 CONFIG_DEBUG_USER=y
 CONFIG_CRYPTO_TWOFISH=y
 CONFIG_CRC_CCITT=y
+CONFIG_DEVMEM=n
+CONFIG_DEVKMEM=n
diff --git a/arch/arm/configs/msm7630-perf_defconfig b/arch/arm/configs/msm7630-perf_defconfig
index 1bf888b..da883dc 100644
--- a/arch/arm/configs/msm7630-perf_defconfig
+++ b/arch/arm/configs/msm7630-perf_defconfig
@@ -379,3 +379,5 @@
 CONFIG_CRYPTO_DEV_QCE=m
 CONFIG_CRYPTO_DEV_QCEDEV=m
 CONFIG_CRC_CCITT=y
+CONFIG_DEVMEM=n
+CONFIG_DEVKMEM=n
diff --git a/arch/arm/configs/msm8660-perf_defconfig b/arch/arm/configs/msm8660-perf_defconfig
index 8c1b6a7..2d9d0fe 100644
--- a/arch/arm/configs/msm8660-perf_defconfig
+++ b/arch/arm/configs/msm8660-perf_defconfig
@@ -450,3 +450,5 @@
 CONFIG_CRYPTO_DEV_QCRYPTO=m
 CONFIG_CRYPTO_DEV_QCE=m
 CONFIG_CRYPTO_DEV_QCEDEV=m
+CONFIG_DEVMEM=n
+CONFIG_DEVKMEM=n
diff --git a/arch/arm/configs/msm8960-perf_defconfig b/arch/arm/configs/msm8960-perf_defconfig
index 61f28a7..0c2b7bb 100644
--- a/arch/arm/configs/msm8960-perf_defconfig
+++ b/arch/arm/configs/msm8960-perf_defconfig
@@ -266,6 +266,7 @@
 CONFIG_BT_HCIUART_ATH3K=y
 CONFIG_MSM_BT_POWER=y
 CONFIG_CFG80211=y
+CONFIG_CFG80211_INTERNAL_REGDB=y
 # CONFIG_CFG80211_WEXT is not set
 CONFIG_RFKILL=y
 CONFIG_GENLOCK=y
@@ -549,3 +550,5 @@
 CONFIG_CRYPTO_DEV_QCEDEV=m
 CONFIG_CRC_CCITT=y
 CONFIG_WCNSS_MEM_PRE_ALLOC=y
+CONFIG_DEVMEM=n
+CONFIG_DEVKMEM=n
diff --git a/arch/arm/include/asm/thread_info.h b/arch/arm/include/asm/thread_info.h
index 2eb0c2c..7013a5c 100644
--- a/arch/arm/include/asm/thread_info.h
+++ b/arch/arm/include/asm/thread_info.h
@@ -148,6 +148,7 @@
 #define TIF_NOTIFY_RESUME	2	/* callback before returning to user */
 #define TIF_SYSCALL_TRACE	8
 #define TIF_SYSCALL_AUDIT	9
+#define TIF_SYSCALL_RESTARTSYS	10
 #define TIF_POLLING_NRFLAG	16
 #define TIF_USING_IWMMXT	17
 #define TIF_MEMDIE		18	/* is terminating due to OOM killer */
@@ -163,9 +164,11 @@
 #define _TIF_USING_IWMMXT	(1 << TIF_USING_IWMMXT)
 #define _TIF_RESTORE_SIGMASK	(1 << TIF_RESTORE_SIGMASK)
 #define _TIF_SECCOMP		(1 << TIF_SECCOMP)
+#define _TIF_SYSCALL_RESTARTSYS	(1 << TIF_SYSCALL_RESTARTSYS)
 
 /* Checks for any syscall work in entry-common.S */
-#define _TIF_SYSCALL_WORK (_TIF_SYSCALL_TRACE | _TIF_SYSCALL_AUDIT)
+#define _TIF_SYSCALL_WORK (_TIF_SYSCALL_TRACE | _TIF_SYSCALL_AUDIT | \
+			   _TIF_SYSCALL_RESTARTSYS)
 
 /*
  * Change these and you break ASM code in entry-common.S
diff --git a/arch/arm/kernel/ptrace.c b/arch/arm/kernel/ptrace.c
index c6c6be7..6533c4b 100644
--- a/arch/arm/kernel/ptrace.c
+++ b/arch/arm/kernel/ptrace.c
@@ -24,6 +24,7 @@
 #include <linux/hw_breakpoint.h>
 #include <linux/regset.h>
 #include <linux/audit.h>
+#include <linux/unistd.h>
 
 #include <asm/pgtable.h>
 #include <asm/traps.h>
@@ -916,6 +917,8 @@
 		audit_syscall_entry(AUDIT_ARCH_ARM, scno, regs->ARM_r0,
 				    regs->ARM_r1, regs->ARM_r2, regs->ARM_r3);
 
+	if (why == 0 && test_and_clear_thread_flag(TIF_SYSCALL_RESTARTSYS))
+		scno = __NR_restart_syscall - __NR_SYSCALL_BASE;
 	if (!test_thread_flag(TIF_SYSCALL_TRACE))
 		return scno;
 	if (!(current->ptrace & PT_PTRACED))
diff --git a/arch/arm/kernel/signal.c b/arch/arm/kernel/signal.c
index d96ac36..09b37d1 100644
--- a/arch/arm/kernel/signal.c
+++ b/arch/arm/kernel/signal.c
@@ -649,12 +649,10 @@
 		case -ERESTARTNOHAND:
 		case -ERESTARTSYS:
 		case -ERESTARTNOINTR:
+		case -ERESTART_RESTARTBLOCK:
 			regs->ARM_r0 = regs->ARM_ORIG_r0;
 			regs->ARM_pc = restart_addr;
 			break;
-		case -ERESTART_RESTARTBLOCK:
-			regs->ARM_r0 = -EINTR;
-			break;
 		}
 	}
 
@@ -675,12 +673,14 @@
 		 * debugger has chosen to restart at a different PC.
 		 */
 		if (regs->ARM_pc == restart_addr) {
-			if (retval == -ERESTARTNOHAND
+			if (retval == -ERESTARTNOHAND ||
+			    retval == -ERESTART_RESTARTBLOCK
 			    || (retval == -ERESTARTSYS
 				&& !(ka.sa.sa_flags & SA_RESTART))) {
 				regs->ARM_r0 = -EINTR;
 				regs->ARM_pc = continue_addr;
 			}
+			clear_thread_flag(TIF_SYSCALL_RESTARTSYS);
 		}
 
 		if (test_thread_flag(TIF_RESTORE_SIGMASK))
@@ -708,38 +708,15 @@
 		 * ignore the restart.
 		 */
 		if (retval == -ERESTART_RESTARTBLOCK
-		    && regs->ARM_pc == continue_addr) {
-			if (thumb_mode(regs)) {
-				regs->ARM_r7 = __NR_restart_syscall - __NR_SYSCALL_BASE;
-				regs->ARM_pc -= 2;
-			} else {
-#if defined(CONFIG_AEABI) && !defined(CONFIG_OABI_COMPAT)
-				regs->ARM_r7 = __NR_restart_syscall;
-				regs->ARM_pc -= 4;
-#else
-				u32 __user *usp;
-
-				regs->ARM_sp -= 4;
-				usp = (u32 __user *)regs->ARM_sp;
-
-				if (put_user(regs->ARM_pc, usp) == 0) {
-					regs->ARM_pc = KERN_RESTART_CODE;
-				} else {
-					regs->ARM_sp += 4;
-					force_sigsegv(0, current);
-				}
-#endif
-			}
-		}
-
-		/* If there's no signal to deliver, we just put the saved sigmask
-		 * back.
-		 */
-		if (test_thread_flag(TIF_RESTORE_SIGMASK)) {
-			clear_thread_flag(TIF_RESTORE_SIGMASK);
-			sigprocmask(SIG_SETMASK, &current->saved_sigmask, NULL);
-		}
+		    && regs->ARM_pc == restart_addr)
+			set_thread_flag(TIF_SYSCALL_RESTARTSYS);
 	}
+
+	/* If there's no signal to deliver, we just put the saved sigmask
+	 * back.
+	 */
+	if (test_and_clear_thread_flag(TIF_RESTORE_SIGMASK))
+		set_current_blocked(&current->saved_sigmask);
 }
 
 asmlinkage void
diff --git a/arch/arm/mach-msm/Kconfig b/arch/arm/mach-msm/Kconfig
index a5c7097..d45d269 100644
--- a/arch/arm/mach-msm/Kconfig
+++ b/arch/arm/mach-msm/Kconfig
@@ -1315,20 +1315,6 @@
 	  Enables the PCIe functionality by configures PCIe core on
 	  MSM chipset and by enabling the ARM PCI framework extension.
 
-config MSM_RPC_SDIO_XPRT
-	depends on MSM_SDIO_AL
-	default y
-	bool "MSM SDIO XPRT Layer"
-	help
-	  SDIO Transport Layer for RPC Rouer
-
-config MSM_RPC_SDIO_DEBUG
-	depends on MSM_RPC_SDIO_XPRT
-	default y
-	bool "MSM SDIO XPRT debug support"
-	help
-	  Support for debugging SDIO XPRT
-
 config MSM_SMD_DEBUG
 	depends on MSM_SMD
 	default y
@@ -1337,21 +1323,6 @@
 	  Support for debugging the SMD for communication
 	  between the ARM9 and ARM11
 
-config MSM_SDIO_AL
-	depends on ((ARCH_MSM7X30 || MACH_MSM8X60_FUSN_FFA || MACH_TYPE_MSM8X60_FUSION) && HAS_WAKELOCK)
-	default y
-	tristate "SDIO-Abstraction-Layer"
-	help
-	  Support MSM<->MDM Communication over SDIO bus.
-	  MDM SDIO-Client should have pipes support.
-
-config MSM_SDIO_DMUX
-	bool "SDIO Data Mux Driver"
-	depends on MSM_SDIO_AL
-	default n
-	help
-	  Support Muxed Data Channels over SDIO interface.
-
 config MSM_BAM_DMUX
 	bool "BAM Data Mux Driver"
 	depends on SPS
@@ -1411,16 +1382,6 @@
 
 	  If in doubt, say yes.
 
-config MSM_SDIO_TTY
-	bool "SDIO TTY Driver"
-	depends on MSM_SDIO_AL
-	default n
-	help
-	  Provides a TTY driver SDIO TTY
-	  This driver can be used by user space
-	  applications for passing data through the
-	  SDIO interface.
-
 config MSM_HSIC_TTY
 	bool "HSIC TTY Driver"
 	default n
@@ -1457,13 +1418,6 @@
 
 	  If in doubt, say yes.
 
-config MSM_SDIO_CMUX
-	bool "SDIO CMUX Driver"
-	depends on MSM_SDIO_AL
-	default n
-	help
-	  Provides a Muxed port interface over SDIO QMI
-
 config MSM_DSPS
 	bool "Sensors DSPS driver"
 	depends on (MSM_PIL && (ARCH_MSM8X60 || ARCH_MSM8960))
@@ -1476,13 +1430,6 @@
 	  The number of clocks and their name may vary between targets.
 	  It also triggers the PIL to load the DSPS firmware.
 
-config MSM_SDIO_CTL
-	bool "SDIO CTL Driver"
-	depends on MSM_SDIO_CMUX
-	default n
-	help
-	  Provides a binary SDIO control port interface.
-
 config MSM_ONCRPCROUTER
 	depends on MSM_SMD
 	default n
@@ -1610,15 +1557,6 @@
 	  Collects performance statistics and shows this information
 	  through a debugfs file rmt_storage_stats.
 
-config MSM_SDIO_SMEM
-        depends on MSM_SDIO_AL
-        default n
-        bool "SDIO SMEM for remote storage"
-        help
-          Copies data from remote MDM9K memory to local MSM8x60
-	  memory. Used by remote storage client to shadow
-	  MDM9K filesystem.
-
 config MSM_DALRPC
 	bool "DAL RPC support"
 	default n
diff --git a/arch/arm/mach-msm/Makefile b/arch/arm/mach-msm/Makefile
index a7eecf8..9a8b84e 100644
--- a/arch/arm/mach-msm/Makefile
+++ b/arch/arm/mach-msm/Makefile
@@ -89,10 +89,6 @@
 obj-$(CONFIG_ARCH_FSM9XXX) += sirc-fsm9xxx.o
 obj-$(CONFIG_MSM_FIQ_SUPPORT) += fiq_glue.o
 obj-$(CONFIG_MACH_TROUT) += board-trout-rfkill.o
-obj-$(CONFIG_MSM_SDIO_AL) += sdio_al.o
-obj-$(CONFIG_MSM_SDIO_AL) += sdio_al_test.o
-obj-$(CONFIG_MSM_SDIO_AL) += sdio_al_dloader.o
-obj-$(CONFIG_MSM_SDIO_DMUX) += sdio_dmux.o
 obj-$(CONFIG_MSM_BAM_DMUX) += bam_dmux.o
 obj-$(CONFIG_MSM_SMD_LOGGING) += smem_log.o
 obj-$(CONFIG_MSM_IPC_LOGGING) += ipc_logging.o
@@ -126,13 +122,10 @@
 endif
 
 obj-$(CONFIG_MSM_HSIC_TTY) += hsic_tty.o
-obj-$(CONFIG_MSM_SDIO_TTY) += sdio_tty.o
 obj-$(CONFIG_MSM_SMD_TTY) += smd_tty.o
 obj-$(CONFIG_MSM_SMD_QMI) += smd_qmi.o
 obj-$(CONFIG_MSM_SMD_PKT) += smd_pkt.o
-obj-$(CONFIG_MSM_SDIO_CMUX) += sdio_cmux.o
 obj-$(CONFIG_MSM_DSPS) += msm_dsps.o
-obj-$(CONFIG_MSM_SDIO_CTL) += sdio_ctl.o
 obj-$(CONFIG_MSM_SMD_NMEA) += smd_nmea.o
 obj-$(CONFIG_MSM_RESET_MODEM) += reset_modem.o
 obj-$(CONFIG_MSM_IPC_ROUTER_SMD_XPRT) += ipc_router_smd_xprt.o
@@ -147,7 +140,6 @@
 obj-$(CONFIG_MSM_ONCRPCROUTER) += smd_rpcrouter_clients.o
 obj-$(CONFIG_MSM_ONCRPCROUTER) += smd_rpcrouter_xdr.o
 obj-$(CONFIG_MSM_ONCRPCROUTER) += rpcrouter_smd_xprt.o
-obj-$(CONFIG_MSM_RPC_SDIO_XPRT) += rpcrouter_sdio_xprt.o
 obj-$(CONFIG_MSM_RPC_PING) += ping_mdm_rpc_client.o
 obj-$(CONFIG_MSM_RPC_PROC_COMM_TEST) += proc_comm_test.o
 obj-$(CONFIG_MSM_RPC_PING) += ping_mdm_rpc_client.o ping_apps_server.o
@@ -319,7 +311,6 @@
 obj-$(CONFIG_HTC_PWRSINK) += htc_pwrsink.o
 obj-$(CONFIG_HTC_HEADSET) += htc_headset.o
 obj-$(CONFIG_MSM_RMT_STORAGE_CLIENT) += rmt_storage_client.o
-obj-$(CONFIG_MSM_SDIO_SMEM) += sdio_smem.o
 obj-$(CONFIG_MSM_RPM) += rpm.o
 ifdef CONFIG_MSM_RPM
 	obj-$(CONFIG_ARCH_APQ8064) += rpm_resources.o
diff --git a/arch/arm/mach-msm/acpuclock-krait.c b/arch/arm/mach-msm/acpuclock-krait.c
index e3a3f54..d22ab41 100644
--- a/arch/arm/mach-msm/acpuclock-krait.c
+++ b/arch/arm/mach-msm/acpuclock-krait.c
@@ -924,7 +924,7 @@
 		int i;
 		/* Construct the freq_table tables from acpu_freq_tbl. */
 		for (i = 0, freq_cnt = 0; drv.acpu_freq_tbl[i].speed.khz != 0
-				&& freq_cnt < ARRAY_SIZE(*freq_table); i++) {
+				&& freq_cnt < ARRAY_SIZE(*freq_table)-1; i++) {
 			if (drv.acpu_freq_tbl[i].use_for_scaling) {
 				freq_table[cpu][freq_cnt].index = freq_cnt;
 				freq_table[cpu][freq_cnt].frequency
diff --git a/arch/arm/mach-msm/bam_dmux.c b/arch/arm/mach-msm/bam_dmux.c
index 991ccef..ea1f65d 100644
--- a/arch/arm/mach-msm/bam_dmux.c
+++ b/arch/arm/mach-msm/bam_dmux.c
@@ -215,9 +215,10 @@
 static void bam_mux_write_done(struct work_struct *work);
 static void handle_bam_mux_cmd(struct work_struct *work);
 static void rx_timer_work_func(struct work_struct *work);
+static void queue_rx_work_func(struct work_struct *work);
 
 static DECLARE_WORK(rx_timer_work, rx_timer_work_func);
-static struct delayed_work queue_rx_work;
+static DECLARE_WORK(queue_rx_work, queue_rx_work_func);
 
 static struct workqueue_struct *bam_mux_rx_workqueue;
 static struct workqueue_struct *bam_mux_tx_workqueue;
@@ -384,7 +385,7 @@
 	spin_unlock_irqrestore(&bam_tx_pool_spinlock, flags);
 }
 
-static void queue_rx(void)
+static void __queue_rx(gfp_t alloc_flags)
 {
 	void *ptr;
 	struct rx_pkt_info *info;
@@ -399,23 +400,23 @@
 		if (in_global_reset)
 			goto fail;
 
-		info = kmalloc(sizeof(struct rx_pkt_info),
-						GFP_NOWAIT | __GFP_NOWARN);
+		info = kmalloc(sizeof(struct rx_pkt_info), alloc_flags);
 		if (!info) {
 			DMUX_LOG_KERR(
-			"%s: unable to alloc rx_pkt_info, will retry later\n",
-								__func__);
+			"%s: unable to alloc rx_pkt_info w/ flags %x, will retry later\n",
+								__func__,
+								alloc_flags);
 			goto fail;
 		}
 
 		INIT_WORK(&info->work, handle_bam_mux_cmd);
 
-		info->skb = __dev_alloc_skb(BUFFER_SIZE,
-						GFP_NOWAIT | __GFP_NOWARN);
+		info->skb = __dev_alloc_skb(BUFFER_SIZE, alloc_flags);
 		if (info->skb == NULL) {
 			DMUX_LOG_KERR(
-				"%s: unable to alloc skb, will retry later\n",
-								__func__);
+				"%s: unable to alloc skb w/ flags %x, will retry later\n",
+								__func__,
+								alloc_flags);
 			goto fail_info;
 		}
 		ptr = skb_put(info->skb, BUFFER_SIZE);
@@ -457,15 +458,30 @@
 	kfree(info);
 
 fail:
-	if (rx_len_cached == 0 && !in_global_reset) {
+	if (!in_global_reset) {
 		DMUX_LOG_KERR("%s: rescheduling\n", __func__);
-		schedule_delayed_work(&queue_rx_work, msecs_to_jiffies(100));
+		schedule_work(&queue_rx_work);
 	}
 }
 
+static void queue_rx(void)
+{
+	/*
+	 * Hot path.  Delays waiting for the allocation to find memory if its
+	 * not immediately available, and delays from logging allocation
+	 * failures which cannot be tolerated at this time.
+	 */
+	__queue_rx(GFP_NOWAIT | __GFP_NOWARN);
+}
+
 static void queue_rx_work_func(struct work_struct *work)
 {
-	queue_rx();
+	/*
+	 * Cold path.  Delays can be tolerated.  Use of GFP_KERNEL should
+	 * guarentee the requested memory will be found, after some ammount of
+	 * delay.
+	 */
+	__queue_rx(GFP_KERNEL);
 }
 
 static void bam_mux_process_data(struct sk_buff *rx_skb)
@@ -1843,8 +1859,6 @@
 			bam_ops->sps_disconnect_ptr(bam_rx_pipe);
 			__memzero(rx_desc_mem_buf.base, rx_desc_mem_buf.size);
 			__memzero(tx_desc_mem_buf.base, tx_desc_mem_buf.size);
-			BAM_DMUX_LOG("%s: device reset\n", __func__);
-			sps_device_reset(a2_device_handle);
 		} else {
 			ssr_skipped_disconnect = 1;
 		}
@@ -2477,7 +2491,6 @@
 	init_completion(&shutdown_completion);
 	complete_all(&shutdown_completion);
 	INIT_DELAYED_WORK(&ul_timeout_work, ul_timeout);
-	INIT_DELAYED_WORK(&queue_rx_work, queue_rx_work_func);
 	wake_lock_init(&bam_wakelock, WAKE_LOCK_SUSPEND, "bam_dmux_wakelock");
 	init_srcu_struct(&bam_dmux_srcu);
 
diff --git a/arch/arm/mach-msm/board-8064-storage.c b/arch/arm/mach-msm/board-8064-storage.c
index cdcc2cd..b07e2fd 100644
--- a/arch/arm/mach-msm/board-8064-storage.c
+++ b/arch/arm/mach-msm/board-8064-storage.c
@@ -346,6 +346,7 @@
 					ARRAY_SIZE(sdc1_sup_clk_rates_all);
 		}
 		apq8064_add_sdcc(1, apq8064_sdc1_pdata);
+		apq8064_add_uio();
 	}
 
 	if (apq8064_sdc2_pdata)
diff --git a/arch/arm/mach-msm/board-8064.h b/arch/arm/mach-msm/board-8064.h
index 256fac9..cab700d 100644
--- a/arch/arm/mach-msm/board-8064.h
+++ b/arch/arm/mach-msm/board-8064.h
@@ -78,6 +78,7 @@
 struct mmc_platform_data;
 int __init apq8064_add_sdcc(unsigned int controller,
 		struct mmc_platform_data *plat);
+int __init apq8064_add_uio(void);
 
 void apq8064_init_mmc(void);
 void apq8064_init_gpiomux(void);
diff --git a/arch/arm/mach-msm/devices-8064.c b/arch/arm/mach-msm/devices-8064.c
index 9d5acf7..8141869 100644
--- a/arch/arm/mach-msm/devices-8064.c
+++ b/arch/arm/mach-msm/devices-8064.c
@@ -1894,6 +1894,30 @@
 	return platform_device_register(pdev);
 }
 
+#define MSM_UIO_RMTFS_BASE	0x8FF00000
+#define MSM_UIO_RMTFS_END	(MSM_UIO_RMTFS_BASE + 0x40000)
+
+static struct resource msm_device_uio_rmtfs_rsc[] = {
+	{
+		.name	= "rmtfs",
+		.flags	= IORESOURCE_MEM,
+		.start	= MSM_UIO_RMTFS_BASE,
+		.end	= MSM_UIO_RMTFS_END - 1,
+	},
+};
+
+struct platform_device apq8064_device_uio_rmtfs = {
+	.name		= "msm_sharedmem",
+	.id		= -1,
+	.num_resources	= ARRAY_SIZE(msm_device_uio_rmtfs_rsc),
+	.resource	= msm_device_uio_rmtfs_rsc,
+};
+
+int __init apq8064_add_uio()
+{
+	return platform_device_register(&apq8064_device_uio_rmtfs);
+}
+
 static struct resource resources_sps[] = {
 	{
 		.name	= "pipe_mem",
diff --git a/arch/arm/mach-msm/dfe-fsm9xxx.c b/arch/arm/mach-msm/dfe-fsm9xxx.c
index 66272d2..3470710 100644
--- a/arch/arm/mach-msm/dfe-fsm9xxx.c
+++ b/arch/arm/mach-msm/dfe-fsm9xxx.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2011-2013, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -50,6 +50,8 @@
 					HH_IRQ_FIFO_SIZE) == \
 					(pdev)->irq_fifo_head)
 
+#define UINT32_MAX  (0xFFFFFFFFU)
+
 static struct hh_dev_node_info {
 	spinlock_t hh_lock;
 	char irq_fifo[HH_IRQ_FIFO_SIZE];
@@ -220,8 +222,9 @@
 				return -EFAULT;
 			if (!HH_OFFSET_VALID(param.offset))
 				return -EINVAL;
-			if (param.num == 0)
-				break;
+			if ((param.num == 0) ||
+			(param.num >= (UINT32_MAX / sizeof(unsigned int))))
+				return -EINVAL;
 			req_sz = sizeof(unsigned int) * param.num;
 
 			if (pdfi->array_num < param.num) {
@@ -270,8 +273,10 @@
 
 			if (copy_from_user(&param, argp, sizeof param))
 				return -EFAULT;
-			if (param.num == 0)
-				break;
+			if ((param.num == 0) ||
+			(param.num >= (UINT32_MAX  /
+			sizeof(struct dfe_command_entry))))
+				return -EINVAL;
 			req_sz = sizeof(struct dfe_command_entry) * param.num;
 
 			if (pdfi->cmd_num < param.num) {
diff --git a/arch/arm/mach-msm/ipc_router.c b/arch/arm/mach-msm/ipc_router.c
index 9b34155..9af8a7e 100644
--- a/arch/arm/mach-msm/ipc_router.c
+++ b/arch/arm/mach-msm/ipc_router.c
@@ -434,7 +434,7 @@
 				       unsigned int len)
 {
 	struct sk_buff *temp;
-	int offset = 0, buf_len = 0, copy_len;
+	unsigned int offset = 0, buf_len = 0, copy_len;
 	void *buf;
 
 	if (!skb_head) {
diff --git a/arch/arm/mach-msm/msm-buspm-dev.h b/arch/arm/mach-msm/msm-buspm-dev.h
index 5754771..1a24b66 100644
--- a/arch/arm/mach-msm/msm-buspm-dev.h
+++ b/arch/arm/mach-msm/msm-buspm-dev.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011, The Linux Foundation. All rights reserved.
+/* 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
@@ -23,7 +23,7 @@
 
 /* Read/write data into kernel buffer */
 struct buspm_xfer_req {
-	int size;		/* Size of this request, in bytes */
+	unsigned int  size;		/* Size of this request, in bytes */
 	void *data;		/* Data buffer to transfer data to/from */
 };
 
diff --git a/arch/arm/mach-msm/msm_bus/msm_bus_config.c b/arch/arm/mach-msm/msm_bus/msm_bus_config.c
index c6fa250..d51aa9b 100644
--- a/arch/arm/mach-msm/msm_bus/msm_bus_config.c
+++ b/arch/arm/mach-msm/msm_bus/msm_bus_config.c
@@ -36,6 +36,10 @@
 	struct msm_bus_fabric_device *fabdev;
 
 	priv_id = msm_bus_board_get_iid(master_port);
+	if (priv_id == -ENXIO) {
+		MSM_BUS_ERR("Error in getting the iid \n");
+		return -ENODEV;
+	}
 	MSM_BUS_DBG("master_port: %d iid: %d fabid%d\n",
 		master_port, priv_id, GET_FABID(priv_id));
 	fabdev = msm_bus_get_fabric_device(GET_FABID(priv_id));
@@ -62,6 +66,10 @@
 	struct msm_bus_fabric_device *fabdev;
 
 	priv_id = msm_bus_board_get_iid(master_port);
+	if (priv_id == -ENXIO) {
+		MSM_BUS_ERR("Error in getting the iid \n");
+		return -ENODEV;
+	}
 	MSM_BUS_DBG("master_port: %d iid: %d fabid: %d\n",
 		master_port, priv_id, GET_FABID(priv_id));
 	fabdev = msm_bus_get_fabric_device(GET_FABID(priv_id));
diff --git a/arch/arm/mach-msm/qdsp6v2/audio_utils.c b/arch/arm/mach-msm/qdsp6v2/audio_utils.c
index b8e55f9..42a2638 100644
--- a/arch/arm/mach-msm/qdsp6v2/audio_utils.c
+++ b/arch/arm/mach-msm/qdsp6v2/audio_utils.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2012, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2010-2012, 2014 The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -395,7 +395,7 @@
 	uint32_t mfield_size = (audio->buf_cfg.meta_info_enable == 0) ? 0 :
 		(sizeof(unsigned char) +
 		(sizeof(struct meta_out_dsp)*(audio->buf_cfg.frames_per_buf)));
-
+	memset(&meta, 0, sizeof(meta));
 	pr_debug("%s:session id %d: read - %d\n", __func__, audio->ac->session,
 			count);
 	if (!audio->enabled)
diff --git a/arch/arm/mach-msm/qdsp6v2/audio_utils_aio.c b/arch/arm/mach-msm/qdsp6v2/audio_utils_aio.c
index eb0c80c..43d0e29 100644
--- a/arch/arm/mach-msm/qdsp6v2/audio_utils_aio.c
+++ b/arch/arm/mach-msm/qdsp6v2/audio_utils_aio.c
@@ -1110,6 +1110,7 @@
 	switch (cmd) {
 	case AUDIO_GET_STATS: {
 		struct msm_audio_stats stats;
+		memset(&stats, 0, sizeof(struct msm_audio_stats));
 		stats.byte_count = atomic_read(&audio->in_bytes);
 		stats.sample_count = atomic_read(&audio->in_samples);
 		if (copy_to_user((void *)arg, &stats, sizeof(stats)))
diff --git a/arch/arm/mach-msm/qdsp6v2/lpa_if_hdmi.c b/arch/arm/mach-msm/qdsp6v2/lpa_if_hdmi.c
deleted file mode 100644
index 71ab566..0000000
--- a/arch/arm/mach-msm/qdsp6v2/lpa_if_hdmi.c
+++ /dev/null
@@ -1,464 +0,0 @@
-/* Copyright (c) 2011, The Linux Foundation. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 and
- * only version 2 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- */
-
-#define pr_fmt(fmt) "%s: " fmt, __func__
-
-#include <linux/fs.h>
-#include <linux/module.h>
-#include <linux/miscdevice.h>
-#include <linux/mutex.h>
-#include <linux/sched.h>
-#include <linux/wait.h>
-#include <linux/slab.h>
-#include <linux/interrupt.h>
-#include <linux/uaccess.h>
-#include <linux/dma-mapping.h>
-#include <linux/msm_audio.h>
-#include <mach/msm_hdmi_audio.h>
-#include <mach/audio_dma_msm8k.h>
-#include <sound/dai.h>
-#include "q6core.h"
-
-#define DMA_ALLOC_BUF_SZ		(SZ_4K * 16)
-
-#define HDMI_AUDIO_FIFO_WATER_MARK	4
-
-struct audio_buffer {
-	dma_addr_t phys;
-	void *data;
-	uint32_t size;
-	uint32_t used;	/* 1 = CPU is waiting for DMA to consume this buf */
-	uint32_t actual_size;	/* actual number of bytes read by DMA */
-};
-
-struct lpa_if {
-	struct mutex lock;
-	struct msm_audio_config cfg;
-	struct audio_buffer audio_buf[6];
-	int cpu_buf;		/* next buffer the CPU will touch */
-	int dma_buf;		/* next buffer the DMA will touch */
-	u8 *buffer;
-	dma_addr_t buffer_phys;
-	u32 dma_ch;
-	wait_queue_head_t wait;
-	u32 config;
-	u32 dma_period_sz;
-	unsigned int num_periods;
-};
-
-static struct lpa_if  *lpa_if_ptr;
-
-static unsigned int dma_buf_index;
-
-static irqreturn_t lpa_if_irq(int intrsrc, void *data)
-{
-	struct lpa_if *lpa_if = data;
-	int dma_ch = 0;
-	unsigned int pending;
-
-	if (lpa_if)
-		dma_ch = lpa_if->dma_ch;
-	else {
-		pr_err("invalid lpa_if\n");
-		return IRQ_NONE;
-	}
-
-	pending = (intrsrc
-		   & (UNDER_CH(dma_ch) | PER_CH(dma_ch) | ERR_CH(dma_ch)));
-
-	if (pending & UNDER_CH(dma_ch))
-		pr_err("under run\n");
-	if (pending & ERR_CH(dma_ch))
-		pr_err("DMA %x Master Error\n", dma_ch);
-
-	if (pending & PER_CH(dma_ch)) {
-
-		lpa_if->audio_buf[lpa_if->dma_buf].used = 0;
-
-		pr_debug("dma_buf %d  used %d\n", lpa_if->dma_buf,
-			lpa_if->audio_buf[lpa_if->dma_buf].used);
-		lpa_if->dma_buf++;
-		lpa_if->dma_buf = lpa_if->dma_buf % lpa_if->cfg.buffer_count;
-
-		if (lpa_if->dma_buf == lpa_if->cpu_buf)
-			pr_err("Err:both dma_buf and cpu_buf are on same index\n");
-		wake_up(&lpa_if->wait);
-	}
-	return IRQ_HANDLED;
-}
-
-
-int lpa_if_start(struct lpa_if *lpa_if)
-{
-	pr_debug("buf1 0x%x, buf2 0x%x dma_ch %d\n",
-		(unsigned int)lpa_if->audio_buf[0].data,
-		(unsigned int)lpa_if->audio_buf[1].data, lpa_if->dma_ch);
-
-	dai_start_hdmi(lpa_if->dma_ch);
-
-	hdmi_audio_enable(1, HDMI_AUDIO_FIFO_WATER_MARK);
-
-	hdmi_audio_packet_enable(1);
-	return 0;
-}
-
-int lpa_if_config(struct lpa_if *lpa_if)
-{
-	struct dai_dma_params dma_params;
-
-	dma_params.src_start = lpa_if->buffer_phys;
-	dma_params.buffer = lpa_if->buffer;
-	dma_params.buffer_size = lpa_if->dma_period_sz * lpa_if->num_periods;
-	dma_params.period_size = lpa_if->dma_period_sz;
-	dma_params.channels = 2;
-
-	lpa_if->dma_ch = 4;
-	dai_set_params(lpa_if->dma_ch, &dma_params);
-
-	register_dma_irq_handler(lpa_if->dma_ch, lpa_if_irq, (void *)lpa_if);
-
-	mb();
-	pr_debug("lpa_if 0x%08x  buf_vir 0x%08x   buf_phys 0x%08x  "
-		"config %u\n", (u32)lpa_if, (u32) (lpa_if->buffer),
-		lpa_if->buffer_phys, lpa_if->config);
-
-	pr_debug("user_buf_cnt %u user_buf_size %u\n",
-			lpa_if->cfg.buffer_count, lpa_if->cfg.buffer_size);
-
-	lpa_if->config = 1;
-
-	lpa_if_start(lpa_if);
-
-	return 0;
-}
-
-
-static long lpa_if_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
-{
-	struct lpa_if *lpa_if = file->private_data;
-	int rc = 0;
-	unsigned int i;
-	pr_debug("cmd %u\n", cmd);
-
-	mutex_lock(&lpa_if->lock);
-
-	switch (cmd) {
-	case AUDIO_START:
-		pr_debug("AUDIO_START\n");
-
-		if (dma_buf_index == 2) {
-			if (!lpa_if->config) {
-				rc = lpa_if_config(lpa_if);
-				if (rc)
-					pr_err("lpa_if_config failed\n");
-			}
-		} else {
-			pr_err("did not receved two buffer for "
-				"AUDIO_STAR\n");
-			rc =  -EPERM;
-		}
-		break;
-
-	case AUDIO_STOP:
-		pr_debug("AUDIO_STOP\n");
-		break;
-
-	case AUDIO_FLUSH:
-		pr_debug("AUDIO_FLUSH\n");
-		break;
-
-
-	case AUDIO_GET_CONFIG:
-		pr_debug("AUDIO_GET_CONFIG\n");
-		if (copy_to_user((void *)arg, &lpa_if->cfg,
-				 sizeof(struct msm_audio_config))) {
-			rc = -EFAULT;
-		}
-		break;
-	case AUDIO_SET_CONFIG: {
-		/*  Setting default rate as 48khz */
-		unsigned int cur_sample_rate =
-			HDMI_SAMPLE_RATE_48KHZ;
-		struct msm_audio_config config;
-
-		pr_debug("AUDIO_SET_CONFIG\n");
-		if (copy_from_user(&config, (void *)arg, sizeof(config))) {
-			rc = -EFAULT;
-			break;
-		}
-		lpa_if->dma_period_sz = config.buffer_size;
-		if ((lpa_if->dma_period_sz * lpa_if->num_periods) >
-			DMA_ALLOC_BUF_SZ) {
-			pr_err("Dma buffer size greater than allocated size\n");
-			return -EINVAL;
-		}
-		pr_debug("Dma_period_sz %d\n", lpa_if->dma_period_sz);
-		if (lpa_if->dma_period_sz < (2 * SZ_4K))
-			lpa_if->num_periods = 6;
-		pr_debug("No. of Periods %d\n", lpa_if->num_periods);
-
-		lpa_if->cfg.buffer_count = lpa_if->num_periods;
-		lpa_if->cfg.buffer_size = lpa_if->dma_period_sz *
-						lpa_if->num_periods;
-
-		for (i = 0; i < lpa_if->cfg.buffer_count; i++) {
-			lpa_if->audio_buf[i].phys =
-				lpa_if->buffer_phys + i * lpa_if->dma_period_sz;
-			lpa_if->audio_buf[i].data =
-				lpa_if->buffer + i * lpa_if->dma_period_sz;
-			lpa_if->audio_buf[i].size = lpa_if->dma_period_sz;
-			lpa_if->audio_buf[i].used = 0;
-		}
-
-		pr_debug("Sample rate %d\n", config.sample_rate);
-		switch (config.sample_rate) {
-		case 48000:
-			cur_sample_rate = HDMI_SAMPLE_RATE_48KHZ;
-			break;
-		case 44100:
-			cur_sample_rate = HDMI_SAMPLE_RATE_44_1KHZ;
-			break;
-		case 32000:
-			cur_sample_rate = HDMI_SAMPLE_RATE_32KHZ;
-			break;
-		case 88200:
-			cur_sample_rate = HDMI_SAMPLE_RATE_88_2KHZ;
-			break;
-		case 96000:
-			cur_sample_rate = HDMI_SAMPLE_RATE_96KHZ;
-			break;
-		case 176400:
-			cur_sample_rate = HDMI_SAMPLE_RATE_176_4KHZ;
-			break;
-		case 192000:
-			cur_sample_rate = HDMI_SAMPLE_RATE_192KHZ;
-			break;
-		default:
-			cur_sample_rate = HDMI_SAMPLE_RATE_48KHZ;
-		}
-		if (cur_sample_rate != hdmi_msm_audio_get_sample_rate())
-			hdmi_msm_audio_sample_rate_reset(cur_sample_rate);
-		else
-			pr_debug("Previous sample rate and current"
-				"sample rate are same\n");
-		break;
-	}
-	default:
-		pr_err("UnKnown Ioctl\n");
-		rc = -EINVAL;
-	}
-
-	mutex_unlock(&lpa_if->lock);
-
-	return rc;
-}
-
-
-static int lpa_if_open(struct inode *inode, struct file *file)
-{
-	pr_debug("\n");
-
-	file->private_data = lpa_if_ptr;
-	dma_buf_index = 0;
-	lpa_if_ptr->cpu_buf = 2;
-	lpa_if_ptr->dma_buf = 0;
-	lpa_if_ptr->num_periods = 4;
-
-	core_req_bus_bandwith(AUDIO_IF_BUS_ID, 100000, 0);
-	mb();
-
-	return 0;
-}
-
-static inline int rt_policy(int policy)
-{
-	if (unlikely(policy == SCHED_FIFO) || unlikely(policy == SCHED_RR))
-		return 1;
-	return 0;
-}
-
-static inline int task_has_rt_policy(struct task_struct *p)
-{
-	return rt_policy(p->policy);
-}
-static ssize_t lpa_if_write(struct file *file, const char __user *buf,
-		size_t count, loff_t *pos)
-{
-	struct lpa_if *lpa_if = file->private_data;
-	struct audio_buffer *ab;
-	const char __user *start = buf;
-	int xfer, rc;
-	struct sched_param s = { .sched_priority = 1 };
-	int old_prio = current->rt_priority;
-	int old_policy = current->policy;
-	int cap_nice = cap_raised(current_cap(), CAP_SYS_NICE);
-
-	 /* just for this write, set us real-time */
-	if (!task_has_rt_policy(current)) {
-		struct cred *new = prepare_creds();
-		cap_raise(new->cap_effective, CAP_SYS_NICE);
-		commit_creds(new);
-		if ((sched_setscheduler(current, SCHED_RR, &s)) < 0)
-			pr_err("sched_setscheduler failed\n");
-	}
-	mutex_lock(&lpa_if->lock);
-
-	if (dma_buf_index < 2) {
-
-		ab = lpa_if->audio_buf + dma_buf_index;
-
-		if (copy_from_user(ab->data, buf, count)) {
-			pr_err("copy from user failed\n");
-			rc = 0;
-			goto end;
-
-		}
-		mb();
-		pr_debug("prefill: count %u  audio_buf[%u].size %u\n",
-			 count, dma_buf_index, ab->size);
-
-		ab->used = 1;
-		dma_buf_index++;
-		rc =  count;
-		goto end;
-	}
-
-	if (lpa_if->config != 1) {
-		pr_err("AUDIO_START did not happen\n");
-		rc = 0;
-		goto end;
-	}
-
-	while (count > 0) {
-
-		ab = lpa_if->audio_buf + lpa_if->cpu_buf;
-
-		rc = wait_event_timeout(lpa_if->wait, (ab->used == 0), 10 * HZ);
-		if (!rc) {
-			pr_err("wait_event_timeout failed\n");
-			rc =  buf - start;
-			goto end;
-		}
-
-		xfer = count;
-
-		if (xfer > lpa_if->dma_period_sz)
-			xfer = lpa_if->dma_period_sz;
-
-		if (copy_from_user(ab->data, buf, xfer)) {
-			pr_err("copy from user failed\n");
-			rc = buf - start;
-			goto end;
-		}
-
-		mb();
-		buf += xfer;
-		count -= xfer;
-		ab->used = 1;
-
-		pr_debug("xfer %d, size %d, used %d cpu_buf %d\n",
-			xfer, ab->size, ab->used, lpa_if->cpu_buf);
-		lpa_if->cpu_buf++;
-		lpa_if->cpu_buf = lpa_if->cpu_buf % lpa_if->cfg.buffer_count;
-	}
-	rc = buf - start;
-end:
-	mutex_unlock(&lpa_if->lock);
-	/* restore old scheduling policy */
-	if (!rt_policy(old_policy)) {
-		struct sched_param v = { .sched_priority = old_prio };
-		if ((sched_setscheduler(current, old_policy, &v)) < 0)
-			pr_err("sched_setscheduler failed\n");
-		if (likely(!cap_nice)) {
-			struct cred *new = prepare_creds();
-			cap_lower(new->cap_effective, CAP_SYS_NICE);
-			commit_creds(new);
-		}
-	}
-	return rc;
-}
-
-static int lpa_if_release(struct inode *inode, struct file *file)
-{
-	struct lpa_if *lpa_if = file->private_data;
-
-	hdmi_audio_packet_enable(0);
-
-	wait_for_dma_cnt_stop(lpa_if->dma_ch);
-
-	hdmi_audio_enable(0, HDMI_AUDIO_FIFO_WATER_MARK);
-
-	if (lpa_if->config) {
-		unregister_dma_irq_handler(lpa_if->dma_ch);
-		dai_stop_hdmi(lpa_if->dma_ch);
-		lpa_if->config = 0;
-	}
-	core_req_bus_bandwith(AUDIO_IF_BUS_ID, 0, 0);
-
-	if (hdmi_msm_audio_get_sample_rate() != HDMI_SAMPLE_RATE_48KHZ)
-		hdmi_msm_audio_sample_rate_reset(HDMI_SAMPLE_RATE_48KHZ);
-
-	return 0;
-}
-
-static const struct file_operations lpa_if_fops = {
-	.owner = THIS_MODULE,
-	.open = lpa_if_open,
-	.write = lpa_if_write,
-	.release = lpa_if_release,
-	.unlocked_ioctl = lpa_if_ioctl,
-};
-
-struct miscdevice lpa_if_misc = {
-	.minor = MISC_DYNAMIC_MINOR,
-	.name = "msm_lpa_if_out",
-	.fops = &lpa_if_fops,
-};
-
-static int __init lpa_if_init(void)
-{
-	int rc;
-
-	lpa_if_ptr = kzalloc(sizeof(struct lpa_if), GFP_KERNEL);
-	if (!lpa_if_ptr) {
-		pr_info("No mem for lpa-if\n");
-		return -ENOMEM;
-	}
-
-	mutex_init(&lpa_if_ptr->lock);
-	init_waitqueue_head(&lpa_if_ptr->wait);
-
-	lpa_if_ptr->buffer = dma_alloc_coherent(NULL, DMA_ALLOC_BUF_SZ,
-				    &(lpa_if_ptr->buffer_phys), GFP_KERNEL);
-	if (!lpa_if_ptr->buffer) {
-		pr_err("dma_alloc_coherent failed\n");
-		kfree(lpa_if_ptr);
-		return -ENOMEM;
-	}
-
-	pr_info("lpa_if_ptr 0x%08x   buf_vir 0x%08x   buf_phy 0x%08x "
-		" buf_zise %u\n", (u32)lpa_if_ptr,
-		(u32)(lpa_if_ptr->buffer), lpa_if_ptr->buffer_phys,
-		DMA_ALLOC_BUF_SZ);
-
-	rc =  misc_register(&lpa_if_misc);
-	if (rc < 0) {
-		pr_err("misc_register failed\n");
-
-		dma_free_coherent(NULL, DMA_ALLOC_BUF_SZ, lpa_if_ptr->buffer,
-				lpa_if_ptr->buffer_phys);
-		kfree(lpa_if_ptr);
-	}
-	return rc;
-}
-
-device_initcall(lpa_if_init);
diff --git a/arch/arm/mach-msm/rpcrouter_sdio_xprt.c b/arch/arm/mach-msm/rpcrouter_sdio_xprt.c
deleted file mode 100644
index e9818e5..0000000
--- a/arch/arm/mach-msm/rpcrouter_sdio_xprt.c
+++ /dev/null
@@ -1,655 +0,0 @@
-/* Copyright (c) 2010-2011, The Linux Foundation. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 and
- * only version 2 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- */
-
-/*
- * RPCROUTER SDIO XPRT module.
- */
-
-#include <linux/platform_device.h>
-#include <linux/types.h>
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/string.h>
-#include <linux/errno.h>
-#include <linux/init.h>
-#include <linux/device.h>
-#include <linux/delay.h>
-#include <linux/fs.h>
-#include <linux/err.h>
-#include <linux/sched.h>
-#include <linux/poll.h>
-#include <linux/wakelock.h>
-#include <asm/uaccess.h>
-#include <linux/slab.h>
-
-#include <mach/sdio_al.h>
-#include "smd_rpcrouter.h"
-
-enum {
-	MSM_SDIO_XPRT_DEBUG = 1U << 0,
-	MSM_SDIO_XPRT_INFO = 1U << 1,
-};
-
-static int msm_sdio_xprt_debug_mask;
-module_param_named(debug_mask, msm_sdio_xprt_debug_mask,
-		   int, S_IRUGO | S_IWUSR | S_IWGRP);
-
-#if defined(CONFIG_MSM_RPC_SDIO_DEBUG)
-#define SDIO_XPRT_DBG(x...) do {                \
-	if (msm_sdio_xprt_debug_mask & MSM_SDIO_XPRT_DEBUG)     \
-		printk(KERN_DEBUG x);           \
-	} while (0)
-
-#define SDIO_XPRT_INFO(x...) do {               \
-	if (msm_sdio_xprt_debug_mask & MSM_SDIO_XPRT_INFO)      \
-		printk(KERN_INFO x);            \
-	} while (0)
-#else
-#define SDIO_XPRT_DBG(x...) do { } while (0)
-#define SDIO_XPRT_INFO(x...) do { } while (0)
-#endif
-
-#define MAX_SDIO_WRITE_RETRY 5
-#define SDIO_BUF_SIZE (RPCROUTER_MSGSIZE_MAX + sizeof(struct rr_header) - 8)
-#define NUM_SDIO_BUFS 20
-#define MAX_TX_BUFS 10
-#define MAX_RX_BUFS 10
-
-struct sdio_xprt {
-	struct sdio_channel *handle;
-
-	struct list_head write_list;
-	spinlock_t write_list_lock;
-
-	struct list_head read_list;
-	spinlock_t read_list_lock;
-
-	struct list_head free_list;
-	spinlock_t free_list_lock;
-
-	struct wake_lock read_wakelock;
-};
-
-struct rpcrouter_sdio_xprt {
-	struct rpcrouter_xprt xprt;
-	struct sdio_xprt *channel;
-};
-
-static struct rpcrouter_sdio_xprt sdio_remote_xprt;
-
-static void sdio_xprt_read_data(struct work_struct *work);
-static DECLARE_DELAYED_WORK(work_read_data, sdio_xprt_read_data);
-static struct workqueue_struct *sdio_xprt_read_workqueue;
-
-struct sdio_buf_struct {
-	struct list_head list;
-	uint32_t size;
-	uint32_t read_index;
-	uint32_t write_index;
-	unsigned char data[SDIO_BUF_SIZE];
-};
-
-static void sdio_xprt_write_data(struct work_struct *work);
-static DECLARE_WORK(work_write_data, sdio_xprt_write_data);
-static wait_queue_head_t write_avail_wait_q;
-static uint32_t num_free_bufs;
-static uint32_t num_tx_bufs;
-static uint32_t num_rx_bufs;
-
-static DEFINE_MUTEX(modem_reset_lock);
-static uint32_t modem_reset;
-
-static void free_sdio_xprt(struct sdio_xprt *chnl)
-{
-	struct sdio_buf_struct *buf;
-	unsigned long flags;
-
-	if (!chnl) {
-		printk(KERN_ERR "Invalid chnl to free\n");
-		return;
-	}
-
-	spin_lock_irqsave(&chnl->free_list_lock, flags);
-	while (!list_empty(&chnl->free_list)) {
-		buf = list_first_entry(&chnl->free_list,
-					struct sdio_buf_struct, list);
-		list_del(&buf->list);
-		kfree(buf);
-	}
-	num_free_bufs = 0;
-	spin_unlock_irqrestore(&chnl->free_list_lock, flags);
-
-	spin_lock_irqsave(&chnl->write_list_lock, flags);
-	while (!list_empty(&chnl->write_list)) {
-		buf = list_first_entry(&chnl->write_list,
-					struct sdio_buf_struct, list);
-		list_del(&buf->list);
-		kfree(buf);
-	}
-	num_tx_bufs = 0;
-	spin_unlock_irqrestore(&chnl->write_list_lock, flags);
-
-	spin_lock_irqsave(&chnl->read_list_lock, flags);
-	while (!list_empty(&chnl->read_list)) {
-		buf = list_first_entry(&chnl->read_list,
-					struct sdio_buf_struct, list);
-		list_del(&buf->list);
-		kfree(buf);
-	}
-	num_rx_bufs = 0;
-	spin_unlock_irqrestore(&chnl->read_list_lock, flags);
-	wake_unlock(&chnl->read_wakelock);
-}
-
-static struct sdio_buf_struct *alloc_from_free_list(struct sdio_xprt *chnl)
-{
-	struct sdio_buf_struct *buf;
-	unsigned long flags;
-
-	spin_lock_irqsave(&chnl->free_list_lock, flags);
-	if (list_empty(&chnl->free_list)) {
-		spin_unlock_irqrestore(&chnl->free_list_lock, flags);
-		SDIO_XPRT_DBG("%s: Free list empty\n", __func__);
-		return NULL;
-	}
-	buf = list_first_entry(&chnl->free_list, struct sdio_buf_struct, list);
-	list_del(&buf->list);
-	num_free_bufs--;
-	spin_unlock_irqrestore(&chnl->free_list_lock, flags);
-
-	buf->size = 0;
-	buf->read_index = 0;
-	buf->write_index = 0;
-
-	return buf;
-}
-
-static void return_to_free_list(struct sdio_xprt *chnl,
-				struct sdio_buf_struct *buf)
-{
-	unsigned long flags;
-
-	if (!chnl || !buf) {
-		pr_err("%s: Invalid chnl or buf\n", __func__);
-		return;
-	}
-
-	buf->size = 0;
-	buf->read_index = 0;
-	buf->write_index = 0;
-
-	spin_lock_irqsave(&chnl->free_list_lock, flags);
-	list_add_tail(&buf->list, &chnl->free_list);
-	num_free_bufs++;
-	spin_unlock_irqrestore(&chnl->free_list_lock, flags);
-
-}
-
-static int rpcrouter_sdio_remote_read_avail(void)
-{
-	int read_avail = 0;
-	unsigned long flags;
-	struct sdio_buf_struct *buf;
-
-	spin_lock_irqsave(&sdio_remote_xprt.channel->read_list_lock, flags);
-	list_for_each_entry(buf, &sdio_remote_xprt.channel->read_list, list) {
-		read_avail += buf->size;
-	}
-	spin_unlock_irqrestore(&sdio_remote_xprt.channel->read_list_lock,
-				flags);
-	return read_avail;
-}
-
-static int rpcrouter_sdio_remote_read(void *data, uint32_t len)
-{
-	struct sdio_buf_struct *buf;
-	unsigned char *buf_data;
-	unsigned long flags;
-
-	SDIO_XPRT_DBG("sdio_xprt Called %s\n", __func__);
-	if (len < 0 || !data)
-		return -EINVAL;
-	else if (len == 0)
-		return 0;
-
-	spin_lock_irqsave(&sdio_remote_xprt.channel->read_list_lock, flags);
-	if (list_empty(&sdio_remote_xprt.channel->read_list)) {
-		spin_unlock_irqrestore(
-			&sdio_remote_xprt.channel->read_list_lock, flags);
-		return -EINVAL;
-	}
-
-	buf = list_first_entry(&sdio_remote_xprt.channel->read_list,
-				struct sdio_buf_struct, list);
-	if (buf->size < len) {
-		spin_unlock_irqrestore(
-			&sdio_remote_xprt.channel->read_list_lock, flags);
-		return -EINVAL;
-	}
-
-	buf_data = buf->data + buf->read_index;
-	memcpy(data, buf_data, len);
-	buf->read_index += len;
-	buf->size -= len;
-	if (buf->size == 0) {
-		list_del(&buf->list);
-		num_rx_bufs--;
-		return_to_free_list(sdio_remote_xprt.channel, buf);
-	}
-
-	if (list_empty(&sdio_remote_xprt.channel->read_list))
-		wake_unlock(&sdio_remote_xprt.channel->read_wakelock);
-	spin_unlock_irqrestore(&sdio_remote_xprt.channel->read_list_lock,
-				flags);
-	return len;
-}
-
-static int rpcrouter_sdio_remote_write_avail(void)
-{
-	uint32_t write_avail = 0;
-	unsigned long flags;
-
-	SDIO_XPRT_DBG("sdio_xprt Called %s\n", __func__);
-	spin_lock_irqsave(&sdio_remote_xprt.channel->write_list_lock, flags);
-	write_avail = (MAX_TX_BUFS - num_tx_bufs) * SDIO_BUF_SIZE;
-	spin_unlock_irqrestore(&sdio_remote_xprt.channel->write_list_lock,
-				flags);
-	return write_avail;
-}
-
-static int rpcrouter_sdio_remote_write(void *data, uint32_t len,
-					enum write_data_type type)
-{
-	unsigned long flags;
-	static struct sdio_buf_struct *buf;
-	unsigned char *buf_data;
-
-	switch (type) {
-	case HEADER:
-		spin_lock_irqsave(&sdio_remote_xprt.channel->write_list_lock,
-				  flags);
-		if (num_tx_bufs == MAX_TX_BUFS) {
-			spin_unlock_irqrestore(
-				&sdio_remote_xprt.channel->write_list_lock,
-				flags);
-			return -ENOMEM;
-		}
-		spin_unlock_irqrestore(
-			&sdio_remote_xprt.channel->write_list_lock, flags);
-
-		SDIO_XPRT_DBG("sdio_xprt WRITE HEADER %s\n", __func__);
-		buf = alloc_from_free_list(sdio_remote_xprt.channel);
-		if (!buf) {
-			pr_err("%s: alloc_from_free_list failed\n", __func__);
-			return -ENOMEM;
-		}
-		buf_data = buf->data + buf->write_index;
-		memcpy(buf_data, data, len);
-		buf->write_index += len;
-		buf->size += len;
-		return len;
-	case PACKMARK:
-		SDIO_XPRT_DBG("sdio_xprt WRITE PACKMARK %s\n",	__func__);
-		if (!buf) {
-			pr_err("%s: HEADER not written or alloc failed\n",
-				__func__);
-			return -ENOMEM;
-		}
-		buf_data = buf->data + buf->write_index;
-		memcpy(buf_data, data, len);
-		buf->write_index += len;
-		buf->size += len;
-		return len;
-	case PAYLOAD:
-		SDIO_XPRT_DBG("sdio_xprt WRITE PAYLOAD %s\n",	__func__);
-		if (!buf) {
-			pr_err("%s: HEADER not written or alloc failed\n",
-				__func__);
-			return -ENOMEM;
-		}
-		buf_data = buf->data + buf->write_index;
-		memcpy(buf_data, data, len);
-		buf->write_index += len;
-		buf->size += len;
-
-		SDIO_XPRT_DBG("sdio_xprt flush %d bytes\n", buf->size);
-		spin_lock_irqsave(&sdio_remote_xprt.channel->write_list_lock,
-				   flags);
-		list_add_tail(&buf->list,
-			      &sdio_remote_xprt.channel->write_list);
-		num_tx_bufs++;
-		spin_unlock_irqrestore(
-			&sdio_remote_xprt.channel->write_list_lock, flags);
-		queue_work(sdio_xprt_read_workqueue, &work_write_data);
-		buf = NULL;
-		return len;
-	default:
-		return -EINVAL;
-	}
-}
-
-static void sdio_xprt_write_data(struct work_struct *work)
-{
-	int rc = 0, sdio_write_retry = 0;
-	unsigned long flags;
-	struct sdio_buf_struct *buf;
-
-	mutex_lock(&modem_reset_lock);
-	if (modem_reset) {
-		mutex_unlock(&modem_reset_lock);
-		return;
-	}
-
-	spin_lock_irqsave(&sdio_remote_xprt.channel->write_list_lock, flags);
-	while (!list_empty(&sdio_remote_xprt.channel->write_list)) {
-		buf = list_first_entry(&sdio_remote_xprt.channel->write_list,
-					struct sdio_buf_struct, list);
-		list_del(&buf->list);
-		spin_unlock_irqrestore(
-			&sdio_remote_xprt.channel->write_list_lock, flags);
-		mutex_unlock(&modem_reset_lock);
-
-		wait_event(write_avail_wait_q,
-			   (!(modem_reset) && (sdio_write_avail(
-			   sdio_remote_xprt.channel->handle) >=
-			   buf->size)));
-
-		mutex_lock(&modem_reset_lock);
-		while (!(modem_reset) &&
-			((rc = sdio_write(sdio_remote_xprt.channel->handle,
-					buf->data, buf->size)) < 0) &&
-			(sdio_write_retry++ < MAX_SDIO_WRITE_RETRY)) {
-			printk(KERN_ERR "sdio_write failed with RC %d\n", rc);
-			mutex_unlock(&modem_reset_lock);
-			msleep(250);
-			mutex_lock(&modem_reset_lock);
-		}
-		if (modem_reset) {
-			mutex_unlock(&modem_reset_lock);
-			kfree(buf);
-			return;
-		} else {
-			return_to_free_list(sdio_remote_xprt.channel, buf);
-		}
-
-		if (!rc)
-			SDIO_XPRT_DBG("sdio_write %d bytes completed\n",
-					buf->size);
-
-		spin_lock_irqsave(&sdio_remote_xprt.channel->write_list_lock,
-				   flags);
-		num_tx_bufs--;
-	}
-	spin_unlock_irqrestore(&sdio_remote_xprt.channel->write_list_lock,
-				flags);
-	mutex_unlock(&modem_reset_lock);
-}
-
-static int rpcrouter_sdio_remote_close(void)
-{
-	SDIO_XPRT_DBG("sdio_xprt Called %s\n", __func__);
-	flush_workqueue(sdio_xprt_read_workqueue);
-	sdio_close(sdio_remote_xprt.channel->handle);
-	free_sdio_xprt(sdio_remote_xprt.channel);
-	return 0;
-}
-
-static void sdio_xprt_read_data(struct work_struct *work)
-{
-	int size = 0, read_avail;
-	unsigned long flags;
-	struct sdio_buf_struct *buf;
-	SDIO_XPRT_DBG("sdio_xprt Called %s\n", __func__);
-
-	mutex_lock(&modem_reset_lock);
-	while (!(modem_reset) &&
-		((read_avail =
-		sdio_read_avail(sdio_remote_xprt.channel->handle)) > 0)) {
-		spin_lock_irqsave(&sdio_remote_xprt.channel->read_list_lock,
-				  flags);
-		if (num_rx_bufs == MAX_RX_BUFS) {
-			spin_unlock_irqrestore(
-				&sdio_remote_xprt.channel->read_list_lock,
-				flags);
-			queue_delayed_work(sdio_xprt_read_workqueue,
-					   &work_read_data,
-					   msecs_to_jiffies(100));
-			break;
-		}
-		spin_unlock_irqrestore(
-			&sdio_remote_xprt.channel->read_list_lock, flags);
-
-		buf = alloc_from_free_list(sdio_remote_xprt.channel);
-		if (!buf) {
-			SDIO_XPRT_DBG("%s: Failed to alloc_from_free_list"
-				      " Try again later\n", __func__);
-			queue_delayed_work(sdio_xprt_read_workqueue,
-					   &work_read_data,
-					   msecs_to_jiffies(100));
-			break;
-		}
-
-		size = sdio_read(sdio_remote_xprt.channel->handle,
-				 buf->data, read_avail);
-		if (size < 0) {
-			printk(KERN_ERR "sdio_read failed,"
-					" read %d bytes, expected %d\n",
-					size, read_avail);
-			return_to_free_list(sdio_remote_xprt.channel, buf);
-			queue_delayed_work(sdio_xprt_read_workqueue,
-					   &work_read_data,
-					   msecs_to_jiffies(100));
-			break;
-		}
-
-		if (size == 0)
-			size = read_avail;
-
-		buf->size = size;
-		buf->write_index = size;
-		spin_lock_irqsave(&sdio_remote_xprt.channel->read_list_lock,
-				   flags);
-		list_add_tail(&buf->list,
-			      &sdio_remote_xprt.channel->read_list);
-		num_rx_bufs++;
-		spin_unlock_irqrestore(
-			&sdio_remote_xprt.channel->read_list_lock, flags);
-		wake_lock(&sdio_remote_xprt.channel->read_wakelock);
-	}
-
-	if (!modem_reset && !list_empty(&sdio_remote_xprt.channel->read_list))
-		msm_rpcrouter_xprt_notify(&sdio_remote_xprt.xprt,
-				  RPCROUTER_XPRT_EVENT_DATA);
-	mutex_unlock(&modem_reset_lock);
-}
-
-static void rpcrouter_sdio_remote_notify(void *_dev, unsigned event)
-{
-	if (event == SDIO_EVENT_DATA_READ_AVAIL) {
-		SDIO_XPRT_DBG("%s Received Notify"
-			      "SDIO_EVENT_DATA_READ_AVAIL\n", __func__);
-		queue_delayed_work(sdio_xprt_read_workqueue,
-				   &work_read_data, 0);
-	}
-	if (event == SDIO_EVENT_DATA_WRITE_AVAIL) {
-		SDIO_XPRT_DBG("%s Received Notify"
-			      "SDIO_EVENT_DATA_WRITE_AVAIL\n", __func__);
-		wake_up(&write_avail_wait_q);
-	}
-}
-
-static int allocate_sdio_xprt(struct sdio_xprt **sdio_xprt_chnl)
-{
-	struct sdio_buf_struct *buf;
-	struct sdio_xprt *chnl;
-	int i;
-	unsigned long flags;
-	int rc = -ENOMEM;
-
-	if (!(*sdio_xprt_chnl)) {
-		chnl = kmalloc(sizeof(struct sdio_xprt), GFP_KERNEL);
-		if (!chnl) {
-			printk(KERN_ERR "sdio_xprt channel"
-					" allocation failed\n");
-			return rc;
-		}
-
-		spin_lock_init(&chnl->write_list_lock);
-		spin_lock_init(&chnl->read_list_lock);
-		spin_lock_init(&chnl->free_list_lock);
-
-		INIT_LIST_HEAD(&chnl->write_list);
-		INIT_LIST_HEAD(&chnl->read_list);
-		INIT_LIST_HEAD(&chnl->free_list);
-		wake_lock_init(&chnl->read_wakelock,
-				WAKE_LOCK_SUSPEND, "rpc_sdio_xprt_read");
-	} else {
-		chnl = *sdio_xprt_chnl;
-	}
-
-	for (i = 0; i < NUM_SDIO_BUFS; i++) {
-		buf = kzalloc(sizeof(struct sdio_buf_struct), GFP_KERNEL);
-		if (!buf) {
-			printk(KERN_ERR "sdio_buf_struct alloc failed\n");
-			goto alloc_failure;
-		}
-		spin_lock_irqsave(&chnl->free_list_lock, flags);
-		list_add_tail(&buf->list, &chnl->free_list);
-		spin_unlock_irqrestore(&chnl->free_list_lock, flags);
-	}
-	num_free_bufs = NUM_SDIO_BUFS;
-
-	*sdio_xprt_chnl = chnl;
-	return 0;
-
-alloc_failure:
-	spin_lock_irqsave(&chnl->free_list_lock, flags);
-	while (!list_empty(&chnl->free_list)) {
-		buf = list_first_entry(&chnl->free_list,
-					struct sdio_buf_struct,
-					list);
-		list_del(&buf->list);
-		kfree(buf);
-	}
-	spin_unlock_irqrestore(&chnl->free_list_lock, flags);
-	wake_lock_destroy(&chnl->read_wakelock);
-
-	kfree(chnl);
-	*sdio_xprt_chnl = NULL;
-	return rc;
-}
-
-static int rpcrouter_sdio_remote_probe(struct platform_device *pdev)
-{
-	int rc;
-
-	SDIO_XPRT_INFO("%s Called\n", __func__);
-
-	mutex_lock(&modem_reset_lock);
-	if (!modem_reset) {
-		sdio_xprt_read_workqueue =
-			create_singlethread_workqueue("sdio_xprt");
-		if (!sdio_xprt_read_workqueue) {
-			mutex_unlock(&modem_reset_lock);
-			return -ENOMEM;
-		}
-
-		sdio_remote_xprt.xprt.name = "rpcrotuer_sdio_xprt";
-		sdio_remote_xprt.xprt.read_avail =
-			rpcrouter_sdio_remote_read_avail;
-		sdio_remote_xprt.xprt.read = rpcrouter_sdio_remote_read;
-		sdio_remote_xprt.xprt.write_avail =
-			rpcrouter_sdio_remote_write_avail;
-		sdio_remote_xprt.xprt.write = rpcrouter_sdio_remote_write;
-		sdio_remote_xprt.xprt.close = rpcrouter_sdio_remote_close;
-		sdio_remote_xprt.xprt.priv = NULL;
-
-		init_waitqueue_head(&write_avail_wait_q);
-	}
-	modem_reset = 0;
-
-	rc = allocate_sdio_xprt(&sdio_remote_xprt.channel);
-	if (rc) {
-		destroy_workqueue(sdio_xprt_read_workqueue);
-		mutex_unlock(&modem_reset_lock);
-		return rc;
-	}
-
-	/* Open up SDIO channel */
-	rc = sdio_open("SDIO_RPC", &sdio_remote_xprt.channel->handle, NULL,
-		      rpcrouter_sdio_remote_notify);
-
-	if (rc < 0) {
-		free_sdio_xprt(sdio_remote_xprt.channel);
-		destroy_workqueue(sdio_xprt_read_workqueue);
-		mutex_unlock(&modem_reset_lock);
-		return rc;
-	}
-	mutex_unlock(&modem_reset_lock);
-
-	msm_rpcrouter_xprt_notify(&sdio_remote_xprt.xprt,
-				  RPCROUTER_XPRT_EVENT_OPEN);
-
-	SDIO_XPRT_INFO("%s Completed\n", __func__);
-
-	return 0;
-}
-
-static int rpcrouter_sdio_remote_remove(struct platform_device *pdev)
-{
-	SDIO_XPRT_INFO("%s Called\n", __func__);
-
-	mutex_lock(&modem_reset_lock);
-	modem_reset = 1;
-	wake_up(&write_avail_wait_q);
-	free_sdio_xprt(sdio_remote_xprt.channel);
-	mutex_unlock(&modem_reset_lock);
-
-	msm_rpcrouter_xprt_notify(&sdio_remote_xprt.xprt,
-				  RPCROUTER_XPRT_EVENT_CLOSE);
-
-	SDIO_XPRT_INFO("%s Completed\n", __func__);
-
-	return 0;
-}
-
-/*Remove this platform driver after mainline of SDIO_AL update*/
-static struct platform_driver rpcrouter_sdio_remote_driver = {
-	.probe		= rpcrouter_sdio_remote_probe,
-	.driver		= {
-			.name	= "SDIO_AL",
-			.owner	= THIS_MODULE,
-	},
-};
-
-static struct platform_driver rpcrouter_sdio_driver = {
-	.probe		= rpcrouter_sdio_remote_probe,
-	.remove		= rpcrouter_sdio_remote_remove,
-	.driver		= {
-			.name	= "SDIO_RPC",
-			.owner	= THIS_MODULE,
-	},
-};
-
-static int __init rpcrouter_sdio_init(void)
-{
-	int rc;
-	msm_sdio_xprt_debug_mask = 0x2;
-	rc = platform_driver_register(&rpcrouter_sdio_remote_driver);
-	if (rc < 0)
-		return rc;
-	return platform_driver_register(&rpcrouter_sdio_driver);
-}
-
-module_init(rpcrouter_sdio_init);
-MODULE_DESCRIPTION("RPC Router SDIO XPRT");
-MODULE_LICENSE("GPL v2");
diff --git a/arch/arm/mach-msm/rpm-regulator-smd.c b/arch/arm/mach-msm/rpm-regulator-smd.c
index c4c9566..654e526 100644
--- a/arch/arm/mach-msm/rpm-regulator-smd.c
+++ b/arch/arm/mach-msm/rpm-regulator-smd.c
@@ -1091,14 +1091,16 @@
 {
 	struct device *dev = &pdev->dev;
 	struct rpm_regulator *reg;
+	struct rpm_vreg *rpm_vreg;
 
 	reg = platform_get_drvdata(pdev);
 	if (reg) {
-		rpm_vreg_lock(reg->rpm_vreg);
+		rpm_vreg = reg->rpm_vreg;
+		rpm_vreg_lock(rpm_vreg);
 		regulator_unregister(reg->rdev);
 		list_del(&reg->list);
 		kfree(reg);
-		rpm_vreg_unlock(reg->rpm_vreg);
+		rpm_vreg_unlock(rpm_vreg);
 	} else {
 		dev_err(dev, "%s: drvdata missing\n", __func__);
 		return -EINVAL;
diff --git a/arch/arm/mach-msm/sdio_al.c b/arch/arm/mach-msm/sdio_al.c
deleted file mode 100644
index bcfc556..0000000
--- a/arch/arm/mach-msm/sdio_al.c
+++ /dev/null
@@ -1,4365 +0,0 @@
-/* Copyright (c) 2010-2011, The Linux Foundation. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 and
- * only version 2 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- */
-
-/*
- * SDIO-Abstraction-Layer Module.
- *
- * To be used with Qualcomm's SDIO-Client connected to this host.
- */
-#include "sdio_al_private.h"
-
-#include <linux/module.h>
-#include <linux/scatterlist.h>
-#include <linux/workqueue.h>
-#include <linux/wait.h>
-#include <linux/delay.h>
-#include <linux/fs.h>
-#include <linux/slab.h>
-#include <linux/wakelock.h>
-#include <linux/mmc/core.h>
-#include <linux/mmc/card.h>
-#include <linux/mmc/host.h>
-#include <linux/mmc/mmc.h>
-#include <linux/mmc/sdio.h>
-#include <linux/mmc/sdio_func.h>
-#include <linux/mmc/sdio_ids.h>
-#include <linux/gpio.h>
-#include <linux/dma-mapping.h>
-#include <linux/earlysuspend.h>
-#include <linux/debugfs.h>
-#include <linux/uaccess.h>
-#include <linux/syscalls.h>
-#include <linux/time.h>
-#include <linux/spinlock.h>
-
-#include <mach/dma.h>
-#include <mach/gpio.h>
-#include <mach/subsystem_notif.h>
-
-#include "../../../drivers/mmc/host/msm_sdcc.h"
-
-/**
- *  Func#0 has SDIO standard registers
- *  Func#1 is for Mailbox.
- *  Functions 2..7 are for channels.
- *  Currently only functions 2..5 are active due to SDIO-Client
- *  number of pipes.
- *
- */
-#define SDIO_AL_MAX_CHANNELS 6
-
-/** Func 1..5 */
-#define SDIO_AL_MAX_FUNCS    (SDIO_AL_MAX_CHANNELS+1)
-#define SDIO_AL_WAKEUP_FUNC  6
-
-/** Number of SDIO-Client pipes */
-#define SDIO_AL_MAX_PIPES    16
-#define SDIO_AL_ACTIVE_PIPES 8
-
-/** CMD53/CMD54 Block size */
-#define SDIO_AL_BLOCK_SIZE   256
-
-/** Func#1 hardware Mailbox base address	 */
-#define HW_MAILBOX_ADDR			0x1000
-
-/** Func#1 peer sdioc software version.
- *  The header is duplicated also to the mailbox of the other
- *  functions. It can be used before other functions are enabled. */
-#define SDIOC_SW_HEADER_ADDR		0x0400
-
-/** Func#2..7 software Mailbox base address at 16K */
-#define SDIOC_SW_MAILBOX_ADDR			0x4000
-
-/** Some Mailbox registers address, written by host for
- control */
-#define PIPES_THRESHOLD_ADDR		0x01000
-
-#define PIPES_0_7_IRQ_MASK_ADDR 	0x01048
-
-#define PIPES_8_15_IRQ_MASK_ADDR	0x0104C
-
-#define FUNC_1_4_MASK_IRQ_ADDR		0x01040
-#define FUNC_5_7_MASK_IRQ_ADDR		0x01044
-#define FUNC_1_4_USER_IRQ_ADDR		0x01050
-#define FUNC_5_7_USER_IRQ_ADDR		0x01054
-
-#define EOT_PIPES_ENABLE		0x00
-
-/** Maximum read/write data available is SDIO-Client limitation */
-#define MAX_DATA_AVAILABLE   		(16*1024)
-#define INVALID_DATA_AVAILABLE  	(0x8000)
-
-/** SDIO-Client HW threshold to generate interrupt to the
- *  SDIO-Host on write available bytes.
- */
-#define DEFAULT_WRITE_THRESHOLD 	(1024)
-
-/** SDIO-Client HW threshold to generate interrupt to the
- *  SDIO-Host on read available bytes, for streaming (non
- *  packet) rx data.
- */
-#define DEFAULT_READ_THRESHOLD  	(1024)
-#define LOW_LATENCY_THRESHOLD		(1)
-
-/* Extra bytes to ensure getting the rx threshold interrupt on stream channels
-   when restoring the threshold after sleep */
-#define THRESHOLD_CHANGE_EXTRA_BYTES (100)
-
-/** SW threshold to trigger reading the mailbox. */
-#define DEFAULT_MIN_WRITE_THRESHOLD 	(1024)
-#define DEFAULT_MIN_WRITE_THRESHOLD_STREAMING	(1600)
-
-#define THRESHOLD_DISABLE_VAL  		(0xFFFFFFFF)
-
-/** Mailbox polling time for packet channels */
-#define DEFAULT_POLL_DELAY_MSEC		10
-/** Mailbox polling time for streaming channels */
-#define DEFAULT_POLL_DELAY_NOPACKET_MSEC 30
-
-/** The SDIO-Client prepares N buffers of size X per Tx pipe.
- *  Even when the transfer fills a partial buffer,
- *  that buffer becomes unusable for the next transfer. */
-#define DEFAULT_PEER_TX_BUF_SIZE	(128)
-
-#define ROUND_UP(x, n) (((x + n - 1) / n) * n)
-
-/** Func#2..7 FIFOs are r/w via
- sdio_readsb() & sdio_writesb(),when inc_addr=0 */
-#define PIPE_RX_FIFO_ADDR   0x00
-#define PIPE_TX_FIFO_ADDR   0x00
-
-/** Inactivity time to go to sleep in mseconds */
-#define INACTIVITY_TIME_MSEC 30
-#define INITIAL_INACTIVITY_TIME_MSEC 5000
-
-/** Context validity check */
-#define SDIO_AL_SIGNATURE 0xAABBCCDD
-
-/* Vendor Specific Command */
-#define SD_IO_RW_EXTENDED_QCOM 54
-
-#define TIME_TO_WAIT_US 500
-#define SDIO_CLOSE_FLUSH_TIMEOUT_MSEC   (10000)
-#define RX_FLUSH_BUFFER_SIZE (16*1024)
-
-#define SDIO_TEST_POSTFIX "_TEST"
-
-#define DATA_DEBUG(x, y...)						\
-	do {								\
-		if (sdio_al->debug.debug_data_on)			\
-			pr_info(y);					\
-		sdio_al_log(x, y);					\
-	} while (0)
-
-#define LPM_DEBUG(x, y...)						\
-	do {								\
-		if (sdio_al->debug.debug_lpm_on)			\
-			pr_info(y);					\
-		sdio_al_log(x, y);					\
-	} while (0)
-
-#define sdio_al_loge(x, y...)						\
-	do {								\
-		pr_err(y);						\
-		sdio_al_log(x, y);					\
-	} while (0)
-
-#define sdio_al_logi(x, y...)						\
-	do {								\
-		pr_info(y);						\
-		sdio_al_log(x, y);					\
-	} while (0)
-
-#define CLOSE_DEBUG(x, y...)						\
-	do {								\
-		if (sdio_al->debug.debug_close_on)			\
-			pr_info(y);					\
-		sdio_al_log(x, y);					\
-	} while (0)
-
-/* The index of the SDIO card used for the sdio_al_dloader */
-#define SDIO_BOOTLOADER_CARD_INDEX 1
-
-
-/* SDIO card state machine */
-enum sdio_al_device_state {
-	CARD_INSERTED,
-	CARD_REMOVED,
-	MODEM_RESTART
-};
-
-struct sdio_al_debug {
-	u8 debug_lpm_on;
-	u8 debug_data_on;
-	u8 debug_close_on;
-	struct dentry *sdio_al_debug_root;
-	struct dentry *sdio_al_debug_lpm_on;
-	struct dentry *sdio_al_debug_data_on;
-	struct dentry *sdio_al_debug_close_on;
-	struct dentry *sdio_al_debug_info;
-	struct dentry *sdio_al_debug_log_buffers[MAX_NUM_OF_SDIO_DEVICES + 1];
-};
-
-/* Polling time for the inactivity timer for devices that doesn't have
- * a streaming channel
- */
-#define SDIO_AL_POLL_TIME_NO_STREAMING 30
-
-#define CHAN_TO_FUNC(x) ((x) + 2 - 1)
-
-/**
- *  Mailbox structure.
- *  The Mailbox is located on the SDIO-Client Function#1.
- *  The mailbox size is 128 bytes, which is one block.
- *  The mailbox allows the host ton:
- *  1. Get the number of available bytes on the pipes.
- *  2. Enable/Disable SDIO-Client interrupt, related to pipes.
- *  3. Set the Threshold for generating interrupt.
- *
- */
-struct sdio_mailbox {
-	u32 pipe_bytes_threshold[SDIO_AL_MAX_PIPES]; /* Addr 0x1000 */
-
-	/* Mask USER interrupts generated towards host - Addr 0x1040 */
-	u32 mask_irq_func_1:8; /* LSB */
-	u32 mask_irq_func_2:8;
-	u32 mask_irq_func_3:8;
-	u32 mask_irq_func_4:8;
-
-	u32 mask_irq_func_5:8;
-	u32 mask_irq_func_6:8;
-	u32 mask_irq_func_7:8;
-	u32 mask_mutex_irq:8;
-
-	/* Mask PIPE interrupts generated towards host - Addr 0x1048 */
-	u32 mask_eot_pipe_0_7:8;
-	u32 mask_thresh_above_limit_pipe_0_7:8;
-	u32 mask_overflow_pipe_0_7:8;
-	u32 mask_underflow_pipe_0_7:8;
-
-	u32 mask_eot_pipe_8_15:8;
-	u32 mask_thresh_above_limit_pipe_8_15:8;
-	u32 mask_overflow_pipe_8_15:8;
-	u32 mask_underflow_pipe_8_15:8;
-
-	/* Status of User interrupts generated towards host - Addr 0x1050 */
-	u32 user_irq_func_1:8;
-	u32 user_irq_func_2:8;
-	u32 user_irq_func_3:8;
-	u32 user_irq_func_4:8;
-
-	u32 user_irq_func_5:8;
-	u32 user_irq_func_6:8;
-	u32 user_irq_func_7:8;
-	u32 user_mutex_irq:8;
-
-	/* Status of PIPE interrupts generated towards host */
-	/* Note: All sources are cleared once they read. - Addr 0x1058 */
-	u32 eot_pipe_0_7:8;
-	u32 thresh_above_limit_pipe_0_7:8;
-	u32 overflow_pipe_0_7:8;
-	u32 underflow_pipe_0_7:8;
-
-	u32 eot_pipe_8_15:8;
-	u32 thresh_above_limit_pipe_8_15:8;
-	u32 overflow_pipe_8_15:8;
-	u32 underflow_pipe_8_15:8;
-
-	u16 pipe_bytes_avail[SDIO_AL_MAX_PIPES];
-};
-
-/** Track pending Rx Packet size */
-struct rx_packet_size {
-	u32 size; /* in bytes */
-	struct list_head	list;
-};
-
-#define PEER_SDIOC_SW_MAILBOX_SIGNATURE 0xFACECAFE
-#define PEER_SDIOC_SW_MAILBOX_UT_SIGNATURE 0x5D107E57
-#define PEER_SDIOC_SW_MAILBOX_BOOT_SIGNATURE 0xDEADBEEF
-
-/* Allow support in old sdio version */
-#define PEER_SDIOC_OLD_VERSION_MAJOR	0x0002
-#define INVALID_SDIO_CHAN		0xFF
-
-/**
- * Peer SDIO-Client software header.
- */
-struct peer_sdioc_sw_header {
-	u32 signature;
-	u32 version;
-	u32 max_channels;
-	char channel_names[SDIO_AL_MAX_CHANNELS][PEER_CHANNEL_NAME_SIZE];
-	u32 reserved[23];
-};
-
-struct peer_sdioc_boot_sw_header {
-	u32 signature;
-	u32 version;
-	u32 boot_ch_num;
-	u32 reserved[29]; /* 32 - previous fields */
-};
-
-/**
- * Peer SDIO-Client software mailbox.
- */
-struct peer_sdioc_sw_mailbox {
-	struct peer_sdioc_sw_header sw_header;
-	struct peer_sdioc_channel_config ch_config[SDIO_AL_MAX_CHANNELS];
-};
-
-#define SDIO_AL_DEBUG_LOG_SIZE 3000
-struct sdio_al_local_log {
-	char buffer[SDIO_AL_DEBUG_LOG_SIZE];
-	unsigned int buf_cur_pos;
-	spinlock_t log_lock;
-};
-
-#define SDIO_AL_DEBUG_TMP_LOG_SIZE 250
-static int sdio_al_log(struct sdio_al_local_log *, const char *fmt, ...);
-
-/**
- *  SDIO Abstraction Layer driver context.
- *
- *  @pdata -
- *  @debug -
- *  @devices - an array of the the devices claimed by sdio_al
- *  @unittest_mode - a flag to indicate if sdio_al is in
- *		   unittest mode
- *  @bootloader_dev - the device which is used for the
- *                 bootloader
- *  @subsys_notif_handle - handle for modem restart
- *                 notifications
- *
- */
-struct sdio_al {
-	struct sdio_al_local_log gen_log;
-	struct sdio_al_local_log device_log[MAX_NUM_OF_SDIO_DEVICES];
-	struct sdio_al_platform_data *pdata;
-	struct sdio_al_debug debug;
-	struct sdio_al_device *devices[MAX_NUM_OF_SDIO_DEVICES];
-	int unittest_mode;
-	struct sdio_al_device *bootloader_dev;
-	void *subsys_notif_handle;
-	int sdioc_major;
-	int skip_print_info;
-};
-
-struct sdio_al_work {
-	struct work_struct work;
-	struct sdio_al_device *sdio_al_dev;
-};
-
-
-/**
- *  SDIO Abstraction Layer device context.
- *
- *  @card - card claimed.
- *
- *  @mailbox - A shadow of the SDIO-Client mailbox.
- *
- *  @channel - Channels context.
- *
- *  @workqueue - workqueue to read the mailbox and handle
- *     pending requests. Reading the mailbox should not happen
- *     in interrupt context.
- *
- *  @work - work to submit to workqueue.
- *
- *  @is_ready - driver is ready.
- *
- *  @ask_mbox - Flag to request reading the mailbox,
- *					  for different reasons.
- *
- *  @wake_lock - Lock when can't sleep.
- *
- *  @lpm_chan - Channel to use for LPM (low power mode)
- *            communication.
- *
- *  @is_ok_to_sleep - Mark if driver is OK with going to sleep
- * 			(no pending transactions).
- *
- *  @inactivity_time - time allowed to be in inactivity before
- * 		going to sleep
- *
- *  @timer - timer to use for polling the mailbox.
- *
- *  @poll_delay_msec - timer delay for polling the mailbox.
- *
- *  @is_err - error detected.
- *
- *  @signature - Context Validity Check.
- *
- *  @flashless_boot_on - flag to indicate if sdio_al is in
- *    flshless boot mode
- *
- */
-struct sdio_al_device {
-	struct sdio_al_local_log *dev_log;
-	struct mmc_card *card;
-	struct mmc_host *host;
-	struct sdio_mailbox *mailbox;
-	struct sdio_channel channel[SDIO_AL_MAX_CHANNELS];
-
-	struct peer_sdioc_sw_header *sdioc_sw_header;
-	struct peer_sdioc_boot_sw_header *sdioc_boot_sw_header;
-
-	struct workqueue_struct *workqueue;
-	struct sdio_al_work sdio_al_work;
-	struct sdio_al_work boot_work;
-
-	int is_ready;
-
-	wait_queue_head_t   wait_mbox;
-	int ask_mbox;
-	int bootloader_done;
-
-	struct wake_lock wake_lock;
-	int lpm_chan;
-	int is_ok_to_sleep;
-	unsigned long inactivity_time;
-
-	struct timer_list timer;
-	u32 poll_delay_msec;
-	int is_timer_initialized;
-
-	int is_err;
-
-	u32 signature;
-
-	unsigned int is_suspended;
-
-	int flashless_boot_on;
-	int ch_close_supported;
-	int state;
-	int (*lpm_callback)(void *, int);
-
-	int print_after_interrupt;
-
-	u8 *rx_flush_buf;
-};
-
-/*
- * Host operation:
- *   lower 16bits are operation code
- *   upper 16bits are operation state
- */
-#define PEER_OPERATION(op_code , op_state) ((op_code) | ((op_state) << 16))
-#define GET_PEER_OPERATION_CODE(op) ((op) & 0xffff)
-#define GET_PEER_OPERATION_STATE(op) ((op) >> 16)
-
-enum peer_op_code {
-	PEER_OP_CODE_CLOSE = 1
-};
-
-enum peer_op_state {
-	PEER_OP_STATE_INIT = 0,
-	PEER_OP_STATE_START = 1
-};
-
-
-/*
- * On the kernel command line specify
- * sdio_al.debug_lpm_on=1 to enable the LPM debug messages
- * By default the LPM debug messages are turned off
- */
-static int debug_lpm_on;
-module_param(debug_lpm_on, int, 0);
-
-/*
- * On the kernel command line specify
- * sdio_al.debug_data_on=1 to enable the DATA debug messages
- * By default the DATA debug messages are turned off
- */
-static int debug_data_on;
-module_param(debug_data_on, int, 0);
-
-/*
- * Enables / disables open close debug messages
- */
-static int debug_close_on = 1;
-module_param(debug_close_on, int, 0);
-
-/** The driver context */
-static struct sdio_al *sdio_al;
-
-/* Static functions declaration */
-static int enable_eot_interrupt(struct sdio_al_device *sdio_al_dev,
-				int pipe_index, int enable);
-static int enable_threshold_interrupt(struct sdio_al_device *sdio_al_dev,
-				      int pipe_index, int enable);
-static void sdio_func_irq(struct sdio_func *func);
-static void sdio_al_timer_handler(unsigned long data);
-static int get_min_poll_time_msec(struct sdio_al_device *sdio_al_dev);
-static u32 check_pending_rx_packet(struct sdio_channel *ch, u32 eot);
-static u32 remove_handled_rx_packet(struct sdio_channel *ch);
-static int set_pipe_threshold(struct sdio_al_device *sdio_al_dev,
-			      int pipe_index, int threshold);
-static int sdio_al_wake_up(struct sdio_al_device *sdio_al_dev,
-			   u32 not_from_int, struct sdio_channel *ch);
-static int sdio_al_client_setup(struct sdio_al_device *sdio_al_dev);
-static int enable_mask_irq(struct sdio_al_device *sdio_al_dev,
-			   int func_num, int enable, u8 bit_offset);
-static int sdio_al_enable_func_retry(struct sdio_func *func, const char *name);
-static void sdio_al_print_info(void);
-static int sdio_read_internal(struct sdio_channel *ch, void *data, int len);
-static int sdio_read_from_closed_ch(struct sdio_channel *ch, int len);
-static void stop_and_del_timer(struct sdio_al_device *sdio_al_dev);
-
-#define SDIO_AL_ERR(func)					\
-	do {							\
-		printk_once(KERN_ERR MODULE_NAME		\
-			":In Error state, ignore %s\n",		\
-			func);					\
-		sdio_al_print_info();				\
-	} while (0)
-
-#ifdef CONFIG_DEBUG_FS
-static int debug_info_open(struct inode *inode, struct file *file)
-{
-	file->private_data = inode->i_private;
-	return 0;
-}
-
-static ssize_t debug_info_write(struct file *file,
-		const char __user *buf, size_t count, loff_t *ppos)
-{
-	sdio_al_print_info();
-	return 1;
-}
-
-const struct file_operations debug_info_ops = {
-	.open = debug_info_open,
-	.write = debug_info_write,
-};
-
-struct debugfs_blob_wrapper sdio_al_dbgfs_log[MAX_NUM_OF_SDIO_DEVICES + 1];
-
-/*
-*
-* Trigger on/off for debug messages
-* for trigger off the data messages debug level use:
-* echo 0 > /sys/kernel/debugfs/sdio_al/debug_data_on
-* for trigger on the data messages debug level use:
-* echo 1 > /sys/kernel/debugfs/sdio_al/debug_data_on
-* for trigger off the lpm messages debug level use:
-* echo 0 > /sys/kernel/debugfs/sdio_al/debug_lpm_on
-* for trigger on the lpm messages debug level use:
-* echo 1 > /sys/kernel/debugfs/sdio_al/debug_lpm_on
-*/
-static int sdio_al_debugfs_init(void)
-{
-	int i, blob_errs = 0;
-
-	sdio_al->debug.sdio_al_debug_root = debugfs_create_dir("sdio_al", NULL);
-	if (!sdio_al->debug.sdio_al_debug_root)
-		return -ENOENT;
-
-	sdio_al->debug.sdio_al_debug_lpm_on = debugfs_create_u8("debug_lpm_on",
-					S_IRUGO | S_IWUGO,
-					sdio_al->debug.sdio_al_debug_root,
-					&sdio_al->debug.debug_lpm_on);
-
-	sdio_al->debug.sdio_al_debug_data_on = debugfs_create_u8(
-					"debug_data_on",
-					S_IRUGO | S_IWUGO,
-					sdio_al->debug.sdio_al_debug_root,
-					&sdio_al->debug.debug_data_on);
-
-	sdio_al->debug.sdio_al_debug_close_on = debugfs_create_u8(
-					"debug_close_on",
-					S_IRUGO | S_IWUGO,
-					sdio_al->debug.sdio_al_debug_root,
-					&sdio_al->debug.debug_close_on);
-
-	sdio_al->debug.sdio_al_debug_info = debugfs_create_file(
-					"sdio_debug_info",
-					S_IRUGO | S_IWUGO,
-					sdio_al->debug.sdio_al_debug_root,
-					NULL,
-					&debug_info_ops);
-
-	for (i = 0; i < MAX_NUM_OF_SDIO_DEVICES; ++i) {
-		char temp[18];
-
-		scnprintf(temp, 18, "sdio_al_log_dev_%d", i + 1);
-		sdio_al->debug.sdio_al_debug_log_buffers[i] =
-			debugfs_create_blob(temp,
-					S_IRUGO | S_IWUGO,
-					sdio_al->debug.sdio_al_debug_root,
-					&sdio_al_dbgfs_log[i]);
-	}
-
-	sdio_al->debug.sdio_al_debug_log_buffers[MAX_NUM_OF_SDIO_DEVICES] =
-			debugfs_create_blob("sdio_al_gen_log",
-				S_IRUGO | S_IWUGO,
-				sdio_al->debug.sdio_al_debug_root,
-				&sdio_al_dbgfs_log[MAX_NUM_OF_SDIO_DEVICES]);
-
-	for (i = 0; i < (MAX_NUM_OF_SDIO_DEVICES + 1); ++i) {
-		if (!sdio_al->debug.sdio_al_debug_log_buffers[i]) {
-			pr_err(MODULE_NAME ": Failed to create debugfs buffer"
-				   " entry for "
-				   "sdio_al->debug.sdio_al_debug_log_buffers[%d]",
-				   i);
-			blob_errs = 1;
-		}
-	}
-
-	if (blob_errs) {
-		for (i = 0; i < (MAX_NUM_OF_SDIO_DEVICES + 1); ++i)
-			if (sdio_al->debug.sdio_al_debug_log_buffers[i])
-				debugfs_remove(
-					sdio_al->
-					debug.sdio_al_debug_log_buffers[i]);
-	}
-
-
-	if ((!sdio_al->debug.sdio_al_debug_data_on) &&
-	    (!sdio_al->debug.sdio_al_debug_lpm_on) &&
-	    (!sdio_al->debug.sdio_al_debug_close_on) &&
-	    (!sdio_al->debug.sdio_al_debug_info) &&
-		blob_errs) {
-		debugfs_remove(sdio_al->debug.sdio_al_debug_root);
-		sdio_al->debug.sdio_al_debug_root = NULL;
-		return -ENOENT;
-	}
-
-	sdio_al_dbgfs_log[MAX_NUM_OF_SDIO_DEVICES].data =
-						sdio_al->gen_log.buffer;
-	sdio_al_dbgfs_log[MAX_NUM_OF_SDIO_DEVICES].size =
-						SDIO_AL_DEBUG_LOG_SIZE;
-
-	return 0;
-}
-
-static void sdio_al_debugfs_cleanup(void)
-{
-	int i;
-
-	debugfs_remove(sdio_al->debug.sdio_al_debug_lpm_on);
-	debugfs_remove(sdio_al->debug.sdio_al_debug_data_on);
-	debugfs_remove(sdio_al->debug.sdio_al_debug_close_on);
-	debugfs_remove(sdio_al->debug.sdio_al_debug_info);
-
-	for (i = 0; i < (MAX_NUM_OF_SDIO_DEVICES + 1); ++i)
-		debugfs_remove(sdio_al->debug.sdio_al_debug_log_buffers[i]);
-
-	debugfs_remove(sdio_al->debug.sdio_al_debug_root);
-}
-#endif
-
-static int sdio_al_log(struct sdio_al_local_log *log, const char *fmt, ...)
-{
-	va_list args;
-	int r;
-	char *tp, *log_buf;
-	unsigned int *log_cur_pos;
-	struct timeval kt;
-	unsigned long flags;
-	static char sdio_al_log_tmp[SDIO_AL_DEBUG_TMP_LOG_SIZE];
-
-	spin_lock_irqsave(&log->log_lock, flags);
-
-	kt = ktime_to_timeval(ktime_get());
-	r = scnprintf(sdio_al_log_tmp, SDIO_AL_DEBUG_TMP_LOG_SIZE,
-			"[%8ld.%6ld] ", kt.tv_sec, kt.tv_usec);
-
-	va_start(args, fmt);
-	r += vscnprintf(&sdio_al_log_tmp[r], (SDIO_AL_DEBUG_TMP_LOG_SIZE - r),
-			fmt, args);
-	va_end(args);
-
-	log_buf = log->buffer;
-	log_cur_pos = &(log->buf_cur_pos);
-
-	for (tp = sdio_al_log_tmp; tp < (sdio_al_log_tmp + r); tp++) {
-		log_buf[(*log_cur_pos)++] = *tp;
-		if ((*log_cur_pos) == SDIO_AL_DEBUG_LOG_SIZE)
-			*log_cur_pos = 0;
-	}
-
-	spin_unlock_irqrestore(&log->log_lock, flags);
-
-	return r;
-}
-
-static int sdio_al_verify_func1(struct sdio_al_device *sdio_al_dev,
-				char const *func)
-{
-	if (sdio_al_dev == NULL) {
-		sdio_al_loge(&sdio_al->gen_log, MODULE_NAME ": %s: NULL "
-				"sdio_al_dev\n", func);
-		return -ENODEV;
-	}
-
-	if (sdio_al_dev->signature != SDIO_AL_SIGNATURE) {
-		sdio_al_loge(sdio_al_dev->dev_log, MODULE_NAME ": %s: Invalid "
-				"signature\n", func);
-		return -ENODEV;
-	}
-
-	if (!sdio_al_dev->card) {
-		sdio_al_loge(sdio_al_dev->dev_log, MODULE_NAME ": %s: NULL "
-				"card\n", func);
-		return -ENODEV;
-	}
-	if (!sdio_al_dev->card->sdio_func[0]) {
-		sdio_al_loge(sdio_al_dev->dev_log, MODULE_NAME ": %s: NULL "
-				"func1\n", func);
-		return -ENODEV;
-	}
-	return 0;
-}
-
-static int sdio_al_claim_mutex(struct sdio_al_device *sdio_al_dev,
-			       char const *func)
-{
-	if (!sdio_al_dev) {
-		sdio_al_loge(&sdio_al->gen_log, MODULE_NAME ": %s: NULL "
-					"device\n", func);
-		return -ENODEV;
-	}
-
-	if (sdio_al_dev->signature != SDIO_AL_SIGNATURE) {
-		sdio_al_loge(sdio_al_dev->dev_log, MODULE_NAME ": %s: Invalid "
-					"device signature\n", func);
-		return -ENODEV;
-	}
-
-	if (!sdio_al_dev->host) {
-		sdio_al_loge(sdio_al_dev->dev_log, MODULE_NAME ": %s: NULL "
-					"host\n", func);
-		return -ENODEV;
-	}
-
-	mmc_claim_host(sdio_al_dev->host);
-
-	return 0;
-}
-
-static int sdio_al_release_mutex(struct sdio_al_device *sdio_al_dev,
-			       char const *func)
-{
-	if (!sdio_al_dev) {
-		sdio_al_loge(&sdio_al->gen_log, MODULE_NAME ": %s: NULL "
-					"device\n", func);
-		return -ENODEV;
-	}
-
-	if (sdio_al_dev->signature != SDIO_AL_SIGNATURE) {
-		sdio_al_loge(sdio_al_dev->dev_log, MODULE_NAME ": %s: Invalid "
-					"device signature\n", func);
-		return -ENODEV;
-	}
-
-	if (!sdio_al_dev->host) {
-		sdio_al_loge(sdio_al_dev->dev_log, MODULE_NAME ": %s: NULL "
-					"host\n", func);
-		return -ENODEV;
-	}
-
-	mmc_release_host(sdio_al_dev->host);
-
-	return 0;
-}
-
-static int sdio_al_claim_mutex_and_verify_dev(
-	struct sdio_al_device *sdio_al_dev,
-	char const *func)
-{
-	if (sdio_al_claim_mutex(sdio_al_dev, __func__))
-		return -ENODEV;
-
-	if (sdio_al_dev->state != CARD_INSERTED) {
-		sdio_al_loge(sdio_al_dev->dev_log, MODULE_NAME ": %s: Invalid "
-				"device state %d\n", func, sdio_al_dev->state);
-		sdio_al_release_mutex(sdio_al_dev, __func__);
-		return -ENODEV;
-	}
-
-	return 0;
-}
-
-static void sdio_al_get_into_err_state(struct sdio_al_device *sdio_al_dev)
-{
-	if ((!sdio_al) || (!sdio_al_dev))
-		return;
-
-	sdio_al_dev->is_err = true;
-	sdio_al->debug.debug_data_on = 0;
-	sdio_al->debug.debug_lpm_on = 0;
-	sdio_al_print_info();
-}
-
-void sdio_al_register_lpm_cb(void *device_handle,
-				       int(*lpm_callback)(void *, int))
-{
-	struct sdio_al_device *sdio_al_dev =
-		(struct sdio_al_device *) device_handle;
-
-	if (!sdio_al_dev) {
-		sdio_al_loge(&sdio_al->gen_log, MODULE_NAME ": %s - "
-				"device_handle is NULL\n", __func__);
-		return;
-	}
-
-	if (lpm_callback) {
-		sdio_al_dev->lpm_callback = lpm_callback;
-		lpm_callback((void *)sdio_al_dev,
-					   sdio_al_dev->is_ok_to_sleep);
-	}
-
-	LPM_DEBUG(sdio_al_dev->dev_log, MODULE_NAME ": %s - device %d "
-			"registered for wakeup callback\n", __func__,
-			sdio_al_dev->host->index);
-}
-
-void sdio_al_unregister_lpm_cb(void *device_handle)
-{
-	struct sdio_al_device *sdio_al_dev =
-		(struct sdio_al_device *) device_handle;
-
-	if (!sdio_al_dev) {
-		sdio_al_loge(&sdio_al->gen_log, MODULE_NAME ": %s - "
-				"device_handle is NULL\n", __func__);
-		return;
-	}
-
-	sdio_al_dev->lpm_callback = NULL;
-	LPM_DEBUG(sdio_al_dev->dev_log, MODULE_NAME ": %s - device %d "
-		"unregister for wakeup callback\n", __func__,
-		sdio_al_dev->host->index);
-}
-
-static void sdio_al_vote_for_sleep(struct sdio_al_device *sdio_al_dev,
-				   int is_vote_for_sleep)
-{
-	pr_debug(MODULE_NAME ": %s()", __func__);
-
-	if (!sdio_al_dev) {
-		sdio_al_loge(&sdio_al->gen_log, MODULE_NAME ": %s - sdio_al_dev"
-				" is NULL\n", __func__);
-		return;
-	}
-
-	if (is_vote_for_sleep) {
-		pr_debug(MODULE_NAME ": %s - sdio vote for Sleep", __func__);
-		wake_unlock(&sdio_al_dev->wake_lock);
-	} else {
-		pr_debug(MODULE_NAME ": %s - sdio vote against sleep",
-			  __func__);
-		wake_lock(&sdio_al_dev->wake_lock);
-	}
-
-	if (sdio_al_dev->lpm_callback != NULL) {
-		LPM_DEBUG(sdio_al_dev->dev_log, MODULE_NAME ": %s - "
-				"is_vote_for_sleep=%d for card#%d, "
-				"calling callback...", __func__,
-				is_vote_for_sleep,
-				sdio_al_dev->host->index);
-		sdio_al_dev->lpm_callback((void *)sdio_al_dev,
-					   is_vote_for_sleep);
-	}
-}
-
-/**
- *  Write SDIO-Client lpm information
- *  Should only be called with host claimed.
- */
-static int write_lpm_info(struct sdio_al_device *sdio_al_dev)
-{
-	struct sdio_func *lpm_func = NULL;
-	int offset = offsetof(struct peer_sdioc_sw_mailbox, ch_config)+
-		sizeof(struct peer_sdioc_channel_config) *
-		sdio_al_dev->lpm_chan+
-		offsetof(struct peer_sdioc_channel_config, is_host_ok_to_sleep);
-	int ret;
-
-	if (sdio_al_dev->lpm_chan == INVALID_SDIO_CHAN) {
-		sdio_al_loge(sdio_al_dev->dev_log, MODULE_NAME ":Invalid "
-				"lpm_chan for card %d\n",
-				sdio_al_dev->host->index);
-		return -EINVAL;
-	}
-
-	if (!sdio_al_dev->card ||
-		!sdio_al_dev->card->sdio_func[sdio_al_dev->lpm_chan+1]) {
-		sdio_al_loge(sdio_al_dev->dev_log, MODULE_NAME
-				": NULL card or lpm_func\n");
-		return -ENODEV;
-	}
-	lpm_func = sdio_al_dev->card->sdio_func[sdio_al_dev->lpm_chan+1];
-
-	pr_debug(MODULE_NAME ":write_lpm_info is_ok_to_sleep=%d, device %d\n",
-		 sdio_al_dev->is_ok_to_sleep,
-		 sdio_al_dev->host->index);
-
-	ret = sdio_memcpy_toio(lpm_func, SDIOC_SW_MAILBOX_ADDR+offset,
-				&sdio_al_dev->is_ok_to_sleep, sizeof(u32));
-	if (ret) {
-		sdio_al_loge(sdio_al_dev->dev_log, MODULE_NAME ":failed to "
-				"write lpm info for card %d\n",
-				sdio_al_dev->host->index);
-		return ret;
-	}
-
-	return 0;
-}
-
-/* Set inactivity counter to intial value to allow clients come up */
-static inline void start_inactive_time(struct sdio_al_device *sdio_al_dev)
-{
-	sdio_al_dev->inactivity_time = jiffies +
-		msecs_to_jiffies(INITIAL_INACTIVITY_TIME_MSEC);
-}
-
-static inline void restart_inactive_time(struct sdio_al_device *sdio_al_dev)
-{
-	sdio_al_dev->inactivity_time = jiffies +
-		msecs_to_jiffies(INACTIVITY_TIME_MSEC);
-}
-
-static inline int is_inactive_time_expired(struct sdio_al_device *sdio_al_dev)
-{
-	return time_after(jiffies, sdio_al_dev->inactivity_time);
-}
-
-
-static int is_user_irq_enabled(struct sdio_al_device *sdio_al_dev,
-			       int func_num)
-{
-	int ret = 0;
-	struct sdio_func *func1;
-	u32 user_irq = 0;
-	u32 addr = 0;
-	u32 offset = 0;
-	u32 masked_user_irq = 0;
-
-	if (sdio_al_verify_func1(sdio_al_dev, __func__))
-		return 0;
-	func1 = sdio_al_dev->card->sdio_func[0];
-
-	if (func_num < 4) {
-		addr = FUNC_1_4_USER_IRQ_ADDR;
-		offset = func_num * 8;
-	} else {
-		addr = FUNC_5_7_USER_IRQ_ADDR;
-		offset = (func_num - 4) * 8;
-	}
-
-	user_irq = sdio_readl(func1, addr, &ret);
-	if (ret) {
-		pr_debug(MODULE_NAME ":read_user_irq fail\n");
-		return 0;
-	}
-
-	masked_user_irq = (user_irq >> offset) && 0xFF;
-	if (masked_user_irq == 0x1) {
-		sdio_al_logi(sdio_al_dev->dev_log, MODULE_NAME ":user_irq "
-				"enabled\n");
-		return 1;
-	}
-
-	return 0;
-}
-
-static void sdio_al_sleep(struct sdio_al_device *sdio_al_dev,
-			  struct mmc_host *host)
-{
-	int i;
-
-	/* Go to sleep */
-	pr_debug(MODULE_NAME  ":Inactivity timer expired."
-		" Going to sleep\n");
-	/* Stop mailbox timer */
-	stop_and_del_timer(sdio_al_dev);
-	/* Make sure we get interrupt for non-packet-mode right away */
-	for (i = 0; i < SDIO_AL_MAX_CHANNELS; i++) {
-		struct sdio_channel *ch = &sdio_al_dev->channel[i];
-		if ((ch->state != SDIO_CHANNEL_STATE_OPEN) &&
-		    (ch->state != SDIO_CHANNEL_STATE_CLOSED)) {
-			pr_debug(MODULE_NAME  ":continue for channel %s in"
-					" state %d\n", ch->name, ch->state);
-			continue;
-		}
-		if (ch->is_packet_mode == false) {
-			ch->read_threshold = LOW_LATENCY_THRESHOLD;
-			set_pipe_threshold(sdio_al_dev,
-					   ch->rx_pipe_index,
-					   ch->read_threshold);
-		}
-	}
-	/* Prevent modem to go to sleep until we get the PROG_DONE on
-	   the dummy CMD52 */
-	msmsdcc_set_pwrsave(sdio_al_dev->host, 0);
-	/* Mark HOST_OK_TOSLEEP */
-	sdio_al_dev->is_ok_to_sleep = 1;
-	write_lpm_info(sdio_al_dev);
-
-	msmsdcc_lpm_enable(host);
-	LPM_DEBUG(sdio_al_dev->dev_log, MODULE_NAME ":Finished sleep sequence"
-			" for card %d. Sleep now.\n",
-		sdio_al_dev->host->index);
-	/* Release wakelock */
-	sdio_al_vote_for_sleep(sdio_al_dev, 1);
-}
-
-
-/**
- *  Read SDIO-Client Mailbox from Function#1.thresh_pipe
- *
- *  The mailbox contain the bytes available per pipe,
- *  and the End-Of-Transfer indication per pipe (if available).
- *
- * WARNING: Each time the Mailbox is read from the client, the
- * read_bytes_avail is incremented with another pending
- * transfer. Therefore, a pending rx-packet should be added to a
- * list before the next read of the mailbox.
- *
- * This function should run from a workqueue context since it
- * notifies the clients.
- *
- * This function assumes that sdio_al_claim_mutex was called before
- * calling it.
- *
- */
-static int read_mailbox(struct sdio_al_device *sdio_al_dev, int from_isr)
-{
-	int ret;
-	struct sdio_func *func1 = NULL;
-	struct sdio_mailbox *mailbox = sdio_al_dev->mailbox;
-	struct mmc_host *host = sdio_al_dev->host;
-	u32 new_write_avail = 0;
-	u32 old_write_avail = 0;
-	u32 any_read_avail = 0;
-	u32 any_write_pending = 0;
-	int i;
-	u32 rx_notify_bitmask = 0;
-	u32 tx_notify_bitmask = 0;
-	u32 eot_pipe = 0;
-	u32 thresh_pipe = 0;
-	u32 overflow_pipe = 0;
-	u32 underflow_pipe = 0;
-	u32 thresh_intr_mask = 0;
-	int is_closing = 0;
-
-	if (sdio_al_dev->is_err) {
-		SDIO_AL_ERR(__func__);
-		return 0;
-	}
-
-	if (sdio_al_verify_func1(sdio_al_dev, __func__))
-		return -ENODEV;
-	func1 = sdio_al_dev->card->sdio_func[0];
-
-	pr_debug(MODULE_NAME ":start %s from_isr = %d for card %d.\n"
-		 , __func__, from_isr, sdio_al_dev->host->index);
-
-	pr_debug(MODULE_NAME ":before sdio_memcpy_fromio.\n");
-	memset(mailbox, 0, sizeof(struct sdio_mailbox));
-	ret = sdio_memcpy_fromio(func1, mailbox,
-			HW_MAILBOX_ADDR, sizeof(*mailbox));
-	pr_debug(MODULE_NAME ":after sdio_memcpy_fromio.\n");
-	if (ret) {
-		sdio_al_loge(sdio_al_dev->dev_log, MODULE_NAME ":Fail to read "
-				"Mailbox for card %d, goto error state\n",
-				sdio_al_dev->host->index);
-		sdio_al_get_into_err_state(sdio_al_dev);
-		goto exit_err;
-	}
-
-	eot_pipe =	(mailbox->eot_pipe_0_7) |
-			(mailbox->eot_pipe_8_15<<8);
-	thresh_pipe = 	(mailbox->thresh_above_limit_pipe_0_7) |
-			(mailbox->thresh_above_limit_pipe_8_15<<8);
-
-	overflow_pipe = (mailbox->overflow_pipe_0_7) |
-			(mailbox->overflow_pipe_8_15<<8);
-	underflow_pipe = mailbox->underflow_pipe_0_7 |
-			(mailbox->underflow_pipe_8_15<<8);
-	thresh_intr_mask =
-		(mailbox->mask_thresh_above_limit_pipe_0_7) |
-		(mailbox->mask_thresh_above_limit_pipe_8_15<<8);
-
-	if (overflow_pipe || underflow_pipe)
-		sdio_al_loge(sdio_al_dev->dev_log, MODULE_NAME ":Mailbox ERROR "
-				"overflow=0x%x, underflow=0x%x\n",
-				overflow_pipe, underflow_pipe);
-
-	/* In case of modem reset we would like to read the daya from the modem
-	   to clear the interrupts but do not process it */
-	if (sdio_al_dev->state != CARD_INSERTED) {
-		sdio_al_loge(sdio_al_dev->dev_log, MODULE_NAME ":sdio_al_device"
-				" (card %d) is in invalid state %d\n",
-				sdio_al_dev->host->index,
-				sdio_al_dev->state);
-		return -ENODEV;
-	}
-
-	pr_debug(MODULE_NAME ":card %d: eot=0x%x, thresh=0x%x\n",
-			sdio_al_dev->host->index,
-			eot_pipe, thresh_pipe);
-
-	/* Scan for Rx Packets available and update read available bytes */
-	for (i = 0; i < SDIO_AL_MAX_CHANNELS; i++) {
-		struct sdio_channel *ch = &sdio_al_dev->channel[i];
-		u32 old_read_avail;
-		u32 read_avail;
-		u32 new_packet_size = 0;
-
-		if (ch->state == SDIO_CHANNEL_STATE_CLOSING)
-			is_closing = true; /* used to prevent sleep */
-
-		old_read_avail = ch->read_avail;
-		read_avail = mailbox->pipe_bytes_avail[ch->rx_pipe_index];
-
-		if ((ch->state == SDIO_CHANNEL_STATE_CLOSED) &&
-			(read_avail > 0)) {
-			sdio_al_loge(sdio_al_dev->dev_log, MODULE_NAME
-				 ":%s: Invalid read_avail 0x%x, for CLOSED ch %s\n",
-				 __func__, read_avail, ch->name);
-			sdio_read_from_closed_ch(ch, read_avail);
-		}
-		if ((ch->state != SDIO_CHANNEL_STATE_OPEN) &&
-		    (ch->state != SDIO_CHANNEL_STATE_CLOSING))
-			continue;
-
-		if (read_avail > INVALID_DATA_AVAILABLE) {
-			sdio_al_loge(sdio_al_dev->dev_log, MODULE_NAME
-				 ":Invalid read_avail 0x%x for pipe %d\n",
-				 read_avail, ch->rx_pipe_index);
-			continue;
-		}
-		any_read_avail |= read_avail | old_read_avail;
-		ch->statistics.last_any_read_avail = any_read_avail;
-		ch->statistics.last_read_avail = read_avail;
-		ch->statistics.last_old_read_avail = old_read_avail;
-
-		if (ch->is_packet_mode) {
-			if ((eot_pipe & (1<<ch->rx_pipe_index)) &&
-			    sdio_al_dev->print_after_interrupt) {
-				LPM_DEBUG(sdio_al_dev->dev_log, MODULE_NAME
-					":Interrupt on ch %s, "
-					"card %d", ch->name,
-					sdio_al_dev->host->index);
-			}
-			new_packet_size = check_pending_rx_packet(ch, eot_pipe);
-		} else {
-			if ((thresh_pipe & (1<<ch->rx_pipe_index)) &&
-			    sdio_al_dev->print_after_interrupt) {
-				LPM_DEBUG(sdio_al_dev->dev_log, MODULE_NAME
-					":Interrupt on ch %s, "
-					"card %d", ch->name,
-					sdio_al_dev->host->index);
-			}
-			ch->read_avail = read_avail;
-
-			/*
-			 * Restore default thresh for non packet channels.
-			 * in case it IS low latency channel then read_threshold
-			 * and def_read_threshold are both
-			 * LOW_LATENCY_THRESHOLD
-			 */
-			if ((ch->read_threshold != ch->def_read_threshold) &&
-			    (read_avail >= ch->threshold_change_cnt)) {
-				if (!ch->is_low_latency_ch) {
-					ch->read_threshold =
-						ch->def_read_threshold;
-					set_pipe_threshold(sdio_al_dev,
-							   ch->rx_pipe_index,
-							   ch->read_threshold);
-				}
-			}
-		}
-
-		if ((ch->is_packet_mode) && (new_packet_size > 0)) {
-			rx_notify_bitmask |= (1<<ch->num);
-			ch->statistics.total_notifs++;
-		}
-
-		if ((!ch->is_packet_mode) && (ch->read_avail > 0) &&
-		    (old_read_avail == 0)) {
-			rx_notify_bitmask |= (1<<ch->num);
-			ch->statistics.total_notifs++;
-		}
-	}
-	sdio_al_dev->print_after_interrupt = 0;
-
-	/* Update Write available */
-	for (i = 0; i < SDIO_AL_MAX_CHANNELS; i++) {
-		struct sdio_channel *ch = &sdio_al_dev->channel[i];
-
-		if ((ch->state != SDIO_CHANNEL_STATE_OPEN) &&
-		    (ch->state != SDIO_CHANNEL_STATE_CLOSING))
-			continue;
-
-		new_write_avail = mailbox->pipe_bytes_avail[ch->tx_pipe_index];
-
-		if (new_write_avail > INVALID_DATA_AVAILABLE) {
-			sdio_al_loge(sdio_al_dev->dev_log, MODULE_NAME
-				 ":Invalid write_avail 0x%x for pipe %d\n",
-				 new_write_avail, ch->tx_pipe_index);
-			continue;
-		}
-
-		old_write_avail = ch->write_avail;
-		ch->write_avail = new_write_avail;
-
-		if ((old_write_avail <= ch->min_write_avail) &&
-			(new_write_avail >= ch->min_write_avail))
-			tx_notify_bitmask |= (1<<ch->num);
-
-		/* There is not enough write avail for this channel.
-		   We need to keep reading mailbox to wait for the appropriate
-		   write avail and cannot sleep. Ignore SMEM channel that has
-		   only one direction. */
-		if (strncmp(ch->name, "SDIO_SMEM", CHANNEL_NAME_SIZE))
-			any_write_pending |=
-			(new_write_avail < ch->ch_config.max_tx_threshold);
-	}
-	/* notify clients */
-	for (i = 0; i < SDIO_AL_MAX_CHANNELS; i++) {
-		struct sdio_channel *ch = &sdio_al_dev->channel[i];
-
-		if ((ch->state != SDIO_CHANNEL_STATE_OPEN) ||
-				(ch->notify == NULL))
-			continue;
-
-		if (rx_notify_bitmask & (1<<ch->num))
-			ch->notify(ch->priv,
-					   SDIO_EVENT_DATA_READ_AVAIL);
-
-		if (tx_notify_bitmask & (1<<ch->num))
-			ch->notify(ch->priv,
-					   SDIO_EVENT_DATA_WRITE_AVAIL);
-	}
-
-
-	if ((rx_notify_bitmask == 0) && (tx_notify_bitmask == 0) &&
-	    !any_read_avail && !any_write_pending) {
-		DATA_DEBUG(sdio_al_dev->dev_log, MODULE_NAME ":Nothing to "
-				"Notify for card %d, is_closing=%d\n",
-				sdio_al_dev->host->index, is_closing);
-		if (is_closing)
-			restart_inactive_time(sdio_al_dev);
-		else if (is_inactive_time_expired(sdio_al_dev))
-			sdio_al_sleep(sdio_al_dev, host);
-	} else {
-		DATA_DEBUG(sdio_al_dev->dev_log, MODULE_NAME ":Notify bitmask"
-				" for card %d rx=0x%x, tx=0x%x.\n",
-				sdio_al_dev->host->index,
-				rx_notify_bitmask, tx_notify_bitmask);
-		/* Restart inactivity timer if any activity on the channel */
-		restart_inactive_time(sdio_al_dev);
-	}
-
-	pr_debug(MODULE_NAME ":end %s.\n", __func__);
-
-exit_err:
-	return ret;
-}
-
-/**
- *  Check pending rx packet when reading the mailbox.
- */
-static u32 check_pending_rx_packet(struct sdio_channel *ch, u32 eot)
-{
-	u32 rx_pending;
-	u32 rx_avail;
-	u32 new_packet_size = 0;
-	struct sdio_al_device *sdio_al_dev = ch->sdio_al_dev;
-
-
-	if (sdio_al_dev == NULL) {
-		sdio_al_loge(&sdio_al->gen_log, MODULE_NAME ": NULL sdio_al_dev"
-				" for channel %s\n", ch->name);
-		return -EINVAL;
-	}
-
-	mutex_lock(&ch->ch_lock);
-
-	rx_pending = ch->rx_pending_bytes;
-	rx_avail = sdio_al_dev->mailbox->pipe_bytes_avail[ch->rx_pipe_index];
-
-	pr_debug(MODULE_NAME ":pipe %d of card %d rx_avail=0x%x, "
-			     "rx_pending=0x%x\n",
-	   ch->rx_pipe_index, sdio_al_dev->host->index, rx_avail,
-		 rx_pending);
-
-
-	/* new packet detected */
-	if (eot & (1<<ch->rx_pipe_index)) {
-		struct rx_packet_size *p = NULL;
-		new_packet_size = rx_avail - rx_pending;
-
-		if ((rx_avail <= rx_pending)) {
-			sdio_al_loge(sdio_al_dev->dev_log, MODULE_NAME
-					": Invalid new packet size."
-					" rx_avail=%d.\n", rx_avail);
-			new_packet_size = 0;
-			goto exit_err;
-		}
-
-		p = kzalloc(sizeof(*p), GFP_KERNEL);
-		if (p == NULL) {
-			sdio_al_loge(sdio_al_dev->dev_log, MODULE_NAME
-					": failed to allocate item for "
-					"rx_pending list. rx_avail=%d, "
-					"rx_pending=%d.\n",
-					rx_avail, rx_pending);
-			new_packet_size = 0;
-			goto exit_err;
-		}
-		p->size = new_packet_size;
-		/* Add new packet as last */
-		list_add_tail(&p->list, &ch->rx_size_list_head);
-		ch->rx_pending_bytes += new_packet_size;
-
-		if (ch->read_avail == 0)
-			ch->read_avail = new_packet_size;
-	}
-
-exit_err:
-	mutex_unlock(&ch->ch_lock);
-
-	return new_packet_size;
-}
-
-
-
-/**
- *  Remove first pending packet from the list.
- */
-static u32 remove_handled_rx_packet(struct sdio_channel *ch)
-{
-	struct rx_packet_size *p = NULL;
-
-	mutex_lock(&ch->ch_lock);
-
-	ch->rx_pending_bytes -= ch->read_avail;
-
-	if (!list_empty(&ch->rx_size_list_head)) {
-		p = list_first_entry(&ch->rx_size_list_head,
-			struct rx_packet_size, list);
-		list_del(&p->list);
-		kfree(p);
-	} else {
-		sdio_al_loge(ch->sdio_al_dev->dev_log, MODULE_NAME ":%s: ch "
-				"%s: unexpected empty list!!\n",
-				__func__, ch->name);
-	}
-
-	if (list_empty(&ch->rx_size_list_head))	{
-		ch->read_avail = 0;
-	} else {
-		p = list_first_entry(&ch->rx_size_list_head,
-			struct rx_packet_size, list);
-		ch->read_avail = p->size;
-	}
-
-	mutex_unlock(&ch->ch_lock);
-
-	return ch->read_avail;
-}
-
-
-/**
- *  Bootloader worker function.
- *
- *  @note: clear the bootloader_done flag only after reading the
- *  mailbox, to ignore more requests while reading the mailbox.
- */
-static void boot_worker(struct work_struct *work)
-{
-	int ret = 0;
-	int func_num = 0;
-	int i;
-	struct sdio_al_device *sdio_al_dev = NULL;
-	struct sdio_al_work *sdio_al_work = container_of(work,
-							 struct sdio_al_work,
-							 work);
-
-	if (sdio_al_work == NULL) {
-		sdio_al_loge(&sdio_al->gen_log, MODULE_NAME ": %s: NULL "
-				"sdio_al_work\n", __func__);
-		return;
-	}
-
-	sdio_al_dev = sdio_al_work->sdio_al_dev;
-	if (sdio_al_dev == NULL) {
-		sdio_al_loge(&sdio_al->gen_log, MODULE_NAME ": %s: NULL "
-				"sdio_al_dev\n", __func__);
-		return;
-	}
-	sdio_al_logi(&sdio_al->gen_log, MODULE_NAME ":Bootloader Worker Started"
-			", wait for bootloader_done event..\n");
-	wait_event(sdio_al_dev->wait_mbox,
-		   sdio_al_dev->bootloader_done);
-	sdio_al_logi(&sdio_al->gen_log, MODULE_NAME ":Got bootloader_done "
-			"event..\n");
-	/* Do polling until MDM is up */
-	for (i = 0; i < 5000; ++i) {
-		if (sdio_al_claim_mutex_and_verify_dev(sdio_al_dev, __func__))
-			return;
-		if (is_user_irq_enabled(sdio_al_dev, func_num)) {
-			sdio_al_release_mutex(sdio_al_dev, __func__);
-			sdio_al_dev->bootloader_done = 0;
-			ret = sdio_al_client_setup(sdio_al_dev);
-			if (ret) {
-				sdio_al_loge(sdio_al_dev->dev_log, MODULE_NAME
-					": sdio_al_client_setup failed, "
-					"for card %d ret=%d\n",
-					sdio_al_dev->host->index, ret);
-				sdio_al_get_into_err_state(sdio_al_dev);
-			}
-			goto done;
-		}
-		sdio_al_release_mutex(sdio_al_dev, __func__);
-		msleep(100);
-	}
-	sdio_al_loge(sdio_al_dev->dev_log, MODULE_NAME ":Timeout waiting for "
-			"user_irq for card %d\n",
-			sdio_al_dev->host->index);
-	sdio_al_get_into_err_state(sdio_al_dev);
-
-done:
-	pr_debug(MODULE_NAME ":Boot Worker for card %d Exit!\n",
-		sdio_al_dev->host->index);
-}
-
-/**
- *  Worker function.
- *
- *  @note: clear the ask_mbox flag only after
- *  	 reading the mailbox, to ignore more requests while
- *  	 reading the mailbox.
- */
-static void worker(struct work_struct *work)
-{
-	int ret = 0;
-	struct sdio_al_device *sdio_al_dev = NULL;
-	struct sdio_al_work *sdio_al_work = container_of(work,
-							 struct sdio_al_work,
-							 work);
-	if (sdio_al_work == NULL) {
-		sdio_al_loge(&sdio_al->gen_log, MODULE_NAME ": worker: NULL "
-				"sdio_al_work\n");
-		return;
-	}
-
-	sdio_al_dev = sdio_al_work->sdio_al_dev;
-	if (sdio_al_dev == NULL) {
-		sdio_al_loge(&sdio_al->gen_log, MODULE_NAME ": worker: NULL "
-				"sdio_al_dev\n");
-		return;
-	}
-	pr_debug(MODULE_NAME ":Worker Started..\n");
-	while ((sdio_al_dev->is_ready) && (ret == 0)) {
-		pr_debug(MODULE_NAME ":Wait for read mailbox request..\n");
-		wait_event(sdio_al_dev->wait_mbox, sdio_al_dev->ask_mbox);
-		if (!sdio_al_dev->is_ready)
-			break;
-		if (sdio_al_claim_mutex_and_verify_dev(sdio_al_dev, __func__))
-			break;
-		if (sdio_al_dev->is_ok_to_sleep) {
-			ret = sdio_al_wake_up(sdio_al_dev, 1, NULL);
-			if (ret) {
-				sdio_al_release_mutex(sdio_al_dev, __func__);
-				return;
-			}
-		}
-		ret = read_mailbox(sdio_al_dev, false);
-		sdio_al_release_mutex(sdio_al_dev, __func__);
-		sdio_al_dev->ask_mbox = false;
-	}
-
-	pr_debug(MODULE_NAME ":Worker Exit!\n");
-}
-
-/**
- *  Write command using CMD54 rather than CMD53.
- *  Writing with CMD54 generate EOT interrupt at the
- *  SDIO-Client.
- *  Based on mmc_io_rw_extended()
- */
-static int sdio_write_cmd54(struct mmc_card *card, unsigned fn,
-	unsigned addr, const u8 *buf,
-	unsigned blocks, unsigned blksz)
-{
-	struct mmc_request mrq;
-	struct mmc_command cmd;
-	struct mmc_data data;
-	struct scatterlist sg;
-	int incr_addr = 1; /* MUST */
-	int write = 1;
-
-	BUG_ON(!card);
-	BUG_ON(fn > 7);
-	BUG_ON(blocks == 1 && blksz > 512);
-	WARN_ON(blocks == 0);
-	WARN_ON(blksz == 0);
-
-	write = true;
-	pr_debug(MODULE_NAME ":sdio_write_cmd54()"
-		"fn=%d,buf=0x%x,blocks=%d,blksz=%d\n",
-		fn, (u32) buf, blocks, blksz);
-
-	memset(&mrq, 0, sizeof(struct mmc_request));
-	memset(&cmd, 0, sizeof(struct mmc_command));
-	memset(&data, 0, sizeof(struct mmc_data));
-
-	mrq.cmd = &cmd;
-	mrq.data = &data;
-
-	cmd.opcode = SD_IO_RW_EXTENDED_QCOM;
-
-	cmd.arg = write ? 0x80000000 : 0x00000000;
-	cmd.arg |= fn << 28;
-	cmd.arg |= incr_addr ? 0x04000000 : 0x00000000;
-	cmd.arg |= addr << 9;
-	if (blocks == 1 && blksz <= 512)
-		cmd.arg |= (blksz == 512) ? 0 : blksz;  /* byte mode */
-	else
-		cmd.arg |= 0x08000000 | blocks; 	/* block mode */
-	cmd.flags = MMC_RSP_SPI_R5 | MMC_RSP_R5 | MMC_CMD_ADTC;
-
-	data.blksz = blksz;
-	data.blocks = blocks;
-	data.flags = write ? MMC_DATA_WRITE : MMC_DATA_READ;
-	data.sg = &sg;
-	data.sg_len = 1;
-
-	sg_init_one(&sg, buf, blksz * blocks);
-
-	mmc_set_data_timeout(&data, card);
-
-	mmc_wait_for_req(card->host, &mrq);
-
-	if (cmd.error)
-		return cmd.error;
-	if (data.error)
-		return data.error;
-
-	if (mmc_host_is_spi(card->host)) {
-		/* host driver already reported errors */
-	} else {
-		if (cmd.resp[0] & R5_ERROR) {
-			sdio_al_loge(&sdio_al->gen_log, MODULE_NAME
-						":%s: R5_ERROR for card %d",
-						__func__, card->host->index);
-			return -EIO;
-		}
-		if (cmd.resp[0] & R5_FUNCTION_NUMBER) {
-			sdio_al_loge(&sdio_al->gen_log, MODULE_NAME
-						":%s: R5_FUNCTION_NUMBER for card %d",
-						__func__, card->host->index);
-			return -EINVAL;
-		}
-		if (cmd.resp[0] & R5_OUT_OF_RANGE) {
-			sdio_al_loge(&sdio_al->gen_log, MODULE_NAME
-						":%s: R5_OUT_OF_RANGE for card %d",
-						__func__, card->host->index);
-			return -ERANGE;
-		}
-	}
-
-	return 0;
-}
-
-
-/**
- *  Write data to channel.
- *  Handle different data size types.
- *
- */
-static int sdio_ch_write(struct sdio_channel *ch, const u8 *buf, u32 len)
-{
-	int ret = 0;
-	unsigned blksz = ch->func->cur_blksize;
-	int blocks = len / blksz;
-	int remain_bytes = len % blksz;
-	struct mmc_card *card = NULL;
-	u32 fn = ch->func->num;
-
-	if (!ch) {
-		sdio_al_loge(&sdio_al->gen_log, MODULE_NAME ": %s: NULL "
-				"channel\n", __func__);
-		return -ENODEV;
-	}
-
-	if (!ch->sdio_al_dev) {
-		sdio_al_loge(&sdio_al->gen_log, MODULE_NAME ": %s: NULL "
-				"sdio_al_dev\n", __func__);
-		return -ENODEV;
-	}
-
-	if (len == 0) {
-		sdio_al_loge(ch->sdio_al_dev->dev_log, MODULE_NAME ":channel "
-				"%s trying to write 0 bytes\n", ch->name);
-		return -EINVAL;
-	}
-
-	card = ch->func->card;
-
-	if (remain_bytes) {
-		/* CMD53 */
-		if (blocks) {
-			ret = sdio_memcpy_toio(ch->func, PIPE_TX_FIFO_ADDR,
-					       (void *) buf, blocks*blksz);
-			if (ret != 0) {
-				sdio_al_loge(ch->sdio_al_dev->dev_log,
-					MODULE_NAME ":%s: sdio_memcpy_toio "
-					"failed for channel %s\n",
-					__func__, ch->name);
-				sdio_al_get_into_err_state(ch->sdio_al_dev);
-				return ret;
-			}
-		}
-
-		buf += (blocks*blksz);
-
-		ret = sdio_write_cmd54(card, fn, PIPE_TX_FIFO_ADDR,
-				buf, 1, remain_bytes);
-	} else {
-		ret = sdio_write_cmd54(card, fn, PIPE_TX_FIFO_ADDR,
-				buf, blocks, blksz);
-	}
-
-	if (ret != 0) {
-		sdio_al_loge(ch->sdio_al_dev->dev_log, MODULE_NAME ":%s: "
-				"sdio_write_cmd54 failed for channel %s\n",
-				__func__, ch->name);
-		ch->sdio_al_dev->is_err = true;
-		return ret;
-	}
-
-	return ret;
-}
-
-static int sdio_al_bootloader_completed(void)
-{
-	int i;
-
-	pr_debug(MODULE_NAME ":sdio_al_bootloader_completed was called\n");
-
-	for (i = 0; i < MAX_NUM_OF_SDIO_DEVICES; ++i) {
-		struct sdio_al_device *dev = NULL;
-		if (sdio_al->devices[i] == NULL)
-			continue;
-		dev = sdio_al->devices[i];
-		dev->bootloader_done = 1;
-		wake_up(&dev->wait_mbox);
-	}
-
-	return 0;
-}
-
-static int sdio_al_wait_for_bootloader_comp(struct sdio_al_device *sdio_al_dev)
-{
-	int ret = 0;
-
-	if (sdio_al_claim_mutex_and_verify_dev(sdio_al_dev, __func__))
-		return -ENODEV;
-
-	/*
-	 * Enable function 0 interrupt mask to allow 9k to raise this interrupt
-	 * in power-up. When sdio_downloader will notify its completion
-	 * we will poll on this interrupt to wait for 9k power-up
-	 */
-	ret = enable_mask_irq(sdio_al_dev, 0, 1, 0);
-	if (ret) {
-		sdio_al_loge(sdio_al_dev->dev_log, MODULE_NAME
-				": Enable_mask_irq for card %d failed, "
-				"ret=%d\n",
-				sdio_al_dev->host->index, ret);
-		sdio_al_release_mutex(sdio_al_dev, __func__);
-		return ret;
-	}
-
-	sdio_al_release_mutex(sdio_al_dev, __func__);
-
-	/*
-	 * Start bootloader worker that will wait for the bootloader
-	 * completion
-	 */
-	sdio_al_dev->boot_work.sdio_al_dev = sdio_al_dev;
-	INIT_WORK(&sdio_al_dev->boot_work.work, boot_worker);
-	sdio_al_dev->bootloader_done = 0;
-	queue_work(sdio_al_dev->workqueue, &sdio_al_dev->boot_work.work);
-
-	return 0;
-}
-
-static int sdio_al_bootloader_setup(void)
-{
-	int ret = 0;
-	struct sdio_al_device *bootloader_dev = sdio_al->bootloader_dev;
-	struct sdio_func *func1 = NULL;
-
-	if (sdio_al_claim_mutex_and_verify_dev(bootloader_dev, __func__))
-		return -ENODEV;
-
-	if (bootloader_dev->flashless_boot_on) {
-		sdio_al_loge(bootloader_dev->dev_log, MODULE_NAME ":Already "
-			"in boot process.\n");
-		sdio_al_release_mutex(bootloader_dev, __func__);
-		return 0;
-	}
-
-	bootloader_dev->sdioc_boot_sw_header
-		= kzalloc(sizeof(*bootloader_dev->sdioc_boot_sw_header),
-			  GFP_KERNEL);
-	if (bootloader_dev->sdioc_boot_sw_header == NULL) {
-		sdio_al_loge(bootloader_dev->dev_log, MODULE_NAME ":fail to "
-			"allocate sdioc boot sw header.\n");
-		sdio_al_release_mutex(bootloader_dev, __func__);
-		return -ENOMEM;
-	}
-
-	if (sdio_al_verify_func1(bootloader_dev, __func__)) {
-		sdio_al_release_mutex(bootloader_dev, __func__);
-		goto exit_err;
-	}
-	func1 = bootloader_dev->card->sdio_func[0];
-
-	ret = sdio_memcpy_fromio(func1,
-				 bootloader_dev->sdioc_boot_sw_header,
-				 SDIOC_SW_HEADER_ADDR,
-				 sizeof(struct peer_sdioc_boot_sw_header));
-	if (ret) {
-		sdio_al_loge(bootloader_dev->dev_log, MODULE_NAME ":fail to "
-			"read sdioc boot sw header.\n");
-		sdio_al_release_mutex(bootloader_dev, __func__);
-		goto exit_err;
-	}
-
-	if (bootloader_dev->sdioc_boot_sw_header->signature !=
-	    (u32) PEER_SDIOC_SW_MAILBOX_BOOT_SIGNATURE) {
-		sdio_al_loge(bootloader_dev->dev_log, MODULE_NAME ":invalid "
-			"mailbox signature 0x%x.\n",
-			bootloader_dev->sdioc_boot_sw_header->signature);
-		sdio_al_release_mutex(bootloader_dev, __func__);
-		ret = -EINVAL;
-		goto exit_err;
-	}
-
-	/* Upper byte has to be equal - no backward compatibility for unequal */
-	if ((bootloader_dev->sdioc_boot_sw_header->version >> 16) !=
-	    (sdio_al->pdata->peer_sdioc_boot_version_major)) {
-		sdio_al_loge(bootloader_dev->dev_log, MODULE_NAME ": HOST(0x%x)"
-			" and CLIENT(0x%x) SDIO_AL BOOT VERSION don't match\n",
-			((sdio_al->pdata->peer_sdioc_boot_version_major<<16)+
-			sdio_al->pdata->peer_sdioc_boot_version_minor),
-			bootloader_dev->sdioc_boot_sw_header->version);
-		sdio_al_release_mutex(bootloader_dev, __func__);
-		ret = -EIO;
-		goto exit_err;
-	}
-
-	sdio_al_logi(bootloader_dev->dev_log, MODULE_NAME ": SDIOC BOOT SW "
-			"version 0x%x\n",
-			bootloader_dev->sdioc_boot_sw_header->version);
-
-	bootloader_dev->flashless_boot_on = true;
-
-	sdio_al_release_mutex(bootloader_dev, __func__);
-
-	ret = sdio_al_wait_for_bootloader_comp(bootloader_dev);
-	if (ret) {
-		sdio_al_loge(bootloader_dev->dev_log, MODULE_NAME
-				": sdio_al_wait_for_bootloader_comp failed, "
-				"err=%d\n", ret);
-		goto exit_err;
-	}
-
-	ret = sdio_downloader_setup(bootloader_dev->card, 1,
-			bootloader_dev->sdioc_boot_sw_header->boot_ch_num,
-			sdio_al_bootloader_completed);
-
-	if (ret) {
-		sdio_al_loge(bootloader_dev->dev_log, MODULE_NAME
-			": sdio_downloader_setup failed, err=%d\n", ret);
-		goto exit_err;
-	}
-
-	sdio_al_logi(bootloader_dev->dev_log, MODULE_NAME ":In Flashless boot,"
-		" waiting for its completion\n");
-
-
-exit_err:
-	sdio_al_logi(&sdio_al->gen_log, MODULE_NAME ":free "
-			"sdioc_boot_sw_header.\n");
-	kfree(bootloader_dev->sdioc_boot_sw_header);
-	bootloader_dev->sdioc_boot_sw_header = NULL;
-	bootloader_dev = NULL;
-
-	return ret;
-}
-
-
-/**
- *  Read SDIO-Client software header
- *
- */
-static int read_sdioc_software_header(struct sdio_al_device *sdio_al_dev,
-				      struct peer_sdioc_sw_header *header)
-{
-	int ret;
-	int i;
-	int test_version = 0;
-	int sdioc_test_version = 0;
-	struct sdio_func *func1 = NULL;
-
-	pr_debug(MODULE_NAME ":reading sdioc sw header.\n");
-
-	if (sdio_al_verify_func1(sdio_al_dev, __func__))
-		return -ENODEV;
-
-	func1 = sdio_al_dev->card->sdio_func[0];
-
-	ret = sdio_memcpy_fromio(func1, header,
-			SDIOC_SW_HEADER_ADDR, sizeof(*header));
-	if (ret) {
-		sdio_al_loge(sdio_al_dev->dev_log, MODULE_NAME ":fail to read "
-				"sdioc sw header.\n");
-		goto exit_err;
-	}
-
-	if (header->signature == (u32)PEER_SDIOC_SW_MAILBOX_UT_SIGNATURE) {
-		sdio_al_logi(sdio_al_dev->dev_log, MODULE_NAME ":SDIOC SW "
-				"unittest signature. 0x%x\n",
-				header->signature);
-		sdio_al->unittest_mode = true;
-		/* Verify test code compatibility with the modem */
-		sdioc_test_version = (header->version & 0xFF00) >> 8;
-		test_version = sdio_al->pdata->peer_sdioc_version_minor >> 8;
-		if (test_version != sdioc_test_version) {
-			sdio_al_loge(sdio_al_dev->dev_log, MODULE_NAME
-				": HOST(0x%x) and CLIENT(0x%x) "
-				"testing VERSION don't match\n",
-				test_version,
-				sdioc_test_version);
-			msleep(500);
-			BUG();
-		}
-	}
-
-	if ((header->signature != (u32) PEER_SDIOC_SW_MAILBOX_SIGNATURE) &&
-	    (header->signature != (u32) PEER_SDIOC_SW_MAILBOX_UT_SIGNATURE)) {
-		sdio_al_loge(sdio_al_dev->dev_log, MODULE_NAME ":SDIOC SW "
-				"invalid signature. 0x%x\n", header->signature);
-		goto exit_err;
-	}
-	/* Upper byte has to be equal - no backward compatibility for unequal */
-	sdio_al->sdioc_major = header->version >> 16;
-	if (sdio_al->pdata->allow_sdioc_version_major_2) {
-		if ((sdio_al->sdioc_major !=
-		    sdio_al->pdata->peer_sdioc_version_major) &&
-		    (sdio_al->sdioc_major != PEER_SDIOC_OLD_VERSION_MAJOR)) {
-			sdio_al_loge(sdio_al_dev->dev_log, MODULE_NAME
-				": HOST(0x%x) and CLIENT(0x%x) "
-				"SDIO_AL VERSION don't match\n",
-				((sdio_al->pdata->peer_sdioc_version_major<<16)+
-				sdio_al->pdata->peer_sdioc_version_minor),
-				header->version);
-			goto exit_err;
-		}
-	} else {
-		if (sdio_al->sdioc_major !=
-		    sdio_al->pdata->peer_sdioc_version_major) {
-			sdio_al_loge(sdio_al_dev->dev_log, MODULE_NAME
-				": HOST(0x%x) and CLIENT(0x%x) "
-				"SDIO_AL VERSION don't match\n",
-				((sdio_al->pdata->peer_sdioc_version_major<<16)+
-				sdio_al->pdata->peer_sdioc_version_minor),
-				header->version);
-			goto exit_err;
-		}
-	}
-	sdio_al_dev->ch_close_supported = (header->version & 0x000F) >=
-		(sdio_al->pdata->peer_sdioc_version_minor & 0xF);
-
-	sdio_al_logi(sdio_al_dev->dev_log, MODULE_NAME ":SDIOC SW version 0x%x,"
-			" sdio_al major 0x%x minor 0x%x\n", header->version,
-			sdio_al->sdioc_major,
-			sdio_al->pdata->peer_sdioc_version_minor);
-
-	sdio_al_dev->flashless_boot_on = false;
-	for (i = 0; i < SDIO_AL_MAX_CHANNELS; i++) {
-		struct sdio_channel *ch = &sdio_al_dev->channel[i];
-
-		/* Set default values */
-		ch->read_threshold  = DEFAULT_READ_THRESHOLD;
-		ch->write_threshold = DEFAULT_WRITE_THRESHOLD;
-		ch->min_write_avail = DEFAULT_MIN_WRITE_THRESHOLD;
-		ch->is_packet_mode = true;
-		ch->peer_tx_buf_size = DEFAULT_PEER_TX_BUF_SIZE;
-		ch->poll_delay_msec = 0;
-
-		ch->num = i;
-		ch->func = NULL;
-		ch->rx_pipe_index = ch->num*2;
-		ch->tx_pipe_index = ch->num*2+1;
-
-		memset(ch->name, 0, sizeof(ch->name));
-
-		if (header->channel_names[i][0]) {
-			memcpy(ch->name, SDIO_PREFIX,
-			       strlen(SDIO_PREFIX));
-			memcpy(ch->name + strlen(SDIO_PREFIX),
-			       header->channel_names[i],
-			       PEER_CHANNEL_NAME_SIZE);
-
-			ch->state = SDIO_CHANNEL_STATE_IDLE;
-			ch->sdio_al_dev = sdio_al_dev;
-			if (sdio_al_dev->card->sdio_func[ch->num+1]) {
-				ch->func =
-				sdio_al_dev->card->sdio_func[ch->num+1];
-			} else {
-				sdio_al_loge(sdio_al_dev->dev_log, MODULE_NAME
-					": NULL func for channel %s\n",
-					ch->name);
-				goto exit_err;
-			}
-		} else {
-			ch->state = SDIO_CHANNEL_STATE_INVALID;
-		}
-
-		sdio_al_logi(sdio_al_dev->dev_log, MODULE_NAME ":Channel=%s, "
-				"state=%d\n", ch->name,	ch->state);
-	}
-
-	return 0;
-
-exit_err:
-	sdio_al_get_into_err_state(sdio_al_dev);
-	memset(header, 0, sizeof(*header));
-
-	return -EIO;
-}
-
-/**
- *  Read SDIO-Client channel configuration
- *
- */
-static int read_sdioc_channel_config(struct sdio_channel *ch)
-{
-	int ret;
-	struct peer_sdioc_sw_mailbox *sw_mailbox = NULL;
-	struct peer_sdioc_channel_config *ch_config = NULL;
-	struct sdio_al_device *sdio_al_dev = ch->sdio_al_dev;
-
-	if (sdio_al_dev == NULL) {
-		sdio_al_loge(&sdio_al->gen_log, MODULE_NAME ": NULL sdio_al_dev"
-				" for channel %s\n", ch->name);
-		return -EINVAL;
-	}
-
-	if (sdio_al_dev->sdioc_sw_header->version == 0)
-		return -1;
-
-	pr_debug(MODULE_NAME ":reading sw mailbox %s channel.\n", ch->name);
-
-	sw_mailbox = kzalloc(sizeof(*sw_mailbox), GFP_KERNEL);
-	if (sw_mailbox == NULL)
-		return -ENOMEM;
-
-	ret = sdio_memcpy_fromio(ch->func, sw_mailbox,
-			SDIOC_SW_MAILBOX_ADDR, sizeof(*sw_mailbox));
-	if (ret) {
-		sdio_al_loge(sdio_al_dev->dev_log, MODULE_NAME ":fail to read "
-				"sw mailbox.\n");
-		goto exit_err;
-	}
-
-	ch_config = &sw_mailbox->ch_config[ch->num];
-	memcpy(&ch->ch_config, ch_config,
-		sizeof(struct peer_sdioc_channel_config));
-
-	if (!ch_config->is_ready) {
-		sdio_al_loge(sdio_al_dev->dev_log, MODULE_NAME ":sw mailbox "
-				"channel not ready.\n");
-		goto exit_err;
-	}
-
-	ch->read_threshold = LOW_LATENCY_THRESHOLD;
-	ch->is_low_latency_ch = ch_config->is_low_latency_ch;
-	/* Threshold on 50% of the maximum size , sdioc uses double-buffer */
-	ch->write_threshold = (ch_config->max_tx_threshold * 5) / 10;
-	ch->threshold_change_cnt = ch->ch_config.max_rx_threshold -
-			ch->read_threshold + THRESHOLD_CHANGE_EXTRA_BYTES;
-
-	if (ch->is_low_latency_ch)
-		ch->def_read_threshold = LOW_LATENCY_THRESHOLD;
-	else /* Aggregation up to 90% of the maximum size */
-		ch->def_read_threshold = (ch_config->max_rx_threshold * 9) / 10;
-
-	ch->is_packet_mode = ch_config->is_packet_mode;
-	if (!ch->is_packet_mode) {
-		ch->poll_delay_msec = DEFAULT_POLL_DELAY_NOPACKET_MSEC;
-		ch->min_write_avail = DEFAULT_MIN_WRITE_THRESHOLD_STREAMING;
-	}
-	/* The max_packet_size is set by the modem in version 3 and on */
-	if (sdio_al->sdioc_major > PEER_SDIOC_OLD_VERSION_MAJOR)
-		ch->min_write_avail = ch_config->max_packet_size;
-
-	if (ch->min_write_avail > ch->write_threshold)
-		ch->min_write_avail = ch->write_threshold;
-
-	CLOSE_DEBUG(sdio_al_dev->dev_log, MODULE_NAME ":ch %s "
-			"read_threshold=%d, write_threshold=%d,"
-			" min_write_avail=%d, max_rx_threshold=%d,"
-			" max_tx_threshold=%d\n", ch->name, ch->read_threshold,
-			ch->write_threshold, ch->min_write_avail,
-			ch_config->max_rx_threshold,
-			ch_config->max_tx_threshold);
-
-	ch->peer_tx_buf_size = ch_config->tx_buf_size;
-
-	kfree(sw_mailbox);
-
-	return 0;
-
-exit_err:
-	sdio_al_logi(sdio_al_dev->dev_log, MODULE_NAME ":Reading SW Mailbox "
-			"error.\n");
-	kfree(sw_mailbox);
-
-	return -1;
-}
-
-
-/**
- *  Enable/Disable EOT interrupt of a pipe.
- *
- */
-static int enable_eot_interrupt(struct sdio_al_device *sdio_al_dev,
-				int pipe_index, int enable)
-{
-	int ret = 0;
-	struct sdio_func *func1;
-	u32 mask;
-	u32 pipe_mask;
-	u32 addr;
-
-	if (sdio_al_verify_func1(sdio_al_dev, __func__))
-		return -ENODEV;
-	func1 = sdio_al_dev->card->sdio_func[0];
-
-	if (pipe_index < 8) {
-		addr = PIPES_0_7_IRQ_MASK_ADDR;
-		pipe_mask = (1<<pipe_index);
-	} else {
-		addr = PIPES_8_15_IRQ_MASK_ADDR;
-		pipe_mask = (1<<(pipe_index-8));
-	}
-
-	mask = sdio_readl(func1, addr, &ret);
-	if (ret) {
-		pr_debug(MODULE_NAME ":enable_eot_interrupt fail\n");
-		goto exit_err;
-	}
-
-	if (enable)
-		mask &= (~pipe_mask); /* 0 = enable */
-	else
-		mask |= (pipe_mask);  /* 1 = disable */
-
-	sdio_writel(func1, mask, addr, &ret);
-
-exit_err:
-	return ret;
-}
-
-
-/**
- *  Enable/Disable mask interrupt of a function.
- *
- */
-static int enable_mask_irq(struct sdio_al_device *sdio_al_dev,
-			   int func_num, int enable, u8 bit_offset)
-{
-	int ret = 0;
-	struct sdio_func *func1 = NULL;
-	u32 mask = 0;
-	u32 func_mask = 0;
-	u32 addr = 0;
-	u32 offset = 0;
-
-	if (sdio_al_verify_func1(sdio_al_dev, __func__))
-		return -ENODEV;
-	func1 = sdio_al_dev->card->sdio_func[0];
-
-	if (func_num < 4) {
-		addr = FUNC_1_4_MASK_IRQ_ADDR;
-		offset = func_num * 8 + bit_offset;
-	} else {
-		addr = FUNC_5_7_MASK_IRQ_ADDR;
-		offset = (func_num - 4) * 8 + bit_offset;
-	}
-
-	func_mask = 1<<offset;
-
-	mask = sdio_readl(func1, addr, &ret);
-	if (ret) {
-		sdio_al_loge(sdio_al_dev->dev_log, MODULE_NAME ": "
-				"enable_mask_irq fail\n");
-		goto exit_err;
-	}
-
-	if (enable)
-		mask &= (~func_mask); /* 0 = enable */
-	else
-		mask |= (func_mask);  /* 1 = disable */
-
-	pr_debug(MODULE_NAME ":enable_mask_irq,  writing mask = 0x%x\n", mask);
-
-	sdio_writel(func1, mask, addr, &ret);
-
-exit_err:
-	return ret;
-}
-
-/**
- *  Enable/Disable Threshold interrupt of a pipe.
- *
- */
-static int enable_threshold_interrupt(struct sdio_al_device *sdio_al_dev,
-				      int pipe_index, int enable)
-{
-	int ret = 0;
-	struct sdio_func *func1;
-	u32 mask;
-	u32 pipe_mask;
-	u32 addr;
-
-	if (sdio_al_verify_func1(sdio_al_dev, __func__))
-		return -ENODEV;
-	func1 = sdio_al_dev->card->sdio_func[0];
-
-	if (pipe_index < 8) {
-		addr = PIPES_0_7_IRQ_MASK_ADDR;
-		pipe_mask = (1<<pipe_index);
-	} else {
-		addr = PIPES_8_15_IRQ_MASK_ADDR;
-		pipe_mask = (1<<(pipe_index-8));
-	}
-
-	mask = sdio_readl(func1, addr, &ret);
-	if (ret) {
-		pr_debug(MODULE_NAME ":enable_threshold_interrupt fail\n");
-		goto exit_err;
-	}
-
-	pipe_mask = pipe_mask<<8; /* Threshold bits 8..15 */
-	if (enable)
-		mask &= (~pipe_mask); /* 0 = enable */
-	else
-		mask |= (pipe_mask);  /* 1 = disable */
-
-	sdio_writel(func1, mask, addr, &ret);
-
-exit_err:
-	return ret;
-}
-
-/**
- *  Set the threshold to trigger interrupt from SDIO-Card on
- *  pipe available bytes.
- *
- */
-static int set_pipe_threshold(struct sdio_al_device *sdio_al_dev,
-			      int pipe_index, int threshold)
-{
-	int ret = 0;
-	struct sdio_func *func1;
-
-	if (sdio_al_verify_func1(sdio_al_dev, __func__))
-		return -ENODEV;
-	func1 = sdio_al_dev->card->sdio_func[0];
-
-	sdio_writel(func1, threshold,
-			PIPES_THRESHOLD_ADDR+pipe_index*4, &ret);
-	if (ret)
-		sdio_al_loge(sdio_al_dev->dev_log, MODULE_NAME ": "
-				"set_pipe_threshold err=%d\n", -ret);
-
-	return ret;
-}
-
-/**
- *  Enable func w/ retries
- *
- */
-static int sdio_al_enable_func_retry(struct sdio_func *func, const char *name)
-{
-	int ret, i;
-	for (i = 0; i < 200; i++) {
-		ret = sdio_enable_func(func);
-		if (ret) {
-			pr_debug(MODULE_NAME ":retry enable %s func#%d "
-					     "ret=%d\n",
-					 name, func->num, ret);
-			msleep(10);
-		} else
-			break;
-	}
-
-	return ret;
-}
-
-/**
- *  Open Channel
- *
- *  1. Init Channel Context.
- *  2. Init the Channel SDIO-Function.
- *  3. Init the Channel Pipes on Mailbox.
- */
-static int open_channel(struct sdio_channel *ch)
-{
-	int ret = 0;
-	struct sdio_al_device *sdio_al_dev = ch->sdio_al_dev;
-
-	if (sdio_al_dev == NULL) {
-		sdio_al_loge(&sdio_al->gen_log, MODULE_NAME ": NULL "
-				"sdio_al_dev for channel %s\n", ch->name);
-		return -EINVAL;
-	}
-
-	/* Init channel Context */
-	/** Func#1 is reserved for mailbox */
-	ch->func = sdio_al_dev->card->sdio_func[ch->num+1];
-	ch->rx_pipe_index = ch->num*2;
-	ch->tx_pipe_index = ch->num*2+1;
-	ch->signature = SDIO_AL_SIGNATURE;
-
-	ch->total_rx_bytes = 0;
-	ch->total_tx_bytes = 0;
-
-	ch->write_avail = 0;
-	ch->read_avail = 0;
-	ch->rx_pending_bytes = 0;
-
-	mutex_init(&ch->ch_lock);
-
-	pr_debug(MODULE_NAME ":open_channel %s func#%d\n",
-			 ch->name, ch->func->num);
-
-	INIT_LIST_HEAD(&(ch->rx_size_list_head));
-
-	/* Init SDIO Function */
-	ret = sdio_al_enable_func_retry(ch->func, ch->name);
-	if (ret) {
-		sdio_al_loge(sdio_al_dev->dev_log, MODULE_NAME ": "
-				"sdio_enable_func() err=%d\n", -ret);
-		goto exit_err;
-	}
-
-	/* Note: Patch Func CIS tuple issue */
-	ret = sdio_set_block_size(ch->func, SDIO_AL_BLOCK_SIZE);
-	if (ret) {
-		sdio_al_loge(sdio_al_dev->dev_log, MODULE_NAME ": "
-				"sdio_set_block_size()failed, err=%d\n", -ret);
-		goto exit_err;
-	}
-
-	ch->func->max_blksize = SDIO_AL_BLOCK_SIZE;
-
-	sdio_set_drvdata(ch->func, ch);
-
-	/* Get channel parameters from the peer SDIO-Client */
-	read_sdioc_channel_config(ch);
-
-	/* Set Pipes Threshold on Mailbox */
-	ret = set_pipe_threshold(sdio_al_dev,
-				 ch->rx_pipe_index, ch->read_threshold);
-	if (ret)
-		goto exit_err;
-	ret = set_pipe_threshold(sdio_al_dev,
-				 ch->tx_pipe_index, ch->write_threshold);
-	if (ret)
-		goto exit_err;
-
-	/* Set flag before interrupts are enabled to allow notify */
-	ch->state = SDIO_CHANNEL_STATE_OPEN;
-	pr_debug(MODULE_NAME ":channel %s is in OPEN state now\n", ch->name);
-
-	sdio_al_dev->poll_delay_msec = get_min_poll_time_msec(sdio_al_dev);
-
-	/* lpm mechanism lives under the assumption there is always a timer */
-	/* Check if need to start the timer */
-	if  ((sdio_al_dev->poll_delay_msec) &&
-	     (sdio_al_dev->is_timer_initialized == false)) {
-
-		init_timer(&sdio_al_dev->timer);
-		sdio_al_dev->timer.data = (unsigned long) sdio_al_dev;
-		sdio_al_dev->timer.function = sdio_al_timer_handler;
-		sdio_al_dev->timer.expires = jiffies +
-			msecs_to_jiffies(sdio_al_dev->poll_delay_msec);
-		add_timer(&sdio_al_dev->timer);
-		sdio_al_dev->is_timer_initialized = true;
-	}
-
-	/* Enable Pipes Interrupts */
-	enable_eot_interrupt(sdio_al_dev, ch->rx_pipe_index, true);
-	enable_eot_interrupt(sdio_al_dev, ch->tx_pipe_index, true);
-
-	enable_threshold_interrupt(sdio_al_dev, ch->rx_pipe_index, true);
-	enable_threshold_interrupt(sdio_al_dev, ch->tx_pipe_index, true);
-
-exit_err:
-
-	return ret;
-}
-
-/**
- *  Ask the worker to read the mailbox.
- */
-static void ask_reading_mailbox(struct sdio_al_device *sdio_al_dev)
-{
-	if (!sdio_al_dev->ask_mbox) {
-		pr_debug(MODULE_NAME ":ask_reading_mailbox for card %d\n",
-			 sdio_al_dev->host->index);
-		sdio_al_dev->ask_mbox = true;
-		wake_up(&sdio_al_dev->wait_mbox);
-	}
-}
-
-/**
- *  Start the timer
- */
-static void start_timer(struct sdio_al_device *sdio_al_dev)
-{
-	if ((sdio_al_dev->poll_delay_msec)  &&
-		(sdio_al_dev->state == CARD_INSERTED)) {
-		sdio_al_dev->timer.expires = jiffies +
-			msecs_to_jiffies(sdio_al_dev->poll_delay_msec);
-		add_timer(&sdio_al_dev->timer);
-	}
-}
-
-/**
- *  Restart(postpone) the already working timer
- */
-static void restart_timer(struct sdio_al_device *sdio_al_dev)
-{
-	if ((sdio_al_dev->poll_delay_msec) &&
-		(sdio_al_dev->state == CARD_INSERTED)) {
-		ulong expires =	jiffies +
-			msecs_to_jiffies(sdio_al_dev->poll_delay_msec);
-		mod_timer(&sdio_al_dev->timer, expires);
-	}
-}
-
-/**
- *  Stop and delete the timer
- */
-static void stop_and_del_timer(struct sdio_al_device *sdio_al_dev)
-{
-	if (sdio_al_dev->is_timer_initialized) {
-		sdio_al_dev->poll_delay_msec = 0;
-		del_timer_sync(&sdio_al_dev->timer);
-	}
-}
-
-/**
- *  Do the wakup sequence.
- *  This function should be called after claiming the host!
- *  The caller is responsible for releasing the host.
- *
- *  Wake up sequence
- *  1. Get lock
- *  2. Enable wake up function if needed
- *  3. Mark NOT OK to sleep and write it
- *  4. Restore default thresholds
- *  5. Start the mailbox and inactivity timer again
- */
-static int sdio_al_wake_up(struct sdio_al_device *sdio_al_dev,
-			   u32 not_from_int, struct sdio_channel *ch)
-{
-	int ret = 0;
-	struct sdio_func *wk_func = NULL;
-	unsigned long time_to_wait;
-	struct mmc_host *host = sdio_al_dev->host;
-
-	if (sdio_al_dev->is_err) {
-		SDIO_AL_ERR(__func__);
-		return -ENODEV;
-	}
-
-	if (!sdio_al_dev->is_ok_to_sleep) {
-		LPM_DEBUG(sdio_al_dev->dev_log, MODULE_NAME ":card %d "
-				"already awake, no need to wake up\n",
-				sdio_al_dev->host->index);
-		return 0;
-	}
-
-	/* Wake up sequence */
-	if (not_from_int) {
-		if (ch) {
-			LPM_DEBUG(sdio_al_dev->dev_log, MODULE_NAME ": Wake up"
-					" card %d (not by interrupt), ch %s",
-					sdio_al_dev->host->index,
-					ch->name);
-		} else {
-			LPM_DEBUG(sdio_al_dev->dev_log, MODULE_NAME ": Wake up"
-					  " card %d (not	by interrupt)",
-					  sdio_al_dev->host->index);
-		}
-	} else {
-		LPM_DEBUG(sdio_al_dev->dev_log, MODULE_NAME ": Wake up card "
-				"%d by interrupt",
-				sdio_al_dev->host->index);
-		sdio_al_dev->print_after_interrupt = 1;
-	}
-
-	sdio_al_vote_for_sleep(sdio_al_dev, 0);
-
-	msmsdcc_lpm_disable(host);
-	msmsdcc_set_pwrsave(host, 0);
-	/* Poll the GPIO */
-	time_to_wait = jiffies + msecs_to_jiffies(1000);
-	while (time_before(jiffies, time_to_wait)) {
-		if (sdio_al->pdata->get_mdm2ap_status())
-			break;
-		udelay(TIME_TO_WAIT_US);
-	}
-
-	pr_debug(MODULE_NAME ":GPIO mdm2ap_status=%d\n",
-		       sdio_al->pdata->get_mdm2ap_status());
-
-	/* Here get_mdm2ap_status() returning 0 is not an error condition */
-	if (sdio_al->pdata->get_mdm2ap_status() == 0)
-		LPM_DEBUG(sdio_al_dev->dev_log, MODULE_NAME ": "
-				"get_mdm2ap_status() is 0\n");
-
-	/* Enable Wake up Function */
-	if (!sdio_al_dev->card ||
-	    !sdio_al_dev->card->sdio_func[SDIO_AL_WAKEUP_FUNC-1]) {
-		sdio_al_loge(sdio_al_dev->dev_log, MODULE_NAME
-				": NULL card or wk_func\n");
-		return -ENODEV;
-	}
-	wk_func = sdio_al_dev->card->sdio_func[SDIO_AL_WAKEUP_FUNC-1];
-	ret = sdio_al_enable_func_retry(wk_func, "wakeup func");
-	if (ret) {
-		sdio_al_loge(sdio_al_dev->dev_log, MODULE_NAME ": "
-				"sdio_enable_func() err=%d\n", -ret);
-		goto error_exit;
-	}
-	/* Mark NOT OK_TOSLEEP */
-	sdio_al_dev->is_ok_to_sleep = 0;
-	ret = write_lpm_info(sdio_al_dev);
-	if (ret) {
-		sdio_al_loge(sdio_al_dev->dev_log, MODULE_NAME ": "
-				"write_lpm_info() failed, err=%d\n", -ret);
-		sdio_al_dev->is_ok_to_sleep = 1;
-		sdio_disable_func(wk_func);
-		goto error_exit;
-	}
-	sdio_disable_func(wk_func);
-
-	/* Start the timer again*/
-	restart_inactive_time(sdio_al_dev);
-	sdio_al_dev->poll_delay_msec = get_min_poll_time_msec(sdio_al_dev);
-	start_timer(sdio_al_dev);
-
-	LPM_DEBUG(sdio_al_dev->dev_log, MODULE_NAME "Finished Wake up sequence"
-			" for card %d", sdio_al_dev->host->index);
-
-	msmsdcc_set_pwrsave(host, 1);
-	pr_debug(MODULE_NAME ":Turn clock off\n");
-
-	return ret;
-error_exit:
-	sdio_al_vote_for_sleep(sdio_al_dev, 1);
-	msmsdcc_set_pwrsave(host, 1);
-	WARN_ON(ret);
-	sdio_al_get_into_err_state(sdio_al_dev);
-	return ret;
-}
-
-
-/**
- *  SDIO Function Interrupt handler.
- *
- *  Interrupt shall be triggered by SDIO-Client when:
- *  1. End-Of-Transfer (EOT) detected in packet mode.
- *  2. Bytes-available reached the threshold.
- *
- *  Reading the mailbox clears the EOT/Threshold interrupt
- *  source.
- *  The interrupt source should be cleared before this ISR
- *  returns. This ISR is called from IRQ Thread and not
- *  interrupt, so it may sleep.
- *
- */
-static void sdio_func_irq(struct sdio_func *func)
-{
-	struct sdio_al_device *sdio_al_dev = sdio_get_drvdata(func);
-
-	pr_debug(MODULE_NAME ":start %s.\n", __func__);
-
-	if (sdio_al_dev == NULL) {
-		sdio_al_loge(&sdio_al->gen_log, MODULE_NAME ": NULL device");
-		return;
-	}
-
-	if (sdio_al_dev->is_ok_to_sleep)
-		sdio_al_wake_up(sdio_al_dev, 0, NULL);
-	else
-		restart_timer(sdio_al_dev);
-
-	read_mailbox(sdio_al_dev, true);
-
-	pr_debug(MODULE_NAME ":end %s.\n", __func__);
-}
-
-/**
- *  Timer Expire Handler
- *
- */
-static void sdio_al_timer_handler(unsigned long data)
-{
-	struct sdio_al_device *sdio_al_dev = (struct sdio_al_device *)data;
-	if (sdio_al_dev == NULL) {
-		sdio_al_loge(sdio_al_dev->dev_log, MODULE_NAME ": NULL "
-				"sdio_al_dev for data %lu\n", data);
-		return;
-	}
-	if (sdio_al_dev->state != CARD_INSERTED) {
-		sdio_al_loge(sdio_al_dev->dev_log, MODULE_NAME ": sdio_al_dev "
-				"is in invalid state %d\n", sdio_al_dev->state);
-		return;
-	}
-	pr_debug(MODULE_NAME " Timer Expired\n");
-
-	ask_reading_mailbox(sdio_al_dev);
-
-	restart_timer(sdio_al_dev);
-}
-
-/**
- *  Driver Setup.
- *
- */
-static int sdio_al_setup(struct sdio_al_device *sdio_al_dev)
-{
-	int ret = 0;
-	struct mmc_card *card = sdio_al_dev->card;
-	struct sdio_func *func1 = NULL;
-	int i = 0;
-	int fn = 0;
-
-	if (sdio_al_verify_func1(sdio_al_dev, __func__))
-		return -ENODEV;
-	func1 = card->sdio_func[0];
-
-	sdio_al_logi(sdio_al_dev->dev_log, MODULE_NAME ":sdio_al_setup for "
-			"card %d\n", sdio_al_dev->host->index);
-
-	ret = sdio_al->pdata->config_mdm2ap_status(1);
-	if (ret) {
-		sdio_al_loge(sdio_al_dev->dev_log, MODULE_NAME "Could not "
-				"request GPIO\n");
-		return ret;
-	}
-
-	INIT_WORK(&sdio_al_dev->sdio_al_work.work, worker);
-	/* disable all pipes interrupts before claim irq.
-	   since all are enabled by default. */
-	for (i = 0 ; i < SDIO_AL_MAX_PIPES; i++) {
-		enable_eot_interrupt(sdio_al_dev, i, false);
-		enable_threshold_interrupt(sdio_al_dev, i, false);
-	}
-
-	/* Disable all SDIO Functions before claim irq. */
-	for (fn = 1 ; fn <= card->sdio_funcs; fn++)
-		sdio_disable_func(card->sdio_func[fn-1]);
-
-	sdio_set_drvdata(func1, sdio_al_dev);
-	sdio_al_logi(sdio_al_dev->dev_log, MODULE_NAME ":claim IRQ for card "
-			"%d\n",	sdio_al_dev->host->index);
-
-	ret = sdio_claim_irq(func1, sdio_func_irq);
-	if (ret) {
-		sdio_al_loge(sdio_al_dev->dev_log, MODULE_NAME ":Fail to claim"
-				" IRQ for card %d\n",
-				sdio_al_dev->host->index);
-		return ret;
-	}
-
-	sdio_al_dev->is_ready = true;
-
-	/* Start worker before interrupt might happen */
-	queue_work(sdio_al_dev->workqueue, &sdio_al_dev->sdio_al_work.work);
-
-	start_inactive_time(sdio_al_dev);
-
-	pr_debug(MODULE_NAME ":Ready.\n");
-
-	return 0;
-}
-
-/**
- *  Driver Tear-Down.
- *
- */
-static void sdio_al_tear_down(void)
-{
-	int i, j;
-	struct sdio_al_device *sdio_al_dev = NULL;
-	struct sdio_func *func1;
-
-	for (i = 0; i < MAX_NUM_OF_SDIO_DEVICES; ++i) {
-		if (sdio_al->devices[i] == NULL)
-			continue;
-		sdio_al_dev = sdio_al->devices[i];
-
-		if (sdio_al_dev->is_ready) {
-			sdio_al_dev->is_ready = false; /* Flag worker to exit */
-			sdio_al_dev->ask_mbox = false;
-			ask_reading_mailbox(sdio_al_dev); /* Wakeup worker */
-			/* allow gracefully exit of the worker thread */
-			msleep(100);
-
-			flush_workqueue(sdio_al_dev->workqueue);
-			destroy_workqueue(sdio_al_dev->workqueue);
-
-			sdio_al_vote_for_sleep(sdio_al_dev, 1);
-
-			if (!sdio_al_claim_mutex_and_verify_dev(sdio_al_dev,
-								__func__)) {
-				if (!sdio_al_dev->card ||
-				    !sdio_al_dev->card->sdio_func[0]) {
-					sdio_al_loge(sdio_al_dev->dev_log,
-						     MODULE_NAME
-							": %s: Invalid func1",
-							__func__);
-					return;
-				}
-				func1 = sdio_al_dev->card->sdio_func[0];
-				sdio_release_irq(func1);
-				sdio_disable_func(func1);
-				sdio_al_release_mutex(sdio_al_dev, __func__);
-			}
-		}
-
-		for (j = 0; j < SDIO_AL_MAX_CHANNELS; j++)
-			sdio_al_dev->channel[j].signature = 0x0;
-		sdio_al_dev->signature = 0;
-
-		kfree(sdio_al_dev->sdioc_sw_header);
-		kfree(sdio_al_dev->mailbox);
-		kfree(sdio_al_dev->rx_flush_buf);
-		kfree(sdio_al_dev);
-	}
-
-	sdio_al->pdata->config_mdm2ap_status(0);
-}
-
-/**
- *  Find channel by name.
- *
- */
-static struct sdio_channel *find_channel_by_name(const char *name)
-{
-	struct sdio_channel *ch = NULL;
-	int i, j;
-	struct sdio_al_device *sdio_al_dev = NULL;
-
-	for (j = 0; j < MAX_NUM_OF_SDIO_DEVICES; ++j) {
-		if (sdio_al->devices[j] == NULL)
-			continue;
-		sdio_al_dev = sdio_al->devices[j];
-		for (i = 0; i < SDIO_AL_MAX_CHANNELS; i++) {
-			if (sdio_al_dev->channel[i].state ==
-					SDIO_CHANNEL_STATE_INVALID)
-				continue;
-			if (strncmp(sdio_al_dev->channel[i].name, name,
-					CHANNEL_NAME_SIZE) == 0) {
-				ch = &sdio_al_dev->channel[i];
-				break;
-			}
-		}
-		if (ch != NULL)
-			break;
-	}
-
-	return ch;
-}
-
-/**
- *  Find the minimal poll time.
- *
- */
-static int get_min_poll_time_msec(struct sdio_al_device *sdio_sl_dev)
-{
-	int i;
-	int poll_delay_msec = 0x0FFFFFFF;
-
-	for (i = 0; i < SDIO_AL_MAX_CHANNELS; i++)
-		if ((sdio_sl_dev->channel[i].state ==
-					SDIO_CHANNEL_STATE_OPEN) &&
-		(sdio_sl_dev->channel[i].poll_delay_msec > 0) &&
-		(sdio_sl_dev->channel[i].poll_delay_msec < poll_delay_msec))
-			poll_delay_msec =
-				sdio_sl_dev->channel[i].poll_delay_msec;
-
-	if (poll_delay_msec == 0x0FFFFFFF)
-		poll_delay_msec = SDIO_AL_POLL_TIME_NO_STREAMING;
-
-	pr_debug(MODULE_NAME ":poll delay time is %d msec\n", poll_delay_msec);
-
-	return poll_delay_msec;
-}
-
-/**
- *  Open SDIO Channel.
- *
- *  Enable the channel.
- *  Set the channel context.
- *  Trigger reading the mailbox to check available bytes.
- *
- */
-int sdio_open(const char *name, struct sdio_channel **ret_ch, void *priv,
-		 void (*notify)(void *priv, unsigned ch_event))
-{
-	int ret = 0;
-	struct sdio_channel *ch = NULL;
-	struct sdio_al_device *sdio_al_dev = NULL;
-
-	*ret_ch = NULL; /* default */
-
-	ch = find_channel_by_name(name);
-	if (ch == NULL) {
-		sdio_al_loge(&sdio_al->gen_log, MODULE_NAME ":Can't find "
-			"channel name %s\n", name);
-		return -EINVAL;
-	}
-
-	sdio_al_dev = ch->sdio_al_dev;
-	if (sdio_al_claim_mutex_and_verify_dev(sdio_al_dev, __func__))
-		return -ENODEV;
-
-	if ((ch->state != SDIO_CHANNEL_STATE_IDLE) &&
-		(ch->state != SDIO_CHANNEL_STATE_CLOSED)) {
-		sdio_al_loge(sdio_al_dev->dev_log, MODULE_NAME ":Wrong ch %s "
-				"state %d\n", name, ch->state);
-		ret = -EPERM;
-		goto exit_err;
-	}
-
-	if (sdio_al_dev->is_err) {
-		SDIO_AL_ERR(__func__);
-		ret = -ENODEV;
-		goto exit_err;
-	}
-
-	ret = sdio_al_wake_up(sdio_al_dev, 1, ch);
-	if (ret)
-		goto exit_err;
-
-	ch->notify = notify;
-	ch->priv = priv;
-
-	/* Note: Set caller returned context before interrupts are enabled */
-	*ret_ch = ch;
-
-	ret = open_channel(ch);
-	if (ret) {
-		sdio_al_loge(sdio_al_dev->dev_log, MODULE_NAME ":sdio_open %s "
-				"err=%d\n", name, -ret);
-		goto exit_err;
-	}
-
-	CLOSE_DEBUG(sdio_al_dev->dev_log, MODULE_NAME ":sdio_open %s "
-							"completed OK\n", name);
-	if (sdio_al_dev->lpm_chan == INVALID_SDIO_CHAN) {
-		if (sdio_al->sdioc_major == PEER_SDIOC_OLD_VERSION_MAJOR) {
-			if (!ch->is_packet_mode) {
-				sdio_al_logi(sdio_al_dev->dev_log, MODULE_NAME
-						":setting channel %s as "
-						"lpm_chan\n", name);
-				sdio_al_dev->lpm_chan = ch->num;
-			}
-		} else {
-			sdio_al_logi(sdio_al_dev->dev_log, MODULE_NAME ": "
-					"setting channel %s as lpm_chan\n",
-					name);
-			sdio_al_dev->lpm_chan = ch->num;
-		}
-	}
-
-exit_err:
-	sdio_al_release_mutex(sdio_al_dev, __func__);
-	return ret;
-}
-EXPORT_SYMBOL(sdio_open);
-
-/**
- *  Request peer operation
- *  note: sanity checks of parameters done by caller
- *        called under bus locked
- */
-static int peer_set_operation(u32 opcode,
-		struct sdio_al_device *sdio_al_dev,
-		struct sdio_channel *ch)
-{
-	int ret;
-	int offset;
-	struct sdio_func *wk_func = NULL;
-	u32 peer_operation;
-	int loop_count = 0;
-
-	if (!sdio_al_dev->card ||
-	    !sdio_al_dev->card->sdio_func[SDIO_AL_WAKEUP_FUNC-1]) {
-		sdio_al_loge(sdio_al_dev->dev_log, MODULE_NAME
-				": NULL card or wk_func\n");
-		ret = -ENODEV;
-		goto exit;
-	}
-	wk_func = sdio_al_dev->card->sdio_func[SDIO_AL_WAKEUP_FUNC-1];
-
-	/* calculate offset of peer_operation field in sw mailbox struct */
-	offset = offsetof(struct peer_sdioc_sw_mailbox, ch_config) +
-		sizeof(struct peer_sdioc_channel_config) * ch->num +
-		offsetof(struct peer_sdioc_channel_config, peer_operation);
-
-	ret = sdio_al_wake_up(sdio_al_dev, 1, ch);
-	if (ret) {
-		sdio_al_loge(sdio_al_dev->dev_log, MODULE_NAME ":Fail to "
-				"wake up\n");
-		goto exit;
-	}
-	/* request operation from MDM peer */
-	peer_operation = PEER_OPERATION(opcode, PEER_OP_STATE_INIT);
-	ret = sdio_memcpy_toio(ch->func, SDIOC_SW_MAILBOX_ADDR+offset,
-			&peer_operation, sizeof(u32));
-	if (ret) {
-		sdio_al_loge(sdio_al_dev->dev_log, MODULE_NAME ":failed to "
-				"request close operation\n");
-		goto exit;
-	}
-	ret = sdio_al_enable_func_retry(wk_func, "wk_func");
-	if (ret) {
-		sdio_al_loge(sdio_al_dev->dev_log, MODULE_NAME ":Fail to enable"
-				" Func#%d\n", wk_func->num);
-		goto exit;
-	}
-	pr_debug(MODULE_NAME ":%s: wk_func enabled on ch %s\n",
-			__func__, ch->name);
-	/* send "start" operation to MDM */
-	peer_operation = PEER_OPERATION(opcode, PEER_OP_STATE_START);
-	ret  =  sdio_memcpy_toio(ch->func, SDIOC_SW_MAILBOX_ADDR+offset,
-			&peer_operation, sizeof(u32));
-	if (ret) {
-		sdio_al_loge(sdio_al_dev->dev_log, MODULE_NAME ":failed to "
-				"send start close operation\n");
-		goto exit;
-	}
-	ret = sdio_disable_func(wk_func);
-	if (ret) {
-		sdio_al_loge(sdio_al_dev->dev_log, MODULE_NAME ":Fail to "
-				"disable Func#%d\n", wk_func->num);
-		goto exit;
-	}
-	/* poll for peer operation ack */
-	while (peer_operation != 0) {
-		ret  =  sdio_memcpy_fromio(ch->func,
-				&peer_operation,
-				SDIOC_SW_MAILBOX_ADDR+offset,
-				sizeof(u32));
-		if (ret) {
-			sdio_al_loge(sdio_al_dev->dev_log, MODULE_NAME
-					":failed to request ack on close"
-					" operation, loop_count = %d\n",
-					loop_count);
-			goto exit;
-		}
-		loop_count++;
-		if (loop_count > 10) {
-			sdio_al_logi(sdio_al_dev->dev_log, MODULE_NAME ":%s: "
-					"peer_operation=0x%x wait loop"
-					" %d on ch %s\n", __func__,
-					peer_operation, loop_count, ch->name);
-		}
-	}
-exit:
-	return ret;
-}
-
-static int channel_close(struct sdio_channel *ch, int flush_flag)
-{
-	int ret;
-	struct sdio_al_device *sdio_al_dev = NULL;
-	int flush_len;
-	ulong flush_expires;
-
-	if (!ch) {
-		sdio_al_loge(&sdio_al->gen_log, MODULE_NAME ":%s: NULL "
-				"channel\n",  __func__);
-		return -ENODEV;
-	}
-
-	if (!ch->func) {
-		sdio_al_loge(sdio_al_dev->dev_log, MODULE_NAME ":%s: NULL func"
-				" on channel:%d\n", __func__, ch->num);
-		return -ENODEV;
-	}
-
-	sdio_al_dev = ch->sdio_al_dev;
-	if (sdio_al_claim_mutex_and_verify_dev(sdio_al_dev, __func__))
-		return -ENODEV;
-
-	if (!sdio_al_dev->ch_close_supported) {
-		sdio_al_loge(sdio_al_dev->dev_log, MODULE_NAME ":%s: Not "
-			"supported by mdm, ch %s\n",
-			__func__, ch->name);
-		ret = -ENOTSUPP;
-		goto error_exit;
-	}
-
-	if (sdio_al_dev->is_err) {
-		SDIO_AL_ERR(__func__);
-		ret = -ENODEV;
-		goto error_exit;
-	}
-	if (ch->state != SDIO_CHANNEL_STATE_OPEN) {
-		sdio_al_loge(sdio_al_dev->dev_log,
-				MODULE_NAME ":%s: ch %s is not in "
-				"open state (%d)\n",
-				__func__, ch->name, ch->state);
-		ret = -ENODEV;
-		goto error_exit;
-	}
-	ch->state = SDIO_CHANNEL_STATE_CLOSING;
-	ret = peer_set_operation(PEER_OP_CODE_CLOSE, sdio_al_dev, ch);
-	if (ret) {
-		sdio_al_loge(sdio_al_dev->dev_log, MODULE_NAME ":%s: "
-				"peer_set_operation() failed: %d\n",
-				__func__, ret);
-		ret = -ENODEV;
-		goto error_exit;
-	}
-	/* udate poll time for opened channels */
-	if  (ch->poll_delay_msec > 0) {
-		sdio_al_dev->poll_delay_msec =
-			get_min_poll_time_msec(sdio_al_dev);
-	}
-	sdio_al_release_mutex(ch->sdio_al_dev, __func__);
-
-	flush_expires = jiffies +
-		msecs_to_jiffies(SDIO_CLOSE_FLUSH_TIMEOUT_MSEC);
-	/* flush rx packets of the channel */
-	if (flush_flag) {
-		do {
-			while (ch->read_avail > 0) {
-				flush_len = ch->read_avail;
-				ret = sdio_read_internal(ch,
-						sdio_al_dev->rx_flush_buf,
-						flush_len);
-				if (ret) {
-					sdio_al_loge(&sdio_al->gen_log,
-						MODULE_NAME ":%s sdio_read"
-						" failed: %d, ch %s\n",
-						__func__, ret,
-						ch->name);
-					return ret;
-				}
-
-				if (time_after(jiffies, flush_expires) != 0) {
-					sdio_al_loge(&sdio_al->gen_log,
-						MODULE_NAME ":%s flush rx "
-						"packets timeout: ch %s\n",
-						__func__, ch->name);
-					sdio_al_get_into_err_state(sdio_al_dev);
-					return -EBUSY;
-				}
-			}
-			msleep(100);
-			if (ch->signature != SDIO_AL_SIGNATURE) {
-					sdio_al_loge(&sdio_al->gen_log,
-						MODULE_NAME ":%s: after sleep,"
-						" invalid signature"
-						" 0x%x\n", __func__,
-						ch->signature);
-				return -ENODEV;
-			}
-			if (sdio_al_claim_mutex_and_verify_dev(ch->sdio_al_dev,
-							       __func__))
-				return -ENODEV;
-
-			ret = read_mailbox(sdio_al_dev, false);
-			if (ret) {
-				sdio_al_loge(&sdio_al->gen_log,
-						MODULE_NAME ":%s: failed to"
-						" read mailbox", __func__);
-				goto error_exit;
-			}
-			sdio_al_release_mutex(ch->sdio_al_dev, __func__);
-		} while (ch->read_avail > 0);
-	}
-	if (sdio_al_claim_mutex_and_verify_dev(ch->sdio_al_dev,
-					       __func__))
-		return -ENODEV;
-	/* disable function to be able to open the channel again */
-	ret = sdio_disable_func(ch->func);
-	if (ret) {
-		sdio_al_loge(&sdio_al->gen_log,
-			MODULE_NAME ":Fail to disable Func#%d\n",
-			ch->func->num);
-		goto error_exit;
-	}
-	ch->state = SDIO_CHANNEL_STATE_CLOSED;
-	CLOSE_DEBUG(sdio_al_dev->dev_log, MODULE_NAME ":%s: Ch %s closed "
-				"successfully\n", __func__, ch->name);
-
-error_exit:
-	sdio_al_release_mutex(ch->sdio_al_dev, __func__);
-
-	return ret;
-}
-
-/**
- *  Close SDIO Channel.
- *
- */
-int sdio_close(struct sdio_channel *ch)
-{
-	return channel_close(ch, true);
-}
-EXPORT_SYMBOL(sdio_close);
-
-/**
- *  Get the number of available bytes to write.
- *
- */
-int sdio_write_avail(struct sdio_channel *ch)
-{
-	if (!ch) {
-		sdio_al_loge(&sdio_al->gen_log, MODULE_NAME ":%s: NULL "
-				"channel\n", __func__);
-		return -ENODEV;
-	}
-	if (ch->signature != SDIO_AL_SIGNATURE) {
-		sdio_al_loge(&sdio_al->gen_log, MODULE_NAME ":%s: "
-				"Invalid signature 0x%x\n",  __func__,
-				ch->signature);
-		return -ENODEV;
-	}
-	if (ch->state != SDIO_CHANNEL_STATE_OPEN) {
-		sdio_al_loge(ch->sdio_al_dev->dev_log, MODULE_NAME ":%s: "
-				"channel %s state is not open (%d)\n",
-				__func__, ch->name, ch->state);
-		return -ENODEV;
-	}
-	pr_debug(MODULE_NAME ":sdio_write_avail %s 0x%x\n",
-			 ch->name, ch->write_avail);
-
-	return ch->write_avail;
-}
-EXPORT_SYMBOL(sdio_write_avail);
-
-/**
- *  Get the number of available bytes to read.
- *
- */
-int sdio_read_avail(struct sdio_channel *ch)
-{
-	if (!ch) {
-		sdio_al_loge(&sdio_al->gen_log, MODULE_NAME ":%s: NULL "
-				"channel\n", __func__);
-		return -ENODEV;
-	}
-	if (ch->signature != SDIO_AL_SIGNATURE) {
-		sdio_al_loge(&sdio_al->gen_log, MODULE_NAME ":%s: "
-				"Invalid signature 0x%x\n",  __func__,
-				ch->signature);
-		return -ENODEV;
-	}
-	if (ch->state != SDIO_CHANNEL_STATE_OPEN) {
-		sdio_al_loge(ch->sdio_al_dev->dev_log, MODULE_NAME ":%s: "
-				"channel %s state is not open (%d)\n",
-				__func__, ch->name, ch->state);
-		return -ENODEV;
-	}
-	pr_debug(MODULE_NAME ":sdio_read_avail %s 0x%x\n",
-			 ch->name, ch->read_avail);
-
-	return ch->read_avail;
-}
-EXPORT_SYMBOL(sdio_read_avail);
-
-static int sdio_read_from_closed_ch(struct sdio_channel *ch, int len)
-{
-	int ret = 0;
-	struct sdio_al_device *sdio_al_dev = NULL;
-
-	if (!ch) {
-		sdio_al_loge(ch->sdio_al_dev->dev_log,
-			MODULE_NAME ":%s: NULL channel\n",  __func__);
-		return -ENODEV;
-	}
-
-	sdio_al_dev = ch->sdio_al_dev;
-	if (sdio_al_claim_mutex_and_verify_dev(sdio_al_dev, __func__))
-		return -ENODEV;
-
-	ret = sdio_memcpy_fromio(ch->func, sdio_al_dev->rx_flush_buf,
-				 PIPE_RX_FIFO_ADDR, len);
-
-	if (ret) {
-		sdio_al_loge(ch->sdio_al_dev->dev_log,
-				MODULE_NAME ":ch %s: %s err=%d, len=%d\n",
-				ch->name, __func__, -ret, len);
-		sdio_al_dev->is_err = true;
-		sdio_al_release_mutex(sdio_al_dev, __func__);
-		return ret;
-	}
-
-	restart_inactive_time(sdio_al_dev);
-
-	sdio_al_release_mutex(sdio_al_dev, __func__);
-
-	return 0;
-}
-
-/**
- *  Internal read from SDIO Channel.
- *
- *  Reading from the pipe will trigger interrupt if there are
- *  other pending packets on the SDIO-Client.
- *
- */
-static int sdio_read_internal(struct sdio_channel *ch, void *data, int len)
-{
-	int ret = 0;
-	struct sdio_al_device *sdio_al_dev = NULL;
-
-	if (!ch) {
-		sdio_al_loge(&sdio_al->gen_log, MODULE_NAME ":%s: NULL "
-				"channel\n",  __func__);
-		return -ENODEV;
-	}
-	if (!data) {
-		sdio_al_loge(&sdio_al->gen_log, MODULE_NAME ":%s: NULL data\n",
-				__func__);
-		return -ENODEV;
-	}
-	if (len == 0) {
-		sdio_al_loge(&sdio_al->gen_log, MODULE_NAME ":channel %s trying"
-				" to read 0 bytes\n", ch->name);
-		return -EINVAL;
-	}
-
-	if (ch->signature != SDIO_AL_SIGNATURE) {
-		sdio_al_loge(&sdio_al->gen_log, MODULE_NAME ":%s: Invalid "
-				"signature 0x%x\n",  __func__, ch->signature);
-		return -ENODEV;
-	}
-
-	sdio_al_dev = ch->sdio_al_dev;
-	if (sdio_al_claim_mutex_and_verify_dev(sdio_al_dev, __func__))
-		return -ENODEV;
-
-	if (sdio_al_dev->is_err) {
-		SDIO_AL_ERR(__func__);
-		ret = -ENODEV;
-		goto exit;
-	}
-
-	/* lpm policy says we can't go to sleep when we have pending rx data,
-	   so either we had rx interrupt and woken up, or we never went to
-	   sleep */
-	if (sdio_al_dev->is_ok_to_sleep) {
-		sdio_al_loge(sdio_al_dev->dev_log, MODULE_NAME ":%s: called "
-				"when is_ok_to_sleep is set for ch %s, len=%d,"
-				" last_any_read_avail=%d, last_read_avail=%d, "
-				"last_old_read_avail=%d", __func__, ch->name,
-				len, ch->statistics.last_any_read_avail,
-				ch->statistics.last_read_avail,
-				ch->statistics.last_old_read_avail);
-	}
-	BUG_ON(sdio_al_dev->is_ok_to_sleep);
-
-	if ((ch->state != SDIO_CHANNEL_STATE_OPEN) &&
-			(ch->state != SDIO_CHANNEL_STATE_CLOSING)) {
-		sdio_al_loge(sdio_al_dev->dev_log, MODULE_NAME ":%s wrong "
-				"channel %s state %d\n",
-				__func__, ch->name, ch->state);
-		ret = -EINVAL;
-		goto exit;
-	}
-
-	DATA_DEBUG(sdio_al_dev->dev_log, MODULE_NAME ":start ch %s read %d "
-			"avail %d.\n", ch->name, len, ch->read_avail);
-
-	restart_inactive_time(sdio_al_dev);
-
-	if ((ch->is_packet_mode) && (len != ch->read_avail)) {
-		sdio_al_loge(sdio_al_dev->dev_log, MODULE_NAME ":sdio_read ch "
-				"%s len != read_avail\n", ch->name);
-		ret = -EINVAL;
-		goto exit;
-	}
-
-	if (len > ch->read_avail) {
-		sdio_al_loge(sdio_al_dev->dev_log, MODULE_NAME ":ERR ch %s: "
-				"reading more bytes (%d) than the avail(%d).\n",
-				ch->name, len, ch->read_avail);
-		ret = -ENOMEM;
-		goto exit;
-	}
-
-	ret = sdio_memcpy_fromio(ch->func, data, PIPE_RX_FIFO_ADDR, len);
-
-	if (ret) {
-		sdio_al_loge(sdio_al_dev->dev_log, MODULE_NAME ":ch %s: "
-				"sdio_read err=%d, len=%d, read_avail=%d, "
-				"last_read_avail=%d, last_old_read_avail=%d\n",
-				ch->name, -ret, len, ch->read_avail,
-				ch->statistics.last_read_avail,
-				ch->statistics.last_old_read_avail);
-		sdio_al_get_into_err_state(sdio_al_dev);
-		goto exit;
-	}
-
-	ch->statistics.total_read_times++;
-
-	/* Remove handled packet from the list regardless if ret is ok */
-	if (ch->is_packet_mode)
-		remove_handled_rx_packet(ch);
-	else
-		ch->read_avail -= len;
-
-	ch->total_rx_bytes += len;
-	DATA_DEBUG(sdio_al_dev->dev_log, MODULE_NAME ":end ch %s read %d "
-			"avail %d total %d.\n", ch->name, len,
-			ch->read_avail, ch->total_rx_bytes);
-
-	if ((ch->read_avail == 0) && !(ch->is_packet_mode))
-		ask_reading_mailbox(sdio_al_dev);
-
-exit:
-	sdio_al_release_mutex(sdio_al_dev, __func__);
-
-	return ret;
-}
-
-/**
- *  Read from SDIO Channel.
- *
- *  Reading from the pipe will trigger interrupt if there are
- *  other pending packets on the SDIO-Client.
- *
- */
-int sdio_read(struct sdio_channel *ch, void *data, int len)
-{
-	if (!ch) {
-		sdio_al_loge(&sdio_al->gen_log, MODULE_NAME ":%s: NULL "
-				"channel\n", __func__);
-		return -ENODEV;
-	}
-	if (ch->signature != SDIO_AL_SIGNATURE) {
-		sdio_al_loge(&sdio_al->gen_log, MODULE_NAME ":%s: "
-			"Invalid signature 0x%x\n",  __func__, ch->signature);
-		return -ENODEV;
-	}
-	if (ch->state == SDIO_CHANNEL_STATE_OPEN) {
-		return sdio_read_internal(ch, data, len);
-	} else {
-		sdio_al_loge(ch->sdio_al_dev->dev_log, MODULE_NAME
-				":%s: Invalid channel %s state %d\n",
-				__func__, ch->name, ch->state);
-	}
-	return -ENODEV;
-}
-EXPORT_SYMBOL(sdio_read);
-
-/**
- *  Write to SDIO Channel.
- *
- */
-int sdio_write(struct sdio_channel *ch, const void *data, int len)
-{
-	int ret = 0;
-	struct sdio_al_device *sdio_al_dev = NULL;
-
-	if (!ch) {
-		sdio_al_loge(&sdio_al->gen_log, MODULE_NAME ":%s: NULL "
-				"channel\n",  __func__);
-		return -ENODEV;
-	}
-	if (!data) {
-		sdio_al_loge(&sdio_al->gen_log, MODULE_NAME ":%s: NULL data\n",
-				__func__);
-		return -ENODEV;
-	}
-	if (len == 0) {
-		sdio_al_loge(&sdio_al->gen_log, MODULE_NAME ":channel %s trying"
-				" to write 0 bytes\n", ch->name);
-		return -EINVAL;
-	}
-
-	if (ch->signature != SDIO_AL_SIGNATURE) {
-		sdio_al_loge(&sdio_al->gen_log, MODULE_NAME ":%s: Invalid "
-				"signature 0x%x\n",  __func__, ch->signature);
-		return -ENODEV;
-	}
-
-	sdio_al_dev = ch->sdio_al_dev;
-	if (sdio_al_claim_mutex_and_verify_dev(sdio_al_dev, __func__))
-		return -ENODEV;
-
-	WARN_ON(len > ch->write_avail);
-
-	if (sdio_al_dev->is_err) {
-		SDIO_AL_ERR(__func__);
-		ret = -ENODEV;
-		goto exit;
-	}
-
-	if (ch->state != SDIO_CHANNEL_STATE_OPEN) {
-		sdio_al_loge(sdio_al_dev->dev_log, MODULE_NAME ":writing to "
-				"closed channel %s\n", ch->name);
-		ret = -EINVAL;
-		goto exit;
-	}
-
-	if (sdio_al_dev->is_ok_to_sleep) {
-		ret = sdio_al_wake_up(sdio_al_dev, 1, ch);
-		if (ret)
-			goto exit;
-	} else {
-		restart_inactive_time(sdio_al_dev);
-	}
-
-	DATA_DEBUG(sdio_al_dev->dev_log, MODULE_NAME ":start ch %s write %d "
-			"avail %d.\n", ch->name, len, ch->write_avail);
-
-	if (len > ch->write_avail) {
-		sdio_al_loge(sdio_al_dev->dev_log, MODULE_NAME ":ERR ch %s: "
-				"write more bytes (%d) than  available %d.\n",
-				ch->name, len, ch->write_avail);
-		ret = -ENOMEM;
-		goto exit;
-	}
-
-	ret = sdio_ch_write(ch, data, len);
-	if (ret) {
-		sdio_al_loge(sdio_al_dev->dev_log, MODULE_NAME ":sdio_write "
-				"on channel %s err=%d\n", ch->name, -ret);
-		goto exit;
-	}
-
-	ch->total_tx_bytes += len;
-	DATA_DEBUG(sdio_al_dev->dev_log, MODULE_NAME ":end ch %s write %d "
-			"avail %d total %d.\n", ch->name, len,
-			ch->write_avail, ch->total_tx_bytes);
-
-	/* Round up to whole buffer size */
-	len = ROUND_UP(len, ch->peer_tx_buf_size);
-	/* Protect from wraparound */
-	len = min(len, (int) ch->write_avail);
-	ch->write_avail -= len;
-
-	if (ch->write_avail < ch->min_write_avail)
-		ask_reading_mailbox(sdio_al_dev);
-
-exit:
-	sdio_al_release_mutex(sdio_al_dev, __func__);
-
-	return ret;
-}
-EXPORT_SYMBOL(sdio_write);
-
-static int __devinit msm_sdio_al_probe(struct platform_device *pdev)
-{
-	if (!sdio_al) {
-		pr_err(MODULE_NAME ": %s: NULL sdio_al\n", __func__);
-		return -ENODEV;
-	}
-
-	sdio_al->pdata = pdev->dev.platform_data;
-	return 0;
-}
-
-static int __devexit msm_sdio_al_remove(struct platform_device *pdev)
-{
-	return 0;
-}
-
-static void sdio_al_close_all_channels(struct sdio_al_device *sdio_al_dev)
-{
-	int j;
-	int ret;
-	struct sdio_channel *ch = NULL;
-
-	sdio_al_logi(&sdio_al->gen_log, MODULE_NAME ": %s", __func__);
-
-	if (!sdio_al_dev) {
-		sdio_al_loge(sdio_al_dev->dev_log,
-			MODULE_NAME ": %s: NULL device", __func__);
-		return;
-	}
-	for (j = 0; j < SDIO_AL_MAX_CHANNELS; j++) {
-		ch = &sdio_al_dev->channel[j];
-
-		if (ch->state == SDIO_CHANNEL_STATE_OPEN) {
-			sdio_al_loge(sdio_al_dev->dev_log,
-				MODULE_NAME ": %s: Call to sdio_close() for"
-				" ch %s\n", __func__, ch->name);
-			ret = channel_close(ch, false);
-			if (ret) {
-				sdio_al_loge(sdio_al_dev->dev_log,
-					MODULE_NAME ": %s: failed sdio_close()"
-					" for ch %s (%d)\n",
-					__func__, ch->name, ret);
-			}
-		} else {
-			pr_debug(MODULE_NAME ": %s: skip sdio_close() ch %s"
-					" (state=%d)\n", __func__,
-					ch->name, ch->state);
-		}
-	}
-}
-
-static void sdio_al_invalidate_sdio_clients(struct sdio_al_device *sdio_al_dev,
-					    struct platform_device **pdev_arr)
-{
-	int j;
-
-	pr_debug(MODULE_NAME ": %s: Notifying SDIO clients for card %d",
-			__func__, sdio_al_dev->host->index);
-	for (j = 0; j < SDIO_AL_MAX_CHANNELS; ++j) {
-		if (sdio_al_dev->channel[j].state ==
-			SDIO_CHANNEL_STATE_INVALID)
-			continue;
-		pdev_arr[j] = sdio_al_dev->channel[j].pdev;
-		sdio_al_dev->channel[j].signature = 0x0;
-		sdio_al_dev->channel[j].state =
-			SDIO_CHANNEL_STATE_INVALID;
-	}
-}
-
-static void sdio_al_modem_reset_operations(struct sdio_al_device
-							*sdio_al_dev)
-{
-	int ret = 0;
-	struct platform_device *pdev_arr[SDIO_AL_MAX_CHANNELS];
-	int j;
-
-	sdio_al_logi(&sdio_al->gen_log, MODULE_NAME ": %s", __func__);
-
-	if (sdio_al_claim_mutex_and_verify_dev(sdio_al_dev, __func__))
-		return;
-
-	if (sdio_al_dev->state == CARD_REMOVED) {
-		sdio_al_logi(&sdio_al->gen_log, MODULE_NAME ": %s: "
-			"card %d is already removed", __func__,
-			sdio_al_dev->host->index);
-		goto exit_err;
-	}
-
-	if (sdio_al_dev->state == MODEM_RESTART) {
-		sdio_al_logi(sdio_al_dev->dev_log, MODULE_NAME ": %s: "
-			"card %d was already notified for modem reset",
-			__func__, sdio_al_dev->host->index);
-		goto exit_err;
-	}
-
-	sdio_al_logi(sdio_al_dev->dev_log, MODULE_NAME ": %s: Set the "
-		"state to MODEM_RESTART for card %d",
-		__func__, sdio_al_dev->host->index);
-	sdio_al_dev->state = MODEM_RESTART;
-	sdio_al_dev->is_ready = false;
-
-	/* Stop mailbox timer */
-	stop_and_del_timer(sdio_al_dev);
-
-	if ((sdio_al_dev->is_ok_to_sleep) &&
-	    (!sdio_al_dev->is_err)) {
-		pr_debug(MODULE_NAME ": %s: wakeup modem for "
-				    "card %d", __func__,
-			sdio_al_dev->host->index);
-		ret = sdio_al_wake_up(sdio_al_dev, 1, NULL);
-	}
-
-	if (!ret && (!sdio_al_dev->is_err) && sdio_al_dev->card &&
-		sdio_al_dev->card->sdio_func[0]) {
-			sdio_al_logi(sdio_al_dev->dev_log, MODULE_NAME
-			": %s: sdio_release_irq for card %d",
-			__func__,
-			sdio_al_dev->host->index);
-			sdio_release_irq(sdio_al_dev->card->sdio_func[0]);
-	}
-
-	memset(pdev_arr, 0, sizeof(pdev_arr));
-	sdio_al_invalidate_sdio_clients(sdio_al_dev, pdev_arr);
-
-	sdio_al_release_mutex(sdio_al_dev, __func__);
-
-	sdio_al_logi(&sdio_al->gen_log, MODULE_NAME ": %s: Notifying SDIO "
-						    "clients for card %d",
-			__func__, sdio_al_dev->host->index);
-	for (j = 0; j < SDIO_AL_MAX_CHANNELS; j++) {
-		if (!pdev_arr[j])
-			continue;
-		platform_device_unregister(pdev_arr[j]);
-	}
-	sdio_al_logi(&sdio_al->gen_log, MODULE_NAME ": %s: Finished Notifying "
-						    "SDIO clients for card %d",
-			__func__, sdio_al_dev->host->index);
-
-	return;
-
-exit_err:
-	sdio_al_release_mutex(sdio_al_dev, __func__);
-	return;
-}
-
-#ifdef CONFIG_MSM_SUBSYSTEM_RESTART
-static void sdio_al_reset(void)
-{
-	int i;
-	struct sdio_al_device *sdio_al_dev;
-
-	sdio_al_logi(&sdio_al->gen_log, MODULE_NAME ": %s", __func__);
-
-	for (i = 0; i < MAX_NUM_OF_SDIO_DEVICES; i++) {
-		if (sdio_al->devices[i] == NULL) {
-			pr_debug(MODULE_NAME ": %s: NULL device in index %d",
-					__func__, i);
-			continue;
-		}
-		sdio_al_dev = sdio_al->devices[i];
-		sdio_al_modem_reset_operations(sdio_al->devices[i]);
-	}
-
-	sdio_al_logi(&sdio_al->gen_log, MODULE_NAME ": %s completed", __func__);
-}
-#endif
-
-static void msm_sdio_al_shutdown(struct platform_device *pdev)
-{
-	int i;
-	struct sdio_al_device *sdio_al_dev;
-
-	sdio_al_logi(&sdio_al->gen_log, MODULE_NAME
-			"Initiating msm_sdio_al_shutdown...");
-
-	for (i = 0; i < MAX_NUM_OF_SDIO_DEVICES; i++) {
-		if (sdio_al->devices[i] == NULL) {
-			pr_debug(MODULE_NAME ": %s: NULL device in index %d",
-					__func__, i);
-			continue;
-		}
-		sdio_al_dev = sdio_al->devices[i];
-
-		if (sdio_al_claim_mutex_and_verify_dev(sdio_al_dev, __func__))
-			return;
-
-		if (sdio_al_dev->ch_close_supported)
-			sdio_al_close_all_channels(sdio_al_dev);
-
-		sdio_al_release_mutex(sdio_al_dev, __func__);
-
-		sdio_al_modem_reset_operations(sdio_al_dev);
-	}
-	sdio_al_logi(&sdio_al->gen_log, MODULE_NAME ": %s: "
-		"msm_sdio_al_shutdown complete.", __func__);
-}
-
-static struct platform_driver msm_sdio_al_driver = {
-	.probe          = msm_sdio_al_probe,
-	.remove         = __exit_p(msm_sdio_al_remove),
-	.shutdown	= msm_sdio_al_shutdown,
-	.driver         = {
-		.name   = "msm_sdio_al",
-	},
-};
-
-/**
- *  Initialize SDIO_AL channels.
- *
- */
-static int init_channels(struct sdio_al_device *sdio_al_dev)
-{
-	int ret = 0;
-	int i;
-
-	if (sdio_al_claim_mutex_and_verify_dev(sdio_al_dev, __func__))
-		return -ENODEV;
-
-	ret = read_sdioc_software_header(sdio_al_dev,
-					 sdio_al_dev->sdioc_sw_header);
-	if (ret)
-		goto exit;
-
-	ret = sdio_al_setup(sdio_al_dev);
-	if (ret)
-		goto exit;
-
-	for (i = 0; i < SDIO_AL_MAX_CHANNELS; i++) {
-		int ch_name_size;
-		if (sdio_al_dev->channel[i].state == SDIO_CHANNEL_STATE_INVALID)
-			continue;
-		if (sdio_al->unittest_mode) {
-			memset(sdio_al_dev->channel[i].ch_test_name, 0,
-				sizeof(sdio_al_dev->channel[i].ch_test_name));
-			ch_name_size = strnlen(sdio_al_dev->channel[i].name,
-				       CHANNEL_NAME_SIZE);
-			strncpy(sdio_al_dev->channel[i].ch_test_name,
-			       sdio_al_dev->channel[i].name,
-			       ch_name_size);
-			strncat(sdio_al_dev->channel[i].ch_test_name +
-			       ch_name_size,
-			       SDIO_TEST_POSTFIX,
-			       SDIO_TEST_POSTFIX_SIZE);
-			pr_debug(MODULE_NAME ":pdev.name = %s\n",
-				sdio_al_dev->channel[i].ch_test_name);
-			sdio_al_dev->channel[i].pdev = platform_device_alloc(
-				sdio_al_dev->channel[i].ch_test_name, -1);
-		} else {
-			pr_debug(MODULE_NAME ":pdev.name = %s\n",
-				sdio_al_dev->channel[i].name);
-			sdio_al_dev->channel[i].pdev = platform_device_alloc(
-				sdio_al_dev->channel[i].name, -1);
-		}
-		if (!sdio_al_dev->channel[i].pdev) {
-			sdio_al_loge(sdio_al_dev->dev_log, MODULE_NAME
-					":NULL platform device for ch %s",
-					sdio_al_dev->channel[i].name);
-			sdio_al_dev->channel[i].state =
-				SDIO_CHANNEL_STATE_INVALID;
-			continue;
-		}
-		ret = platform_device_add(sdio_al_dev->channel[i].pdev);
-		if (ret) {
-			sdio_al_loge(sdio_al_dev->dev_log, MODULE_NAME
-					":platform_device_add failed, "
-					"ret=%d\n", ret);
-			sdio_al_dev->channel[i].state =
-				SDIO_CHANNEL_STATE_INVALID;
-		}
-	}
-
-exit:
-	sdio_al_release_mutex(sdio_al_dev, __func__);
-	return ret;
-}
-
-/**
- *  Initialize SDIO_AL channels according to the client setup.
- *  This function also check if the client is in boot mode and
- *  flashless boot is required to be activated or the client is
- *  up and running.
- *
- */
-static int sdio_al_client_setup(struct sdio_al_device *sdio_al_dev)
-{
-	int ret = 0;
-	struct sdio_func *func1;
-	int signature = 0;
-
-	if (sdio_al_claim_mutex_and_verify_dev(sdio_al_dev, __func__))
-		return -ENODEV;
-
-	if (!sdio_al_dev->card || !sdio_al_dev->card->sdio_func[0]) {
-		sdio_al_loge(sdio_al_dev->dev_log, MODULE_NAME ":NULL card or "
-							       "func1\n");
-		sdio_al_release_mutex(sdio_al_dev, __func__);
-		return -ENODEV;
-	}
-	func1 = sdio_al_dev->card->sdio_func[0];
-
-	/* Read the header signature to determine the status of the MDM
-	 * SDIO Client
-	 */
-	signature = sdio_readl(func1, SDIOC_SW_HEADER_ADDR, &ret);
-	sdio_al_release_mutex(sdio_al_dev, __func__);
-	if (ret) {
-		sdio_al_loge(sdio_al_dev->dev_log, MODULE_NAME ":fail to read "
-				"signature from sw header.\n");
-		return ret;
-	}
-
-	switch (signature) {
-	case PEER_SDIOC_SW_MAILBOX_BOOT_SIGNATURE:
-		if (sdio_al_dev == sdio_al->bootloader_dev) {
-			sdio_al_logi(sdio_al_dev->dev_log, MODULE_NAME ":setup "
-					"bootloader on card %d\n",
-					sdio_al_dev->host->index);
-			return sdio_al_bootloader_setup();
-		} else {
-			sdio_al_logi(sdio_al_dev->dev_log, MODULE_NAME ":wait "
-					"for bootloader completion "
-					"on card %d\n",
-					sdio_al_dev->host->index);
-			return sdio_al_wait_for_bootloader_comp(sdio_al_dev);
-		}
-	case PEER_SDIOC_SW_MAILBOX_SIGNATURE:
-	case PEER_SDIOC_SW_MAILBOX_UT_SIGNATURE:
-		return init_channels(sdio_al_dev);
-	default:
-		sdio_al_loge(sdio_al_dev->dev_log, MODULE_NAME ":Invalid "
-				"signature 0x%x\n", signature);
-		return -EINVAL;
-	}
-
-	return 0;
-}
-
-static void clean_sdio_al_device_data(struct sdio_al_device *sdio_al_dev)
-{
-	sdio_al_dev->is_ready = 0;
-	sdio_al_dev->bootloader_done = 0;
-	sdio_al_dev->lpm_chan = 0;
-	sdio_al_dev->is_ok_to_sleep = 0;
-	sdio_al_dev->inactivity_time = 0;
-	sdio_al_dev->poll_delay_msec = 0;
-	sdio_al_dev->is_timer_initialized = 0;
-	sdio_al_dev->is_err = 0;
-	sdio_al_dev->is_suspended = 0;
-	sdio_al_dev->flashless_boot_on = 0;
-	sdio_al_dev->ch_close_supported = 0;
-	sdio_al_dev->print_after_interrupt = 0;
-	memset(sdio_al_dev->sdioc_sw_header, 0,
-	       sizeof(*sdio_al_dev->sdioc_sw_header));
-	memset(sdio_al_dev->mailbox, 0, sizeof(*sdio_al_dev->mailbox));
-	memset(sdio_al_dev->rx_flush_buf, 0,
-	       sizeof(*sdio_al_dev->rx_flush_buf));
-}
-
-/*
- * SDIO driver functions
- */
-static int sdio_al_sdio_probe(struct sdio_func *func,
-		const struct sdio_device_id *sdio_dev_id)
-{
-	int ret = 0;
-	struct sdio_al_device *sdio_al_dev = NULL;
-	int i;
-	struct mmc_card *card = NULL;
-
-	if (!func) {
-		sdio_al_loge(&sdio_al->gen_log, MODULE_NAME ": %s: NULL func\n",
-				__func__);
-		return -ENODEV;
-	}
-	card = func->card;
-
-	if (!card) {
-		sdio_al_loge(&sdio_al->gen_log, MODULE_NAME ": %s: NULL card\n",
-				__func__);
-		return -ENODEV;
-	}
-
-	if (!card->sdio_func[0]) {
-		sdio_al_loge(&sdio_al->gen_log, MODULE_NAME ": %s: NULL "
-							    "func1\n",
-				__func__);
-		return -ENODEV;
-	}
-
-	if (card->sdio_funcs < SDIO_AL_MAX_FUNCS) {
-		dev_info(&card->dev,
-			 "SDIO-functions# %d less than expected.\n",
-			 card->sdio_funcs);
-		return -ENODEV;
-	}
-
-	/* Check if there is already a device for this card */
-	for (i = 0; i < MAX_NUM_OF_SDIO_DEVICES; ++i) {
-		if (sdio_al->devices[i] == NULL)
-			continue;
-		if (sdio_al->devices[i]->host == card->host) {
-			sdio_al_dev = sdio_al->devices[i];
-			if (sdio_al_dev->state == CARD_INSERTED)
-				return 0;
-			clean_sdio_al_device_data(sdio_al_dev);
-			break;
-		}
-	}
-
-	if (!sdio_al_dev) {
-		sdio_al_dev = kzalloc(sizeof(struct sdio_al_device),
-				      GFP_KERNEL);
-		if (sdio_al_dev == NULL)
-			return -ENOMEM;
-
-		for (i = 0; i < MAX_NUM_OF_SDIO_DEVICES ; ++i)
-			if (sdio_al->devices[i] == NULL) {
-				sdio_al->devices[i] = sdio_al_dev;
-				sdio_al_dev->dev_log = &sdio_al->device_log[i];
-				spin_lock_init(&sdio_al_dev->dev_log->log_lock);
-	#ifdef CONFIG_DEBUG_FS
-				sdio_al_dbgfs_log[i].data =
-						sdio_al_dev->dev_log->buffer;
-				sdio_al_dbgfs_log[i].size =
-					SDIO_AL_DEBUG_LOG_SIZE;
-	#endif
-				break;
-			}
-		if (i == MAX_NUM_OF_SDIO_DEVICES) {
-			sdio_al_loge(&sdio_al->gen_log, MODULE_NAME ":No space "
-					"in devices array for the device\n");
-			return -ENOMEM;
-		}
-	}
-
-	dev_info(&card->dev, "SDIO Card claimed.\n");
-	sdio_al->skip_print_info = 0;
-
-	sdio_al_dev->state = CARD_INSERTED;
-
-	if (card->host->index == SDIO_BOOTLOADER_CARD_INDEX)
-		sdio_al->bootloader_dev = sdio_al_dev;
-
-	sdio_al_dev->is_ready = false;
-
-	sdio_al_dev->signature = SDIO_AL_SIGNATURE;
-
-	sdio_al_dev->is_suspended = 0;
-	sdio_al_dev->is_timer_initialized = false;
-
-	sdio_al_dev->lpm_chan = INVALID_SDIO_CHAN;
-
-	sdio_al_dev->card = card;
-	sdio_al_dev->host = card->host;
-
-	if (!sdio_al_dev->mailbox) {
-		sdio_al_dev->mailbox = kzalloc(sizeof(struct sdio_mailbox),
-					       GFP_KERNEL);
-		if (sdio_al_dev->mailbox == NULL)
-			return -ENOMEM;
-	}
-
-	if (!sdio_al_dev->sdioc_sw_header) {
-		sdio_al_dev->sdioc_sw_header
-			= kzalloc(sizeof(*sdio_al_dev->sdioc_sw_header),
-				  GFP_KERNEL);
-		if (sdio_al_dev->sdioc_sw_header == NULL)
-			return -ENOMEM;
-	}
-
-	if (!sdio_al_dev->rx_flush_buf) {
-		sdio_al_dev->rx_flush_buf = kzalloc(RX_FLUSH_BUFFER_SIZE,
-						    GFP_KERNEL);
-		if (sdio_al_dev->rx_flush_buf == NULL) {
-			sdio_al_loge(&sdio_al->gen_log,
-					MODULE_NAME ":Fail to allocate "
-					   "rx_flush_buf for card %d\n",
-			       card->host->index);
-			return -ENOMEM;
-		}
-	}
-
-	sdio_al_dev->timer.data = (unsigned long)sdio_al_dev;
-
-	wake_lock_init(&sdio_al_dev->wake_lock, WAKE_LOCK_SUSPEND, MODULE_NAME);
-	/* Don't allow sleep until all required clients register */
-	sdio_al_vote_for_sleep(sdio_al_dev, 0);
-
-	if (sdio_al_claim_mutex_and_verify_dev(sdio_al_dev, __func__))
-		return -ENODEV;
-
-	/* Init Func#1 */
-	ret = sdio_al_enable_func_retry(card->sdio_func[0], "Init Func#1");
-	if (ret) {
-		sdio_al_loge(sdio_al_dev->dev_log, MODULE_NAME ":Fail to "
-				"enable Func#%d\n", card->sdio_func[0]->num);
-		goto exit;
-	}
-
-	/* Patch Func CIS tuple issue */
-	ret = sdio_set_block_size(card->sdio_func[0], SDIO_AL_BLOCK_SIZE);
-	if (ret) {
-		sdio_al_loge(sdio_al_dev->dev_log, MODULE_NAME ":Fail to set "
-			"block size, Func#%d\n", card->sdio_func[0]->num);
-		goto exit;
-	}
-	sdio_al_dev->card->sdio_func[0]->max_blksize = SDIO_AL_BLOCK_SIZE;
-
-	sdio_al_dev->workqueue = create_singlethread_workqueue("sdio_al_wq");
-	sdio_al_dev->sdio_al_work.sdio_al_dev = sdio_al_dev;
-	init_waitqueue_head(&sdio_al_dev->wait_mbox);
-
-	ret = sdio_al_client_setup(sdio_al_dev);
-
-exit:
-	sdio_al_release_mutex(sdio_al_dev, __func__);
-	return ret;
-}
-
-static void sdio_al_sdio_remove(struct sdio_func *func)
-{
-	struct sdio_al_device *sdio_al_dev = NULL;
-	int i;
-	struct mmc_card *card = NULL;
-	struct platform_device *pdev_arr[SDIO_AL_MAX_CHANNELS];
-
-	if (!func) {
-		sdio_al_loge(&sdio_al->gen_log, MODULE_NAME ": %s: NULL func\n",
-				__func__);
-		return;
-	}
-	card = func->card;
-
-	if (!card) {
-		sdio_al_loge(&sdio_al->gen_log, MODULE_NAME ": %s: NULL card\n",
-				__func__);
-		return;
-	}
-
-	/* Find the sdio_al_device of this card */
-	for (i = 0; i < MAX_NUM_OF_SDIO_DEVICES; ++i) {
-		if (sdio_al->devices[i] == NULL)
-			continue;
-		if (sdio_al->devices[i]->card == card) {
-			sdio_al_dev = sdio_al->devices[i];
-			break;
-		}
-	}
-	if (sdio_al_dev == NULL) {
-		pr_debug(MODULE_NAME ":%s :NULL sdio_al_dev for card %d\n",
-				 __func__, card->host->index);
-		return;
-	}
-
-	if (sdio_al_claim_mutex(sdio_al_dev, __func__))
-		return;
-
-	if (sdio_al_dev->state == CARD_REMOVED) {
-		sdio_al_release_mutex(sdio_al_dev, __func__);
-		return;
-	}
-
-	if (!card->sdio_func[0]) {
-		sdio_al_loge(&sdio_al->gen_log, MODULE_NAME ": %s: NULL "
-						"func1\n", __func__);
-		sdio_al_release_mutex(sdio_al_dev, __func__);
-		return;
-	}
-
-	sdio_al_logi(&sdio_al->gen_log, MODULE_NAME ":%s for card %d\n",
-			 __func__, card->host->index);
-
-	sdio_al_dev->state = CARD_REMOVED;
-
-	memset(pdev_arr, 0, sizeof(pdev_arr));
-	sdio_al_invalidate_sdio_clients(sdio_al_dev, pdev_arr);
-
-	sdio_al_logi(&sdio_al->gen_log, MODULE_NAME ":%s: ask_reading_mailbox "
-			"for card %d\n", __func__, card->host->index);
-	sdio_al_dev->is_ready = false; /* Flag worker to exit */
-	sdio_al_dev->ask_mbox = false;
-	ask_reading_mailbox(sdio_al_dev); /* Wakeup worker */
-
-	stop_and_del_timer(sdio_al_dev);
-
-	sdio_al_release_mutex(sdio_al_dev, __func__);
-
-	sdio_al_logi(&sdio_al->gen_log, MODULE_NAME ": %s: Notifying SDIO "
-						    "clients for card %d",
-			__func__, sdio_al_dev->host->index);
-	for (i = 0; i < SDIO_AL_MAX_CHANNELS; i++) {
-		if (!pdev_arr[i])
-			continue;
-		platform_device_unregister(pdev_arr[i]);
-	}
-	sdio_al_logi(&sdio_al->gen_log, MODULE_NAME ": %s: Finished Notifying "
-						    "SDIO clients for card %d",
-			__func__, sdio_al_dev->host->index);
-
-	sdio_al_logi(&sdio_al->gen_log, MODULE_NAME ":%s: vote for sleep for "
-			"card %d\n", __func__, card->host->index);
-	sdio_al_vote_for_sleep(sdio_al_dev, 1);
-
-	sdio_al_logi(&sdio_al->gen_log, MODULE_NAME ":%s: flush_workqueue for "
-			"card %d\n", __func__, card->host->index);
-	flush_workqueue(sdio_al_dev->workqueue);
-	destroy_workqueue(sdio_al_dev->workqueue);
-	wake_lock_destroy(&sdio_al_dev->wake_lock);
-
-	sdio_al_logi(&sdio_al->gen_log, MODULE_NAME ":%s: sdio card %d removed."
-			"\n", __func__,	card->host->index);
-}
-
-static void sdio_print_mailbox(char *prefix_str, struct sdio_mailbox *mailbox)
-{
-	int k = 0;
-	char buf[256];
-	char buf1[10];
-
-	if (!mailbox) {
-		sdio_al_loge(&sdio_al->gen_log, MODULE_NAME ": mailbox is "
-				"NULL\n");
-		return;
-	}
-
-	sdio_al_loge(&sdio_al->gen_log, MODULE_NAME ": %s: pipes 0_7: eot=0x%x,"
-		" thresh=0x%x, overflow=0x%x, "
-		"underflow=0x%x, mask_thresh=0x%x\n",
-		 prefix_str, mailbox->eot_pipe_0_7,
-		 mailbox->thresh_above_limit_pipe_0_7,
-		 mailbox->overflow_pipe_0_7,
-		 mailbox->underflow_pipe_0_7,
-		 mailbox->mask_thresh_above_limit_pipe_0_7);
-
-	memset(buf, 0, sizeof(buf));
-	strncat(buf, ": bytes_avail:", sizeof(buf));
-
-	for (k = 0 ; k < SDIO_AL_ACTIVE_PIPES ; ++k) {
-		snprintf(buf1, sizeof(buf1), "%d, ",
-			 mailbox->pipe_bytes_avail[k]);
-		strncat(buf, buf1, sizeof(buf));
-	}
-
-	sdio_al_loge(&sdio_al->gen_log, MODULE_NAME "%s", buf);
-}
-
-static void sdio_al_print_info(void)
-{
-	int i = 0;
-	int j = 0;
-	int ret = 0;
-	struct sdio_mailbox *mailbox = NULL;
-	struct sdio_mailbox *hw_mailbox = NULL;
-	struct peer_sdioc_channel_config *ch_config = NULL;
-	struct sdio_func *func1 = NULL;
-	struct sdio_func *lpm_func = NULL;
-	int offset = 0;
-	int is_ok_to_sleep = 0;
-	char buf[50];
-
-	if (sdio_al->skip_print_info == 1)
-		return;
-
-	sdio_al->skip_print_info = 1;
-
-	sdio_al_loge(&sdio_al->gen_log, MODULE_NAME ": %s - SDIO DEBUG INFO\n",
-			__func__);
-
-	if (!sdio_al) {
-		sdio_al_loge(&sdio_al->gen_log, MODULE_NAME ": %s - ERROR - "
-				"sdio_al is NULL\n",  __func__);
-		return;
-	}
-
-	sdio_al_loge(&sdio_al->gen_log, MODULE_NAME ": GPIO mdm2ap_status=%d\n",
-				sdio_al->pdata->get_mdm2ap_status());
-
-	for (j = 0 ; j < MAX_NUM_OF_SDIO_DEVICES ; ++j) {
-		struct sdio_al_device *sdio_al_dev = sdio_al->devices[j];
-
-		if (sdio_al_dev == NULL) {
-			continue;
-		}
-
-		if (!sdio_al_dev->host) {
-			sdio_al_loge(sdio_al_dev->dev_log, MODULE_NAME ": Host"
-					" is NULL\n);");
-			continue;
-		}
-
-		snprintf(buf, sizeof(buf), "Card#%d: Shadow HW MB",
-		       sdio_al_dev->host->index);
-
-		/* printing Shadowing HW Mailbox*/
-		mailbox = sdio_al_dev->mailbox;
-		sdio_print_mailbox(buf, mailbox);
-
-		sdio_al_loge(sdio_al_dev->dev_log, MODULE_NAME ": Card#%d: "
-			"is_ok_to_sleep=%d\n",
-			sdio_al_dev->host->index,
-			sdio_al_dev->is_ok_to_sleep);
-
-
-		sdio_al_loge(sdio_al_dev->dev_log, MODULE_NAME ": Card#%d: "
-				   "Shadow channels SW MB:",
-		       sdio_al_dev->host->index);
-
-		/* printing Shadowing SW Mailbox per channel*/
-		for (i = 0 ; i < SDIO_AL_MAX_CHANNELS ; ++i) {
-			struct sdio_channel *ch = &sdio_al_dev->channel[i];
-
-			if (ch == NULL) {
-				continue;
-			}
-
-			if (ch->state == SDIO_CHANNEL_STATE_INVALID)
-				continue;
-
-			ch_config = &sdio_al_dev->channel[i].ch_config;
-
-			sdio_al_loge(sdio_al_dev->dev_log, MODULE_NAME
-				": Ch %s: max_rx_thres=0x%x, "
-				"max_tx_thres=0x%x, tx_buf=0x%x, "
-				"is_packet_mode=%d, "
-				"max_packet=0x%x, min_write=0x%x",
-				ch->name, ch_config->max_rx_threshold,
-				ch_config->max_tx_threshold,
-				ch_config->tx_buf_size,
-				ch_config->is_packet_mode,
-				ch_config->max_packet_size,
-				ch->min_write_avail);
-
-			sdio_al_loge(sdio_al_dev->dev_log, MODULE_NAME
-				": total_rx=0x%x, total_tx=0x%x, "
-				"read_avail=0x%x, write_avail=0x%x, "
-				"rx_pending=0x%x, num_reads=0x%x, "
-				"num_notifs=0x%x", ch->total_rx_bytes,
-				ch->total_tx_bytes, ch->read_avail,
-				ch->write_avail, ch->rx_pending_bytes,
-				ch->statistics.total_read_times,
-				ch->statistics.total_notifs);
-		} /* end loop over all channels */
-
-	} /* end loop over all devices */
-
-	/* reading from client and printing is_host_ok_to_sleep per device */
-	for (j = 0 ; j < MAX_NUM_OF_SDIO_DEVICES ; ++j) {
-		struct sdio_al_device *sdio_al_dev = sdio_al->devices[j];
-
-		if (sdio_al_verify_func1(sdio_al_dev, __func__))
-			continue;
-
-		if (!sdio_al_dev->host) {
-			sdio_al_loge(sdio_al_dev->dev_log, MODULE_NAME
-					": Host is NULL");
-			continue;
-		}
-
-		if (sdio_al_dev->lpm_chan == INVALID_SDIO_CHAN) {
-			sdio_al_loge(sdio_al_dev->dev_log, MODULE_NAME
-				": %s - for Card#%d, is lpm_chan=="
-				"INVALID_SDIO_CHAN. continuing...",
-				__func__, sdio_al_dev->host->index);
-			continue;
-		}
-
-		offset = offsetof(struct peer_sdioc_sw_mailbox, ch_config)+
-		sizeof(struct peer_sdioc_channel_config) *
-		sdio_al_dev->lpm_chan+
-		offsetof(struct peer_sdioc_channel_config, is_host_ok_to_sleep);
-
-		lpm_func = sdio_al_dev->card->sdio_func[sdio_al_dev->
-								lpm_chan+1];
-		if (!lpm_func) {
-			sdio_al_loge(sdio_al_dev->dev_log, MODULE_NAME
-					": %s - lpm_func is NULL for card#%d"
-					" continuing...\n", __func__,
-					sdio_al_dev->host->index);
-			continue;
-		}
-
-		if (sdio_al_claim_mutex_and_verify_dev(sdio_al_dev, __func__))
-			return;
-		ret  =  sdio_memcpy_fromio(lpm_func,
-					    &is_ok_to_sleep,
-					    SDIOC_SW_MAILBOX_ADDR+offset,
-					    sizeof(int));
-		sdio_al_release_mutex(sdio_al_dev, __func__);
-
-		if (ret)
-			sdio_al_loge(sdio_al_dev->dev_log, MODULE_NAME
-					": %s - fail to read "
-				"is_HOST_ok_to_sleep from mailbox for card %d",
-				__func__, sdio_al_dev->host->index);
-		else
-			sdio_al_loge(sdio_al_dev->dev_log, MODULE_NAME
-					": Card#%d: "
-				"is_HOST_ok_to_sleep=%d\n",
-				sdio_al_dev->host->index,
-				is_ok_to_sleep);
-	}
-
-	for (j = 0 ; j < MAX_NUM_OF_SDIO_DEVICES ; ++j) {
-		struct sdio_al_device *sdio_al_dev = sdio_al->devices[j];
-
-		if (!sdio_al_dev)
-			continue;
-
-		/* Reading HW Mailbox */
-		hw_mailbox = sdio_al_dev->mailbox;
-
-		if (sdio_al_claim_mutex_and_verify_dev(sdio_al_dev, __func__))
-			return;
-
-		if (!sdio_al_dev->card || !sdio_al_dev->card->sdio_func[0]) {
-			sdio_al_release_mutex(sdio_al_dev, __func__);
-			return;
-		}
-		func1 = sdio_al_dev->card->sdio_func[0];
-		ret = sdio_memcpy_fromio(func1, hw_mailbox,
-			HW_MAILBOX_ADDR, sizeof(*hw_mailbox));
-		sdio_al_release_mutex(sdio_al_dev, __func__);
-
-		if (ret) {
-			sdio_al_loge(sdio_al_dev->dev_log, MODULE_NAME
-					": fail to read "
-			       "mailbox for card#%d. "
-			       "continuing...\n",
-			       sdio_al_dev->host->index);
-			continue;
-		}
-
-		snprintf(buf, sizeof(buf), "Card#%d: Current HW MB",
-		       sdio_al_dev->host->index);
-
-		/* Printing HW Mailbox */
-		sdio_print_mailbox(buf, hw_mailbox);
-	}
-}
-
-static struct sdio_device_id sdio_al_sdioid[] = {
-    {.class = 0, .vendor = 0x70, .device = 0x2460},
-    {.class = 0, .vendor = 0x70, .device = 0x0460},
-    {.class = 0, .vendor = 0x70, .device = 0x23F1},
-    {.class = 0, .vendor = 0x70, .device = 0x23F0},
-    {}
-};
-
-static struct sdio_driver sdio_al_sdiofn_driver = {
-    .name      = "sdio_al_sdiofn",
-    .id_table  = sdio_al_sdioid,
-    .probe     = sdio_al_sdio_probe,
-    .remove    = sdio_al_sdio_remove,
-};
-
-#ifdef CONFIG_MSM_SUBSYSTEM_RESTART
-/*
- *  Callback for notifications from restart mudule.
- *  This function handles only the BEFORE_RESTART notification.
- *  Stop all the activity on the card and notify our clients.
- */
-static int sdio_al_subsys_notifier_cb(struct notifier_block *this,
-				  unsigned long notif_type,
-				  void *data)
-{
-	if (notif_type != SUBSYS_BEFORE_SHUTDOWN) {
-		sdio_al_logi(&sdio_al->gen_log, MODULE_NAME ": %s: got "
-				"notification %ld", __func__, notif_type);
-		return NOTIFY_DONE;
-	}
-
-	sdio_al_reset();
-	return NOTIFY_OK;
-}
-
-static struct notifier_block sdio_al_nb = {
-	.notifier_call = sdio_al_subsys_notifier_cb,
-};
-#endif
-
-/**
- *  Module Init.
- *
- *  @warn: allocate sdio_al context before registering driver.
- *
- */
-static int __init sdio_al_init(void)
-{
-	int ret = 0;
-	int i;
-
-	pr_debug(MODULE_NAME ":sdio_al_init\n");
-
-	pr_info(MODULE_NAME ":SDIO-AL SW version %s\n",
-		DRV_VERSION);
-
-	sdio_al = kzalloc(sizeof(struct sdio_al), GFP_KERNEL);
-	if (sdio_al == NULL)
-		return -ENOMEM;
-
-	for (i = 0; i < MAX_NUM_OF_SDIO_DEVICES ; ++i)
-		sdio_al->devices[i] = NULL;
-
-	sdio_al->unittest_mode = false;
-
-	sdio_al->debug.debug_lpm_on = debug_lpm_on;
-	sdio_al->debug.debug_data_on = debug_data_on;
-	sdio_al->debug.debug_close_on = debug_close_on;
-
-#ifdef CONFIG_DEBUG_FS
-	sdio_al_debugfs_init();
-#endif
-
-
-#ifdef CONFIG_MSM_SUBSYSTEM_RESTART
-	sdio_al->subsys_notif_handle = subsys_notif_register_notifier(
-		"external_modem", &sdio_al_nb);
-#endif
-
-	ret = platform_driver_register(&msm_sdio_al_driver);
-	if (ret) {
-		pr_err(MODULE_NAME ": platform_driver_register failed: %d\n",
-		       ret);
-		goto exit;
-	}
-
-	sdio_register_driver(&sdio_al_sdiofn_driver);
-
-	spin_lock_init(&sdio_al->gen_log.log_lock);
-
-exit:
-	if (ret)
-		kfree(sdio_al);
-	return ret;
-}
-
-/**
- *  Module Exit.
- *
- *  Free allocated memory.
- *  Disable SDIO-Card.
- *  Unregister driver.
- *
- */
-static void __exit sdio_al_exit(void)
-{
-	if (sdio_al == NULL)
-		return;
-
-	pr_debug(MODULE_NAME ":sdio_al_exit\n");
-
-#ifdef CONFIG_MSM_SUBSYSTEM_RESTART
-	subsys_notif_unregister_notifier(
-		sdio_al->subsys_notif_handle, &sdio_al_nb);
-#endif
-
-	sdio_al_tear_down();
-
-	sdio_unregister_driver(&sdio_al_sdiofn_driver);
-
-	kfree(sdio_al);
-
-#ifdef CONFIG_DEBUG_FS
-	sdio_al_debugfs_cleanup();
-#endif
-
-	platform_driver_unregister(&msm_sdio_al_driver);
-
-	pr_debug(MODULE_NAME ":sdio_al_exit complete\n");
-}
-
-module_init(sdio_al_init);
-module_exit(sdio_al_exit);
-
-MODULE_LICENSE("GPL v2");
-MODULE_DESCRIPTION("SDIO Abstraction Layer");
-MODULE_AUTHOR("Amir Samuelov <amirs@codeaurora.org>");
-MODULE_VERSION(DRV_VERSION);
-
diff --git a/arch/arm/mach-msm/sdio_al_dloader.c b/arch/arm/mach-msm/sdio_al_dloader.c
deleted file mode 100644
index 167c163..0000000
--- a/arch/arm/mach-msm/sdio_al_dloader.c
+++ /dev/null
@@ -1,2541 +0,0 @@
-/* Copyright (c) 2011-2012, The Linux Foundation. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 and
- * only version 2 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- */
-
-/*
- * SDIO-Downloader
- *
- * To be used with Qualcomm's SDIO-Client connected to this host.
- */
-
-/* INCLUDES */
-#include <linux/slab.h>
-#include <linux/module.h>
-#include <linux/delay.h>
-#include <linux/wakelock.h>
-#include <linux/mmc/card.h>
-#include <linux/dma-mapping.h>
-#include <mach/dma.h>
-#include <linux/mmc/sdio_func.h>
-#include "sdio_al_private.h"
-#include <linux/tty.h>
-#include <linux/tty_flip.h>
-#include <linux/kthread.h>
-#include <linux/version.h>
-#include <linux/errno.h>
-#include <linux/debugfs.h>
-
-/* DEFINES AND MACROS */
-#define MAX_NUM_DEVICES		1
-#define TTY_SDIO_DEV			"tty_sdio_0"
-#define TTY_SDIO_DEV_TEST		"tty_sdio_test_0"
-#define SDIOC_MAILBOX_ADDRESS		0
-#define SDIO_DL_BLOCK_SIZE		512
-#define SDIO_DL_MAIN_THREAD_NAME	"sdio_tty_main_thread"
-#define SDIOC_DL_BUFF_ADDRESS		0
-#define SDIOC_UP_BUFF_ADDRESS		0x4
-#define SDIOC_DL_BUFF_SIZE_OFFSET	0x8
-#define SDIOC_UP_BUFF_SIZE_OFFSET	0xC
-#define SDIOC_DL_WR_PTR		0x10
-#define SDIOC_DL_RD_PTR		0x14
-#define SDIOC_UL_WR_PTR		0x18
-#define SDIOC_UL_RD_PTR		0x1C
-#define SDIOC_EXIT_PTR			0x20
-#define SDIOC_OP_MODE_PTR		0x24
-#define SDIOC_PTRS_OFFSET		0x10
-#define SDIOC_PTR_REGS_SIZE		0x10
-#define SDIOC_CFG_REGS_SIZE		0x10
-#define WRITE_RETRIES			0xFFFFFFFF
-#define INPUT_SPEED			4800
-#define OUTPUT_SPEED			4800
-#define SDIOC_EXIT_CODE		0xDEADDEAD
-#define SLEEP_MS			10
-#define PRINTING_GAP			200
-#define TIMER_DURATION			10
-#define PUSH_TIMER_DURATION		5000
-#define MULTIPLE_RATIO			1
-#define MS_IN_SEC			1000
-#define BITS_IN_BYTE			8
-#define BYTES_IN_KB			1024
-#define WRITE_TILL_END_RETRIES		5
-#define SDIO_DLD_NORMAL_MODE_NAME	"SDIO DLD NORMAL MODE"
-#define SDIO_DLD_BOOT_TEST_MODE_NAME	"SDIO DLD BOOT TEST MODE"
-#define SDIO_DLD_AMSS_TEST_MODE_NAME	"SDIO DLD AMSS TEST MODE"
-#define TEST_NAME_MAX_SIZE		30
-#define PUSH_STRING
-#define SDIO_DLD_OUTGOING_BUFFER_SIZE	(48*1024*MULTIPLE_RATIO)
-
-/* FORWARD DECLARATIONS */
-static int sdio_dld_open(struct tty_struct *tty, struct file *file);
-static void sdio_dld_close(struct tty_struct *tty, struct file *file);
-static int sdio_dld_write_callback(struct tty_struct *tty,
-				   const unsigned char *buf, int count);
-static int sdio_dld_write_room(struct tty_struct *tty);
-static int sdio_dld_main_task(void *card);
-static void sdio_dld_print_info(void);
-#ifdef CONFIG_DEBUG_FS
-static int sdio_dld_debug_info_open(struct inode *inode, struct file *file);
-static ssize_t sdio_dld_debug_info_write(struct file *file,
-		const char __user *buf, size_t count, loff_t *ppos);
-#endif
-
-
-/* STRUCTURES AND TYPES */
-enum sdio_dld_op_mode {
-	 SDIO_DLD_NO_MODE = 0,
-	 SDIO_DLD_NORMAL_MODE = 1,
-	 SDIO_DLD_BOOT_TEST_MODE = 2,
-	 SDIO_DLD_AMSS_TEST_MODE = 3,
-	 SDIO_DLD_NUM_OF_MODES,
-};
-
-struct sdioc_reg_sequential_chunk_ptrs {
-	unsigned int dl_wr_ptr;
-	unsigned int dl_rd_ptr;
-	unsigned int up_wr_ptr;
-	unsigned int up_rd_ptr;
-};
-
-struct sdioc_reg_sequential_chunk_cfg {
-	unsigned int dl_buff_address;
-	unsigned int up_buff_address;
-	unsigned int dl_buff_size;
-	unsigned int ul_buff_size;
-};
-
-struct sdioc_reg {
-	unsigned int reg_val;
-	unsigned int reg_offset;
-};
-
-struct sdioc_reg_chunk {
-	struct sdioc_reg dl_buff_address;
-	struct sdioc_reg up_buff_address;
-	struct sdioc_reg dl_buff_size;
-	struct sdioc_reg ul_buff_size;
-	struct sdioc_reg dl_wr_ptr;
-	struct sdioc_reg dl_rd_ptr;
-	struct sdioc_reg up_wr_ptr;
-	struct sdioc_reg up_rd_ptr;
-	struct sdioc_reg good_to_exit_ptr;
-};
-
-struct sdio_data {
-	char *data;
-	int offset_read_p;
-	int offset_write_p;
-	int buffer_size;
-	int num_of_bytes_in_use;
-};
-
-struct sdio_dld_data {
-	struct sdioc_reg_chunk sdioc_reg;
-	struct sdio_data incoming_data;
-	struct sdio_data outgoing_data;
-};
-
-struct sdio_dld_wait_event {
-	wait_queue_head_t wait_event;
-	int wake_up_signal;
-};
-
-struct sdio_dld_task {
-	struct task_struct *dld_task;
-	const char *task_name;
-	struct sdio_dld_wait_event exit_wait;
-	atomic_t please_close;
-};
-
-#ifdef CONFIG_DEBUG_FS
-struct sdio_dloader_debug {
-	struct dentry *sdio_dld_debug_root;
-	struct dentry *sdio_al_dloader;
-};
-
-const struct file_operations sdio_dld_debug_info_ops = {
-	.open = sdio_dld_debug_info_open,
-	.write = sdio_dld_debug_info_write,
-};
-#endif
-
-struct sdio_downloader {
-	int sdioc_boot_func;
-	struct sdio_dld_wait_event write_callback_event;
-	struct sdio_dld_task dld_main_thread;
-	struct tty_driver *tty_drv;
-	struct tty_struct *tty_str;
-	struct sdio_dld_data sdio_dloader_data;
-	struct mmc_card *card;
-	int(*done_callback)(void);
-	struct sdio_dld_wait_event main_loop_event;
-	struct timer_list timer;
-	unsigned int poll_ms;
-	struct timer_list push_timer;
-	unsigned int push_timer_ms;
-	enum sdio_dld_op_mode op_mode;
-	char op_mode_name[TEST_NAME_MAX_SIZE];
-};
-
-struct sdio_dld_global_info {
-	int global_bytes_write_toio;
-	int global_bytes_write_tty;
-	int global_bytes_read_fromio;
-	int global_bytes_push_tty;
-	u64 start_time;
-	u64 end_time;
-	u64 delta_jiffies;
-	unsigned int time_msec;
-	unsigned int throughput;
-	int cl_dl_wr_ptr;
-	int cl_dl_rd_ptr;
-	int cl_up_wr_ptr;
-	int cl_up_rd_ptr;
-	int host_read_ptr;
-	int host_write_ptr;
-	int cl_dl_buffer_size;
-	int cl_up_buffer_size;
-	int host_outgoing_buffer_size;
-	int cl_dl_buffer_address;
-	int cl_up_buffer_address;
-};
-
-static const struct tty_operations sdio_dloader_tty_ops = {
-	.open = sdio_dld_open,
-	.close = sdio_dld_close,
-	.write = sdio_dld_write_callback,
-	.write_room = sdio_dld_write_room,
-};
-
-/* GLOBAL VARIABLES */
-struct sdio_downloader *sdio_dld;
-struct sdio_dld_global_info sdio_dld_info;
-static char outgoing_data_buffer[SDIO_DLD_OUTGOING_BUFFER_SIZE];
-
-static DEFINE_SPINLOCK(lock1);
-static unsigned long lock_flags1;
-static DEFINE_SPINLOCK(lock2);
-static unsigned long lock_flags2;
-
-/*
- * sdio_op_mode sets the operation mode of the sdio_dloader -
- * it may be in NORMAL_MODE, BOOT_TEST_MODE or AMSS_TEST_MODE
- */
-static int sdio_op_mode = (int)SDIO_DLD_NORMAL_MODE;
-module_param(sdio_op_mode, int, 0);
-
-#ifdef CONFIG_DEBUG_FS
-
-struct sdio_dloader_debug sdio_dld_debug;
-
-#define ARR_SIZE 30000
-#define SDIO_DLD_DEBUGFS_INIT_VALUE	87654321
-#define SDIO_DLD_DEBUGFS_CASE_1_CODE	11111111
-#define SDIO_DLD_DEBUGFS_CASE_2_CODE	22222222
-#define SDIO_DLD_DEBUGFS_CASE_3_CODE	33333333
-#define SDIO_DLD_DEBUGFS_CASE_4_CODE	44444444
-#define SDIO_DLD_DEBUGFS_CASE_5_CODE	55555555
-#define SDIO_DLD_DEBUGFS_CASE_6_CODE	66666666
-#define SDIO_DLD_DEBUGFS_CASE_7_CODE	77777777
-#define SDIO_DLD_DEBUGFS_CASE_8_CODE	88888888
-#define SDIO_DLD_DEBUGFS_CASE_9_CODE	99999999
-#define SDIO_DLD_DEBUGFS_CASE_10_CODE	10101010
-#define SDIO_DLD_DEBUGFS_CASE_11_CODE	11001100
-#define SDIO_DLD_DEBUGFS_CASE_12_CODE	12001200
-#define SDIO_DLD_DEBUGFS_LOOP_WAIT	7
-#define SDIO_DLD_DEBUGFS_LOOP_WAKEUP	8
-#define SDIO_DLD_DEBUGFS_CB_WAIT	3
-#define SDIO_DLD_DEBUGFS_CB_WAKEUP	4
-
-static int curr_index;
-struct ptrs {
-	int h_w_ptr;
-	int h_r_ptr;
-	int c_u_w_ptr;
-	int c_u_r_ptr;
-	int code;
-	int h_has_to_send;
-	int c_has_to_receive;
-	int min_of;
-	int reserve2;
-	int tty_count;
-	int write_tty;
-	int write_toio;
-	int loop_wait_wake;
-	int cb_wait_wake;
-	int c_d_w_ptr;
-	int c_d_r_ptr;
-	int to_read;
-	int push_to_tty;
-	int global_tty_send;
-	int global_sdio_send;
-	int global_tty_received;
-	int global_sdio_received;
-	int reserve22;
-	int reserve23;
-	int reserve24;
-	int reserve25;
-	int reserve26;
-	int reserve27;
-	int reserve28;
-	int reserve29;
-	int reserve30;
-	int reserve31;
-};
-
-struct global_data {
-	int curr_i;
-	int duration_ms;
-	int global_bytes_sent;
-	int throughput_Mbs;
-	int host_outgoing_buffer_size_KB;
-	int client_up_buffer_size_KB;
-	int client_dl_buffer_size_KB;
-	int client_dl_buffer_address;
-	int client_up_buffer_address;
-	int global_bytes_received;
-	int global_bytes_pushed;
-	int reserve11;
-	int reserve12;
-	int reserve13;
-	int reserve14;
-	int reserve15;
-	int reserve16;
-	int reserve17;
-	int reserve18;
-	int reserve19;
-	int reserve20;
-	int reserve21;
-	int reserve22;
-	int reserve23;
-	int reserve24;
-	int reserve25;
-	int reserve26;
-	int reserve27;
-	int reserve28;
-	int reserve29;
-	int reserve30;
-	int reserve31;
-	struct ptrs ptr_array[ARR_SIZE];
-};
-
-static struct global_data gd;
-static struct debugfs_blob_wrapper blob;
-static struct dentry *root;
-static struct dentry *dld;
-
-struct debugfs_global {
-	int global_8k_has;
-	int global_9k_has;
-	int global_min;
-	int global_count;
-	int global_write_tty;
-	int global_write_toio;
-	int global_bytes_cb_tty;
-	int global_to_read;
-	int global_push_to_tty;
-	int global_tty_send;
-	int global_sdio_send;
-	int global_sdio_received;
-	int global_tty_push;
-};
-
-static struct debugfs_global debugfs_glob;
-
-static void update_standard_fields(int index)
-{
-
-	gd.ptr_array[index].global_tty_send =
-		sdio_dld_info.global_bytes_write_tty;
-	gd.ptr_array[index].global_sdio_send =
-		sdio_dld_info.global_bytes_write_toio;
-	gd.ptr_array[index].global_tty_received =
-		sdio_dld_info.global_bytes_push_tty;
-	gd.ptr_array[index].global_sdio_received =
-		sdio_dld_info.global_bytes_read_fromio;
-}
-
-static void update_gd(int code)
-{
-	struct sdioc_reg_chunk *reg_str =
-					&sdio_dld->sdio_dloader_data.sdioc_reg;
-	struct sdio_data *outgoing = &sdio_dld->sdio_dloader_data.outgoing_data;
-	int index = curr_index%ARR_SIZE;
-
-	gd.curr_i = curr_index;
-	gd.duration_ms = 0;
-	gd.global_bytes_sent = 0;
-	gd.throughput_Mbs = 0;
-	gd.host_outgoing_buffer_size_KB = 0;
-	gd.client_up_buffer_size_KB = 0;
-	gd.client_dl_buffer_size_KB = 0;
-	gd.client_dl_buffer_address = 0;
-	gd.client_up_buffer_address = 0;
-	gd.global_bytes_received = 0;
-	gd.global_bytes_pushed = 0;
-	gd.reserve11 = 0;
-	gd.reserve12 = 0;
-	gd.reserve13 = 0;
-	gd.reserve14 = 0;
-	gd.reserve15 = 0;
-	gd.reserve16 = 0;
-	gd.reserve17 = 0;
-	gd.reserve18 = 0;
-	gd.reserve19 = 0;
-	gd.reserve20 = 0;
-	gd.reserve21 = 0;
-	gd.reserve22 = 0;
-	gd.reserve23 = 0;
-	gd.reserve24 = 0;
-	gd.reserve25 = 0;
-	gd.reserve26 = 0;
-	gd.reserve27 = 0;
-	gd.reserve28 = 0;
-	gd.reserve29 = 0;
-	gd.reserve30 = 0;
-	gd.reserve31 = 0;
-
-	gd.ptr_array[index].h_w_ptr = SDIO_DLD_DEBUGFS_INIT_VALUE;	/*0*/
-	gd.ptr_array[index].h_r_ptr = SDIO_DLD_DEBUGFS_INIT_VALUE;	/*1*/
-	gd.ptr_array[index].c_u_w_ptr =	SDIO_DLD_DEBUGFS_INIT_VALUE;	/*2*/
-	gd.ptr_array[index].c_u_r_ptr =	SDIO_DLD_DEBUGFS_INIT_VALUE;	/*3*/
-	gd.ptr_array[index].code = SDIO_DLD_DEBUGFS_INIT_VALUE;		/*4*/
-	gd.ptr_array[index].h_has_to_send = SDIO_DLD_DEBUGFS_INIT_VALUE;/*5*/
-	gd.ptr_array[index].c_has_to_receive =
-		SDIO_DLD_DEBUGFS_INIT_VALUE;				/*6*/
-	gd.ptr_array[index].min_of = SDIO_DLD_DEBUGFS_INIT_VALUE;	/*7*/
-	gd.ptr_array[index].reserve2 = SDIO_DLD_DEBUGFS_INIT_VALUE;	/*8*/
-	gd.ptr_array[index].tty_count = SDIO_DLD_DEBUGFS_INIT_VALUE;	/*9*/
-	gd.ptr_array[index].write_tty = SDIO_DLD_DEBUGFS_INIT_VALUE;	/*A*/
-	gd.ptr_array[index].write_toio = SDIO_DLD_DEBUGFS_INIT_VALUE;	/*B*/
-	gd.ptr_array[index].loop_wait_wake =
-		SDIO_DLD_DEBUGFS_INIT_VALUE;				/*C*/
-	gd.ptr_array[index].cb_wait_wake = SDIO_DLD_DEBUGFS_INIT_VALUE;	/*D*/
-	gd.ptr_array[index].c_d_w_ptr =	SDIO_DLD_DEBUGFS_INIT_VALUE;	/*E*/
-	gd.ptr_array[index].c_d_r_ptr =	SDIO_DLD_DEBUGFS_INIT_VALUE;	/*F*/
-	gd.ptr_array[index].to_read =
-		SDIO_DLD_DEBUGFS_INIT_VALUE;			/*0x10*/
-	gd.ptr_array[index].push_to_tty =
-		SDIO_DLD_DEBUGFS_INIT_VALUE;			/*0x11*/
-	gd.ptr_array[index].global_tty_send =
-		SDIO_DLD_DEBUGFS_INIT_VALUE;			/*0x12*/
-	gd.ptr_array[index].global_sdio_send =
-		SDIO_DLD_DEBUGFS_INIT_VALUE;			/*0x13*/
-	gd.ptr_array[index].global_tty_received =
-		SDIO_DLD_DEBUGFS_INIT_VALUE;			/*0x14*/
-	gd.ptr_array[index].global_sdio_received =
-		SDIO_DLD_DEBUGFS_INIT_VALUE;			/*0x15*/
-	gd.ptr_array[index].reserve22 = SDIO_DLD_DEBUGFS_INIT_VALUE;
-	gd.ptr_array[index].reserve23 = SDIO_DLD_DEBUGFS_INIT_VALUE;
-	gd.ptr_array[index].reserve24 = SDIO_DLD_DEBUGFS_INIT_VALUE;
-	gd.ptr_array[index].reserve25 = SDIO_DLD_DEBUGFS_INIT_VALUE;
-	gd.ptr_array[index].reserve26 = SDIO_DLD_DEBUGFS_INIT_VALUE;
-	gd.ptr_array[index].reserve27 = SDIO_DLD_DEBUGFS_INIT_VALUE;
-	gd.ptr_array[index].reserve28 = SDIO_DLD_DEBUGFS_INIT_VALUE;
-	gd.ptr_array[index].reserve29 = SDIO_DLD_DEBUGFS_INIT_VALUE;
-	gd.ptr_array[index].reserve30 = SDIO_DLD_DEBUGFS_INIT_VALUE;
-	gd.ptr_array[index].reserve31 = SDIO_DLD_DEBUGFS_INIT_VALUE;
-
-	switch (code) {
-	case SDIO_DLD_DEBUGFS_CASE_1_CODE:
-		gd.ptr_array[index].code = SDIO_DLD_DEBUGFS_CASE_1_CODE;
-		gd.ptr_array[index].h_w_ptr = outgoing->offset_write_p;
-		gd.ptr_array[index].h_r_ptr = outgoing->offset_read_p;
-		gd.ptr_array[index].c_u_w_ptr =	reg_str->up_wr_ptr.reg_val;
-		gd.ptr_array[index].c_u_r_ptr =	reg_str->up_rd_ptr.reg_val;
-		gd.ptr_array[index].c_d_w_ptr =	reg_str->dl_wr_ptr.reg_val;
-		gd.ptr_array[index].c_d_r_ptr =	reg_str->dl_rd_ptr.reg_val;
-		break;
-
-	case SDIO_DLD_DEBUGFS_CASE_2_CODE:
-		gd.ptr_array[index].code = SDIO_DLD_DEBUGFS_CASE_2_CODE;
-		gd.ptr_array[index].c_u_r_ptr = reg_str->up_rd_ptr.reg_val;
-		gd.ptr_array[index].c_u_w_ptr = reg_str->up_wr_ptr.reg_val;
-		gd.ptr_array[index].h_has_to_send = debugfs_glob.global_8k_has;
-		gd.ptr_array[index].c_has_to_receive =
-			debugfs_glob.global_9k_has;
-		gd.ptr_array[index].min_of = debugfs_glob.global_min;
-		break;
-
-	case SDIO_DLD_DEBUGFS_CASE_3_CODE:
-		gd.ptr_array[index].code = SDIO_DLD_DEBUGFS_CASE_3_CODE;
-		gd.ptr_array[index].h_w_ptr = outgoing->offset_write_p;
-		gd.ptr_array[index].h_r_ptr = outgoing->offset_read_p;
-		gd.ptr_array[index].write_tty = debugfs_glob.global_write_tty;
-		break;
-
-	case SDIO_DLD_DEBUGFS_CASE_4_CODE:
-		gd.ptr_array[index].code = SDIO_DLD_DEBUGFS_CASE_4_CODE;
-		gd.ptr_array[index].h_w_ptr = outgoing->offset_write_p;
-		gd.ptr_array[index].h_r_ptr = outgoing->offset_read_p;
-		gd.ptr_array[index].c_u_r_ptr = reg_str->up_rd_ptr.reg_val;
-		gd.ptr_array[index].c_u_w_ptr = reg_str->up_wr_ptr.reg_val;
-		gd.ptr_array[index].write_toio =
-			debugfs_glob.global_write_toio;
-		break;
-
-	case SDIO_DLD_DEBUGFS_CASE_5_CODE:
-		gd.ptr_array[index].code = SDIO_DLD_DEBUGFS_CASE_5_CODE;
-		gd.ptr_array[index].tty_count = debugfs_glob.global_count;
-		break;
-
-	case SDIO_DLD_DEBUGFS_CASE_6_CODE:
-		gd.ptr_array[index].code = SDIO_DLD_DEBUGFS_CASE_6_CODE;
-		gd.ptr_array[index].loop_wait_wake = 7;
-		break;
-
-	case SDIO_DLD_DEBUGFS_CASE_7_CODE:
-		gd.ptr_array[index].code = SDIO_DLD_DEBUGFS_CASE_7_CODE;
-		gd.ptr_array[index].loop_wait_wake = 8;
-		break;
-
-	case SDIO_DLD_DEBUGFS_CASE_8_CODE:
-		gd.ptr_array[index].code = SDIO_DLD_DEBUGFS_CASE_8_CODE;
-		gd.ptr_array[index].cb_wait_wake = 3;
-		break;
-
-	case SDIO_DLD_DEBUGFS_CASE_9_CODE:
-		gd.ptr_array[index].code = SDIO_DLD_DEBUGFS_CASE_9_CODE;
-		gd.ptr_array[index].cb_wait_wake = 4;
-		break;
-
-	case SDIO_DLD_DEBUGFS_CASE_10_CODE:
-		gd.ptr_array[index].code = SDIO_DLD_DEBUGFS_CASE_10_CODE;
-		gd.ptr_array[index].cb_wait_wake =
-			debugfs_glob.global_bytes_cb_tty;
-		break;
-
-	case SDIO_DLD_DEBUGFS_CASE_11_CODE:
-		gd.ptr_array[index].code = SDIO_DLD_DEBUGFS_CASE_11_CODE;
-		gd.ptr_array[index].to_read = debugfs_glob.global_to_read;
-		break;
-
-	case SDIO_DLD_DEBUGFS_CASE_12_CODE:
-		gd.ptr_array[index].code = SDIO_DLD_DEBUGFS_CASE_12_CODE;
-		gd.ptr_array[index].push_to_tty =
-			debugfs_glob.global_push_to_tty;
-		break;
-
-	default:
-		break;
-	}
-	update_standard_fields(index);
-	curr_index++;
-}
-
-static int bootloader_debugfs_init(void)
-{
-	/* /sys/kernel/debug/bootloader there will be dld_arr file */
-	root = debugfs_create_dir("bootloader", NULL);
-	if (!root) {
-		pr_info(MODULE_NAME ": %s - creating root dir "
-			"failed\n", __func__);
-		return -ENODEV;
-	}
-
-	blob.data = &gd;
-	blob.size = sizeof(struct global_data);
-	dld = debugfs_create_blob("dld_arr", S_IRUGO, root, &blob);
-	if (!dld) {
-		debugfs_remove_recursive(root);
-		pr_err(MODULE_NAME ": %s, failed to create debugfs entry\n",
-		       __func__);
-		return -ENODEV;
-	}
-
-	return 0;
-}
-
-/*
-* for triggering the sdio_dld info use:
-* echo 1 > /sys/kernel/debug/sdio_al_dld/sdio_al_dloader_info
-*/
-static int sdio_dld_debug_init(void)
-{
-	sdio_dld_debug.sdio_dld_debug_root =
-				debugfs_create_dir("sdio_al_dld", NULL);
-	if (!sdio_dld_debug.sdio_dld_debug_root) {
-		pr_err(MODULE_NAME ": %s - Failed to create folder. "
-		       "sdio_dld_debug_root is NULL",
-		       __func__);
-		return -ENOENT;
-	}
-
-	sdio_dld_debug.sdio_al_dloader = debugfs_create_file(
-					"sdio_al_dloader_info",
-					S_IRUGO | S_IWUGO,
-					sdio_dld_debug.sdio_dld_debug_root,
-					NULL,
-					&sdio_dld_debug_info_ops);
-
-	if (!sdio_dld_debug.sdio_al_dloader) {
-		pr_err(MODULE_NAME ": %s - Failed to create a file. "
-		       "sdio_al_dloader is NULL",
-		       __func__);
-		debugfs_remove(sdio_dld_debug.sdio_dld_debug_root);
-		sdio_dld_debug.sdio_dld_debug_root = NULL;
-		return -ENOENT;
-	}
-
-	return 0;
-}
-
-static int sdio_dld_debug_info_open(struct inode *inode, struct file *file)
-{
-	file->private_data = inode->i_private;
-	return 0;
-}
-
-static ssize_t sdio_dld_debug_info_write(struct file *file,
-		const char __user *buf, size_t count, loff_t *ppos)
-{
-	sdio_dld_print_info();
-	return count;
-}
-#endif /* CONFIG_DEBUG_FS */
-
-static void sdio_dld_print_info(void)
-{
-
-	sdio_dld_info.end_time = get_jiffies_64(); /* read the current time */
-	sdio_dld_info.delta_jiffies =
-		sdio_dld_info.end_time - sdio_dld_info.start_time;
-	sdio_dld_info.time_msec = jiffies_to_msecs(sdio_dld_info.delta_jiffies);
-
-	sdio_dld_info.throughput = sdio_dld_info.global_bytes_write_toio *
-		BITS_IN_BYTE / sdio_dld_info.time_msec;
-	sdio_dld_info.throughput /= MS_IN_SEC;
-
-	pr_info(MODULE_NAME ": %s, FLASHLESS BOOT - DURATION IN MSEC = %d\n",
-		__func__,
-		sdio_dld_info.time_msec);
-
-	pr_info(MODULE_NAME ": %s, FLASHLESS BOOT - BYTES WRITTEN ON SDIO BUS "
-			    "= %d...BYTES SENT BY TTY = %d",
-		__func__,
-	       sdio_dld_info.global_bytes_write_toio,
-	       sdio_dld_info.global_bytes_write_tty);
-
-	pr_info(MODULE_NAME ": %s, FLASHLESS BOOT - BYTES RECEIVED ON SDIO BUS "
-			    "= %d...BYTES SENT TO TTY = %d",
-		__func__,
-		sdio_dld_info.global_bytes_read_fromio,
-		sdio_dld_info.global_bytes_push_tty);
-
-	pr_info(MODULE_NAME ": %s, FLASHLESS BOOT - THROUGHPUT=%d Mbit/Sec",
-		__func__, sdio_dld_info.throughput);
-
-	pr_info(MODULE_NAME ": %s, FLASHLESS BOOT - CLIENT DL_BUFFER_SIZE=%d"
-		" KB..CLIENT UL_BUFFER=%d KB\n",
-		__func__,
-		sdio_dld_info.cl_dl_buffer_size/BYTES_IN_KB,
-		sdio_dld_info.cl_up_buffer_size/BYTES_IN_KB);
-
-	pr_info(MODULE_NAME ": %s, FLASHLESS BOOT - HOST OUTGOING BUFFER_SIZE"
-			    "=%d KB",
-		__func__,
-		sdio_dld_info.host_outgoing_buffer_size/BYTES_IN_KB);
-
-	pr_info(MODULE_NAME ": %s, FLASHLESS BOOT - CLIENT DL BUFFER "
-		 "ADDRESS = 0x%x", __func__,
-		sdio_dld_info.cl_dl_buffer_address);
-
-	pr_info(MODULE_NAME ": %s, FLASHLESS BOOT - CLIENT UP BUFFER "
-		"ADDRESS = 0x%x",
-		__func__,
-		sdio_dld_info.cl_up_buffer_address);
-
-	pr_info(MODULE_NAME ": %s, FLASHLESS BOOT - CLIENT - UPLINK BUFFER - "
-		"READ POINTER = %d", __func__,
-		sdio_dld_info.cl_up_rd_ptr);
-
-	pr_info(MODULE_NAME ": %s, FLASHLESS BOOT - CLIENT - UPLINK BUFFER - "
-		"WRITE POINTER = %d", __func__,
-		sdio_dld_info.cl_up_wr_ptr);
-
-	pr_info(MODULE_NAME ": %s, FLASHLESS BOOT - CLIENT - DOWNLINK BUFFER - "
-		"READ POINTER = %d", __func__,
-		sdio_dld_info.cl_dl_rd_ptr);
-
-	pr_info(MODULE_NAME ": %s, FLASHLESS BOOT - CLIENT - DOWNLINK BUFFER - "
-		"WRITE POINTER = %d", __func__,
-		sdio_dld_info.cl_dl_wr_ptr);
-
-	pr_info(MODULE_NAME ": %s, FLASHLESS BOOT - HOST - OUTGOING BUFFER - "
-		"READ POINTER = %d", __func__,
-		sdio_dld_info.host_read_ptr);
-
-	pr_info(MODULE_NAME ": %s, FLASHLESS BOOT - HOST - OUTGOING BUFFER - "
-		"WRITE POINTER = %d", __func__,
-		sdio_dld_info.host_write_ptr);
-
-	pr_info(MODULE_NAME ": %s, FLASHLESS BOOT - END DEBUG INFO", __func__);
-}
-
-/**
-  * sdio_dld_set_op_mode
-  * sets the op_mode and the name of the op_mode. Also, in case
-  * it's invalid mode sets op_mode to SDIO_DLD_NORMAL_MODE
-  *
-  * @op_mode: the operation mode to be set
-  * @return NONE
-  */
-static void sdio_dld_set_op_mode(enum sdio_dld_op_mode op_mode)
-{
-	sdio_dld->op_mode = op_mode;
-
-	switch (op_mode) {
-	case SDIO_DLD_NORMAL_MODE:
-		memcpy(sdio_dld->op_mode_name,
-		       SDIO_DLD_NORMAL_MODE_NAME, TEST_NAME_MAX_SIZE);
-		break;
-	case SDIO_DLD_BOOT_TEST_MODE:
-		memcpy(sdio_dld->op_mode_name,
-		       SDIO_DLD_BOOT_TEST_MODE_NAME, TEST_NAME_MAX_SIZE);
-		break;
-	case SDIO_DLD_AMSS_TEST_MODE:
-		memcpy(sdio_dld->op_mode_name,
-		       SDIO_DLD_AMSS_TEST_MODE_NAME, TEST_NAME_MAX_SIZE);
-		break;
-	default:
-		sdio_dld->op_mode = SDIO_DLD_NORMAL_MODE;
-		pr_err(MODULE_NAME ": %s - Invalid Op_Mode = %d. Settings "
-		       "Op_Mode to default - NORMAL_MODE\n",
-		       __func__, op_mode);
-		memcpy(sdio_dld->op_mode_name,
-		       SDIO_DLD_NORMAL_MODE_NAME, TEST_NAME_MAX_SIZE);
-		break;
-	}
-
-	if (sdio_dld->op_mode_name != NULL) {
-		pr_info(MODULE_NAME ": %s - FLASHLESS BOOT - Op_Mode is set to "
-			"%s\n", __func__, sdio_dld->op_mode_name);
-	} else {
-		pr_info(MODULE_NAME ": %s - FLASHLESS BOOT - op_mode_name is "
-			"NULL\n", __func__);
-	}
-}
-
-/**
-  * sdio_dld_allocate_local_buffers
-  * allocates local outgoing and incoming buffers and also sets
-  * threshold for outgoing data.
-  *
-  * @return 0 on success or negative value on error.
-  */
-static int sdio_dld_allocate_local_buffers(void)
-{
-	struct sdioc_reg_chunk *reg_str = &sdio_dld->sdio_dloader_data.
-		sdioc_reg;
-	struct sdio_data *outgoing = &sdio_dld->sdio_dloader_data.outgoing_data;
-	struct sdio_data *incoming = &sdio_dld->sdio_dloader_data.incoming_data;
-
-	incoming->data =
-		kzalloc(reg_str->dl_buff_size.reg_val, GFP_KERNEL);
-
-	if (!incoming->data) {
-		pr_err(MODULE_NAME ": %s - param ""incoming->data"" is NULL. "
-		       "Couldn't allocate incoming_data local buffer\n",
-		       __func__);
-		return -ENOMEM;
-	}
-
-	incoming->buffer_size = reg_str->dl_buff_size.reg_val;
-
-	outgoing->data = outgoing_data_buffer;
-
-	outgoing->buffer_size = SDIO_DLD_OUTGOING_BUFFER_SIZE;
-
-	if (outgoing->buffer_size !=
-	    reg_str->ul_buff_size.reg_val*MULTIPLE_RATIO) {
-		pr_err(MODULE_NAME ": %s - HOST outgoing buffer size (%d bytes)"
-		       "must be a multiple of ClIENT uplink buffer size (%d "
-		       "bytes). HOST_SIZE == n*CLIENT_SIZE.(n=1,2,3...)\n",
-		       __func__,
-		       SDIO_DLD_OUTGOING_BUFFER_SIZE,
-		       reg_str->ul_buff_size.reg_val);
-		kfree(incoming->data);
-		return -EINVAL;
-	}
-
-	/* keep sdio_dld_info up to date */
-	sdio_dld_info.host_outgoing_buffer_size = outgoing->buffer_size;
-
-	return 0;
-}
-
-/**
-  * sdio_dld_dealloc_local_buffers frees incoming and outgoing
-  * buffers.
-  *
-  * @return None.
-  */
-static void sdio_dld_dealloc_local_buffers(void)
-{
-	kfree((void *)sdio_dld->sdio_dloader_data.incoming_data.data);
-}
-
-/**
-  * mailbox_to_seq_chunk_read_cfg
-  * reads 4 configuration registers of mailbox from str_func, as
-  * a sequentail chunk in memory, and updates global struct
-  * accordingly.
-  *
-  * @str_func: a pointer to func struct.
-  * @return 0 on success or negative value on error.
-  */
-static int mailbox_to_seq_chunk_read_cfg(struct sdio_func *str_func)
-{
-	struct sdioc_reg_sequential_chunk_cfg seq_chunk;
-	struct sdioc_reg_chunk *reg = &sdio_dld->sdio_dloader_data.sdioc_reg;
-	int status = 0;
-
-	if (!str_func) {
-		pr_err(MODULE_NAME ": %s - param ""str_func"" is NULL.\n",
-		       __func__);
-		return -EINVAL;
-	}
-
-	sdio_claim_host(str_func);
-
-	/* reading SDIOC_MAILBOX_SIZE bytes from SDIOC_MAILBOX_ADDRESS */
-	status = sdio_memcpy_fromio(str_func,
-				    (void *)&seq_chunk,
-				    SDIOC_MAILBOX_ADDRESS,
-				    SDIOC_CFG_REGS_SIZE);
-	if (status) {
-		pr_err(MODULE_NAME ": %s - sdio_memcpy_fromio()"
-		       " READING CFG MAILBOX failed. status=%d.\n",
-		       __func__, status);
-	}
-
-	sdio_release_host(str_func);
-
-	reg->dl_buff_address.reg_val = seq_chunk.dl_buff_address;
-	reg->up_buff_address.reg_val = seq_chunk.up_buff_address;
-	reg->dl_buff_size.reg_val = seq_chunk.dl_buff_size;
-	reg->ul_buff_size.reg_val = seq_chunk.ul_buff_size;
-
-	/* keep sdio_dld_info up to date */
-	sdio_dld_info.cl_dl_buffer_size = seq_chunk.dl_buff_size;
-	sdio_dld_info.cl_up_buffer_size = seq_chunk.ul_buff_size;
-	sdio_dld_info.cl_dl_buffer_address = seq_chunk.dl_buff_address;
-	sdio_dld_info.cl_up_buffer_address = seq_chunk.up_buff_address;
-
-	return status;
-}
-
-/**
-  * mailbox_to_seq_chunk_read_ptrs
-  * reads 4 pointers registers of mailbox from str_func, as a
-  * sequentail chunk in memory, and updates global struct
-  * accordingly.
-  *
-  * @str_func: a pointer to func struct.
-  * @return 0 on success or negative value on error.
-  */
-static int mailbox_to_seq_chunk_read_ptrs(struct sdio_func *str_func)
-{
-	struct sdioc_reg_sequential_chunk_ptrs seq_chunk;
-	struct sdioc_reg_chunk *reg = &sdio_dld->sdio_dloader_data.sdioc_reg;
-	int status = 0;
-
-	struct sdio_data *outgoing = &sdio_dld->sdio_dloader_data.outgoing_data;
-	static int counter = 1;
-	static int offset_write_p;
-	static int offset_read_p;
-	static int up_wr_ptr;
-	static int up_rd_ptr;
-	static int dl_wr_ptr;
-	static int dl_rd_ptr;
-
-	if (!str_func) {
-		pr_err(MODULE_NAME ": %s - param ""str_func"" is NULL.\n",
-		       __func__);
-		return -EINVAL;
-	}
-
-	sdio_claim_host(str_func);
-
-	/* reading SDIOC_MAILBOX_SIZE bytes from SDIOC_MAILBOX_ADDRESS */
-	status = sdio_memcpy_fromio(str_func,
-				    (void *)&seq_chunk,
-				    SDIOC_PTRS_OFFSET,
-				    SDIOC_PTR_REGS_SIZE);
-	if (status) {
-		pr_err(MODULE_NAME ": %s - sdio_memcpy_fromio()"
-		       " READING PTRS MAILBOX failed. status=%d.\n",
-		       __func__, status);
-	}
-
-	sdio_release_host(str_func);
-
-	reg->dl_rd_ptr.reg_val = seq_chunk.dl_rd_ptr;
-	reg->dl_wr_ptr.reg_val = seq_chunk.dl_wr_ptr;
-	reg->up_rd_ptr.reg_val = seq_chunk.up_rd_ptr;
-	reg->up_wr_ptr.reg_val = seq_chunk.up_wr_ptr;
-
-	/* keeping sdio_dld_info up to date */
-	sdio_dld_info.cl_dl_rd_ptr = seq_chunk.dl_rd_ptr;
-	sdio_dld_info.cl_dl_wr_ptr = seq_chunk.dl_wr_ptr;
-	sdio_dld_info.cl_up_rd_ptr = seq_chunk.up_rd_ptr;
-	sdio_dld_info.cl_up_wr_ptr = seq_chunk.up_wr_ptr;
-
-
-	/* DEBUG - if there was a change in value */
-	if ((offset_write_p != outgoing->offset_write_p) ||
-	    (offset_read_p != outgoing->offset_read_p) ||
-	    (up_wr_ptr != reg->up_wr_ptr.reg_val) ||
-	    (up_rd_ptr != reg->up_rd_ptr.reg_val) ||
-	    (dl_wr_ptr != reg->dl_wr_ptr.reg_val) ||
-	    (dl_rd_ptr != reg->dl_rd_ptr.reg_val) ||
-	    (counter % PRINTING_GAP == 0)) {
-		counter = 1;
-		pr_debug(MODULE_NAME ": %s MailBox pointers: BLOCK_SIZE=%d, "
-			 "hw=%d, hr=%d, cuw=%d, cur=%d, cdw=%d, cdr=%d\n",
-			 __func__,
-			 SDIO_DL_BLOCK_SIZE,
-			 outgoing->offset_write_p,
-			 outgoing->offset_read_p,
-			 reg->up_wr_ptr.reg_val,
-			 reg->up_rd_ptr.reg_val,
-			 reg->dl_wr_ptr.reg_val,
-			 reg->dl_rd_ptr.reg_val);
-
-#ifdef CONFIG_DEBUG_FS
-		update_gd(SDIO_DLD_DEBUGFS_CASE_1_CODE);
-#endif
-		/* update static variables */
-		offset_write_p = outgoing->offset_write_p;
-		offset_read_p =	outgoing->offset_read_p;
-		up_wr_ptr = reg->up_wr_ptr.reg_val;
-		up_rd_ptr = reg->up_rd_ptr.reg_val;
-		dl_wr_ptr = reg->dl_wr_ptr.reg_val;
-		dl_rd_ptr = reg->dl_rd_ptr.reg_val;
-	} else {
-		counter++;
-	}
-	return status;
-}
-
-/**
-  * sdio_dld_init_func
-  * enables the sdio func, and sets the func block size.
-  *
-  * @str_func: a pointer to func struct.
-  * @return 0 on success or negative value on error.
-  */
-static int sdio_dld_init_func(struct sdio_func *str_func)
-{
-	int status1 = 0;
-	int status2 = 0;
-
-	if (!str_func) {
-		pr_err(MODULE_NAME ": %s - param ""str_func"" is NULL.\n",
-		       __func__);
-		return -EINVAL;
-	}
-
-	sdio_claim_host(str_func);
-
-	status1 = sdio_enable_func(str_func);
-	if (status1) {
-		sdio_release_host(str_func);
-		pr_err(MODULE_NAME ": %s - sdio_enable_func() failed. "
-		       "status=%d\n", __func__, status1);
-		return status1;
-	}
-
-	status2 = sdio_set_block_size(str_func, SDIO_DL_BLOCK_SIZE);
-	if (status2) {
-		pr_err(MODULE_NAME ": %s - sdio_set_block_size() failed. "
-		       "status=%d\n", __func__, status2);
-		status1 = sdio_disable_func(str_func);
-		if (status1) {
-			pr_err(MODULE_NAME ": %s - sdio_disable_func() "
-		       "failed. status=%d\n", __func__, status1);
-		}
-		sdio_release_host(str_func);
-		return status2;
-	}
-
-	sdio_release_host(str_func);
-	str_func->max_blksize = SDIO_DL_BLOCK_SIZE;
-	return 0;
-}
-
-/**
-  * sdio_dld_allocate_buffers
-  * initializes the sdio func, and then reads the mailbox, in
-  * order to allocate incoming and outgoing buffers according to
-  * the size that was read from the mailbox.
-  *
-  * @str_func: a pointer to func struct.
-  * @return 0 on success or negative value on error.
-  */
-static int sdio_dld_allocate_buffers(struct sdio_func *str_func)
-{
-	int status = 0;
-
-	if (!str_func) {
-		pr_err(MODULE_NAME ": %s - param ""str_func"" is NULL.\n",
-		       __func__);
-		return -EINVAL;
-	}
-
-	status = mailbox_to_seq_chunk_read_cfg(str_func);
-	if (status) {
-		pr_err(MODULE_NAME ": %s - Failure in Function "
-		       "mailbox_to_seq_chunk_read_cfg(). status=%d\n",
-		       __func__, status);
-		return status;
-	}
-
-	status = sdio_dld_allocate_local_buffers();
-	if (status) {
-		pr_err(MODULE_NAME ": %s - Failure in Function "
-		       "sdio_dld_allocate_local_buffers(). status=%d\n",
-		       __func__, status);
-		return status;
-	}
-	return 0;
-}
-
-/**
-  * sdio_dld_create_thread
-  * creates thread and wakes it up.
-  *
-  * @return 0 on success or negative value on error.
-  */
-static int sdio_dld_create_thread(void)
-{
-	sdio_dld->dld_main_thread.task_name = SDIO_DL_MAIN_THREAD_NAME;
-
-	sdio_dld->dld_main_thread.dld_task =
-		kthread_create(sdio_dld_main_task,
-			       (void *)(sdio_dld->card),
-			       sdio_dld->dld_main_thread.task_name);
-
-	if (IS_ERR(sdio_dld->dld_main_thread.dld_task)) {
-		pr_err(MODULE_NAME ": %s - kthread_create() failed\n",
-			__func__);
-		return -ENOMEM;
-	}
-	wake_up_process(sdio_dld->dld_main_thread.dld_task);
-	return 0;
-}
-
-/**
-  * start_timer
-  * sets the timer and starts.
-  *
-  * @timer: the timer to configure and add
-  * @ms: the ms until it expires
-  * @return None.
-  */
-static void start_timer(struct timer_list *timer, unsigned int ms)
-{
-	if ((ms == 0) || (timer == NULL)) {
-		pr_err(MODULE_NAME ": %s - invalid parameter", __func__);
-	} else {
-		timer->expires = jiffies +
-			msecs_to_jiffies(ms);
-		add_timer(timer);
-	}
-}
-
-/**
-  * sdio_dld_timer_handler
-  * this is the timer handler. whenever it is invoked, it wakes
-  * up the main loop task, and the write callback, and starts
-  * the timer again.
-  *
-  * @data: a pointer to the tty device driver structure.
-  * @return None.
-  */
-
-static void sdio_dld_timer_handler(unsigned long data)
-{
-	pr_debug(MODULE_NAME " Timer Expired\n");
-	spin_lock_irqsave(&lock2, lock_flags2);
-	if (sdio_dld->main_loop_event.wake_up_signal == 0) {
-		sdio_dld->main_loop_event.wake_up_signal = 1;
-		wake_up(&sdio_dld->main_loop_event.wait_event);
-	}
-	spin_unlock_irqrestore(&lock2, lock_flags2);
-
-	sdio_dld->write_callback_event.wake_up_signal = 1;
-	wake_up(&sdio_dld->write_callback_event.wait_event);
-
-	start_timer(&sdio_dld->timer, sdio_dld->poll_ms);
-}
-
-/**
-  * sdio_dld_push_timer_handler
-  * this is a timer handler of the push_timer.
-  *
-  * @data: a pointer to the tty device driver structure.
-  * @return None.
-  */
-static void sdio_dld_push_timer_handler(unsigned long data)
-{
-	pr_err(MODULE_NAME " %s - Push Timer Expired... Trying to "
-		"push data to TTY Core for over then %d ms.\n",
-		__func__, sdio_dld->push_timer_ms);
-}
-
-/**
-  * sdio_dld_open
-  * this is the open callback of the tty driver.
-  * it initializes the sdio func, allocates the buffers, and
-  * creates the main thread.
-  *
-  * @tty: a pointer to the tty struct.
-  * @file: file descriptor.
-  * @return 0 on success or negative value on error.
-  */
-static int sdio_dld_open(struct tty_struct *tty, struct file *file)
-{
-	int status = 0;
-	int func_in_array =
-		REAL_FUNC_TO_FUNC_IN_ARRAY(sdio_dld->sdioc_boot_func);
-	struct sdio_func *str_func = sdio_dld->card->sdio_func[func_in_array];
-
-	sdio_dld->tty_str = tty;
-	sdio_dld->tty_str->low_latency = 1;
-	sdio_dld->tty_str->icanon = 0;
-	set_bit(TTY_NO_WRITE_SPLIT, &sdio_dld->tty_str->flags);
-
-	pr_info(MODULE_NAME ": %s, TTY DEVICE FOR FLASHLESS BOOT OPENED\n",
-	       __func__);
-	sdio_dld_info.start_time = get_jiffies_64(); /* read the current time */
-
-	if (!tty) {
-		pr_err(MODULE_NAME ": %s - param ""tty"" is NULL.\n",
-		       __func__);
-		return -EINVAL;
-	}
-
-	if (!str_func) {
-		pr_err(MODULE_NAME ": %s - param ""str_func"" is NULL.\n",
-		       __func__);
-		return -EINVAL;
-	}
-
-	atomic_set(&sdio_dld->dld_main_thread.please_close, 0);
-	sdio_dld->dld_main_thread.exit_wait.wake_up_signal = 0;
-
-	status = sdio_dld_allocate_buffers(str_func);
-	if (status) {
-		pr_err(MODULE_NAME ": %s, failed in "
-		       "sdio_dld_allocate_buffers(). status=%d\n",
-		       __func__, status);
-		return status;
-	}
-
-	/* init waiting event of the write callback */
-	init_waitqueue_head(&sdio_dld->write_callback_event.wait_event);
-
-	/* init waiting event of the main loop */
-	init_waitqueue_head(&sdio_dld->main_loop_event.wait_event);
-
-	/* configure and init the timer */
-	sdio_dld->poll_ms = TIMER_DURATION;
-	init_timer(&sdio_dld->timer);
-	sdio_dld->timer.data = (unsigned long) sdio_dld;
-	sdio_dld->timer.function = sdio_dld_timer_handler;
-	sdio_dld->timer.expires = jiffies +
-		msecs_to_jiffies(sdio_dld->poll_ms);
-	add_timer(&sdio_dld->timer);
-
-	sdio_dld->push_timer_ms = PUSH_TIMER_DURATION;
-	init_timer(&sdio_dld->push_timer);
-	sdio_dld->push_timer.data = (unsigned long) sdio_dld;
-	sdio_dld->push_timer.function = sdio_dld_push_timer_handler;
-
-	status = sdio_dld_create_thread();
-	if (status) {
-		del_timer_sync(&sdio_dld->timer);
-		del_timer_sync(&sdio_dld->push_timer);
-		sdio_dld_dealloc_local_buffers();
-		pr_err(MODULE_NAME ": %s, failed in sdio_dld_create_thread()."
-				   "status=%d\n", __func__, status);
-		return status;
-	}
-	return 0;
-}
-
-/**
-  * sdio_dld_close
-  * this is the close callback of the tty driver. it requests
-  * the main thread to exit, and waits for notification of it.
-  * it also de-allocates the buffers, and unregisters the tty
-  * driver and device.
-  *
-  * @tty: a pointer to the tty struct.
-  * @file: file descriptor.
-  * @return None.
-  */
-static void sdio_dld_close(struct tty_struct *tty, struct file *file)
-{
-	int status = 0;
-	struct sdioc_reg_chunk *reg = &sdio_dld->sdio_dloader_data.sdioc_reg;
-
-	/* informing the SDIOC that it can exit boot phase */
-	sdio_dld->sdio_dloader_data.sdioc_reg.good_to_exit_ptr.reg_val =
-		SDIOC_EXIT_CODE;
-
-	atomic_set(&sdio_dld->dld_main_thread.please_close, 1);
-
-	pr_debug(MODULE_NAME ": %s - CLOSING - WAITING...", __func__);
-
-	wait_event(sdio_dld->dld_main_thread.exit_wait.wait_event,
-		   sdio_dld->dld_main_thread.exit_wait.wake_up_signal);
-	pr_debug(MODULE_NAME ": %s - CLOSING - WOKE UP...", __func__);
-
-	del_timer_sync(&sdio_dld->timer);
-	del_timer_sync(&sdio_dld->push_timer);
-
-	sdio_dld_dealloc_local_buffers();
-
-	tty_unregister_device(sdio_dld->tty_drv, 0);
-
-	status = tty_unregister_driver(sdio_dld->tty_drv);
-
-	if (status) {
-		pr_err(MODULE_NAME ": %s - tty_unregister_driver() failed\n",
-		       __func__);
-	}
-
-#ifdef CONFIG_DEBUG_FS
-	gd.curr_i = curr_index;
-	gd.duration_ms = sdio_dld_info.time_msec;
-	gd.global_bytes_sent = sdio_dld_info.global_bytes_write_toio;
-	gd.global_bytes_received = 0;
-	gd.throughput_Mbs = sdio_dld_info.throughput;
-	gd.host_outgoing_buffer_size_KB = sdio_dld->sdio_dloader_data.
-		outgoing_data.buffer_size/BYTES_IN_KB;
-	gd.client_up_buffer_size_KB = reg->ul_buff_size.reg_val/BYTES_IN_KB;
-	gd.client_dl_buffer_size_KB = reg->dl_buff_size.reg_val/BYTES_IN_KB;
-	gd.client_dl_buffer_address = reg->dl_buff_address.reg_val;
-	gd.client_up_buffer_address = reg->up_buff_address.reg_val;
-	gd.global_bytes_received = sdio_dld_info.global_bytes_read_fromio;
-	gd.global_bytes_pushed = sdio_dld_info.global_bytes_push_tty;
-#endif
-
-	/* saving register values before deallocating sdio_dld
-	   in order to use it in sdio_dld_print_info() through shell command */
-	sdio_dld_info.cl_dl_rd_ptr = reg->dl_rd_ptr.reg_val;
-	sdio_dld_info.cl_dl_wr_ptr = reg->dl_wr_ptr.reg_val;
-	sdio_dld_info.cl_up_rd_ptr = reg->up_rd_ptr.reg_val;
-	sdio_dld_info.cl_up_wr_ptr = reg->up_wr_ptr.reg_val;
-
-	sdio_dld_info.host_read_ptr =
-		sdio_dld->sdio_dloader_data.outgoing_data.offset_read_p;
-
-	sdio_dld_info.host_write_ptr =
-		sdio_dld->sdio_dloader_data.outgoing_data.offset_write_p;
-
-	sdio_dld_info.cl_dl_buffer_size =
-		sdio_dld->sdio_dloader_data.sdioc_reg.dl_buff_size.reg_val;
-
-	sdio_dld_info.cl_up_buffer_size =
-		sdio_dld->sdio_dloader_data.sdioc_reg.ul_buff_size.reg_val;
-
-	sdio_dld_info.host_outgoing_buffer_size =
-		sdio_dld->sdio_dloader_data.outgoing_data.buffer_size;
-
-	sdio_dld_info.cl_dl_buffer_address =
-		sdio_dld->sdio_dloader_data.sdioc_reg.dl_buff_address.reg_val;
-
-	sdio_dld_info.cl_up_buffer_address =
-		sdio_dld->sdio_dloader_data.sdioc_reg.up_buff_address.reg_val;
-
-	sdio_dld_print_info();
-
-	if (sdio_dld->done_callback)
-		sdio_dld->done_callback();
-
-	pr_info(MODULE_NAME ": %s - Freeing sdio_dld data structure, and "
-		" returning...", __func__);
-	kfree(sdio_dld);
-}
-
-/**
-  * writing_size_to_buf
-  * writes from src buffer into dest buffer. if dest buffer
-  * reaches its end, rollover happens.
-  *
-  * @dest: destination buffer.
-  * @src: source buffer.
-  * @dest_wr_ptr: writing pointer in destination buffer.
-  * @dest_size: destination buffer size.
-  * @dest_rd_ptr: reading pointer in destination buffer.
-  * @size_to_write: size of bytes to write.
-  * @return -how many bytes actually written to destination
-  * buffer.
-  *
-  * ONLY destination buffer is treated as cyclic buffer.
-  */
-static int writing_size_to_buf(char *dest,
-			       const unsigned char *src,
-			       int *dest_wr_ptr,
-			       int dest_size,
-			       int dest_rd_ptr,
-			       int size_to_write)
-{
-	int actually_written = 0;
-	int size_to_add = *dest_wr_ptr;
-
-	if (!dest) {
-		pr_err(MODULE_NAME ": %s - param ""dest"" is NULL.\n",
-		       __func__);
-		return -EINVAL;
-	}
-
-	if (!src) {
-		pr_err(MODULE_NAME ": %s - param ""src"" is NULL.\n",
-		       __func__);
-		return -EINVAL;
-	}
-
-	if (!dest_wr_ptr) {
-		pr_err(MODULE_NAME ": %s - param ""dest_wr_ptr"" is NULL.\n",
-		       __func__);
-		return -EINVAL;
-	}
-
-	for (actually_written = 0 ;
-	      actually_written < size_to_write ; ++actually_written) {
-		/* checking if buffer is full */
-		if (((size_to_add + 1) % dest_size) == dest_rd_ptr) {
-			*dest_wr_ptr = size_to_add;
-			return actually_written;
-		}
-
-		dest[size_to_add] = src[actually_written];
-		size_to_add = (size_to_add+1)%dest_size;
-	}
-
-	*dest_wr_ptr = size_to_add;
-
-	return actually_written;
-}
-
-/**
-  * sdioc_bytes_till_end_of_buffer - this routine calculates how many bytes are
-  * empty/in use. if calculation requires rap around - it will ignore the rap
-  * around and will do the calculation untill the end of the buffer
-  *
-  * @write_ptr: writing pointer.
-  * @read_ptr: reading pointer.
-  * @total_size: buffer size.
-  * @free_bytes: return value-how many free bytes.
-  * @bytes_in_use: return value-how many bytes in use.
-  * @return 0 on success or negative value on error.
-  *
-  * buffer is treated as a cyclic buffer.
-  */
-static int sdioc_bytes_till_end_of_buffer(int write_ptr,
-					  int read_ptr,
-					  int total_size,
-					  int *free_bytes,
-					  int *bytes_in_use)
-{
-	if (!free_bytes) {
-		pr_err(MODULE_NAME ": %s - param ""free_bytes"" is NULL.\n",
-		       __func__);
-		return -EINVAL;
-	}
-
-	if (!bytes_in_use) {
-		pr_err(MODULE_NAME ": %s - param ""bytes_in_use"" is NULL.\n",
-		       __func__);
-		return -EINVAL;
-	}
-
-	if (write_ptr >= read_ptr) {
-		if (read_ptr == 0)
-			*free_bytes = total_size - write_ptr - 1;
-		else
-			*free_bytes = total_size - write_ptr;
-		*bytes_in_use = write_ptr - read_ptr;
-	} else {
-		*bytes_in_use = total_size - read_ptr;
-		*free_bytes = read_ptr - write_ptr - 1;
-	}
-
-	return  0;
-}
-
-/**
-  * sdioc_bytes_free_in_buffer
-  * this routine calculates how many bytes are free in a buffer
-  * and how many are in use, according to its reading and
-  * writing pointer offsets.
-  *
-  * @write_ptr: writing pointer.
-  * @read_ptr: reading pointer.
-  * @total_size: buffer size.
-  * @free_bytes: return value-how many free bytes in buffer.
-  * @bytes_in_use: return value-how many bytes in use in buffer.
-  * @return 0 on success or negative value on error.
-  *
-  * buffer is treated as a cyclic buffer.
-  */
-static int sdioc_bytes_free_in_buffer(int write_ptr,
-				      int read_ptr,
-				      int total_size,
-				      int *free_bytes,
-				      int *bytes_in_use)
-{
-	if (!free_bytes) {
-		pr_err(MODULE_NAME ": %s - param ""free_bytes"" is NULL.\n",
-		       __func__);
-		return -EINVAL;
-	}
-
-	if (!bytes_in_use) {
-		pr_err(MODULE_NAME ": %s - param ""bytes_in_use"" is NULL.\n",
-		       __func__);
-		return -EINVAL;
-	}
-
-	/* if pointers equel - buffers are empty. nothing to read/write */
-
-	if (write_ptr >= read_ptr)
-		*bytes_in_use = write_ptr - read_ptr;
-	else
-		*bytes_in_use = total_size - (read_ptr - write_ptr);
-
-	*free_bytes = total_size - *bytes_in_use - 1;
-
-	return 0;
-}
-
-/*
-* sdio_dld_write_room
-*
-* This is the write_room function of the tty driver.
-*
-* @tty: pointer to tty struct.
-* @return free bytes for write.
-*
-*/
-static int sdio_dld_write_room(struct tty_struct *tty)
-{
-	return sdio_dld->sdio_dloader_data.outgoing_data.buffer_size;
-}
-
-/**
-  * sdio_dld_write_callback
-  * this is the write callback of the tty driver.
-  *
-  * @tty: pointer to tty struct.
-  * @buf: buffer to write from.
-  * @count: number of bytes to write.
-  * @return bytes written or negative value on error.
-  *
-  * if destination buffer has not enough room for the incoming
-  * data, returns an error.
-  */
-static int sdio_dld_write_callback(struct tty_struct *tty,
-				   const unsigned char *buf, int count)
-{
-	struct sdio_data *outgoing = &sdio_dld->sdio_dloader_data.outgoing_data;
-	int dst_free_bytes = 0;
-	int dummy = 0;
-	int status = 0;
-	int bytes_written = 0;
-	int total_written = 0;
-	static int write_retry;
-	int pending_to_write = count;
-
-#ifdef CONFIG_DEBUG_FS
-	debugfs_glob.global_count = count;
-	update_gd(SDIO_DLD_DEBUGFS_CASE_5_CODE);
-#endif
-
-	pr_debug(MODULE_NAME ": %s - WRITING CALLBACK CALLED WITH %d bytes\n",
-		 __func__, count);
-
-	if (!outgoing->data) {
-		pr_err(MODULE_NAME ": %s - param ""outgoing->data"" is NULL.\n",
-		       __func__);
-		return -EINVAL;
-	}
-
-	pr_debug(MODULE_NAME ": %s - WRITE CALLBACK size to write to outgoing"
-		 " buffer %d\n", __func__, count);
-
-	/* as long as there is something to write to outgoing buffer */
-	do {
-		int bytes_to_write = 0;
-		status = sdioc_bytes_free_in_buffer(
-			outgoing->offset_write_p,
-			outgoing->offset_read_p,
-			outgoing->buffer_size,
-			&dst_free_bytes,
-			&dummy);
-
-		if (status) {
-			pr_err(MODULE_NAME ": %s - Failure in Function "
-			       "sdioc_bytes_free_in_buffer(). status=%d\n",
-			       __func__, status);
-			return status;
-		}
-
-		/*
-		 * if there is free room in outgoing buffer
-		 * lock mutex and request trigger notification from the main
-		 * task. unlock mutex, and wait for sinal
-		 */
-		if (dst_free_bytes > 0) {
-			write_retry = 0;
-			/*
-			 * if there is more data to write to outgoing buffer
-			 * than it can receive, wait for signal from main task
-			 */
-			if (pending_to_write > dst_free_bytes) {
-
-				/* sampling updated dst_free_bytes */
-				status = sdioc_bytes_free_in_buffer(
-				outgoing->offset_write_p,
-				outgoing->offset_read_p,
-				outgoing->buffer_size,
-				&dst_free_bytes,
-				&dummy);
-
-				if (status) {
-					pr_err(MODULE_NAME ": %s - Failure in "
-							   "Function "
-					       "sdioc_bytes_free_in_buffer(). "
-					       "status=%d\n", __func__, status);
-					return status;
-				}
-			}
-
-			bytes_to_write = min(pending_to_write, dst_free_bytes);
-			bytes_written =
-				writing_size_to_buf(outgoing->data,
-						    buf+total_written,
-						    &outgoing->offset_write_p,
-						    outgoing->buffer_size,
-						    outgoing->offset_read_p,
-						    bytes_to_write);
-
-			/* keeping sdio_dld_info up to date */
-			sdio_dld_info.host_write_ptr =
-				sdio_dld->sdio_dloader_data.
-					    outgoing_data.offset_write_p;
-
-#ifdef CONFIG_DEBUG_FS
-			debugfs_glob.global_write_tty = bytes_written;
-			update_gd(SDIO_DLD_DEBUGFS_CASE_3_CODE);
-#endif
-			sdio_dld_info.global_bytes_write_tty += bytes_written;
-
-			spin_lock_irqsave(&lock2, lock_flags2);
-			if (sdio_dld->main_loop_event.wake_up_signal == 0) {
-				sdio_dld->main_loop_event.wake_up_signal = 1;
-				wake_up(&sdio_dld->main_loop_event.wait_event);
-			}
-			spin_unlock_irqrestore(&lock2, lock_flags2);
-
-			/*
-			 * although outgoing buffer has enough room, writing
-			 * failed
-			 */
-			if (bytes_written != bytes_to_write) {
-				pr_err(MODULE_NAME ": %s - couldn't write "
-				       "%d bytes to " "outgoing buffer."
-				       "bytes_written=%d\n",
-				       __func__, bytes_to_write,
-				       bytes_written);
-			       return -EIO;
-			}
-
-			total_written += bytes_written;
-			pending_to_write -= bytes_written;
-			outgoing->num_of_bytes_in_use += bytes_written;
-
-			pr_debug(MODULE_NAME ": %s - WRITE CHUNK to outgoing "
-					   "buffer. pending_to_write=%d, "
-					   "outgoing_free_bytes=%d, "
-					   "bytes_written=%d\n",
-				 __func__,
-				 pending_to_write,
-				 dst_free_bytes,
-				 bytes_written);
-
-		} else {
-			write_retry++;
-
-			pr_debug(MODULE_NAME ": %s - WRITE CALLBACK - NO ROOM."
-			       " pending_to_write=%d, write_retry=%d\n",
-				 __func__,
-				 pending_to_write,
-				 write_retry);
-
-			spin_lock_irqsave(&lock1, lock_flags1);
-			sdio_dld->write_callback_event.wake_up_signal = 0;
-			spin_unlock_irqrestore(&lock1, lock_flags1);
-
-			pr_debug(MODULE_NAME ": %s - WRITE CALLBACK - "
-					     "WAITING...", __func__);
-#ifdef CONFIG_DEBUG_FS
-			update_gd(SDIO_DLD_DEBUGFS_CASE_8_CODE);
-#endif
-			wait_event(sdio_dld->write_callback_event.wait_event,
-				   sdio_dld->write_callback_event.
-				   wake_up_signal);
-#ifdef CONFIG_DEBUG_FS
-			update_gd(SDIO_DLD_DEBUGFS_CASE_9_CODE);
-#endif
-			pr_debug(MODULE_NAME ": %s - WRITE CALLBACK - "
-					     "WOKE UP...", __func__);
-		}
-	} while (pending_to_write > 0 && write_retry < WRITE_RETRIES);
-
-	if (pending_to_write > 0) {
-
-		pr_err(MODULE_NAME ": %s - WRITE CALLBACK - pending data is "
-				   "%d out of %d > 0. total written in this "
-				   "callback = %d\n",
-		       __func__, pending_to_write, count, total_written);
-	}
-
-	if (write_retry == WRITE_RETRIES) {
-		pr_err(MODULE_NAME ": %s, write_retry=%d= max\n",
-		       __func__, write_retry);
-	}
-
-#ifdef CONFIG_DEBUG_FS
-	debugfs_glob.global_bytes_cb_tty = total_written;
-	update_gd(SDIO_DLD_DEBUGFS_CASE_10_CODE);
-#endif
-
-	return total_written;
-}
-
-/**
-  * sdio_memcpy_fromio_wrapper -
-  * reads from sdioc, and updats the sdioc registers according
-  * to how many bytes were actually read.
-  *
-  * @str_func: a pointer to func struct.
-  * @client_rd_ptr: sdioc value of downlink read ptr.
-  * @client_wr_ptr: sdioc value of downlink write ptr.
-  * @buffer_to_store: buffer to store incoming data.
-  * @address_to_read: address to start reading from in sdioc.
-  * @size_to_read: size of bytes to read.
-  * @client_buffer_size: sdioc downlink buffer size.
-  * @return 0 on success or negative value on error.
-  */
-static int sdio_memcpy_fromio_wrapper(struct sdio_func *str_func,
-				      unsigned int client_rd_ptr,
-				      unsigned int client_wr_ptr,
-				      void *buffer_to_store,
-				      unsigned int address_to_read_from,
-				      int size_to_read,
-				      int client_buffer_size)
-{
-	int status = 0;
-	struct sdioc_reg_chunk *reg_str =
-		&sdio_dld->sdio_dloader_data.sdioc_reg;
-
-	if (!str_func) {
-		pr_err(MODULE_NAME ": %s - param ""str_func"" is NULL.\n",
-		       __func__);
-		return -EINVAL;
-	}
-
-	if (!buffer_to_store) {
-		pr_err(MODULE_NAME ": %s - param ""buffer_to_store"" is "
-				   "NULL.\n",
-		       __func__);
-		return -EINVAL;
-	}
-
-	if (size_to_read < 0) {
-		pr_err(MODULE_NAME ": %s - invalid size to read=%d\n",
-			__func__, size_to_read);
-		return -EINVAL;
-	}
-
-	sdio_claim_host(str_func);
-
-	pr_debug(MODULE_NAME ": %s, READING DATA - from add %d, "
-			   "size_to_read=%d\n",
-	       __func__, address_to_read_from, size_to_read);
-
-	status = sdio_memcpy_fromio(str_func,
-				    (void *)buffer_to_store,
-				    address_to_read_from,
-				    size_to_read);
-	if (status) {
-		pr_err(MODULE_NAME ": %s - sdio_memcpy_fromio()"
-		       " DATA failed. status=%d.\n",
-		       __func__, status);
-		sdio_release_host(str_func);
-		return status;
-	}
-
-	/* updating an offset according to cyclic buffer size */
-	reg_str->dl_rd_ptr.reg_val =
-		(reg_str->dl_rd_ptr.reg_val + size_to_read) %
-		client_buffer_size;
-	/* keeping sdio_dld_info up to date */
-	sdio_dld_info.cl_dl_rd_ptr = reg_str->dl_rd_ptr.reg_val;
-
-	status = sdio_memcpy_toio(str_func,
-				  reg_str->dl_rd_ptr.reg_offset,
-				  (void *)&reg_str->dl_rd_ptr.reg_val,
-				  sizeof(reg_str->dl_rd_ptr.reg_val));
-
-	if (status) {
-		pr_err(MODULE_NAME ": %s - sdio_memcpy_toio() "
-		       "UPDATE PTR failed. status=%d.\n",
-		       __func__, status);
-	}
-
-	sdio_release_host(str_func);
-	return status;
-}
-
-/**
-  * sdio_memcpy_toio_wrapper
-  * writes to sdioc, and updats the sdioc registers according
-  * to how many bytes were actually read.
-  *
-  * @str_func: a pointer to func struct.
-  * @client_wr_ptr: sdioc downlink write ptr.
-  * @h_read_ptr: host incoming read ptrs
-  * @buf_write_from: buffer to write from.
-  * @bytes_to_write: number of bytes to write.
-  * @return 0 on success or negative value on error.
-  */
-static int sdio_memcpy_toio_wrapper(struct sdio_func *str_func,
-				    unsigned int client_wr_ptr,
-				    unsigned int h_read_ptr,
-				    void *buf_write_from,
-				    int bytes_to_write)
-{
-	int status = 0;
-	struct sdioc_reg_chunk *reg_str =
-		&sdio_dld->sdio_dloader_data.sdioc_reg;
-	struct sdio_data *outgoing = &sdio_dld->sdio_dloader_data.outgoing_data;
-
-	if (!str_func) {
-		pr_err(MODULE_NAME ": %s - param ""str_func"" is NULL.\n",
-		       __func__);
-		return -EINVAL;
-	}
-
-	if (!buf_write_from) {
-		pr_err(MODULE_NAME ": %s - param ""buf_write_from"" is NULL.\n",
-		       __func__);
-		return -EINVAL;
-	}
-
-	sdio_claim_host(str_func);
-
-	pr_debug(MODULE_NAME ": %s, WRITING DATA TOIO to address 0x%x, "
-		 "bytes_to_write=%d\n",
-		 __func__,
-		reg_str->up_buff_address.reg_val + reg_str->up_wr_ptr.reg_val,
-		 bytes_to_write);
-
-	status = sdio_memcpy_toio(str_func,
-				  reg_str->up_buff_address.reg_val +
-				  reg_str->up_wr_ptr.reg_val,
-				  (void *) (outgoing->data + h_read_ptr),
-				  bytes_to_write);
-
-	if (status) {
-		pr_err(MODULE_NAME ": %s - sdio_memcpy_toio() "
-		       "DATA failed. status=%d.\n", __func__, status);
-		sdio_release_host(str_func);
-		return status;
-	}
-
-	sdio_dld_info.global_bytes_write_toio += bytes_to_write;
-	outgoing->num_of_bytes_in_use -= bytes_to_write;
-
-	/*
-	 * if writing to client succeeded, then
-	 * 1. update the client up_wr_ptr
-	 * 2. update the host outgoing rd ptr
-	 **/
-	reg_str->up_wr_ptr.reg_val =
-		((reg_str->up_wr_ptr.reg_val + bytes_to_write) %
-		 reg_str->ul_buff_size.reg_val);
-
-	/* keeping sdio_dld_info up to date */
-	sdio_dld_info.cl_up_wr_ptr = reg_str->up_wr_ptr.reg_val;
-
-	outgoing->offset_read_p =
-		((outgoing->offset_read_p + bytes_to_write) %
-		  outgoing->buffer_size);
-
-	/* keeping sdio_dld_info up to date*/
-	sdio_dld_info.host_read_ptr = outgoing->offset_read_p;
-
-#ifdef CONFIG_DEBUG_FS
-	debugfs_glob.global_write_toio = bytes_to_write;
-	update_gd(SDIO_DLD_DEBUGFS_CASE_4_CODE);
-#endif
-
-	/* updating uplink write pointer according to size that was written */
-	status = sdio_memcpy_toio(str_func,
-				  reg_str->up_wr_ptr.reg_offset,
-				  (void *)(&reg_str->up_wr_ptr.reg_val),
-				  sizeof(reg_str->up_wr_ptr.reg_val));
-	if (status) {
-		pr_err(MODULE_NAME ": %s - sdio_memcpy_toio() "
-				       "UPDATE PTR failed. status=%d.\n",
-		       __func__, status);
-	}
-
-	sdio_release_host(str_func);
-	return status;
-}
-
-/**
-  * sdio_dld_read
-  * reads from sdioc
-  *
-  * @client_rd_ptr: sdioc downlink read ptr.
-  * @client_wr_ptr: sdioc downlink write ptr.
-  * @reg_str: sdioc register shadowing struct.
-  * @str_func: a pointer to func struct.
-  * @bytes_read:how many bytes read.
-  * @return 0 on success or negative value on error.
-  */
-static int sdio_dld_read(unsigned int client_rd_ptr,
-			 unsigned int client_wr_ptr,
-			 struct sdioc_reg_chunk *reg_str,
-			 struct sdio_func *str_func,
-			 int *bytes_read)
-{
-	int status = 0;
-	struct sdio_data *incoming = &sdio_dld->sdio_dloader_data.incoming_data;
-
-	if (!reg_str) {
-		pr_err(MODULE_NAME ": %s - param ""reg_str"" is NULL.\n",
-		       __func__);
-		return -EINVAL;
-	}
-
-	if (!str_func) {
-		pr_err(MODULE_NAME ": %s - param ""str_func"" is NULL.\n",
-		       __func__);
-		return -EINVAL;
-	}
-
-	if (!bytes_read) {
-		pr_err(MODULE_NAME ": %s - param ""bytes_read"" is NULL.\n",
-		       __func__);
-		return -EINVAL;
-	}
-
-	/* there is data to read in ONE chunk */
-	if (client_wr_ptr > client_rd_ptr) {
-		status = sdio_memcpy_fromio_wrapper(
-			str_func,
-			client_rd_ptr,
-			client_wr_ptr,
-			(void *)incoming->data,
-			reg_str->dl_buff_address.reg_val + client_rd_ptr,
-			client_wr_ptr - client_rd_ptr,
-			reg_str->dl_buff_size.reg_val);
-
-		if (status) {
-			pr_err(MODULE_NAME ": %s - Failure in Function "
-			       "sdio_memcpy_fromio_wrapper(). "
-			       "SINGLE CHUNK READ. status=%d\n",
-			       __func__, status);
-			return status;
-		}
-
-		incoming->num_of_bytes_in_use += client_wr_ptr - client_rd_ptr;
-		*bytes_read = client_wr_ptr - client_rd_ptr;
-
-#ifdef CONFIG_DEBUG_FS
-			debugfs_glob.global_to_read =
-				client_wr_ptr - client_rd_ptr;
-			update_gd(SDIO_DLD_DEBUGFS_CASE_11_CODE);
-#endif
-	}
-
-	/* there is data to read in TWO chunks */
-	else {
-		int dl_buf_size = reg_str->dl_buff_size.reg_val;
-		int tail_size = dl_buf_size - client_rd_ptr;
-
-		/* reading chunk#1: from rd_ptr to the end of the buffer */
-		status = sdio_memcpy_fromio_wrapper(
-			str_func,
-			client_rd_ptr,
-			dl_buf_size,
-			(void *)incoming->data,
-			reg_str->dl_buff_address.reg_val + client_rd_ptr,
-			tail_size,
-			dl_buf_size);
-
-		if (status) {
-			pr_err(MODULE_NAME ": %s - Failure in Function "
-			       "sdio_memcpy_fromio_wrapper(). "
-			       "1 of 2 CHUNKS READ. status=%d\n",
-			       __func__, status);
-			return status;
-		}
-
-		incoming->num_of_bytes_in_use += tail_size;
-		*bytes_read = tail_size;
-
-#ifdef CONFIG_DEBUG_FS
-			debugfs_glob.global_to_read = tail_size;
-			update_gd(SDIO_DLD_DEBUGFS_CASE_11_CODE);
-#endif
-
-		/* reading chunk#2: reading from beginning buffer */
-		status = sdio_memcpy_fromio_wrapper(
-			str_func,
-			client_rd_ptr,
-			client_wr_ptr,
-			(void *)(incoming->data + tail_size),
-			reg_str->dl_buff_address.reg_val,
-			client_wr_ptr,
-			reg_str->dl_buff_size.reg_val);
-
-		if (status) {
-			pr_err(MODULE_NAME ": %s - Failure in Function "
-			       "sdio_memcpy_fromio_wrapper(). "
-			       "2 of 2 CHUNKS READ. status=%d\n",
-			       __func__, status);
-			return status;
-		}
-
-		incoming->num_of_bytes_in_use += client_wr_ptr;
-		*bytes_read += client_wr_ptr;
-
-#ifdef CONFIG_DEBUG_FS
-			debugfs_glob.global_to_read = client_wr_ptr;
-			update_gd(SDIO_DLD_DEBUGFS_CASE_11_CODE);
-#endif
-	}
-	return 0;
-}
-
-/**
-  * sdio_dld_main_task
-  * sdio downloader main task. reads mailboxf checks if there is
-  * anything to read, checks if host has anything to
-  * write.
-  *
-  * @card: a pointer to mmc_card.
-  * @return 0 on success or negative value on error.
-  */
-static int sdio_dld_main_task(void *card)
-{
-	int status = 0;
-	struct tty_struct *tty = sdio_dld->tty_str;
-	struct sdioc_reg_chunk *reg_str =
-		&sdio_dld->sdio_dloader_data.sdioc_reg;
-	int func = sdio_dld->sdioc_boot_func;
-	struct sdio_func *str_func = NULL;
-	struct sdio_data *outgoing = &sdio_dld->sdio_dloader_data.outgoing_data;
-	struct sdio_data *incoming = &sdio_dld->sdio_dloader_data.incoming_data;
-	struct sdio_dld_task *task = &sdio_dld->dld_main_thread;
-	int retries = 0;
-#ifdef PUSH_STRING
-	int bytes_pushed = 0;
-#endif
-
-	msleep(SLEEP_MS);
-
-	if (!card) {
-		pr_err(MODULE_NAME ": %s - param ""card"" is NULL.\n",
-		       __func__);
-		return -EINVAL;
-	}
-
-	if (!tty) {
-		pr_err(MODULE_NAME ": %s - param ""tty"" is NULL.\n",
-		       __func__);
-		return -EINVAL;
-	}
-
-	str_func = ((struct mmc_card *)card)->
-		sdio_func[REAL_FUNC_TO_FUNC_IN_ARRAY(func)];
-
-	if (!str_func) {
-		pr_err(MODULE_NAME ": %s - param ""str_func"" is NULL.\n",
-		       __func__);
-		return -EINVAL;
-	}
-
-	while (true) {
-		/* client pointers for both buffers */
-		int client_ul_wr_ptr = 0;
-		int client_ul_rd_ptr = 0;
-		int client_dl_wr_ptr = 0;
-		int client_dl_rd_ptr = 0;
-
-		/* host pointer for outgoing buffer */
-		int h_out_wr_ptr = 0;
-		int h_out_rd_ptr = 0;
-
-		int h_bytes_rdy_wr = 0;
-		int c_bytes_rdy_rcve = 0;
-
-		int need_to_write = 0;
-		int need_to_read = 0;
-
-		/*
-		 * forever, checking for signal to die, then read MailBox.
-		 * if nothing to read or nothing to write to client, sleep,
-		 * and again read MailBox
-		 */
-		do {
-			int dummy = 0;
-
-			/*  checking if a signal to die was sent */
-			if (atomic_read(&task->please_close) == 1) {
-
-				pr_debug(MODULE_NAME ": %s - 0x%x was written "
-					 "to 9K\n", __func__, SDIOC_EXIT_CODE);
-
-				sdio_claim_host(str_func);
-
-				/* returned value is not checked on purpose */
-				sdio_memcpy_toio(
-					str_func,
-					reg_str->good_to_exit_ptr.reg_offset,
-					(void *)&reg_str->good_to_exit_ptr.
-					reg_val,
-					sizeof(reg_str->good_to_exit_ptr.
-					       reg_val));
-
-				sdio_release_host(str_func);
-
-				task->exit_wait.wake_up_signal = 1;
-				wake_up(&task->exit_wait.wait_event);
-				return 0;
-			}
-
-			status = mailbox_to_seq_chunk_read_ptrs(str_func);
-			if (status) {
-				pr_err(MODULE_NAME ": %s - Failure in Function "
-				       "mailbox_to_seq_chunk_read_ptrs(). "
-				       "status=%d\n", __func__, status);
-				return status;
-			}
-
-			/* calculate how many bytes the host has send */
-			h_out_wr_ptr = outgoing->offset_write_p;
-			h_out_rd_ptr = outgoing->offset_read_p;
-
-			status = sdioc_bytes_till_end_of_buffer(
-				h_out_wr_ptr,
-				h_out_rd_ptr,
-				outgoing->buffer_size,
-				&dummy,
-				&h_bytes_rdy_wr);
-
-			if (status) {
-				pr_err(MODULE_NAME ": %s - Failure in Function "
-				       "sdioc_bytes_till_end_of_buffer(). "
-				       "status=%d\n", __func__, status);
-				return status;
-			}
-
-			/* is there something to read from client */
-			client_dl_wr_ptr = reg_str->dl_wr_ptr.reg_val;
-			client_dl_rd_ptr = reg_str->dl_rd_ptr.reg_val;
-
-			if (client_dl_rd_ptr != client_dl_wr_ptr)
-				need_to_read = 1;
-
-			/*
-			 *  calculate how many bytes the client can receive
-			 *  from host
-			 */
-			client_ul_wr_ptr = reg_str->up_wr_ptr.reg_val;
-			client_ul_rd_ptr = reg_str->up_rd_ptr.reg_val;
-
-			status = sdioc_bytes_till_end_of_buffer(
-				client_ul_wr_ptr,
-				client_ul_rd_ptr,
-				reg_str->ul_buff_size.reg_val,
-				&c_bytes_rdy_rcve,
-				&dummy);
-
-			if (status) {
-				pr_err(MODULE_NAME ": %s - Failure in Function "
-				       "sdioc_bytes_till_end_of_buffer(). "
-				       "status=%d\n", __func__, status);
-				return status;
-			}
-
-			/* if host has anything to write */
-			if (h_bytes_rdy_wr > 0)
-				need_to_write = 1;
-
-			if (need_to_write || need_to_read)
-				break;
-
-			spin_lock_irqsave(&lock2, lock_flags2);
-			sdio_dld->main_loop_event.wake_up_signal = 0;
-			spin_unlock_irqrestore(&lock2, lock_flags2);
-
-			pr_debug(MODULE_NAME ": %s - MAIN LOOP - WAITING...\n",
-				 __func__);
-#ifdef CONFIG_DEBUG_FS
-			update_gd(SDIO_DLD_DEBUGFS_CASE_6_CODE);
-#endif
-			wait_event(sdio_dld->main_loop_event.wait_event,
-				   sdio_dld->main_loop_event.wake_up_signal);
-#ifdef CONFIG_DEBUG_FS
-			update_gd(SDIO_DLD_DEBUGFS_CASE_7_CODE);
-#endif
-
-			pr_debug(MODULE_NAME ": %s - MAIN LOOP - WOKE UP...\n",
-				 __func__);
-
-		} while (1);
-
-		/* CHECK IF THERE IS ANYTHING TO READ IN CLIENT */
-		if (need_to_read) {
-#ifdef PUSH_STRING
-			int num_push = 0;
-			int left = 0;
-			int bytes_read;
-#else
-			int i;
-#endif
-			need_to_read = 0;
-
-			status = sdio_dld_read(client_dl_rd_ptr,
-					       client_dl_wr_ptr,
-					       reg_str,
-					       str_func,
-					       &bytes_read);
-
-			if (status) {
-				pr_err(MODULE_NAME ": %s - Failure in Function "
-				       "sdio_dld_read(). status=%d\n",
-				       __func__, status);
-				return status;
-			}
-
-			sdio_dld_info.global_bytes_read_fromio +=
-				bytes_read;
-
-			bytes_pushed = 0;
-#ifdef PUSH_STRING
-			left = incoming->num_of_bytes_in_use;
-			start_timer(&sdio_dld->push_timer,
-				    sdio_dld->push_timer_ms);
-			do {
-				num_push = tty_insert_flip_string(
-					tty,
-					incoming->data+bytes_pushed,
-					left);
-
-				bytes_pushed += num_push;
-				left -= num_push;
-				tty_flip_buffer_push(tty);
-			} while (left != 0);
-
-			del_timer(&sdio_dld->push_timer);
-
-			if (bytes_pushed != incoming->num_of_bytes_in_use) {
-				pr_err(MODULE_NAME ": %s - failed\n",
-				       __func__);
-			}
-#else
-			pr_debug(MODULE_NAME ": %s - NEED TO READ %d\n",
-			       __func__, incoming->num_of_bytes_in_use);
-
-			for (i = 0 ; i < incoming->num_of_bytes_in_use ; ++i) {
-				int err = 0;
-				err = tty_insert_flip_char(tty,
-							   incoming->data[i],
-							   TTY_NORMAL);
-				tty_flip_buffer_push(tty);
-			}
-
-			pr_debug(MODULE_NAME ": %s - JUST READ\n", __func__);
-#endif /*PUSH_STRING*/
-			sdio_dld_info.global_bytes_push_tty +=
-				incoming->num_of_bytes_in_use;
-#ifdef CONFIG_DEBUG_FS
-			debugfs_glob.global_push_to_tty = bytes_read;
-			update_gd(SDIO_DLD_DEBUGFS_CASE_12_CODE);
-#endif
-			incoming->num_of_bytes_in_use = 0;
-			tty_flip_buffer_push(tty);
-		}
-
-		/* CHECK IF THERE IS ANYTHING TO WRITE IN HOST AND HOW MUCH */
-		if (need_to_write) {
-			int dummy = 0;
-
-			do {
-				int bytes_to_write = min(c_bytes_rdy_rcve,
-							 h_bytes_rdy_wr);
-
-				/*
-				 * in case nothing to send or no room to
-				 * receive
-				 */
-				if (bytes_to_write == 0)
-					break;
-
-				if (client_ul_rd_ptr == 0 &&
-				    (client_ul_rd_ptr != client_ul_wr_ptr))
-					break;
-
-				/*
-				 * if client_rd_ptr points to start, but there
-				 * is data to read wait until WRITE_TILL_END
-				 * before writing a chunk of data, to avoid
-				 * writing until (BUF_SIZE - 1), because it will
-				 * yield an extra write of "1" bytes
-				 */
-				if (client_ul_rd_ptr == 0 &&
-				    (client_ul_rd_ptr != client_ul_wr_ptr) &&
-				    retries < WRITE_TILL_END_RETRIES) {
-					retries++;
-					break;
-				}
-				retries = 0;
-
-#ifdef CONFIG_DEBUG_FS
-				debugfs_glob.global_8k_has = h_bytes_rdy_wr;
-				debugfs_glob.global_9k_has = c_bytes_rdy_rcve;
-				debugfs_glob.global_min = bytes_to_write;
-				update_gd(SDIO_DLD_DEBUGFS_CASE_2_CODE);
-#endif
-				need_to_write = 0;
-
-				pr_debug(MODULE_NAME ": %s - NEED TO WRITE "
-					 "TOIO %d\n",
-					 __func__, bytes_to_write);
-
-				status = sdio_memcpy_toio_wrapper(
-					str_func,
-					reg_str->up_wr_ptr.reg_val,
-					outgoing->offset_read_p,
-					(void *)((char *)outgoing->data +
-						 outgoing->offset_read_p),
-					bytes_to_write);
-
-				if (status) {
-					pr_err(MODULE_NAME ": %s - Failure in "
-					       "Function "
-					       "sdio_memcpy_toio_wrapper(). "
-					       "SINGLE CHUNK WRITE. "
-					       "status=%d\n",
-					       __func__, status);
-					return status;
-				}
-
-				sdio_claim_host(str_func);
-
-				status = sdio_memcpy_fromio(
-					str_func,
-					(void *)&reg_str->up_rd_ptr.reg_val,
-					SDIOC_UL_RD_PTR,
-					sizeof(reg_str->up_rd_ptr.reg_val));
-
-				if (status) {
-					pr_err(MODULE_NAME ": %s - "
-					       "sdio_memcpy_fromio() "
-					       "failed. status=%d\n",
-					       __func__, status);
-					sdio_release_host(str_func);
-
-					return status;
-				}
-
-				sdio_release_host(str_func);
-
-				spin_lock_irqsave(&lock1, lock_flags1);
-				if (sdio_dld->write_callback_event.
-				    wake_up_signal == 0) {
-					sdio_dld->write_callback_event.
-						wake_up_signal = 1;
-					wake_up(&sdio_dld->
-						write_callback_event.
-						wait_event);
-				}
-
-				spin_unlock_irqrestore(&lock1, lock_flags1);
-				client_ul_wr_ptr = reg_str->up_wr_ptr.reg_val;
-				client_ul_rd_ptr = reg_str->up_rd_ptr.reg_val;
-
-				status = sdioc_bytes_till_end_of_buffer(
-					client_ul_wr_ptr,
-					client_ul_rd_ptr,
-					reg_str->ul_buff_size.reg_val,
-					&c_bytes_rdy_rcve,
-					&dummy);
-
-				/* calculate how many bytes host has to send */
-				h_out_wr_ptr = outgoing->offset_write_p;
-				h_out_rd_ptr = outgoing->offset_read_p;
-
-				status = sdioc_bytes_till_end_of_buffer(
-					h_out_wr_ptr,
-					h_out_rd_ptr,
-					outgoing->buffer_size,
-					&dummy,
-					&h_bytes_rdy_wr);
-
-			} while (h_out_wr_ptr != h_out_rd_ptr);
-		}
-	}
-	return 0;
-}
-
-/**
-  * sdio_dld_init_global
-  * initialization of sdio_dld global struct
-  *
-  * @card: a pointer to mmc_card.
-  * @return 0 on success or negative value on error.
-  */
-static int sdio_dld_init_global(struct mmc_card *card,
-				int(*done)(void))
-{
-	if (!card) {
-		pr_err(MODULE_NAME ": %s - param ""card"" is NULL.\n",
-		       __func__);
-		return -EINVAL;
-	}
-
-	if (!done) {
-		pr_err(MODULE_NAME ": %s - param ""done"" is NULL.\n",
-		       __func__);
-		return -EINVAL;
-	}
-
-	sdio_dld->done_callback = done;
-	sdio_dld->card = card;
-	init_waitqueue_head(&sdio_dld->dld_main_thread.exit_wait.wait_event);
-	sdio_dld->write_callback_event.wake_up_signal = 1;
-	sdio_dld->main_loop_event.wake_up_signal = 1;
-
-	sdio_dld->sdio_dloader_data.sdioc_reg.dl_buff_size.reg_offset =
-		SDIOC_DL_BUFF_SIZE_OFFSET;
-
-	sdio_dld->sdio_dloader_data.sdioc_reg.dl_rd_ptr.reg_offset =
-		SDIOC_DL_RD_PTR;
-
-	sdio_dld->sdio_dloader_data.sdioc_reg.dl_wr_ptr.reg_offset =
-		SDIOC_DL_WR_PTR;
-
-	sdio_dld->sdio_dloader_data.sdioc_reg.ul_buff_size.reg_offset =
-		SDIOC_UP_BUFF_SIZE_OFFSET;
-
-	sdio_dld->sdio_dloader_data.sdioc_reg.up_rd_ptr.reg_offset =
-		SDIOC_UL_RD_PTR;
-
-	sdio_dld->sdio_dloader_data.sdioc_reg.up_wr_ptr.reg_offset =
-		SDIOC_UL_WR_PTR;
-
-	sdio_dld->sdio_dloader_data.sdioc_reg.good_to_exit_ptr.reg_offset =
-		SDIOC_EXIT_PTR;
-
-	sdio_dld->sdio_dloader_data.sdioc_reg.dl_buff_address.reg_offset =
-		SDIOC_DL_BUFF_ADDRESS;
-
-	sdio_dld->sdio_dloader_data.sdioc_reg.up_buff_address.reg_offset =
-		SDIOC_UP_BUFF_ADDRESS;
-
-	sdio_dld_set_op_mode(SDIO_DLD_NORMAL_MODE);
-
-	return 0;
-}
-
-/**
- * sdio_downloader_setup
- * initializes the TTY driver
- *
- * @card: a pointer to mmc_card.
- * @num_of_devices: number of devices.
- * @channel_number: channel number.
- * @return 0 on success or negative value on error.
- *
- * The TTY stack needs to know in advance how many devices it should
- * plan to manage. Use this call to set up the ports that will
- * be exported through SDIO.
- */
-int sdio_downloader_setup(struct mmc_card *card,
-			  unsigned int num_of_devices,
-			  int channel_number,
-			  int(*done)(void))
-{
-	int status = 0;
-	int result = 0;
-	int func_in_array = 0;
-	struct sdio_func *str_func = NULL;
-	struct device *tty_dev;
-
-	if (num_of_devices == 0 || num_of_devices > MAX_NUM_DEVICES) {
-		pr_err(MODULE_NAME ": %s - invalid number of devices\n",
-		       __func__);
-		return -EINVAL;
-	}
-
-	if (!card) {
-		pr_err(MODULE_NAME ": %s - param ""card"" is NULL.\n",
-		       __func__);
-		return -EINVAL;
-	}
-
-	if (!done) {
-		pr_err(MODULE_NAME ": %s - param ""done"" is NULL.\n",
-		       __func__);
-		return -EINVAL;
-	}
-
-	sdio_dld = kzalloc(sizeof(struct sdio_downloader), GFP_KERNEL);
-	if (!sdio_dld) {
-		pr_err(MODULE_NAME ": %s - couldn't allocate sdio_dld data "
-		       "structure.", __func__);
-		return -ENOMEM;
-	}
-
-#ifdef CONFIG_DEBUG_FS
-	bootloader_debugfs_init();
-#endif /* CONFIG_DEBUG_FS */
-
-	status = sdio_dld_init_global(card, done);
-
-	if (status) {
-		pr_err(MODULE_NAME ": %s - Failure in Function "
-		       "sdio_dld_init_global(). status=%d\n",
-		       __func__, status);
-		kfree(sdio_dld);
-		return status;
-	}
-
-	sdio_dld->tty_drv = alloc_tty_driver(num_of_devices);
-
-	if (!sdio_dld->tty_drv) {
-		pr_err(MODULE_NAME ": %s - param ""sdio_dld->tty_drv"" is "
-				   "NULL.\n", __func__);
-		kfree(sdio_dld);
-		return -EINVAL;
-	}
-
-	sdio_dld_set_op_mode((enum sdio_dld_op_mode)sdio_op_mode);
-
-	/* according to op_mode, a different tty device is created */
-	if (sdio_dld->op_mode == SDIO_DLD_BOOT_TEST_MODE)
-		sdio_dld->tty_drv->name = TTY_SDIO_DEV_TEST;
-	else
-	    sdio_dld->tty_drv->name = TTY_SDIO_DEV;
-
-	sdio_dld->tty_drv->owner = THIS_MODULE;
-	sdio_dld->tty_drv->driver_name = "SDIO_Dloader";
-
-	/* uses dynamically assigned dev_t values */
-	sdio_dld->tty_drv->type = TTY_DRIVER_TYPE_SERIAL;
-	sdio_dld->tty_drv->subtype = SERIAL_TYPE_NORMAL;
-	sdio_dld->tty_drv->flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV
-				| TTY_DRIVER_RESET_TERMIOS;
-
-	/* initializing the tty driver */
-	sdio_dld->tty_drv->init_termios = tty_std_termios;
-	sdio_dld->tty_drv->init_termios.c_cflag =
-		B4800 | CS8 | CREAD | HUPCL | CLOCAL;
-	sdio_dld->tty_drv->init_termios.c_ispeed = INPUT_SPEED;
-	sdio_dld->tty_drv->init_termios.c_ospeed = OUTPUT_SPEED;
-
-	tty_set_operations(sdio_dld->tty_drv, &sdio_dloader_tty_ops);
-
-	status = tty_register_driver(sdio_dld->tty_drv);
-	if (status) {
-		put_tty_driver(sdio_dld->tty_drv);
-		pr_err(MODULE_NAME ": %s - tty_register_driver() failed\n",
-			__func__);
-
-		sdio_dld->tty_drv = NULL;
-		kfree(sdio_dld);
-		return status;
-	}
-
-	tty_dev = tty_register_device(sdio_dld->tty_drv, 0, NULL);
-	if (IS_ERR(tty_dev)) {
-		pr_err(MODULE_NAME ": %s - tty_register_device() "
-			"failed\n", __func__);
-		tty_unregister_driver(sdio_dld->tty_drv);
-		kfree(sdio_dld);
-		return PTR_ERR(tty_dev);
-	}
-
-	sdio_dld->sdioc_boot_func = SDIOC_CHAN_TO_FUNC_NUM(channel_number);
-	func_in_array = REAL_FUNC_TO_FUNC_IN_ARRAY(sdio_dld->sdioc_boot_func);
-	str_func = sdio_dld->card->sdio_func[func_in_array];
-	status = sdio_dld_init_func(str_func);
-	if (status) {
-		pr_err(MODULE_NAME ": %s - Failure in Function "
-		       "sdio_dld_init_func(). status=%d\n",
-		       __func__, status);
-		goto exit_err;
-	}
-
-#ifdef CONFIG_DEBUG_FS
-	sdio_dld_debug_init();
-#endif
-
-	sdio_claim_host(str_func);
-
-	/*
-	 * notifing the client by writing what mode we are by writing
-	 * to a special register
-	 */
-	status = sdio_memcpy_toio(str_func,
-				  SDIOC_OP_MODE_PTR,
-				  (void *)&sdio_dld->op_mode,
-				  sizeof(sdio_dld->op_mode));
-
-	sdio_release_host(str_func);
-
-	if (status) {
-		pr_err(MODULE_NAME ": %s - sdio_memcpy_toio() "
-		       "writing to OP_MODE_REGISTER failed. "
-		       "status=%d.\n",
-		       __func__, status);
-		goto exit_err;
-	}
-
-	return 0;
-
-exit_err:
-	tty_unregister_device(sdio_dld->tty_drv, 0);
-	result = tty_unregister_driver(sdio_dld->tty_drv);
-	if (result)
-		pr_err(MODULE_NAME ": %s - tty_unregister_driver() "
-		       "failed. result=%d\n", __func__, -result);
-	kfree(sdio_dld);
-	return status;
-}
-
-MODULE_LICENSE("GPL v2");
-MODULE_DESCRIPTION("SDIO Downloader");
-MODULE_AUTHOR("Yaniv Gardi <ygardi@codeaurora.org>");
-MODULE_VERSION(DRV_VERSION);
-
diff --git a/arch/arm/mach-msm/sdio_al_private.h b/arch/arm/mach-msm/sdio_al_private.h
deleted file mode 100644
index 3a5ab79..0000000
--- a/arch/arm/mach-msm/sdio_al_private.h
+++ /dev/null
@@ -1,267 +0,0 @@
-/* Copyright (c) 2011, The Linux Foundation. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 and
- * only version 2 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- */
-
-/*
- * SDIO-Abstraction-Layer internal interface.
- */
-
-#ifndef __SDIO_AL_PRIVATE__
-#define __SDIO_AL_PRIVATE__
-
-#include <linux/mmc/card.h>
-#include <linux/platform_device.h>
-#include <mach/sdio_al.h>
-
-#define DRV_VERSION "1.30"
-#define MODULE_NAME "sdio_al"
-#define SDIOC_CHAN_TO_FUNC_NUM(x)	((x)+2)
-#define REAL_FUNC_TO_FUNC_IN_ARRAY(x)	((x)-1)
-#define SDIO_PREFIX "SDIO_"
-#define PEER_CHANNEL_NAME_SIZE		4
-#define CHANNEL_NAME_SIZE (sizeof(SDIO_PREFIX) + PEER_CHANNEL_NAME_SIZE)
-#define SDIO_TEST_POSTFIX_SIZE 5
-#define MAX_NUM_OF_SDIO_DEVICES	2
-#define TEST_CH_NAME_SIZE (CHANNEL_NAME_SIZE + SDIO_TEST_POSTFIX_SIZE)
-
-struct sdio_al_device; /* Forward Declaration */
-
-enum sdio_channel_state {
-	SDIO_CHANNEL_STATE_INVALID,	 /* before reading software header */
-	SDIO_CHANNEL_STATE_IDLE,         /* channel valid, not opened    */
-	SDIO_CHANNEL_STATE_CLOSED,       /* was closed */
-	SDIO_CHANNEL_STATE_OPEN,	 /* opened */
-	SDIO_CHANNEL_STATE_CLOSING,      /* during flush, when closing */
-};
-/**
- * Peer SDIO-Client channel configuration.
- *
- *  @is_ready - channel is ready and the data is valid.
- *
- *  @max_rx_threshold - maximum rx threshold, according to the
- *		total buffers size on the peer pipe.
- *  @max_tx_threshold - maximum tx threshold, according to the
- *		total buffers size on the peer pipe.
- *  @tx_buf_size - size of a single buffer on the peer pipe; a
- *		transfer smaller than the buffer size still
- *		make the buffer unusable for the next transfer.
- * @max_packet_size
- * @is_host_ok_to_sleep - Host marks this bit when it's okay to
- *		sleep (no pending transactions)
- */
-struct peer_sdioc_channel_config {
-	u32 is_ready;
-	u32 max_rx_threshold; /* Downlink */
-	u32 max_tx_threshold; /* Uplink */
-	u32 tx_buf_size;
-	u32 max_packet_size;
-	u32 is_host_ok_to_sleep;
-	u32 is_packet_mode;
-	u32 peer_operation;
-	u32 is_low_latency_ch;
-	u32 reserved[23];
-};
-
-
-/**
- * Peer SDIO-Client channel statsitics.
- *
- * @last_any_read_avail - the last read avail in all the
- *		 channels including this channel.
- * @last_read_avail - the last read_avail that was read from HW
- *	    mailbox.
- * @last_old_read_avail - the last read_avail channel shadow.
- * @total_notifs - the total number of read notifications sent
- *	 to this channel client
- * @total_read_times - the total number of successful sdio_read
- *	     calls for this channel
- */
-struct sdio_channel_statistics {
-	int last_any_read_avail;
-	int last_read_avail;
-	int last_old_read_avail;
-	int total_notifs;
-	int total_read_times;
-};
-
-/**
- *  SDIO Channel context.
- *
- *  @name - channel name. Used by the caller to open the
- *	  channel.
- *
- *  @read_threshold - Threshold on SDIO-Client mailbox for Rx
- *				Data available bytes. When the limit exceed
- *				the SDIO-Client generates an interrupt to the
- *				host.
- *
- *  @write_threshold - Threshold on SDIO-Client mailbox for Tx
- *				Data available bytes. When the limit exceed
- *				the SDIO-Client generates an interrupt to the
- *				host.
- *
- *  @def_read_threshold - Default theshold on SDIO-Client for Rx
- *
- *  @min_write_avail - Threshold of minimal available bytes
- *					 to write. Below that threshold the host
- *					 will initiate reading the mailbox.
- *
- *  @poll_delay_msec - Delay between polling the mailbox. When
- *				 the SDIO-Client doesn't generates EOT
- *				 interrupt for Rx Available bytes, the host
- *				 should poll the SDIO-Client mailbox.
- *
- *  @is_packet_mode - The host get interrupt when a packet is
- *				available at the SDIO-client (pipe EOT
- *				indication).
- *
- *  @num - channel number.
- *
- *  @notify - Client's callback. Should not call sdio read/write.
- *
- *  @priv - Client's private context, provided to callback.
- *
- *  @is_valid - Channel is used (we have a list of
- *		SDIO_AL_MAX_CHANNELS and not all of them are in
- *		use).
- *
- *  @is_open - Channel is open.
- *
- *  @func - SDIO Function handle.
- *
- *  @rx_pipe_index - SDIO-Client Pipe Index for Rx Data.
- *
- *  @tx_pipe_index - SDIO-Client Pipe Index for Tx Data.
- *
- *  @ch_lock - Channel lock to protect channel specific Data
- *
- *  @rx_pending_bytes - Total number of Rx pending bytes, at Rx
- *				  packet list. Maximum of 16KB-1 limited by
- *				  SDIO-Client specification.
- *
- *  @read_avail - Available bytes to read.
- *
- *  @write_avail - Available bytes to write.
- *
- *  @rx_size_list_head - The head of Rx Pending Packets List.
- *
- *  @pdev - platform device - clients to probe for the sdio-al.
- *
- *  @signature - Context Validity check.
- *
- *  @sdio_al_dev - a pointer to the sdio_al_device instance of
- *   this channel
- *
- *   @statistics - channel statistics
- *
- */
-struct sdio_channel {
-	/* Channel Configuration Parameters*/
-	char name[CHANNEL_NAME_SIZE];
-	char ch_test_name[TEST_CH_NAME_SIZE];
-	int read_threshold;
-	int write_threshold;
-	int def_read_threshold;
-	int threshold_change_cnt;
-	int min_write_avail;
-	int poll_delay_msec;
-	int is_packet_mode;
-	int is_low_latency_ch;
-
-	struct peer_sdioc_channel_config ch_config;
-
-	/* Channel Info */
-	int num;
-
-	void (*notify)(void *priv, unsigned channel_event);
-	void *priv;
-
-	int state;
-
-	struct sdio_func *func;
-
-	int rx_pipe_index;
-	int tx_pipe_index;
-
-	struct mutex ch_lock;
-
-	u32 read_avail;
-	u32 write_avail;
-
-	u32 peer_tx_buf_size;
-
-	u16 rx_pending_bytes;
-
-	struct list_head rx_size_list_head;
-
-	struct platform_device *pdev;
-
-	u32 total_rx_bytes;
-	u32 total_tx_bytes;
-
-	u32 signature;
-
-	struct sdio_al_device *sdio_al_dev;
-
-	struct sdio_channel_statistics statistics;
-};
-
-/**
- * sdio_downloader_setup
- * initializes the TTY driver
- *
- * @card: a pointer to mmc_card.
- * @num_of_devices: number of devices.
- * @channel_number: channel number.
- * @return 0 on success or negative value on error.
- *
- * The TTY stack needs to know in advance how many devices it should
- * plan to manage. Use this call to set up the ports that will
- * be exported through SDIO.
- */
-int sdio_downloader_setup(struct mmc_card *card,
-			  unsigned int num_of_devices,
-			  int func_number,
-			  int(*func)(void));
-
-/**
- * test_channel_init
- * initializes a test channel
- *
- * @name: the channel name.
- * @return 0 on success or negative value on error.
- *
- */
-int test_channel_init(char *name);
-
-/**
- * sdio_al_register_lpm_cb
- * Allow the sdio_al test to register for lpm voting
- * notifications
- *
- * @device_handle: the device handle.
- * @wakeup_callback: callback function to be called when voting.
- *
- */
-void sdio_al_register_lpm_cb(void *device_handle,
-				       int(*lpm_callback)(void *, int));
-
-/**
- * sdio_al_unregister_lpm_cb
- * Allow the sdio_al test to unregister for lpm voting
- * notifications
- *
- * @device_handle: the device handle.
- *
- */
-void sdio_al_unregister_lpm_cb(void *device_handle);
-
-#endif /* __SDIO_AL_PRIVATE__ */
diff --git a/arch/arm/mach-msm/sdio_al_test.c b/arch/arm/mach-msm/sdio_al_test.c
deleted file mode 100644
index 2c9f675..0000000
--- a/arch/arm/mach-msm/sdio_al_test.c
+++ /dev/null
@@ -1,6500 +0,0 @@
-/* Copyright (c) 2010-2011, The Linux Foundation. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 and
- * only version 2 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- */
-
-/*
- * SDIO-Abstraction-Layer Test Module.
- *
- */
-
-#include <linux/module.h>
-#include <linux/device.h>
-#include <linux/workqueue.h>
-#include <linux/fs.h>
-#include <linux/cdev.h>
-#include <linux/sched.h>
-#include <linux/wait.h>
-#include <linux/delay.h>
-#include <linux/slab.h>
-#include <linux/random.h>
-#include <linux/platform_device.h>
-#include <mach/sdio_smem.h>
-#include <linux/wakelock.h>
-#include <linux/uaccess.h>
-
-#include "sdio_al_private.h"
-#include <linux/debugfs.h>
-
-#include <linux/kthread.h>
-enum lpm_test_msg_type {
-	LPM_NO_MSG,	/* 0 */
-	LPM_MSG_SEND,	/* 1 */
-	LPM_MSG_REC,	/* 2 */
-	LPM_SLEEP,	/* 3 */
-	LPM_WAKEUP,	/* 4 */
-	LPM_NOTIFY	/* 5 */
-};
-
-#define LPM_NO_MSG_NAME "LPM No Event"
-#define LPM_MSG_SEND_NAME "LPM Send Msg Event"
-#define LPM_MSG_REC_NAME "LPM Receive Msg Event"
-#define LPM_SLEEP_NAME "LPM Sleep Event"
-#define LPM_WAKEUP_NAME "LPM Wakeup Event"
-
-/** Module name string */
-#define TEST_MODULE_NAME "sdio_al_test"
-
-#define TEST_SIGNATURE 0x12345678
-#define TEST_CONFIG_SIGNATURE 0xBEEFCAFE
-
-#define MAX_XFER_SIZE (16*1024)
-#define SMEM_MAX_XFER_SIZE 0xBC000
-#define A2_MIN_PACKET_SIZE 5
-#define RMNT_PACKET_SIZE (4*1024)
-#define DUN_PACKET_SIZE (2*1024)
-#define CSVT_PACKET_SIZE 1700
-
-#define TEST_DBG(x...) if (test_ctx->runtime_debug) pr_info(x)
-
-#define LPM_TEST_NUM_OF_PACKETS 100
-#define LPM_MAX_OPEN_CHAN_PER_DEV 4
-#define LPM_ARRAY_SIZE	(7*LPM_TEST_NUM_OF_PACKETS*LPM_MAX_OPEN_CHAN_PER_DEV)
-#define SDIO_LPM_TEST "sdio_lpm_test_reading_task"
-#define LPM_TEST_CONFIG_SIGNATURE 0xDEADBABE
-#define LPM_MSG_NAME_SIZE 20
-#define MAX_STR_SIZE	10
-#define MAX_AVG_RTT_TIME_USEC	2500
-#define SDIO_RMNT_RTT_PACKET_SIZE	32
-#define SDIO_CSVT_RTT_PACKET_SIZE	1900
-
-#define A2_HEADER_OVERHEAD 8
-
-enum rx_process_state {
-	RX_PROCESS_PACKET_INIT,
-	RX_PROCESS_A2_HEADER,
-	RX_PROCESS_PACKET_DATA,
-};
-
-enum sdio_test_case_type {
-	SDIO_TEST_LOOPBACK_HOST,
-	SDIO_TEST_LOOPBACK_CLIENT,
-	SDIO_TEST_LPM_HOST_WAKER,
-	SDIO_TEST_LPM_CLIENT_WAKER,
-	SDIO_TEST_LPM_RANDOM,
-	SDIO_TEST_HOST_SENDER_NO_LP,
-	SDIO_TEST_CLOSE_CHANNEL,
-	SDIO_TEST_A2_VALIDATION,
-	/* The following tests are not part of the 9k tests and should be
-	 * kept last in case new tests are added
-	 */
-	SDIO_TEST_PERF,
-	SDIO_TEST_RTT,
-	SDIO_TEST_MODEM_RESET,
-};
-
-struct lpm_task {
-	struct task_struct *lpm_task;
-	const char *task_name;
-};
-
-struct lpm_entry_type {
-	enum lpm_test_msg_type msg_type;
-	char msg_name[LPM_MSG_NAME_SIZE];
-	u32 counter;
-	u32 current_ms;
-	u32 read_avail_mask;
-	char chan_name[CHANNEL_NAME_SIZE];
-};
-
-struct lpm_msg {
-	u32 signature;
-	u32 counter;
-	u32 reserve1;
-	u32 reserve2;
-};
-
-struct test_config_msg {
-	u32 signature;
-	u32 test_case;
-	u32 test_param;
-	u32 num_packets;
-	u32 num_iterations;
-};
-
-struct test_result_msg {
-	u32 signature;
-	u32 is_successful;
-};
-
-struct test_work {
-	struct work_struct work;
-	struct test_channel *test_ch;
-};
-
-enum sdio_channels_ids {
-	SDIO_RPC,
-	SDIO_QMI,
-	SDIO_RMNT,
-	SDIO_DIAG,
-	SDIO_DUN,
-	SDIO_SMEM,
-	SDIO_CSVT,
-	SDIO_MAX_CHANNELS
-};
-
-enum sdio_test_results {
-	TEST_NO_RESULT,
-	TEST_FAILED,
-	TEST_PASSED
-};
-
-enum sdio_lpm_vote_state {
-	SDIO_NO_VOTE,
-	SDIO_VOTE_FOR_SLEEP,
-	SDIO_VOTE_AGAINST_SLEEP
-};
-
-struct sdio_test_device {
-	int open_channels_counter_to_recv;
-	int open_channels_counter_to_send;
-	struct lpm_entry_type *lpm_arr;
-	int array_size;
-	void *sdio_al_device;
-	spinlock_t lpm_array_lock;
-	unsigned long lpm_array_lock_flags;
-	u32 next_avail_entry_in_array;
-	struct lpm_task lpm_test_task;
-	u32 next_mask_id;
-	u32 read_avail_mask;
-	int modem_result_per_dev;
-	int final_result_per_dev;
-};
-
-struct test_channel {
-	struct sdio_channel *ch;
-
-	char name[CHANNEL_NAME_SIZE];
-	int ch_id;
-
-	struct sdio_test_device *test_device;
-
-	u32 *buf;
-	u32 buf_size;
-
-	struct workqueue_struct *workqueue;
-	struct test_work test_work;
-
-	u32 rx_bytes;
-	u32 tx_bytes;
-
-	wait_queue_head_t   wait_q;
-	atomic_t rx_notify_count;
-	atomic_t tx_notify_count;
-	atomic_t any_notify_count;
-	atomic_t wakeup_client;
-	atomic_t card_detected_event;
-
-	int wait_counter;
-
-	int is_used;
-	int test_type;
-	int ch_ready;
-
-	struct test_config_msg config_msg;
-
-	int test_completed;
-	int test_result;
-	struct timer_list timer;
-	int timer_interval_ms;
-
-	struct timer_list timeout_timer;
-	int timeout_ms;
-	void *sdio_al_device;
-	int is_ok_to_sleep;
-	unsigned int packet_length;
-	int random_packet_size;
-	int next_index_in_sent_msg_per_chan;
-	int channel_mask_id;
-	int modem_result_per_chan;
-	int notify_counter_per_chan;
-	int max_burst_size;        /* number of writes before close/open */
-	int card_removed;
-};
-
-struct sdio_al_test_debug {
-	u32 dun_throughput;
-	u32 rmnt_throughput;
-	struct dentry *debug_root;
-	struct dentry *debug_test_result;
-	struct dentry *debug_dun_throughput;
-	struct dentry *debug_rmnt_throughput;
-	struct dentry *rpc_sender_test;
-	struct dentry *rpc_qmi_diag_sender_test;
-	struct dentry *smem_test;
-	struct dentry *smem_rpc_test;
-	struct dentry *rmnet_a2_validation_test;
-	struct dentry *dun_a2_validation_test;
-	struct dentry *rmnet_a2_perf_test;
-	struct dentry *dun_a2_perf_test;
-	struct dentry *csvt_a2_perf_test;
-	struct dentry *rmnet_dun_a2_perf_test;
-	struct dentry *rpc_sender_rmnet_a2_perf_test;
-	struct dentry *all_channels_test;
-	struct dentry *host_sender_no_lp_diag_test;
-	struct dentry *host_sender_no_lp_diag_rpc_test;
-	struct dentry *rmnet_small_packets_test;
-	struct dentry *rmnet_rtt_test;
-	struct dentry *csvt_rtt_test;
-	struct dentry *modem_reset_rpc_test;
-	struct dentry *modem_reset_rmnet_test;
-	struct dentry *modem_reset_channels_4bit_dev_test;
-	struct dentry *modem_reset_channels_8bit_dev_test;
-	struct dentry *modem_reset_all_channels_test;
-	struct dentry *open_close_test;
-	struct dentry *open_close_dun_rmnet_test;
-	struct dentry *close_chan_lpm_test;
-	struct dentry *lpm_test_client_wakes_host_test;
-	struct dentry *lpm_test_host_wakes_client_test;
-	struct dentry *lpm_test_random_single_channel_test;
-	struct dentry *lpm_test_random_multi_channel_test;
-};
-
-struct test_context {
-	dev_t dev_num;
-	struct device *dev;
-	struct cdev *cdev;
-	int number_of_active_devices;
-	int max_number_of_devices;
-
-	struct sdio_test_device test_dev_arr[MAX_NUM_OF_SDIO_DEVICES];
-
-	struct test_channel *test_ch;
-
-	struct test_channel *test_ch_arr[SDIO_MAX_CHANNELS];
-
-	long testcase;
-
-	const char *name;
-
-	int exit_flag;
-
-	u32 signature;
-
-	int runtime_debug;
-
-	struct platform_device *smem_pdev;
-	struct sdio_smem_client *sdio_smem;
-	int smem_was_init;
-	u8 *smem_buf;
-	uint32_t smem_counter;
-
-	struct platform_device *csvt_app_pdev;
-
-	wait_queue_head_t   wait_q;
-	int test_completed;
-	int test_result;
-	struct sdio_al_test_debug debug;
-
-	struct wake_lock wake_lock;
-
-	unsigned int lpm_pseudo_random_seed;
-};
-
-/* FORWARD DECLARATIONS */
-static int set_params_loopback_9k(struct test_channel *tch);
-static int set_params_smem_test(struct test_channel *tch);
-static int set_params_a2_validation(struct test_channel *tch);
-static int set_params_a2_perf(struct test_channel *tch);
-static int set_params_8k_sender_no_lp(struct test_channel *tch);
-static int set_params_a2_small_pkts(struct test_channel *tch);
-static int set_params_rtt(struct test_channel *tch);
-static int set_params_loopback_9k_close(struct test_channel *tch);
-static int close_channel_lpm_test(int channel_num);
-static int set_params_lpm_test(struct test_channel *tch,
-				enum sdio_test_case_type test,
-				int timer_interval_ms);
-static void set_pseudo_random_seed(void);
-static int set_params_modem_reset(struct test_channel *tch);
-static int test_start(void);
-static void rx_cleanup(struct test_channel *test_ch, int *rx_packet_count);
-static void sdio_al_test_cleanup_channels(void);
-static void notify(void *priv, unsigned channel_event);
-#ifdef CONFIG_MSM_SDIO_SMEM
-static int sdio_smem_open(struct sdio_smem_client *sdio_smem);
-#endif
-
-/*
- * Seed for pseudo random time sleeping in Random LPM test.
- * If not set, current time in jiffies is used.
- */
-static unsigned int seed;
-module_param(seed, int, 0);
-static struct test_context *test_ctx;
-
-static void sdio_al_test_initial_dev_and_chan(struct test_context *test_ctx)
-{
-	int i = 0;
-
-	if (!test_ctx) {
-		pr_err(TEST_MODULE_NAME ":%s - test_ctx is NULL.\n", __func__);
-		return;
-	}
-
-	for (i = 0 ; i < MAX_NUM_OF_SDIO_DEVICES ; ++i)
-		test_ctx->test_dev_arr[i].sdio_al_device = NULL;
-
-	for (i = 0; i < SDIO_MAX_CHANNELS; i++) {
-		struct test_channel *tch = test_ctx->test_ch_arr[i];
-		if (!tch)
-			continue;
-		tch->is_used = 0;
-	}
-
-	sdio_al_test_cleanup_channels();
-}
-
-#ifdef CONFIG_DEBUG_FS
-
-static int message_repeat;
-
-static int sdio_al_test_extract_number(const char __user *buf,
-					size_t count)
-{
-	int ret = 0;
-	int number = -1;
-	char local_buf[MAX_STR_SIZE] = {0};
-	char *start = NULL;
-
-	if (count > MAX_STR_SIZE) {
-		pr_err(TEST_MODULE_NAME ": %s - MAX_STR_SIZE(%d) < count(%d). "
-		       "Please choose smaller number\n",
-		       __func__, MAX_STR_SIZE, (int)count);
-		return -EINVAL;
-	}
-
-	if (copy_from_user(local_buf, buf, count)) {
-		pr_err(TEST_MODULE_NAME ": %s - copy_from_user() failed\n",
-		       __func__);
-		return -EINVAL;
-	}
-
-	/* adding null termination to the string */
-	local_buf[count] = '\0';
-
-	/* stripping leading and trailing white spaces */
-	start = strstrip(local_buf);
-
-	ret = kstrtoint(start, 10, &number);
-
-	if (ret) {
-		pr_err(TEST_MODULE_NAME " : %s - kstrtoint() failed\n",
-		       __func__);
-		return ret;
-	}
-
-	return number;
-}
-
-static int sdio_al_test_open(struct inode *inode, struct file *file)
-{
-	file->private_data = inode->i_private;
-	message_repeat = 1;
-	return 0;
-}
-
-static void sdio_al_test_cleanup_channels(void)
-{
-	int channel_num;
-	int dummy = 0;
-
-	for (channel_num = 0 ; channel_num < SDIO_MAX_CHANNELS ;
-	      ++channel_num) {
-		if (channel_num == SDIO_SMEM)
-			continue;
-
-		 rx_cleanup(test_ctx->test_ch_arr[channel_num], &dummy);
-	}
-
-	return;
-}
-
-/* RPC SENDER TEST */
-static ssize_t rpc_sender_test_write(struct file *file,
-				      const char __user *buf,
-				      size_t count,
-				      loff_t *ppos)
-{
-	int ret = 0;
-	int i = 0;
-	int number = -1;
-
-	pr_info(TEST_MODULE_NAME "-- RPC SENDER TEST --\n");
-
-	number = sdio_al_test_extract_number(buf, count);
-
-	if (number < 0) {
-		pr_err(TEST_MODULE_NAME " : %s - sdio_al_test_extract_number() "
-		       "failed. number = %d\n", __func__, number);
-		return count;
-	}
-
-	for (i = 0 ; i < number ; ++i) {
-		pr_info(TEST_MODULE_NAME " - Cycle # %d / %d\n", i+1, number);
-		pr_info(TEST_MODULE_NAME " ===================");
-
-		sdio_al_test_initial_dev_and_chan(test_ctx);
-
-		set_params_loopback_9k(test_ctx->test_ch_arr[SDIO_RPC]);
-
-		ret = test_start();
-
-		if (ret)
-			break;
-	}
-
-	return count;
-}
-
-static ssize_t rpc_sender_test_read(struct file *file,
-				     char __user *buffer,
-				     size_t count,
-				     loff_t *offset)
-{
-	memset((void *)buffer, 0, count);
-
-	snprintf(buffer, count,
-		 "\nRPC_SENDER_TEST\n"
-		 "===============\n"
-		 "Description:\n"
-		 "TBD\n");
-
-	if (message_repeat == 1) {
-		message_repeat = 0;
-		return strnlen(buffer, count);
-	} else {
-		return 0;
-	}
-}
-
-const struct file_operations rpc_sender_test_ops = {
-	.open = sdio_al_test_open,
-	.write = rpc_sender_test_write,
-	.read = rpc_sender_test_read,
-};
-
-/* RPC, QMI & DIAG SENDER TEST */
-static ssize_t rpc_qmi_diag_sender_test_write(struct file *file,
-					       const char __user *buf,
-					       size_t count,
-					       loff_t *ppos)
-{
-	int ret = 0;
-	int i = 0;
-	int number = -1;
-
-	pr_info(TEST_MODULE_NAME "-- RPC, QMI AND DIAG SENDER TEST --\n");
-
-	number = sdio_al_test_extract_number(buf, count);
-
-	if (number < 0) {
-		pr_err(TEST_MODULE_NAME " : %s - sdio_al_test_extract_number() "
-		       "failed. number = %d\n", __func__, number);
-		return count;
-	}
-
-	for (i = 0 ; i < number ; ++i) {
-		pr_info(TEST_MODULE_NAME " - Cycle # %d / %d\n", i+1, number);
-		pr_info(TEST_MODULE_NAME " ===================");
-
-		sdio_al_test_initial_dev_and_chan(test_ctx);
-
-		set_params_loopback_9k(test_ctx->test_ch_arr[SDIO_RPC]);
-		set_params_loopback_9k(test_ctx->test_ch_arr[SDIO_QMI]);
-		set_params_loopback_9k(test_ctx->test_ch_arr[SDIO_DIAG]);
-
-		ret = test_start();
-
-		if (ret)
-			break;
-	}
-
-	return count;
-}
-
-static ssize_t rpc_qmi_diag_sender_test_read(struct file *file,
-					      char __user
-					      *buffer, size_t count,
-					      loff_t *offset)
-{
-	memset((void *)buffer, 0, count);
-
-	snprintf(buffer, count,
-		 "\nRPC_QMI_DIAG_SENDER_TEST\n"
-		 "========================\n"
-		 "Description:\n"
-		 "TBD\n");
-
-
-	if (message_repeat == 1) {
-		message_repeat = 0;
-		return strnlen(buffer, count);
-	} else {
-		return 0;
-	}
-}
-
-const struct file_operations rpc_qmi_diag_sender_test_ops = {
-	.open = sdio_al_test_open,
-	.write = rpc_qmi_diag_sender_test_write,
-	.read = rpc_qmi_diag_sender_test_read,
-};
-
-/* SMEM TEST */
-static ssize_t smem_test_write(struct file *file,
-				const char __user *buf,
-				size_t count,
-				loff_t *ppos)
-{
-	int ret = 0;
-	int i = 0;
-	int number = -1;
-
-	pr_info(TEST_MODULE_NAME "-- SMEM TEST --\n");
-
-	number = sdio_al_test_extract_number(buf, count);
-
-	if (number < 0) {
-		pr_err(TEST_MODULE_NAME " : %s - sdio_al_test_extract_number() "
-		       "failed. number = %d\n", __func__, number);
-		return count;
-	}
-
-	for (i = 0 ; i < number ; ++i) {
-		pr_info(TEST_MODULE_NAME " - Cycle # %d / %d\n", i+1, number);
-		pr_info(TEST_MODULE_NAME " ===================");
-
-		sdio_al_test_initial_dev_and_chan(test_ctx);
-
-		set_params_smem_test(test_ctx->test_ch_arr[SDIO_SMEM]);
-
-		ret = test_start();
-
-		if (ret)
-			break;
-	}
-
-	return count;
-}
-
-static ssize_t smem_test_read(struct file *file,
-			       char __user *buffer,
-			       size_t count,
-			       loff_t *offset)
-{
-	memset((void *)buffer, 0, count);
-
-	snprintf(buffer, count,
-		 "\nSMEM_TEST\n"
-		 "=========\n"
-		 "Description:\n"
-		 "TBD\n");
-
-	if (message_repeat == 1) {
-		message_repeat = 0;
-		return strnlen(buffer, count);
-	} else {
-		return 0;
-	}
-}
-
-const struct file_operations smem_test_ops = {
-	.open = sdio_al_test_open,
-	.write = smem_test_write,
-	.read = smem_test_read,
-};
-
-/* SMEM & RPC TEST */
-static ssize_t smem_rpc_test_write(struct file *file,
-				    const char __user *buf,
-				    size_t count,
-				    loff_t *ppos)
-{
-	int ret = 0;
-	int i = 0;
-	int number = -1;
-
-	pr_info(TEST_MODULE_NAME "-- SMEM AND RPC TEST --\n");
-
-	number = sdio_al_test_extract_number(buf, count);
-
-	if (number < 0) {
-		pr_err(TEST_MODULE_NAME " : %s - sdio_al_test_extract_number() "
-		       "failed. number = %d\n", __func__, number);
-		return count;
-	}
-
-	for (i = 0 ; i < number ; ++i) {
-		pr_info(TEST_MODULE_NAME " - Cycle # %d / %d\n", i+1, number);
-		pr_info(TEST_MODULE_NAME " ===================");
-
-		sdio_al_test_initial_dev_and_chan(test_ctx);
-
-		set_params_loopback_9k(test_ctx->test_ch_arr[SDIO_RPC]);
-		set_params_smem_test(test_ctx->test_ch_arr[SDIO_SMEM]);
-
-		ret = test_start();
-
-		if (ret)
-			break;
-	}
-
-	return count;
-}
-
-static ssize_t smem_rpc_test_read(struct file *file,
-				   char __user *buffer,
-				   size_t count,
-				   loff_t *offset)
-{
-	memset((void *)buffer, 0, count);
-
-	snprintf(buffer, count,
-		 "\nSMEM_RPC_TEST\n"
-		 "=============\n"
-		 "Description:\n"
-		 "TBD\n");
-
-	if (message_repeat == 1) {
-		message_repeat = 0;
-		return strnlen(buffer, count);
-	} else {
-		return 0;
-	}
-}
-
-const struct file_operations smem_rpc_test_ops = {
-	.open = sdio_al_test_open,
-	.write = smem_rpc_test_write,
-	.read = smem_rpc_test_read,
-};
-
-/* RMNET A2 VALIDATION TEST */
-static ssize_t rmnet_a2_validation_test_write(struct file *file,
-						const char __user *buf,
-						size_t count,
-						loff_t *ppos)
-{
-	int ret = 0;
-	int i = 0;
-	int number = -1;
-
-	pr_info(TEST_MODULE_NAME "-- RMNET A2 VALIDATION TEST --\n");
-
-	number = sdio_al_test_extract_number(buf, count);
-
-	if (number < 0) {
-		pr_err(TEST_MODULE_NAME " : %s - sdio_al_test_extract_number() "
-		       "failed. number = %d\n", __func__, number);
-		return count;
-	}
-
-	for (i = 0 ; i < number ; ++i) {
-		pr_info(TEST_MODULE_NAME " - Cycle # %d / %d\n", i+1, number);
-		pr_info(TEST_MODULE_NAME " ===================");
-
-		sdio_al_test_initial_dev_and_chan(test_ctx);
-
-		set_params_a2_validation(test_ctx->test_ch_arr[SDIO_RMNT]);
-
-		ret = test_start();
-
-		if (ret)
-			break;
-	}
-
-	return count;
-}
-
-static ssize_t rmnet_a2_validation_test_read(struct file *file,
-						char __user *buffer,
-						size_t count,
-						loff_t *offset)
-{
-	memset((void *)buffer, 0, count);
-
-	snprintf(buffer, count,
-		 "\nRMNET_A2_VALIDATION_TEST\n"
-		 "=========================\n"
-		 "Description:\n"
-		 "In this test, the HOST sends multiple packets to the\n"
-		 "CLIENT and validates the packets loop backed from A2\n"
-		 "for the RMNET channel.\n\n"
-		 "END OF DESCRIPTION\n");
-
-	if (message_repeat == 1) {
-		message_repeat = 0;
-		return strnlen(buffer, count);
-	} else {
-		return 0;
-	}
-}
-
-const struct file_operations rmnet_a2_validation_test_ops = {
-	.open = sdio_al_test_open,
-	.write = rmnet_a2_validation_test_write,
-	.read = rmnet_a2_validation_test_read,
-};
-
-/* DUN A2 VALIDATION TEST */
-static ssize_t dun_a2_validation_test_write(struct file *file,
-						const char __user *buf,
-						size_t count,
-						loff_t *ppos)
-{
-	int ret = 0;
-	int i = 0;
-	int number = -1;
-
-	pr_info(TEST_MODULE_NAME "-- DUN A2 VALIDATION TEST --\n");
-
-	number = sdio_al_test_extract_number(buf, count);
-
-	if (number < 0) {
-		pr_err(TEST_MODULE_NAME " : %s - sdio_al_test_extract_number() "
-		       "failed. number = %d\n", __func__, number);
-		return count;
-	}
-
-	for (i = 0 ; i < number ; ++i) {
-		pr_info(TEST_MODULE_NAME " - Cycle # %d / %d\n", i+1, number);
-		pr_info(TEST_MODULE_NAME " ===================");
-
-		sdio_al_test_initial_dev_and_chan(test_ctx);
-
-		set_params_a2_validation(test_ctx->test_ch_arr[SDIO_DUN]);
-
-		ret = test_start();
-
-		if (ret)
-			break;
-	}
-
-	return count;
-}
-
-static ssize_t dun_a2_validation_test_read(struct file *file,
-						char __user *buffer,
-						size_t count,
-						loff_t *offset)
-{
-	memset((void *)buffer, 0, count);
-
-	snprintf(buffer, count,
-		"\nDUN_A2_VALIDATION_TEST\n"
-		"=========================\n"
-		"Description:\n"
-		"In this test, the HOST sends multiple packets to the\n"
-		"CLIENT and validates the packets loop backed from A2\n"
-		"for the DUN channel.\n\n"
-		"END OF DESCRIPTION\n");
-
-	if (message_repeat == 1) {
-		message_repeat = 0;
-		return strnlen(buffer, count);
-	} else {
-		return 0;
-	}
-}
-
-const struct file_operations dun_a2_validation_test_ops = {
-	.open = sdio_al_test_open,
-	.write = dun_a2_validation_test_write,
-	.read = dun_a2_validation_test_read,
-};
-
-/* RMNET A2 PERFORMANCE TEST */
-static ssize_t rmnet_a2_perf_test_write(struct file *file,
-					 const char __user *buf,
-					 size_t count,
-					 loff_t *ppos)
-{
-	int ret = 0;
-	int i = 0;
-	int number = -1;
-
-	pr_info(TEST_MODULE_NAME "-- RMNET A2 PERFORMANCE TEST --\n");
-
-	number = sdio_al_test_extract_number(buf, count);
-
-	if (number < 0) {
-		pr_err(TEST_MODULE_NAME " : %s - sdio_al_test_extract_number() "
-		       "failed. number = %d\n", __func__, number);
-		return count;
-	}
-
-	for (i = 0 ; i < number ; ++i) {
-		pr_info(TEST_MODULE_NAME " - Cycle # %d / %d\n", i+1, number);
-		pr_info(TEST_MODULE_NAME " ===================");
-
-		sdio_al_test_initial_dev_and_chan(test_ctx);
-
-		set_params_a2_perf(test_ctx->test_ch_arr[SDIO_RMNT]);
-
-		ret = test_start();
-
-		if (ret)
-			break;
-	}
-
-	return count;
-}
-
-static ssize_t rmnet_a2_perf_test_read(struct file *file,
-					char __user *buffer,
-					size_t count,
-					loff_t *offset)
-{
-	memset((void *)buffer, 0, count);
-
-	snprintf(buffer, count,
-		 "\nRMNET_A2_PERFORMANCE_TEST\n"
-		 "=========================\n"
-		 "Description:\n"
-		 "TBD\n");
-
-	if (message_repeat == 1) {
-		message_repeat = 0;
-		return strnlen(buffer, count);
-	} else {
-		return 0;
-	}
-}
-
-const struct file_operations rmnet_a2_perf_test_ops = {
-	.open = sdio_al_test_open,
-	.write = rmnet_a2_perf_test_write,
-	.read = rmnet_a2_perf_test_read,
-};
-
-/* DUN A2 PERFORMANCE TEST */
-static ssize_t dun_a2_perf_test_write(struct file *file,
-				       const char __user *buf,
-				       size_t count,
-				       loff_t *ppos)
-{
-	int ret = 0;
-	int i = 0;
-	int number = -1;
-
-	pr_info(TEST_MODULE_NAME "-- DUN A2 PERFORMANCE TEST --\n");
-
-	number = sdio_al_test_extract_number(buf, count);
-
-	if (number < 0) {
-		pr_err(TEST_MODULE_NAME " : %s - sdio_al_test_extract_number() "
-		       "failed. number = %d\n", __func__, number);
-		return count;
-	}
-
-	for (i = 0 ; i < number ; ++i) {
-		pr_info(TEST_MODULE_NAME " - Cycle # %d / %d\n", i+1, number);
-		pr_info(TEST_MODULE_NAME " ===================");
-
-		sdio_al_test_initial_dev_and_chan(test_ctx);
-
-		set_params_a2_perf(test_ctx->test_ch_arr[SDIO_DUN]);
-
-		ret = test_start();
-
-		if (ret)
-			break;
-	}
-
-	return count;
-}
-
-static ssize_t dun_a2_perf_test_read(struct file *file,
-				      char __user *buffer,
-				      size_t count,
-				      loff_t *offset)
-{
-	memset((void *)buffer, 0, count);
-
-	snprintf(buffer, count,
-		 "\nDUN_A2_PERFORMANCE_TEST\n"
-		 "=======================\n"
-		 "Description:\n"
-		 "TBD\n");
-
-	if (message_repeat == 1) {
-		message_repeat = 0;
-		return strnlen(buffer, count);
-	} else {
-		return 0;
-	}
-}
-
-const struct file_operations dun_a2_perf_test_ops = {
-	.open = sdio_al_test_open,
-	.write = dun_a2_perf_test_write,
-	.read = dun_a2_perf_test_read,
-};
-
-/* CSVT A2 PERFORMANCE TEST */
-static ssize_t csvt_a2_perf_test_write(struct file *file,
-					const char __user *buf,
-					size_t count,
-					loff_t *ppos)
-{
-	int ret = 0;
-	int i = 0;
-	int number = -1;
-
-	pr_info(TEST_MODULE_NAME "-- CSVT A2 PERFORMANCE TEST --\n");
-
-	number = sdio_al_test_extract_number(buf, count);
-
-	if (number < 0) {
-		pr_err(TEST_MODULE_NAME " : %s - sdio_al_test_extract_number() "
-		       "failed. number = %d\n", __func__, number);
-		return count;
-	}
-
-	for (i = 0 ; i < number ; ++i) {
-		pr_info(TEST_MODULE_NAME " - Cycle # %d / %d\n", i+1, number);
-		pr_info(TEST_MODULE_NAME " ===================");
-
-		sdio_al_test_initial_dev_and_chan(test_ctx);
-
-		set_params_a2_perf(test_ctx->test_ch_arr[SDIO_CSVT]);
-
-		ret = test_start();
-
-		if (ret)
-			break;
-	}
-
-	return count;
-}
-
-static ssize_t csvt_a2_perf_test_read(struct file *file,
-				       char __user *buffer,
-				       size_t count,
-				       loff_t *offset)
-{
-	memset((void *)buffer, 0, count);
-
-	snprintf(buffer, count,
-		 "\nCSVT_A2_PERFORMANCE_TEST\n"
-		 "========================\n"
-		 "Description:\n"
-		 "Loopback test on the CSVT Channel, in order to check "
-		 "throughput performance.\n"
-		 "Packet size that are sent on the CSVT channel in this "
-		 "test is %d.bytes\n\n"
-		 "END OF DESCRIPTION\n", CSVT_PACKET_SIZE);
-
-	if (message_repeat == 1) {
-		message_repeat = 0;
-		return strnlen(buffer, count);
-	} else {
-		return 0;
-	}
-}
-
-const struct file_operations csvt_a2_perf_test_ops = {
-	.open = sdio_al_test_open,
-	.write = csvt_a2_perf_test_write,
-	.read = csvt_a2_perf_test_read,
-};
-
-/* RMNET DUN A2 PERFORMANCE TEST */
-static ssize_t rmnet_dun_a2_perf_test_write(struct file *file,
-					     const char __user *buf,
-					     size_t count,
-					     loff_t *ppos)
-{
-	int ret = 0;
-	int i = 0;
-	int number = -1;
-
-	pr_info(TEST_MODULE_NAME "-- RMNET AND DUN A2 PERFORMANCE TEST --\n");
-
-	number = sdio_al_test_extract_number(buf, count);
-
-	if (number < 0) {
-		pr_err(TEST_MODULE_NAME " : %s - sdio_al_test_extract_number() "
-		       "failed. number = %d\n", __func__, number);
-		return count;
-	}
-
-	for (i = 0 ; i < number ; ++i) {
-		pr_info(TEST_MODULE_NAME " - Cycle # %d / %d\n", i+1, number);
-		pr_info(TEST_MODULE_NAME " ===================");
-
-		sdio_al_test_initial_dev_and_chan(test_ctx);
-
-		set_params_a2_perf(test_ctx->test_ch_arr[SDIO_RMNT]);
-		set_params_a2_perf(test_ctx->test_ch_arr[SDIO_DUN]);
-
-		ret = test_start();
-
-		if (ret)
-			break;
-	}
-
-	return count;
-}
-
-static ssize_t rmnet_dun_a2_perf_test_read(struct file *file,
-					    char __user *buffer,
-					    size_t count,
-					    loff_t *offset)
-{
-	memset((void *)buffer, 0, count);
-
-	snprintf(buffer, count,
-		 "\nRMNET_DUN_A2_PERFORMANCE_TEST\n"
-		 "=============================\n"
-		 "Description:\n"
-		 "TBD\n");
-
-	if (message_repeat == 1) {
-		message_repeat = 0;
-		return strnlen(buffer, count);
-	} else {
-		return 0;
-	}
-}
-
-const struct file_operations rmnet_dun_a2_perf_test_ops = {
-	.open = sdio_al_test_open,
-	.write = rmnet_dun_a2_perf_test_write,
-	.read = rmnet_dun_a2_perf_test_read,
-};
-
-/* RPC SENDER & RMNET A2 PERFORMANCE TEST */
-static ssize_t rpc_sender_rmnet_a2_perf_test_write(struct file *file,
-						    const char __user *buf,
-						    size_t count,
-						    loff_t *ppos)
-{
-	int ret = 0;
-	int i = 0;
-	int number = -1;
-
-	pr_info(TEST_MODULE_NAME "--RPC SENDER AND RMNET A2 "
-		"PERFORMANCE --\n");
-
-	number = sdio_al_test_extract_number(buf, count);
-
-	if (number < 0) {
-		pr_err(TEST_MODULE_NAME " : %s - sdio_al_test_extract_number() "
-		       "failed. number = %d\n", __func__, number);
-		return count;
-	}
-
-	for (i = 0 ; i < number ; ++i) {
-		pr_info(TEST_MODULE_NAME " - Cycle # %d / %d\n", i+1, number);
-		pr_info(TEST_MODULE_NAME " ===================");
-
-		sdio_al_test_initial_dev_and_chan(test_ctx);
-
-		set_params_loopback_9k(test_ctx->test_ch_arr[SDIO_RPC]);
-		set_params_a2_perf(test_ctx->test_ch_arr[SDIO_RMNT]);
-
-		ret = test_start();
-
-		if (ret)
-			break;
-	}
-
-	return count;
-}
-
-static ssize_t rpc_sender_rmnet_a2_perf_test_read(struct file *file,
-						   char __user *buffer,
-						   size_t count,
-						   loff_t *offset)
-{
-	memset((void *)buffer, 0, count);
-
-	snprintf(buffer, count,
-		 "\nRPC_SENDER_RMNET_A2_PERFORMANCE_TEST\n"
-		 "====================================\n"
-		 "Description:\n"
-		 "TBD\n");
-
-	if (message_repeat == 1) {
-		message_repeat = 0;
-		return strnlen(buffer, count);
-	} else {
-		return 0;
-	}
-}
-
-const struct file_operations rpc_sender_rmnet_a2_perf_test_ops = {
-	.open = sdio_al_test_open,
-	.write = rpc_sender_rmnet_a2_perf_test_write,
-	.read = rpc_sender_rmnet_a2_perf_test_read,
-};
-
-/* ALL CHANNELS TEST */
-static ssize_t all_channels_test_write(struct file *file,
-					const char __user *buf,
-					size_t count,
-					loff_t *ppos)
-{
-	int ret = 0;
-	int i = 0;
-	int number = -1;
-
-	pr_info(TEST_MODULE_NAME "-- ALL THE CHANNELS TEST --\n");
-
-	number = sdio_al_test_extract_number(buf, count);
-
-	if (number < 0) {
-		pr_err(TEST_MODULE_NAME " : %s - sdio_al_test_extract_number() "
-		       "failed. number = %d\n", __func__, number);
-		return count;
-	}
-
-	for (i = 0 ; i < number ; ++i) {
-		pr_info(TEST_MODULE_NAME " - Cycle # %d / %d\n", i+1, number);
-		pr_info(TEST_MODULE_NAME " ===================");
-
-		sdio_al_test_initial_dev_and_chan(test_ctx);
-
-		set_params_loopback_9k(test_ctx->test_ch_arr[SDIO_RPC]);
-		set_params_loopback_9k(test_ctx->test_ch_arr[SDIO_QMI]);
-		set_params_loopback_9k(test_ctx->test_ch_arr[SDIO_DIAG]);
-		set_params_a2_perf(test_ctx->test_ch_arr[SDIO_RMNT]);
-		set_params_a2_perf(test_ctx->test_ch_arr[SDIO_DUN]);
-		set_params_smem_test(test_ctx->test_ch_arr[SDIO_SMEM]);
-		set_params_a2_perf(test_ctx->test_ch_arr[SDIO_CSVT]);
-
-		ret = test_start();
-
-		if (ret)
-			break;
-	}
-
-	return count;
-}
-
-static ssize_t all_channels_test_read(struct file *file,
-				       char __user *buffer,
-				       size_t count,
-				       loff_t *offset)
-{
-	memset((void *)buffer, 0, count);
-
-	snprintf(buffer, count,
-		 "\nALL_CHANNELS_TEST\n"
-		 "=================\n"
-		 "Description:\n"
-		 "TBD\n");
-
-	if (message_repeat == 1) {
-		message_repeat = 0;
-		return strnlen(buffer, count);
-	} else {
-		return 0;
-	}
-}
-
-const struct file_operations all_channels_test_ops = {
-	.open = sdio_al_test_open,
-	.write = all_channels_test_write,
-	.read = all_channels_test_read,
-};
-
-/* HOST SENDER NO LP DIAG TEST */
-static ssize_t host_sender_no_lp_diag_test_write(struct file *file,
-						  const char __user *buf,
-						  size_t count,
-						  loff_t *ppos)
-{
-	int ret = 0;
-	int i = 0;
-	int number = -1;
-
-	pr_info(TEST_MODULE_NAME "-- HOST SENDER NO LP FOR DIAG TEST --");
-
-	number = sdio_al_test_extract_number(buf, count);
-
-	if (number < 0) {
-		pr_err(TEST_MODULE_NAME " : %s - sdio_al_test_extract_number() "
-		       "failed. number = %d\n", __func__, number);
-		return count;
-	}
-
-	for (i = 0 ; i < number ; ++i) {
-		pr_info(TEST_MODULE_NAME " - Cycle # %d / %d\n", i+1, number);
-		pr_info(TEST_MODULE_NAME " ===================");
-
-		sdio_al_test_initial_dev_and_chan(test_ctx);
-
-		set_params_8k_sender_no_lp(test_ctx->test_ch_arr[SDIO_DIAG]);
-
-		ret = test_start();
-
-		if (ret)
-			break;
-	}
-
-	return count;
-}
-
-static ssize_t host_sender_no_lp_diag_test_read(struct file *file,
-						 char __user *buffer,
-						 size_t count,
-						 loff_t *offset)
-{
-	memset((void *)buffer, 0, count);
-
-	snprintf(buffer, count,
-		 "\nHOST_SENDER_NO_LP_DIAG_TEST\n"
-		 "===========================\n"
-		 "Description:\n"
-		 "TBD\n");
-
-	if (message_repeat == 1) {
-		message_repeat = 0;
-		return strnlen(buffer, count);
-	} else {
-		return 0;
-	}
-}
-
-const struct file_operations host_sender_no_lp_diag_test_ops = {
-	.open = sdio_al_test_open,
-	.write = host_sender_no_lp_diag_test_write,
-	.read = host_sender_no_lp_diag_test_read,
-};
-
-/* HOST SENDER NO LP DIAG, RPC TEST */
-static ssize_t host_sender_no_lp_diag_rpc_test_write(
-						 struct file *file,
-						 const char __user *buf,
-						 size_t count,
-						 loff_t *ppos)
-{
-	int ret = 0;
-	int i = 0;
-	int number = -1;
-
-	pr_info(TEST_MODULE_NAME "-- HOST SENDER NO LP FOR DIAG, RPC "
-		"TEST --");
-
-	number = sdio_al_test_extract_number(buf, count);
-
-	if (number < 0) {
-		pr_err(TEST_MODULE_NAME " : %s - sdio_al_test_extract_number() "
-		       "failed. number = %d\n", __func__, number);
-		return count;
-	}
-
-	for (i = 0 ; i < number ; ++i) {
-		pr_info(TEST_MODULE_NAME " - Cycle # %d / %d\n", i+1, number);
-		pr_info(TEST_MODULE_NAME " ===================");
-
-		sdio_al_test_initial_dev_and_chan(test_ctx);
-
-		set_params_8k_sender_no_lp(test_ctx->test_ch_arr[SDIO_DIAG]);
-		set_params_8k_sender_no_lp(test_ctx->test_ch_arr[SDIO_RPC]);
-
-		ret = test_start();
-
-		if (ret)
-			break;
-	}
-
-	return count;
-}
-
-static ssize_t host_sender_no_lp_diag_rpc_test_read(
-						 struct file *file,
-						 char __user *buffer,
-						 size_t count,
-						 loff_t *offset)
-{
-	memset((void *)buffer, 0, count);
-
-	snprintf(buffer, count,
-		 "\nHOST_SENDER_NO_LP_DIAG_RPC_TEST\n"
-		 "===================================\n"
-		 "Description:\n"
-		 "TBD\n");
-
-	if (message_repeat == 1) {
-		message_repeat = 0;
-		return strnlen(buffer, count);
-	} else {
-		return 0;
-	}
-}
-
-const struct file_operations host_sender_no_lp_diag_rpc_test_ops = {
-	.open = sdio_al_test_open,
-	.write = host_sender_no_lp_diag_rpc_test_write,
-	.read = host_sender_no_lp_diag_rpc_test_read,
-};
-
-/* RMNET SMALL PACKETS TEST */
-static ssize_t rmnet_small_packets_test_write(struct file *file,
-					       const char __user *buf,
-					       size_t count,
-					       loff_t *ppos)
-{
-	int ret = 0;
-	int i = 0;
-	int number = -1;
-
-	pr_info(TEST_MODULE_NAME "-- RMNET SMALL PACKETS (5-128) TEST --");
-
-	number = sdio_al_test_extract_number(buf, count);
-
-	if (number < 0) {
-		pr_err(TEST_MODULE_NAME " : %s - sdio_al_test_extract_number() "
-		       "failed. number = %d\n", __func__, number);
-		return count;
-	}
-
-	for (i = 0 ; i < number ; ++i) {
-		pr_info(TEST_MODULE_NAME " - Cycle # %d / %d\n", i+1, number);
-		pr_info(TEST_MODULE_NAME " ===================");
-
-		sdio_al_test_initial_dev_and_chan(test_ctx);
-
-		set_params_a2_small_pkts(test_ctx->test_ch_arr[SDIO_RMNT]);
-
-		ret = test_start();
-
-		if (ret)
-			break;
-	}
-
-	return count;
-}
-
-static ssize_t rmnet_small_packets_test_read(struct file *file,
-					      char __user *buffer,
-					      size_t count,
-					      loff_t *offset)
-{
-	memset((void *)buffer, 0, count);
-
-	snprintf(buffer, count,
-		 "\nRMNET_SMALL_PACKETS_TEST\n"
-		 "========================\n"
-		 "Description:\n"
-		 "TBD\n");
-
-	if (message_repeat == 1) {
-		message_repeat = 0;
-		return strnlen(buffer, count);
-	} else {
-		return 0;
-	}
-}
-
-const struct file_operations rmnet_small_packets_test_ops = {
-	.open = sdio_al_test_open,
-	.write = rmnet_small_packets_test_write,
-	.read = rmnet_small_packets_test_read,
-};
-
-/* RMNET RTT TEST */
-static ssize_t rmnet_rtt_test_write(struct file *file,
-				     const char __user *buf,
-				     size_t count,
-				     loff_t *ppos)
-{
-	int ret = 0;
-	int i = 0;
-	int number = -1;
-
-	pr_info(TEST_MODULE_NAME "-- RMNET RTT TEST --");
-
-	number = sdio_al_test_extract_number(buf, count);
-
-	if (number < 0) {
-		pr_err(TEST_MODULE_NAME " : %s - sdio_al_test_extract_number() "
-		       "failed. number = %d\n", __func__, number);
-		return count;
-	}
-
-	for (i = 0 ; i < number ; ++i) {
-		pr_info(TEST_MODULE_NAME " - Cycle # %d / %d\n", i+1, number);
-		pr_info(TEST_MODULE_NAME " ===================");
-
-		sdio_al_test_initial_dev_and_chan(test_ctx);
-
-		set_params_rtt(test_ctx->test_ch_arr[SDIO_RMNT]);
-
-		ret = test_start();
-
-		if (ret)
-			break;
-	}
-
-	return count;
-}
-
-static ssize_t rmnet_rtt_test_read(struct file *file,
-				    char __user *buffer,
-				    size_t count,
-				    loff_t *offset)
-{
-	memset((void *)buffer, 0, count);
-
-	snprintf(buffer, count,
-		 "\nRMNET_RTT_TEST\n"
-		 "==============\n"
-		 "Description:\n"
-		 "TBD\n");
-
-	if (message_repeat == 1) {
-		message_repeat = 0;
-		return strnlen(buffer, count);
-	} else {
-		return 0;
-	}
-}
-
-const struct file_operations rmnet_rtt_test_ops = {
-	.open = sdio_al_test_open,
-	.write = rmnet_rtt_test_write,
-	.read = rmnet_rtt_test_read,
-};
-
-/* CSVT RTT TEST */
-static ssize_t csvt_rtt_test_write(struct file *file,
-				    const char __user *buf,
-				    size_t count,
-				    loff_t *ppos)
-{
-	int ret = 0;
-	int i = 0;
-	int number = -1;
-
-	pr_info(TEST_MODULE_NAME "-- CSVT RTT TEST --");
-
-	number = sdio_al_test_extract_number(buf, count);
-
-	if (number < 0) {
-		pr_err(TEST_MODULE_NAME " : %s - sdio_al_test_extract_number() "
-		       "failed. number = %d\n", __func__, number);
-		return count;
-	}
-
-	for (i = 0 ; i < number ; ++i) {
-		pr_info(TEST_MODULE_NAME " - Cycle # %d / %d\n", i+1, number);
-		pr_info(TEST_MODULE_NAME " ===================");
-
-		sdio_al_test_initial_dev_and_chan(test_ctx);
-
-		set_params_rtt(test_ctx->test_ch_arr[SDIO_CSVT]);
-
-		ret = test_start();
-
-		if (ret)
-			break;
-	}
-
-	return count;
-}
-
-static ssize_t csvt_rtt_test_read(struct file *file,
-				   char __user *buffer,
-				   size_t count,
-				   loff_t *offset)
-{
-	memset((void *)buffer, 0, count);
-
-	snprintf(buffer, count,
-		 "\nCSVT_RTT_TEST\n"
-		 "==============\n"
-		 "Description:\n"
-		 "In this test the HOST send a message of %d bytes "
-		 "to the CLIENT\n\n"
-		 "END OF DESCRIPTION\n", SDIO_CSVT_RTT_PACKET_SIZE);
-
-	if (message_repeat == 1) {
-		message_repeat = 0;
-		return strnlen(buffer, count);
-	} else {
-		return 0;
-	}
-}
-
-const struct file_operations csvt_rtt_test_ops = {
-	.open = sdio_al_test_open,
-	.write = csvt_rtt_test_write,
-	.read = csvt_rtt_test_read,
-};
-
-/* MODEM RESET RPC TEST */
-static ssize_t modem_reset_rpc_test_write(struct file *file,
-					   const char __user *buf,
-					   size_t count,
-					   loff_t *ppos)
-{
-	int ret = 0;
-	int i = 0;
-	int number = -1;
-
-	pr_info(TEST_MODULE_NAME "-- MODEM RESET - RPC CHANNEL TEST --");
-
-	number = sdio_al_test_extract_number(buf, count);
-
-	if (number < 0) {
-		pr_err(TEST_MODULE_NAME " : %s - sdio_al_test_extract_number() "
-		       "failed. number = %d\n", __func__, number);
-		return count;
-	}
-
-	for (i = 0 ; i < number ; ++i) {
-		pr_info(TEST_MODULE_NAME " - Cycle # %d / %d\n", i+1, number);
-		pr_info(TEST_MODULE_NAME " ===================");
-
-		sdio_al_test_initial_dev_and_chan(test_ctx);
-
-		set_params_modem_reset(test_ctx->test_ch_arr[SDIO_RPC]);
-
-		ret = test_start();
-
-		if (ret)
-			break;
-	}
-
-	return count;
-}
-
-static ssize_t modem_reset_rpc_test_read(struct file *file,
-					  char __user *buffer,
-					  size_t count,
-					  loff_t *offset)
-{
-	memset((void *)buffer, 0, count);
-
-	snprintf(buffer, count,
-		 "\nMODEM_RESET_RPC_TEST\n"
-		 "====================\n"
-		 "Description:\n"
-		 "TBD\n");
-
-	if (message_repeat == 1) {
-		message_repeat = 0;
-		return strnlen(buffer, count);
-	} else {
-		return 0;
-	}
-}
-
-const struct file_operations modem_reset_rpc_test_ops = {
-	.open = sdio_al_test_open,
-	.write = modem_reset_rpc_test_write,
-	.read = modem_reset_rpc_test_read,
-};
-
-/* MODEM RESET RMNET TEST */
-static ssize_t modem_reset_rmnet_test_write(struct file *file,
-					     const char __user *buf,
-					     size_t count,
-					     loff_t *ppos)
-{
-	int ret = 0;
-	int i = 0;
-	int number = -1;
-
-	pr_info(TEST_MODULE_NAME "-- MODEM RESET - RMNT CHANNEL TEST --");
-
-	number = sdio_al_test_extract_number(buf, count);
-
-	if (number < 0) {
-		pr_err(TEST_MODULE_NAME " : %s - sdio_al_test_extract_number() "
-		       "failed. number = %d\n", __func__, number);
-		return count;
-	}
-
-	for (i = 0 ; i < number ; ++i) {
-		pr_info(TEST_MODULE_NAME " - Cycle # %d / %d\n", i+1, number);
-		pr_info(TEST_MODULE_NAME " ===================");
-
-		sdio_al_test_initial_dev_and_chan(test_ctx);
-
-		set_params_modem_reset(test_ctx->test_ch_arr[SDIO_RMNT]);
-
-		ret = test_start();
-
-		if (ret)
-			break;
-	}
-
-	return count;
-}
-
-static ssize_t modem_reset_rmnet_test_read(struct file *file,
-					    char __user *buffer,
-					    size_t count,
-					    loff_t *offset)
-{
-	memset((void *)buffer, 0, count);
-
-	snprintf(buffer, count,
-		 "\nMODEM_RESET_RMNET_TEST\n"
-		 "======================\n"
-		 "Description:\n"
-		 "TBD\n");
-
-	if (message_repeat == 1) {
-		message_repeat = 0;
-		return strnlen(buffer, count);
-	} else {
-		return 0;
-	}
-}
-
-const struct file_operations modem_reset_rmnet_test_ops = {
-	.open = sdio_al_test_open,
-	.write = modem_reset_rmnet_test_write,
-	.read = modem_reset_rmnet_test_read,
-};
-
-/* MODEM RESET - CHANNELS IN 4BIT DEVICE TEST */
-static ssize_t modem_reset_channels_4bit_dev_test_write(
-						struct file *file,
-						const char __user *buf,
-						size_t count,
-						loff_t *ppos)
-{
-	int ret = 0;
-	int i = 0;
-	int number = -1;
-
-	pr_info(TEST_MODULE_NAME "-- MODEM RESET - ALL CHANNELS IN "
-		"4BIT DEVICE TEST --");
-
-	number = sdio_al_test_extract_number(buf, count);
-
-	if (number < 0) {
-		pr_err(TEST_MODULE_NAME " : %s - sdio_al_test_extract_number() "
-		       "failed. number = %d\n", __func__, number);
-		return count;
-	}
-
-	for (i = 0 ; i < number ; ++i) {
-		pr_info(TEST_MODULE_NAME " - Cycle # %d / %d\n", i+1, number);
-		pr_info(TEST_MODULE_NAME " ===================");
-
-		sdio_al_test_initial_dev_and_chan(test_ctx);
-
-		set_params_modem_reset(test_ctx->test_ch_arr[SDIO_RPC]);
-		set_params_modem_reset(test_ctx->test_ch_arr[SDIO_QMI]);
-		set_params_modem_reset(test_ctx->test_ch_arr[SDIO_DIAG]);
-
-		ret = test_start();
-
-		if (ret)
-			break;
-	}
-
-	return count;
-}
-
-static ssize_t modem_reset_channels_4bit_dev_test_read(
-						struct file *file,
-						char __user *buffer,
-						size_t count,
-						loff_t *offset)
-{
-	memset((void *)buffer, 0, count);
-
-	snprintf(buffer, count,
-		 "\nMODEM_RESET_CHANNELS_4BIT_DEV_TEST\n"
-		 "==================================\n"
-		 "Description:\n"
-		 "TBD\n");
-
-	if (message_repeat == 1) {
-		message_repeat = 0;
-		return strnlen(buffer, count);
-	} else {
-		return 0;
-	}
-}
-
-const struct file_operations modem_reset_channels_4bit_dev_test_ops = {
-	.open = sdio_al_test_open,
-	.write = modem_reset_channels_4bit_dev_test_write,
-	.read = modem_reset_channels_4bit_dev_test_read,
-};
-
-/* MODEM RESET - CHANNELS IN 8BIT DEVICE TEST */
-static ssize_t modem_reset_channels_8bit_dev_test_write(
-						struct file *file,
-						const char __user *buf,
-						size_t count,
-						loff_t *ppos)
-{
-	int ret = 0;
-	int i = 0;
-	int number = -1;
-
-	pr_info(TEST_MODULE_NAME "-- MODEM RESET - ALL CHANNELS IN "
-		"8BIT DEVICE TEST --");
-
-	number = sdio_al_test_extract_number(buf, count);
-
-	if (number < 0) {
-		pr_err(TEST_MODULE_NAME " : %s - sdio_al_test_extract_number() "
-		       "failed. number = %d\n", __func__, number);
-		return count;
-	}
-
-	for (i = 0 ; i < number ; ++i) {
-		pr_info(TEST_MODULE_NAME " - Cycle # %d / %d\n", i+1, number);
-		pr_info(TEST_MODULE_NAME " ===================");
-
-		sdio_al_test_initial_dev_and_chan(test_ctx);
-
-		set_params_modem_reset(test_ctx->test_ch_arr[SDIO_RMNT]);
-		set_params_modem_reset(test_ctx->test_ch_arr[SDIO_DUN]);
-
-		ret = test_start();
-
-		if (ret)
-			break;
-	}
-
-	return count;
-}
-
-static ssize_t modem_reset_channels_8bit_dev_test_read(
-						struct file *file,
-						char __user *buffer,
-						size_t count,
-						loff_t *offset)
-{
-	memset((void *)buffer, 0, count);
-
-	snprintf(buffer, count,
-		 "\nMODEM_RESET_CHANNELS_8BIT_DEV_TEST\n"
-		 "==================================\n"
-		 "Description:\n"
-		 "TBD\n");
-
-	if (message_repeat == 1) {
-		message_repeat = 0;
-		return strnlen(buffer, count);
-	} else {
-		return 0;
-	}
-}
-
-const struct file_operations modem_reset_channels_8bit_dev_test_ops = {
-	.open = sdio_al_test_open,
-	.write = modem_reset_channels_8bit_dev_test_write,
-	.read = modem_reset_channels_8bit_dev_test_read,
-};
-
-/* MODEM RESET - ALL CHANNELS TEST */
-static ssize_t modem_reset_all_channels_test_write(struct file *file,
-						    const char __user *buf,
-						    size_t count,
-						    loff_t *ppos)
-{
-	int ret = 0;
-	int i = 0;
-	int number = -1;
-
-	pr_info(TEST_MODULE_NAME "-- MODEM RESET - ALL CHANNELS TEST --");
-
-	number = sdio_al_test_extract_number(buf, count);
-
-	if (number < 0) {
-		pr_err(TEST_MODULE_NAME " : %s - sdio_al_test_extract_number() "
-		       "failed. number = %d\n", __func__, number);
-		return count;
-	}
-
-	for (i = 0 ; i < number ; ++i) {
-		pr_info(TEST_MODULE_NAME " - Cycle # %d / %d\n", i+1, number);
-		pr_info(TEST_MODULE_NAME " ===================");
-
-		sdio_al_test_initial_dev_and_chan(test_ctx);
-
-		set_params_modem_reset(test_ctx->test_ch_arr[SDIO_RPC]);
-		set_params_modem_reset(test_ctx->test_ch_arr[SDIO_QMI]);
-		set_params_modem_reset(test_ctx->test_ch_arr[SDIO_DIAG]);
-		set_params_modem_reset(test_ctx->test_ch_arr[SDIO_RMNT]);
-		set_params_modem_reset(test_ctx->test_ch_arr[SDIO_DUN]);
-
-		ret = test_start();
-
-		if (ret)
-			break;
-	}
-
-	return count;
-}
-
-static ssize_t modem_reset_all_channels_test_read(struct file *file,
-						   char __user *buffer,
-						   size_t count,
-						   loff_t *offset)
-{
-	memset((void *)buffer, 0, count);
-
-	snprintf(buffer, count,
-		 "\nMODEM_RESET_ALL_CHANNELS_TEST\n"
-		 "=============================\n"
-		 "Description:\n"
-		 "TBD\n");
-
-	if (message_repeat == 1) {
-		message_repeat = 0;
-		return strnlen(buffer, count);
-	} else {
-		return 0;
-	}
-}
-
-const struct file_operations modem_reset_all_channels_test_ops = {
-	.open = sdio_al_test_open,
-	.write = modem_reset_all_channels_test_write,
-	.read = modem_reset_all_channels_test_read,
-};
-
-/* HOST SENDER WITH OPEN/CLOSE TEST */
-static ssize_t open_close_test_write(struct file *file,
-						   const char __user *buf,
-						   size_t count,
-						   loff_t *ppos)
-{
-	int ret = 0;
-	struct test_channel **ch_arr = test_ctx->test_ch_arr;
-	int i = 0;
-	int number = -1;
-
-	pr_info(TEST_MODULE_NAME "-- HOST SENDER WITH OPEN/CLOSE TEST --");
-
-	number = sdio_al_test_extract_number(buf, count);
-
-	if (number < 0) {
-		pr_err(TEST_MODULE_NAME " : %s - sdio_al_test_extract_number() "
-		       "failed. number = %d\n", __func__, number);
-		return count;
-	}
-
-	for (i = 0 ; i < number ; ++i) {
-		pr_info(TEST_MODULE_NAME " - Cycle # %d / %d\n", i+1, number);
-		pr_info(TEST_MODULE_NAME " ===================");
-
-		sdio_al_test_initial_dev_and_chan(test_ctx);
-
-		set_params_loopback_9k_close(ch_arr[SDIO_DIAG]);
-		set_params_loopback_9k_close(ch_arr[SDIO_RPC]);
-		set_params_loopback_9k_close(ch_arr[SDIO_SMEM]);
-		set_params_loopback_9k_close(ch_arr[SDIO_QMI]);
-		set_params_loopback_9k_close(ch_arr[SDIO_RMNT]);
-		set_params_loopback_9k_close(ch_arr[SDIO_DUN]);
-		set_params_loopback_9k_close(ch_arr[SDIO_CSVT]);
-
-		ret = test_start();
-
-		if (ret)
-			break;
-
-		pr_info(TEST_MODULE_NAME " -- correctness test for"
-				"DIAG ");
-		set_params_loopback_9k(ch_arr[SDIO_DIAG]);
-
-		ret = test_start();
-
-		if (ret)
-			break;
-	}
-
-	return count;
-}
-
-static ssize_t open_close_test_read(struct file *file,
-						  char __user *buffer,
-						  size_t count,
-						  loff_t *offset)
-{
-	memset((void *)buffer, 0, count);
-
-	snprintf(buffer, count,
-		 "\nOPEN_CLOSE_TEST\n"
-		 "============================\n"
-		 "Description:\n"
-		 "In this test the host sends 5k packets to the modem in the "
-		 "following sequence: Send a random burst of packets on "
-		 "Diag and Rmnet channels, read 0 or a random number "
-		 "of packets, close and re-open the channel. At the end of the "
-		 "test, the channel is verified by running a loopback test\n\n"
-		 "END OF DESCRIPTION\n");
-
-	if (message_repeat == 1) {
-		message_repeat = 0;
-		return strnlen(buffer, count);
-	} else {
-		return 0;
-	}
-}
-
-const struct file_operations open_close_test_ops = {
-	.open = sdio_al_test_open,
-	.write = open_close_test_write,
-	.read = open_close_test_read,
-};
-
-/* HOST SENDER WITH OPEN/CLOSE FOR DUN & RMNET TEST */
-static ssize_t open_close_dun_rmnet_test_write(struct file *file,
-						   const char __user *buf,
-						   size_t count,
-						   loff_t *ppos)
-{
-	int ret = 0;
-	struct test_channel **ch_arr = test_ctx->test_ch_arr;
-	int i = 0;
-	int number = -1;
-
-	pr_info(TEST_MODULE_NAME "-- HOST SENDER WITH OPEN/CLOSE FOR "
-		"DUN AND RMNET TEST --");
-
-	number = sdio_al_test_extract_number(buf, count);
-
-	if (number < 0) {
-		pr_err(TEST_MODULE_NAME " : %s - sdio_al_test_extract_number() "
-		       "failed. number = %d\n", __func__, number);
-		return count;
-	}
-
-	for (i = 0 ; i < number ; ++i) {
-		pr_info(TEST_MODULE_NAME " - Cycle # %d / %d\n", i+1, number);
-		pr_info(TEST_MODULE_NAME " ===================");
-
-		sdio_al_test_initial_dev_and_chan(test_ctx);
-
-		set_params_loopback_9k_close(ch_arr[SDIO_DUN]);
-		set_params_loopback_9k_close(ch_arr[SDIO_RMNT]);
-
-		ret = test_start();
-
-		if (ret)
-			break;
-	}
-
-	return count;
-}
-
-static ssize_t open_close_dun_rmnet_test_read(struct file *file,
-						  char __user *buffer,
-						  size_t count,
-						  loff_t *offset)
-{
-	memset((void *)buffer, 0, count);
-
-	snprintf(buffer, count,
-		 "\nOPEN_CLOSE_DUN_RMNET_TEST\n"
-		 "============================\n"
-		 "Description:\n"
-		 "In this test the host sends 5k packets to the modem in the "
-		 "following sequence: Send a random burst of packets on "
-		 "DUN and Rmnet channels, read 0 or a random number "
-		 "of packets, close and re-open the channel.\n\n"
-		 "END OF DESCRIPTION\n");
-
-	if (message_repeat == 1) {
-		message_repeat = 0;
-		return strnlen(buffer, count);
-	} else {
-		return 0;
-	}
-}
-
-const struct file_operations open_close_dun_rmnet_test_ops = {
-	.open = sdio_al_test_open,
-	.write = open_close_dun_rmnet_test_write,
-	.read = open_close_dun_rmnet_test_read,
-};
-
-/* CLOSE CHANNEL & LPM TEST HOST WAKES THE CLIENT TEST */
-static ssize_t close_chan_lpm_test_write(struct file *file,
-					  const char __user *buf,
-					  size_t count,
-					  loff_t *ppos)
-{
-	int ret = 0;
-	int i = 0;
-	int channel_num = 0;
-	int number = -1;
-
-	pr_info(TEST_MODULE_NAME "-- CLOSE CHANNEL & LPM TEST "
-		"HOST WAKES THE CLIENT TEST --\n");
-
-	number = sdio_al_test_extract_number(buf, count);
-
-	if (number < 0) {
-		pr_err(TEST_MODULE_NAME " : %s - sdio_al_test_extract_number() "
-		       "failed. number = %d\n", __func__, number);
-		return count;
-	}
-
-	for (i = 0 ; i < number ; ++i) {
-		pr_info(TEST_MODULE_NAME " - Cycle # %d / %d\n", i+1, number);
-		pr_info(TEST_MODULE_NAME " ===================");
-
-		sdio_al_test_initial_dev_and_chan(test_ctx);
-
-		for (channel_num = 0 ; channel_num < SDIO_MAX_CHANNELS ;
-		     channel_num++) {
-
-			ret = close_channel_lpm_test(channel_num);
-
-			if (ret)
-				break;
-
-			set_params_lpm_test(test_ctx->test_ch_arr[SDIO_RPC],
-					    SDIO_TEST_LPM_HOST_WAKER, 120);
-
-			ret = test_start();
-
-			if (ret)
-				break;
-		}
-
-		if (ret) {
-			pr_err(TEST_MODULE_NAME " -- Close channel & LPM Test "
-			       "FAILED: %d --\n", ret);
-		} else {
-			pr_err(TEST_MODULE_NAME " -- Close channel & LPM Test "
-			       "PASSED\n");
-		}
-	}
-
-	return count;
-}
-
-static ssize_t close_chan_lpm_test_read(struct file *file,
-					 char __user *buffer,
-					 size_t count,
-					 loff_t *offset)
-{
-	memset((void *)buffer, 0, count);
-
-	snprintf(buffer, count,
-		 "\nCLOSE_CHAN_LPM_TEST\n"
-		 "===================\n"
-		 "Description:\n"
-		 "TBD\n");
-
-	if (message_repeat == 1) {
-		message_repeat = 0;
-		return strnlen(buffer, count);
-	} else {
-		return 0;
-	}
-}
-
-const struct file_operations close_chan_lpm_test_ops = {
-	.open = sdio_al_test_open,
-	.write = close_chan_lpm_test_write,
-	.read = close_chan_lpm_test_read,
-};
-
-/* LPM TEST FOR DEVICE 1. CLIENT WAKES THE HOST TEST */
-static ssize_t lpm_test_client_wakes_host_test_write(struct file *file,
-						      const char __user *buf,
-						      size_t count,
-						      loff_t *ppos)
-{
-	int ret = 0;
-	int i = 0;
-	int number = -1;
-
-	pr_info(TEST_MODULE_NAME "-- LPM TEST FOR DEVICE 1. CLIENT "
-		"WAKES THE HOST TEST --\n");
-
-	number = sdio_al_test_extract_number(buf, count);
-
-	if (number < 0) {
-		pr_err(TEST_MODULE_NAME " : %s - sdio_al_test_extract_number() "
-		       "failed. number = %d\n", __func__, number);
-		return count;
-	}
-
-	for (i = 0 ; i < number ; ++i) {
-		pr_info(TEST_MODULE_NAME " - Cycle # %d / %d\n", i+1, number);
-		pr_info(TEST_MODULE_NAME " ===================");
-
-		sdio_al_test_initial_dev_and_chan(test_ctx);
-
-		set_params_lpm_test(test_ctx->test_ch_arr[SDIO_RPC],
-				    SDIO_TEST_LPM_CLIENT_WAKER, 90);
-
-		ret = test_start();
-
-		if (ret)
-			break;
-	}
-
-	return count;
-}
-
-static ssize_t lpm_test_client_wakes_host_test_read(struct file *file,
-						     char __user *buffer,
-						     size_t count,
-						     loff_t *offset)
-{
-	memset((void *)buffer, 0, count);
-
-	snprintf(buffer, count,
-		 "\nLPM_TEST_CLIENT_WAKES_HOST_TEST\n"
-		 "===============================\n"
-		 "Description:\n"
-		 "In this test, the HOST is going into LPM mode,\n"
-		 "and the CLIENT is responsible to send it a message\n"
-		 "in order to wake it up\n\n"
-		 "END OF DESCRIPTION\n");
-
-	if (message_repeat == 1) {
-		message_repeat = 0;
-		return strnlen(buffer, count);
-	} else {
-		return 0;
-	}
-}
-
-const struct file_operations lpm_test_client_wakes_host_test_ops = {
-	.open = sdio_al_test_open,
-	.write = lpm_test_client_wakes_host_test_write,
-	.read = lpm_test_client_wakes_host_test_read,
-};
-
-/* LPM TEST FOR DEVICE 1. HOST WAKES THE CLIENT TEST */
-static ssize_t lpm_test_host_wakes_client_test_write(struct file *file,
-						      const char __user *buf,
-						      size_t count,
-						      loff_t *ppos)
-{
-	int ret = 0;
-	int i = 0;
-	int number = -1;
-
-	pr_info(TEST_MODULE_NAME "-- LPM TEST FOR DEVICE 1. HOST "
-		"WAKES THE CLIENT TEST --\n");
-
-	number = sdio_al_test_extract_number(buf, count);
-
-	if (number < 0) {
-		pr_err(TEST_MODULE_NAME " : %s - sdio_al_test_extract_number() "
-		       "failed. number = %d\n", __func__, number);
-		return count;
-	}
-
-	for (i = 0 ; i < number ; ++i) {
-		pr_info(TEST_MODULE_NAME " - Cycle # %d / %d\n", i+1, number);
-		pr_info(TEST_MODULE_NAME " ===================");
-
-		sdio_al_test_initial_dev_and_chan(test_ctx);
-
-		set_params_lpm_test(test_ctx->test_ch_arr[SDIO_RPC],
-			    SDIO_TEST_LPM_HOST_WAKER, 120);
-
-		ret = test_start();
-
-		if (ret)
-			break;
-	}
-
-	return count;
-}
-
-static ssize_t lpm_test_host_wakes_client_test_read(struct file *file,
-						     char __user *buffer,
-						     size_t count,
-						     loff_t *offset)
-{
-	memset((void *)buffer, 0, count);
-
-	snprintf(buffer, count,
-		 "\nLPM_TEST_HOST_WAKES_CLIENT_TEST\n"
-		 "===============================\n"
-		 "Description:\n"
-		 "In this test, the CLIENT goes into LPM mode, and the\n"
-		 "HOST is responsible to send it a message\n"
-		 "in order to wake it up\n\n"
-		 "END OF DESCRIPTION\n");
-
-	if (message_repeat == 1) {
-		message_repeat = 0;
-		return strnlen(buffer, count);
-	} else {
-		return 0;
-	}
-}
-
-const struct file_operations lpm_test_host_wakes_client_test_ops = {
-	.open = sdio_al_test_open,
-	.write = lpm_test_host_wakes_client_test_write,
-	.read = lpm_test_host_wakes_client_test_read,
-};
-
-/* LPM TEST RANDOM, SINGLE CHANNEL TEST */
-static ssize_t lpm_test_random_single_channel_test_write(
-						struct file *file,
-						const char __user *buf,
-						size_t count,
-						loff_t *ppos)
-{
-	int ret = 0;
-	int i = 0;
-	int number = -1;
-
-	pr_info(TEST_MODULE_NAME "-- LPM TEST RANDOM SINGLE "
-		"CHANNEL TEST --\n");
-
-	number = sdio_al_test_extract_number(buf, count);
-
-	if (number < 0) {
-		pr_err(TEST_MODULE_NAME " : %s - sdio_al_test_extract_number() "
-		       "failed. number = %d\n", __func__, number);
-		return count;
-	}
-
-	for (i = 0 ; i < number ; ++i) {
-		pr_info(TEST_MODULE_NAME " - Cycle # %d / %d\n", i+1, number);
-		pr_info(TEST_MODULE_NAME " ===================");
-
-		sdio_al_test_initial_dev_and_chan(test_ctx);
-
-		set_pseudo_random_seed();
-		set_params_lpm_test(test_ctx->test_ch_arr[SDIO_RPC],
-				    SDIO_TEST_LPM_RANDOM, 0);
-
-		ret = test_start();
-
-		if (ret)
-			break;
-	}
-
-	return count;
-}
-
-static ssize_t lpm_test_random_single_channel_test_read(
-						struct file *file,
-						char __user *buffer,
-						size_t count,
-						loff_t *offset)
-{
-	memset((void *)buffer, 0, count);
-
-	snprintf(buffer, count,
-		 "\nLPM_TEST_RANDOM_SINGLE_CHANNEL_TEST\n"
-		 "===================================\n"
-		 "Description:\n"
-		 "In this test, the HOST and CLIENT "
-		 "send messages to each other,\n"
-		 "random in time, over RPC channel only.\n"
-		 "All events are being recorded, and later on,\n"
-		 "they are being analysed by the HOST and by the CLIENT\n,"
-		 "in order to check if the LPM mechanism worked properly,\n"
-		 "meaning:"
-		 " When all the relevant conditions are met, a device should:\n"
-		 "1. Go to sleep\n"
-		 "2. Wake up\n"
-		 "3. Stay awake\n\n"
-		 "END OF DESCRIPTION\n");
-
-	if (message_repeat == 1) {
-		message_repeat = 0;
-		return strnlen(buffer, count);
-	} else {
-		return 0;
-	}
-}
-
-const struct file_operations lpm_test_random_single_channel_test_ops = {
-	.open = sdio_al_test_open,
-	.write = lpm_test_random_single_channel_test_write,
-	.read = lpm_test_random_single_channel_test_read,
-};
-
-/* LPM TEST RANDOM, MULTI CHANNEL TEST */
-static ssize_t lpm_test_random_multi_channel_test_write(
-						struct file *file,
-						const char __user *buf,
-						size_t count,
-						loff_t *ppos)
-{
-	int ret = 0;
-	int i = 0;
-	int number = -1;
-
-	pr_info(TEST_MODULE_NAME "-- LPM TEST RANDOM MULTI CHANNEL TEST --\n");
-
-	number = sdio_al_test_extract_number(buf, count);
-
-	if (number < 0) {
-		pr_err(TEST_MODULE_NAME " : %s - sdio_al_test_extract_number() "
-		       "failed. number = %d\n", __func__, number);
-		return count;
-	}
-
-	for (i = 0 ; i < number ; ++i) {
-		pr_info(TEST_MODULE_NAME " - Cycle # %d / %d\n", i+1, number);
-		pr_info(TEST_MODULE_NAME " ===================");
-
-		sdio_al_test_initial_dev_and_chan(test_ctx);
-
-		set_pseudo_random_seed();
-
-		set_params_lpm_test(test_ctx->test_ch_arr[SDIO_RPC],
-				    SDIO_TEST_LPM_RANDOM, 0);
-		set_params_lpm_test(test_ctx->test_ch_arr[SDIO_DIAG],
-				    SDIO_TEST_LPM_RANDOM, 0);
-		set_params_lpm_test(test_ctx->test_ch_arr[SDIO_QMI],
-				SDIO_TEST_LPM_RANDOM, 0);
-
-		ret = test_start();
-
-		if (ret)
-			break;
-	}
-
-	return count;
-}
-
-static ssize_t lpm_test_random_multi_channel_test_read(
-				 struct file *file,
-				 char __user *buffer,
-				 size_t count,
-				 loff_t *offset)
-{
-	memset((void *)buffer, 0, count);
-
-	snprintf(buffer, count,
-		 "\nLPM_TEST_RANDOM_MULTI_CHANNEL_TEST\n"
-		 "==================================\n"
-		 "Description:\n"
-		 "In this test, the HOST and CLIENT "
-		 "send messages to each other,\n"
-		 "random in time, over RPC, QMI AND DIAG channels\n"
-		 "(i.e, on both SDIO devices).\n"
-		 "All events are being recorded, and later on,\n"
-		 "they are being analysed by the HOST and by the CLIENT,\n"
-		 "in order to check if the LPM mechanism worked properly,\n"
-		 "meaning:"
-		 " When all the relevant conditions are met, a device should:\n"
-		 "1. Go to sleep\n"
-		 "2. Wake up\n"
-		 "3. Stay awake\n\n"
-		 "END OF DESCRIPTION\n");
-
-	if (message_repeat == 1) {
-		message_repeat = 0;
-		return strnlen(buffer, count);
-	} else {
-		return 0;
-	}
-}
-
-const struct file_operations lpm_test_random_multi_channel_test_ops = {
-	.open = sdio_al_test_open,
-	.write = lpm_test_random_multi_channel_test_write,
-	.read = lpm_test_random_multi_channel_test_read,
-};
-
-static int sdio_al_test_debugfs_init(void)
-{
-	test_ctx->debug.debug_root = debugfs_create_dir("sdio_al_test",
-							       NULL);
-	if (!test_ctx->debug.debug_root)
-		return -ENOENT;
-
-	test_ctx->debug.debug_test_result = debugfs_create_u32(
-					"test_result",
-					S_IRUGO | S_IWUGO,
-					test_ctx->debug.debug_root,
-					&test_ctx->test_result);
-
-	test_ctx->debug.debug_dun_throughput = debugfs_create_u32(
-					"dun_throughput",
-					S_IRUGO | S_IWUGO,
-					test_ctx->debug.debug_root,
-					&test_ctx->debug.dun_throughput);
-
-	test_ctx->debug.debug_rmnt_throughput = debugfs_create_u32(
-					"rmnt_throughput",
-					S_IRUGO | S_IWUGO,
-					test_ctx->debug.debug_root,
-					&test_ctx->debug.rmnt_throughput);
-
-	test_ctx->debug.rpc_sender_test =
-		debugfs_create_file("10_rpc_sender_test",
-				    S_IRUGO | S_IWUGO,
-				    test_ctx->debug.debug_root,
-				    NULL,
-				    &rpc_sender_test_ops);
-
-	test_ctx->debug.rpc_qmi_diag_sender_test =
-		debugfs_create_file("20_rpc_qmi_diag_sender_test",
-				    S_IRUGO | S_IWUGO,
-				    test_ctx->debug.debug_root,
-				    NULL,
-				    &rpc_qmi_diag_sender_test_ops);
-
-	test_ctx->debug.rmnet_a2_validation_test =
-		debugfs_create_file("30_rmnet_a2_validation_test",
-				    S_IRUGO | S_IWUGO,
-				    test_ctx->debug.debug_root,
-				    NULL,
-				    &rmnet_a2_validation_test_ops);
-
-	test_ctx->debug.dun_a2_validation_test =
-		debugfs_create_file("40_dun_a2_validation_test",
-				    S_IRUGO | S_IWUGO,
-				    test_ctx->debug.debug_root,
-				    NULL,
-				    &dun_a2_validation_test_ops);
-
-	test_ctx->debug.rmnet_a2_perf_test =
-		debugfs_create_file("50_rmnet_a2_perf_test",
-				    S_IRUGO | S_IWUGO,
-				    test_ctx->debug.debug_root,
-				    NULL,
-				    &rmnet_a2_perf_test_ops);
-
-	test_ctx->debug.dun_a2_perf_test =
-		debugfs_create_file("60_dun_a2_perf_test",
-				    S_IRUGO | S_IWUGO,
-				    test_ctx->debug.debug_root,
-				    NULL,
-				    &dun_a2_perf_test_ops);
-
-	test_ctx->debug.csvt_a2_perf_test =
-		debugfs_create_file("71_csvt_a2_perf_test",
-				    S_IRUGO | S_IWUGO,
-				    test_ctx->debug.debug_root,
-				    NULL,
-				    &csvt_a2_perf_test_ops);
-
-	test_ctx->debug.rmnet_dun_a2_perf_test =
-		debugfs_create_file("70_rmnet_dun_a2_perf_test",
-				    S_IRUGO | S_IWUGO,
-				    test_ctx->debug.debug_root,
-				    NULL,
-				    &rmnet_dun_a2_perf_test_ops);
-
-	test_ctx->debug.rpc_sender_rmnet_a2_perf_test =
-		debugfs_create_file("80_rpc_sender_rmnet_a2_perf_test",
-				    S_IRUGO | S_IWUGO,
-				    test_ctx->debug.debug_root,
-				    NULL,
-				    &rpc_sender_rmnet_a2_perf_test_ops);
-
-	test_ctx->debug.smem_test =
-		debugfs_create_file("90_smem_test",
-				    S_IRUGO | S_IWUGO,
-				    test_ctx->debug.debug_root,
-				    NULL,
-				    &smem_test_ops);
-
-	test_ctx->debug.smem_rpc_test =
-		debugfs_create_file("100_smem_rpc_test",
-				    S_IRUGO | S_IWUGO,
-				    test_ctx->debug.debug_root,
-				    NULL,
-				    &smem_rpc_test_ops);
-
-	test_ctx->debug.all_channels_test =
-		debugfs_create_file("150_all_channels_test",
-				    S_IRUGO | S_IWUGO,
-				    test_ctx->debug.debug_root,
-				    NULL,
-				    &all_channels_test_ops);
-
-	test_ctx->debug.host_sender_no_lp_diag_test =
-		debugfs_create_file("160_host_sender_no_lp_diag_test",
-				    S_IRUGO | S_IWUGO,
-				    test_ctx->debug.debug_root,
-				    NULL,
-				    &host_sender_no_lp_diag_test_ops);
-
-	test_ctx->debug.host_sender_no_lp_diag_rpc_test =
-		debugfs_create_file("170_host_sender_no_lp_diag_rpc_test",
-				     S_IRUGO | S_IWUGO,
-				     test_ctx->debug.debug_root,
-				     NULL,
-				     &host_sender_no_lp_diag_rpc_test_ops);
-
-	test_ctx->debug.rmnet_small_packets_test =
-		debugfs_create_file("180_rmnet_small_packets_test",
-				     S_IRUGO | S_IWUGO,
-				     test_ctx->debug.debug_root,
-				     NULL,
-				     &rmnet_small_packets_test_ops);
-
-	test_ctx->debug.rmnet_rtt_test =
-		debugfs_create_file("190_rmnet_rtt_test",
-				     S_IRUGO | S_IWUGO,
-				     test_ctx->debug.debug_root,
-				     NULL,
-				     &rmnet_rtt_test_ops);
-
-	test_ctx->debug.csvt_rtt_test =
-		debugfs_create_file("191_csvt_rtt_test",
-				     S_IRUGO | S_IWUGO,
-				     test_ctx->debug.debug_root,
-				     NULL,
-				     &csvt_rtt_test_ops);
-
-	test_ctx->debug.modem_reset_rpc_test =
-		debugfs_create_file("220_modem_reset_rpc_test",
-				     S_IRUGO | S_IWUGO,
-				     test_ctx->debug.debug_root,
-				     NULL,
-				     &modem_reset_rpc_test_ops);
-
-	test_ctx->debug.modem_reset_rmnet_test =
-		debugfs_create_file("230_modem_reset_rmnet_test",
-				     S_IRUGO | S_IWUGO,
-				     test_ctx->debug.debug_root,
-				     NULL,
-				     &modem_reset_rmnet_test_ops);
-
-	test_ctx->debug.modem_reset_channels_4bit_dev_test =
-		debugfs_create_file("240_modem_reset_channels_4bit_dev_test",
-				     S_IRUGO | S_IWUGO,
-				     test_ctx->debug.debug_root,
-				     NULL,
-				     &modem_reset_channels_4bit_dev_test_ops);
-
-	test_ctx->debug.modem_reset_channels_8bit_dev_test =
-		debugfs_create_file("250_modem_reset_channels_8bit_dev_test",
-				     S_IRUGO | S_IWUGO,
-				     test_ctx->debug.debug_root,
-				     NULL,
-				     &modem_reset_channels_8bit_dev_test_ops);
-
-	test_ctx->debug.modem_reset_all_channels_test =
-		debugfs_create_file("260_modem_reset_all_channels_test",
-				     S_IRUGO | S_IWUGO,
-				     test_ctx->debug.debug_root,
-				     NULL,
-				     &modem_reset_all_channels_test_ops);
-
-	test_ctx->debug.open_close_test =
-		debugfs_create_file("270_open_close_test",
-				     S_IRUGO | S_IWUGO,
-				     test_ctx->debug.debug_root,
-				     NULL,
-				     &open_close_test_ops);
-
-	test_ctx->debug.open_close_dun_rmnet_test =
-		debugfs_create_file("271_open_close_dun_rmnet_test",
-				     S_IRUGO | S_IWUGO,
-				     test_ctx->debug.debug_root,
-				     NULL,
-				     &open_close_dun_rmnet_test_ops);
-
-	test_ctx->debug.close_chan_lpm_test =
-		debugfs_create_file("280_close_chan_lpm_test",
-				     S_IRUGO | S_IWUGO,
-				     test_ctx->debug.debug_root,
-				     NULL,
-				     &close_chan_lpm_test_ops);
-
-	test_ctx->debug.lpm_test_client_wakes_host_test =
-		debugfs_create_file("600_lpm_test_client_wakes_host_test",
-				     S_IRUGO | S_IWUGO,
-				     test_ctx->debug.debug_root,
-				     NULL,
-				     &lpm_test_client_wakes_host_test_ops);
-
-	test_ctx->debug.lpm_test_host_wakes_client_test =
-		debugfs_create_file("610_lpm_test_host_wakes_client_test",
-				     S_IRUGO | S_IWUGO,
-				     test_ctx->debug.debug_root,
-				     NULL,
-				     &lpm_test_host_wakes_client_test_ops);
-
-	test_ctx->debug.lpm_test_random_single_channel_test =
-		debugfs_create_file("620_lpm_test_random_single_channel_test",
-				     S_IRUGO | S_IWUGO,
-				     test_ctx->debug.debug_root,
-				     NULL,
-				     &lpm_test_random_single_channel_test_ops);
-
-	test_ctx->debug.lpm_test_random_multi_channel_test =
-		debugfs_create_file("630_lpm_test_random_multi_channel_test",
-				     S_IRUGO | S_IWUGO,
-				     test_ctx->debug.debug_root,
-				     NULL,
-				     &lpm_test_random_multi_channel_test_ops);
-
-	if ((!test_ctx->debug.debug_dun_throughput) &&
-	    (!test_ctx->debug.debug_rmnt_throughput)) {
-		debugfs_remove_recursive(test_ctx->debug.debug_root);
-		test_ctx->debug.debug_root = NULL;
-		return -ENOENT;
-	}
-	return 0;
-}
-
-static void sdio_al_test_debugfs_cleanup(void)
-{
-       debugfs_remove(test_ctx->debug.debug_dun_throughput);
-       debugfs_remove(test_ctx->debug.debug_rmnt_throughput);
-       debugfs_remove(test_ctx->debug.debug_root);
-}
-#endif
-
-static int channel_name_to_id(char *name)
-{
-	pr_info(TEST_MODULE_NAME "%s: channel name %s\n",
-		__func__, name);
-
-	if (!strncmp(name, "SDIO_RPC_TEST",
-		     strnlen("SDIO_RPC_TEST", CHANNEL_NAME_SIZE)))
-		return SDIO_RPC;
-	else if (!strncmp(name, "SDIO_QMI_TEST",
-			  strnlen("SDIO_QMI_TEST", TEST_CH_NAME_SIZE)))
-		return SDIO_QMI;
-	else if (!strncmp(name, "SDIO_RMNT_TEST",
-			  strnlen("SDIO_RMNT_TEST", TEST_CH_NAME_SIZE)))
-		return SDIO_RMNT;
-	else if (!strncmp(name, "SDIO_DIAG_TEST",
-			  strnlen("SDIO_DIAG", TEST_CH_NAME_SIZE)))
-		return SDIO_DIAG;
-	else if (!strncmp(name, "SDIO_DUN_TEST",
-			  strnlen("SDIO_DUN_TEST", TEST_CH_NAME_SIZE)))
-		return SDIO_DUN;
-	else if (!strncmp(name, "SDIO_SMEM_TEST",
-			  strnlen("SDIO_SMEM_TEST", TEST_CH_NAME_SIZE)))
-		return SDIO_SMEM;
-	else if (!strncmp(name, "SDIO_CSVT_TEST",
-			  strnlen("SDIO_CSVT_TEST", TEST_CH_NAME_SIZE)))
-		return SDIO_CSVT;
-	else
-		return SDIO_MAX_CHANNELS;
-
-	return SDIO_MAX_CHANNELS;
-}
-
-/**
- * Allocate and add SDIO_SMEM platform device
- */
-#ifdef CONFIG_MSM_SDIO_SMEM
-static int add_sdio_smem(void)
-{
-	int ret = 0;
-
-	test_ctx->smem_pdev = platform_device_alloc("SDIO_SMEM", -1);
-	ret = platform_device_add(test_ctx->smem_pdev);
-	if (ret) {
-		pr_err(TEST_MODULE_NAME ": platform_device_add failed, "
-				   "ret=%d\n", ret);
-		return ret;
-	}
-	return 0;
-}
-#endif
-
-static int open_sdio_ch(struct test_channel *tch)
-{
-	int ret = 0;
-
-	if (!tch) {
-		pr_err(TEST_MODULE_NAME ": %s NULL tch\n", __func__);
-		return -EINVAL;
-	}
-
-	if (!tch->ch_ready) {
-		TEST_DBG(TEST_MODULE_NAME ":openning channel %s\n",
-			tch->name);
-		if (tch->ch_id == SDIO_SMEM) {
-#ifdef CONFIG_MSM_SDIO_SMEM
-			if (!test_ctx->smem_pdev)
-				ret = add_sdio_smem();
-			else
-				ret = sdio_smem_open(test_ctx->sdio_smem);
-			if (ret) {
-				pr_err(TEST_MODULE_NAME
-					":openning channel %s failed\n",
-				tch->name);
-				tch->ch_ready = false;
-				return -EINVAL;
-			}
-#endif
-		} else {
-			tch->ch_ready = true;
-			ret = sdio_open(tch->name , &tch->ch, tch,
-					notify);
-			if (ret) {
-				pr_err(TEST_MODULE_NAME
-					":openning channel %s failed\n",
-				tch->name);
-				tch->ch_ready = false;
-				return -EINVAL;
-			}
-		}
-	}
-	return ret;
-}
-
-static int close_sdio_ch(struct test_channel *tch)
-{
-	int ret = 0;
-
-	if (!tch) {
-		pr_err(TEST_MODULE_NAME ": %s NULL tch\n", __func__);
-		return -EINVAL;
-	}
-
-	if (tch->ch_id == SDIO_SMEM) {
-#ifdef CONFIG_MSM_SDIO_SMEM
-		TEST_DBG(TEST_MODULE_NAME":%s closing channel %s",
-		       __func__, tch->name);
-		ret = sdio_smem_unregister_client();
-		test_ctx->smem_counter = 0;
-#endif
-	} else {
-		ret = sdio_close(tch->ch);
-	}
-
-	if (ret) {
-		pr_err(TEST_MODULE_NAME":%s close channel %s"
-				" failed\n", __func__, tch->name);
-	} else {
-		TEST_DBG(TEST_MODULE_NAME":%s close channel %s"
-				" success\n", __func__, tch->name);
-		tch->ch_ready = false;
-	}
-	return ret;
-}
-
-/**
- * Config message
- */
-
-static void send_config_msg(struct test_channel *test_ch)
-{
-	int ret = 0 ;
-	u32 write_avail = 0;
-	int size = sizeof(test_ch->config_msg);
-
-	pr_debug(TEST_MODULE_NAME "%s\n", __func__);
-
-	memcpy(test_ch->buf, (void *)&test_ch->config_msg, size);
-
-	if (test_ctx->exit_flag) {
-		pr_info(TEST_MODULE_NAME ":Exit Test.\n");
-		return;
-	}
-
-	pr_info(TEST_MODULE_NAME ":Sending the config message.\n");
-
-	/* wait for data ready event */
-	write_avail = sdio_write_avail(test_ch->ch);
-	pr_debug(TEST_MODULE_NAME ":write_avail=%d\n", write_avail);
-	if (write_avail < size) {
-		wait_event(test_ch->wait_q,
-			   atomic_read(&test_ch->tx_notify_count));
-		atomic_dec(&test_ch->tx_notify_count);
-	}
-
-	write_avail = sdio_write_avail(test_ch->ch);
-	pr_debug(TEST_MODULE_NAME ":write_avail=%d\n", write_avail);
-	if (write_avail < size) {
-		pr_info(TEST_MODULE_NAME ":not enough write avail.\n");
-		return;
-	}
-
-	ret = sdio_write(test_ch->ch, test_ch->buf, size);
-	if (ret)
-		pr_err(TEST_MODULE_NAME ":%s sdio_write err=%d.\n",
-			__func__, -ret);
-	else
-		pr_info(TEST_MODULE_NAME ":%s sent config_msg successfully.\n",
-		       __func__);
-}
-
-/**
- * Loopback Test
- */
-static void loopback_test(struct test_channel *test_ch)
-{
-	int ret = 0 ;
-	u32 read_avail = 0;
-	u32 write_avail = 0;
-
-	while (1) {
-
-		if (test_ctx->exit_flag) {
-			pr_info(TEST_MODULE_NAME ":Exit Test.\n");
-			return;
-		}
-
-		TEST_DBG(TEST_MODULE_NAME "--LOOPBACK WAIT FOR EVENT--.\n");
-		/* wait for data ready event */
-		wait_event(test_ch->wait_q,
-			   atomic_read(&test_ch->rx_notify_count));
-		atomic_dec(&test_ch->rx_notify_count);
-
-		read_avail = sdio_read_avail(test_ch->ch);
-		if (read_avail == 0)
-			continue;
-
-
-		write_avail = sdio_write_avail(test_ch->ch);
-		if (write_avail < read_avail) {
-			pr_info(TEST_MODULE_NAME
-				":not enough write avail.\n");
-			continue;
-		}
-
-		ret = sdio_read(test_ch->ch, test_ch->buf, read_avail);
-		if (ret) {
-			pr_info(TEST_MODULE_NAME
-			       ":worker, sdio_read err=%d.\n", -ret);
-			continue;
-		}
-		test_ch->rx_bytes += read_avail;
-
-		TEST_DBG(TEST_MODULE_NAME ":worker total rx bytes = 0x%x.\n",
-			 test_ch->rx_bytes);
-
-
-		ret = sdio_write(test_ch->ch,
-				 test_ch->buf, read_avail);
-		if (ret) {
-			pr_info(TEST_MODULE_NAME
-				":loopback sdio_write err=%d.\n",
-				-ret);
-			continue;
-		}
-		test_ch->tx_bytes += read_avail;
-
-		TEST_DBG(TEST_MODULE_NAME
-			 ":loopback total tx bytes = 0x%x.\n",
-			 test_ch->tx_bytes);
-	} /* end of while */
-}
-
-/**
- * Check if all tests completed
- */
-static void check_test_completion(void)
-{
-	int i;
-
-	for (i = 0; i < SDIO_MAX_CHANNELS; i++) {
-		struct test_channel *tch = test_ctx->test_ch_arr[i];
-
-		if ((!tch) || (!tch->is_used) || (!tch->ch_ready))
-			continue;
-		if (!tch->test_completed) {
-			pr_info(TEST_MODULE_NAME ": %s - Channel %s test is "
-				"not completed", __func__, tch->name);
-			return;
-		}
-	}
-	pr_info(TEST_MODULE_NAME ": %s - Test is completed", __func__);
-	test_ctx->test_completed = 1;
-	wake_up(&test_ctx->wait_q);
-}
-
-static int pseudo_random_seed(unsigned int *seed_number)
-{
-	if (!seed_number)
-		return 0;
-
-	*seed_number = (unsigned int)(((unsigned long)*seed_number *
-				(unsigned long)1103515367) + 35757);
-	return (int)((*seed_number / (64*1024)) % 500);
-}
-
-/* this function must be locked before accessing it */
-static void lpm_test_update_entry(struct test_channel *tch,
-				  enum lpm_test_msg_type msg_type,
-				   char *msg_name,
-				  int counter)
-{
-	u32 index = 0;
-	static int print_full = 1;
-	struct sdio_test_device *test_device;
-
-	if (!tch) {
-		pr_err(TEST_MODULE_NAME ": %s - NULL test channel\n", __func__);
-		return;
-	}
-
-	test_device = tch->test_device;
-
-	if (!test_device) {
-		pr_err(TEST_MODULE_NAME ": %s - NULL test device\n", __func__);
-		return;
-	}
-
-	if (!test_device->lpm_arr) {
-		pr_err(TEST_MODULE_NAME ": %s - NULL lpm_arr\n", __func__);
-		return;
-	}
-
-	if (test_device->next_avail_entry_in_array >=
-					test_device->array_size) {
-		pr_err(TEST_MODULE_NAME ": %s - lpm array is full",
-			__func__);
-
-		if (print_full) {
-			print_hex_dump(KERN_INFO, TEST_MODULE_NAME ": lpm_arr:",
-				0, 32, 2,
-				(void *)test_device->lpm_arr,
-				sizeof(test_device->lpm_arr), false);
-			print_full = 0;
-		}
-		return;
-	}
-
-	index = test_device->next_avail_entry_in_array;
-	if ((msg_type == LPM_MSG_SEND) || (msg_type == LPM_MSG_REC))
-		test_device->lpm_arr[index].counter = counter;
-	else
-		test_device->lpm_arr[index].counter = 0;
-
-	test_device->lpm_arr[index].msg_type = msg_type;
-	memcpy(test_device->lpm_arr[index].msg_name, msg_name,
-	       LPM_MSG_NAME_SIZE);
-	test_device->lpm_arr[index].current_ms =
-		jiffies_to_msecs(get_jiffies_64());
-
-	test_device->lpm_arr[index].read_avail_mask =
-		test_device->read_avail_mask;
-
-	if ((msg_type == LPM_SLEEP) || (msg_type == LPM_WAKEUP))
-		memcpy(test_device->lpm_arr[index].chan_name, "DEVICE  ",
-		       CHANNEL_NAME_SIZE);
-	else
-		memcpy(test_device->lpm_arr[index].chan_name, tch->name,
-		       CHANNEL_NAME_SIZE);
-
-	test_device->next_avail_entry_in_array++;
-}
-
-static int wait_for_result_msg(struct test_channel *test_ch)
-{
-	u32 read_avail = 0;
-	int ret = 0;
-
-	pr_info(TEST_MODULE_NAME ": %s - START, channel %s\n",
-		__func__, test_ch->name);
-
-	while (1) {
-		read_avail = sdio_read_avail(test_ch->ch);
-
-		if (read_avail == 0) {
-			pr_info(TEST_MODULE_NAME
-				": read_avail is 0 for chan %s\n",
-				test_ch->name);
-			wait_event(test_ch->wait_q,
-				   atomic_read(&test_ch->rx_notify_count));
-			atomic_dec(&test_ch->rx_notify_count);
-			continue;
-		}
-
-		memset(test_ch->buf, 0x00, test_ch->buf_size);
-
-		ret = sdio_read(test_ch->ch, test_ch->buf, read_avail);
-		if (ret) {
-			pr_info(TEST_MODULE_NAME ":  sdio_read for chan"
-				"%s failed, err=%d.\n",
-				test_ch->name, -ret);
-			goto exit_err;
-		}
-
-		if (test_ch->buf[0] != TEST_CONFIG_SIGNATURE) {
-			pr_info(TEST_MODULE_NAME ": Not a test_result "
-				"signature. expected 0x%x. received 0x%x "
-				"for chan %s\n",
-				TEST_CONFIG_SIGNATURE,
-				test_ch->buf[0],
-				test_ch->name);
-			continue;
-		} else {
-			pr_info(TEST_MODULE_NAME ": Signature is "
-				"TEST_CONFIG_SIGNATURE as expected for"
-				"channel %s\n", test_ch->name);
-			break;
-		}
-	}
-
-	return test_ch->buf[1];
-
-exit_err:
-	return 0;
-}
-
-static void print_random_lpm_test_array(struct sdio_test_device *test_dev)
-{
-	int i;
-
-	if (!test_dev) {
-		pr_err(TEST_MODULE_NAME ": %s - NULL test device\n", __func__);
-		return;
-	}
-
-	for (i = 0 ; i < test_dev->next_avail_entry_in_array ; ++i) {
-		if (i == 0)
-			pr_err(TEST_MODULE_NAME ": index %4d, chan=%2s, "
-			       "code=%1d=%4s, msg#%1d, ms from before=-1, "
-			       "read_mask=0x%d, ms=%2u",
-			       i,
-			       test_dev->lpm_arr[i].chan_name,
-			       test_dev->lpm_arr[i].msg_type,
-			       test_dev->lpm_arr[i].msg_name,
-			       test_dev->lpm_arr[i].counter,
-			       test_dev->lpm_arr[i].read_avail_mask,
-			       test_dev->lpm_arr[i].current_ms);
-		else
-			pr_err(TEST_MODULE_NAME ": index "
-			       "%4d, %2s, code=%1d=%4s, msg#%1d, ms from "
-			       "before=%2u, read_mask=0x%d, ms=%2u",
-			       i,
-			       test_dev->lpm_arr[i].chan_name,
-			       test_dev->lpm_arr[i].msg_type,
-			       test_dev->lpm_arr[i].msg_name,
-			       test_dev->lpm_arr[i].counter,
-			       test_dev->lpm_arr[i].current_ms -
-			       test_dev->lpm_arr[i-1].current_ms,
-			       test_dev->lpm_arr[i].read_avail_mask,
-			       test_dev->lpm_arr[i].current_ms);
-
-		udelay(1000);
-	}
-}
-
-static int check_random_lpm_test_array(struct sdio_test_device *test_dev)
-{
-	int i = 0, j = 0;
-	unsigned int delta_ms = 0;
-	int arr_ind = 0;
-	int ret = 0;
-	int notify_counter = 0;
-	int sleep_counter = 0;
-	int wakeup_counter = 0;
-	int lpm_activity_counter = 0;
-
-	if (!test_dev) {
-		pr_err(TEST_MODULE_NAME ": %s - NULL test device\n", __func__);
-		return -ENODEV;
-	}
-
-	for (i = 0; i < test_dev->next_avail_entry_in_array; i++) {
-		notify_counter = 0;
-		sleep_counter = 0;
-		wakeup_counter = 0;
-
-		if ((test_dev->lpm_arr[i].msg_type == LPM_MSG_SEND) ||
-		     (test_dev->lpm_arr[i].msg_type == LPM_MSG_REC)) {
-			/* find the next message in the array */
-			arr_ind = test_dev->next_avail_entry_in_array;
-			for (j = i+1; j < arr_ind; j++) {
-				if ((test_dev->lpm_arr[j].msg_type ==
-				     LPM_MSG_SEND) ||
-				    (test_dev->lpm_arr[j].msg_type ==
-				     LPM_MSG_REC) ||
-				    (test_dev->lpm_arr[j].msg_type ==
-				     LPM_NOTIFY))
-					break;
-				if (test_dev->lpm_arr[j].msg_type ==
-				    LPM_SLEEP)
-					sleep_counter++;
-				if (test_dev->lpm_arr[j].msg_type ==
-				    LPM_WAKEUP)
-					wakeup_counter++;
-			}
-			if (j == arr_ind) {
-				ret = 0;
-				break;
-			}
-
-			delta_ms = test_dev->lpm_arr[j].current_ms -
-				test_dev->lpm_arr[i].current_ms;
-			if (delta_ms < 30) {
-				if ((sleep_counter == 0)
-				    && (wakeup_counter == 0)) {
-					continue;
-				} else {
-					pr_err(TEST_MODULE_NAME "%s: lpm "
-						"activity while delta is less "
-						"than 30, i=%d, j=%d, "
-						"sleep_counter=%d, "
-						"wakeup_counter=%d",
-					       __func__, i, j,
-					       sleep_counter, wakeup_counter);
-					ret = -ENODEV;
-					break;
-				}
-			} else {
-				if ((delta_ms > 90) &&
-				    (test_dev->lpm_arr[i].
-						read_avail_mask == 0)) {
-					if (j != i+3) {
-						pr_err(TEST_MODULE_NAME
-						       "%s: unexpected "
-						       "lpm activity "
-						       "while delta is "
-						       "bigger than "
-						       "90, i=%d, "
-						       "j=%d, "
-						       "notify_counter"
-						       "=%d",
-						       __func__, i, j,
-						       notify_counter);
-						ret = -ENODEV;
-						break;
-					}
-					lpm_activity_counter++;
-				}
-			}
-		}
-	}
-
-	pr_info(TEST_MODULE_NAME ": %s - lpm_activity_counter=%d",
-		__func__, lpm_activity_counter);
-
-	return ret;
-}
-
-static int lpm_test_main_task(void *ptr)
-{
-	u32 read_avail = 0;
-	int last_msg_index = 0;
-	struct test_channel *test_ch = (struct test_channel *)ptr;
-	struct sdio_test_device *test_dev;
-	struct lpm_msg lpm_msg;
-	int ret = 0;
-	int host_result = 0;
-
-	if (!test_ch) {
-		pr_err(TEST_MODULE_NAME ": %s - NULL channel\n", __func__);
-		return -ENODEV;
-	}
-
-	pr_err(TEST_MODULE_NAME ": %s - STARTED. channel %s\n",
-	       __func__, test_ch->name);
-
-	test_dev = test_ch->test_device;
-
-	if (!test_dev) {
-		pr_err(TEST_MODULE_NAME ": %s - NULL Test Device\n", __func__);
-		return -ENODEV;
-	}
-
-	while (last_msg_index < test_ch->config_msg.num_packets - 1) {
-
-		TEST_DBG(TEST_MODULE_NAME ": %s - "
-			"IN LOOP last_msg_index=%d\n",
-		       __func__, last_msg_index);
-
-		read_avail = sdio_read_avail(test_ch->ch);
-		if (read_avail == 0) {
-			TEST_DBG(TEST_MODULE_NAME
-					":read_avail 0 for chan %s, "
-					"wait for event\n",
-					test_ch->name);
-			wait_event(test_ch->wait_q,
-				   atomic_read(&test_ch->rx_notify_count));
-			atomic_dec(&test_ch->rx_notify_count);
-
-			read_avail = sdio_read_avail(test_ch->ch);
-			if (read_avail == 0) {
-				pr_err(TEST_MODULE_NAME
-					":read_avail size %d for chan %s not as"
-					" expected\n",
-					read_avail, test_ch->name);
-				continue;
-			}
-		}
-
-		memset(test_ch->buf, 0x00, sizeof(test_ch->buf));
-
-		ret = sdio_read(test_ch->ch, test_ch->buf, read_avail);
-		if (ret) {
-			pr_info(TEST_MODULE_NAME ":sdio_read for chan %s"
-				" err=%d.\n", test_ch->name, -ret);
-			goto exit_err;
-		}
-
-		memcpy((void *)&lpm_msg, test_ch->buf, sizeof(lpm_msg));
-
-		/*
-		 * when reading from channel, we want to turn off the bit
-		 * mask that implies that there is pending data on that channel
-		 */
-		if (test_ch->test_device != NULL) {
-			spin_lock_irqsave(&test_dev->lpm_array_lock,
-					  test_dev->lpm_array_lock_flags);
-
-			test_ch->notify_counter_per_chan--;
-
-			/*
-			 * if the channel has no pending data, turn off the
-			 * pending data bit mask of the channel
-			 */
-			if (test_ch->notify_counter_per_chan == 0) {
-				test_ch->test_device->read_avail_mask =
-					test_ch->test_device->read_avail_mask &
-					~test_ch->channel_mask_id;
-			}
-
-			last_msg_index = lpm_msg.counter;
-			lpm_test_update_entry(test_ch,
-					      LPM_MSG_REC,
-					      "RECEIVE",
-					      last_msg_index);
-
-			spin_unlock_irqrestore(&test_dev->lpm_array_lock,
-					       test_dev->lpm_array_lock_flags);
-		}
-	}
-
-	pr_info(TEST_MODULE_NAME ":%s: Finished to recieve all (%d) "
-		"packets from the modem %s. Waiting for result_msg",
-		__func__, test_ch->config_msg.num_packets, test_ch->name);
-
-	/* Wait for the resault message from the modem */
-	test_ch->modem_result_per_chan = wait_for_result_msg(test_ch);
-
-	/*
-	 * the DEVICE modem result is a failure if one of the channels on
-	 * that device, got modem_result = 0. this is why we bitwise "AND" each
-	 * time another channel completes its task
-	 */
-	test_dev->modem_result_per_dev &= test_ch->modem_result_per_chan;
-
-	/*
-	 * when reading from channel, we want to turn off the bit
-	 * mask that implies that there is pending data on that channel
-	 */
-	spin_lock_irqsave(&test_dev->lpm_array_lock,
-					  test_dev->lpm_array_lock_flags);
-
-	test_dev->open_channels_counter_to_recv--;
-
-	/* turning off the read_avail bit of the channel */
-	test_ch->test_device->read_avail_mask =
-		test_ch->test_device->read_avail_mask &
-		~test_ch->channel_mask_id;
-
-	spin_unlock_irqrestore(&test_dev->lpm_array_lock,
-					       test_dev->lpm_array_lock_flags);
-
-	/* Wait for all the packets to be sent to the modem */
-	while (1) {
-		spin_lock_irqsave(&test_dev->lpm_array_lock,
-				  test_dev->lpm_array_lock_flags);
-
-		if (test_ch->next_index_in_sent_msg_per_chan >=
-		    test_ch->config_msg.num_packets - 1) {
-
-			spin_unlock_irqrestore(&test_dev->lpm_array_lock,
-					       test_dev->lpm_array_lock_flags);
-			break;
-		} else {
-			pr_info(TEST_MODULE_NAME ":%s: Didn't finished to send "
-				"all packets, "
-				"next_index_in_sent_msg_per_chan = %d ",
-				__func__,
-				test_ch->next_index_in_sent_msg_per_chan);
-		}
-		spin_unlock_irqrestore(&test_dev->lpm_array_lock,
-				       test_dev->lpm_array_lock_flags);
-		msleep(60);
-	}
-
-	/*
-	 * if device has still open channels to test, then the test on the
-	 * device is still running but the test on current channel is completed
-	 */
-	if (test_dev->open_channels_counter_to_recv != 0 ||
-	    test_dev->open_channels_counter_to_send != 0) {
-		test_ch->test_completed = 1;
-		return 0;
-	} else {
-		test_ctx->number_of_active_devices--;
-		sdio_al_unregister_lpm_cb(test_ch->sdio_al_device);
-
-		if (test_ch->test_type == SDIO_TEST_LPM_RANDOM)
-			host_result = check_random_lpm_test_array(test_dev);
-
-		if (host_result ||
-		    !test_dev->modem_result_per_dev ||
-		    test_ctx->runtime_debug)
-			print_random_lpm_test_array(test_dev);
-
-		pr_info(TEST_MODULE_NAME ": %s - host_result=%d.(0 for "
-			"SUCCESS) device_modem_result=%d (1 for SUCCESS)",
-			__func__, host_result, test_dev->modem_result_per_dev);
-
-		test_ch->test_completed = 1;
-		if (test_dev->modem_result_per_dev && !host_result) {
-			pr_info(TEST_MODULE_NAME ": %s - Random LPM "
-				"TEST_PASSED for device %d of %d\n",
-				__func__,
-				(test_ctx->max_number_of_devices-
-				test_ctx->number_of_active_devices),
-				test_ctx->max_number_of_devices);
-			test_dev->final_result_per_dev = 1; /* PASSED */
-		} else {
-			pr_info(TEST_MODULE_NAME ": %s - Random LPM "
-				"TEST_FAILED for device %d of %d\n",
-				__func__,
-				(test_ctx->max_number_of_devices-
-				test_ctx->number_of_active_devices),
-				test_ctx->max_number_of_devices);
-			test_dev->final_result_per_dev = 0; /* FAILED */
-		}
-
-		check_test_completion();
-
-		kfree(test_ch->test_device->lpm_arr);
-
-		return 0;
-	}
-
-exit_err:
-	pr_info(TEST_MODULE_NAME ": TEST FAIL for chan %s.\n",
-		test_ch->name);
-	test_ch->test_completed = 1;
-	test_dev->open_channels_counter_to_recv--;
-	test_dev->next_avail_entry_in_array = 0;
-	test_ch->next_index_in_sent_msg_per_chan = 0;
-	test_ch->test_result = TEST_FAILED;
-	check_test_completion();
-	return -ENODEV;
-}
-
-static int lpm_test_create_read_thread(struct test_channel *test_ch)
-{
-	struct sdio_test_device *test_dev;
-
-	pr_info(TEST_MODULE_NAME ": %s - STARTED channel %s\n",
-		__func__, test_ch->name);
-
-	if (!test_ch) {
-		pr_err(TEST_MODULE_NAME ": %s - NULL test channel\n", __func__);
-		return -ENODEV;
-	}
-
-	test_dev = test_ch->test_device;
-
-	if (!test_dev) {
-		pr_err(TEST_MODULE_NAME ": %s - NULL test device\n", __func__);
-		return -ENODEV;
-	}
-
-	test_dev->lpm_test_task.task_name = SDIO_LPM_TEST;
-
-	test_dev->lpm_test_task.lpm_task =
-		kthread_create(lpm_test_main_task,
-			       (void *)(test_ch),
-			       test_dev->lpm_test_task.task_name);
-
-	if (IS_ERR(test_dev->lpm_test_task.lpm_task)) {
-		pr_err(TEST_MODULE_NAME ": %s - kthread_create() failed\n",
-			__func__);
-		return -ENOMEM;
-	}
-
-	wake_up_process(test_dev->lpm_test_task.lpm_task);
-
-	return 0;
-}
-
-static void lpm_continuous_rand_test(struct test_channel *test_ch)
-{
-	unsigned int local_ms = 0;
-	int ret = 0;
-	unsigned int write_avail = 0;
-	struct sdio_test_device *test_dev;
-
-	pr_info(MODULE_NAME ": %s - STARTED\n", __func__);
-
-	if (!test_ch) {
-		pr_err(TEST_MODULE_NAME ": %s - NULL channel\n", __func__);
-		return;
-	}
-
-	test_dev = test_ch->test_device;
-
-	if (!test_dev) {
-		pr_err(TEST_MODULE_NAME ": %s - NULL Test Device\n", __func__);
-		return;
-	}
-
-	ret = lpm_test_create_read_thread(test_ch);
-	if (ret != 0) {
-		pr_err(TEST_MODULE_NAME ": %s - failed to create lpm reading "
-		       "thread", __func__);
-	}
-
-	while (1) {
-
-		struct lpm_msg msg;
-		u32 ret = 0;
-
-		/* sleeping period is dependent on number of open channels */
-		test_ch->config_msg.test_param =
-				test_ctx->lpm_pseudo_random_seed;
-
-		local_ms = test_dev->open_channels_counter_to_send *
-			test_ctx->lpm_pseudo_random_seed;
-		TEST_DBG(TEST_MODULE_NAME ":%s: SLEEPING for %d ms",
-		       __func__, local_ms);
-		msleep(local_ms);
-
-		msg.counter = test_ch->next_index_in_sent_msg_per_chan;
-		msg.signature = LPM_TEST_CONFIG_SIGNATURE;
-		msg.reserve1 = 0;
-		msg.reserve2 = 0;
-
-		/* wait for data ready event */
-		write_avail = sdio_write_avail(test_ch->ch);
-		pr_debug(TEST_MODULE_NAME ": %s: write_avail=%d\n",
-		       __func__, write_avail);
-		if (write_avail < sizeof(msg)) {
-			wait_event(test_ch->wait_q,
-				   atomic_read(&test_ch->tx_notify_count));
-			atomic_dec(&test_ch->tx_notify_count);
-		}
-
-		write_avail = sdio_write_avail(test_ch->ch);
-		if (write_avail < sizeof(msg)) {
-			pr_info(TEST_MODULE_NAME ": %s: not enough write "
-				"avail.\n", __func__);
-			break;
-		}
-
-		ret = sdio_write(test_ch->ch, (u32 *)&msg, sizeof(msg));
-		if (ret)
-			pr_err(TEST_MODULE_NAME ":%s: sdio_write err=%d.\n",
-				__func__, -ret);
-
-		TEST_DBG(TEST_MODULE_NAME ": %s: for chan %s, write, "
-			 "msg # %d\n",
-			 __func__,
-			 test_ch->name,
-			 test_ch->next_index_in_sent_msg_per_chan);
-
-		if (test_ch->test_type == SDIO_TEST_LPM_RANDOM) {
-			spin_lock_irqsave(&test_dev->lpm_array_lock,
-					  test_dev->lpm_array_lock_flags);
-			lpm_test_update_entry(test_ch, LPM_MSG_SEND,
-					      "SEND  ",
-					      test_ch->
-					      next_index_in_sent_msg_per_chan);
-
-			test_ch->next_index_in_sent_msg_per_chan++;
-
-			if (test_ch->next_index_in_sent_msg_per_chan ==
-			    test_ch->config_msg.num_packets) {
-				spin_unlock_irqrestore(
-				    &test_dev->lpm_array_lock,
-				    test_dev->lpm_array_lock_flags);
-				break;
-			}
-
-			spin_unlock_irqrestore(&test_dev->lpm_array_lock,
-					       test_dev->lpm_array_lock_flags);
-		}
-	}
-
-	spin_lock_irqsave(&test_dev->lpm_array_lock,
-				  test_dev->lpm_array_lock_flags);
-	test_dev->open_channels_counter_to_send--;
-	spin_unlock_irqrestore(&test_dev->lpm_array_lock,
-				       test_dev->lpm_array_lock_flags);
-
-	pr_info(TEST_MODULE_NAME ": %s: - Finished to send all (%d) "
-		"packets to the modem on channel %s",
-		__func__, test_ch->config_msg.num_packets, test_ch->name);
-
-	return;
-}
-
-static void lpm_test(struct test_channel *test_ch)
-{
-	pr_info(TEST_MODULE_NAME ": %s - START channel %s\n", __func__,
-		test_ch->name);
-
-	if (!test_ch) {
-		pr_err(TEST_MODULE_NAME ": %s - NULL test channel\n", __func__);
-		return;
-	}
-
-	test_ch->modem_result_per_chan = wait_for_result_msg(test_ch);
-	pr_debug(TEST_MODULE_NAME ": %s - delete the timeout timer\n",
-	       __func__);
-	del_timer_sync(&test_ch->timeout_timer);
-
-	if (test_ch->modem_result_per_chan == 0) {
-		pr_err(TEST_MODULE_NAME ": LPM TEST - Client didn't sleep. "
-		       "Result Msg - is_successful=%d\n", test_ch->buf[1]);
-		goto exit_err;
-	} else {
-		pr_info(TEST_MODULE_NAME ": %s -"
-			"LPM 9K WAS SLEEPING - PASS\n", __func__);
-		if (test_ch->test_result == TEST_PASSED) {
-			pr_info(TEST_MODULE_NAME ": LPM TEST_PASSED\n");
-			test_ch->test_completed = 1;
-			check_test_completion();
-		} else {
-			pr_err(TEST_MODULE_NAME ": LPM TEST - Host didn't "
-			       "sleep. Client slept\n");
-			goto exit_err;
-		}
-	}
-
-	return;
-
-exit_err:
-	pr_info(TEST_MODULE_NAME ": TEST FAIL for chan %s.\n",
-		test_ch->name);
-	test_ch->test_completed = 1;
-	test_ch->test_result = TEST_FAILED;
-	check_test_completion();
-	return;
-}
-
-
-/**
- * LPM Test while the host wakes up the modem
- */
-static void lpm_test_host_waker(struct test_channel *test_ch)
-{
-	pr_info(TEST_MODULE_NAME ": %s - START\n", __func__);
-	wait_event(test_ch->wait_q, atomic_read(&test_ch->wakeup_client));
-	atomic_set(&test_ch->wakeup_client, 0);
-
-	pr_info(TEST_MODULE_NAME ": %s - Sending the config_msg to wakeup "
-		" the client\n", __func__);
-	send_config_msg(test_ch);
-
-	lpm_test(test_ch);
-}
-
-/**
-  * Writes number of packets into test channel
-  * @test_ch: test channel control struct
-  * @burst_size: number of packets to send
-  */
-static int write_packet_burst(struct test_channel *test_ch,
-		int burst_size)
-{
-	int ret = 0;
-	int packet_count = 0;
-	unsigned int random_num = 0;
-	int size = test_ch->packet_length; /* first packet size */
-	u32 write_avail = 0;
-
-	while (packet_count < burst_size) {
-		/* wait for data ready event */
-		write_avail = sdio_write_avail(test_ch->ch);
-		TEST_DBG(TEST_MODULE_NAME ":%s write_avail=%d,size=%d on chan"
-				" %s\n", __func__,
-				write_avail, size, test_ch->name);
-		if (write_avail < size) {
-			TEST_DBG(TEST_MODULE_NAME ":%s wait for event on"
-					" chan %s\n", __func__, test_ch->name);
-			wait_event(test_ch->wait_q,
-					atomic_read(&test_ch->tx_notify_count));
-			atomic_dec(&test_ch->tx_notify_count);
-		}
-		write_avail = sdio_write_avail(test_ch->ch);
-		if (write_avail < size) {
-			pr_info(TEST_MODULE_NAME ":%s not enough write"
-					" avail %d, need %d on chan %s\n",
-					__func__, write_avail, size,
-					test_ch->name);
-			continue;
-		}
-		ret = sdio_write(test_ch->ch, test_ch->buf, size);
-		if (ret) {
-			pr_err(TEST_MODULE_NAME ":%s sdio_write "
-					"failed (%d) on chan %s\n", __func__,
-					ret, test_ch->name);
-			break;
-		}
-		udelay(1000); /*low bus usage while running number of channels*/
-		TEST_DBG(TEST_MODULE_NAME ":%s() successfully write %d bytes"
-				", packet_count=%d on chan %s\n", __func__,
-				size, packet_count, test_ch->name);
-		test_ch->tx_bytes += size;
-		packet_count++;
-		/* get next packet size */
-		random_num = get_random_int();
-		size = (random_num % test_ch->packet_length) + 1;
-	}
-	return ret;
-}
-
-/**
-  * Reads packet from test channel and checks that packet number
-  * encoded into the packet is equal to packet_counter
-  * This function is applicable for packet mode channels only
-  *
-  * @test_ch: test channel
-  * @size: expected packet size
-  * @packet_counter: number to validate readed packet
-  */
-static int read_data_from_packet_ch(struct test_channel *test_ch,
-				unsigned int size,
-				int packet_counter)
-{
-	u32 read_avail = 0;
-	int ret = 0;
-
-	if (!test_ch || !test_ch->ch) {
-		pr_err(TEST_MODULE_NAME
-				":%s: NULL channel\n", __func__);
-		return -EINVAL;
-	}
-
-	if (!test_ch->ch->is_packet_mode) {
-		pr_err(TEST_MODULE_NAME
-				":%s:not packet mode ch %s\n",
-				__func__, test_ch->name);
-		return -EINVAL;
-	}
-	read_avail = sdio_read_avail(test_ch->ch);
-	/* wait for read data ready event */
-	if (read_avail < size) {
-		TEST_DBG(TEST_MODULE_NAME ":%s() wait for rx data on "
-				"chan %s\n", __func__, test_ch->name);
-		wait_event(test_ch->wait_q,
-				atomic_read(&test_ch->rx_notify_count));
-		atomic_dec(&test_ch->rx_notify_count);
-	}
-	read_avail = sdio_read_avail(test_ch->ch);
-	TEST_DBG(TEST_MODULE_NAME ":%s read_avail=%d bytes on chan %s\n",
-			__func__, read_avail, test_ch->name);
-
-	if (read_avail != size) {
-		pr_err(TEST_MODULE_NAME
-				":read_avail size %d for chan %s not as "
-				"expected size %d\n",
-				read_avail, test_ch->name, size);
-		return -EINVAL;
-	}
-
-	ret = sdio_read(test_ch->ch, test_ch->buf, read_avail);
-	if (ret) {
-		pr_err(TEST_MODULE_NAME ":%s() sdio_read for chan %s (%d)\n",
-				__func__, test_ch->name, -ret);
-		return ret;
-	}
-	if ((test_ch->buf[0] != packet_counter) && (size != 1)) {
-		pr_err(TEST_MODULE_NAME ":Read WRONG DATA"
-				" for chan %s, size=%d\n",
-				test_ch->name, size);
-		return -EINVAL;
-	}
-	return 0;
-}
-
-
-/**
-  * Reads packet from test channel and checks that packet number
-  * encoded into the packet is equal to packet_counter
-  * This function is applicable for streaming mode channels only
-  *
-  * @test_ch: test channel
-  * @size: expected packet size
-  * @packet_counter: number to validate readed packet
-  */
-static int read_data_from_stream_ch(struct test_channel *test_ch,
-				unsigned int size,
-				int packet_counter)
-{
-	u32 read_avail = 0;
-	int ret = 0;
-
-	if (!test_ch || !test_ch->ch) {
-		pr_err(TEST_MODULE_NAME
-				":%s: NULL channel\n", __func__);
-		return -EINVAL;
-	}
-
-	if (test_ch->ch->is_packet_mode) {
-		pr_err(TEST_MODULE_NAME
-				":%s:not streaming mode ch %s\n",
-				__func__, test_ch->name);
-		return -EINVAL;
-	}
-	read_avail = sdio_read_avail(test_ch->ch);
-	/* wait for read data ready event */
-	if (read_avail < size) {
-		TEST_DBG(TEST_MODULE_NAME ":%s() wait for rx data on "
-				"chan %s\n", __func__, test_ch->name);
-		wait_event(test_ch->wait_q,
-				atomic_read(&test_ch->rx_notify_count));
-		atomic_dec(&test_ch->rx_notify_count);
-	}
-	read_avail = sdio_read_avail(test_ch->ch);
-	TEST_DBG(TEST_MODULE_NAME ":%s read_avail=%d bytes on chan %s\n",
-			__func__, read_avail, test_ch->name);
-
-	if (read_avail < size) {
-		pr_err(TEST_MODULE_NAME
-				":read_avail size %d for chan %s not as "
-				"expected size %d\n",
-				read_avail, test_ch->name, size);
-		return -EINVAL;
-	}
-
-	ret = sdio_read(test_ch->ch, test_ch->buf, size + A2_HEADER_OVERHEAD);
-	if (ret) {
-		pr_err(TEST_MODULE_NAME ":%s() sdio_read for chan %s (%d)\n",
-				__func__, test_ch->name, -ret);
-		return ret;
-	}
-	if ((test_ch->buf[A2_HEADER_OVERHEAD/4] != packet_counter) &&
-	    (size != 1)) {
-		pr_err(TEST_MODULE_NAME ":Read WRONG DATA"
-				" for chan %s, size=%d, packet_counter=%d\n",
-				test_ch->name, size, packet_counter);
-		print_hex_dump(KERN_INFO, TEST_MODULE_NAME ": rmnet:",
-				0, 32, 2,
-				(void *)test_ch->buf,
-				size + A2_HEADER_OVERHEAD, false);
-		return -EINVAL;
-	}
-	return 0;
-}
-
-/**
- *   Test close channel feature for SDIO_SMEM channel:
- *   close && re-open the SDIO_SMEM channel.
- */
-#ifdef CONFIG_MSM_SDIO_SMEM
-static void open_close_smem_test(struct test_channel *test_ch)
-{
-	int i = 0;
-	int ret = 0;
-
-	pr_info(TEST_MODULE_NAME ":%s\n", __func__);
-
-	for (i = 0; i < 100 ; ++i) {
-		ret = close_sdio_ch(test_ch);
-		if (ret) {
-			pr_err(TEST_MODULE_NAME ":%s close_sdio_ch for ch %s"
-						" failed\n",
-						__func__, test_ch->name);
-			goto exit_err;
-		}
-		ret = open_sdio_ch(test_ch);
-		if (ret) {
-			pr_err(TEST_MODULE_NAME ":%s open_sdio_ch for ch %s "
-						" failed\n",
-						__func__, test_ch->name);
-			goto exit_err;
-		}
-	}
-
-	pr_info(TEST_MODULE_NAME ":%s TEST PASS for chan %s.\n", __func__,
-			test_ch->name);
-	test_ch->test_completed = 1;
-	test_ch->test_result = TEST_PASSED;
-	check_test_completion();
-	return;
-exit_err:
-	pr_info(TEST_MODULE_NAME ":%s TEST FAIL for chan %s.\n", __func__,
-			test_ch->name);
-	test_ch->test_completed = 1;
-	test_ch->test_result = TEST_FAILED;
-	check_test_completion();
-	return;
-}
-#endif
-
-/**
- *   Test close channel feature:
- *   1. write random packet number into channel
- *   2. read some data from channel (do this only for second half of
- *   requested packets to send).
- *   3. close && re-open then repeat 1.
- *
- *   Total packets to send: test_ch->config_msg.num_packets.
- *   Burst size is random in [1..test_ch->max_burst_size] range
- *   Packet size is random in [1..test_ch->packet_length]
- */
-static void open_close_test(struct test_channel *test_ch)
-{
-	int ret = 0;
-	u32 read_avail = 0;
-	int total_packet_count = 0;
-	int size = 0;
-	u16 *buf16 = NULL;
-	int i;
-	int max_packet_count = 0;
-	unsigned int random_num = 0;
-	int curr_burst_size = 0;
-
-	if (!test_ch || !test_ch->ch) {
-		pr_err(TEST_MODULE_NAME ":%s NULL channel\n",
-				__func__);
-		return;
-	}
-
-	curr_burst_size = test_ch->max_burst_size;
-	size = test_ch->packet_length;
-	buf16 = (u16 *) test_ch->buf;
-
-	/* the test sends configured number of packets in
-	   2 portions: first without reading between write bursts,
-	   second with it */
-	max_packet_count = test_ch->config_msg.num_packets / 2;
-
-	pr_info(TEST_MODULE_NAME ":%s channel %s, total packets:%d,"
-			" max packet size %d, max burst size:%d\n",
-			__func__, test_ch->name,
-			test_ch->config_msg.num_packets, test_ch->packet_length,
-			test_ch->max_burst_size);
-	for (i = 0 ; i < size / 2 ; i++)
-		buf16[i] = (u16) (i & 0xFFFF);
-
-	for (i = 0; i < 2 ; i++) {
-		total_packet_count = 0;
-		while (total_packet_count < max_packet_count) {
-			if (test_ctx->exit_flag) {
-				pr_info(TEST_MODULE_NAME ":%s exit test\n",
-						__func__);
-				return;
-			}
-			test_ch->buf[0] = total_packet_count;
-			random_num = get_random_int();
-			curr_burst_size = (random_num %
-					test_ch->max_burst_size) + 1;
-
-			/* limit burst size to send
-			 * no more than configured packets */
-			if (curr_burst_size + total_packet_count >
-					max_packet_count) {
-				curr_burst_size = max_packet_count -
-					total_packet_count;
-			}
-			TEST_DBG(TEST_MODULE_NAME ":%s Current burst size:%d"
-					" on chan %s\n", __func__,
-					curr_burst_size, test_ch->name);
-			ret = write_packet_burst(test_ch, curr_burst_size);
-			if (ret) {
-				pr_err(TEST_MODULE_NAME ":%s write burst failed (%d), ch %s\n",
-						__func__, ret, test_ch->name);
-				goto exit_err;
-			}
-			if (i > 0) {
-				/* read from channel */
-				if (test_ch->ch->is_packet_mode)
-					ret = read_data_from_packet_ch(test_ch,
-							size,
-							total_packet_count);
-				else
-					ret = read_data_from_stream_ch(test_ch,
-							size,
-							total_packet_count);
-				if (ret) {
-					pr_err(TEST_MODULE_NAME ":%s read"
-							" failed:%d, chan %s\n",
-							__func__, ret,
-							test_ch->name);
-					goto exit_err;
-				}
-			}
-			TEST_DBG(TEST_MODULE_NAME ":%s before close, ch %s\n",
-					__func__, test_ch->name);
-			ret = close_sdio_ch(test_ch);
-			if (ret) {
-				pr_err(TEST_MODULE_NAME":%s close channel %s"
-						" failed (%d)\n",
-						__func__, test_ch->name, ret);
-				goto exit_err;
-			} else {
-				TEST_DBG(TEST_MODULE_NAME":%s close channel %s"
-						" success\n", __func__,
-						test_ch->name);
-				total_packet_count += curr_burst_size;
-				atomic_set(&test_ch->rx_notify_count, 0);
-				atomic_set(&test_ch->tx_notify_count, 0);
-				atomic_set(&test_ch->any_notify_count, 0);
-			}
-			TEST_DBG(TEST_MODULE_NAME ":%s before open, ch %s\n",
-					__func__, test_ch->name);
-			ret = open_sdio_ch(test_ch);
-			if (ret) {
-				pr_err(TEST_MODULE_NAME":%s open channel %s"
-						" failed (%d)\n",
-						__func__, test_ch->name, ret);
-				goto exit_err;
-			} else {
-				read_avail = sdio_read_avail(test_ch->ch);
-				if (read_avail > 0) {
-					pr_err(TEST_MODULE_NAME": after open"
-						" ch %s read_availis not zero"
-						" (%d bytes)\n",
-						test_ch->name, read_avail);
-					goto exit_err;
-				}
-			}
-			TEST_DBG(TEST_MODULE_NAME ":%s total tx = %d,"
-					" packet# = %d, size = %d for ch %s\n",
-					__func__, test_ch->tx_bytes,
-					total_packet_count, size,
-					test_ch->name);
-		} /* end of while */
-	}
-	pr_info(TEST_MODULE_NAME ":%s Test end: total rx bytes = 0x%x,"
-			" total tx bytes = 0x%x for chan %s\n", __func__,
-			test_ch->rx_bytes, test_ch->tx_bytes, test_ch->name);
-	pr_info(TEST_MODULE_NAME ":%s TEST PASS for chan %s.\n", __func__,
-			test_ch->name);
-	test_ch->test_completed = 1;
-	test_ch->test_result = TEST_PASSED;
-	check_test_completion();
-	return;
-exit_err:
-	pr_info(TEST_MODULE_NAME ":%s TEST FAIL for chan %s.\n", __func__,
-			test_ch->name);
-	test_ch->test_completed = 1;
-	test_ch->test_result = TEST_FAILED;
-	check_test_completion();
-	return;
-}
-
-/**
- * sender Test
- */
-static void sender_test(struct test_channel *test_ch)
-{
-	int ret = 0 ;
-	u32 read_avail = 0;
-	u32 write_avail = 0;
-	int packet_count = 0;
-	int size = 512;
-	u16 *buf16 = (u16 *) test_ch->buf;
-	int i;
-	int max_packet_count = 10000;
-	int random_num = 0;
-
-	max_packet_count = test_ch->config_msg.num_packets;
-
-	for (i = 0 ; i < size / 2 ; i++)
-		buf16[i] = (u16) (i & 0xFFFF);
-
-
-	pr_info(TEST_MODULE_NAME
-		 ":SENDER TEST START for chan %s\n", test_ch->name);
-
-	while (packet_count < max_packet_count) {
-
-		if (test_ctx->exit_flag) {
-			pr_info(TEST_MODULE_NAME ":Exit Test.\n");
-			return;
-		}
-
-		random_num = get_random_int();
-		size = (random_num % test_ch->packet_length) + 1;
-
-		TEST_DBG(TEST_MODULE_NAME "SENDER WAIT FOR EVENT for chan %s\n",
-			test_ch->name);
-
-		/* wait for data ready event */
-		write_avail = sdio_write_avail(test_ch->ch);
-		TEST_DBG(TEST_MODULE_NAME ":write_avail=%d\n", write_avail);
-		if (write_avail < size) {
-			wait_event(test_ch->wait_q,
-				   atomic_read(&test_ch->tx_notify_count));
-			atomic_dec(&test_ch->tx_notify_count);
-		}
-
-		write_avail = sdio_write_avail(test_ch->ch);
-		TEST_DBG(TEST_MODULE_NAME ":write_avail=%d\n", write_avail);
-		if (write_avail < size) {
-			pr_info(TEST_MODULE_NAME ":not enough write avail.\n");
-			continue;
-		}
-
-		test_ch->buf[0] = packet_count;
-
-		ret = sdio_write(test_ch->ch, test_ch->buf, size);
-		if (ret) {
-			pr_info(TEST_MODULE_NAME ":sender sdio_write err=%d.\n",
-				-ret);
-			goto exit_err;
-		}
-
-		/* wait for read data ready event */
-		TEST_DBG(TEST_MODULE_NAME ":sender wait for rx data for "
-					  "chan %s\n",
-			 test_ch->name);
-		read_avail = sdio_read_avail(test_ch->ch);
-		wait_event(test_ch->wait_q,
-			   atomic_read(&test_ch->rx_notify_count));
-		atomic_dec(&test_ch->rx_notify_count);
-
-		read_avail = sdio_read_avail(test_ch->ch);
-
-		if (read_avail != size) {
-			pr_info(TEST_MODULE_NAME
-				":read_avail size %d for chan %s not as "
-				"expected size %d.\n",
-				read_avail, test_ch->name, size);
-			goto exit_err;
-		}
-
-		memset(test_ch->buf, 0x00, size);
-
-		ret = sdio_read(test_ch->ch, test_ch->buf, size);
-		if (ret) {
-			pr_info(TEST_MODULE_NAME ":sender sdio_read for chan %s"
-						 " err=%d.\n",
-				test_ch->name, -ret);
-			goto exit_err;
-		}
-
-
-		if ((test_ch->buf[0] != packet_count) && (size != 1)) {
-			pr_info(TEST_MODULE_NAME ":sender sdio_read WRONG DATA"
-						 " for chan %s, size=%d\n",
-				test_ch->name, size);
-			goto exit_err;
-		}
-
-		test_ch->tx_bytes += size;
-		test_ch->rx_bytes += size;
-		packet_count++;
-
-		TEST_DBG(TEST_MODULE_NAME
-			 ":sender total rx bytes = 0x%x , packet#=%d, size=%d"
-			 " for chan %s\n",
-			 test_ch->rx_bytes, packet_count, size, test_ch->name);
-		TEST_DBG(TEST_MODULE_NAME
-			 ":sender total tx bytes = 0x%x , packet#=%d, size=%d"
-			 " for chan %s\n",
-			 test_ch->tx_bytes, packet_count, size, test_ch->name);
-
-	} /* end of while */
-
-	pr_info(TEST_MODULE_NAME
-		 ":SENDER TEST END: total rx bytes = 0x%x, "
-		 " total tx bytes = 0x%x for chan %s\n",
-		 test_ch->rx_bytes, test_ch->tx_bytes, test_ch->name);
-
-	pr_info(TEST_MODULE_NAME ": TEST PASS for chan %s.\n",
-		test_ch->name);
-	test_ch->test_completed = 1;
-	test_ch->test_result = TEST_PASSED;
-	check_test_completion();
-	return;
-
-exit_err:
-	pr_info(TEST_MODULE_NAME ": TEST FAIL for chan %s.\n",
-		test_ch->name);
-	test_ch->test_completed = 1;
-	test_ch->test_result = TEST_FAILED;
-	check_test_completion();
-	return;
-}
-
-/**
- * A2 Perf Test
- */
-static void a2_performance_test(struct test_channel *test_ch)
-{
-	int ret = 0 ;
-	u32 read_avail = 0;
-	u32 write_avail = 0;
-	int tx_packet_count = 0;
-	int rx_packet_count = 0;
-	int size = 0;
-	u16 *buf16 = (u16 *) test_ch->buf;
-	int i;
-	int total_bytes = 0;
-	int max_packets = 10000;
-	u32 packet_size = test_ch->buf_size;
-	int rand_size = 0;
-
-	u64 start_jiffy, end_jiffy, delta_jiffies;
-	unsigned int time_msec = 0;
-	u32 throughput = 0;
-
-	max_packets = test_ch->config_msg.num_packets;
-	packet_size = test_ch->packet_length;
-
-	for (i = 0; i < packet_size / 2; i++)
-		buf16[i] = (u16) (i & 0xFFFF);
-
-	pr_info(TEST_MODULE_NAME ": A2 PERFORMANCE TEST START for chan %s\n",
-		test_ch->name);
-
-	start_jiffy = get_jiffies_64(); /* read the current time */
-
-	while (tx_packet_count < max_packets) {
-
-		if (test_ctx->exit_flag) {
-			pr_info(TEST_MODULE_NAME ":Exit Test.\n");
-			return;
-		}
-
-		if (test_ch->random_packet_size) {
-			rand_size = get_random_int();
-			packet_size = (rand_size % test_ch->packet_length) + 1;
-			if (packet_size < A2_MIN_PACKET_SIZE)
-				packet_size = A2_MIN_PACKET_SIZE;
-		}
-
-		/* wait for data ready event */
-		/* use a func to avoid compiler optimizations */
-		write_avail = sdio_write_avail(test_ch->ch);
-		read_avail = sdio_read_avail(test_ch->ch);
-		TEST_DBG(TEST_MODULE_NAME ":channel %s, write_avail=%d, "
-					 "read_avail=%d for chan %s\n",
-			test_ch->name, write_avail, read_avail,
-			test_ch->name);
-		if ((write_avail == 0) && (read_avail == 0)) {
-			wait_event(test_ch->wait_q,
-				   atomic_read(&test_ch->any_notify_count));
-			atomic_set(&test_ch->any_notify_count, 0);
-		}
-
-		write_avail = sdio_write_avail(test_ch->ch);
-		TEST_DBG(TEST_MODULE_NAME ":channel %s, write_avail=%d\n",
-			 test_ch->name, write_avail);
-		if (write_avail > 0) {
-			size = min(packet_size, write_avail) ;
-			TEST_DBG(TEST_MODULE_NAME ":tx size = %d for chan %s\n",
-				 size, test_ch->name);
-			test_ch->buf[0] = tx_packet_count;
-			test_ch->buf[(size/4)-1] = tx_packet_count;
-
-			ret = sdio_write(test_ch->ch, test_ch->buf, size);
-			if (ret) {
-				pr_info(TEST_MODULE_NAME ":sdio_write err=%d"
-							 " for chan %s\n",
-					-ret, test_ch->name);
-				goto exit_err;
-			}
-			tx_packet_count++;
-			test_ch->tx_bytes += size;
-		}
-
-		read_avail = sdio_read_avail(test_ch->ch);
-		TEST_DBG(TEST_MODULE_NAME ":channel %s, read_avail=%d\n",
-			 test_ch->name, read_avail);
-		if (read_avail > 0) {
-			size = min(packet_size, read_avail);
-			pr_debug(TEST_MODULE_NAME ":rx size = %d.\n", size);
-			ret = sdio_read(test_ch->ch, test_ch->buf, size);
-			if (ret) {
-				pr_info(TEST_MODULE_NAME ": sdio_read size %d "
-							 " err=%d"
-							 " for chan %s\n",
-					size, -ret, test_ch->name);
-				goto exit_err;
-			}
-			rx_packet_count++;
-			test_ch->rx_bytes += size;
-		}
-
-		TEST_DBG(TEST_MODULE_NAME
-			 ":total rx bytes = %d , rx_packet#=%d"
-			 " for chan %s\n",
-			 test_ch->rx_bytes, rx_packet_count, test_ch->name);
-		TEST_DBG(TEST_MODULE_NAME
-			 ":total tx bytes = %d , tx_packet#=%d"
-			 " for chan %s\n",
-			 test_ch->tx_bytes, tx_packet_count, test_ch->name);
-
-	} /* while (tx_packet_count < max_packets ) */
-
-	end_jiffy = get_jiffies_64(); /* read the current time */
-
-	delta_jiffies = end_jiffy - start_jiffy;
-	time_msec = jiffies_to_msecs(delta_jiffies);
-
-	pr_info(TEST_MODULE_NAME ":total rx bytes = 0x%x , rx_packet#=%d for"
-				 " chan %s.\n",
-		test_ch->rx_bytes, rx_packet_count, test_ch->name);
-	pr_info(TEST_MODULE_NAME ":total tx bytes = 0x%x , tx_packet#=%d"
-				 " for chan %s.\n",
-		test_ch->tx_bytes, tx_packet_count, test_ch->name);
-
-	total_bytes = (test_ch->tx_bytes + test_ch->rx_bytes);
-	pr_err(TEST_MODULE_NAME ":total bytes = %d, time msec = %d"
-				" for chan %s\n",
-		   total_bytes , (int) time_msec, test_ch->name);
-
-	if (!test_ch->random_packet_size) {
-		if (time_msec) {
-			throughput = (total_bytes / time_msec) * 8 / 1000;
-			pr_err(TEST_MODULE_NAME ": %s - Performance = "
-			       "%d Mbit/sec for chan %s\n",
-			       __func__, throughput, test_ch->name);
-		} else {
-			pr_err(TEST_MODULE_NAME ": %s - time_msec = 0 Couldn't "
-			       "calculate performence for chan %s\n",
-			   __func__, test_ch->name);
-		}
-
-	}
-
-#ifdef CONFIG_DEBUG_FS
-	switch (test_ch->ch_id) {
-	case SDIO_DUN:
-		test_ctx->debug.dun_throughput = throughput;
-		break;
-	case SDIO_RMNT:
-		test_ctx->debug.rmnt_throughput = throughput;
-		break;
-	default:
-		pr_err(TEST_MODULE_NAME "No debugfs for this channel "
-					"throughput");
-	}
-#endif
-
-	pr_err(TEST_MODULE_NAME ": A2 PERFORMANCE TEST END for chan %s.\n",
-	       test_ch->name);
-
-	pr_err(TEST_MODULE_NAME ": TEST PASS for chan %s\n", test_ch->name);
-	test_ch->test_completed = 1;
-	test_ch->test_result = TEST_PASSED;
-	check_test_completion();
-	return;
-
-exit_err:
-	pr_err(TEST_MODULE_NAME ": TEST FAIL for chan %s\n", test_ch->name);
-	test_ch->test_completed = 1;
-	test_ch->test_result = TEST_FAILED;
-	check_test_completion();
-	return;
-}
-
-/**
- * rx_cleanup
- * This function reads all the messages sent by the modem until
- * the read_avail is 0 after 1 second of sleep.
- * The function returns the number of packets that was received.
- */
-static void rx_cleanup(struct test_channel *test_ch, int *rx_packet_count)
-{
-	int read_avail = 0;
-	int ret = 0;
-	int counter = 0;
-
-	if (!test_ch || !test_ch->ch) {
-		pr_err(TEST_MODULE_NAME ":%s NULL channel\n",
-				__func__);
-		return;
-	}
-
-	read_avail = sdio_read_avail(test_ch->ch);
-	TEST_DBG(TEST_MODULE_NAME ":channel %s, read_avail=%d\n",
-		 test_ch->name, read_avail);
-
-	/* If no pending messages, wait to see if the modem sends data */
-	if (read_avail == 0) {
-		msleep(1000);
-		read_avail = sdio_read_avail(test_ch->ch);
-	}
-
-	while ((read_avail > 0) && (counter < 10)) {
-		TEST_DBG(TEST_MODULE_NAME ": read_avail=%d for ch %s\n",
-			 read_avail, test_ch->name);
-
-		ret = sdio_read(test_ch->ch, test_ch->buf, read_avail);
-		if (ret) {
-			pr_info(TEST_MODULE_NAME ": sdio_read size %d "
-						 " err=%d for chan %s\n",
-				read_avail, -ret, test_ch->name);
-			break;
-		}
-		(*rx_packet_count)++;
-		test_ch->rx_bytes += read_avail;
-		read_avail = sdio_read_avail(test_ch->ch);
-		if (read_avail == 0) {
-			msleep(1000);
-			counter++;
-			read_avail = sdio_read_avail(test_ch->ch);
-		}
-	}
-	pr_info(TEST_MODULE_NAME ": finished cleanup for ch %s, "
-				 "rx_packet_count=%d, total rx bytes=%d\n",
-			 test_ch->name, *rx_packet_count, test_ch->rx_bytes);
-}
-
-
-/**
- * A2 RTT Test
- * This function sends a packet and calculate the RTT time of
- * this packet.
- * The test also calculte Min, Max and Average RTT
- */
-static void a2_rtt_test(struct test_channel *test_ch)
-{
-	int ret = 0 ;
-	u32 read_avail = 0;
-	u32 write_avail = 0;
-	int tx_packet_count = 0;
-	int rx_packet_count = 0;
-	u16 *buf16 = NULL;
-	int i;
-	int max_packets = 0;
-	u32 packet_size = 0;
-	s64 start_time, end_time;
-	int delta_usec = 0;
-	int time_average = 0;
-	int min_delta_usec = 0xFFFF;
-	int max_delta_usec = 0;
-	int total_time = 0;
-	int expected_read_size = 0;
-	int delay_ms = 0;
-	int slow_rtt_counter = 0;
-	int read_avail_so_far = 0;
-
-	if (test_ch) {
-		/*
-		 * Cleanup the pending RX data (such as loopback of the
-		 * config msg)
-		 */
-		rx_cleanup(test_ch, &rx_packet_count);
-		rx_packet_count = 0;
-	} else {
-		return;
-	}
-
-	max_packets = test_ch->config_msg.num_packets;
-	packet_size = test_ch->packet_length;
-	buf16 = (u16 *) test_ch->buf;
-
-	for (i = 0; i < packet_size / 2; i++)
-		buf16[i] = (u16) (i & 0xFFFF);
-
-	pr_info(TEST_MODULE_NAME ": A2 RTT TEST START for chan %s\n",
-		test_ch->name);
-
-	switch (test_ch->ch_id) {
-	case SDIO_RMNT:
-		delay_ms = 100;
-		break;
-	case SDIO_CSVT:
-		delay_ms = 0;
-		break;
-	default:
-		pr_err(TEST_MODULE_NAME ": %s - ch_id invalid.\n",
-		       __func__);
-		return;
-	}
-
-	while (tx_packet_count < max_packets) {
-		if (test_ctx->exit_flag) {
-			pr_info(TEST_MODULE_NAME ":Exit Test.\n");
-			return;
-		}
-		start_time = 0;
-		end_time = 0;
-		read_avail_so_far = 0;
-
-		if (delay_ms)
-			msleep(delay_ms);
-
-		/* wait for data ready event */
-		write_avail = sdio_write_avail(test_ch->ch);
-		TEST_DBG(TEST_MODULE_NAME ":ch %s: write_avail=%d\n",
-			test_ch->name, write_avail);
-		if (write_avail == 0) {
-			wait_event(test_ch->wait_q,
-				   atomic_read(&test_ch->tx_notify_count));
-			atomic_dec(&test_ch->tx_notify_count);
-		}
-
-		write_avail = sdio_write_avail(test_ch->ch);
-		TEST_DBG(TEST_MODULE_NAME ":channel %s, write_avail=%d\n",
-			 test_ch->name, write_avail);
-		if (write_avail > 0) {
-			TEST_DBG(TEST_MODULE_NAME ":tx size = %d for chan %s\n",
-				 packet_size, test_ch->name);
-			test_ch->buf[0] = tx_packet_count;
-
-			start_time = ktime_to_us(ktime_get());
-			ret = sdio_write(test_ch->ch, test_ch->buf,
-					 packet_size);
-			if (ret) {
-				pr_err(TEST_MODULE_NAME ":sdio_write err=%d"
-							 " for chan %s\n",
-					-ret, test_ch->name);
-				goto exit_err;
-			}
-			tx_packet_count++;
-			test_ch->tx_bytes += packet_size;
-		} else {
-				pr_err(TEST_MODULE_NAME ": Invalid write_avail"
-							 " %d for chan %s\n",
-					write_avail, test_ch->name);
-				goto exit_err;
-		}
-
-		expected_read_size = packet_size + A2_HEADER_OVERHEAD;
-
-		while (read_avail_so_far < expected_read_size) {
-
-			read_avail = sdio_read_avail(test_ch->ch);
-
-			if (!read_avail) {
-				wait_event(test_ch->wait_q,
-					   atomic_read(&test_ch->
-						       rx_notify_count));
-
-				atomic_dec(&test_ch->rx_notify_count);
-				continue;
-			}
-
-			read_avail_so_far += read_avail;
-
-			if (read_avail_so_far > expected_read_size) {
-				pr_err(TEST_MODULE_NAME ": %s - Invalid "
-				       "read_avail(%d)  read_avail_so_far(%d) "
-				       "can't be larger than "
-				       "expected_read_size(%d).",
-				       __func__,
-				       read_avail,
-				       read_avail_so_far,
-				       expected_read_size);
-				goto exit_err;
-			}
-
-			/*
-			 * must read entire pending bytes, so later, we will
-			 * get a notification when more data arrives
-			 */
-			ret = sdio_read(test_ch->ch, test_ch->buf,
-					read_avail);
-
-			if (ret) {
-				pr_info(TEST_MODULE_NAME ": sdio_read size %d "
-					" err=%d for chan %s\n",
-					read_avail, -ret,
-					test_ch->name);
-				goto exit_err;
-			}
-		}
-
-		end_time = ktime_to_us(ktime_get());
-		rx_packet_count++;
-		test_ch->rx_bytes += expected_read_size;
-
-		delta_usec = (int)(end_time - start_time);
-		total_time += delta_usec;
-		if (delta_usec < min_delta_usec)
-				min_delta_usec = delta_usec;
-		if (delta_usec > max_delta_usec)
-				max_delta_usec = delta_usec;
-
-		/* checking the RTT per channel criteria */
-		if (delta_usec > MAX_AVG_RTT_TIME_USEC) {
-			pr_err(TEST_MODULE_NAME ": %s - "
-			       "msg # %d - rtt time (%d usec) is "
-			       "longer than %d usec\n",
-			       __func__,
-			       tx_packet_count,
-			       delta_usec,
-			       MAX_AVG_RTT_TIME_USEC);
-			slow_rtt_counter++;
-		}
-
-		TEST_DBG(TEST_MODULE_NAME
-			 ":RTT time=%d for packet #%d for chan %s\n",
-			 delta_usec, tx_packet_count, test_ch->name);
-	} /* while (tx_packet_count < max_packets ) */
-
-	pr_info(TEST_MODULE_NAME ": %s - tx_packet_count = %d\n",
-		__func__, tx_packet_count);
-
-	pr_info(TEST_MODULE_NAME ": %s - total rx bytes = 0x%x, "
-		"rx_packet# = %d for chan %s.\n",
-		__func__, test_ch->rx_bytes, rx_packet_count, test_ch->name);
-
-	pr_info(TEST_MODULE_NAME ": %s - total tx bytes = 0x%x, "
-		"tx_packet# = %d for chan %s.\n",
-		__func__, test_ch->tx_bytes, tx_packet_count, test_ch->name);
-
-	pr_info(TEST_MODULE_NAME ": %s - slow_rtt_counter = %d for "
-		"chan %s.\n",
-		__func__, slow_rtt_counter, test_ch->name);
-
-	if (tx_packet_count) {
-		time_average = total_time / tx_packet_count;
-		pr_info(TEST_MODULE_NAME ":Average RTT time = %d for chan %s\n",
-		   time_average, test_ch->name);
-	} else {
-		pr_err(TEST_MODULE_NAME ": %s - tx_packet_count=0. couldn't "
-		       "calculate average rtt time", __func__);
-	}
-
-	pr_info(TEST_MODULE_NAME ":MIN RTT time = %d for chan %s\n",
-		   min_delta_usec, test_ch->name);
-	pr_info(TEST_MODULE_NAME ":MAX RTT time = %d for chan %s\n",
-		   max_delta_usec, test_ch->name);
-
-	pr_info(TEST_MODULE_NAME ": A2 RTT TEST END for chan %s.\n",
-	       test_ch->name);
-
-	if (ret)
-		goto exit_err;
-
-	if (time_average == 0 || time_average > MAX_AVG_RTT_TIME_USEC) {
-		pr_err(TEST_MODULE_NAME ": %s - average_time = %d. Invalid "
-		       "value",
-		       __func__, time_average);
-		goto exit_err;
-
-	}
-
-	pr_info(TEST_MODULE_NAME ": TEST PASS for chan %s\n", test_ch->name);
-	test_ch->test_completed = 1;
-	test_ch->test_result = TEST_PASSED;
-	check_test_completion();
-	return;
-
-exit_err:
-	pr_err(TEST_MODULE_NAME ": TEST FAIL for chan %s\n", test_ch->name);
-	test_ch->test_completed = 1;
-	test_ch->test_result = TEST_FAILED;
-	check_test_completion();
-	return;
-}
-
-/**
- * Process Rx Data - Helper for A2 Validation Test
- * @test_ch(in/out) : Test channel that contains Rx data buffer to process.
- *
- * @rx_unprocessed_bytes(in) : Number of bytes to process in the buffer.
- *
- * @rx_process_packet_state(in/out) :
- * Current processing state (used to identify what to process
- * next in a partial packet)
- *
- * @rx_packet_size(in/out) :
- * Number of bytes remaining in the packet to be processed.
- *
- * @rx_packet_count(in/out) :
- * Number of packets processed.
- */
-static int process_rx_data(struct test_channel *test_ch,
-			   u32 rx_unprocessed_bytes,
-			   int *rx_process_packet_state,
-			   u16 *rx_packet_size,
-			   int *rx_packet_count)
-{
-	u8 *buf = (u8 *)test_ch->buf;
-	int eop = 0;
-	int i = 0;
-	int ret = 0;
-	u32 *ptr = 0;
-	u16 size = 0;
-
-	/* process rx data */
-	while (rx_unprocessed_bytes) {
-		TEST_DBG(TEST_MODULE_NAME ": unprocessed bytes : %u\n",
-			rx_unprocessed_bytes);
-
-		switch (*rx_process_packet_state) {
-		case RX_PROCESS_PACKET_INIT:
-			/* process the A2 header */
-			TEST_DBG(TEST_MODULE_NAME ": "
-				"RX_PROCESS_PACKET_INIT\n");
-			*rx_process_packet_state = RX_PROCESS_PACKET_INIT;
-			if (rx_unprocessed_bytes < 4)
-				break;
-
-			i += 4;
-			rx_unprocessed_bytes -= 4;
-
-		case RX_PROCESS_A2_HEADER:
-			/* process the rest of A2 header */
-			TEST_DBG(TEST_MODULE_NAME ": RX_PROCESS_A2_HEADER\n");
-			*rx_process_packet_state = RX_PROCESS_A2_HEADER;
-			if (rx_unprocessed_bytes < 4)
-				break;
-
-			ptr = (u32 *)&buf[i];
-			/*
-			 * upper 2 bytes of the last 4 bytes of A2 header
-			 * contains the size of the packet
-			 */
-			*rx_packet_size = *ptr >> 0x10;
-
-			i += 4;
-			rx_unprocessed_bytes -= 4;
-
-		case RX_PROCESS_PACKET_DATA:
-			/* process the2_2_ packet data */
-			TEST_DBG(TEST_MODULE_NAME ": RX_PROCESS_PACKET_DATA "
-				 "- packet size - %u\n", *rx_packet_size);
-			*rx_process_packet_state = RX_PROCESS_PACKET_DATA;
-
-			size = *rx_packet_size;
-			if (*rx_packet_size <= rx_unprocessed_bytes) {
-				eop = *rx_packet_size;
-				*rx_packet_size = 0;
-			} else {
-				eop = rx_unprocessed_bytes;
-				*rx_packet_size = *rx_packet_size -
-						  rx_unprocessed_bytes;
-			}
-
-			/* no more bytes available to process */
-			if (!eop)
-				break;
-			/*
-			 * end of packet is starting from
-			 * the current position
-			 */
-			eop = eop + i;
-			TEST_DBG(TEST_MODULE_NAME ": size - %u, "
-				 "packet size - %u eop - %d\n",
-				 size, *rx_packet_size, eop);
-
-			/* validate the data */
-			for (; i < eop; i++) {
-				if (buf[i] != (test_ch->rx_bytes % 256)) {
-					pr_err(TEST_MODULE_NAME ": "
-					       "Corrupt data. buf:%u, "
-					       "data:%u\n", buf[i],
-					       test_ch->rx_bytes % 256);
-					ret = -EINVAL;
-					goto err;
-				}
-				rx_unprocessed_bytes--;
-				test_ch->rx_bytes++;
-			}
-
-			/* have more data to be processed */
-			if (*rx_packet_size)
-				break;
-
-			/*
-			 * A2 sends data in 4 byte alignment,
-			 * skip the padding
-			 */
-			if (size % 4) {
-				i += 4 - (size % 4);
-				rx_unprocessed_bytes -= 4 - (size % 4);
-			}
-			*rx_packet_count = *rx_packet_count + 1;
-
-			/* re init the state to process new packet */
-			*rx_process_packet_state = RX_PROCESS_PACKET_INIT;
-			break;
-		default:
-			pr_err(TEST_MODULE_NAME ": Invalid case: %d\n",
-			       *rx_process_packet_state);
-			ret = -EINVAL;
-			goto err;
-		}
-		TEST_DBG(TEST_MODULE_NAME ": Continue processing "
-			"if more data is available\n");
-	}
-
-err:
-	return ret;
-}
-
-/**
- * A2 Validation Test
- * Send packets and validate the returned packets.
- * Transmit one packet at a time, while process multiple rx
- * packets in a single transaction.
- * A transaction is of size min(random number, write_avail).
- * A packet consists of a min of 1 byte to channel supported max.
- */
-static void a2_validation_test(struct test_channel *test_ch)
-{
-	int ret = 0 ;
-	u32 read_avail = 0;
-	u32 write_avail = 0;
-	int tx_packet_count = 0;
-	int rx_packet_count = 0;
-	int initial_rx_packet_count = 0;
-	u32 size = 0;
-	u8 *buf8 = (u8 *)test_ch->buf;
-	int i = 0;
-	int max_packets = test_ch->config_msg.num_packets;
-	u16 tx_packet_size = 0;
-	u16 rx_packet_size = 0;
-	u32 random_num = 0;
-	int rx_process_packet_state = RX_PROCESS_PACKET_INIT;
-
-	pr_info(TEST_MODULE_NAME ": A2 VALIDATION TEST START for chan %s\n",
-		test_ch->name);
-
-	/* Wait for the initial rx messages before starting the test. */
-	rx_cleanup(test_ch, &initial_rx_packet_count);
-
-	test_ch->tx_bytes = 0;
-	test_ch->rx_bytes = 0;
-
-	/* Continue till we have transmitted and received all packets */
-	while ((tx_packet_count < max_packets) ||
-	       (rx_packet_count < max_packets)) {
-
-		if (test_ctx->exit_flag) {
-			pr_info(TEST_MODULE_NAME ":Exit Test.\n");
-			return;
-		}
-
-		random_num = get_random_int();
-		size = (random_num % test_ch->packet_length) + 1;
-		TEST_DBG(TEST_MODULE_NAME ": Random tx packet size =%u", size);
-
-		/*
-		 * wait for data ready event
-		 * use a func to avoid compiler optimizations
-		 */
-		write_avail = sdio_write_avail(test_ch->ch);
-		read_avail = sdio_read_avail(test_ch->ch);
-		TEST_DBG(TEST_MODULE_NAME ": write_avail=%d, "
-			"read_avail=%d for chan %s\n",
-			write_avail, read_avail, test_ch->name);
-
-		if ((write_avail == 0) && (read_avail == 0)) {
-			wait_event(test_ch->wait_q,
-				   atomic_read(&test_ch->any_notify_count));
-			atomic_set(&test_ch->any_notify_count, 0);
-		}
-
-		/* Transmit data */
-		write_avail = sdio_write_avail(test_ch->ch);
-		if ((tx_packet_count < max_packets) && (write_avail > 0)) {
-			tx_packet_size = min(size, write_avail) ;
-			TEST_DBG(TEST_MODULE_NAME ": tx size = %u, "
-				"write_avail = %u tx_packet# = %d\n",
-				tx_packet_size, write_avail,
-				tx_packet_count);
-			memset(test_ch->buf, 0, test_ch->buf_size);
-			/* populate the buffer */
-			for (i = 0; i < tx_packet_size; i++) {
-				buf8[i] = test_ch->tx_bytes % 256;
-				test_ch->tx_bytes++;
-			}
-
-			ret = sdio_write(test_ch->ch, test_ch->buf,
-					  tx_packet_size);
-			if (ret) {
-				pr_err(TEST_MODULE_NAME ":sdio_write err=%d"
-					" for chan %s\n",
-					-ret, test_ch->name);
-				goto exit_err;
-			}
-			tx_packet_count++;
-		}
-
-		/* Receive data */
-		read_avail = sdio_read_avail(test_ch->ch);
-		if (read_avail > 0) {
-			TEST_DBG(TEST_MODULE_NAME ": rx size = %u, "
-				"rx_packet#=%d.\n",
-				read_avail, rx_packet_count);
-			memset(test_ch->buf, 0, test_ch->buf_size);
-
-			ret = sdio_read(test_ch->ch, test_ch->buf,
-					read_avail);
-			if (ret) {
-				pr_err(TEST_MODULE_NAME ": sdio_read "
-					"size %d err=%d for chan %s\n",
-					size, -ret, test_ch->name);
-				goto exit_err;
-			}
-
-			/* Process data */
-			ret = process_rx_data(test_ch, read_avail,
-					      &rx_process_packet_state,
-					      &rx_packet_size,
-					      &rx_packet_count);
-
-			if (ret != 0)
-				goto exit_err;
-		}
-		TEST_DBG(TEST_MODULE_NAME ": Continue loop ...\n");
-	}
-
-	if (test_ch->tx_bytes != test_ch->rx_bytes) {
-		pr_err(TEST_MODULE_NAME ": Total number of bytes "
-			"transmitted (%u) does not match the total "
-			"number of bytes received (%u).", test_ch->tx_bytes,
-			test_ch->rx_bytes);
-		goto exit_err;
-	}
-
-	pr_info(TEST_MODULE_NAME ": A2 VALIDATION TEST END for chan %s.\n",
-		test_ch->name);
-
-	pr_info(TEST_MODULE_NAME ": TEST PASS for chan %s\n", test_ch->name);
-	test_ch->test_completed = 1;
-	test_ch->test_result = TEST_PASSED;
-	check_test_completion();
-	return;
-
-exit_err:
-	pr_info(TEST_MODULE_NAME ": TEST FAIL for chan %s\n", test_ch->name);
-	test_ch->test_completed = 1;
-	test_ch->test_result = TEST_FAILED;
-	check_test_completion();
-	return;
-}
-
-/**
- * sender No loopback Test
- */
-static void sender_no_loopback_test(struct test_channel *test_ch)
-{
-	int ret = 0 ;
-	u32 write_avail = 0;
-	int packet_count = 0;
-	int size = 512;
-	u16 *buf16 = (u16 *) test_ch->buf;
-	int i;
-	int max_packet_count = 10000;
-	unsigned int random_num = 0;
-
-	max_packet_count = test_ch->config_msg.num_packets;
-
-	for (i = 0 ; i < size / 2 ; i++)
-		buf16[i] = (u16) (i & 0xFFFF);
-
-	pr_info(TEST_MODULE_NAME
-		 ":SENDER NO LP TEST START for chan %s\n", test_ch->name);
-
-	while (packet_count < max_packet_count) {
-
-		if (test_ctx->exit_flag) {
-			pr_info(TEST_MODULE_NAME ":Exit Test.\n");
-			return;
-		}
-
-		random_num = get_random_int();
-		size = (random_num % test_ch->packet_length) + 1;
-
-		TEST_DBG(TEST_MODULE_NAME ":SENDER WAIT FOR EVENT "
-					  "for chan %s\n",
-			test_ch->name);
-
-		/* wait for data ready event */
-		write_avail = sdio_write_avail(test_ch->ch);
-		TEST_DBG(TEST_MODULE_NAME ":write_avail=%d\n", write_avail);
-		if (write_avail < size) {
-			wait_event(test_ch->wait_q,
-				   atomic_read(&test_ch->tx_notify_count));
-			atomic_dec(&test_ch->tx_notify_count);
-		}
-
-		write_avail = sdio_write_avail(test_ch->ch);
-		TEST_DBG(TEST_MODULE_NAME ":write_avail=%d\n", write_avail);
-		if (write_avail < size) {
-			pr_info(TEST_MODULE_NAME ":not enough write avail.\n");
-			continue;
-		}
-
-		test_ch->buf[0] = packet_count;
-
-		ret = sdio_write(test_ch->ch, test_ch->buf, size);
-		if (ret) {
-			pr_info(TEST_MODULE_NAME ":sender sdio_write err=%d.\n",
-				-ret);
-			goto exit_err;
-		}
-
-		test_ch->tx_bytes += size;
-		packet_count++;
-
-		TEST_DBG(TEST_MODULE_NAME
-			 ":sender total tx bytes = 0x%x , packet#=%d, size=%d"
-			 " for chan %s\n",
-			 test_ch->tx_bytes, packet_count, size, test_ch->name);
-
-	} /* end of while */
-
-	pr_info(TEST_MODULE_NAME
-		 ":SENDER TEST END: total tx bytes = 0x%x, "
-		 " for chan %s\n",
-		 test_ch->tx_bytes, test_ch->name);
-
-	test_ch->modem_result_per_chan = wait_for_result_msg(test_ch);
-
-	if (test_ch->modem_result_per_chan) {
-		pr_info(TEST_MODULE_NAME ": TEST PASS for chan %s.\n",
-			test_ch->name);
-		test_ch->test_result = TEST_PASSED;
-	} else {
-		pr_info(TEST_MODULE_NAME ": TEST FAILURE for chan %s.\n",
-			test_ch->name);
-		test_ch->test_result = TEST_FAILED;
-	}
-	test_ch->test_completed = 1;
-	check_test_completion();
-	return;
-
-exit_err:
-	pr_info(TEST_MODULE_NAME ": TEST FAIL for chan %s.\n",
-		test_ch->name);
-	test_ch->test_completed = 1;
-	test_ch->test_result = TEST_FAILED;
-	check_test_completion();
-	return;
-}
-
-
-/**
- * Modem reset Test
- * The test verifies that it finished sending all the packets
- * while there might be modem reset in the middle
- */
-static void modem_reset_test(struct test_channel *test_ch)
-{
-	int ret = 0 ;
-	u32 read_avail = 0;
-	u32 write_avail = 0;
-	int tx_packet_count = 0;
-	int rx_packet_count = 0;
-	int size = 0;
-	u16 *buf16 = (u16 *) test_ch->buf;
-	int i;
-	int max_packets = 10000;
-	u32 packet_size = test_ch->buf_size;
-	int is_err = 0;
-
-	max_packets = test_ch->config_msg.num_packets;
-	packet_size = test_ch->packet_length;
-
-	for (i = 0; i < packet_size / 2; i++)
-		buf16[i] = (u16) (i & 0xFFFF);
-
-	pr_info(TEST_MODULE_NAME ": Modem Reset TEST START for chan %s\n",
-		test_ch->name);
-
-	while (tx_packet_count < max_packets) {
-
-		if (test_ctx->exit_flag) {
-			pr_info(TEST_MODULE_NAME ":Exit Test.\n");
-			return;
-		}
-
-		if (test_ch->card_removed) {
-			pr_info(TEST_MODULE_NAME ": card removal was detected "
-				"for chan %s, tx_total=0x%x\n",
-				test_ch->name, test_ch->tx_bytes);
-			wait_event(test_ch->wait_q,
-				   atomic_read(&test_ch->card_detected_event));
-			atomic_set(&test_ch->card_detected_event, 0);
-			pr_info(TEST_MODULE_NAME ": card_detected_event "
-					"for chan %s\n", test_ch->name);
-			if (test_ch->card_removed)
-				continue;
-			is_err = 0;
-			/* Need to wait for the modem to be ready */
-			msleep(5000);
-			pr_info(TEST_MODULE_NAME ": sending the config message "
-					"for chan %s\n", test_ch->name);
-			send_config_msg(test_ch);
-		}
-
-		/* wait for data ready event */
-		/* use a func to avoid compiler optimizations */
-		write_avail = sdio_write_avail(test_ch->ch);
-		read_avail = sdio_read_avail(test_ch->ch);
-		TEST_DBG(TEST_MODULE_NAME ":channel %s, write_avail=%d, "
-					 "read_avail=%d for chan %s\n",
-			test_ch->name, write_avail, read_avail,
-			test_ch->name);
-		if ((write_avail == 0) && (read_avail == 0)) {
-			wait_event(test_ch->wait_q,
-				   atomic_read(&test_ch->any_notify_count));
-			atomic_set(&test_ch->any_notify_count, 0);
-		}
-		if (atomic_read(&test_ch->card_detected_event)) {
-			atomic_set(&test_ch->card_detected_event, 0);
-			pr_info(TEST_MODULE_NAME ": card_detected_event "
-				"for chan %s, tx_total=0x%x\n",
-				test_ch->name,  test_ch->tx_bytes);
-			if (test_ch->card_removed)
-				continue;
-			/* Need to wait for the modem to be ready */
-			msleep(5000);
-			is_err = 0;
-			pr_info(TEST_MODULE_NAME ": sending the config message "
-					"for chan %s\n", test_ch->name);
-			send_config_msg(test_ch);
-		}
-
-		write_avail = sdio_write_avail(test_ch->ch);
-		TEST_DBG(TEST_MODULE_NAME ":channel %s, write_avail=%d\n",
-			 test_ch->name, write_avail);
-		if (write_avail > 0) {
-			size = min(packet_size, write_avail) ;
-			pr_debug(TEST_MODULE_NAME ":tx size = %d for chan %s\n",
-				 size, test_ch->name);
-			test_ch->buf[0] = tx_packet_count;
-			test_ch->buf[(size/4)-1] = tx_packet_count;
-
-			TEST_DBG(TEST_MODULE_NAME ":channel %s, sdio_write, "
-				"size=%d\n", test_ch->name, size);
-			if (is_err) {
-				msleep(100);
-				continue;
-			}
-			ret = sdio_write(test_ch->ch, test_ch->buf, size);
-			if (ret) {
-				pr_info(TEST_MODULE_NAME ":sdio_write err=%d"
-							 " for chan %s\n",
-					-ret, test_ch->name);
-				is_err = 1;
-				msleep(20);
-				continue;
-			}
-			tx_packet_count++;
-			test_ch->tx_bytes += size;
-			test_ch->config_msg.num_packets--;
-		}
-
-		read_avail = sdio_read_avail(test_ch->ch);
-		TEST_DBG(TEST_MODULE_NAME ":channel %s, read_avail=%d\n",
-			 test_ch->name, read_avail);
-		if (read_avail > 0) {
-			size = min(packet_size, read_avail);
-			pr_debug(TEST_MODULE_NAME ":rx size = %d.\n", size);
-			TEST_DBG(TEST_MODULE_NAME ":channel %s, sdio_read, "
-				"size=%d\n", test_ch->name, size);
-			if (is_err) {
-				msleep(100);
-				continue;
-			}
-			ret = sdio_read(test_ch->ch, test_ch->buf, size);
-			if (ret) {
-				pr_info(TEST_MODULE_NAME ": sdio_read size %d "
-							 " err=%d"
-							 " for chan %s\n",
-					size, -ret, test_ch->name);
-				is_err = 1;
-				msleep(20);
-				continue;
-			}
-			rx_packet_count++;
-			test_ch->rx_bytes += size;
-		}
-
-		TEST_DBG(TEST_MODULE_NAME
-			 ":total rx bytes = %d , rx_packet#=%d"
-			 " for chan %s\n",
-			 test_ch->rx_bytes, rx_packet_count, test_ch->name);
-		TEST_DBG(TEST_MODULE_NAME
-			 ":total tx bytes = %d , tx_packet#=%d"
-			 " for chan %s\n",
-			 test_ch->tx_bytes, tx_packet_count, test_ch->name);
-
-		udelay(500);
-
-	} /* while (tx_packet_count < max_packets ) */
-
-	pr_info(TEST_MODULE_NAME ":total rx bytes = 0x%x , rx_packet#=%d for"
-				 " chan %s.\n",
-		test_ch->rx_bytes, rx_packet_count, test_ch->name);
-	pr_info(TEST_MODULE_NAME ":total tx bytes = 0x%x , tx_packet#=%d"
-				 " for chan %s.\n",
-		test_ch->tx_bytes, tx_packet_count, test_ch->name);
-
-	pr_err(TEST_MODULE_NAME ": Modem Reset TEST END for chan %s.\n",
-	       test_ch->name);
-
-	pr_err(TEST_MODULE_NAME ": TEST PASS for chan %s\n", test_ch->name);
-	test_ch->test_completed = 1;
-	test_ch->test_result = TEST_PASSED;
-	check_test_completion();
-	return;
-}
-
-/**
- * Worker thread to handle the tests types
- */
-static void worker(struct work_struct *work)
-{
-	struct test_channel *test_ch = NULL;
-	struct test_work *test_work = container_of(work,
-						 struct	test_work,
-						 work);
-	int test_type = 0;
-
-	test_ch = test_work->test_ch;
-
-	if (test_ch == NULL) {
-		pr_err(TEST_MODULE_NAME ":NULL test_ch\n");
-		return;
-	}
-
-	test_type = test_ch->test_type;
-
-	switch (test_type) {
-	case SDIO_TEST_LOOPBACK_HOST:
-		loopback_test(test_ch);
-		break;
-	case SDIO_TEST_LOOPBACK_CLIENT:
-		sender_test(test_ch);
-		break;
-	case SDIO_TEST_PERF:
-		a2_performance_test(test_ch);
-		break;
-	case SDIO_TEST_LPM_CLIENT_WAKER:
-		lpm_test(test_ch);
-		break;
-	case SDIO_TEST_LPM_HOST_WAKER:
-		lpm_test_host_waker(test_ch);
-		break;
-	case SDIO_TEST_HOST_SENDER_NO_LP:
-		sender_no_loopback_test(test_ch);
-		break;
-	case SDIO_TEST_LPM_RANDOM:
-		lpm_continuous_rand_test(test_ch);
-		break;
-	case SDIO_TEST_RTT:
-		a2_rtt_test(test_ch);
-		break;
-	case SDIO_TEST_CLOSE_CHANNEL:
-		if (test_ch->ch_id != SDIO_SMEM)
-			open_close_test(test_ch);
-		break;
-	case SDIO_TEST_MODEM_RESET:
-		modem_reset_test(test_ch);
-		break;
-	case SDIO_TEST_A2_VALIDATION:
-		a2_validation_test(test_ch);
-		break;
-	default:
-		pr_err(TEST_MODULE_NAME ":Bad Test type = %d.\n",
-			(int) test_type);
-	}
-}
-
-
-/**
- * Notification Callback
- *
- * Notify the worker
- *
- */
-static void notify(void *priv, unsigned channel_event)
-{
-	struct test_channel *test_ch = (struct test_channel *) priv;
-
-	pr_debug(TEST_MODULE_NAME ": %s - notify event=%d.\n",
-		 __func__, channel_event);
-
-	if (test_ch->ch == NULL) {
-		pr_info(TEST_MODULE_NAME ": %s - notify before ch ready.\n",
-			__func__);
-		return;
-	}
-
-	switch (channel_event) {
-	case SDIO_EVENT_DATA_READ_AVAIL:
-		atomic_inc(&test_ch->rx_notify_count);
-		atomic_set(&test_ch->any_notify_count, 1);
-		TEST_DBG(TEST_MODULE_NAME ": %s - SDIO_EVENT_DATA_READ_AVAIL, "
-			 "any_notify_count=%d, rx_notify_count=%d\n",
-			 __func__,
-			 atomic_read(&test_ch->any_notify_count),
-			 atomic_read(&test_ch->rx_notify_count));
-		/*
-		 * when there is pending data on a channel we would like to
-		 * turn on the bit mask that implies that there is pending
-		 * data for that channel on that deivce
-		 */
-		if (test_ch->test_device != NULL &&
-		    test_ch->test_type == SDIO_TEST_LPM_RANDOM) {
-			spin_lock_irqsave(&test_ch->test_device->lpm_array_lock,
-					  test_ch->test_device->
-						  lpm_array_lock_flags);
-			test_ch->test_device->read_avail_mask |=
-				test_ch->channel_mask_id;
-			test_ch->notify_counter_per_chan++;
-
-			lpm_test_update_entry(test_ch, LPM_NOTIFY, "NOTIFY", 0);
-			spin_unlock_irqrestore(&test_ch->test_device->
-					       lpm_array_lock,
-					       test_ch->test_device->
-						  lpm_array_lock_flags);
-		}
-		break;
-
-	case SDIO_EVENT_DATA_WRITE_AVAIL:
-		atomic_inc(&test_ch->tx_notify_count);
-		atomic_set(&test_ch->any_notify_count, 1);
-		TEST_DBG(TEST_MODULE_NAME ": %s - SDIO_EVENT_DATA_WRITE_AVAIL, "
-			 "any_notify_count=%d, tx_notify_count=%d\n",
-			 __func__,
-			 atomic_read(&test_ch->any_notify_count),
-			 atomic_read(&test_ch->tx_notify_count));
-		break;
-
-	default:
-		BUG();
-	}
-	wake_up(&test_ch->wait_q);
-
-}
-
-#ifdef CONFIG_MSM_SDIO_SMEM
-static int sdio_smem_test_cb(int event)
-{
-	struct test_channel *tch = test_ctx->test_ch_arr[SDIO_SMEM];
-	int i;
-	int *smem_buf = (int *)test_ctx->smem_buf;
-	uint32_t val = 0;
-	int ret = 0;
-
-	pr_debug(TEST_MODULE_NAME ":%s: Received event %d\n", __func__, event);
-
-	if (!tch) {
-		pr_err(TEST_MODULE_NAME ": %s NULL tch\n", __func__);
-		return -EINVAL;
-	}
-
-	switch (event) {
-	case SDIO_SMEM_EVENT_READ_DONE:
-		tch->rx_bytes += SMEM_MAX_XFER_SIZE;
-		for (i = 0; i < SMEM_MAX_XFER_SIZE;) {
-			val = (int)*smem_buf;
-			if ((val != test_ctx->smem_counter) && tch->is_used) {
-				pr_err(TEST_MODULE_NAME ":%s: Invalid value %d "
-				"expected %d in smem arr",
-				__func__, val, test_ctx->smem_counter);
-				pr_err(TEST_MODULE_NAME ":SMEM test FAILED\n");
-				tch->test_completed = 1;
-				tch->test_result = TEST_FAILED;
-				check_test_completion();
-				ret = -EINVAL;
-				goto exit;
-			}
-			i += 4;
-			smem_buf++;
-			test_ctx->smem_counter++;
-		}
-		if (tch->rx_bytes >= 40000000) {
-			if ((!tch->test_completed) && tch->is_used) {
-				pr_info(TEST_MODULE_NAME ":SMEM test PASSED\n");
-				tch->test_completed = 1;
-				tch->test_result = TEST_PASSED;
-				check_test_completion();
-			}
-		}
-		break;
-	case SDIO_SMEM_EVENT_READ_ERR:
-		if (tch->is_used) {
-			pr_err(TEST_MODULE_NAME ":Read overflow, "
-						"SMEM test FAILED\n");
-			tch->test_completed = 1;
-			tch->test_result = TEST_FAILED;
-			ret = -EIO;
-		}
-		break;
-	default:
-		if (tch->is_used) {
-			pr_err(TEST_MODULE_NAME ":Unhandled event %d\n", event);
-			ret = -EINVAL;
-		}
-		break;
-	}
-exit:
-	return ret;
-}
-
-static int sdio_smem_open(struct sdio_smem_client *sdio_smem)
-{
-	int ret = 0;
-
-	if (!sdio_smem) {
-		pr_info(TEST_MODULE_NAME "%s: NULL sdio_smem_client\n",
-			__func__);
-		return -EINVAL;
-	}
-
-	if (test_ctx->test_ch_arr[SDIO_SMEM]->ch_ready) {
-		pr_info(TEST_MODULE_NAME "%s: SDIO_SMEM channel is already opened\n",
-			__func__);
-		return 0;
-	}
-
-	test_ctx->test_ch_arr[SDIO_SMEM]->ch_ready = 1;
-	sdio_smem->buf = test_ctx->smem_buf;
-	sdio_smem->size = SMEM_MAX_XFER_SIZE;
-	sdio_smem->cb_func = sdio_smem_test_cb;
-	ret = sdio_smem_register_client();
-	if (ret)
-		pr_info(TEST_MODULE_NAME "%s: Error (%d) registering sdio_smem "
-					 "test client\n",
-			__func__, ret);
-
-	return ret;
-}
-
-static int sdio_smem_test_probe(struct platform_device *pdev)
-{
-	test_ctx->sdio_smem = container_of(pdev, struct sdio_smem_client,
-					   plat_dev);
-
-	return sdio_smem_open(test_ctx->sdio_smem);
-}
-
-static struct platform_driver sdio_smem_client_drv = {
-	.probe		= sdio_smem_test_probe,
-	.driver		= {
-		.name	= "SDIO_SMEM_CLIENT",
-		.owner	= THIS_MODULE,
-	},
-};
-#endif
-
-static void sdio_test_lpm_timeout_handler(unsigned long data)
-{
-	struct test_channel *tch = (struct test_channel *)data;
-
-	pr_info(TEST_MODULE_NAME ": %s - LPM TEST TIMEOUT Expired after "
-			    "%d ms\n", __func__, tch->timeout_ms);
-	tch->test_completed = 1;
-	pr_info(TEST_MODULE_NAME ": %s - tch->test_result = TEST_FAILED\n",
-		__func__);
-	tch->test_completed = 1;
-	tch->test_result = TEST_FAILED;
-	check_test_completion();
-	return;
-}
-
-static void sdio_test_lpm_timer_handler(unsigned long data)
-{
-	struct test_channel *tch = (struct test_channel *)data;
-
-	pr_info(TEST_MODULE_NAME ": %s - LPM TEST Timer Expired after "
-			    "%d ms\n", __func__, tch->timer_interval_ms);
-
-	if (!tch) {
-		pr_err(TEST_MODULE_NAME ": %s - LPM TEST FAILED. "
-		       "tch is NULL\n", __func__);
-		return;
-	}
-
-	if (!tch->ch) {
-		pr_err(TEST_MODULE_NAME ": %s - LPM TEST FAILED. tch->ch "
-		       "is NULL\n", __func__);
-		tch->test_result = TEST_FAILED;
-		return;
-	}
-
-	/* Verfiy that we voted for sleep */
-	if (tch->is_ok_to_sleep) {
-		tch->test_result = TEST_PASSED;
-		pr_info(TEST_MODULE_NAME ": %s - 8K voted for sleep\n",
-			__func__);
-	} else {
-		tch->test_result = TEST_FAILED;
-		pr_info(TEST_MODULE_NAME ": %s - 8K voted against sleep\n",
-			__func__);
-
-	}
-
-	sdio_al_unregister_lpm_cb(tch->sdio_al_device);
-
-	if (tch->test_type == SDIO_TEST_LPM_HOST_WAKER) {
-		atomic_set(&tch->wakeup_client, 1);
-		wake_up(&tch->wait_q);
-	}
-}
-
-int sdio_test_wakeup_callback(void *device_handle, int is_vote_for_sleep)
-{
-	int i = 0;
-
-	TEST_DBG(TEST_MODULE_NAME ": %s is_vote_for_sleep=%d!!!",
-		__func__, is_vote_for_sleep);
-
-	for (i = 0; i < SDIO_MAX_CHANNELS; i++) {
-		struct test_channel *tch = test_ctx->test_ch_arr[i];
-
-		if ((!tch) || (!tch->is_used) || (!tch->ch_ready))
-			continue;
-		if (tch->sdio_al_device == device_handle) {
-			tch->is_ok_to_sleep = is_vote_for_sleep;
-
-			if (tch->test_type == SDIO_TEST_LPM_RANDOM) {
-				spin_lock_irqsave(&tch->test_device->
-						  lpm_array_lock,
-						  tch->test_device->
-						  lpm_array_lock_flags);
-				if (is_vote_for_sleep == 1)
-					lpm_test_update_entry(tch,
-							      LPM_SLEEP,
-							      "SLEEP ", 0);
-				else
-					lpm_test_update_entry(tch,
-							      LPM_WAKEUP,
-							      "WAKEUP", 0);
-
-				spin_unlock_irqrestore(&tch->test_device->
-						       lpm_array_lock,
-						       tch->test_device->
-						       lpm_array_lock_flags);
-				break;
-			}
-		}
-	}
-
-	return 0;
-}
-
-static int sdio_test_find_dev(struct test_channel *tch)
-{
-	int j;
-	int null_index = -1;
-
-	for (j = 0 ; j < MAX_NUM_OF_SDIO_DEVICES; ++j) {
-
-		struct sdio_test_device *test_dev =
-		&test_ctx->test_dev_arr[j];
-
-		if (test_dev->sdio_al_device == NULL) {
-			if (null_index == -1)
-				null_index = j;
-			continue;
-		}
-
-		if (test_dev->sdio_al_device ==
-		    tch->ch->sdio_al_dev) {
-			test_dev->open_channels_counter_to_recv++;
-			test_dev->open_channels_counter_to_send++;
-			tch->test_device = test_dev;
-			/* setting mask id for pending data for
-			   this channel */
-			tch->channel_mask_id = test_dev->next_mask_id;
-			test_dev->next_mask_id *= 2;
-			pr_info(TEST_MODULE_NAME ": %s - channel %s "
-				"got read_mask_id = 0x%x. device "
-				"next_mask_id=0x%x",
-				__func__, tch->name, tch->channel_mask_id,
-				test_dev->next_mask_id);
-			break;
-		}
-	}
-
-	/*
-	 * happens ones a new device is "discovered" while testing. i.e
-	 * if testing a few channels, a new deivce will be "discovered" once
-	 * the first channel of a device is being tested
-	 */
-	if (j == MAX_NUM_OF_SDIO_DEVICES) {
-
-		struct sdio_test_device *test_dev =
-			&test_ctx->
-			test_dev_arr[null_index];
-		test_dev->sdio_al_device =
-			tch->ch->sdio_al_dev;
-
-		test_ctx->number_of_active_devices++;
-		test_ctx->max_number_of_devices++;
-		test_dev->open_channels_counter_to_recv++;
-		test_dev->open_channels_counter_to_send++;
-		test_dev->next_avail_entry_in_array = 0;
-		tch->test_device = test_dev;
-		tch->test_device->array_size =
-			LPM_ARRAY_SIZE;
-		test_dev->modem_result_per_dev = 1;
-		tch->modem_result_per_chan = 0;
-		test_dev->next_avail_entry_in_array = 0;
-
-		spin_lock_init(&test_dev->
-			       lpm_array_lock);
-
-		if (tch->test_type == SDIO_TEST_LPM_RANDOM) {
-			pr_err(MODULE_NAME ": %s - "
-			       "Allocating Msg Array for "
-			       "Maximum open channels for device (%d) "
-			       "Channels. Array has %d entries",
-			       __func__,
-			       LPM_MAX_OPEN_CHAN_PER_DEV,
-			       test_dev->array_size);
-
-			test_dev->lpm_arr =
-				kzalloc(sizeof(
-				struct lpm_entry_type) *
-					tch->
-					test_device->array_size,
-				GFP_KERNEL);
-
-			if (!test_dev->lpm_arr) {
-				pr_err(MODULE_NAME ": %s - "
-					"lpm_arr is NULL",
-					__func__);
-				return -ENOMEM;
-			}
-		}
-
-		/*
-		 * in new device, initialize next_mask_id, and setting
-		 * mask_id to the channel
-		 */
-		test_dev->next_mask_id = 0x1;
-		tch->channel_mask_id = test_dev->next_mask_id;
-		test_dev->next_mask_id *= 2;
-		pr_info(TEST_MODULE_NAME ": %s - channel %s got "
-			"read_mask_id = 0x%x. device next_mask_id=0x%x",
-			__func__,
-			tch->name,
-			tch->channel_mask_id,
-			test_dev->next_mask_id);
-	}
-
-	return 0;
-}
-
-static void check_test_result(void)
-{
-	int result = 1;
-	int i = 0;
-
-	test_ctx->max_number_of_devices = 0;
-
-	pr_info(TEST_MODULE_NAME ": %s - Woke Up\n", __func__);
-
-	for (i = 0; i < SDIO_MAX_CHANNELS; i++) {
-		struct test_channel *tch = test_ctx->test_ch_arr[i];
-
-		if ((!tch) || (!tch->is_used) || (!tch->ch_ready))
-			continue;
-
-		if (tch->test_type == SDIO_TEST_LPM_RANDOM)
-			result &= tch->test_device->final_result_per_dev;
-		else
-			if (tch->test_result == TEST_FAILED) {
-				pr_info(TEST_MODULE_NAME ": %s - "
-					"Test FAILED\n", __func__);
-				test_ctx->test_result = TEST_FAILED;
-				pr_err(TEST_MODULE_NAME ": %s - "
-				       "test_result %d",
-				       __func__, test_ctx->test_result);
-				return;
-			}
-	}
-
-	if (result == 0) {
-		pr_info(TEST_MODULE_NAME ": %s - Test FAILED\n", __func__);
-		test_ctx->test_result = TEST_FAILED;
-		pr_err(TEST_MODULE_NAME ": %s - "
-		       "test_result %d",
-		       __func__, test_ctx->test_result);
-		return;
-	}
-
-	pr_info(TEST_MODULE_NAME ": %s - Test PASSED", __func__);
-	test_ctx->test_result = TEST_PASSED;
-	pr_err(TEST_MODULE_NAME ": %s - "
-	       "test_result %d",
-	       __func__, test_ctx->test_result);
-	return;
-}
-
-/**
- * Test Main
- */
-static int test_start(void)
-{
-	int ret = -ENOMEM;
-	int i;
-
-	pr_debug(TEST_MODULE_NAME ":Starting Test ....\n");
-
-	test_ctx->test_completed = 0;
-	test_ctx->test_result = TEST_NO_RESULT;
-	test_ctx->debug.dun_throughput = 0;
-	test_ctx->debug.rmnt_throughput = 0;
-	test_ctx->number_of_active_devices = 0;
-
-	pr_err(TEST_MODULE_NAME ": %s - test_result %d",
-	       __func__, test_ctx->test_result);
-
-	memset(test_ctx->test_dev_arr, 0,
-		sizeof(struct sdio_test_device)*MAX_NUM_OF_SDIO_DEVICES);
-
-	/* Open The Channels */
-	for (i = 0; i < SDIO_MAX_CHANNELS; i++) {
-		struct test_channel *tch = test_ctx->test_ch_arr[i];
-
-		if ((!tch) || (!tch->is_used))
-			continue;
-
-		tch->rx_bytes = 0;
-		tch->tx_bytes = 0;
-
-		atomic_set(&tch->tx_notify_count, 0);
-		atomic_set(&tch->rx_notify_count, 0);
-		atomic_set(&tch->any_notify_count, 0);
-		atomic_set(&tch->wakeup_client, 0);
-
-		/* in case there are values left from previous tests */
-		tch->notify_counter_per_chan = 0;
-		tch->next_index_in_sent_msg_per_chan = 0;
-
-		memset(tch->buf, 0x00, tch->buf_size);
-		tch->test_result = TEST_NO_RESULT;
-
-		tch->test_completed = 0;
-
-		ret = open_sdio_ch(tch);
-		if (ret)
-			continue;
-
-		if (tch->ch_id != SDIO_SMEM) {
-			ret = sdio_test_find_dev(tch);
-
-			if (ret) {
-				pr_err(TEST_MODULE_NAME ": %s - "
-				       "sdio_test_find_dev() returned with "
-				       "error", __func__);
-				return -ENODEV;
-			}
-
-			tch->sdio_al_device = tch->ch->sdio_al_dev;
-		}
-
-		if ((tch->test_type == SDIO_TEST_LPM_HOST_WAKER) ||
-		    (tch->test_type == SDIO_TEST_LPM_CLIENT_WAKER) ||
-		    (tch->test_type == SDIO_TEST_LPM_RANDOM))
-			sdio_al_register_lpm_cb(tch->sdio_al_device,
-					 sdio_test_wakeup_callback);
-	}
-
-	/*
-	 * make some space between opening the channels and sending the
-	 * config messages
-	 */
-	msleep(100);
-
-	/*
-	 * try to delay send_config_msg of all channels to after the point
-	 * when we open them all
-	 */
-	for (i = 0; i < SDIO_MAX_CHANNELS; i++) {
-		struct test_channel *tch = test_ctx->test_ch_arr[i];
-
-		if ((!tch) || (!tch->is_used))
-			continue;
-
-		if ((tch->ch_ready) && (tch->ch_id != SDIO_SMEM))
-			send_config_msg(tch);
-
-		if ((tch->test_type == SDIO_TEST_LPM_HOST_WAKER) ||
-		    (tch->test_type == SDIO_TEST_LPM_CLIENT_WAKER) ||
-		    (tch->test_type == SDIO_TEST_LPM_RANDOM)) {
-			if (tch->timer_interval_ms > 0) {
-				pr_info(TEST_MODULE_NAME ": %s - init timer, "
-					"ms=%d\n",
-					__func__, tch->timer_interval_ms);
-				init_timer(&tch->timer);
-				tch->timer.data = (unsigned long)tch;
-				tch->timer.function =
-					sdio_test_lpm_timer_handler;
-				tch->timer.expires = jiffies +
-				    msecs_to_jiffies(tch->timer_interval_ms);
-				add_timer(&tch->timer);
-			}
-		}
-	}
-
-	pr_debug(TEST_MODULE_NAME ":queue_work..\n");
-	for (i = 0; i < SDIO_MAX_CHANNELS; i++) {
-		struct test_channel *tch = test_ctx->test_ch_arr[i];
-
-		if ((!tch) || (!tch->is_used) || (!tch->ch_ready))
-			continue;
-
-		if (tch->ch_id == SDIO_SMEM) {
-#ifdef CONFIG_MSM_SDIO_SMEM
-			if (tch->test_type == SDIO_TEST_CLOSE_CHANNEL)
-				open_close_smem_test(tch);
-#endif
-		} else {
-			queue_work(tch->workqueue, &tch->test_work.work);
-		}
-
-	}
-
-	pr_info(TEST_MODULE_NAME ": %s - Waiting for the test completion\n",
-		__func__);
-
-	wait_event(test_ctx->wait_q, test_ctx->test_completed);
-	check_test_result();
-
-	/*
-	 * Close the channels and zero the is_used flag so that if the modem
-	 * will be reset after the test completion we won't re-open
-	 * the channels
-	 */
-	for (i = 0; i < SDIO_MAX_CHANNELS; i++) {
-		struct test_channel *tch = test_ctx->test_ch_arr[i];
-
-		if ((!tch) || (!tch->is_used))
-			continue;
-		if (!tch->ch_ready) {
-			tch->is_used = 0;
-			continue;
-		}
-
-		close_sdio_ch(tch);
-		tch->is_used = 0;
-	}
-
-	if (test_ctx->test_result == TEST_PASSED)
-		return 0;
-	else
-		return -EINVAL;
-}
-
-static int set_params_loopback_9k(struct test_channel *tch)
-{
-	if (!tch) {
-		pr_err(TEST_MODULE_NAME ":NULL channel\n");
-		return -EINVAL;
-	}
-	tch->is_used = 1;
-	tch->test_type = SDIO_TEST_LOOPBACK_CLIENT;
-	tch->config_msg.signature = TEST_CONFIG_SIGNATURE;
-	tch->config_msg.test_case = SDIO_TEST_LOOPBACK_CLIENT;
-	tch->config_msg.num_packets = 10000;
-	tch->config_msg.num_iterations = 1;
-
-	tch->packet_length = 512;
-	if (tch->ch_id == SDIO_RPC)
-		tch->packet_length = 128;
-	tch->timer_interval_ms = 0;
-
-	return 0;
-}
-static int set_params_loopback_9k_close(struct test_channel *tch)
-{
-	if (!tch) {
-		pr_err(TEST_MODULE_NAME ":NULL channel\n");
-		return -EINVAL;
-	}
-	tch->is_used = 1;
-	tch->test_type = SDIO_TEST_CLOSE_CHANNEL;
-	tch->config_msg.signature = TEST_CONFIG_SIGNATURE;
-	tch->config_msg.test_case = SDIO_TEST_LOOPBACK_CLIENT;
-	tch->config_msg.num_packets = 5000;
-	tch->config_msg.num_iterations = 1;
-	tch->max_burst_size = 10;
-	switch (tch->ch_id) {
-	case SDIO_DUN:
-	case SDIO_RPC:
-		tch->packet_length = 128; /* max is 2K*/
-		break;
-	case SDIO_DIAG:
-	case SDIO_RMNT:
-	default:
-		tch->packet_length = 512; /* max is 4k */
-	}
-	tch->timer_interval_ms = 0;
-	return 0;
-}
-static int set_params_a2_perf(struct test_channel *tch)
-{
-	if (!tch) {
-		pr_err(TEST_MODULE_NAME ":NULL channel\n");
-		return -EINVAL;
-	}
-	tch->is_used = 1;
-	tch->test_type = SDIO_TEST_PERF;
-	tch->config_msg.signature = TEST_CONFIG_SIGNATURE;
-	tch->config_msg.test_case = SDIO_TEST_LOOPBACK_CLIENT;
-
-	switch (tch->ch_id) {
-	case SDIO_DIAG:
-		tch->packet_length = 512;
-		break;
-	case SDIO_DUN:
-		tch->packet_length = DUN_PACKET_SIZE;
-		break;
-	case SDIO_CSVT:
-		tch->packet_length = CSVT_PACKET_SIZE;
-		break;
-	default:
-		tch->packet_length = MAX_XFER_SIZE;
-		break;
-	}
-
-	pr_info(TEST_MODULE_NAME ": %s: packet_length=%d", __func__,
-			tch->packet_length);
-
-	tch->config_msg.num_packets = 10000;
-	tch->config_msg.num_iterations = 1;
-	tch->random_packet_size = 0;
-
-	tch->timer_interval_ms = 0;
-
-	return 0;
-}
-
-static int set_params_rtt(struct test_channel *tch)
-{
-	if (!tch) {
-		pr_err(TEST_MODULE_NAME ":NULL channel\n");
-		return -EINVAL;
-	}
-	tch->is_used = 1;
-	tch->test_type = SDIO_TEST_RTT;
-	tch->config_msg.signature = TEST_CONFIG_SIGNATURE;
-	tch->config_msg.test_case = SDIO_TEST_LOOPBACK_CLIENT;
-
-	switch (tch->ch_id) {
-	case SDIO_RMNT:
-		tch->packet_length = SDIO_RMNT_RTT_PACKET_SIZE;
-		break;
-	case SDIO_CSVT:
-		tch->packet_length = SDIO_CSVT_RTT_PACKET_SIZE;
-		break;
-	default:
-		pr_err(TEST_MODULE_NAME ": %s - ch_id invalid.\n", __func__);
-		return -EINVAL;
-	}
-
-	pr_info(TEST_MODULE_NAME ": %s: packet_length=%d", __func__,
-			tch->packet_length);
-
-	tch->config_msg.num_packets = 200;
-	tch->config_msg.num_iterations = 1;
-	tch->random_packet_size = 0;
-
-	tch->timer_interval_ms = 0;
-
-	return 0;
-}
-
-static int set_params_a2_small_pkts(struct test_channel *tch)
-{
-	if (!tch) {
-		pr_err(TEST_MODULE_NAME ":NULL channel\n");
-		return -EINVAL;
-	}
-	tch->is_used = 1;
-	tch->test_type = SDIO_TEST_PERF;
-	tch->config_msg.signature = TEST_CONFIG_SIGNATURE;
-	tch->config_msg.test_case = SDIO_TEST_LOOPBACK_CLIENT;
-	tch->packet_length = 128;
-
-	tch->config_msg.num_packets = 1000000;
-	tch->config_msg.num_iterations = 1;
-	tch->random_packet_size = 1;
-
-	tch->timer_interval_ms = 0;
-
-	return 0;
-}
-
-static int set_params_modem_reset(struct test_channel *tch)
-{
-	if (!tch) {
-		pr_err(TEST_MODULE_NAME ":NULL channel\n");
-		return -EINVAL;
-	}
-	tch->is_used = 1;
-	tch->test_type = SDIO_TEST_MODEM_RESET;
-	tch->config_msg.signature = TEST_CONFIG_SIGNATURE;
-	tch->config_msg.test_case = SDIO_TEST_LOOPBACK_CLIENT;
-	tch->packet_length = 512;
-	if (tch->ch_id == SDIO_RPC)
-		tch->packet_length = 128;
-	else if ((tch->ch_id == SDIO_RMNT) || (tch->ch_id == SDIO_DUN))
-		tch->packet_length = MAX_XFER_SIZE;
-
-	tch->config_msg.num_packets = 50000;
-	tch->config_msg.num_iterations = 1;
-
-	tch->timer_interval_ms = 0;
-
-	return 0;
-}
-
-static int set_params_a2_validation(struct test_channel *tch)
-{
-	if (!tch) {
-		pr_err(TEST_MODULE_NAME ":NULL channel\n");
-		return -EINVAL;
-	}
-	tch->is_used = 1;
-	tch->test_type = SDIO_TEST_A2_VALIDATION;
-	tch->config_msg.signature = TEST_CONFIG_SIGNATURE;
-	tch->config_msg.test_case = SDIO_TEST_LOOPBACK_CLIENT;
-
-	if (tch->ch_id == SDIO_RMNT)
-		tch->packet_length = RMNT_PACKET_SIZE;
-	else if (tch->ch_id == SDIO_DUN)
-		tch->packet_length = DUN_PACKET_SIZE;
-	else
-		tch->packet_length = MAX_XFER_SIZE;
-
-	tch->config_msg.num_packets = 10000;
-	tch->config_msg.num_iterations = 1;
-	tch->timer_interval_ms = 0;
-
-	return 0;
-}
-
-static int set_params_smem_test(struct test_channel *tch)
-{
-	if (!tch) {
-		pr_err(TEST_MODULE_NAME ":NULL channel\n");
-		return -EINVAL;
-	}
-	tch->is_used = 1;
-	tch->timer_interval_ms = 0;
-
-	return 0;
-}
-
-static int set_params_lpm_test(struct test_channel *tch,
-				enum sdio_test_case_type test,
-				int timer_interval_ms)
-{
-	static int first_time = 1;
-	if (!tch) {
-		pr_err(TEST_MODULE_NAME ": %s - NULL channel\n", __func__);
-		return -EINVAL;
-	}
-
-	tch->is_used = 1;
-	tch->test_type = test;
-	tch->config_msg.signature = TEST_CONFIG_SIGNATURE;
-	tch->config_msg.test_case = test;
-	tch->config_msg.num_packets = LPM_TEST_NUM_OF_PACKETS;
-	tch->config_msg.num_iterations = 1;
-	tch->timer_interval_ms = timer_interval_ms;
-	tch->timeout_ms = 10000;
-
-	tch->packet_length = 0;
-	if (test != SDIO_TEST_LPM_RANDOM) {
-		init_timer(&tch->timeout_timer);
-		tch->timeout_timer.data = (unsigned long)tch;
-		tch->timeout_timer.function = sdio_test_lpm_timeout_handler;
-		tch->timeout_timer.expires = jiffies +
-			msecs_to_jiffies(tch->timeout_ms);
-		add_timer(&tch->timeout_timer);
-		pr_info(TEST_MODULE_NAME ": %s - Initiated LPM TIMEOUT TIMER."
-			"set to %d ms\n",
-			__func__, tch->timeout_ms);
-	}
-
-	if (first_time) {
-		pr_info(TEST_MODULE_NAME ": %s - wake_lock_init() called\n",
-		__func__);
-		wake_lock_init(&test_ctx->wake_lock,
-			       WAKE_LOCK_SUSPEND, TEST_MODULE_NAME);
-		first_time = 0;
-	}
-
-	pr_info(TEST_MODULE_NAME ": %s - wake_lock() for the TEST is "
-		"called channel %s. to prevent real sleeping\n",
-		__func__, tch->name);
-	wake_lock(&test_ctx->wake_lock);
-
-	return 0;
-}
-
-static int set_params_8k_sender_no_lp(struct test_channel *tch)
-{
-	if (!tch) {
-		pr_err(TEST_MODULE_NAME ":NULL channel\n");
-		return -EINVAL;
-	}
-	tch->is_used = 1;
-	tch->test_type = SDIO_TEST_HOST_SENDER_NO_LP;
-	tch->config_msg.signature = TEST_CONFIG_SIGNATURE;
-	tch->config_msg.test_case = SDIO_TEST_HOST_SENDER_NO_LP;
-	tch->config_msg.num_packets = 1000;
-	tch->config_msg.num_iterations = 1;
-
-	tch->packet_length = 512;
-	if (tch->ch_id == SDIO_RPC)
-		tch->packet_length = 128;
-	tch->timer_interval_ms = 0;
-
-	return 0;
-}
-
-static void set_pseudo_random_seed(void)
-{
-	/* Set the seed accoring to the kernel command parameters if any or
-	   get a random value */
-	if (seed != 0) {
-		test_ctx->lpm_pseudo_random_seed = seed;
-	} else {
-		test_ctx->lpm_pseudo_random_seed =
-			(unsigned int)(get_jiffies_64() & 0xFFFF);
-		test_ctx->lpm_pseudo_random_seed =
-			pseudo_random_seed(&test_ctx->lpm_pseudo_random_seed);
-	}
-
-	pr_info(TEST_MODULE_NAME ":%s: seed is %u",
-		   __func__, test_ctx->lpm_pseudo_random_seed);
-}
-
-/*
-   for each channel
-   1. open channel
-   2. close channel
-*/
-static int close_channel_lpm_test(int channel_num)
-{
-	int ret = 0;
-	struct test_channel *tch = NULL;
-	tch = test_ctx->test_ch_arr[channel_num];
-
-	if (!tch) {
-		pr_info(TEST_MODULE_NAME ":%s ch#%d is NULL\n",
-			__func__, channel_num);
-		return 0;
-	}
-
-	ret = open_sdio_ch(tch);
-	if (ret) {
-		pr_err(TEST_MODULE_NAME":%s open channel %s"
-			" failed\n", __func__, tch->name);
-		return ret;
-	} else {
-		pr_info(TEST_MODULE_NAME":%s open channel %s"
-			" success\n", __func__, tch->name);
-	}
-	ret = close_sdio_ch(tch);
-	if (ret) {
-		pr_err(TEST_MODULE_NAME":%s close channel %s"
-				" failed\n", __func__, tch->name);
-		return ret;
-	} else {
-		pr_info(TEST_MODULE_NAME":%s close channel %s"
-				" success\n", __func__, tch->name);
-	}
-
-	tch->is_used = 0;
-
-	return ret;
-}
-
-/**
- * Write File.
- *
- * @note Trigger the test from user space by:
- * echo 1 > /dev/sdio_al_test
- *
- */
-ssize_t test_write(struct file *filp, const char __user *buf, size_t size,
-		   loff_t *f_pos)
-{
-	sdio_al_test_initial_dev_and_chan(test_ctx);
-
-	if (strict_strtol(buf, 10, &test_ctx->testcase))
-		return -EINVAL;
-
-	switch (test_ctx->testcase) {
-	case 98:
-		pr_info(TEST_MODULE_NAME " set runtime debug on");
-		test_ctx->runtime_debug = 1;
-		return size;
-	case 99:
-		pr_info(TEST_MODULE_NAME " set runtime debug off");
-		test_ctx->runtime_debug = 0;
-		return size;
-	default:
-		pr_info(TEST_MODULE_NAME ":Bad Test number = %d.\n",
-			(int)test_ctx->testcase);
-		return size;
-	}
-
-	return size;
-}
-
-/**
- * Test Channel Init.
- */
-int test_channel_init(char *name)
-{
-	struct test_channel *test_ch;
-	int ch_id = 0;
-	int ret;
-
-	pr_debug(TEST_MODULE_NAME ":%s.\n", __func__);
-	pr_info(TEST_MODULE_NAME ": init test channel %s.\n", name);
-
-	ch_id = channel_name_to_id(name);
-	pr_debug(TEST_MODULE_NAME ":id = %d.\n", ch_id);
-	if (test_ctx->test_ch_arr[ch_id] == NULL) {
-		test_ch = kzalloc(sizeof(*test_ch), GFP_KERNEL);
-		if (test_ch == NULL) {
-			pr_err(TEST_MODULE_NAME ":kzalloc err for allocating "
-						"test_ch %s.\n",
-			       name);
-			return -ENOMEM;
-		}
-		test_ctx->test_ch_arr[ch_id] = test_ch;
-
-		test_ch->ch_id = ch_id;
-
-		strncpy(test_ch->name, name,
-		       strnlen(name, TEST_CH_NAME_SIZE)-SDIO_TEST_POSTFIX_SIZE);
-
-		test_ch->buf_size = MAX_XFER_SIZE;
-
-		test_ch->buf = kzalloc(test_ch->buf_size, GFP_KERNEL);
-		if (test_ch->buf == NULL) {
-			kfree(test_ch);
-			test_ctx->test_ch = NULL;
-			return -ENOMEM;
-		}
-
-		if (test_ch->ch_id == SDIO_SMEM) {
-			test_ctx->smem_buf = kzalloc(SMEM_MAX_XFER_SIZE,
-						     GFP_KERNEL);
-			if (test_ctx->smem_buf == NULL) {
-				pr_err(TEST_MODULE_NAME ":%s: Unable to "
-							"allocate smem buf\n",
-				       __func__);
-				kfree(test_ch);
-				test_ctx->test_ch = NULL;
-				return -ENOMEM;
-			}
-
-#ifdef CONFIG_MSM_SDIO_SMEM
-			ret = platform_driver_register(&sdio_smem_client_drv);
-			if (ret) {
-				pr_err(TEST_MODULE_NAME ":%s: Unable to "
-							"register sdio smem "
-							"test client\n",
-				       __func__);
-				return ret;
-			}
-#endif
-		} else {
-			test_ch->workqueue =
-				create_singlethread_workqueue(test_ch->name);
-			test_ch->test_work.test_ch = test_ch;
-			INIT_WORK(&test_ch->test_work.work, worker);
-
-			init_waitqueue_head(&test_ch->wait_q);
-		}
-	} else {
-		test_ch = test_ctx->test_ch_arr[ch_id];
-		pr_info(TEST_MODULE_NAME ":%s: ch %s was detected again\n",
-			__func__, test_ch->name);
-		test_ch->card_removed = 0;
-		if ((test_ch->is_used) &&
-		    (test_ch->test_type == SDIO_TEST_MODEM_RESET)) {
-			if (test_ch->ch_id == SDIO_SMEM) {
-#ifdef CONFIG_MSM_SDIO_SMEM
-				ret = add_sdio_smem();
-				if (ret) {
-					test_ch->ch_ready = false;
-					return 0;
-				}
-#endif
-			} else {
-				ret = open_sdio_ch(test_ch);
-				if (ret) {
-					pr_info(TEST_MODULE_NAME
-						":%s: open channel %s failed\n",
-					__func__, test_ch->name);
-					return 0;
-				}
-				ret = sdio_test_find_dev(test_ch);
-
-				if (ret) {
-					pr_err(TEST_MODULE_NAME ": %s - "
-					       "sdio_test_find_dev() returned "
-					       "with error", __func__);
-					return -ENODEV;
-				}
-
-				test_ch->sdio_al_device =
-					test_ch->ch->sdio_al_dev;
-			}
-			atomic_set(&test_ch->card_detected_event, 1);
-			wake_up(&test_ch->wait_q);
-		}
-	}
-
-	return 0;
-}
-
-static int sdio_test_channel_probe(struct platform_device *pdev)
-{
-	if (!pdev)
-		return -EIO;
-	return test_channel_init((char *)pdev->name);
-}
-
-static int sdio_test_channel_remove(struct platform_device *pdev)
-{
-	int ch_id;
-
-	if (!pdev)
-		return -EIO;
-
-	ch_id = channel_name_to_id((char *)pdev->name);
-	if (test_ctx->test_ch_arr[ch_id] == NULL)
-		return 0;
-
-	pr_info(TEST_MODULE_NAME "%s: remove ch %s\n",
-		__func__, test_ctx->test_ch_arr[ch_id]->name);
-
-	if ((ch_id == SDIO_SMEM) && (test_ctx->smem_pdev)) {
-		platform_device_unregister(test_ctx->smem_pdev);
-		test_ctx->smem_pdev = NULL;
-	}
-
-	test_ctx->test_ch_arr[ch_id]->ch_ready = 0;
-	test_ctx->test_ch_arr[ch_id]->card_removed = 1;
-
-	return 0;
-
-}
-
-static int sdio_test_channel_csvt_probe(struct platform_device *pdev)
-{
-	int ret = 0;
-
-	if (!pdev)
-		return -ENODEV;
-
-	test_ctx->csvt_app_pdev = platform_device_alloc("SDIO_CSVT_TEST_APP",
-							-1);
-	ret = platform_device_add(test_ctx->csvt_app_pdev);
-		if (ret) {
-			pr_err(MODULE_NAME ":platform_device_add failed, "
-					   "ret=%d\n", ret);
-			return ret;
-		}
-
-	return sdio_test_channel_probe(pdev);
-}
-
-static int sdio_test_channel_csvt_remove(struct platform_device *pdev)
-{
-	if (!pdev)
-		return -ENODEV;
-
-	platform_device_unregister(test_ctx->csvt_app_pdev);
-
-	return sdio_test_channel_remove(pdev);
-}
-
-static struct platform_driver sdio_rpc_drv = {
-	.probe		= sdio_test_channel_probe,
-	.remove		= sdio_test_channel_remove,
-	.driver		= {
-		.name	= "SDIO_RPC_TEST",
-		.owner	= THIS_MODULE,
-	},
-};
-
-static struct platform_driver sdio_qmi_drv = {
-	.probe		= sdio_test_channel_probe,
-	.remove		= sdio_test_channel_remove,
-	.driver		= {
-		.name	= "SDIO_QMI_TEST",
-		.owner	= THIS_MODULE,
-	},
-};
-
-static struct platform_driver sdio_diag_drv = {
-	.probe		= sdio_test_channel_probe,
-	.remove		= sdio_test_channel_remove,
-	.driver		= {
-		.name	= "SDIO_DIAG_TEST",
-		.owner	= THIS_MODULE,
-	},
-};
-
-static struct platform_driver sdio_smem_drv = {
-	.probe		= sdio_test_channel_probe,
-	.remove		= sdio_test_channel_remove,
-	.driver		= {
-		.name	= "SDIO_SMEM_TEST",
-		.owner	= THIS_MODULE,
-	},
-};
-
-static struct platform_driver sdio_rmnt_drv = {
-	.probe		= sdio_test_channel_probe,
-	.remove		= sdio_test_channel_remove,
-	.driver		= {
-		.name	= "SDIO_RMNT_TEST",
-		.owner	= THIS_MODULE,
-	},
-};
-
-static struct platform_driver sdio_dun_drv = {
-	.probe		= sdio_test_channel_probe,
-	.remove		= sdio_test_channel_remove,
-	.driver		= {
-		.name	= "SDIO_DUN_TEST",
-		.owner	= THIS_MODULE,
-	},
-};
-
-static struct platform_driver sdio_csvt_drv = {
-	.probe		= sdio_test_channel_csvt_probe,
-	.remove		= sdio_test_channel_csvt_remove,
-	.driver		= {
-		.name	= "SDIO_CSVT_TEST",
-		.owner	= THIS_MODULE,
-	},
-};
-
-static struct class *test_class;
-
-const struct file_operations test_fops = {
-	.owner = THIS_MODULE,
-	.write = test_write,
-};
-
-/**
- * Module Init.
- */
-static int __init test_init(void)
-{
-	int ret;
-
-	pr_debug(TEST_MODULE_NAME ":test_init.\n");
-
-	test_ctx = kzalloc(sizeof(struct test_context), GFP_KERNEL);
-
-	if (test_ctx == NULL) {
-		pr_err(TEST_MODULE_NAME ":kzalloc err.\n");
-		return -ENOMEM;
-	}
-	test_ctx->test_ch = NULL;
-	test_ctx->signature = TEST_SIGNATURE;
-
-	test_ctx->name = "UNKNOWN";
-
-	init_waitqueue_head(&test_ctx->wait_q);
-
-#ifdef CONFIG_DEBUG_FS
-	sdio_al_test_debugfs_init();
-#endif
-
-	test_class = class_create(THIS_MODULE, TEST_MODULE_NAME);
-
-	ret = alloc_chrdev_region(&test_ctx->dev_num, 0, 1, TEST_MODULE_NAME);
-	if (ret) {
-		pr_err(TEST_MODULE_NAME "alloc_chrdev_region err.\n");
-		return -ENODEV;
-	}
-
-	test_ctx->dev = device_create(test_class, NULL, test_ctx->dev_num,
-				      test_ctx, TEST_MODULE_NAME);
-	if (IS_ERR(test_ctx->dev)) {
-		pr_err(TEST_MODULE_NAME ":device_create err.\n");
-		return -ENODEV;
-	}
-
-	test_ctx->cdev = cdev_alloc();
-	if (test_ctx->cdev == NULL) {
-		pr_err(TEST_MODULE_NAME ":cdev_alloc err.\n");
-		return -ENODEV;
-	}
-	cdev_init(test_ctx->cdev, &test_fops);
-	test_ctx->cdev->owner = THIS_MODULE;
-
-	ret = cdev_add(test_ctx->cdev, test_ctx->dev_num, 1);
-	if (ret)
-		pr_err(TEST_MODULE_NAME ":cdev_add err=%d\n", -ret);
-	else
-		pr_debug(TEST_MODULE_NAME ":SDIO-AL-Test init OK..\n");
-
-	platform_driver_register(&sdio_rpc_drv);
-	platform_driver_register(&sdio_qmi_drv);
-	platform_driver_register(&sdio_diag_drv);
-	platform_driver_register(&sdio_smem_drv);
-	platform_driver_register(&sdio_rmnt_drv);
-	platform_driver_register(&sdio_dun_drv);
-	platform_driver_register(&sdio_csvt_drv);
-
-	return ret;
-}
-
-/**
- * Module Exit.
- */
-static void __exit test_exit(void)
-{
-	int i;
-
-	pr_debug(TEST_MODULE_NAME ":test_exit.\n");
-
-	test_ctx->exit_flag = true;
-
-	msleep(100); /* allow gracefully exit of the worker thread */
-
-	cdev_del(test_ctx->cdev);
-	device_destroy(test_class, test_ctx->dev_num);
-	unregister_chrdev_region(test_ctx->dev_num, 1);
-
-	platform_driver_unregister(&sdio_rpc_drv);
-	platform_driver_unregister(&sdio_qmi_drv);
-	platform_driver_unregister(&sdio_diag_drv);
-	platform_driver_unregister(&sdio_smem_drv);
-	platform_driver_unregister(&sdio_rmnt_drv);
-	platform_driver_unregister(&sdio_dun_drv);
-	platform_driver_unregister(&sdio_csvt_drv);
-
-	for (i = 0; i < SDIO_MAX_CHANNELS; i++) {
-		struct test_channel *tch = test_ctx->test_ch_arr[i];
-		if (!tch)
-			continue;
-		kfree(tch->buf);
-		kfree(tch);
-	}
-
-#ifdef CONFIG_DEBUG_FS
-	sdio_al_test_debugfs_cleanup();
-#endif
-
-	kfree(test_ctx);
-
-	pr_debug(TEST_MODULE_NAME ":test_exit complete.\n");
-}
-
-module_init(test_init);
-module_exit(test_exit);
-
-MODULE_LICENSE("GPL v2");
-MODULE_DESCRIPTION("SDIO_AL Test");
-MODULE_AUTHOR("Amir Samuelov <amirs@codeaurora.org>");
-
-
diff --git a/arch/arm/mach-msm/sdio_cmux.c b/arch/arm/mach-msm/sdio_cmux.c
deleted file mode 100644
index 70935b2..0000000
--- a/arch/arm/mach-msm/sdio_cmux.c
+++ /dev/null
@@ -1,885 +0,0 @@
-/* Copyright (c) 2010-2011, The Linux Foundation. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 and
- * only version 2 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- */
-
-#define DEBUG
-
-#include <linux/module.h>
-#include <linux/fs.h>
-#include <linux/device.h>
-#include <linux/delay.h>
-#include <linux/sched.h>
-#include <linux/spinlock.h>
-#include <linux/mutex.h>
-#include <linux/uaccess.h>
-#include <linux/workqueue.h>
-#include <linux/platform_device.h>
-#include <linux/slab.h>
-#include <linux/termios.h>
-#include <linux/debugfs.h>
-#include <linux/moduleparam.h>
-
-#include <mach/sdio_al.h>
-#include <mach/sdio_cmux.h>
-
-#include "modem_notifier.h"
-
-#define MAX_WRITE_RETRY 5
-#define MAGIC_NO_V1 0x33FC
-
-static int msm_sdio_cmux_debug_mask;
-module_param_named(debug_mask, msm_sdio_cmux_debug_mask,
-		   int, S_IRUGO | S_IWUSR | S_IWGRP);
-
-enum cmd_type {
-	DATA = 0,
-	OPEN,
-	CLOSE,
-	STATUS,
-	NUM_CMDS
-};
-
-#define DSR_POS 0x1
-#define CTS_POS 0x2
-#define RI_POS 0x4
-#define CD_POS 0x8
-
-struct sdio_cmux_ch {
-	int lc_id;
-
-	struct mutex lc_lock;
-	wait_queue_head_t open_wait_queue;
-	int is_remote_open;
-	int is_local_open;
-	int is_channel_reset;
-
-	char local_status;
-	char remote_status;
-
-	struct mutex tx_lock;
-	struct list_head tx_list;
-
-	void *priv;
-	void (*receive_cb)(void *, int, void *);
-	void (*write_done)(void *, int, void *);
-	void (*status_callback)(int, void *);
-} logical_ch[SDIO_CMUX_NUM_CHANNELS];
-
-struct sdio_cmux_hdr {
-	uint16_t magic_no;
-	uint8_t status;         /* This field is reserved for commands other
-				 * than STATUS */
-	uint8_t cmd;
-	uint8_t pad_bytes;
-	uint8_t lc_id;
-	uint16_t pkt_len;
-};
-
-struct sdio_cmux_pkt {
-	struct sdio_cmux_hdr *hdr;
-	void *data;
-};
-
-struct sdio_cmux_list_elem {
-	struct list_head list;
-	struct sdio_cmux_pkt cmux_pkt;
-};
-
-#define logical_ch_is_local_open(x)                        \
-	(logical_ch[(x)].is_local_open)
-
-#define logical_ch_is_remote_open(x)                       \
-	(logical_ch[(x)].is_remote_open)
-
-static void sdio_cdemux_fn(struct work_struct *work);
-static DECLARE_WORK(sdio_cdemux_work, sdio_cdemux_fn);
-static struct workqueue_struct *sdio_cdemux_wq;
-
-static DEFINE_MUTEX(write_lock);
-static uint32_t bytes_to_write;
-static DEFINE_MUTEX(temp_rx_lock);
-static LIST_HEAD(temp_rx_list);
-
-static void sdio_cmux_fn(struct work_struct *work);
-static DECLARE_WORK(sdio_cmux_work, sdio_cmux_fn);
-static struct workqueue_struct *sdio_cmux_wq;
-
-static struct sdio_channel *sdio_qmi_chl;
-static uint32_t sdio_cmux_inited;
-
-static uint32_t abort_tx;
-static DEFINE_MUTEX(modem_reset_lock);
-
-static DEFINE_MUTEX(probe_lock);
-
-enum {
-	MSM_SDIO_CMUX_DEBUG = 1U << 0,
-	MSM_SDIO_CMUX_DUMP_BUFFER = 1U << 1,
-};
-
-static struct platform_device sdio_ctl_dev = {
-	.name		= "SDIO_CTL",
-	.id		= -1,
-};
-
-#if defined(DEBUG)
-#define D_DUMP_BUFFER(prestr, cnt, buf) \
-do { \
-	if (msm_sdio_cmux_debug_mask & MSM_SDIO_CMUX_DUMP_BUFFER) { \
-		int i; \
-		pr_debug("%s", prestr); \
-		for (i = 0; i < cnt; i++) \
-			pr_info("%.2x", buf[i]); \
-		pr_debug("\n"); \
-	} \
-} while (0)
-
-#define D(x...) \
-do { \
-	if (msm_sdio_cmux_debug_mask & MSM_SDIO_CMUX_DEBUG) \
-		pr_debug(x); \
-} while (0)
-
-#else
-#define D_DUMP_BUFFER(prestr, cnt, buf) do {} while (0)
-#define D(x...) do {} while (0)
-#endif
-
-static int sdio_cmux_ch_alloc(int id)
-{
-	if (id < 0 || id >= SDIO_CMUX_NUM_CHANNELS) {
-		pr_err("%s: Invalid lc_id - %d\n", __func__, id);
-		return -EINVAL;
-	}
-
-	logical_ch[id].lc_id = id;
-	mutex_init(&logical_ch[id].lc_lock);
-	init_waitqueue_head(&logical_ch[id].open_wait_queue);
-	logical_ch[id].is_remote_open = 0;
-	logical_ch[id].is_local_open = 0;
-	logical_ch[id].is_channel_reset = 0;
-
-	INIT_LIST_HEAD(&logical_ch[id].tx_list);
-	mutex_init(&logical_ch[id].tx_lock);
-
-	logical_ch[id].priv = NULL;
-	logical_ch[id].receive_cb = NULL;
-	logical_ch[id].write_done = NULL;
-	return 0;
-}
-
-static int sdio_cmux_ch_clear_and_signal(int id)
-{
-	struct sdio_cmux_list_elem *list_elem;
-
-	if (id < 0 || id >= SDIO_CMUX_NUM_CHANNELS) {
-		pr_err("%s: Invalid lc_id - %d\n", __func__, id);
-		return -EINVAL;
-	}
-
-	mutex_lock(&logical_ch[id].lc_lock);
-	logical_ch[id].is_remote_open = 0;
-	mutex_lock(&logical_ch[id].tx_lock);
-	while (!list_empty(&logical_ch[id].tx_list)) {
-		list_elem = list_first_entry(&logical_ch[id].tx_list,
-					     struct sdio_cmux_list_elem,
-					     list);
-		list_del(&list_elem->list);
-		kfree(list_elem->cmux_pkt.hdr);
-		kfree(list_elem);
-	}
-	mutex_unlock(&logical_ch[id].tx_lock);
-	if (logical_ch[id].receive_cb)
-		logical_ch[id].receive_cb(NULL, 0, logical_ch[id].priv);
-	if (logical_ch[id].write_done)
-		logical_ch[id].write_done(NULL, 0, logical_ch[id].priv);
-	mutex_unlock(&logical_ch[id].lc_lock);
-	wake_up(&logical_ch[id].open_wait_queue);
-	return 0;
-}
-
-static int sdio_cmux_write_cmd(const int id, enum cmd_type type)
-{
-	int write_size = 0;
-	void *write_data = NULL;
-	struct sdio_cmux_list_elem *list_elem;
-
-	if (id < 0 || id >= SDIO_CMUX_NUM_CHANNELS) {
-		pr_err("%s: Invalid lc_id - %d\n", __func__, id);
-		return -EINVAL;
-	}
-
-	if (type < 0 || type > NUM_CMDS) {
-		pr_err("%s: Invalid cmd - %d\n", __func__, type);
-		return -EINVAL;
-	}
-
-	write_size = sizeof(struct sdio_cmux_hdr);
-	list_elem = kmalloc(sizeof(struct sdio_cmux_list_elem), GFP_KERNEL);
-	if (!list_elem) {
-		pr_err("%s: list_elem alloc failed\n", __func__);
-		return -ENOMEM;
-	}
-
-	write_data = kmalloc(write_size, GFP_KERNEL);
-	if (!write_data) {
-		pr_err("%s: write_data alloc failed\n", __func__);
-		kfree(list_elem);
-		return -ENOMEM;
-	}
-
-	list_elem->cmux_pkt.hdr = (struct sdio_cmux_hdr *)write_data;
-	list_elem->cmux_pkt.data = NULL;
-
-	list_elem->cmux_pkt.hdr->lc_id = (uint8_t)id;
-	list_elem->cmux_pkt.hdr->pkt_len = (uint16_t)0;
-	list_elem->cmux_pkt.hdr->cmd = (uint8_t)type;
-	list_elem->cmux_pkt.hdr->status = (uint8_t)0;
-	if (type == STATUS)
-		list_elem->cmux_pkt.hdr->status = logical_ch[id].local_status;
-	list_elem->cmux_pkt.hdr->pad_bytes = (uint8_t)0;
-	list_elem->cmux_pkt.hdr->magic_no = (uint16_t)MAGIC_NO_V1;
-
-	mutex_lock(&logical_ch[id].tx_lock);
-	list_add_tail(&list_elem->list, &logical_ch[id].tx_list);
-	mutex_unlock(&logical_ch[id].tx_lock);
-
-	mutex_lock(&write_lock);
-	bytes_to_write += write_size;
-	mutex_unlock(&write_lock);
-	queue_work(sdio_cmux_wq, &sdio_cmux_work);
-
-	return 0;
-}
-
-int sdio_cmux_open(const int id,
-		   void (*receive_cb)(void *, int, void *),
-		   void (*write_done)(void *, int, void *),
-		   void (*status_callback)(int, void *),
-		   void *priv)
-{
-	int r;
-	struct sdio_cmux_list_elem *list_elem, *list_elem_tmp;
-
-	if (!sdio_cmux_inited)
-		return -ENODEV;
-	if (id < 0 || id >= SDIO_CMUX_NUM_CHANNELS) {
-		pr_err("%s: Invalid id - %d\n", __func__, id);
-		return -EINVAL;
-	}
-
-	r = wait_event_timeout(logical_ch[id].open_wait_queue,
-				logical_ch[id].is_remote_open, (1 * HZ));
-	if (r < 0) {
-		pr_err("ERROR %s: wait_event_timeout() failed for"
-		       " ch%d with rc %d\n", __func__, id, r);
-		return r;
-	}
-	if (r == 0) {
-		pr_err("ERROR %s: Wait Timed Out for ch%d\n", __func__, id);
-		return -ETIMEDOUT;
-	}
-
-	mutex_lock(&logical_ch[id].lc_lock);
-	if (!logical_ch[id].is_remote_open) {
-		pr_err("%s: Remote ch%d not opened\n", __func__, id);
-		mutex_unlock(&logical_ch[id].lc_lock);
-		return -EINVAL;
-	}
-	if (logical_ch[id].is_local_open) {
-		mutex_unlock(&logical_ch[id].lc_lock);
-		return 0;
-	}
-	logical_ch[id].is_local_open = 1;
-	logical_ch[id].priv = priv;
-	logical_ch[id].receive_cb = receive_cb;
-	logical_ch[id].write_done = write_done;
-	logical_ch[id].status_callback = status_callback;
-	if (logical_ch[id].receive_cb) {
-		mutex_lock(&temp_rx_lock);
-		list_for_each_entry_safe(list_elem, list_elem_tmp,
-					 &temp_rx_list, list) {
-			if ((int)list_elem->cmux_pkt.hdr->lc_id == id) {
-				logical_ch[id].receive_cb(
-					list_elem->cmux_pkt.data,
-					(int)list_elem->cmux_pkt.hdr->pkt_len,
-					logical_ch[id].priv);
-				list_del(&list_elem->list);
-				kfree(list_elem->cmux_pkt.hdr);
-				kfree(list_elem);
-			}
-		}
-		mutex_unlock(&temp_rx_lock);
-	}
-	mutex_unlock(&logical_ch[id].lc_lock);
-	sdio_cmux_write_cmd(id, OPEN);
-	return 0;
-}
-EXPORT_SYMBOL(sdio_cmux_open);
-
-int sdio_cmux_close(int id)
-{
-	struct sdio_cmux_ch *ch;
-
-	if (!sdio_cmux_inited)
-		return -ENODEV;
-	if (id < 0 || id >= SDIO_CMUX_NUM_CHANNELS) {
-		pr_err("%s: Invalid channel close\n", __func__);
-		return -EINVAL;
-	}
-
-	ch = &logical_ch[id];
-	mutex_lock(&ch->lc_lock);
-	ch->receive_cb = NULL;
-	mutex_lock(&ch->tx_lock);
-	ch->write_done = NULL;
-	mutex_unlock(&ch->tx_lock);
-	ch->is_local_open = 0;
-	ch->priv = NULL;
-	mutex_unlock(&ch->lc_lock);
-	sdio_cmux_write_cmd(ch->lc_id, CLOSE);
-	return 0;
-}
-EXPORT_SYMBOL(sdio_cmux_close);
-
-int sdio_cmux_write_avail(int id)
-{
-	int write_avail;
-
-	mutex_lock(&logical_ch[id].lc_lock);
-	if (logical_ch[id].is_channel_reset) {
-		mutex_unlock(&logical_ch[id].lc_lock);
-		return -ENETRESET;
-	}
-	mutex_unlock(&logical_ch[id].lc_lock);
-	write_avail = sdio_write_avail(sdio_qmi_chl);
-	return write_avail - bytes_to_write;
-}
-EXPORT_SYMBOL(sdio_cmux_write_avail);
-
-int sdio_cmux_write(int id, void *data, int len)
-{
-	struct sdio_cmux_list_elem *list_elem;
-	uint32_t write_size;
-	void *write_data = NULL;
-	struct sdio_cmux_ch *ch;
-	int ret;
-
-	if (!sdio_cmux_inited)
-		return -ENODEV;
-	if (id < 0 || id >= SDIO_CMUX_NUM_CHANNELS) {
-		pr_err("%s: Invalid channel id %d\n", __func__, id);
-		return -ENODEV;
-	}
-
-	ch = &logical_ch[id];
-	if (len <= 0) {
-		pr_err("%s: Invalid len %d bytes to write\n",
-			__func__, len);
-		return -EINVAL;
-	}
-
-	write_size = sizeof(struct sdio_cmux_hdr) + len;
-	list_elem = kmalloc(sizeof(struct sdio_cmux_list_elem), GFP_KERNEL);
-	if (!list_elem) {
-		pr_err("%s: list_elem alloc failed\n", __func__);
-		return -ENOMEM;
-	}
-
-	write_data = kmalloc(write_size, GFP_KERNEL);
-	if (!write_data) {
-		pr_err("%s: write_data alloc failed\n", __func__);
-		kfree(list_elem);
-		return -ENOMEM;
-	}
-
-	list_elem->cmux_pkt.hdr = (struct sdio_cmux_hdr *)write_data;
-	list_elem->cmux_pkt.data = (void *)((char *)write_data +
-						sizeof(struct sdio_cmux_hdr));
-	memcpy(list_elem->cmux_pkt.data, data, len);
-
-	list_elem->cmux_pkt.hdr->lc_id = (uint8_t)ch->lc_id;
-	list_elem->cmux_pkt.hdr->pkt_len = (uint16_t)len;
-	list_elem->cmux_pkt.hdr->cmd = (uint8_t)DATA;
-	list_elem->cmux_pkt.hdr->status = (uint8_t)0;
-	list_elem->cmux_pkt.hdr->pad_bytes = (uint8_t)0;
-	list_elem->cmux_pkt.hdr->magic_no = (uint16_t)MAGIC_NO_V1;
-
-	mutex_lock(&ch->lc_lock);
-	if (!ch->is_remote_open || !ch->is_local_open) {
-		pr_err("%s: Local ch%d sending data before sending/receiving"
-		       " OPEN command\n", __func__, ch->lc_id);
-		if (ch->is_channel_reset)
-			ret = -ENETRESET;
-		else
-			ret = -ENODEV;
-		mutex_unlock(&ch->lc_lock);
-		kfree(write_data);
-		kfree(list_elem);
-		return ret;
-	}
-	mutex_lock(&ch->tx_lock);
-	list_add_tail(&list_elem->list, &ch->tx_list);
-	mutex_unlock(&ch->tx_lock);
-	mutex_unlock(&ch->lc_lock);
-
-	mutex_lock(&write_lock);
-	bytes_to_write += write_size;
-	mutex_unlock(&write_lock);
-	queue_work(sdio_cmux_wq, &sdio_cmux_work);
-
-	return len;
-}
-EXPORT_SYMBOL(sdio_cmux_write);
-
-int is_remote_open(int id)
-{
-	if (id < 0 || id >= SDIO_CMUX_NUM_CHANNELS)
-		return -ENODEV;
-
-	return logical_ch_is_remote_open(id);
-}
-EXPORT_SYMBOL(is_remote_open);
-
-int sdio_cmux_is_channel_reset(int id)
-{
-	int ret;
-	if (id < 0 || id >= SDIO_CMUX_NUM_CHANNELS)
-		return -ENODEV;
-
-	mutex_lock(&logical_ch[id].lc_lock);
-	ret = logical_ch[id].is_channel_reset;
-	mutex_unlock(&logical_ch[id].lc_lock);
-	return ret;
-}
-EXPORT_SYMBOL(sdio_cmux_is_channel_reset);
-
-int sdio_cmux_tiocmget(int id)
-{
-	int ret =  (logical_ch[id].remote_status & DSR_POS ? TIOCM_DSR : 0) |
-		(logical_ch[id].remote_status & CTS_POS ? TIOCM_CTS : 0) |
-		(logical_ch[id].remote_status & CD_POS ? TIOCM_CD : 0) |
-		(logical_ch[id].remote_status & RI_POS ? TIOCM_RI : 0) |
-		(logical_ch[id].local_status & CTS_POS ? TIOCM_RTS : 0) |
-		(logical_ch[id].local_status & DSR_POS ? TIOCM_DTR : 0);
-	return ret;
-}
-EXPORT_SYMBOL(sdio_cmux_tiocmget);
-
-int sdio_cmux_tiocmset(int id, unsigned int set, unsigned int clear)
-{
-	if (set & TIOCM_DTR)
-		logical_ch[id].local_status |= DSR_POS;
-
-	if (set & TIOCM_RTS)
-		logical_ch[id].local_status |= CTS_POS;
-
-	if (clear & TIOCM_DTR)
-		logical_ch[id].local_status &= ~DSR_POS;
-
-	if (clear & TIOCM_RTS)
-		logical_ch[id].local_status &= ~CTS_POS;
-
-	sdio_cmux_write_cmd(id, STATUS);
-	return 0;
-}
-EXPORT_SYMBOL(sdio_cmux_tiocmset);
-
-static int copy_packet(void *pkt, int size)
-{
-	struct sdio_cmux_list_elem *list_elem = NULL;
-	void *temp_pkt = NULL;
-
-	list_elem = kmalloc(sizeof(struct sdio_cmux_list_elem), GFP_KERNEL);
-	if (!list_elem) {
-		pr_err("%s: list_elem alloc failed\n", __func__);
-		return -ENOMEM;
-	}
-	temp_pkt = kmalloc(size, GFP_KERNEL);
-	if (!temp_pkt) {
-		pr_err("%s: temp_pkt alloc failed\n", __func__);
-		kfree(list_elem);
-		return -ENOMEM;
-	}
-
-	memcpy(temp_pkt, pkt, size);
-	list_elem->cmux_pkt.hdr = temp_pkt;
-	list_elem->cmux_pkt.data = (void *)((char *)temp_pkt +
-					    sizeof(struct sdio_cmux_hdr));
-	mutex_lock(&temp_rx_lock);
-	list_add_tail(&list_elem->list, &temp_rx_list);
-	mutex_unlock(&temp_rx_lock);
-	return 0;
-}
-
-static int process_cmux_pkt(void *pkt, int size)
-{
-	struct sdio_cmux_hdr *mux_hdr;
-	uint32_t id, data_size;
-	void *data;
-	char *dump_buf = (char *)pkt;
-
-	D_DUMP_BUFFER("process_cmux_pkt:", size, dump_buf);
-	mux_hdr = (struct sdio_cmux_hdr *)pkt;
-	switch (mux_hdr->cmd) {
-	case OPEN:
-		id = (uint32_t)(mux_hdr->lc_id);
-		D("%s: Received OPEN command for ch%d\n", __func__, id);
-		mutex_lock(&logical_ch[id].lc_lock);
-		logical_ch[id].is_remote_open = 1;
-		if (logical_ch[id].is_channel_reset) {
-			sdio_cmux_write_cmd(id, OPEN);
-			logical_ch[id].is_channel_reset = 0;
-		}
-		mutex_unlock(&logical_ch[id].lc_lock);
-		wake_up(&logical_ch[id].open_wait_queue);
-		break;
-
-	case CLOSE:
-		id = (uint32_t)(mux_hdr->lc_id);
-		D("%s: Received CLOSE command for ch%d\n", __func__, id);
-		sdio_cmux_ch_clear_and_signal(id);
-		break;
-
-	case DATA:
-		id = (uint32_t)(mux_hdr->lc_id);
-		D("%s: Received DATA for ch%d\n", __func__, id);
-		/*Channel is not locally open & if single packet received
-		  then drop it*/
-		mutex_lock(&logical_ch[id].lc_lock);
-		if (!logical_ch[id].is_remote_open) {
-			mutex_unlock(&logical_ch[id].lc_lock);
-			pr_err("%s: Remote Ch%d sent data before sending/"
-			       "receiving OPEN command\n", __func__, id);
-			return -ENODEV;
-		}
-
-		data = (void *)((char *)pkt + sizeof(struct sdio_cmux_hdr));
-		data_size = (int)(((struct sdio_cmux_hdr *)pkt)->pkt_len);
-		if (logical_ch[id].receive_cb)
-			logical_ch[id].receive_cb(data, data_size,
-						logical_ch[id].priv);
-		else
-			copy_packet(pkt, size);
-		mutex_unlock(&logical_ch[id].lc_lock);
-		break;
-
-	case STATUS:
-		id = (uint32_t)(mux_hdr->lc_id);
-		D("%s: Received STATUS command for ch%d\n", __func__, id);
-		if (logical_ch[id].remote_status != mux_hdr->status) {
-			mutex_lock(&logical_ch[id].lc_lock);
-			logical_ch[id].remote_status = mux_hdr->status;
-			mutex_unlock(&logical_ch[id].lc_lock);
-			if (logical_ch[id].status_callback)
-				logical_ch[id].status_callback(
-							sdio_cmux_tiocmget(id),
-							logical_ch[id].priv);
-		}
-		break;
-	}
-	return 0;
-}
-
-static void parse_cmux_data(void *data, int size)
-{
-	int data_parsed = 0, pkt_size;
-	char *temp_ptr;
-
-	D("Entered %s\n", __func__);
-	temp_ptr = (char *)data;
-	while (data_parsed < size) {
-		pkt_size = sizeof(struct sdio_cmux_hdr) +
-			   (int)(((struct sdio_cmux_hdr *)temp_ptr)->pkt_len);
-		D("Parsed %d bytes, Current Pkt Size %d bytes,"
-		  " Total size %d bytes\n", data_parsed, pkt_size, size);
-		process_cmux_pkt((void *)temp_ptr, pkt_size);
-		data_parsed += pkt_size;
-		temp_ptr += pkt_size;
-	}
-
-	kfree(data);
-}
-
-static void sdio_cdemux_fn(struct work_struct *work)
-{
-	int r = 0, read_avail = 0;
-	void *cmux_data;
-
-	while (1) {
-		read_avail = sdio_read_avail(sdio_qmi_chl);
-		if (read_avail < 0) {
-			pr_err("%s: sdio_read_avail failed with rc %d\n",
-				__func__, read_avail);
-			return;
-		}
-
-		if (read_avail == 0) {
-			D("%s: Nothing to read\n", __func__);
-			return;
-		}
-
-		D("%s: kmalloc %d bytes\n", __func__, read_avail);
-		cmux_data = kmalloc(read_avail, GFP_KERNEL);
-		if (!cmux_data) {
-			pr_err("%s: kmalloc Failed\n", __func__);
-			return;
-		}
-
-		D("%s: sdio_read %d bytes\n", __func__, read_avail);
-		r = sdio_read(sdio_qmi_chl, cmux_data, read_avail);
-		if (r < 0) {
-			pr_err("%s: sdio_read failed with rc %d\n",
-				__func__, r);
-			kfree(cmux_data);
-			return;
-		}
-
-		parse_cmux_data(cmux_data, read_avail);
-	}
-	return;
-}
-
-static void sdio_cmux_fn(struct work_struct *work)
-{
-	int i, r = 0;
-	void *write_data;
-	uint32_t write_size, write_avail, write_retry = 0;
-	int bytes_written;
-	struct sdio_cmux_list_elem *list_elem = NULL;
-	struct sdio_cmux_ch *ch;
-
-	for (i = 0; i < SDIO_CMUX_NUM_CHANNELS; ++i) {
-		ch = &logical_ch[i];
-		bytes_written = 0;
-		mutex_lock(&ch->tx_lock);
-		while (!list_empty(&ch->tx_list)) {
-			list_elem = list_first_entry(&ch->tx_list,
-					     struct sdio_cmux_list_elem,
-					     list);
-			list_del(&list_elem->list);
-			mutex_unlock(&ch->tx_lock);
-
-			write_data = (void *)list_elem->cmux_pkt.hdr;
-			write_size = sizeof(struct sdio_cmux_hdr) +
-				(uint32_t)list_elem->cmux_pkt.hdr->pkt_len;
-
-			mutex_lock(&modem_reset_lock);
-			while (!(abort_tx) &&
-				((write_avail = sdio_write_avail(sdio_qmi_chl))
-						< write_size)) {
-				mutex_unlock(&modem_reset_lock);
-				pr_err("%s: sdio_write_avail %d bytes, "
-				       "write size %d bytes. Waiting...\n",
-					__func__, write_avail, write_size);
-				msleep(250);
-				mutex_lock(&modem_reset_lock);
-			}
-			while (!(abort_tx) &&
-				((r = sdio_write(sdio_qmi_chl,
-						write_data, write_size)) < 0)
-				&& (r != -ENODEV)
-				&& (write_retry++ < MAX_WRITE_RETRY)) {
-				mutex_unlock(&modem_reset_lock);
-				pr_err("%s: sdio_write failed with rc %d."
-				       "Retrying...", __func__, r);
-				msleep(250);
-				mutex_lock(&modem_reset_lock);
-			}
-			if (!r && !abort_tx) {
-				D("%s: sdio_write_completed %dbytes\n",
-				  __func__, write_size);
-				bytes_written += write_size;
-			} else if (r == -ENODEV) {
-				pr_err("%s: aborting_tx because sdio_write"
-				       " returned %d\n", __func__, r);
-				r = 0;
-				abort_tx = 1;
-			}
-			mutex_unlock(&modem_reset_lock);
-			kfree(list_elem->cmux_pkt.hdr);
-			kfree(list_elem);
-			mutex_lock(&write_lock);
-			bytes_to_write -= write_size;
-			mutex_unlock(&write_lock);
-			mutex_lock(&ch->tx_lock);
-		}
-		if (ch->write_done)
-			ch->write_done(NULL, bytes_written, ch->priv);
-		mutex_unlock(&ch->tx_lock);
-	}
-	return;
-}
-
-static void sdio_qmi_chl_notify(void *priv, unsigned event)
-{
-	if (event == SDIO_EVENT_DATA_READ_AVAIL) {
-		D("%s: Received SDIO_EVENT_DATA_READ_AVAIL\n", __func__);
-		queue_work(sdio_cdemux_wq, &sdio_cdemux_work);
-	}
-}
-
-#ifdef CONFIG_DEBUG_FS
-
-static int debug_tbl(char *buf, int max)
-{
-	int i = 0;
-	int j;
-
-	for (j = 0; j < SDIO_CMUX_NUM_CHANNELS; ++j) {
-		i += scnprintf(buf + i, max - i,
-			"ch%02d  local open=%s  remote open=%s\n",
-			j, logical_ch_is_local_open(j) ? "Y" : "N",
-			logical_ch_is_remote_open(j) ? "Y" : "N");
-	}
-
-	return i;
-}
-
-#define DEBUG_BUFMAX 4096
-static char debug_buffer[DEBUG_BUFMAX];
-
-static ssize_t debug_read(struct file *file, char __user *buf,
-				size_t count, loff_t *ppos)
-{
-	int (*fill)(char *buf, int max) = file->private_data;
-	int bsize = fill(debug_buffer, DEBUG_BUFMAX);
-	return simple_read_from_buffer(buf, count, ppos, debug_buffer, bsize);
-}
-
-static int debug_open(struct inode *inode, struct file *file)
-{
-	file->private_data = inode->i_private;
-	return 0;
-}
-
-
-static const struct file_operations debug_ops = {
-	.read = debug_read,
-	.open = debug_open,
-};
-
-static void debug_create(const char *name, mode_t mode,
-				struct dentry *dent,
-				int (*fill)(char *buf, int max))
-{
-	debugfs_create_file(name, mode, dent, fill, &debug_ops);
-}
-
-#endif
-
-static int sdio_cmux_probe(struct platform_device *pdev)
-{
-	int i, r;
-
-	mutex_lock(&probe_lock);
-	D("%s Begins\n", __func__);
-	if (sdio_cmux_inited) {
-		mutex_lock(&modem_reset_lock);
-		r =  sdio_open("SDIO_QMI", &sdio_qmi_chl, NULL,
-				sdio_qmi_chl_notify);
-		if (r < 0) {
-			mutex_unlock(&modem_reset_lock);
-			pr_err("%s: sdio_open() failed\n", __func__);
-			goto error0;
-		}
-		abort_tx = 0;
-		mutex_unlock(&modem_reset_lock);
-		mutex_unlock(&probe_lock);
-		return 0;
-	}
-
-	for (i = 0; i < SDIO_CMUX_NUM_CHANNELS; ++i)
-		sdio_cmux_ch_alloc(i);
-	INIT_LIST_HEAD(&temp_rx_list);
-
-	sdio_cmux_wq = create_singlethread_workqueue("sdio_cmux");
-	if (IS_ERR(sdio_cmux_wq)) {
-		pr_err("%s: create_singlethread_workqueue() ENOMEM\n",
-			__func__);
-		r = -ENOMEM;
-		goto error0;
-	}
-
-	sdio_cdemux_wq = create_singlethread_workqueue("sdio_cdemux");
-	if (IS_ERR(sdio_cdemux_wq)) {
-		pr_err("%s: create_singlethread_workqueue() ENOMEM\n",
-			__func__);
-		r = -ENOMEM;
-		goto error1;
-	}
-
-	r = sdio_open("SDIO_QMI", &sdio_qmi_chl, NULL, sdio_qmi_chl_notify);
-	if (r < 0) {
-		pr_err("%s: sdio_open() failed\n", __func__);
-		goto error2;
-	}
-
-	platform_device_register(&sdio_ctl_dev);
-	sdio_cmux_inited = 1;
-	D("SDIO Control MUX Driver Initialized.\n");
-	mutex_unlock(&probe_lock);
-	return 0;
-
-error2:
-	destroy_workqueue(sdio_cdemux_wq);
-error1:
-	destroy_workqueue(sdio_cmux_wq);
-error0:
-	mutex_unlock(&probe_lock);
-	return r;
-}
-
-static int sdio_cmux_remove(struct platform_device *pdev)
-{
-	int i;
-
-	mutex_lock(&modem_reset_lock);
-	abort_tx = 1;
-
-	for (i = 0; i < SDIO_CMUX_NUM_CHANNELS; ++i) {
-		mutex_lock(&logical_ch[i].lc_lock);
-		logical_ch[i].is_channel_reset = 1;
-		mutex_unlock(&logical_ch[i].lc_lock);
-		sdio_cmux_ch_clear_and_signal(i);
-	}
-	sdio_qmi_chl = NULL;
-	mutex_unlock(&modem_reset_lock);
-
-	return 0;
-}
-
-static struct platform_driver sdio_cmux_driver = {
-	.probe          = sdio_cmux_probe,
-	.remove         = sdio_cmux_remove,
-	.driver         = {
-			.name   = "SDIO_QMI",
-			.owner  = THIS_MODULE,
-	},
-};
-
-static int __init sdio_cmux_init(void)
-{
-#ifdef CONFIG_DEBUG_FS
-	struct dentry *dent;
-
-	dent = debugfs_create_dir("sdio_cmux", 0);
-	if (!IS_ERR(dent))
-		debug_create("tbl", 0444, dent, debug_tbl);
-#endif
-
-	msm_sdio_cmux_debug_mask = 0;
-	return platform_driver_register(&sdio_cmux_driver);
-}
-
-module_init(sdio_cmux_init);
-MODULE_DESCRIPTION("MSM SDIO Control MUX");
-MODULE_LICENSE("GPL v2");
diff --git a/arch/arm/mach-msm/sdio_ctl.c b/arch/arm/mach-msm/sdio_ctl.c
deleted file mode 100644
index cacdce9..0000000
--- a/arch/arm/mach-msm/sdio_ctl.c
+++ /dev/null
@@ -1,575 +0,0 @@
-/* Copyright (c) 2010-2012, The Linux Foundation. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 and
- * only version 2 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- */
-
-/*
- * SDIO Control Driver -- Provides a binary SDIO muxed control port
- *                       interface.
- */
-
-#include <linux/cdev.h>
-#include <linux/module.h>
-#include <linux/fs.h>
-#include <linux/device.h>
-#include <linux/delay.h>
-#include <linux/sched.h>
-#include <linux/spinlock.h>
-#include <linux/mutex.h>
-#include <linux/uaccess.h>
-#include <linux/workqueue.h>
-#include <linux/poll.h>
-#include <asm/ioctls.h>
-#include <linux/platform_device.h>
-#include <mach/msm_smd.h>
-#include <mach/sdio_al.h>
-#include <mach/sdio_cmux.h>
-#include "modem_notifier.h"
-#include <linux/slab.h>
-
-#define MAX_WRITE_RETRY 5
-#define MAGIC_NO_V1 0x33FC
-#define NUM_SDIO_CTL_PORTS 10
-#define DEVICE_NAME "sdioctl"
-#define MAX_BUF_SIZE 2048
-#define DEBUG
-
-static int msm_sdio_ctl_debug_mask;
-module_param_named(debug_mask, msm_sdio_ctl_debug_mask,
-		   int, S_IRUGO | S_IWUSR | S_IWGRP);
-
-struct sdio_ctl_dev {
-	int id;
-	char name[9];
-	struct cdev cdev;
-	struct device *devicep;
-	struct mutex dev_lock;
-	int ref_count;
-
-	struct mutex rx_lock;
-	uint32_t read_avail;
-	struct list_head rx_list;
-
-	wait_queue_head_t read_wait_queue;
-	wait_queue_head_t write_wait_queue;
-} *sdio_ctl_devp[NUM_SDIO_CTL_PORTS];
-
-struct sdio_ctl_pkt {
-	int data_size;
-	void *data;
-};
-
-struct sdio_ctl_list_elem {
-	struct list_head list;
-	struct sdio_ctl_pkt ctl_pkt;
-};
-
-struct class *sdio_ctl_classp;
-static dev_t sdio_ctl_number;
-static uint32_t sdio_ctl_inited;
-
-enum {
-	MSM_SDIO_CTL_DEBUG = 1U << 0,
-	MSM_SDIO_CTL_DUMP_BUFFER = 1U << 1,
-};
-
-#if defined(DEBUG)
-#define D_DUMP_BUFFER(prestr, cnt, buf) \
-do { \
-	if (msm_sdio_ctl_debug_mask & MSM_SDIO_CTL_DUMP_BUFFER) { \
-		int i; \
-		pr_info("%s", prestr); \
-		for (i = 0; i < cnt; i++) \
-			pr_info("%.2x", buf[i]); \
-		pr_info("\n"); \
-	} \
-} while (0)
-
-#define D(x...) \
-do { \
-	if (msm_sdio_ctl_debug_mask & MSM_SDIO_CTL_DEBUG) \
-		pr_info(x); \
-} while (0)
-
-#else
-#define D_DUMP_BUFFER(prestr, cnt, buf) do {} while (0)
-#define D(x...) do {} while (0)
-#endif
-
-static uint32_t cmux_ch_id[] = {
-	SDIO_CMUX_DATA_CTL_0,
-	SDIO_CMUX_DATA_CTL_1,
-	SDIO_CMUX_DATA_CTL_2,
-	SDIO_CMUX_DATA_CTL_3,
-	SDIO_CMUX_DATA_CTL_4,
-	SDIO_CMUX_DATA_CTL_5,
-	SDIO_CMUX_DATA_CTL_6,
-	SDIO_CMUX_DATA_CTL_7,
-	SDIO_CMUX_USB_CTL_0,
-	SDIO_CMUX_CSVT_CTL_0
-};
-
-static int get_ctl_dev_index(int id)
-{
-	int dev_index;
-	for (dev_index = 0; dev_index < NUM_SDIO_CTL_PORTS; dev_index++) {
-		if (cmux_ch_id[dev_index] == id)
-			return dev_index;
-	}
-	return -ENODEV;
-}
-
-static void sdio_ctl_receive_cb(void *data, int size, void *priv)
-{
-	struct sdio_ctl_list_elem *list_elem = NULL;
-	int id = ((struct sdio_ctl_dev *)(priv))->id;
-	int dev_index;
-
-	if (id < 0 || id > cmux_ch_id[NUM_SDIO_CTL_PORTS - 1])
-		return;
-	dev_index = get_ctl_dev_index(id);
-	if (dev_index < 0) {
-		pr_err("%s: Ch%d is not exported to user-space\n",
-			__func__, id);
-		return;
-	}
-
-	if (!data || size <= 0) {
-		wake_up(&sdio_ctl_devp[dev_index]->read_wait_queue);
-		return;
-	}
-
-	list_elem = kmalloc(sizeof(struct sdio_ctl_list_elem), GFP_KERNEL);
-	if (!list_elem) {
-		pr_err("%s: list_elem alloc failed\n", __func__);
-		return;
-	}
-
-	list_elem->ctl_pkt.data = kmalloc(size, GFP_KERNEL);
-	if (!list_elem->ctl_pkt.data) {
-		pr_err("%s: list_elem->data alloc failed\n", __func__);
-		kfree(list_elem);
-		return;
-	}
-	memcpy(list_elem->ctl_pkt.data, data, size);
-	list_elem->ctl_pkt.data_size = size;
-	mutex_lock(&sdio_ctl_devp[dev_index]->rx_lock);
-	list_add_tail(&list_elem->list, &sdio_ctl_devp[dev_index]->rx_list);
-	sdio_ctl_devp[dev_index]->read_avail += size;
-	mutex_unlock(&sdio_ctl_devp[dev_index]->rx_lock);
-	wake_up(&sdio_ctl_devp[dev_index]->read_wait_queue);
-}
-
-static void sdio_ctl_write_done(void *data, int size, void *priv)
-{
-	int id = ((struct sdio_ctl_dev *)(priv))->id;
-	int dev_index;
-	if (id < 0 || id > cmux_ch_id[NUM_SDIO_CTL_PORTS - 1])
-		return;
-
-	dev_index = get_ctl_dev_index(id);
-	if (dev_index < 0) {
-		pr_err("%s: Ch%d is not exported to user-space\n",
-			__func__, id);
-		return;
-	}
-	wake_up(&sdio_ctl_devp[dev_index]->write_wait_queue);
-}
-
-static long sdio_ctl_ioctl(struct file *file, unsigned int cmd,
-					      unsigned long arg)
-{
-	int ret;
-	struct sdio_ctl_dev *sdio_ctl_devp;
-
-	sdio_ctl_devp = file->private_data;
-	if (!sdio_ctl_devp)
-		return -ENODEV;
-
-	switch (cmd) {
-	case TIOCMGET:
-		ret = sdio_cmux_tiocmget(sdio_ctl_devp->id);
-		break;
-	case TIOCMSET:
-		ret = sdio_cmux_tiocmset(sdio_ctl_devp->id, arg, ~arg);
-		break;
-	default:
-		ret = -EINVAL;
-	}
-
-	return ret;
-}
-
-static unsigned int sdio_ctl_poll(struct file *file, poll_table *wait)
-{
-	struct sdio_ctl_dev *sdio_ctl_devp;
-	unsigned int mask = 0;
-
-	sdio_ctl_devp = file->private_data;
-	if (!sdio_ctl_devp) {
-		pr_err("%s: on a NULL device\n", __func__);
-		return POLLERR;
-	}
-
-	poll_wait(file, &sdio_ctl_devp->read_wait_queue, wait);
-	mutex_lock(&sdio_ctl_devp->rx_lock);
-	if (sdio_cmux_is_channel_reset(sdio_ctl_devp->id)) {
-		mutex_unlock(&sdio_ctl_devp->rx_lock);
-		pr_err("%s notifying reset for sdio_ctl_dev id:%d\n",
-			__func__, sdio_ctl_devp->id);
-		return POLLERR;
-	}
-
-	if (sdio_ctl_devp->read_avail > 0)
-		mask |= POLLIN | POLLRDNORM;
-
-	mutex_unlock(&sdio_ctl_devp->rx_lock);
-
-	return mask;
-}
-
-ssize_t sdio_ctl_read(struct file *file,
-		      char __user *buf,
-		      size_t count,
-		      loff_t *ppos)
-{
-	int r = 0, id, bytes_to_read;
-	struct sdio_ctl_dev *sdio_ctl_devp;
-	struct sdio_ctl_list_elem *list_elem = NULL;
-
-	sdio_ctl_devp = file->private_data;
-
-	if (!sdio_ctl_devp)
-		return -ENODEV;
-
-	D("%s: read from ch%d\n", __func__, sdio_ctl_devp->id);
-
-	id = sdio_ctl_devp->id;
-	mutex_lock(&sdio_ctl_devp->rx_lock);
-	while (sdio_ctl_devp->read_avail <= 0) {
-		mutex_unlock(&sdio_ctl_devp->rx_lock);
-		r = wait_event_interruptible(sdio_ctl_devp->read_wait_queue,
-					     sdio_ctl_devp->read_avail > 0 ||
-					     !is_remote_open(id));
-		if (sdio_cmux_is_channel_reset(id))
-			return -ENETRESET;
-
-		if (!is_remote_open(id))
-			return -ENODEV;
-
-		if (r < 0) {
-			/* qualify error message */
-			/* we get this anytime a signal comes in */
-			if (r != -ERESTARTSYS)
-				pr_err("ERROR:%s: wait_event_interruptible "
-				       "ret %i\n", __func__, r);
-			return r;
-		}
-		mutex_lock(&sdio_ctl_devp->rx_lock);
-	}
-
-	if (list_empty(&sdio_ctl_devp->rx_list)) {
-		mutex_unlock(&sdio_ctl_devp->rx_lock);
-		D("%s: Nothing in ch%d's rx_list\n", __func__,
-		  sdio_ctl_devp->id);
-		return -EAGAIN;
-	}
-
-	list_elem = list_first_entry(&sdio_ctl_devp->rx_list,
-				     struct sdio_ctl_list_elem, list);
-	bytes_to_read = (uint32_t)(list_elem->ctl_pkt.data_size);
-	if (bytes_to_read > count) {
-		mutex_unlock(&sdio_ctl_devp->rx_lock);
-		pr_err("%s: Packet size %d > buf size %d\n", __func__,
-			bytes_to_read, count);
-		return -ENOMEM;
-	}
-
-	if (copy_to_user(buf, list_elem->ctl_pkt.data, bytes_to_read)) {
-		mutex_unlock(&sdio_ctl_devp->rx_lock);
-		pr_err("%s: copy_to_user failed for ch%d\n", __func__,
-			sdio_ctl_devp->id);
-		return -EFAULT;
-	}
-	sdio_ctl_devp->read_avail -= bytes_to_read;
-	list_del(&list_elem->list);
-	kfree(list_elem->ctl_pkt.data);
-	kfree(list_elem);
-	mutex_unlock(&sdio_ctl_devp->rx_lock);
-	D("%s: Returning %d bytes to ch%d\n", __func__,
-			bytes_to_read, sdio_ctl_devp->id);
-	return bytes_to_read;
-}
-
-
-ssize_t sdio_ctl_write(struct file *file,
-		       const char __user *buf,
-		       size_t count,
-		       loff_t *ppos)
-{
-	int r = 0, id;
-	char *temp_buf;
-	struct sdio_ctl_dev *sdio_ctl_devp;
-
-	if (count <= 0)
-		return -EINVAL;
-
-	sdio_ctl_devp = file->private_data;
-	if (!sdio_ctl_devp)
-		return -ENODEV;
-
-	D("%s: writing %i bytes on ch%d\n",
-	  __func__, count, sdio_ctl_devp->id);
-	id = sdio_ctl_devp->id;
-	mutex_lock(&sdio_ctl_devp->dev_lock);
-	while (sdio_cmux_write_avail(id) < count) {
-		mutex_unlock(&sdio_ctl_devp->dev_lock);
-		r = wait_event_interruptible(sdio_ctl_devp->write_wait_queue,
-					     sdio_cmux_write_avail(id) >= count
-					     || !is_remote_open(id));
-
-		if (sdio_cmux_is_channel_reset(id))
-			return -ENETRESET;
-
-		if (!is_remote_open(id))
-			return -ENODEV;
-
-		if (r < 0) {
-			/* qualify error message */
-			/* we get this anytime a signal comes in */
-			if (r != -ERESTARTSYS)
-				pr_err("ERROR:%s: wait_event_interruptible "
-				       "ret %i\n", __func__, r);
-			return r;
-		}
-		mutex_lock(&sdio_ctl_devp->dev_lock);
-	}
-
-	temp_buf = kmalloc(count, GFP_KERNEL);
-	if (!temp_buf) {
-		mutex_unlock(&sdio_ctl_devp->dev_lock);
-		pr_err("%s: temp_buf alloc failed\n", __func__);
-		return -ENOMEM;
-	}
-
-	if (copy_from_user(temp_buf, buf, count)) {
-		mutex_unlock(&sdio_ctl_devp->dev_lock);
-		pr_err("%s: copy_from_user failed\n", __func__);
-		kfree(temp_buf);
-		return -EFAULT;
-	}
-
-	r = sdio_cmux_write(id, (void *)temp_buf, count);
-	kfree(temp_buf);
-	mutex_unlock(&sdio_ctl_devp->dev_lock);
-	return r;
-}
-
-
-int sdio_ctl_open(struct inode *inode, struct file *file)
-{
-	int r = 0;
-	struct sdio_ctl_dev *sdio_ctl_devp;
-
-	if (!sdio_ctl_inited)
-		return -EIO;
-
-	sdio_ctl_devp = container_of(inode->i_cdev, struct sdio_ctl_dev, cdev);
-
-	if (!sdio_ctl_devp)
-		return -ENODEV;
-
-	D("%s called on sdioctl%d device\n", __func__, sdio_ctl_devp->id);
-	r = sdio_cmux_open(sdio_ctl_devp->id, sdio_ctl_receive_cb,
-			   sdio_ctl_write_done, NULL,
-			   sdio_ctl_devp);
-	if (r < 0) {
-		pr_err("ERROR %s: sdio_cmux_open failed with rc %d\n",
-			__func__, r);
-		return r;
-	}
-
-	mutex_lock(&sdio_ctl_devp->dev_lock);
-	sdio_ctl_devp->ref_count++;
-	mutex_unlock(&sdio_ctl_devp->dev_lock);
-
-	file->private_data = sdio_ctl_devp;
-	return 0;
-}
-
-int sdio_ctl_release(struct inode *inode, struct file *file)
-{
-	struct sdio_ctl_dev *sdio_ctl_devp;
-	struct sdio_ctl_list_elem *list_elem = NULL;
-
-	sdio_ctl_devp = file->private_data;
-	if (!sdio_ctl_devp)
-		return -EINVAL;
-
-	D("%s called on sdioctl%d device\n", __func__, sdio_ctl_devp->id);
-
-	mutex_lock(&sdio_ctl_devp->dev_lock);
-	if (sdio_ctl_devp->ref_count > 0) {
-		sdio_ctl_devp->ref_count--;
-		if (!sdio_ctl_devp->ref_count) {
-			mutex_lock(&sdio_ctl_devp->rx_lock);
-			while (!list_empty(&sdio_ctl_devp->rx_list)) {
-				list_elem = list_first_entry(
-						&sdio_ctl_devp->rx_list,
-						struct sdio_ctl_list_elem,
-						list);
-				list_del(&list_elem->list);
-				kfree(list_elem->ctl_pkt.data);
-				kfree(list_elem);
-			}
-			sdio_ctl_devp->read_avail = 0;
-			mutex_unlock(&sdio_ctl_devp->rx_lock);
-			sdio_cmux_close(sdio_ctl_devp->id);
-		}
-	}
-	mutex_unlock(&sdio_ctl_devp->dev_lock);
-
-	file->private_data = NULL;
-	return 0;
-}
-
-static const struct file_operations sdio_ctl_fops = {
-	.owner = THIS_MODULE,
-	.open = sdio_ctl_open,
-	.release = sdio_ctl_release,
-	.read = sdio_ctl_read,
-	.write = sdio_ctl_write,
-	.poll = sdio_ctl_poll,
-	.unlocked_ioctl = sdio_ctl_ioctl,
-};
-
-static int sdio_ctl_probe(struct platform_device *pdev)
-{
-	int i;
-	int r;
-
-	pr_info("%s Begins\n", __func__);
-	for (i = 0; i < NUM_SDIO_CTL_PORTS; ++i) {
-		sdio_ctl_devp[i] = kzalloc(sizeof(struct sdio_ctl_dev),
-					GFP_KERNEL);
-		if (IS_ERR(sdio_ctl_devp[i])) {
-			pr_err("ERROR:%s kmalloc() ENOMEM\n", __func__);
-			r = -ENOMEM;
-			goto error0;
-		}
-
-		sdio_ctl_devp[i]->id = cmux_ch_id[i];
-		sdio_ctl_devp[i]->ref_count = 0;
-
-		mutex_init(&sdio_ctl_devp[i]->dev_lock);
-		init_waitqueue_head(&sdio_ctl_devp[i]->read_wait_queue);
-		init_waitqueue_head(&sdio_ctl_devp[i]->write_wait_queue);
-		mutex_init(&sdio_ctl_devp[i]->rx_lock);
-		INIT_LIST_HEAD(&sdio_ctl_devp[i]->rx_list);
-		sdio_ctl_devp[i]->read_avail = 0;
-	}
-
-	r = alloc_chrdev_region(&sdio_ctl_number, 0, NUM_SDIO_CTL_PORTS,
-				DEVICE_NAME);
-	if (IS_ERR_VALUE(r)) {
-		pr_err("ERROR:%s: alloc_chrdev_region() ret %i.\n",
-		       __func__, r);
-		goto error0;
-	}
-
-	sdio_ctl_classp = class_create(THIS_MODULE, DEVICE_NAME);
-	if (IS_ERR(sdio_ctl_classp)) {
-		pr_err("ERROR:%s: class_create() ENOMEM\n", __func__);
-		r = -ENOMEM;
-		goto error1;
-	}
-
-	for (i = 0; i < NUM_SDIO_CTL_PORTS; ++i) {
-		cdev_init(&sdio_ctl_devp[i]->cdev, &sdio_ctl_fops);
-		sdio_ctl_devp[i]->cdev.owner = THIS_MODULE;
-
-		r = cdev_add(&sdio_ctl_devp[i]->cdev, (sdio_ctl_number + i),
-			     1);
-
-		if (IS_ERR_VALUE(r)) {
-			pr_err("%s: cdev_add() ret %i\n", __func__, r);
-			kfree(sdio_ctl_devp[i]);
-			goto error2;
-		}
-
-		sdio_ctl_devp[i]->devicep =
-				device_create(sdio_ctl_classp, NULL,
-				      (sdio_ctl_number + i), NULL,
-				      DEVICE_NAME "%d", cmux_ch_id[i]);
-
-		if (IS_ERR(sdio_ctl_devp[i]->devicep)) {
-			pr_err("%s: device_create() ENOMEM\n", __func__);
-			r = -ENOMEM;
-			cdev_del(&sdio_ctl_devp[i]->cdev);
-			kfree(sdio_ctl_devp[i]);
-			goto error2;
-		}
-	}
-
-	sdio_ctl_inited = 1;
-	D("SDIO Control Port Driver Initialized.\n");
-	return 0;
-
-error2:
-	while (--i >= 0) {
-		cdev_del(&sdio_ctl_devp[i]->cdev);
-		device_destroy(sdio_ctl_classp,
-			       MKDEV(MAJOR(sdio_ctl_number), i));
-	}
-
-	class_destroy(sdio_ctl_classp);
-	i = NUM_SDIO_CTL_PORTS;
-error1:
-	unregister_chrdev_region(MAJOR(sdio_ctl_number), NUM_SDIO_CTL_PORTS);
-error0:
-	while (--i >= 0)
-		kfree(sdio_ctl_devp[i]);
-	return r;
-}
-
-static int sdio_ctl_remove(struct platform_device *pdev)
-{
-	int i;
-
-	for (i = 0; i < NUM_SDIO_CTL_PORTS; ++i) {
-		cdev_del(&sdio_ctl_devp[i]->cdev);
-		kfree(sdio_ctl_devp[i]);
-		device_destroy(sdio_ctl_classp,
-			       MKDEV(MAJOR(sdio_ctl_number), i));
-	}
-	class_destroy(sdio_ctl_classp);
-	unregister_chrdev_region(MAJOR(sdio_ctl_number), NUM_SDIO_CTL_PORTS);
-
-	return 0;
-}
-
-static struct platform_driver sdio_ctl_driver = {
-	.probe		= sdio_ctl_probe,
-	.remove		= sdio_ctl_remove,
-	.driver		= {
-			.name	= "SDIO_CTL",
-			.owner	= THIS_MODULE,
-	},
-};
-
-static int __init sdio_ctl_init(void)
-{
-	msm_sdio_ctl_debug_mask = 0;
-	return platform_driver_register(&sdio_ctl_driver);
-}
-
-module_init(sdio_ctl_init);
-MODULE_DESCRIPTION("MSM SDIO Control Port");
-MODULE_LICENSE("GPL v2");
diff --git a/arch/arm/mach-msm/sdio_dmux.c b/arch/arm/mach-msm/sdio_dmux.c
deleted file mode 100644
index c6d665d..0000000
--- a/arch/arm/mach-msm/sdio_dmux.c
+++ /dev/null
@@ -1,925 +0,0 @@
-/* Copyright (c) 2010-2011, The Linux Foundation. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 and
- * only version 2 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- */
-
-/*
- *  SDIO DMUX module.
- */
-
-#define DEBUG
-
-#include <linux/delay.h>
-#include <linux/module.h>
-#include <linux/netdevice.h>
-#include <linux/platform_device.h>
-#include <linux/sched.h>
-#include <linux/skbuff.h>
-#include <linux/wakelock.h>
-#include <linux/debugfs.h>
-#include <linux/smp.h>
-#include <linux/cpumask.h>
-
-#include <mach/sdio_al.h>
-#include <mach/sdio_dmux.h>
-
-#define SDIO_CH_LOCAL_OPEN       0x1
-#define SDIO_CH_REMOTE_OPEN      0x2
-#define SDIO_CH_IN_RESET         0x4
-
-#define SDIO_MUX_HDR_MAGIC_NO    0x33fc
-
-#define SDIO_MUX_HDR_CMD_DATA    0
-#define SDIO_MUX_HDR_CMD_OPEN    1
-#define SDIO_MUX_HDR_CMD_CLOSE   2
-
-#define LOW_WATERMARK            2
-#define HIGH_WATERMARK           4
-
-static int msm_sdio_dmux_debug_enable;
-module_param_named(debug_enable, msm_sdio_dmux_debug_enable,
-		   int, S_IRUGO | S_IWUSR | S_IWGRP);
-
-#if defined(DEBUG)
-static uint32_t sdio_dmux_read_cnt;
-static uint32_t sdio_dmux_write_cnt;
-static uint32_t sdio_dmux_write_cpy_cnt;
-static uint32_t sdio_dmux_write_cpy_bytes;
-
-#define DBG(x...) do {		                 \
-		if (msm_sdio_dmux_debug_enable)  \
-			pr_debug(x);	         \
-	} while (0)
-
-#define DBG_INC_READ_CNT(x) do {	                               \
-		sdio_dmux_read_cnt += (x);                             \
-		if (msm_sdio_dmux_debug_enable)                        \
-			pr_debug("%s: total read bytes %u\n",          \
-				 __func__, sdio_dmux_read_cnt);        \
-	} while (0)
-
-#define DBG_INC_WRITE_CNT(x)  do {	                               \
-		sdio_dmux_write_cnt += (x);                            \
-		if (msm_sdio_dmux_debug_enable)                        \
-			pr_debug("%s: total written bytes %u\n",       \
-				 __func__, sdio_dmux_write_cnt);       \
-	} while (0)
-
-#define DBG_INC_WRITE_CPY(x)  do {	                                     \
-		sdio_dmux_write_cpy_bytes += (x);                            \
-		sdio_dmux_write_cpy_cnt++;                                   \
-		if (msm_sdio_dmux_debug_enable)                              \
-			pr_debug("%s: total write copy cnt %u, bytes %u\n",  \
-				 __func__, sdio_dmux_write_cpy_cnt,          \
-				 sdio_dmux_write_cpy_bytes);                 \
-	} while (0)
-#else
-#define DBG(x...) do { } while (0)
-#define DBG_INC_READ_CNT(x...) do { } while (0)
-#define DBG_INC_WRITE_CNT(x...) do { } while (0)
-#define DBG_INC_WRITE_CPY(x...) do { } while (0)
-#endif
-
-struct sdio_ch_info {
-	uint32_t status;
-	void (*receive_cb)(void *, struct sk_buff *);
-	void (*write_done)(void *, struct sk_buff *);
-	void *priv;
-	spinlock_t lock;
-	int num_tx_pkts;
-	int use_wm;
-};
-
-static struct sk_buff_head sdio_mux_write_pool;
-static spinlock_t sdio_mux_write_lock;
-
-static struct sdio_channel *sdio_mux_ch;
-static struct sdio_ch_info sdio_ch[SDIO_DMUX_NUM_CHANNELS];
-struct wake_lock sdio_mux_ch_wakelock;
-static int sdio_mux_initialized;
-static int fatal_error;
-
-struct sdio_mux_hdr {
-	uint16_t magic_num;
-	uint8_t reserved;
-	uint8_t cmd;
-	uint8_t pad_len;
-	uint8_t ch_id;
-	uint16_t pkt_len;
-};
-
-struct sdio_partial_pkt_info {
-	uint32_t valid;
-	struct sk_buff *skb;
-	struct sdio_mux_hdr *hdr;
-};
-
-static void sdio_mux_read_data(struct work_struct *work);
-static void sdio_mux_write_data(struct work_struct *work);
-static void sdio_mux_send_open_cmd(uint32_t id);
-
-static DEFINE_MUTEX(sdio_mux_lock);
-static DECLARE_WORK(work_sdio_mux_read, sdio_mux_read_data);
-static DECLARE_WORK(work_sdio_mux_write, sdio_mux_write_data);
-static DECLARE_DELAYED_WORK(delayed_work_sdio_mux_write, sdio_mux_write_data);
-
-static struct workqueue_struct *sdio_mux_workqueue;
-static struct sdio_partial_pkt_info sdio_partial_pkt;
-
-#define sdio_ch_is_open(x)						\
-	(sdio_ch[(x)].status == (SDIO_CH_LOCAL_OPEN | SDIO_CH_REMOTE_OPEN))
-
-#define sdio_ch_is_local_open(x)			\
-	(sdio_ch[(x)].status & SDIO_CH_LOCAL_OPEN)
-
-#define sdio_ch_is_remote_open(x)			\
-	(sdio_ch[(x)].status & SDIO_CH_REMOTE_OPEN)
-
-#define sdio_ch_is_in_reset(x)			\
-	(sdio_ch[(x)].status & SDIO_CH_IN_RESET)
-
-static inline void skb_set_data(struct sk_buff *skb,
-				unsigned char *data,
-				unsigned int len)
-{
-	/* panic if tail > end */
-	skb->data = data;
-	skb->tail = skb->data + len;
-	skb->len  = len;
-	skb->truesize = len + sizeof(struct sk_buff);
-}
-
-static void sdio_mux_save_partial_pkt(struct sdio_mux_hdr *hdr,
-				      struct sk_buff *skb_mux)
-{
-	struct sk_buff *skb;
-
-	/* i think we can avoid cloning here */
-	skb =  skb_clone(skb_mux, GFP_KERNEL);
-	if (!skb) {
-		pr_err("%s: cannot clone skb\n", __func__);
-		return;
-	}
-
-	/* protect? */
-	skb_set_data(skb, (unsigned char *)hdr,
-		     skb->tail - (unsigned char *)hdr);
-	sdio_partial_pkt.skb = skb;
-	sdio_partial_pkt.valid = 1;
-	DBG("%s: head %p data %p tail %p end %p len %d\n", __func__,
-	    skb->head, skb->data, skb->tail, skb->end, skb->len);
-	return;
-}
-
-static void *handle_sdio_mux_data(struct sdio_mux_hdr *hdr,
-				  struct sk_buff *skb_mux)
-{
-	struct sk_buff *skb;
-	void *rp = (void *)hdr;
-	unsigned long flags;
-
-	/* protect? */
-	rp += sizeof(*hdr);
-	if (rp < (void *)skb_mux->tail)
-		rp += (hdr->pkt_len + hdr->pad_len);
-
-	if (rp > (void *)skb_mux->tail) {
-		/* partial packet */
-		sdio_mux_save_partial_pkt(hdr, skb_mux);
-		goto packet_done;
-	}
-
-	DBG("%s: hdr %p next %p tail %p pkt_size %d\n",
-	    __func__, hdr, rp, skb_mux->tail, hdr->pkt_len + hdr->pad_len);
-
-	skb =  skb_clone(skb_mux, GFP_KERNEL);
-	if (!skb) {
-		pr_err("%s: cannot clone skb\n", __func__);
-		goto packet_done;
-	}
-
-	skb_set_data(skb, (unsigned char *)(hdr + 1), hdr->pkt_len);
-	DBG("%s: head %p data %p tail %p end %p len %d\n",
-	    __func__, skb->head, skb->data, skb->tail, skb->end, skb->len);
-
-	/* probably we should check channel status */
-	/* discard packet early if local side not open */
-	spin_lock_irqsave(&sdio_ch[hdr->ch_id].lock, flags);
-	if (sdio_ch[hdr->ch_id].receive_cb)
-		sdio_ch[hdr->ch_id].receive_cb(sdio_ch[hdr->ch_id].priv, skb);
-	else
-		dev_kfree_skb_any(skb);
-	spin_unlock_irqrestore(&sdio_ch[hdr->ch_id].lock, flags);
-
-packet_done:
-	return rp;
-}
-
-static void *handle_sdio_mux_command(struct sdio_mux_hdr *hdr,
-				     struct sk_buff *skb_mux)
-{
-	void *rp;
-	unsigned long flags;
-	int send_open = 0;
-
-	DBG("%s: cmd %d ch %d\n", __func__, hdr->cmd, hdr->ch_id);
-	switch (hdr->cmd) {
-	case SDIO_MUX_HDR_CMD_DATA:
-		rp = handle_sdio_mux_data(hdr, skb_mux);
-		break;
-	case SDIO_MUX_HDR_CMD_OPEN:
-		spin_lock_irqsave(&sdio_ch[hdr->ch_id].lock, flags);
-		sdio_ch[hdr->ch_id].status |= SDIO_CH_REMOTE_OPEN;
-		sdio_ch[hdr->ch_id].num_tx_pkts = 0;
-
-		if (sdio_ch_is_in_reset(hdr->ch_id)) {
-			DBG("%s: in reset - sending open cmd\n", __func__);
-			sdio_ch[hdr->ch_id].status &= ~SDIO_CH_IN_RESET;
-			send_open = 1;
-		}
-
-		/* notify client so it can update its status */
-		if (sdio_ch[hdr->ch_id].receive_cb)
-			sdio_ch[hdr->ch_id].receive_cb(
-					sdio_ch[hdr->ch_id].priv, NULL);
-
-		if (sdio_ch[hdr->ch_id].write_done)
-			sdio_ch[hdr->ch_id].write_done(
-					sdio_ch[hdr->ch_id].priv, NULL);
-		spin_unlock_irqrestore(&sdio_ch[hdr->ch_id].lock, flags);
-		rp = hdr + 1;
-		if (send_open)
-			sdio_mux_send_open_cmd(hdr->ch_id);
-
-		break;
-	case SDIO_MUX_HDR_CMD_CLOSE:
-		/* probably should drop pending write */
-		spin_lock_irqsave(&sdio_ch[hdr->ch_id].lock, flags);
-		sdio_ch[hdr->ch_id].status &= ~SDIO_CH_REMOTE_OPEN;
-		spin_unlock_irqrestore(&sdio_ch[hdr->ch_id].lock, flags);
-		rp = hdr + 1;
-		break;
-	default:
-		rp = hdr + 1;
-	}
-
-	return rp;
-}
-
-static void *handle_sdio_partial_pkt(struct sk_buff *skb_mux)
-{
-	struct sk_buff *p_skb;
-	struct sdio_mux_hdr *p_hdr;
-	void *ptr, *rp = skb_mux->data;
-
-	/* protoect? */
-	if (sdio_partial_pkt.valid) {
-		p_skb = sdio_partial_pkt.skb;
-
-		ptr = skb_push(skb_mux, p_skb->len);
-		memcpy(ptr, p_skb->data, p_skb->len);
-		sdio_partial_pkt.skb = NULL;
-		sdio_partial_pkt.valid = 0;
-		dev_kfree_skb_any(p_skb);
-
-		DBG("%s: head %p data %p tail %p end %p len %d\n", __func__,
-		    skb_mux->head, skb_mux->data, skb_mux->tail,
-		    skb_mux->end, skb_mux->len);
-
-		p_hdr = (struct sdio_mux_hdr *)skb_mux->data;
-		rp = handle_sdio_mux_command(p_hdr, skb_mux);
-	}
-	return rp;
-}
-
-static void sdio_mux_read_data(struct work_struct *work)
-{
-	struct sk_buff *skb_mux;
-	void *ptr = 0;
-	int sz, rc, len = 0;
-	struct sdio_mux_hdr *hdr;
-	static int workqueue_pinned;
-
-	if (!workqueue_pinned) {
-		struct cpumask cpus;
-
-		cpumask_clear(&cpus);
-		cpumask_set_cpu(0, &cpus);
-
-		if (sched_setaffinity(current->pid, &cpus))
-			pr_err("%s: sdio_dmux set CPU affinity failed\n",
-					__func__);
-		workqueue_pinned = 1;
-	}
-
-	DBG("%s: reading\n", __func__);
-	/* should probably have a separate read lock */
-	mutex_lock(&sdio_mux_lock);
-	sz = sdio_read_avail(sdio_mux_ch);
-	DBG("%s: read avail %d\n", __func__, sz);
-	if (sz <= 0) {
-		if (sz)
-			pr_err("%s: read avail failed %d\n", __func__, sz);
-		mutex_unlock(&sdio_mux_lock);
-		return;
-	}
-
-	/* net_ip_aling is probably not required */
-	if (sdio_partial_pkt.valid)
-		len = sdio_partial_pkt.skb->len;
-
-	/* If allocation fails attempt to get a smaller chunk of mem */
-	do {
-		skb_mux = __dev_alloc_skb(sz + NET_IP_ALIGN + len, GFP_KERNEL);
-		if (skb_mux)
-			break;
-
-		pr_err("%s: cannot allocate skb of size:%d + "
-			"%d (NET_SKB_PAD)\n", __func__,
-			sz + NET_IP_ALIGN + len, NET_SKB_PAD);
-		/* the skb structure adds NET_SKB_PAD bytes to the memory
-		 * request, which may push the actual request above PAGE_SIZE
-		 * in that case, we need to iterate one more time to make sure
-		 * we get the memory request under PAGE_SIZE
-		 */
-		if (sz + NET_IP_ALIGN + len + NET_SKB_PAD <= PAGE_SIZE) {
-			pr_err("%s: allocation failed\n", __func__);
-			mutex_unlock(&sdio_mux_lock);
-			return;
-		}
-		sz /= 2;
-	} while (1);
-
-	skb_reserve(skb_mux, NET_IP_ALIGN + len);
-	ptr = skb_put(skb_mux, sz);
-
-	/* half second wakelock is fine? */
-	wake_lock_timeout(&sdio_mux_ch_wakelock, HZ / 2);
-	rc = sdio_read(sdio_mux_ch, ptr, sz);
-	DBG("%s: read %d\n", __func__, rc);
-	if (rc) {
-		pr_err("%s: sdio read failed %d\n", __func__, rc);
-		dev_kfree_skb_any(skb_mux);
-		mutex_unlock(&sdio_mux_lock);
-		queue_work(sdio_mux_workqueue, &work_sdio_mux_read);
-		return;
-	}
-	mutex_unlock(&sdio_mux_lock);
-
-	DBG_INC_READ_CNT(sz);
-	DBG("%s: head %p data %p tail %p end %p len %d\n", __func__,
-	    skb_mux->head, skb_mux->data, skb_mux->tail,
-	    skb_mux->end, skb_mux->len);
-
-	/* move to a separate function */
-	/* probably do skb_pull instead of pointer adjustment */
-	hdr = handle_sdio_partial_pkt(skb_mux);
-	while ((void *)hdr < (void *)skb_mux->tail) {
-
-		if (((void *)hdr + sizeof(*hdr)) > (void *)skb_mux->tail) {
-			/* handle partial header */
-			sdio_mux_save_partial_pkt(hdr, skb_mux);
-			break;
-		}
-
-		if (hdr->magic_num != SDIO_MUX_HDR_MAGIC_NO) {
-			pr_err("%s: packet error\n", __func__);
-			break;
-		}
-
-		hdr = handle_sdio_mux_command(hdr, skb_mux);
-	}
-	dev_kfree_skb_any(skb_mux);
-
-	DBG("%s: read done\n", __func__);
-	queue_work(sdio_mux_workqueue, &work_sdio_mux_read);
-}
-
-static int sdio_mux_write(struct sk_buff *skb)
-{
-	int rc, sz;
-
-	mutex_lock(&sdio_mux_lock);
-	sz = sdio_write_avail(sdio_mux_ch);
-	DBG("%s: avail %d len %d\n", __func__, sz, skb->len);
-	if (skb->len <= sz) {
-		rc = sdio_write(sdio_mux_ch, skb->data, skb->len);
-		DBG("%s: write returned %d\n", __func__, rc);
-		if (rc == 0)
-			DBG_INC_WRITE_CNT(skb->len);
-	} else
-		rc = -ENOMEM;
-
-	mutex_unlock(&sdio_mux_lock);
-	return rc;
-}
-
-static int sdio_mux_write_cmd(void *data, uint32_t len)
-{
-	int avail, rc;
-	for (;;) {
-		mutex_lock(&sdio_mux_lock);
-		avail = sdio_write_avail(sdio_mux_ch);
-		DBG("%s: avail %d len %d\n", __func__, avail, len);
-		if (avail >= len) {
-			rc = sdio_write(sdio_mux_ch, data, len);
-			DBG("%s: write returned %d\n", __func__, rc);
-			if (!rc) {
-				DBG_INC_WRITE_CNT(len);
-				break;
-			}
-		}
-		mutex_unlock(&sdio_mux_lock);
-		msleep(250);
-	}
-	mutex_unlock(&sdio_mux_lock);
-	return 0;
-}
-
-static void sdio_mux_send_open_cmd(uint32_t id)
-{
-	struct sdio_mux_hdr hdr = {
-		.magic_num = SDIO_MUX_HDR_MAGIC_NO,
-		.cmd = SDIO_MUX_HDR_CMD_OPEN,
-		.reserved = 0,
-		.ch_id = id,
-		.pkt_len = 0,
-		.pad_len = 0
-	};
-
-	sdio_mux_write_cmd((void *)&hdr, sizeof(hdr));
-}
-
-static void sdio_mux_write_data(struct work_struct *work)
-{
-	int rc, reschedule = 0;
-	int notify = 0;
-	struct sk_buff *skb;
-	unsigned long flags;
-	int avail;
-	int ch_id;
-
-	spin_lock_irqsave(&sdio_mux_write_lock, flags);
-	while ((skb = __skb_dequeue(&sdio_mux_write_pool))) {
-		ch_id = ((struct sdio_mux_hdr *)skb->data)->ch_id;
-
-		avail = sdio_write_avail(sdio_mux_ch);
-		if (avail < skb->len) {
-			/* we may have to wait for write avail
-			 * notification from sdio al
-			 */
-			DBG("%s: sdio_write_avail(%d) < skb->len(%d)\n",
-					__func__, avail, skb->len);
-
-			reschedule = 1;
-			break;
-		}
-		spin_unlock_irqrestore(&sdio_mux_write_lock, flags);
-		rc = sdio_mux_write(skb);
-		spin_lock_irqsave(&sdio_mux_write_lock, flags);
-		if (rc == 0) {
-
-			spin_lock(&sdio_ch[ch_id].lock);
-			sdio_ch[ch_id].num_tx_pkts--;
-			spin_unlock(&sdio_ch[ch_id].lock);
-
-			if (sdio_ch[ch_id].write_done)
-				sdio_ch[ch_id].write_done(
-						sdio_ch[ch_id].priv, skb);
-			else
-				dev_kfree_skb_any(skb);
-		} else if (rc == -EAGAIN || rc == -ENOMEM) {
-			/* recoverable error - retry again later */
-			reschedule = 1;
-			break;
-		} else if (rc == -ENODEV) {
-			/*
-			 * sdio_al suffered some kind of fatal error
-			 * prevent future writes and clean up pending ones
-			 */
-			fatal_error = 1;
-			do {
-				ch_id = ((struct sdio_mux_hdr *)
-						skb->data)->ch_id;
-				spin_lock(&sdio_ch[ch_id].lock);
-				sdio_ch[ch_id].num_tx_pkts--;
-				spin_unlock(&sdio_ch[ch_id].lock);
-				dev_kfree_skb_any(skb);
-			} while ((skb = __skb_dequeue(&sdio_mux_write_pool)));
-			spin_unlock_irqrestore(&sdio_mux_write_lock, flags);
-			return;
-		} else {
-			/* unknown error condition - drop the
-			 * skb and reschedule for the
-			 * other skb's
-			 */
-			pr_err("%s: sdio_mux_write error %d"
-				   " for ch %d, skb=%p\n",
-				__func__, rc, ch_id, skb);
-			notify = 1;
-			break;
-		}
-	}
-
-	if (reschedule) {
-		if (sdio_ch_is_in_reset(ch_id)) {
-			notify = 1;
-		} else {
-			__skb_queue_head(&sdio_mux_write_pool, skb);
-			queue_delayed_work(sdio_mux_workqueue,
-					&delayed_work_sdio_mux_write,
-					msecs_to_jiffies(250)
-					);
-		}
-	}
-
-	if (notify) {
-		spin_lock(&sdio_ch[ch_id].lock);
-		sdio_ch[ch_id].num_tx_pkts--;
-		spin_unlock(&sdio_ch[ch_id].lock);
-
-		if (sdio_ch[ch_id].write_done)
-			sdio_ch[ch_id].write_done(
-				sdio_ch[ch_id].priv, skb);
-		else
-			dev_kfree_skb_any(skb);
-	}
-	spin_unlock_irqrestore(&sdio_mux_write_lock, flags);
-}
-
-int msm_sdio_is_channel_in_reset(uint32_t id)
-{
-	int rc = 0;
-
-	if (id >= SDIO_DMUX_NUM_CHANNELS)
-		return -EINVAL;
-
-	if (sdio_ch_is_in_reset(id))
-		rc = 1;
-
-	return rc;
-}
-
-int msm_sdio_dmux_write(uint32_t id, struct sk_buff *skb)
-{
-	int rc = 0;
-	struct sdio_mux_hdr *hdr;
-	unsigned long flags;
-	struct sk_buff *new_skb;
-
-	if (id >= SDIO_DMUX_NUM_CHANNELS)
-		return -EINVAL;
-	if (!skb)
-		return -EINVAL;
-	if (!sdio_mux_initialized)
-		return -ENODEV;
-	if (fatal_error)
-		return -ENODEV;
-
-	DBG("%s: writing to ch %d len %d\n", __func__, id, skb->len);
-	spin_lock_irqsave(&sdio_ch[id].lock, flags);
-	if (sdio_ch_is_in_reset(id)) {
-		spin_unlock_irqrestore(&sdio_ch[id].lock, flags);
-		pr_err("%s: port is in reset: %d\n", __func__,
-				sdio_ch[id].status);
-		return -ENETRESET;
-	}
-	if (!sdio_ch_is_local_open(id)) {
-		spin_unlock_irqrestore(&sdio_ch[id].lock, flags);
-		pr_err("%s: port not open: %d\n", __func__, sdio_ch[id].status);
-		return -ENODEV;
-	}
-	if (sdio_ch[id].use_wm &&
-			(sdio_ch[id].num_tx_pkts >= HIGH_WATERMARK)) {
-		spin_unlock_irqrestore(&sdio_ch[id].lock, flags);
-		pr_err("%s: watermark exceeded: %d\n", __func__, id);
-		return -EAGAIN;
-	}
-	spin_unlock_irqrestore(&sdio_ch[id].lock, flags);
-
-	spin_lock_irqsave(&sdio_mux_write_lock, flags);
-	/* if skb do not have any tailroom for padding,
-	   copy the skb into a new expanded skb */
-	if ((skb->len & 0x3) && (skb_tailroom(skb) < (4 - (skb->len & 0x3)))) {
-		/* revisit, probably dev_alloc_skb and memcpy is effecient */
-		new_skb = skb_copy_expand(skb, skb_headroom(skb),
-					  4 - (skb->len & 0x3), GFP_ATOMIC);
-		if (new_skb == NULL) {
-			pr_err("%s: cannot allocate skb\n", __func__);
-			rc = -ENOMEM;
-			goto write_done;
-		}
-		dev_kfree_skb_any(skb);
-		skb = new_skb;
-		DBG_INC_WRITE_CPY(skb->len);
-	}
-
-	hdr = (struct sdio_mux_hdr *)skb_push(skb, sizeof(struct sdio_mux_hdr));
-
-	/* caller should allocate for hdr and padding
-	   hdr is fine, padding is tricky */
-	hdr->magic_num = SDIO_MUX_HDR_MAGIC_NO;
-	hdr->cmd = SDIO_MUX_HDR_CMD_DATA;
-	hdr->reserved = 0;
-	hdr->ch_id = id;
-	hdr->pkt_len = skb->len - sizeof(struct sdio_mux_hdr);
-	if (skb->len & 0x3)
-		skb_put(skb, 4 - (skb->len & 0x3));
-
-	hdr->pad_len = skb->len - (sizeof(struct sdio_mux_hdr) + hdr->pkt_len);
-
-	DBG("%s: data %p, tail %p skb len %d pkt len %d pad len %d\n",
-	    __func__, skb->data, skb->tail, skb->len,
-	    hdr->pkt_len, hdr->pad_len);
-	__skb_queue_tail(&sdio_mux_write_pool, skb);
-
-	spin_lock(&sdio_ch[id].lock);
-	sdio_ch[id].num_tx_pkts++;
-	spin_unlock(&sdio_ch[id].lock);
-
-	queue_work(sdio_mux_workqueue, &work_sdio_mux_write);
-
-write_done:
-	spin_unlock_irqrestore(&sdio_mux_write_lock, flags);
-	return rc;
-}
-
-int msm_sdio_dmux_open(uint32_t id, void *priv,
-			void (*receive_cb)(void *, struct sk_buff *),
-			void (*write_done)(void *, struct sk_buff *))
-{
-	unsigned long flags;
-
-	DBG("%s: opening ch %d\n", __func__, id);
-	if (!sdio_mux_initialized)
-		return -ENODEV;
-	if (id >= SDIO_DMUX_NUM_CHANNELS)
-		return -EINVAL;
-
-	spin_lock_irqsave(&sdio_ch[id].lock, flags);
-	if (sdio_ch_is_local_open(id)) {
-		pr_info("%s: Already opened %d\n", __func__, id);
-		spin_unlock_irqrestore(&sdio_ch[id].lock, flags);
-		goto open_done;
-	}
-
-	sdio_ch[id].receive_cb = receive_cb;
-	sdio_ch[id].write_done = write_done;
-	sdio_ch[id].priv = priv;
-	sdio_ch[id].status |= SDIO_CH_LOCAL_OPEN;
-	sdio_ch[id].num_tx_pkts = 0;
-	sdio_ch[id].use_wm = 0;
-	spin_unlock_irqrestore(&sdio_ch[id].lock, flags);
-
-	sdio_mux_send_open_cmd(id);
-
-open_done:
-	pr_info("%s: opened ch %d\n", __func__, id);
-	return 0;
-}
-
-int msm_sdio_dmux_close(uint32_t id)
-{
-	struct sdio_mux_hdr hdr;
-	unsigned long flags;
-
-	if (id >= SDIO_DMUX_NUM_CHANNELS)
-		return -EINVAL;
-	DBG("%s: closing ch %d\n", __func__, id);
-	if (!sdio_mux_initialized)
-		return -ENODEV;
-	spin_lock_irqsave(&sdio_ch[id].lock, flags);
-
-	sdio_ch[id].receive_cb = NULL;
-	sdio_ch[id].priv = NULL;
-	sdio_ch[id].status &= ~SDIO_CH_LOCAL_OPEN;
-	sdio_ch[id].status &= ~SDIO_CH_IN_RESET;
-	spin_unlock_irqrestore(&sdio_ch[id].lock, flags);
-
-	hdr.magic_num = SDIO_MUX_HDR_MAGIC_NO;
-	hdr.cmd = SDIO_MUX_HDR_CMD_CLOSE;
-	hdr.reserved = 0;
-	hdr.ch_id = id;
-	hdr.pkt_len = 0;
-	hdr.pad_len = 0;
-
-	sdio_mux_write_cmd((void *)&hdr, sizeof(hdr));
-
-	pr_info("%s: closed ch %d\n", __func__, id);
-	return 0;
-}
-
-static void sdio_mux_notify(void *_dev, unsigned event)
-{
-	DBG("%s: event %d notified\n", __func__, event);
-
-	/* write avail may not be enouogh for a packet, but should be fine */
-	if ((event == SDIO_EVENT_DATA_WRITE_AVAIL) &&
-	    sdio_write_avail(sdio_mux_ch))
-		queue_work(sdio_mux_workqueue, &work_sdio_mux_write);
-
-	if ((event == SDIO_EVENT_DATA_READ_AVAIL) &&
-	    sdio_read_avail(sdio_mux_ch))
-		queue_work(sdio_mux_workqueue, &work_sdio_mux_read);
-}
-
-int msm_sdio_dmux_is_ch_full(uint32_t id)
-{
-	unsigned long flags;
-	int ret;
-
-	if (id >= SDIO_DMUX_NUM_CHANNELS)
-		return -EINVAL;
-
-	spin_lock_irqsave(&sdio_ch[id].lock, flags);
-	sdio_ch[id].use_wm = 1;
-	ret = sdio_ch[id].num_tx_pkts >= HIGH_WATERMARK;
-	DBG("%s: ch %d num tx pkts=%d, HWM=%d\n", __func__,
-			id, sdio_ch[id].num_tx_pkts, ret);
-	if (!sdio_ch_is_local_open(id)) {
-		ret = -ENODEV;
-		pr_err("%s: port not open: %d\n", __func__, sdio_ch[id].status);
-	}
-	spin_unlock_irqrestore(&sdio_ch[id].lock, flags);
-
-	return ret;
-}
-
-int msm_sdio_dmux_is_ch_low(uint32_t id)
-{
-	int ret;
-
-	if (id >= SDIO_DMUX_NUM_CHANNELS)
-		return -EINVAL;
-
-	sdio_ch[id].use_wm = 1;
-	ret = sdio_ch[id].num_tx_pkts <= LOW_WATERMARK;
-	DBG("%s: ch %d num tx pkts=%d, LWM=%d\n", __func__,
-			id, sdio_ch[id].num_tx_pkts, ret);
-	if (!sdio_ch_is_local_open(id)) {
-		ret = -ENODEV;
-		pr_err("%s: port not open: %d\n", __func__, sdio_ch[id].status);
-	}
-
-	return ret;
-}
-
-#ifdef CONFIG_DEBUG_FS
-
-static int debug_tbl(char *buf, int max)
-{
-	int i = 0;
-	int j;
-
-	for (j = 0; j < SDIO_DMUX_NUM_CHANNELS; ++j) {
-		i += scnprintf(buf + i, max - i,
-			"ch%02d  local open=%s  remote open=%s\n",
-			j, sdio_ch_is_local_open(j) ? "Y" : "N",
-			sdio_ch_is_remote_open(j) ? "Y" : "N");
-	}
-
-	return i;
-}
-
-#define DEBUG_BUFMAX 4096
-static char debug_buffer[DEBUG_BUFMAX];
-
-static ssize_t debug_read(struct file *file, char __user *buf,
-				size_t count, loff_t *ppos)
-{
-	int (*fill)(char *buf, int max) = file->private_data;
-	int bsize = fill(debug_buffer, DEBUG_BUFMAX);
-	return simple_read_from_buffer(buf, count, ppos, debug_buffer, bsize);
-}
-
-static int debug_open(struct inode *inode, struct file *file)
-{
-	file->private_data = inode->i_private;
-	return 0;
-}
-
-
-static const struct file_operations debug_ops = {
-	.read = debug_read,
-	.open = debug_open,
-};
-
-static void debug_create(const char *name, mode_t mode,
-				struct dentry *dent,
-				int (*fill)(char *buf, int max))
-{
-	debugfs_create_file(name, mode, dent, fill, &debug_ops);
-}
-
-#endif
-
-static int sdio_dmux_probe(struct platform_device *pdev)
-{
-	int rc;
-
-	DBG("%s probe called\n", __func__);
-
-	if (!sdio_mux_initialized) {
-		sdio_mux_workqueue = create_singlethread_workqueue("sdio_dmux");
-		if (!sdio_mux_workqueue)
-			return -ENOMEM;
-
-		skb_queue_head_init(&sdio_mux_write_pool);
-		spin_lock_init(&sdio_mux_write_lock);
-
-		for (rc = 0; rc < SDIO_DMUX_NUM_CHANNELS; ++rc)
-			spin_lock_init(&sdio_ch[rc].lock);
-
-
-		wake_lock_init(&sdio_mux_ch_wakelock, WAKE_LOCK_SUSPEND,
-				   "sdio_dmux");
-	}
-
-	rc = sdio_open("SDIO_RMNT", &sdio_mux_ch, NULL, sdio_mux_notify);
-	if (rc < 0) {
-		pr_err("%s: sido open failed %d\n", __func__, rc);
-		wake_lock_destroy(&sdio_mux_ch_wakelock);
-		destroy_workqueue(sdio_mux_workqueue);
-		sdio_mux_initialized = 0;
-		return rc;
-	}
-
-	fatal_error = 0;
-	sdio_mux_initialized = 1;
-	return 0;
-}
-
-static int sdio_dmux_remove(struct platform_device *pdev)
-{
-	int i;
-	unsigned long ch_lock_flags;
-	unsigned long write_lock_flags;
-	struct sk_buff *skb;
-
-	DBG("%s remove called\n", __func__);
-	if (!sdio_mux_initialized)
-		return 0;
-
-	/* set reset state for any open channels */
-	for (i = 0; i < SDIO_DMUX_NUM_CHANNELS; ++i) {
-		spin_lock_irqsave(&sdio_ch[i].lock, ch_lock_flags);
-		if (sdio_ch_is_open(i)) {
-			sdio_ch[i].status |= SDIO_CH_IN_RESET;
-			sdio_ch[i].status &= ~SDIO_CH_REMOTE_OPEN;
-
-			/* notify client so it can update its status */
-			if (sdio_ch[i].receive_cb)
-				sdio_ch[i].receive_cb(
-						sdio_ch[i].priv, NULL);
-		}
-		spin_unlock_irqrestore(&sdio_ch[i].lock, ch_lock_flags);
-	}
-
-	/* cancel any pending writes */
-	spin_lock_irqsave(&sdio_mux_write_lock, write_lock_flags);
-	while ((skb = __skb_dequeue(&sdio_mux_write_pool))) {
-		i = ((struct sdio_mux_hdr *)skb->data)->ch_id;
-		if (sdio_ch[i].write_done)
-			sdio_ch[i].write_done(
-					sdio_ch[i].priv, skb);
-		else
-			dev_kfree_skb_any(skb);
-	}
-	spin_unlock_irqrestore(&sdio_mux_write_lock,
-			write_lock_flags);
-
-	return 0;
-}
-
-static struct platform_driver sdio_dmux_driver = {
-	.probe		= sdio_dmux_probe,
-	.remove   = sdio_dmux_remove,
-	.driver		= {
-		.name	= "SDIO_RMNT",
-		.owner	= THIS_MODULE,
-	},
-};
-
-static int __init sdio_dmux_init(void)
-{
-#ifdef CONFIG_DEBUG_FS
-	struct dentry *dent;
-
-	dent = debugfs_create_dir("sdio_dmux", 0);
-	if (!IS_ERR(dent))
-		debug_create("tbl", 0444, dent, debug_tbl);
-#endif
-	return platform_driver_register(&sdio_dmux_driver);
-}
-
-module_init(sdio_dmux_init);
-MODULE_DESCRIPTION("MSM SDIO DMUX");
-MODULE_LICENSE("GPL v2");
diff --git a/arch/arm/mach-msm/sdio_smem.c b/arch/arm/mach-msm/sdio_smem.c
deleted file mode 100644
index edc0d23..0000000
--- a/arch/arm/mach-msm/sdio_smem.c
+++ /dev/null
@@ -1,175 +0,0 @@
-/* Copyright (c) 2010-2011, The Linux Foundation. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 and
- * only version 2 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- */
-
-#define pr_fmt(fmt) "%s: " fmt, __func__
-
-#include <linux/sched.h>
-#include <linux/wait.h>
-#include <linux/workqueue.h>
-#include <linux/module.h>
-#include <mach/sdio_al.h>
-#include <mach/sdio_smem.h>
-
-static void sdio_smem_read(struct work_struct *work);
-
-static struct sdio_channel *channel;
-static struct workqueue_struct *workq;
-static DECLARE_WORK(work_read, sdio_smem_read);
-static DECLARE_WAIT_QUEUE_HEAD(waitq);
-static int bytes_avail;
-static int sdio_ch_opened;
-
-static void sdio_smem_release(struct device *dev)
-{
-	pr_debug("sdio smem released\n");
-}
-
-static struct sdio_smem_client client;
-
-static void sdio_smem_read(struct work_struct *work)
-{
-	int err;
-	int read_avail;
-	char *data = client.buf;
-
-	if (!sdio_ch_opened)
-		return;
-
-	read_avail = sdio_read_avail(channel);
-	if (read_avail > bytes_avail ||
-		read_avail < 0) {
-		pr_err("Error: read_avail=%d bytes_avail=%d\n",
-			read_avail, bytes_avail);
-		goto read_err;
-	}
-
-	if (read_avail == 0)
-		return;
-
-	err = sdio_read(channel,
-			&data[client.size - bytes_avail],
-			read_avail);
-	if (err) {
-		pr_err("sdio_read error (%d)", err);
-		goto read_err;
-	}
-
-	bytes_avail -= read_avail;
-	pr_debug("read %d bytes (bytes_avail = %d)\n",
-			read_avail, bytes_avail);
-
-	if (!bytes_avail) {
-		bytes_avail = client.size;
-		err = client.cb_func(SDIO_SMEM_EVENT_READ_DONE);
-	}
-	if (err)
-		pr_err("error (%d) on callback\n", err);
-
-	return;
-
-read_err:
-	if (sdio_ch_opened)
-		client.cb_func(SDIO_SMEM_EVENT_READ_ERR);
-	return;
-}
-
-static void sdio_smem_notify(void *priv, unsigned event)
-{
-	pr_debug("%d event received\n", event);
-
-	if (event == SDIO_EVENT_DATA_READ_AVAIL ||
-	    event == SDIO_EVENT_DATA_WRITE_AVAIL)
-		queue_work(workq, &work_read);
-}
-
-int sdio_smem_register_client(void)
-{
-	int err = 0;
-
-	if (!client.buf || !client.size || !client.cb_func)
-		return -EINVAL;
-
-	pr_debug("buf = %p\n", client.buf);
-	pr_debug("size = 0x%x\n", client.size);
-
-	bytes_avail = client.size;
-	workq = create_singlethread_workqueue("sdio_smem");
-	if (!workq)
-		return -ENOMEM;
-
-	sdio_ch_opened = 1;
-	err = sdio_open("SDIO_SMEM", &channel, NULL, sdio_smem_notify);
-	if (err) {
-		sdio_ch_opened = 0;
-		pr_err("sdio_open error (%d)\n", err);
-		destroy_workqueue(workq);
-		return err;
-	}
-	pr_debug("SDIO SMEM channel opened\n");
-	return err;
-}
-
-int sdio_smem_unregister_client(void)
-{
-	int err = 0;
-
-	sdio_ch_opened = 0;
-	err = sdio_close(channel);
-	if (err) {
-		pr_err("sdio_close error (%d)\n", err);
-		return err;
-	}
-	pr_debug("SDIO SMEM channel closed\n");
-	flush_workqueue(workq);
-	destroy_workqueue(workq);
-	bytes_avail = 0;
-	client.buf = NULL;
-	client.cb_func = NULL;
-	client.size = 0;
-
-	return 0;
-}
-
-static int sdio_smem_probe(struct platform_device *pdev)
-{
-	client.plat_dev.name = "SDIO_SMEM_CLIENT";
-	client.plat_dev.id = -1;
-	client.plat_dev.dev.release = sdio_smem_release;
-
-	return platform_device_register(&client.plat_dev);
-}
-
-static int sdio_smem_remove(struct platform_device *pdev)
-{
-	platform_device_unregister(&client.plat_dev);
-	memset(&client, 0, sizeof(client));
-	sdio_ch_opened = 0;
-	return 0;
-}
-static struct platform_driver sdio_smem_drv = {
-	.probe		= sdio_smem_probe,
-	.remove		= sdio_smem_remove,
-	.driver		= {
-		.name	= "SDIO_SMEM",
-		.owner	= THIS_MODULE,
-	},
-};
-
-static int __init sdio_smem_init(void)
-{
-	return platform_driver_register(&sdio_smem_drv);
-};
-
-module_init(sdio_smem_init);
-
-MODULE_DESCRIPTION("SDIO SMEM");
-MODULE_LICENSE("GPL v2");
diff --git a/arch/arm/mach-msm/sdio_tty.c b/arch/arm/mach-msm/sdio_tty.c
deleted file mode 100644
index c4b7673..0000000
--- a/arch/arm/mach-msm/sdio_tty.c
+++ /dev/null
@@ -1,824 +0,0 @@
-/* Copyright (c) 2011, The Linux Foundation. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 and
- * only version 2 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- */
-
-#include <linux/slab.h>
-#include <linux/sched.h>
-#include <linux/wait.h>
-#include <linux/workqueue.h>
-#include <linux/platform_device.h>
-#include <linux/tty.h>
-#include <linux/tty_flip.h>
-#include <linux/module.h>
-#include <linux/debugfs.h>
-#include <mach/sdio_al.h>
-
-#define INPUT_SPEED			4800
-#define OUTPUT_SPEED			4800
-#define SDIO_TTY_MODULE_NAME		"sdio_tty"
-#define SDIO_TTY_MAX_PACKET_SIZE	4096
-#define MAX_SDIO_TTY_DRV		1
-#define MAX_SDIO_TTY_DEVS		2
-#define MAX_SDIO_TTY_DEV_NAME_SIZE	25
-
-/* Configurations per channel device */
-/* CSVT */
-#define SDIO_TTY_CSVT_DEV		"sdio_tty_csvt_0"
-#define SDIO_TTY_CSVT_TEST_DEV		"sdio_tty_csvt_test_0"
-#define SDIO_TTY_CH_CSVT		"SDIO_CSVT"
-
-enum sdio_tty_state {
-	TTY_INITIAL = 0,
-	TTY_REGISTERED = 1,
-	TTY_OPENED = 2,
-	TTY_CLOSED = 3,
-};
-
-enum sdio_tty_devices {
-	SDIO_CSVT,
-	SDIO_CSVT_TEST_APP,
-};
-
-static const struct platform_device_id sdio_tty_id_table[] = {
-	{ "SDIO_CSVT",		SDIO_CSVT },
-	{ "SDIO_CSVT_TEST_APP",	SDIO_CSVT_TEST_APP },
-	{ },
-};
-MODULE_DEVICE_TABLE(platform, sdio_tty_id_table);
-
-struct sdio_tty {
-	struct sdio_channel *ch;
-	char *sdio_ch_name;
-	char tty_dev_name[MAX_SDIO_TTY_DEV_NAME_SIZE];
-	int device_id;
-	struct workqueue_struct *workq;
-	struct work_struct work_read;
-	wait_queue_head_t   waitq;
-	struct tty_driver *tty_drv;
-	struct tty_struct *tty_str;
-	int debug_msg_on;
-	char *read_buf;
-	enum sdio_tty_state sdio_tty_state;
-	int is_sdio_open;
-	int tty_open_count;
-	int total_rx;
-	int total_tx;
-};
-
-static struct sdio_tty *sdio_tty[MAX_SDIO_TTY_DEVS];
-
-#ifdef CONFIG_DEBUG_FS
-struct dentry *sdio_tty_debug_root;
-struct dentry *sdio_tty_debug_info;
-#endif
-
-#define DEBUG_MSG(sdio_tty_drv, x...) if (sdio_tty_drv->debug_msg_on) pr_info(x)
-
-/*
- * Enable sdio_tty debug messages
- * By default the sdio_tty debug messages are turned off
- */
-static int csvt_debug_msg_on;
-module_param(csvt_debug_msg_on, int, 0);
-
-static void sdio_tty_read(struct work_struct *work)
-{
-	int ret = 0;
-	int read_avail = 0;
-	int left = 0;
-	int total_push = 0;
-	int num_push = 0;
-	struct sdio_tty *sdio_tty_drv = NULL;
-
-	sdio_tty_drv = container_of(work, struct sdio_tty, work_read);
-
-	if (!sdio_tty_drv) {
-		pr_err(SDIO_TTY_MODULE_NAME ": %s: NULL sdio_tty", __func__);
-		return ;
-	}
-
-	if (sdio_tty_drv->sdio_tty_state != TTY_OPENED) {
-		pr_err(SDIO_TTY_MODULE_NAME ": %s: sdio_tty_state = %d",
-			__func__, sdio_tty_drv->sdio_tty_state);
-		return;
-	}
-
-	if (!sdio_tty_drv->read_buf) {
-		pr_err(SDIO_TTY_MODULE_NAME ": %s: NULL read_buf for dev %s",
-			__func__, sdio_tty_drv->tty_dev_name);
-		return;
-	}
-
-	/* Read the data from the SDIO channel as long as there is available
-	   data */
-	while (1) {
-		if (test_bit(TTY_THROTTLED, &sdio_tty_drv->tty_str->flags)) {
-			DEBUG_MSG(sdio_tty_drv, SDIO_TTY_MODULE_NAME
-					": %s: TTY_THROTTLED bit is set for "
-					"dev %s, exit", __func__,
-					sdio_tty_drv->tty_dev_name);
-			return;
-		}
-
-		total_push = 0;
-		read_avail = sdio_read_avail(sdio_tty_drv->ch);
-
-		DEBUG_MSG(sdio_tty_drv, SDIO_TTY_MODULE_NAME
-				": %s: read_avail is %d for dev %s", __func__,
-				read_avail, sdio_tty_drv->tty_dev_name);
-
-		if (read_avail == 0) {
-			DEBUG_MSG(sdio_tty_drv, SDIO_TTY_MODULE_NAME
-					": %s: read_avail is 0 for dev %s",
-					__func__, sdio_tty_drv->tty_dev_name);
-			return;
-		}
-
-		if (read_avail > SDIO_TTY_MAX_PACKET_SIZE) {
-			pr_err(SDIO_TTY_MODULE_NAME ": %s: read_avail(%d) is "
-				"bigger than SDIO_TTY_MAX_PACKET_SIZE(%d) "
-				"for dev %s", __func__, read_avail,
-				SDIO_TTY_MAX_PACKET_SIZE,
-				sdio_tty_drv->tty_dev_name);
-			return;
-		}
-
-		ret = sdio_read(sdio_tty_drv->ch,
-				sdio_tty_drv->read_buf,
-				read_avail);
-		if (ret < 0) {
-			pr_err(SDIO_TTY_MODULE_NAME ": %s: sdio_read error(%d) "
-				"for dev %s", __func__, ret,
-				sdio_tty_drv->tty_dev_name);
-			return;
-		}
-
-		left = read_avail;
-		do {
-			num_push = tty_insert_flip_string(
-				sdio_tty_drv->tty_str,
-				sdio_tty_drv->read_buf+total_push,
-				left);
-			total_push += num_push;
-			left -= num_push;
-			tty_flip_buffer_push(sdio_tty_drv->tty_str);
-		} while (left != 0);
-
-		if (total_push != read_avail) {
-			pr_err(SDIO_TTY_MODULE_NAME ": %s: failed, total_push"
-				"(%d) != read_avail(%d) for dev %s\n",
-				__func__, total_push, read_avail,
-				sdio_tty_drv->tty_dev_name);
-		}
-
-		tty_flip_buffer_push(sdio_tty_drv->tty_str);
-		sdio_tty_drv->total_rx += read_avail;
-
-		DEBUG_MSG(sdio_tty_drv, SDIO_TTY_MODULE_NAME ": %s: Rx: %d, "
-				"Total Rx = %d bytes for dev %s", __func__,
-				read_avail, sdio_tty_drv->total_rx,
-				sdio_tty_drv->tty_dev_name);
-	}
-}
-
-/**
-  * sdio_tty_write_room
-  *
-  * This is the write_room function of the tty driver.
-  *
-  * @tty: pointer to tty struct.
-  * @return free bytes for write.
-  *
-  */
-static int sdio_tty_write_room(struct tty_struct *tty)
-{
-	int write_avail = 0;
-	struct sdio_tty *sdio_tty_drv = NULL;
-
-	if (!tty) {
-		pr_err(SDIO_TTY_MODULE_NAME ": %s: NULL tty", __func__);
-		return -ENODEV;
-	}
-	sdio_tty_drv = tty->driver_data;
-	if (!sdio_tty_drv) {
-		pr_err(SDIO_TTY_MODULE_NAME ": %s: NULL sdio_tty_drv",
-			__func__);
-		return -ENODEV;
-	}
-
-	if (sdio_tty_drv->sdio_tty_state != TTY_OPENED) {
-		pr_err(SDIO_TTY_MODULE_NAME ": %s: sdio_tty_state = %d",
-			__func__, sdio_tty_drv->sdio_tty_state);
-		return -EPERM;
-	}
-
-	write_avail = sdio_write_avail(sdio_tty_drv->ch);
-	DEBUG_MSG(sdio_tty_drv, SDIO_TTY_MODULE_NAME ": %s: write_avail=%d "
-			"for dev %s", __func__, write_avail,
-			sdio_tty_drv->tty_dev_name);
-
-	return write_avail;
-}
-
-/**
-  * sdio_tty_write_callback
-  * this is the write callback of the tty driver.
-  *
-  * @tty: pointer to tty struct.
-  * @buf: buffer to write from.
-  * @count: number of bytes to write.
-  * @return bytes written or negative value on error.
-  *
-  * if destination buffer has not enough room for the incoming
-  * data, writes the possible amount of bytes .
-  */
-static int sdio_tty_write_callback(struct tty_struct *tty,
-				   const unsigned char *buf, int count)
-{
-	int write_avail = 0;
-	int len = count;
-	int ret = 0;
-	struct sdio_tty *sdio_tty_drv = NULL;
-
-	if (!tty) {
-		pr_err(SDIO_TTY_MODULE_NAME ": %s: NULL tty", __func__);
-		return -ENODEV;
-	}
-	sdio_tty_drv = tty->driver_data;
-	if (!sdio_tty_drv) {
-		pr_err(SDIO_TTY_MODULE_NAME ": %s: NULL sdio_tty_drv",
-			__func__);
-		return -ENODEV;
-	}
-
-	if (sdio_tty_drv->sdio_tty_state != TTY_OPENED) {
-		pr_err(SDIO_TTY_MODULE_NAME ": %s: sdio_tty_state = %d",
-			__func__, sdio_tty_drv->sdio_tty_state);
-		return -EPERM;
-	}
-
-	DEBUG_MSG(sdio_tty_drv, SDIO_TTY_MODULE_NAME ": %s: Write Callback "
-			"called with %d bytes for dev %s\n", __func__, count,
-			sdio_tty_drv->tty_dev_name);
-	write_avail = sdio_write_avail(sdio_tty_drv->ch);
-	if (write_avail == 0) {
-		DEBUG_MSG(sdio_tty_drv, SDIO_TTY_MODULE_NAME ": %s: "
-				"write_avail is 0 for dev %s\n",
-				__func__, sdio_tty_drv->tty_dev_name);
-		return 0;
-	}
-	if (write_avail > SDIO_TTY_MAX_PACKET_SIZE) {
-		DEBUG_MSG(sdio_tty_drv, SDIO_TTY_MODULE_NAME ": %s: "
-				"write_avail(%d) is bigger than max packet "
-				"size(%d) for dev %s, setting to "
-				"max_packet_size\n", __func__, write_avail,
-				SDIO_TTY_MAX_PACKET_SIZE,
-				sdio_tty_drv->tty_dev_name);
-		write_avail = SDIO_TTY_MAX_PACKET_SIZE;
-	}
-	if (write_avail < count) {
-		DEBUG_MSG(sdio_tty_drv, SDIO_TTY_MODULE_NAME ": %s: "
-				"write_avail(%d) is smaller than required(%d) "
-				"for dev %s, writing only %d bytes\n",
-				__func__, write_avail, count,
-				sdio_tty_drv->tty_dev_name, write_avail);
-		len = write_avail;
-	}
-	ret = sdio_write(sdio_tty_drv->ch, buf, len);
-	if (ret) {
-		pr_err(SDIO_TTY_MODULE_NAME ": %s: sdio_write failed for "
-			"dev %s, ret=%d\n", __func__,
-			sdio_tty_drv->tty_dev_name, ret);
-		return 0;
-	}
-
-	sdio_tty_drv->total_tx += len;
-
-	DEBUG_MSG(sdio_tty_drv, SDIO_TTY_MODULE_NAME ": %s: Tx: %d, "
-			"Total Tx = %d for dev %s", __func__, len,
-			sdio_tty_drv->total_tx, sdio_tty_drv->tty_dev_name);
-	return len;
-}
-
-static void sdio_tty_notify(void *priv, unsigned event)
-{
-	struct sdio_tty *sdio_tty_drv = priv;
-
-	if (!sdio_tty_drv) {
-		pr_err(SDIO_TTY_MODULE_NAME ": %s: NULL sdio_tty_drv",
-			__func__);
-	}
-
-	if (sdio_tty_drv->sdio_tty_state != TTY_OPENED) {
-		pr_err(SDIO_TTY_MODULE_NAME ": %s: sdio_tty_state = %d",
-			__func__, sdio_tty_drv->sdio_tty_state);
-		return;
-	}
-
-	DEBUG_MSG(sdio_tty_drv, SDIO_TTY_MODULE_NAME ": %s: event %d "
-			"received for dev %s\n", __func__, event,
-			sdio_tty_drv->tty_dev_name);
-
-	if (event == SDIO_EVENT_DATA_READ_AVAIL)
-		queue_work(sdio_tty_drv->workq, &sdio_tty_drv->work_read);
-}
-
-/**
-  * sdio_tty_open
-  * This is the open callback of the tty driver. it opens
-  * the sdio channel, and creates the workqueue.
-  *
-  * @tty: a pointer to the tty struct.
-  * @file: file descriptor.
-  * @return 0 on success or negative value on error.
-  */
-static int sdio_tty_open(struct tty_struct *tty, struct file *file)
-{
-	int ret = 0;
-	int i = 0;
-	struct sdio_tty *sdio_tty_drv = NULL;
-
-	if (!tty) {
-		pr_err(SDIO_TTY_MODULE_NAME ": %s: NULL tty", __func__);
-		return -ENODEV;
-	}
-
-	for (i = 0; i < MAX_SDIO_TTY_DEVS; i++) {
-		if (sdio_tty[i] == NULL)
-			continue;
-		if (!strncmp(sdio_tty[i]->tty_dev_name, tty->name,
-				MAX_SDIO_TTY_DEV_NAME_SIZE)) {
-			sdio_tty_drv = sdio_tty[i];
-			break;
-		}
-	}
-
-	if (!sdio_tty_drv) {
-		pr_err(SDIO_TTY_MODULE_NAME ": %s: NULL sdio_tty_drv",
-		       __func__);
-		return -ENODEV;
-	}
-
-	sdio_tty_drv->tty_open_count++;
-	if (sdio_tty_drv->sdio_tty_state == TTY_OPENED) {
-		pr_err(SDIO_TTY_MODULE_NAME ": %s: tty dev(%s) is already open",
-			__func__, sdio_tty_drv->tty_dev_name);
-		return -EBUSY;
-	}
-
-	tty->driver_data = sdio_tty_drv;
-
-	sdio_tty_drv->tty_str = tty;
-	sdio_tty_drv->tty_str->low_latency = 1;
-	sdio_tty_drv->tty_str->icanon = 0;
-	set_bit(TTY_NO_WRITE_SPLIT, &sdio_tty_drv->tty_str->flags);
-
-	sdio_tty_drv->read_buf = kzalloc(SDIO_TTY_MAX_PACKET_SIZE, GFP_KERNEL);
-	if (sdio_tty_drv->read_buf == NULL) {
-		pr_err(SDIO_TTY_MODULE_NAME ": %s: failed to allocate read_buf "
-			"for dev %s", __func__, sdio_tty_drv->tty_dev_name);
-		return -ENOMEM;
-	}
-
-	sdio_tty_drv->workq = create_singlethread_workqueue("sdio_tty_read");
-	if (!sdio_tty_drv->workq) {
-		pr_err(SDIO_TTY_MODULE_NAME ": %s: failed to create workq "
-			"for dev %s", __func__, sdio_tty_drv->tty_dev_name);
-		return -ENOMEM;
-	}
-
-	if (!sdio_tty_drv->is_sdio_open) {
-		ret = sdio_open(sdio_tty_drv->sdio_ch_name, &sdio_tty_drv->ch,
-				sdio_tty_drv, sdio_tty_notify);
-		if (ret < 0) {
-			pr_err(SDIO_TTY_MODULE_NAME ": %s: sdio_open err=%d "
-				"for dev %s\n", __func__, ret,
-				sdio_tty_drv->tty_dev_name);
-			destroy_workqueue(sdio_tty_drv->workq);
-			return ret;
-		}
-
-		pr_info(SDIO_TTY_MODULE_NAME ": %s: SDIO_TTY channel(%s) "
-			"opened\n", __func__, sdio_tty_drv->sdio_ch_name);
-
-		sdio_tty_drv->is_sdio_open = 1;
-	} else {
-		/* If SDIO channel is already open try to read the data
-		 * from the modem
-		 */
-		queue_work(sdio_tty_drv->workq, &sdio_tty_drv->work_read);
-
-	}
-
-	sdio_tty_drv->sdio_tty_state = TTY_OPENED;
-
-	pr_info(SDIO_TTY_MODULE_NAME ": %s: TTY device(%s) opened\n",
-		__func__, sdio_tty_drv->tty_dev_name);
-
-	return ret;
-}
-
-/**
-  * sdio_tty_close
-  * This is the close callback of the tty driver. it requests
-  * the main thread to exit, and waits for notification of it.
-  * it also de-allocates the buffers, and unregisters the tty
-  * driver and device.
-  *
-  * @tty: a pointer to the tty struct.
-  * @file: file descriptor.
-  * @return None.
-  */
-static void sdio_tty_close(struct tty_struct *tty, struct file *file)
-{
-	struct sdio_tty *sdio_tty_drv = NULL;
-
-	if (!tty) {
-		pr_err(SDIO_TTY_MODULE_NAME ": %s: NULL tty", __func__);
-		return;
-	}
-	sdio_tty_drv = tty->driver_data;
-	if (!sdio_tty_drv) {
-		pr_err(SDIO_TTY_MODULE_NAME ": %s: NULL sdio_tty_drv",
-		       __func__);
-		return;
-	}
-	if (sdio_tty_drv->sdio_tty_state != TTY_OPENED) {
-		pr_err(SDIO_TTY_MODULE_NAME ": %s: trying to close a "
-			"TTY device that was not opened\n", __func__);
-		return;
-	}
-	if (--sdio_tty_drv->tty_open_count != 0)
-		return;
-
-	flush_workqueue(sdio_tty_drv->workq);
-	destroy_workqueue(sdio_tty_drv->workq);
-
-	kfree(sdio_tty_drv->read_buf);
-	sdio_tty_drv->read_buf = NULL;
-
-	sdio_tty_drv->sdio_tty_state = TTY_CLOSED;
-
-	pr_info(SDIO_TTY_MODULE_NAME ": %s: SDIO_TTY device(%s) closed\n",
-		__func__, sdio_tty_drv->tty_dev_name);
-}
-
-static void sdio_tty_unthrottle(struct tty_struct *tty)
-{
-	struct sdio_tty *sdio_tty_drv = NULL;
-
-	if (!tty) {
-		pr_err(SDIO_TTY_MODULE_NAME ": %s: NULL tty", __func__);
-		return;
-	}
-	sdio_tty_drv = tty->driver_data;
-	if (!sdio_tty_drv) {
-		pr_err(SDIO_TTY_MODULE_NAME ": %s: NULL sdio_tty_drv",
-		       __func__);
-		return;
-	}
-
-	if (sdio_tty_drv->sdio_tty_state != TTY_OPENED) {
-		pr_err(SDIO_TTY_MODULE_NAME ": %s: sdio_tty_state = %d",
-		       __func__, sdio_tty_drv->sdio_tty_state);
-		return;
-	}
-
-	queue_work(sdio_tty_drv->workq, &sdio_tty_drv->work_read);
-	return;
-}
-
-static const struct tty_operations sdio_tty_ops = {
-	.open = sdio_tty_open,
-	.close = sdio_tty_close,
-	.write = sdio_tty_write_callback,
-	.write_room = sdio_tty_write_room,
-	.unthrottle = sdio_tty_unthrottle,
-};
-
-int sdio_tty_init_tty(char *tty_name, char *sdio_ch_name,
-			enum sdio_tty_devices device_id, int debug_msg_on)
-{
-	int ret = 0;
-	int i = 0;
-	struct device *tty_dev = NULL;
-	struct sdio_tty *sdio_tty_drv = NULL;
-
-	sdio_tty_drv = kzalloc(sizeof(struct sdio_tty), GFP_KERNEL);
-	if (sdio_tty_drv == NULL) {
-		pr_err(SDIO_TTY_MODULE_NAME ": %s: failed to allocate sdio_tty "
-			"for dev %s", __func__, tty_name);
-		return -ENOMEM;
-	}
-
-	for (i = 0; i < MAX_SDIO_TTY_DEVS; i++) {
-		if (sdio_tty[i] == NULL) {
-			sdio_tty[i] = sdio_tty_drv;
-			break;
-		}
-	}
-
-	if (i == MAX_SDIO_TTY_DEVS) {
-		pr_err(SDIO_TTY_MODULE_NAME ": %s: tty dev(%s) creation failed,"
-			" max limit(%d) reached.", __func__, tty_name,
-			MAX_SDIO_TTY_DEVS);
-		kfree(sdio_tty_drv);
-		return -ENODEV;
-	}
-
-	snprintf(sdio_tty_drv->tty_dev_name, MAX_SDIO_TTY_DEV_NAME_SIZE,
-			"%s%d", tty_name, 0);
-	sdio_tty_drv->sdio_ch_name = sdio_ch_name;
-	sdio_tty_drv->device_id = device_id;
-	pr_info(SDIO_TTY_MODULE_NAME ": %s: dev=%s, id=%d, channel=%s\n",
-		__func__, sdio_tty_drv->tty_dev_name, sdio_tty_drv->device_id,
-		sdio_tty_drv->sdio_ch_name);
-
-	INIT_WORK(&sdio_tty_drv->work_read, sdio_tty_read);
-
-	sdio_tty_drv->tty_drv = alloc_tty_driver(MAX_SDIO_TTY_DRV);
-
-	if (!sdio_tty_drv->tty_drv) {
-		pr_err(SDIO_TTY_MODULE_NAME ": %s - tty_drv is NULL for dev %s",
-			__func__, sdio_tty_drv->tty_dev_name);
-		kfree(sdio_tty_drv);
-		return -ENODEV;
-	}
-
-	sdio_tty_drv->tty_drv->name = tty_name;
-	sdio_tty_drv->tty_drv->owner = THIS_MODULE;
-	sdio_tty_drv->tty_drv->driver_name = "SDIO_tty";
-	/* uses dynamically assigned dev_t values */
-	sdio_tty_drv->tty_drv->type = TTY_DRIVER_TYPE_SERIAL;
-	sdio_tty_drv->tty_drv->subtype = SERIAL_TYPE_NORMAL;
-	sdio_tty_drv->tty_drv->flags = TTY_DRIVER_REAL_RAW
-		| TTY_DRIVER_DYNAMIC_DEV
-		| TTY_DRIVER_RESET_TERMIOS;
-
-	/* initializing the tty driver */
-	sdio_tty_drv->tty_drv->init_termios = tty_std_termios;
-	sdio_tty_drv->tty_drv->init_termios.c_cflag =
-		B4800 | CS8 | CREAD | HUPCL | CLOCAL;
-	sdio_tty_drv->tty_drv->init_termios.c_ispeed = INPUT_SPEED;
-	sdio_tty_drv->tty_drv->init_termios.c_ospeed = OUTPUT_SPEED;
-
-	tty_set_operations(sdio_tty_drv->tty_drv, &sdio_tty_ops);
-
-	ret = tty_register_driver(sdio_tty_drv->tty_drv);
-	if (ret) {
-		put_tty_driver(sdio_tty_drv->tty_drv);
-		pr_err(SDIO_TTY_MODULE_NAME ": %s: tty_register_driver() "
-			"failed for dev %s\n", __func__,
-			sdio_tty_drv->tty_dev_name);
-
-		sdio_tty_drv->tty_drv = NULL;
-		kfree(sdio_tty_drv);
-		return -ENODEV;
-	}
-
-	tty_dev = tty_register_device(sdio_tty_drv->tty_drv, 0, NULL);
-	if (IS_ERR(tty_dev)) {
-		pr_err(SDIO_TTY_MODULE_NAME ": %s: tty_register_device() "
-			"failed for dev %s\n", __func__,
-			sdio_tty_drv->tty_dev_name);
-		tty_unregister_driver(sdio_tty_drv->tty_drv);
-		put_tty_driver(sdio_tty_drv->tty_drv);
-		kfree(sdio_tty_drv);
-		return -ENODEV;
-	}
-
-	sdio_tty_drv->sdio_tty_state = TTY_REGISTERED;
-	if (debug_msg_on) {
-		pr_info(SDIO_TTY_MODULE_NAME ": %s: turn on debug msg for %s",
-			__func__, sdio_tty_drv->tty_dev_name);
-		sdio_tty_drv->debug_msg_on = debug_msg_on;
-	}
-	return 0;
-}
-
-int sdio_tty_uninit_tty(void *sdio_tty_handle)
-{
-	int ret = 0;
-	int i = 0;
-	struct sdio_tty *sdio_tty_drv = sdio_tty_handle;
-
-	if (!sdio_tty_drv) {
-		pr_err(SDIO_TTY_MODULE_NAME ": %s: NULL sdio_tty_drv",
-		       __func__);
-		return -ENODEV;
-	}
-	if (sdio_tty_drv->sdio_tty_state == TTY_OPENED) {
-		flush_workqueue(sdio_tty_drv->workq);
-		destroy_workqueue(sdio_tty_drv->workq);
-
-		kfree(sdio_tty_drv->read_buf);
-		sdio_tty_drv->read_buf = NULL;
-	}
-
-	if (sdio_tty_drv->sdio_tty_state != TTY_INITIAL) {
-		tty_unregister_device(sdio_tty_drv->tty_drv, 0);
-
-		ret = tty_unregister_driver(sdio_tty_drv->tty_drv);
-		if (ret) {
-			pr_err(SDIO_TTY_MODULE_NAME ": %s: "
-				"tty_unregister_driver() failed for dev %s\n",
-				__func__, sdio_tty_drv->tty_dev_name);
-		}
-		put_tty_driver(sdio_tty_drv->tty_drv);
-		sdio_tty_drv->sdio_tty_state = TTY_INITIAL;
-		sdio_tty_drv->tty_drv = NULL;
-	}
-
-	for (i = 0; i < MAX_SDIO_TTY_DEVS; i++) {
-		if (sdio_tty[i] == NULL)
-			continue;
-		if (sdio_tty[i]->device_id == sdio_tty_drv->device_id) {
-			sdio_tty[i] = NULL;
-			break;
-		}
-	}
-
-	DEBUG_MSG(sdio_tty_drv, SDIO_TTY_MODULE_NAME ": %s: Freeing sdio_tty "
-			"structure, dev=%s", __func__,
-			sdio_tty_drv->tty_dev_name);
-	kfree(sdio_tty_drv);
-
-	return 0;
-}
-
-static int sdio_tty_probe(struct platform_device *pdev)
-{
-	const struct platform_device_id *id = platform_get_device_id(pdev);
-	enum sdio_tty_devices device_id = id->driver_data;
-	char *device_name = NULL;
-	char *channel_name = NULL;
-	int debug_msg_on = 0;
-	int ret = 0;
-
-	pr_debug(SDIO_TTY_MODULE_NAME ": %s for %s", __func__, pdev->name);
-
-	switch (device_id) {
-	case SDIO_CSVT:
-		device_name = SDIO_TTY_CSVT_DEV;
-		channel_name = SDIO_TTY_CH_CSVT;
-		debug_msg_on = csvt_debug_msg_on;
-		break;
-	case SDIO_CSVT_TEST_APP:
-		device_name = SDIO_TTY_CSVT_TEST_DEV;
-		channel_name = SDIO_TTY_CH_CSVT;
-		debug_msg_on = csvt_debug_msg_on;
-		break;
-	default:
-		pr_err(SDIO_TTY_MODULE_NAME ": %s Invalid device:%s, id:%d",
-			__func__, pdev->name, device_id);
-		ret = -ENODEV;
-		break;
-	}
-
-	if (device_name) {
-		ret = sdio_tty_init_tty(device_name, channel_name,
-					device_id, debug_msg_on);
-		if (ret) {
-			pr_err(SDIO_TTY_MODULE_NAME ": %s: sdio_tty_init_tty "
-				"failed for dev:%s", __func__, device_name);
-		}
-	}
-	return ret;
-}
-
-static int sdio_tty_remove(struct platform_device *pdev)
-{
-	const struct platform_device_id *id = platform_get_device_id(pdev);
-	enum sdio_tty_devices device_id = id->driver_data;
-	struct sdio_tty *sdio_tty_drv = NULL;
-	int i = 0;
-	int ret = 0;
-
-	pr_debug(SDIO_TTY_MODULE_NAME ": %s for %s", __func__, pdev->name);
-
-	for (i = 0; i < MAX_SDIO_TTY_DEVS; i++) {
-		if (sdio_tty[i] == NULL)
-			continue;
-		if (sdio_tty[i]->device_id == device_id) {
-			sdio_tty_drv = sdio_tty[i];
-			break;
-		}
-	}
-
-	if (!sdio_tty_drv) {
-		pr_err(SDIO_TTY_MODULE_NAME ": %s: NULL sdio_tty_drv",
-		       __func__);
-		return -ENODEV;
-	}
-
-	ret = sdio_tty_uninit_tty(sdio_tty_drv);
-	if (ret) {
-		pr_err(SDIO_TTY_MODULE_NAME ": %s: sdio_tty_uninit_tty "
-			"failed for %s", __func__, pdev->name);
-	}
-	return ret;
-}
-
-static struct platform_driver sdio_tty_pdrv = {
-	.probe		= sdio_tty_probe,
-	.remove		= sdio_tty_remove,
-	.id_table	= sdio_tty_id_table,
-	.driver		= {
-		.name	= "SDIO_TTY",
-		.owner	= THIS_MODULE,
-	},
-};
-
-#ifdef CONFIG_DEBUG_FS
-void sdio_tty_print_info(void)
-{
-	int i = 0;
-
-	for (i = 0; i < MAX_SDIO_TTY_DEVS; i++) {
-		if (sdio_tty[i] == NULL)
-			continue;
-		pr_info(SDIO_TTY_MODULE_NAME ": %s: Total Rx=%d, Tx = %d "
-			"for dev %s", __func__, sdio_tty[i]->total_rx,
-			sdio_tty[i]->total_tx, sdio_tty[i]->tty_dev_name);
-	}
-}
-
-static int tty_debug_info_open(struct inode *inode, struct file *file)
-{
-	file->private_data = inode->i_private;
-	return 0;
-}
-
-static ssize_t tty_debug_info_write(struct file *file,
-		const char __user *buf, size_t count, loff_t *ppos)
-{
-	sdio_tty_print_info();
-	return count;
-}
-
-const struct file_operations tty_debug_info_ops = {
-	.open = tty_debug_info_open,
-	.write = tty_debug_info_write,
-};
-#endif
-
-/*
- *  Module Init.
- *
- *  Register SDIO TTY driver.
- *
- */
-static int __init sdio_tty_init(void)
-{
-	int ret = 0;
-
-	ret = platform_driver_register(&sdio_tty_pdrv);
-	if (ret) {
-		pr_err(SDIO_TTY_MODULE_NAME ": %s: platform_driver_register "
-					    "failed", __func__);
-	}
-#ifdef CONFIG_DEBUG_FS
-	else {
-		sdio_tty_debug_root = debugfs_create_dir("sdio_tty", NULL);
-		if (sdio_tty_debug_root) {
-			sdio_tty_debug_info = debugfs_create_file(
-							"sdio_tty_debug",
-							S_IRUGO | S_IWUGO,
-							sdio_tty_debug_root,
-							NULL,
-							&tty_debug_info_ops);
-		}
-	}
-#endif
-	return ret;
-};
-
-/*
- *  Module Exit.
- *
- *  Unregister SDIO TTY driver.
- *
- */
-static void __exit sdio_tty_exit(void)
-{
-#ifdef CONFIG_DEBUG_FS
-	debugfs_remove(sdio_tty_debug_info);
-	debugfs_remove(sdio_tty_debug_root);
-#endif
-	platform_driver_unregister(&sdio_tty_pdrv);
-}
-
-module_init(sdio_tty_init);
-module_exit(sdio_tty_exit);
-
-MODULE_DESCRIPTION("SDIO TTY");
-MODULE_LICENSE("GPL v2");
-MODULE_AUTHOR("Maya Erez <merez@codeaurora.org>");
diff --git a/drivers/base/bus.c b/drivers/base/bus.c
index b850cec..feb30c1 100644
--- a/drivers/base/bus.c
+++ b/drivers/base/bus.c
@@ -715,12 +715,12 @@
 	if (error)
 		goto out_unregister;
 
+	klist_add_tail(&priv->knode_bus, &bus->p->klist_drivers);
 	if (drv->bus->p->drivers_autoprobe) {
 		error = driver_attach(drv);
 		if (error)
 			goto out_unregister;
 	}
-	klist_add_tail(&priv->knode_bus, &bus->p->klist_drivers);
 	module_add_driver(drv->owner, drv);
 
 	error = driver_create_file(drv, &driver_attr_uevent);
diff --git a/drivers/char/adsprpc.c b/drivers/char/adsprpc.c
index 8e68acd..0be61e8 100644
--- a/drivers/char/adsprpc.c
+++ b/drivers/char/adsprpc.c
@@ -91,7 +91,7 @@
 	int n = -1, err = 0;
 
 	VERIFY(err, 0 != access_ok(access ? VERIFY_WRITE : VERIFY_READ,
-			      (void __user *)start, len));
+					(void __user *)start, len));
 	if (err)
 		goto bail;
 	VERIFY(err, 0 != (vma = find_vma(current->mm, start)));
@@ -162,8 +162,8 @@
 {
 	struct fastrpc_apps *me = &gfa;
 
-	if (buf->handle) {
-		if (buf->virt) {
+	if (!IS_ERR_OR_NULL(buf->handle)) {
+		if (!IS_ERR_OR_NULL(buf->virt)) {
 			ion_unmap_kernel(me->iclient, buf->handle);
 			buf->virt = 0;
 		}
@@ -183,8 +183,8 @@
 	VERIFY(err, 0 == IS_ERR_OR_NULL(buf->handle));
 	if (err)
 		goto bail;
-	buf->virt = 0;
-	VERIFY(err, 0 != (buf->virt = ion_map_kernel(clnt, buf->handle)));
+	buf->virt = ion_map_kernel(clnt, buf->handle);
+	VERIFY(err, 0 == IS_ERR_OR_NULL(buf->virt));
 	if (err)
 		goto bail;
 	VERIFY(err, 0 != (sg = ion_sg_table(clnt, buf->handle)));
@@ -296,6 +296,9 @@
 		list[i].num = 0;
 		list[i].pgidx = 0;
 		len = pra[i].buf.len;
+		VERIFY(err, len >= 0);
+		if (err)
+			goto bail;
 		if (!len)
 			continue;
 		buf = pra[i].buf.pv;
@@ -622,27 +625,28 @@
 static int get_dev(struct fastrpc_apps *me, struct fastrpc_device **rdev)
 {
 	struct hlist_head *head;
-	struct fastrpc_device *dev = 0;
-	struct hlist_node *n;
+	struct fastrpc_device *dev = 0, *devfree = 0;
+	struct hlist_node *pos, *n;
 	uint32_t h = hash_32(current->tgid, RPC_HASH_BITS);
 	int err = 0;
 
 	spin_lock(&me->hlock);
 	head = &me->htbl[h];
-	hlist_for_each_entry(dev, n, head, hn) {
+	hlist_for_each_entry_safe(dev, pos, n, head, hn) {
 		if (dev->tgid == current->tgid) {
 			hlist_del(&dev->hn);
+			devfree = dev;
 			break;
 		}
 	}
 	spin_unlock(&me->hlock);
-	VERIFY(err, dev != 0);
+	VERIFY(err, devfree != 0);
 	if (err)
 		goto bail;
-	*rdev = dev;
+	*rdev = devfree;
  bail:
 	if (err) {
-		free_dev(dev);
+		free_dev(devfree);
 		err = alloc_dev(rdev);
 	}
 	return err;
@@ -767,22 +771,23 @@
 	struct fastrpc_apps *me = &gfa;
 	uint32_t h = hash_32(current->tgid, RPC_HASH_BITS);
 	struct hlist_head *head;
-	struct hlist_node *pos;
-	struct fastrpc_device *dev;
+	struct hlist_node *pos, *n;
+	struct fastrpc_device *dev, *devfree;
 
  rnext:
-	dev = 0;
+	devfree = dev = 0;
 	spin_lock(&me->hlock);
 	head = &me->htbl[h];
-	hlist_for_each_entry(dev, pos, head, hn) {
+	hlist_for_each_entry_safe(dev, pos, n, head, hn) {
 		if (dev->tgid == current->tgid) {
 			hlist_del(&dev->hn);
+			devfree = dev;
 			break;
 		}
 	}
 	spin_unlock(&me->hlock);
-	if (dev) {
-		free_dev(dev);
+	if (devfree) {
+		free_dev(devfree);
 		goto rnext;
 	}
 	return;
diff --git a/drivers/char/diag/diag_dci.c b/drivers/char/diag/diag_dci.c
index 682d876..c7b3253 100644
--- a/drivers/char/diag/diag_dci.c
+++ b/drivers/char/diag/diag_dci.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2012-2014, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -95,6 +95,11 @@
 	if (recv_pkt_cmd_code != DCI_PKT_RSP_CODE)
 		cmd_code_len = 4; /* delayed response */
 	write_len = (int)(*(uint16_t *)(buf+2)) - cmd_code_len;
+	if (write_len <= 0) {
+		pr_err("diag: Invalid length in %s, write_len: %d",
+					__func__, write_len);
+		return;
+	}
 	pr_debug("diag: len = %d\n", write_len);
 	/* look up DCI client with tag */
 	for (i = 0; i < dci_max_reg; i++) {
@@ -149,7 +154,7 @@
 {
 	uint16_t event_id, event_id_packet, length, temp_len;
 	uint8_t *event_mask_ptr, byte_mask, payload_len, payload_len_field;
-	uint8_t timestamp[8], bit_index, timestamp_len;
+	uint8_t timestamp[8] = {0}, bit_index, timestamp_len;
 	uint8_t event_data[MAX_EVENT_SIZE];
 	unsigned int byte_index, total_event_len, i;
 	struct diag_dci_client_tbl *entry;
@@ -243,17 +248,23 @@
 
 void extract_dci_log(unsigned char *buf)
 {
-	uint16_t log_code, item_num;
+	uint16_t log_code, item_num, log_length;
 	uint8_t equip_id, *log_mask_ptr, byte_mask;
 	unsigned int i, byte_index, byte_offset = 0;
 	struct diag_dci_client_tbl *entry;
 
+	log_length = *(uint16_t *)(buf + 2);
 	log_code = *(uint16_t *)(buf + 6);
 	equip_id = LOG_GET_EQUIP_ID(log_code);
 	item_num = LOG_GET_ITEM_NUM(log_code);
 	byte_index = item_num/8 + 2;
 	byte_mask = 0x01 << (item_num % 8);
 
+	if (log_length > USHRT_MAX - 4) {
+		pr_err("diag: Integer overflow in %s, log_len:%d",
+				__func__, log_length);
+		return;
+	}
 	byte_offset = (equip_id * 514) + byte_index;
 	if (byte_offset >=  DCI_LOG_MASK_SIZE) {
 		pr_err("diag: Invalid byte_offset %d in dci log\n",
@@ -287,8 +298,8 @@
 				*(int *)(entry->dci_data+entry->data_len) =
 								DCI_LOG_TYPE;
 				memcpy(entry->dci_data + entry->data_len + 4,
-					    buf + 4, *(uint16_t *)(buf + 2));
-				entry->data_len += 4 + *(uint16_t *)(buf + 2);
+					    buf + 4, log_length);
+				entry->data_len += 4 + log_length;
 			}
 			mutex_unlock(&dci_health_mutex);
 		}
@@ -661,6 +672,22 @@
 	return ret;
 }
 
+int diag_dci_find_client_index_health(int client_id)
+{
+	int i, ret = DCI_CLIENT_INDEX_INVALID;
+
+	for (i = 0; i < MAX_DCI_CLIENTS; i++) {
+		if (driver->dci_client_tbl[i].client != NULL) {
+			if (driver->dci_client_tbl[i].client_id ==
+					client_id) {
+				ret = i;
+				break;
+			}
+		}
+	}
+	return ret;
+}
+
 int diag_dci_find_client_index(int client_id)
 {
 	int i, ret = DCI_CLIENT_INDEX_INVALID;
diff --git a/drivers/char/diag/diag_dci.h b/drivers/char/diag/diag_dci.h
index 260cdf3..2c1e7ae 100644
--- a/drivers/char/diag/diag_dci.h
+++ b/drivers/char/diag/diag_dci.h
@@ -46,6 +46,7 @@
 };
 
 struct diag_dci_client_tbl {
+	int client_id;
 	struct task_struct *client;
 	uint16_t list; /* bit mask */
 	int signal_type;
@@ -62,6 +63,7 @@
 
 /* This is used for DCI health stats */
 struct diag_dci_health_stats {
+	int client_id;
 	int dropped_logs;
 	int dropped_events;
 	int received_logs;
@@ -96,6 +98,7 @@
 int diag_send_dci_pkt(struct diag_master_table entry, unsigned char *buf,
 							 int len, int index);
 void extract_dci_pkt_rsp(unsigned char *buf);
+int diag_dci_find_client_index_health(int client_id);
 int diag_dci_find_client_index(int client_id);
 /* DCI Log streaming functions */
 void create_dci_log_mask_tbl(unsigned char *tbl_buf);
diff --git a/drivers/char/diag/diag_debugfs.c b/drivers/char/diag/diag_debugfs.c
index e5385fc..deb4d9c 100644
--- a/drivers/char/diag/diag_debugfs.c
+++ b/drivers/char/diag/diag_debugfs.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2013, The Linux Foundation. All rights reserved.
+/* 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
@@ -29,14 +29,14 @@
 {
 	char *buf;
 	int ret;
-
+	unsigned int buf_size;
 	buf = kzalloc(sizeof(char) * DEBUG_BUF_SIZE, GFP_KERNEL);
 	if (!buf) {
 		pr_err("diag: %s, Error allocating memory\n", __func__);
 		return -ENOMEM;
 	}
-
-	ret = scnprintf(buf, DEBUG_BUF_SIZE,
+	buf_size = ksize(buf);
+	ret = scnprintf(buf, buf_size,
 		"modem ch: 0x%x\n"
 		"lpass ch: 0x%x\n"
 		"riva ch: 0x%x\n"
@@ -81,7 +81,7 @@
 		driver->logging_mode);
 
 #ifdef CONFIG_DIAG_OVER_USB
-	ret += scnprintf(buf+ret, DEBUG_BUF_SIZE,
+	ret += scnprintf(buf+ret, buf_size-ret,
 		"usb_connected: %d\n",
 		driver->usb_connected);
 #endif
@@ -96,6 +96,7 @@
 {
 	char *buf;
 	int ret;
+	unsigned int buf_size;
 
 	buf = kzalloc(sizeof(char) * DEBUG_BUF_SIZE, GFP_KERNEL);
 	if (!buf) {
@@ -103,7 +104,8 @@
 		return -ENOMEM;
 	}
 
-	ret = scnprintf(buf, DEBUG_BUF_SIZE,
+	buf_size = ksize(buf);
+	ret = scnprintf(buf, buf_size,
 		"Pending status for work_stucts:\n"
 		"diag_drain_work: %d\n"
 		"Modem data diag_read_smd_work: %d\n"
@@ -151,7 +153,7 @@
 						diag_notify_update_smd_work)));
 
 #ifdef CONFIG_DIAG_OVER_USB
-	ret += scnprintf(buf+ret, DEBUG_BUF_SIZE,
+	ret += scnprintf(buf+ret, buf_size-ret,
 		"diag_proc_hdlc_work: %d\n"
 		"diag_read_work: %d\n",
 		work_pending(&(driver->diag_proc_hdlc_work)),
@@ -169,10 +171,11 @@
 	char *buf;
 	int ret = 0;
 	int i;
-	int bytes_remaining;
-	int bytes_in_buffer = 0;
-	int bytes_written;
-	int buf_size = (DEBUG_BUF_SIZE < count) ? DEBUG_BUF_SIZE : count;
+	unsigned int bytes_remaining;
+	unsigned int bytes_in_buffer = 0;
+	unsigned int bytes_written;
+	unsigned int buf_size;
+	buf_size = (DEBUG_BUF_SIZE < count) ? DEBUG_BUF_SIZE : count;
 
 	if (diag_dbgfs_table_index >= diag_max_reg) {
 		/* Done. Reset to prepare for future requests */
@@ -185,7 +188,7 @@
 		pr_err("diag: %s, Error allocating memory\n", __func__);
 		return -ENOMEM;
 	}
-
+	buf_size = ksize(buf);
 	bytes_remaining = buf_size;
 
 	if (diag_dbgfs_table_index == 0) {
@@ -194,6 +197,7 @@
 			"WCNSS: %d, APPS: %d\n",
 			MODEM_DATA, LPASS_DATA, WCNSS_DATA, APPS_DATA);
 		bytes_in_buffer += bytes_written;
+		bytes_remaining -= bytes_written;
 	}
 
 	for (i = diag_dbgfs_table_index; i < diag_max_reg; i++) {
@@ -236,13 +240,15 @@
 	char *buf;
 	int ret;
 	int i;
-	int bytes_remaining;
-	int bytes_in_buffer = 0;
-	int bytes_written;
-	int buf_size = (DEBUG_BUF_SIZE < count) ? DEBUG_BUF_SIZE : count;
+	unsigned int bytes_remaining;
+	unsigned int bytes_in_buffer = 0;
+	unsigned int bytes_written;
+	unsigned int buf_size;
 	int bytes_hsic_inited = 45;
 	int bytes_hsic_not_inited = 410;
 
+	buf_size = (DEBUG_BUF_SIZE < count) ? DEBUG_BUF_SIZE : count;
+
 	if (diag_dbgfs_finished) {
 		diag_dbgfs_finished = 0;
 		return 0;
@@ -254,6 +260,7 @@
 		return -ENOMEM;
 	}
 
+	buf_size = ksize(buf);
 	bytes_remaining = buf_size;
 
 	/* Only one smux for now */
diff --git a/drivers/char/diag/diagchar_core.c b/drivers/char/diag/diagchar_core.c
index b92666c..a7763cd 100644
--- a/drivers/char/diag/diagchar_core.c
+++ b/drivers/char/diag/diagchar_core.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2008-2013, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2008-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
@@ -47,6 +47,7 @@
 MODULE_LICENSE("GPL v2");
 MODULE_VERSION("1.0");
 
+#define MIN_SIZ_ALLOW 4
 #define INIT	1
 #define EXIT	-1
 struct diagchar_dev *driver;
@@ -976,6 +977,8 @@
 		for (i = 0; i < MAX_DCI_CLIENTS; i++) {
 			if (driver->dci_client_tbl[i].client == NULL) {
 				driver->dci_client_tbl[i].client = current;
+				driver->dci_client_tbl[i].client_id =
+							driver->dci_client_id;
 				driver->dci_client_tbl[i].list =
 							 dci_params->list;
 				driver->dci_client_tbl[i].signal_type =
@@ -1056,7 +1059,7 @@
 				 sizeof(struct diag_dci_health_stats)))
 			return -EFAULT;
 		mutex_lock(&dci_health_mutex);
-		i = diag_dci_find_client_index(current->tgid);
+		i = diag_dci_find_client_index_health(stats.client_id);
 		if (i != DCI_CLIENT_INDEX_INVALID) {
 			dci_params = &(driver->dci_client_tbl[i]);
 			stats.dropped_logs = dci_params->dropped_logs;
@@ -1391,6 +1394,10 @@
 	index = 0;
 	/* Get the packet type F3/log/event/Pkt response */
 	err = copy_from_user((&pkt_type), buf, 4);
+	if (err) {
+		pr_alert("diag: copy failed for pkt_type\n");
+		return -EAGAIN;
+	}
 	/* First 4 bytes indicate the type of payload - ignore these */
 	if (count < 4) {
 		pr_err("diag: Client sending short data\n");
@@ -1431,8 +1438,9 @@
 		return err;
 	}
 	if (pkt_type == CALLBACK_DATA_TYPE) {
-		if (payload_size > itemsize) {
-			pr_err("diag: Dropping packet, packet payload size crosses 4KB limit. Current payload size %d\n",
+		if (payload_size > itemsize ||
+				payload_size <= MIN_SIZ_ALLOW) {
+			pr_err("diag: Dropping packet, invalid packet size. Current payload size %d\n",
 				payload_size);
 			driver->dropped_count++;
 			return -EBADMSG;
@@ -1577,6 +1585,11 @@
 		remote_proc = diag_get_remote(*(int *)user_space_data);
 
 		if (remote_proc) {
+			if (payload_size <= MIN_SIZ_ALLOW) {
+				pr_err("diag: Integer underflow in %s, payload size: %d",
+							__func__, payload_size);
+				return -EBADMSG;
+			}
 			token_offset = 4;
 			payload_size -= 4;
 			buf += 4;
diff --git a/drivers/char/diag/diagchar_hdlc.c b/drivers/char/diag/diagchar_hdlc.c
index 2369c4d..f78a0fe 100644
--- a/drivers/char/diag/diagchar_hdlc.c
+++ b/drivers/char/diag/diagchar_hdlc.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2008-2009, 2012-2013, The Linux Foundation.
+/* Copyright (c) 2008-2009, 2012-2014, The Linux Foundation.
  * All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
@@ -176,8 +176,8 @@
 	int msg_start;
 
 	if (hdlc && hdlc->src_ptr && hdlc->dest_ptr &&
-	    (hdlc->src_size - hdlc->src_idx > 0) &&
-	    (hdlc->dest_size - hdlc->dest_idx > 0)) {
+	    (hdlc->src_size > hdlc->src_idx) &&
+	    (hdlc->dest_size > hdlc->dest_idx)) {
 
 		msg_start = (hdlc->src_idx == 0) ? 1 : 0;
 
diff --git a/drivers/char/diag/diagmem.c b/drivers/char/diag/diagmem.c
index bd339e2..576811b 100644
--- a/drivers/char/diag/diagmem.c
+++ b/drivers/char/diag/diagmem.c
@@ -15,6 +15,7 @@
 #include <linux/module.h>
 #include <linux/mempool.h>
 #include <linux/mutex.h>
+#include <linux/ratelimit.h>
 #include <asm/atomic.h>
 #include "diagchar.h"
 #include "diagfwd_bridge.h"
@@ -223,7 +224,7 @@
 			atomic_add(-1, (atomic_t *)
 				   &diag_hsic[index].count_hsic_pool);
 		} else
-			pr_err("diag: Attempt to free up DIAG driver HSIC mempool which is already free %d, ch = %d",
+			pr_err_ratelimited("diag: Attempt to free up DIAG driver HSIC mempool which is already free %d, ch = %d",
 				diag_hsic[index].count_hsic_pool, index);
 	} else if (pool_type == POOL_TYPE_HSIC_WRITE ||
 				pool_type == POOL_TYPE_HSIC_2_WRITE) {
diff --git a/drivers/char/msm_rotator.c b/drivers/char/msm_rotator.c
index aaf42d1..9a54e69 100644
--- a/drivers/char/msm_rotator.c
+++ b/drivers/char/msm_rotator.c
@@ -449,7 +449,7 @@
 		rc = 1;
 #endif
 	if (rc == 1) {
-		cancel_delayed_work(&msm_rotator_dev->imem_clk_work);
+		cancel_delayed_work_sync(&msm_rotator_dev->imem_clk_work);
 		if (msm_rotator_dev->imem_clk_state != CLK_EN
 			&& msm_rotator_dev->imem_clk) {
 			clk_prepare_enable(msm_rotator_dev->imem_clk);
@@ -1347,12 +1347,10 @@
 
 	msm_rotator_dev->processing = 1;
 	iowrite32(0x1, MSM_ROTATOR_START);
-	mutex_unlock(&msm_rotator_dev->rotator_lock);
 	/* End of Pass-1 */
 	wait_event(msm_rotator_dev->wq,
 		   (msm_rotator_dev->processing == 0));
 	/* Beginning of Pass-2 */
-	mutex_lock(&msm_rotator_dev->rotator_lock);
 	status = (unsigned char)ioread32(MSM_ROTATOR_INTR_STATUS);
 	if ((status & 0x03) != 0x01) {
 		pr_err("%s(): AXI Bus Error, issuing SW_RESET\n",
@@ -2028,7 +2026,7 @@
 	msm_rotator_wait_for_fence(commit_info->acq_fen);
 	commit_info->acq_fen = NULL;
 
-	cancel_delayed_work(&msm_rotator_dev->rot_clk_work);
+	cancel_delayed_work_sync(&msm_rotator_dev->rot_clk_work);
 	if (msm_rotator_dev->rot_clk_state != CLK_EN) {
 		enable_rot_clks();
 		msm_rotator_dev->rot_clk_state = CLK_EN;
@@ -2140,10 +2138,8 @@
 
 	msm_rotator_dev->processing = 1;
 	iowrite32(0x1, MSM_ROTATOR_START);
-	mutex_unlock(&msm_rotator_dev->rotator_lock);
 	wait_event(msm_rotator_dev->wq,
 		   (msm_rotator_dev->processing == 0));
-	mutex_lock(&msm_rotator_dev->rotator_lock);
 	status = (unsigned char)ioread32(MSM_ROTATOR_INTR_STATUS);
 	if ((status & 0x03) != 0x01) {
 		pr_err("%s(): AXI Bus Error, issuing SW_RESET\n", __func__);
diff --git a/drivers/gpu/msm/a3xx_reg.h b/drivers/gpu/msm/a3xx_reg.h
index f81fc67..21d4759 100644
--- a/drivers/gpu/msm/a3xx_reg.h
+++ b/drivers/gpu/msm/a3xx_reg.h
@@ -231,7 +231,6 @@
 #define A3XX_PC_PERFCOUNTER1_SELECT 0xC49
 #define A3XX_PC_PERFCOUNTER2_SELECT 0xC4A
 #define A3XX_PC_PERFCOUNTER3_SELECT 0xC4B
-#define A3XX_GRAS_TSE_DEBUG_ECO 0xC81
 #define A3XX_GRAS_PERFCOUNTER0_SELECT 0xC88
 #define A3XX_GRAS_PERFCOUNTER1_SELECT 0xC89
 #define A3XX_GRAS_PERFCOUNTER2_SELECT 0xC8A
@@ -269,10 +268,6 @@
 #define A3XX_HLSQ_PERFCOUNTER3_SELECT 0xE03
 #define A3XX_HLSQ_PERFCOUNTER4_SELECT 0xE04
 #define A3XX_HLSQ_PERFCOUNTER5_SELECT 0xE05
-#define A3XX_RB_DEBUG_ECO_CONTROLS_ADDR 0xCC1
-#define A3XX_RB_PERFCOUNTER0_SELECT   0xCC6
-#define A3XX_RB_PERFCOUNTER1_SELECT   0xCC7
-#define A3XX_RB_FRAME_BUFFER_DIMENSION 0xCE0
 #define A3XX_VFD_PERFCOUNTER0_SELECT 0xE44
 #define A3XX_VFD_PERFCOUNTER1_SELECT 0xE45
 #define A3XX_VPC_VPC_DEBUG_RAM_SEL 0xE61
@@ -304,9 +299,6 @@
 #define A3XX_GRAS_CL_CLIP_CNTL 0x2040
 #define A3XX_GRAS_CL_GB_CLIP_ADJ 0x2044
 #define A3XX_GRAS_CL_VPORT_XOFFSET 0x2048
-#define A3XX_GRAS_CL_VPORT_XSCALE 0x2049
-#define A3XX_GRAS_CL_VPORT_YOFFSET 0x204A
-#define A3XX_GRAS_CL_VPORT_YSCALE 0x204B
 #define A3XX_GRAS_CL_VPORT_ZOFFSET 0x204C
 #define A3XX_GRAS_CL_VPORT_ZSCALE 0x204D
 #define A3XX_GRAS_SU_POINT_MINMAX 0x2068
@@ -322,75 +314,30 @@
 #define A3XX_RB_MODE_CONTROL 0x20C0
 #define A3XX_RB_RENDER_CONTROL 0x20C1
 #define A3XX_RB_MSAA_CONTROL 0x20C2
-#define A3XX_RB_ALPHA_REFERENCE 0x20C3
 #define A3XX_RB_MRT_CONTROL0 0x20C4
 #define A3XX_RB_MRT_BUF_INFO0 0x20C5
-#define A3XX_RB_MRT_BUF_BASE0 0x20C6
 #define A3XX_RB_MRT_BLEND_CONTROL0 0x20C7
-#define A3XX_RB_MRT_CONTROL1 0x20C8
-#define A3XX_RB_MRT_BUF_INFO1 0x20C9
-#define A3XX_RB_MRT_BUF_BASE1 0x20CA
 #define A3XX_RB_MRT_BLEND_CONTROL1 0x20CB
-#define A3XX_RB_MRT_CONTROL2 0x20CC
-#define A3XX_RB_MRT_BUF_INFO2 0x20CD
-#define A3XX_RB_MRT_BUF_BASE2 0x20CE
 #define A3XX_RB_MRT_BLEND_CONTROL2 0x20CF
-#define A3XX_RB_MRT_CONTROL3 0x20D0
-#define A3XX_RB_MRT_BUF_INFO3 0x20D1
-#define A3XX_RB_MRT_BUF_BASE3 0x20D2
 #define A3XX_RB_MRT_BLEND_CONTROL3 0x20D3
 #define A3XX_RB_BLEND_RED 0x20E4
-#define A3XX_RB_BLEND_GREEN 0x20E5
-#define A3XX_RB_BLEND_BLUE 0x20E6
-#define A3XX_RB_BLEND_ALPHA 0x20E7
-#define A3XX_RB_CLEAR_COLOR_DW0 0x20E8
-#define A3XX_RB_CLEAR_COLOR_DW1 0x20E9
-#define A3XX_RB_CLEAR_COLOR_DW2 0x20EA
-#define A3XX_RB_CLEAR_COLOR_DW3 0x20EB
 #define A3XX_RB_COPY_CONTROL 0x20EC
-#define A3XX_RB_COPY_DEST_BASE 0x20ED
-#define A3XX_RB_COPY_DEST_PITCH 0x20EE
 #define A3XX_RB_COPY_DEST_INFO 0x20EF
 #define A3XX_RB_DEPTH_CONTROL 0x2100
-#define A3XX_RB_DEPTH_CLEAR 0x2101
-#define A3XX_RB_DEPTH_BUF_INFO 0x2102
-#define A3XX_RB_DEPTH_BUF_PITCH 0x2103
 #define A3XX_RB_STENCIL_CONTROL 0x2104
-#define A3XX_RB_STENCIL_CLEAR 0x2105
-#define A3XX_RB_STENCIL_BUF_INFO 0x2106
-#define A3XX_RB_STENCIL_BUF_PITCH 0x2107
-#define A3XX_RB_STENCIL_REF_MASK 0x2108
-#define A3XX_RB_STENCIL_REF_MASK_BF 0x2109
-#define A3XX_RB_LRZ_VSC_CONTROL 0x210C
-#define A3XX_RB_WINDOW_OFFSET 0x210E
-#define A3XX_RB_SAMPLE_COUNT_CONTROL 0x2110
-#define A3XX_RB_SAMPLE_COUNT_ADDR 0x2111
-#define A3XX_RB_Z_CLAMP_MIN 0x2114
-#define A3XX_RB_Z_CLAMP_MAX 0x2115
 #define A3XX_PC_VSTREAM_CONTROL 0x21E4
 #define A3XX_PC_VERTEX_REUSE_BLOCK_CNTL 0x21EA
 #define A3XX_PC_PRIM_VTX_CNTL 0x21EC
 #define A3XX_PC_RESTART_INDEX 0x21ED
 #define A3XX_HLSQ_CONTROL_0_REG 0x2200
-#define A3XX_HLSQ_CONTROL_1_REG 0x2201
-#define A3XX_HLSQ_CONTROL_2_REG 0x2202
-#define A3XX_HLSQ_CONTROL_3_REG 0x2203
 #define A3XX_HLSQ_VS_CONTROL_REG 0x2204
-#define A3XX_HLSQ_FS_CONTROL_REG 0x2205
-#define A3XX_HLSQ_CONST_VSPRESV_RANGE_REG 0x2206
 #define A3XX_HLSQ_CONST_FSPRESV_RANGE_REG 0x2207
 #define A3XX_HLSQ_CL_NDRANGE_0_REG 0x220A
-#define A3XX_HLSQ_CL_NDRANGE_1_REG 0x220B
 #define A3XX_HLSQ_CL_NDRANGE_2_REG 0x220C
-#define A3XX_HLSQ_CL_NDRANGE_3_REG 0x220D
-#define A3XX_HLSQ_CL_NDRANGE_4_REG 0x220E
-#define A3XX_HLSQ_CL_NDRANGE_5_REG 0x220F
-#define A3XX_HLSQ_CL_NDRANGE_6_REG 0x2210
 #define A3XX_HLSQ_CL_CONTROL_0_REG 0x2211
 #define A3XX_HLSQ_CL_CONTROL_1_REG 0x2212
 #define A3XX_HLSQ_CL_KERNEL_CONST_REG 0x2214
 #define A3XX_HLSQ_CL_KERNEL_GROUP_X_REG 0x2215
-#define A3XX_HLSQ_CL_KERNEL_GROUP_Y_REG 0x2216
 #define A3XX_HLSQ_CL_KERNEL_GROUP_Z_REG 0x2217
 #define A3XX_HLSQ_CL_WG_OFFSET_REG 0x221A
 #define A3XX_VFD_CONTROL_0 0x2240
@@ -407,21 +354,10 @@
 #define A3XX_SP_VS_CTRL_REG0 0x22C4
 #define A3XX_SP_VS_CTRL_REG1 0x22C5
 #define A3XX_SP_VS_PARAM_REG 0x22C6
-#define A3XX_SP_VS_OUT_REG_0 0x22C7
-#define A3XX_SP_VS_OUT_REG_1 0x22C8
-#define A3XX_SP_VS_OUT_REG_2 0x22C9
-#define A3XX_SP_VS_OUT_REG_3 0x22CA
-#define A3XX_SP_VS_OUT_REG_4 0x22CB
-#define A3XX_SP_VS_OUT_REG_5 0x22CC
-#define A3XX_SP_VS_OUT_REG_6 0x22CD
 #define A3XX_SP_VS_OUT_REG_7 0x22CE
 #define A3XX_SP_VS_VPC_DST_REG_0 0x22D0
-#define A3XX_SP_VS_VPC_DST_REG_1 0x22D1
-#define A3XX_SP_VS_VPC_DST_REG_2 0x22D2
-#define A3XX_SP_VS_VPC_DST_REG_3 0x22D3
 #define A3XX_SP_VS_OBJ_OFFSET_REG 0x22D4
 #define A3XX_SP_VS_OBJ_START_REG 0x22D5
-#define A3XX_SP_VS_PVT_MEM_PARAM_REG 0x22D6
 #define A3XX_SP_VS_PVT_MEM_ADDR_REG 0x22D7
 #define A3XX_SP_VS_PVT_MEM_SIZE_REG 0x22D8
 #define A3XX_SP_VS_LENGTH_REG 0x22DF
@@ -429,19 +365,13 @@
 #define A3XX_SP_FS_CTRL_REG1 0x22E1
 #define A3XX_SP_FS_OBJ_OFFSET_REG 0x22E2
 #define A3XX_SP_FS_OBJ_START_REG 0x22E3
-#define A3XX_SP_FS_PVT_MEM_PARAM_REG 0x22E4
 #define A3XX_SP_FS_PVT_MEM_ADDR_REG 0x22E5
 #define A3XX_SP_FS_PVT_MEM_SIZE_REG 0x22E6
 #define A3XX_SP_FS_FLAT_SHAD_MODE_REG_0 0x22E8
 #define A3XX_SP_FS_FLAT_SHAD_MODE_REG_1 0x22E9
 #define A3XX_SP_FS_OUTPUT_REG 0x22EC
 #define A3XX_SP_FS_MRT_REG_0 0x22F0
-#define A3XX_SP_FS_MRT_REG_1 0x22F1
-#define A3XX_SP_FS_MRT_REG_2 0x22F2
-#define A3XX_SP_FS_MRT_REG_3 0x22F3
 #define A3XX_SP_FS_IMAGE_OUTPUT_REG_0 0x22F4
-#define A3XX_SP_FS_IMAGE_OUTPUT_REG_1 0x22F5
-#define A3XX_SP_FS_IMAGE_OUTPUT_REG_2 0x22F6
 #define A3XX_SP_FS_IMAGE_OUTPUT_REG_3 0x22F7
 #define A3XX_SP_FS_LENGTH_REG 0x22FF
 #define A3XX_TPL1_TP_VS_TEX_OFFSET 0x2340
diff --git a/drivers/gpu/msm/adreno.c b/drivers/gpu/msm/adreno.c
index c096b8c..a93fe14 100644
--- a/drivers/gpu/msm/adreno.c
+++ b/drivers/gpu/msm/adreno.c
@@ -292,7 +292,7 @@
  */
 
 int adreno_perfcounter_read_group(struct adreno_device *adreno_dev,
-	struct kgsl_perfcounter_read_group *reads, unsigned int count)
+	struct kgsl_perfcounter_read_group __user *reads, unsigned int count)
 {
 	struct adreno_perfcounters *counters = adreno_dev->gpudev->perfcounters;
 	struct adreno_perfcount_group *group;
@@ -312,12 +312,6 @@
 	if (reads == NULL || count == 0 || count > 100)
 		return -EINVAL;
 
-	/* verify valid inputs group ids and countables */
-	for (i = 0; i < count; i++) {
-		if (reads[i].groupid >= counters->group_count)
-			return -EINVAL;
-	}
-
 	list = kmalloc(sizeof(struct kgsl_perfcounter_read_group) * count,
 			GFP_KERNEL);
 	if (!list)
@@ -331,8 +325,15 @@
 
 	/* list iterator */
 	for (j = 0; j < count; j++) {
+
 		list[j].value = 0;
 
+		/* Verify that the group ID is within range */
+		if (list[j].groupid >= counters->group_count) {
+			ret = -EINVAL;
+			goto done;
+		}
+
 		group = &(counters->groups[list[j].groupid]);
 
 		/* group/counter iterator */
@@ -572,15 +573,13 @@
 
 	kgsl_mmu_unmap(pagetable, &device->memstore);
 
-	kgsl_mmu_unmap(pagetable, &adreno_dev->pwron_fixup);
-
 	kgsl_mmu_unmap(pagetable, &device->mmu.setstate_memory);
 }
 
 static int adreno_setup_pt(struct kgsl_device *device,
 			struct kgsl_pagetable *pagetable)
 {
-	int result;
+	int result = 0;
 	struct adreno_device *adreno_dev = ADRENO_DEVICE(device);
 	struct adreno_ringbuffer *rb = &adreno_dev->ringbuffer;
 
@@ -596,13 +595,9 @@
 	if (result)
 		goto unmap_memptrs_desc;
 
-	result = kgsl_mmu_map_global(pagetable, &adreno_dev->pwron_fixup);
-	if (result)
-		goto unmap_memstore_desc;
-
 	result = kgsl_mmu_map_global(pagetable, &device->mmu.setstate_memory);
 	if (result)
-		goto unmap_pwron_fixup_desc;
+		goto unmap_memstore_desc;
 
 	/*
 	 * Set the mpu end to the last "normal" global memory we use.
@@ -613,9 +608,6 @@
 				device->mmu.setstate_memory.size;
 	return result;
 
-unmap_pwron_fixup_desc:
-	kgsl_mmu_unmap(pagetable, &adreno_dev->pwron_fixup);
-
 unmap_memstore_desc:
 	kgsl_mmu_unmap(pagetable, &device->memstore);
 
@@ -1648,11 +1640,6 @@
 	kgsl_pwrctrl_enable(device);
 
 	/* Set up a2xx special case */
-
-	/* Set the bit to indicate that we've just powered on */
-	set_bit(ADRENO_DEVICE_PWRON, &adreno_dev->priv);
-
-	/* Set up the MMU */
 	if (adreno_is_a2xx(adreno_dev)) {
 		/*
 		 * the MH_CLNT_INTF_CTRL_CONFIG registers aren't present
@@ -3226,9 +3213,6 @@
 	if (kgsl_gpuaddr_in_memdesc(&device->memstore, gpuaddr, size))
 		return &device->memstore;
 
-	if (kgsl_gpuaddr_in_memdesc(&adreno_dev->pwron_fixup, gpuaddr, size))
-		return &adreno_dev->pwron_fixup;
-
 	if (kgsl_gpuaddr_in_memdesc(&device->mmu.setstate_memory, gpuaddr,
 					size))
 		return &device->mmu.setstate_memory;
diff --git a/drivers/gpu/msm/adreno.h b/drivers/gpu/msm/adreno.h
old mode 100755
new mode 100644
index 314d4e9..59cf265
--- a/drivers/gpu/msm/adreno.h
+++ b/drivers/gpu/msm/adreno.h
@@ -35,7 +35,6 @@
 #define KGSL_CMD_FLAGS_PMODE		0x00000001
 #define KGSL_CMD_FLAGS_INTERNAL_ISSUE	0x00000002
 #define KGSL_CMD_FLAGS_GET_INT		0x00000004
-#define KGSL_CMD_FLAGS_PWRON_FIXUP      0x00000008
 #define KGSL_CMD_FLAGS_EOF	        0x00000100
 
 /* Command identifiers */
@@ -46,7 +45,6 @@
 #define KGSL_END_OF_IB_IDENTIFIER	0x2ABEDEAD
 #define KGSL_END_OF_FRAME_IDENTIFIER	0x2E0F2E0F
 #define KGSL_NOP_IB_IDENTIFIER	        0x20F20F20
-#define KGSL_PWRON_FIXUP_IDENTIFIER	0x2AFAFAFA
 
 #ifdef CONFIG_MSM_SCM
 #define ADRENO_DEFAULT_PWRSCALE_POLICY  (&kgsl_pwrscale_policy_tz)
@@ -82,7 +80,6 @@
 
 struct adreno_device {
 	struct kgsl_device dev;    /* Must be first field in this struct */
-	unsigned long priv;
 	unsigned int chip_id;
 	enum adreno_gpurev gpurev;
 	unsigned long gmem_base;
@@ -115,8 +112,6 @@
 	struct ocmem_buf *ocmem_hdl;
 	unsigned int ocmem_base;
 	unsigned int gpu_cycles;
-	struct kgsl_memdesc pwron_fixup;
-	unsigned int pwron_fixup_dwords;
 };
 
 #define PERFCOUNTER_FLAG_NONE 0x0
@@ -157,17 +152,6 @@
 	unsigned int group_count;
 };
 
-/**
- * enum adreno_device_flags - Private flags for the adreno_device
- * @ADRENO_DEVICE_PWRON - Set during init after a power collapse
- * @ADRENO_DEVICE_PWRON_FIXUP - Set if the target requires the shader fixup
- * after power collapse
- */
-enum adreno_device_flags {
-	ADRENO_DEVICE_PWRON = 0,
-	ADRENO_DEVICE_PWRON_FIXUP = 1,
-};
-
 struct adreno_gpudev {
 	/*
 	 * These registers are in a different location on A3XX,  so define
@@ -326,8 +310,6 @@
 int adreno_ft_init_sysfs(struct kgsl_device *device);
 void adreno_ft_uninit_sysfs(struct kgsl_device *device);
 
-int adreno_a3xx_pwron_fixup_init(struct adreno_device *adreno_dev);
-
 static inline int adreno_is_a200(struct adreno_device *adreno_dev)
 {
 	return (adreno_dev->gpurev == ADRENO_REV_A200);
diff --git a/drivers/gpu/msm/adreno_a3xx.c b/drivers/gpu/msm/adreno_a3xx.c
index af828df..a8cc524 100644
--- a/drivers/gpu/msm/adreno_a3xx.c
+++ b/drivers/gpu/msm/adreno_a3xx.c
@@ -2497,270 +2497,6 @@
 	}
 }
 
-static const unsigned int _a3xx_pwron_fixup_fs_instructions[] = {
-	0x00000000, 0x10000400, 0x00000000, 0x00000000,
-	0x00000000, 0x00000000, 0x00000000, 0x03000000,
-};
-
-/**
- * adreno_a3xx_pwron_fixup_init() - Initalize a special command buffer to run a
- * post-power collapse shader workaround
- * @adreno_dev: Pointer to a adreno_device struct
- *
- * A3xx targets require a CL Exec after recovery from power-collapse.
- * Construct the IB once at init time and keep it handy.
- *
- * Returns: 0 on success or negative on error
- */
-int adreno_a3xx_pwron_fixup_init(struct adreno_device *adreno_dev)
-{
-	unsigned int *cmds;
-	int count = sizeof(_a3xx_pwron_fixup_fs_instructions) >> 2;
-	int ret;
-	/* Return if the fixup is already in place */
-	if (test_bit(ADRENO_DEVICE_PWRON_FIXUP, &adreno_dev->priv))
-		return 0;
-
-	ret = kgsl_allocate_contiguous(&adreno_dev->pwron_fixup, PAGE_SIZE);
-
-	if (ret)
-		return ret;
-	adreno_dev->pwron_fixup.flags |= KGSL_MEMFLAGS_GPUREADONLY;
-	cmds = adreno_dev->pwron_fixup.hostptr;
-
-	*cmds++ = cp_type0_packet(A3XX_UCHE_CACHE_INVALIDATE0_REG, 2);
-	*cmds++ = 0x00000000;
-	*cmds++ = 0x90000000;
-	*cmds++ = cp_type3_packet(CP_WAIT_FOR_IDLE, 1);
-	*cmds++ = 0x00000000;
-	*cmds++ = cp_type3_packet(CP_REG_RMW, 3);
-	*cmds++ = A3XX_RBBM_CLOCK_CTL;
-	*cmds++ = 0xFFFCFFFF;
-	*cmds++ = 0x00010000;
-	*cmds++ = cp_type3_packet(CP_WAIT_FOR_IDLE, 1);
-	*cmds++ = 0x00000000;
-	*cmds++ = cp_type0_packet(A3XX_HLSQ_CONTROL_0_REG, 1);
-	*cmds++ = 0x1E000150;
-	*cmds++ = cp_type3_packet(CP_WAIT_FOR_IDLE, 1);
-	*cmds++ = 0x00000000;
-	*cmds++ = cp_type3_packet(CP_SET_CONSTANT, 2);
-	*cmds++ = CP_REG(A3XX_HLSQ_CONTROL_0_REG) | (0x1 << 30);
-	*cmds++ = 0x1E000150;
-	*cmds++ = cp_type3_packet(CP_WAIT_FOR_IDLE, 1);
-	*cmds++ = 0x00000000;
-	*cmds++ = cp_type0_packet(A3XX_HLSQ_CONTROL_0_REG, 1);
-	*cmds++ = 0x1E000150;
-	*cmds++ = cp_type0_packet(A3XX_HLSQ_CONTROL_1_REG, 1);
-	*cmds++ = 0x00000040;
-	*cmds++ = cp_type0_packet(A3XX_HLSQ_CONTROL_2_REG, 1);
-	*cmds++ = 0x80000000;
-	*cmds++ = cp_type0_packet(A3XX_HLSQ_CONTROL_3_REG, 1);
-	*cmds++ = 0x00000000;
-	*cmds++ = cp_type0_packet(A3XX_HLSQ_VS_CONTROL_REG, 1);
-	*cmds++ = 0x00000001;
-	*cmds++ = cp_type0_packet(A3XX_HLSQ_FS_CONTROL_REG, 1);
-	*cmds++ = 0x00001002 | (count >> 3) << 24;
-	*cmds++ = cp_type0_packet(A3XX_HLSQ_CONST_VSPRESV_RANGE_REG, 1);
-	*cmds++ = 0x00000000;
-	*cmds++ = cp_type0_packet(A3XX_HLSQ_CONST_FSPRESV_RANGE_REG, 1);
-	*cmds++ = 0x00000000;
-	*cmds++ = cp_type0_packet(A3XX_HLSQ_CL_NDRANGE_0_REG, 1);
-	*cmds++ = 0x00401101;
-	*cmds++ = cp_type0_packet(A3XX_HLSQ_CL_NDRANGE_1_REG, 1);
-	*cmds++ = 0x00000400;
-	*cmds++ = cp_type0_packet(A3XX_HLSQ_CL_NDRANGE_2_REG, 1);
-	*cmds++ = 0x00000000;
-	*cmds++ = cp_type0_packet(A3XX_HLSQ_CL_NDRANGE_3_REG, 1);
-	*cmds++ = 0x00000001;
-	*cmds++ = cp_type0_packet(A3XX_HLSQ_CL_NDRANGE_4_REG, 1);
-	*cmds++ = 0x00000000;
-	*cmds++ = cp_type0_packet(A3XX_HLSQ_CL_NDRANGE_5_REG, 1);
-	*cmds++ = 0x00000001;
-	*cmds++ = cp_type0_packet(A3XX_HLSQ_CL_NDRANGE_6_REG, 1);
-	*cmds++ = 0x00000000;
-	*cmds++ = cp_type0_packet(A3XX_HLSQ_CL_CONTROL_0_REG, 1);
-	*cmds++ = 0x00000000;
-	*cmds++ = cp_type0_packet(A3XX_HLSQ_CL_CONTROL_1_REG, 1);
-	*cmds++ = 0x00000000;
-	*cmds++ = cp_type0_packet(A3XX_HLSQ_CL_KERNEL_CONST_REG, 1);
-	*cmds++ = 0x00000000;
-	*cmds++ = cp_type0_packet(A3XX_HLSQ_CL_KERNEL_GROUP_X_REG, 1);
-	*cmds++ = 0x00000010;
-	*cmds++ = cp_type0_packet(A3XX_HLSQ_CL_KERNEL_GROUP_Y_REG, 1);
-	*cmds++ = 0x00000001;
-	*cmds++ = cp_type0_packet(A3XX_HLSQ_CL_KERNEL_GROUP_Z_REG, 1);
-	*cmds++ = 0x00000001;
-	*cmds++ = cp_type0_packet(A3XX_HLSQ_CL_WG_OFFSET_REG, 1);
-	*cmds++ = 0x00000000;
-	*cmds++ = cp_type0_packet(A3XX_SP_SP_CTRL_REG, 1);
-	*cmds++ = 0x00040000;
-	*cmds++ = cp_type0_packet(A3XX_SP_VS_CTRL_REG0, 1);
-	*cmds++ = 0x0000000A;
-	*cmds++ = cp_type0_packet(A3XX_SP_VS_CTRL_REG1, 1);
-	*cmds++ = 0x00000001;
-	*cmds++ = cp_type0_packet(A3XX_SP_VS_PARAM_REG, 1);
-	*cmds++ = 0x00000000;
-	*cmds++ = cp_type0_packet(A3XX_SP_VS_OUT_REG_0, 1);
-	*cmds++ = 0x00000000;
-	*cmds++ = cp_type0_packet(A3XX_SP_VS_OUT_REG_1, 1);
-	*cmds++ = 0x00000000;
-	*cmds++ = cp_type0_packet(A3XX_SP_VS_OUT_REG_2, 1);
-	*cmds++ = 0x00000000;
-	*cmds++ = cp_type0_packet(A3XX_SP_VS_OUT_REG_3, 1);
-	*cmds++ = 0x00000000;
-	*cmds++ = cp_type0_packet(A3XX_SP_VS_OUT_REG_4, 1);
-	*cmds++ = 0x00000000;
-	*cmds++ = cp_type0_packet(A3XX_SP_VS_OUT_REG_5, 1);
-	*cmds++ = 0x00000000;
-	*cmds++ = cp_type0_packet(A3XX_SP_VS_OUT_REG_6, 1);
-	*cmds++ = 0x00000000;
-	*cmds++ = cp_type0_packet(A3XX_SP_VS_OUT_REG_7, 1);
-	*cmds++ = 0x00000000;
-	*cmds++ = cp_type0_packet(A3XX_SP_VS_VPC_DST_REG_0, 1);
-	*cmds++ = 0x00000000;
-	*cmds++ = cp_type0_packet(A3XX_SP_VS_VPC_DST_REG_1, 1);
-	*cmds++ = 0x00000000;
-	*cmds++ = cp_type0_packet(A3XX_SP_VS_VPC_DST_REG_2, 1);
-	*cmds++ = 0x00000000;
-	*cmds++ = cp_type0_packet(A3XX_SP_VS_VPC_DST_REG_3, 1);
-	*cmds++ = 0x00000000;
-	*cmds++ = cp_type0_packet(A3XX_SP_VS_OBJ_OFFSET_REG, 1);
-	*cmds++ = 0x00000000;
-	*cmds++ = cp_type0_packet(A3XX_SP_VS_OBJ_START_REG, 1);
-	*cmds++ = 0x00000004;
-	*cmds++ = cp_type0_packet(A3XX_SP_VS_PVT_MEM_PARAM_REG, 1);
-	*cmds++ = 0x04008001;
-	*cmds++ = cp_type0_packet(A3XX_SP_VS_PVT_MEM_ADDR_REG, 1);
-	*cmds++ = 0x00000000;
-	*cmds++ = cp_type0_packet(A3XX_SP_VS_PVT_MEM_SIZE_REG, 1);
-	*cmds++ = 0x00000000;
-	*cmds++ = cp_type0_packet(A3XX_SP_VS_LENGTH_REG, 1);
-	*cmds++ = 0x00000000;
-	*cmds++ = cp_type0_packet(A3XX_SP_FS_CTRL_REG0, 1);
-	*cmds++ = 0x00B0400A | (count >> 3) << 24;
-	*cmds++ = cp_type0_packet(A3XX_SP_FS_CTRL_REG1, 1);
-	*cmds++ = 0x00300402;
-	*cmds++ = cp_type0_packet(A3XX_SP_FS_OBJ_OFFSET_REG, 1);
-	*cmds++ = 0x00010000;
-	*cmds++ = cp_type0_packet(A3XX_SP_FS_OBJ_START_REG, 1);
-	*cmds++ = 0x00000000;
-	*cmds++ = cp_type0_packet(A3XX_SP_FS_PVT_MEM_PARAM_REG, 1);
-	*cmds++ = 0x04008001;
-	*cmds++ = cp_type0_packet(A3XX_SP_FS_PVT_MEM_ADDR_REG, 1);
-	*cmds++ = 0x00000000;
-	*cmds++ = cp_type0_packet(A3XX_SP_FS_PVT_MEM_SIZE_REG, 1);
-	*cmds++ = 0x00000000;
-	*cmds++ = cp_type0_packet(A3XX_SP_FS_FLAT_SHAD_MODE_REG_0, 1);
-	*cmds++ = 0x00000000;
-	*cmds++ = cp_type0_packet(A3XX_SP_FS_FLAT_SHAD_MODE_REG_1, 1);
-	*cmds++ = 0x00000000;
-	*cmds++ = cp_type0_packet(A3XX_SP_FS_OUTPUT_REG, 1);
-	*cmds++ = 0x00000000;
-	*cmds++ = cp_type0_packet(A3XX_SP_FS_MRT_REG_0, 1);
-	*cmds++ = 0x00000000;
-	*cmds++ = cp_type0_packet(A3XX_SP_FS_MRT_REG_1, 1);
-	*cmds++ = 0x00000000;
-	*cmds++ = cp_type0_packet(A3XX_SP_FS_MRT_REG_2, 1);
-	*cmds++ = 0x00000000;
-	*cmds++ = cp_type0_packet(A3XX_SP_FS_MRT_REG_3, 1);
-	*cmds++ = 0x00000000;
-	*cmds++ = cp_type0_packet(A3XX_SP_FS_IMAGE_OUTPUT_REG_0, 1);
-	*cmds++ = 0x00000000;
-	*cmds++ = cp_type0_packet(A3XX_SP_FS_IMAGE_OUTPUT_REG_1, 1);
-	*cmds++ = 0x00000000;
-	*cmds++ = cp_type0_packet(A3XX_SP_FS_IMAGE_OUTPUT_REG_2, 1);
-	*cmds++ = 0x00000000;
-	*cmds++ = cp_type0_packet(A3XX_SP_FS_IMAGE_OUTPUT_REG_3, 1);
-	*cmds++ = 0x00000000;
-	*cmds++ = cp_type0_packet(A3XX_SP_FS_LENGTH_REG, 1);
-	*cmds++ = count >> 3;
-	*cmds++ = cp_type0_packet(A3XX_RB_MODE_CONTROL, 1);
-	*cmds++ = 0x00008000;
-	*cmds++ = cp_type0_packet(A3XX_RB_RENDER_CONTROL, 1);
-	*cmds++ = 0x00000000;
-	*cmds++ = cp_type0_packet(A3XX_RB_MSAA_CONTROL, 1);
-	*cmds++ = 0x00000000;
-	*cmds++ = cp_type0_packet(A3XX_RB_ALPHA_REFERENCE, 1);
-	*cmds++ = 0x00000000;
-	*cmds++ = cp_type0_packet(A3XX_RB_MRT_CONTROL0, 1);
-	*cmds++ = 0x00000000;
-	*cmds++ = cp_type0_packet(A3XX_RB_MRT_CONTROL1, 1);
-	*cmds++ = 0x00000000;
-	*cmds++ = cp_type0_packet(A3XX_RB_MRT_CONTROL2, 1);
-	*cmds++ = 0x00000000;
-	*cmds++ = cp_type0_packet(A3XX_RB_MRT_CONTROL3, 1);
-	*cmds++ = 0x00000000;
-	*cmds++ = cp_type0_packet(A3XX_RB_MRT_BUF_INFO0, 1);
-	*cmds++ = 0x00000000;
-	*cmds++ = cp_type0_packet(A3XX_RB_MRT_BUF_INFO1, 1);
-	*cmds++ = 0x00000000;
-	*cmds++ = cp_type0_packet(A3XX_RB_MRT_BUF_INFO2, 1);
-	*cmds++ = 0x00000000;
-	*cmds++ = cp_type0_packet(A3XX_RB_MRT_BUF_INFO3, 1);
-	*cmds++ = 0x00000000;
-	*cmds++ = cp_type0_packet(A3XX_RB_MRT_BUF_BASE0, 1);
-	*cmds++ = 0x00000000;
-	*cmds++ = cp_type0_packet(A3XX_RB_MRT_BUF_BASE1, 1);
-	*cmds++ = 0x00000000;
-	*cmds++ = cp_type0_packet(A3XX_RB_MRT_BUF_BASE2, 1);
-	*cmds++ = 0x00000000;
-	*cmds++ = cp_type0_packet(A3XX_RB_MRT_BUF_BASE3, 1);
-	*cmds++ = 0x00000000;
-
-	*cmds++ = cp_type0_packet(A3XX_RB_PERFCOUNTER0_SELECT, 1);
-	*cmds++ = 0x00000000;
-	*cmds++ = cp_type0_packet(A3XX_RB_PERFCOUNTER1_SELECT, 1);
-	*cmds++ = 0x00000000;
-	*cmds++ = cp_type0_packet(A3XX_RB_FRAME_BUFFER_DIMENSION, 1);
-	*cmds++ = 0x00000000;
-	*cmds++ = cp_type3_packet(CP_WAIT_FOR_IDLE, 1);
-	*cmds++ = 0x00000000;
-
-	*cmds++ = cp_type3_packet(CP_LOAD_STATE, 2 + count);
-	*cmds++ = (6 << CP_LOADSTATE_STATEBLOCKID_SHIFT) |
-		  ((count >> 3) << CP_LOADSTATE_NUMOFUNITS_SHIFT);
-	*cmds++ = 0x00000000;
-	memcpy(cmds, _a3xx_pwron_fixup_fs_instructions, count << 2);
-	cmds += count;
-
-	*cmds++ = cp_type3_packet(CP_EXEC_CL, 1);
-	*cmds++ = 0x00000000;
-	*cmds++ = cp_nop_packet(1);
-	*cmds++ = 0x00000000;
-	*cmds++ = cp_type3_packet(CP_WAIT_FOR_IDLE, 1);
-	*cmds++ = 0x00000000;
-	*cmds++ = cp_type0_packet(A3XX_HLSQ_CL_CONTROL_0_REG, 1);
-	*cmds++ = 0x00000000;
-	*cmds++ = cp_type3_packet(CP_WAIT_FOR_IDLE, 1);
-	*cmds++ = 0x00000000;
-	*cmds++ = cp_type0_packet(A3XX_HLSQ_CONTROL_0_REG, 1);
-	*cmds++ = 0x1E000150;
-	*cmds++ = cp_type3_packet(CP_WAIT_FOR_IDLE, 1);
-	*cmds++ = 0x00000000;
-	*cmds++ = cp_type3_packet(CP_SET_CONSTANT, 2);
-	*cmds++ = CP_REG(A3XX_HLSQ_CONTROL_0_REG);
-	*cmds++ = 0x1E000050;
-	*cmds++ = cp_type3_packet(CP_WAIT_FOR_IDLE, 1);
-	*cmds++ = 0x00000000;
-	*cmds++ = cp_type3_packet(CP_REG_RMW, 3);
-	*cmds++ = A3XX_RBBM_CLOCK_CTL;
-	*cmds++ = 0xFFFCFFFF;
-	*cmds++ = 0x00000000;
-	*cmds++ = cp_type3_packet(CP_WAIT_FOR_IDLE, 1);
-	*cmds++ = 0x00000000;
-
-	/*
-	 * Remember the number of dwords in the command buffer for when we
-	 * program the indirect buffer call in the ringbuffer
-	 */
-	adreno_dev->pwron_fixup_dwords =
-		(cmds - (unsigned int *)adreno_dev->pwron_fixup.hostptr);
-
-	/* Mark the flag in ->priv to show that we have the fix */
-	set_bit(ADRENO_DEVICE_PWRON_FIXUP, &adreno_dev->priv);
-	return 0;
-}
-
 static int a3xx_rb_init(struct adreno_device *adreno_dev,
 			 struct adreno_ringbuffer *rb)
 {
diff --git a/drivers/gpu/msm/adreno_pm4types.h b/drivers/gpu/msm/adreno_pm4types.h
index e6ec91d..a3fa312 100644
--- a/drivers/gpu/msm/adreno_pm4types.h
+++ b/drivers/gpu/msm/adreno_pm4types.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2002,2007-2013, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2002,2007-2012, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -177,8 +177,6 @@
 /* Load a buffer with pre-fetch enabled */
 #define CP_INDIRECT_BUFFER_PFE 0x3F
 
-#define CP_EXEC_CL 0x31
-
 #define CP_LOADSTATE_DSTOFFSET_SHIFT 0x00000000
 #define CP_LOADSTATE_STATESRC_SHIFT 0x00000010
 #define CP_LOADSTATE_STATEBLOCKID_SHIFT 0x00000013
diff --git a/drivers/gpu/msm/adreno_ringbuffer.c b/drivers/gpu/msm/adreno_ringbuffer.c
index c2a0270..bc7a5c2 100644
--- a/drivers/gpu/msm/adreno_ringbuffer.c
+++ b/drivers/gpu/msm/adreno_ringbuffer.c
@@ -584,10 +584,6 @@
 	if (flags & KGSL_CMD_FLAGS_EOF)
 		total_sizedwords += 2;
 
-	/* Add space for the power on shader fixup if we need it */
-	if (flags & KGSL_CMD_FLAGS_PWRON_FIXUP)
-		total_sizedwords += 5;
-
 	ringcmds = adreno_ringbuffer_allocspace(rb, context, total_sizedwords);
 	if (!ringcmds)
 		return -ENOSPC;
@@ -595,18 +591,6 @@
 	rcmd_gpu = rb->buffer_desc.gpuaddr
 		+ sizeof(uint)*(rb->wptr-total_sizedwords);
 
-	if (flags & KGSL_CMD_FLAGS_PWRON_FIXUP) {
-		GSL_RB_WRITE(ringcmds, rcmd_gpu, cp_nop_packet(1));
-		GSL_RB_WRITE(ringcmds, rcmd_gpu,
-				KGSL_PWRON_FIXUP_IDENTIFIER);
-		GSL_RB_WRITE(ringcmds, rcmd_gpu,
-			CP_HDR_INDIRECT_BUFFER_PFD);
-		GSL_RB_WRITE(ringcmds, rcmd_gpu,
-			adreno_dev->pwron_fixup.gpuaddr);
-		GSL_RB_WRITE(ringcmds, rcmd_gpu,
-			adreno_dev->pwron_fixup_dwords);
-	}
-
 	GSL_RB_WRITE(ringcmds, rcmd_gpu, cp_nop_packet(1));
 	GSL_RB_WRITE(ringcmds, rcmd_gpu, KGSL_CMD_IDENTIFIER);
 
@@ -1085,22 +1069,9 @@
 	} else
 		drawctxt->timestamp++;
 
-	flags &= KGSL_CMD_FLAGS_EOF;
-
-	/*
-	 * For some targets, we need to execute a dummy shader operation after a
-	 * power collapse
-	 */
-
-	if (test_and_clear_bit(ADRENO_DEVICE_PWRON, &adreno_dev->priv) &&
-	    test_bit(ADRENO_DEVICE_PWRON_FIXUP, &adreno_dev->priv))
-	{
-		flags |= KGSL_CMD_FLAGS_PWRON_FIXUP;
-	}
-
 	ret = adreno_ringbuffer_addcmds(&adreno_dev->ringbuffer,
 					drawctxt,
-					flags,
+					(flags & KGSL_CMD_FLAGS_EOF),
 					&link[0], (cmds - link));
 	if (ret)
 		goto done;
diff --git a/drivers/gpu/msm/kgsl.c b/drivers/gpu/msm/kgsl.c
index 6375991..9acac1a 100755
--- a/drivers/gpu/msm/kgsl.c
+++ b/drivers/gpu/msm/kgsl.c
@@ -2949,7 +2949,7 @@
 static inline bool
 mmap_range_valid(unsigned long addr, unsigned long len)
 {
-	return (addr + len) > addr && (addr + len) < TASK_SIZE;
+	return ((ULONG_MAX - addr) > len) && ((addr + len) < TASK_SIZE);
 }
 
 static unsigned long
diff --git a/drivers/gpu/msm/kgsl.h b/drivers/gpu/msm/kgsl.h
index bf6ace7..17e6fa3 100644
--- a/drivers/gpu/msm/kgsl.h
+++ b/drivers/gpu/msm/kgsl.h
@@ -262,7 +262,7 @@
 		size = 1;
 
 	/* don't overflow */
-	if ((gpuaddr + size) < gpuaddr)
+	if (size > UINT_MAX - gpuaddr)
 		return 0;
 
 	if (gpuaddr >= memdesc->gpuaddr &&
diff --git a/drivers/gpu/msm/kgsl_sharedmem.c b/drivers/gpu/msm/kgsl_sharedmem.c
old mode 100755
new mode 100644
index de62c3a..2881e49
--- a/drivers/gpu/msm/kgsl_sharedmem.c
+++ b/drivers/gpu/msm/kgsl_sharedmem.c
@@ -552,7 +552,6 @@
 
 	sglen_alloc = PAGE_ALIGN(size) >> PAGE_SHIFT;
 
-	memdesc->size = size;
 	memdesc->pagetable = pagetable;
 	memdesc->ops = &kgsl_page_alloc_ops;
 
@@ -615,6 +614,14 @@
 				continue;
 			}
 
+			/*
+			 * Update sglen and memdesc size,as requested allocation
+			 * not served fully. So that they can be correctly freed
+			 * in kgsl_sharedmem_free().
+			 */
+			memdesc->sglen = sglen;
+			memdesc->size = (size - len);
+
 			KGSL_CORE_ERR(
 				"Out of memory: only allocated %dKB of %dKB requested\n",
 				(size - len) >> 10, size >> 10);
@@ -631,6 +638,7 @@
 	}
 
 	memdesc->sglen = sglen;
+	memdesc->size = size;
 
 	/*
 	 * All memory that goes to the user has to be zeroed out before it gets
@@ -671,15 +679,15 @@
 	outer_cache_range_op_sg(memdesc->sg, memdesc->sglen,
 				KGSL_CACHE_OP_FLUSH);
 
-	KGSL_STATS_ADD(size, kgsl_driver.stats.page_alloc,
-		kgsl_driver.stats.page_alloc_max);
-
 	order = get_order(size);
 
 	if (order < 16)
 		kgsl_driver.stats.histogram[order]++;
 
 done:
+	KGSL_STATS_ADD(memdesc->size, kgsl_driver.stats.page_alloc,
+		kgsl_driver.stats.page_alloc_max);
+
 	if ((memdesc->sglen_alloc * sizeof(struct page *)) > PAGE_SIZE)
 		vfree(pages);
 	else
diff --git a/drivers/media/media-device.c b/drivers/media/media-device.c
index 6f9eb94..4f39838 100644
--- a/drivers/media/media-device.c
+++ b/drivers/media/media-device.c
@@ -139,7 +139,7 @@
 		unsigned int p;
 
 		for (p = 0; p < entity->num_pads; p++) {
-			struct media_pad_desc pad;
+			struct media_pad_desc pad = {0};
 			media_device_kpad_to_upad(&entity->pads[p], &pad);
 			if (copy_to_user(&links.pads[p], &pad, sizeof(pad)))
 				return -EFAULT;
diff --git a/drivers/misc/qseecom.c b/drivers/misc/qseecom.c
index af65e28..3423032 100644
--- a/drivers/misc/qseecom.c
+++ b/drivers/misc/qseecom.c
@@ -294,7 +294,7 @@
 	/* Get the handle of the shared fd */
 	svc->ihandle = ion_import_dma_buf(qseecom.ion_clnt,
 					listener->ifd_data_fd);
-	if (svc->ihandle == NULL) {
+	if (IS_ERR_OR_NULL(svc->ihandle)) {
 		pr_err("Ion client could not retrieve the handle\n");
 		return -ENOMEM;
 	}
diff --git a/drivers/net/usb/rmnet_usb_data.c b/drivers/net/usb/rmnet_usb_data.c
index 079f396..11ef72d 100755
--- a/drivers/net/usb/rmnet_usb_data.c
+++ b/drivers/net/usb/rmnet_usb_data.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2013, The Linux Foundation. All rights reserved.
+/* 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
@@ -388,8 +388,6 @@
 {
 	__be16	protocol = 0;
 
-	skb->dev = dev;
-
 	switch (skb->data[0] & 0xf0) {
 	case 0x40:
 		protocol = htons(ETH_P_IP);
@@ -425,7 +423,6 @@
 			/*map urb to actual network iface based on mux id*/
 			unet_id = unet_offset + mux_id;
 			skb->dev = unet_list[unet_id]->net;
-			entry->dev = unet_list[unet_id];
 		}
 	}
 
diff --git a/drivers/net/wireless/wcnss/wcnss_wlan.c b/drivers/net/wireless/wcnss/wcnss_wlan.c
index 807cdb4..5ad2f50 100644
--- a/drivers/net/wireless/wcnss/wcnss_wlan.c
+++ b/drivers/net/wireless/wcnss/wcnss_wlan.c
@@ -42,11 +42,13 @@
 #endif
 
 #define DEVICE "wcnss_wlan"
+#define CTRL_DEVICE "wcnss_ctrl"
 #define VERSION "1.01"
 #define WCNSS_PIL_DEVICE "wcnss"
 
 /* module params */
 #define WCNSS_CONFIG_UNSPECIFIED (-1)
+#define UINT32_MAX (0xFFFFFFFFU)
 
 static int has_48mhz_xo = WCNSS_CONFIG_UNSPECIFIED;
 module_param(has_48mhz_xo, int, S_IWUSR | S_IRUGO);
@@ -74,6 +76,16 @@
 #define WCNSS_CTRL_CHANNEL			"WCNSS_CTRL"
 #define WCNSS_MAX_FRAME_SIZE		(4*1024)
 #define WCNSS_VERSION_LEN			30
+#define WCNSS_MAX_CMD_LEN		(128)
+#define WCNSS_MIN_CMD_LEN		(3)
+#define WCNSS_MIN_SERIAL_LEN		(6)
+
+/* control messages from userspace */
+#define WCNSS_USR_CTRL_MSG_START  0x00000000
+#define WCNSS_USR_SERIAL_NUM      (WCNSS_USR_CTRL_MSG_START + 1)
+#define WCNSS_USR_HAS_CAL_DATA    (WCNSS_USR_CTRL_MSG_START + 2)
+
+#define MAC_ADDRESS_STR "%02x:%02x:%02x:%02x:%02x:%02x"
 
 /* message types */
 #define WCNSS_CTRL_MSG_START	0x01000000
@@ -86,6 +98,8 @@
 #define	WCNSS_CALDATA_DNLD_REQ        (WCNSS_CTRL_MSG_START + 6)
 #define	WCNSS_CALDATA_DNLD_RSP        (WCNSS_CTRL_MSG_START + 7)
 
+/* max 20mhz channel count */
+#define WCNSS_MAX_CH_NUM			45
 
 #define VALID_VERSION(version) \
 	((strncmp(version, "INVALID", WCNSS_VERSION_LEN)) ? 1 : 0)
@@ -249,13 +263,62 @@
 	int	fw_cal_available;
 	int	user_cal_read;
 	int	user_cal_available;
-	int	user_cal_rcvd;
+	u32	user_cal_rcvd;
 	int	user_cal_exp_size;
 	int	device_opened;
+	int	ctrl_device_opened;
+	char	wlan_nv_macAddr[WLAN_MAC_ADDR_SIZE];
 	struct mutex dev_lock;
+	struct mutex ctrl_lock;
 	wait_queue_head_t read_wait;
+	u16 unsafe_ch_count;
+	u16 unsafe_ch_list[WCNSS_MAX_CH_NUM];
 } *penv = NULL;
 
+static ssize_t wcnss_wlan_macaddr_store(struct device *dev,
+		struct device_attribute *attr, const char *buf, size_t count)
+{
+	char macAddr[WLAN_MAC_ADDR_SIZE];
+
+	if (!penv)
+		return -ENODEV;
+
+	pr_debug("%s: Receive MAC Addr From user space: %s\n", __func__, buf);
+
+	if (WLAN_MAC_ADDR_SIZE != sscanf(buf, MAC_ADDRESS_STR,
+		 (int *)&macAddr[0], (int *)&macAddr[1],
+		 (int *)&macAddr[2], (int *)&macAddr[3],
+		 (int *)&macAddr[4], (int *)&macAddr[5])) {
+
+		pr_err("%s: Failed to Copy MAC\n", __func__);
+		return -EINVAL;
+	}
+
+	memcpy(penv->wlan_nv_macAddr, macAddr, sizeof(penv->wlan_nv_macAddr));
+
+	pr_info("%s: Write MAC Addr:" MAC_ADDRESS_STR "\n", __func__,
+		penv->wlan_nv_macAddr[0], penv->wlan_nv_macAddr[1],
+		penv->wlan_nv_macAddr[2], penv->wlan_nv_macAddr[3],
+		penv->wlan_nv_macAddr[4], penv->wlan_nv_macAddr[5]);
+
+	return count;
+}
+
+static ssize_t wcnss_wlan_macaddr_show(struct device *dev,
+		struct device_attribute *attr, char *buf)
+{
+	if (!penv)
+		return -ENODEV;
+
+	return scnprintf(buf, PAGE_SIZE, MAC_ADDRESS_STR,
+		penv->wlan_nv_macAddr[0], penv->wlan_nv_macAddr[1],
+		penv->wlan_nv_macAddr[2], penv->wlan_nv_macAddr[3],
+		penv->wlan_nv_macAddr[4], penv->wlan_nv_macAddr[5]);
+}
+
+static DEVICE_ATTR(wcnss_mac_addr, S_IRUSR | S_IWUSR,
+	wcnss_wlan_macaddr_show, wcnss_wlan_macaddr_store);
+
 static ssize_t wcnss_serial_number_show(struct device *dev,
 				struct device_attribute *attr, char *buf)
 {
@@ -372,8 +435,14 @@
 	if (ret)
 		goto remove_thermal;
 
+	ret = device_create_file(dev, &dev_attr_wcnss_mac_addr);
+	if (ret)
+		goto remove_version;
+
 	return 0;
 
+remove_version:
+	device_remove_file(dev, &dev_attr_wcnss_version);
 remove_thermal:
 	device_remove_file(dev, &dev_attr_thermal_mitigation);
 remove_serial:
@@ -388,6 +457,7 @@
 		device_remove_file(dev, &dev_attr_serial_number);
 		device_remove_file(dev, &dev_attr_thermal_mitigation);
 		device_remove_file(dev, &dev_attr_wcnss_version);
+		device_remove_file(dev, &dev_attr_wcnss_mac_addr);
 	}
 }
 static void wcnss_smd_notify_event(void *data, unsigned int event)
@@ -678,6 +748,20 @@
 }
 EXPORT_SYMBOL(wcnss_ssr_boot_notify);
 
+int wcnss_get_wlan_mac_address(char mac_addr[WLAN_MAC_ADDR_SIZE])
+{
+	if (!penv)
+		return -ENODEV;
+
+	memcpy(mac_addr, penv->wlan_nv_macAddr, WLAN_MAC_ADDR_SIZE);
+	pr_debug("%s: Get MAC Addr:" MAC_ADDRESS_STR "\n", __func__,
+		penv->wlan_nv_macAddr[0], penv->wlan_nv_macAddr[1],
+		penv->wlan_nv_macAddr[2], penv->wlan_nv_macAddr[3],
+		penv->wlan_nv_macAddr[4], penv->wlan_nv_macAddr[5]);
+	return 0;
+}
+EXPORT_SYMBOL(wcnss_get_wlan_mac_address);
+
 static int enable_wcnss_suspend_notify;
 
 static int enable_wcnss_suspend_notify_set(const char *val,
@@ -793,6 +877,35 @@
 		return -ENODEV;
 }
 
+int wcnss_set_wlan_unsafe_channel(u16 *unsafe_ch_list, u16 ch_count)
+{
+	if (penv && unsafe_ch_list &&
+		(ch_count <= WCNSS_MAX_CH_NUM)) {
+		memcpy((char *)penv->unsafe_ch_list,
+			(char *)unsafe_ch_list, ch_count * sizeof(u16));
+		penv->unsafe_ch_count = ch_count;
+		return 0;
+	} else
+		return -ENODEV;
+}
+EXPORT_SYMBOL(wcnss_set_wlan_unsafe_channel);
+
+int wcnss_get_wlan_unsafe_channel(u16 *unsafe_ch_list, u16 buffer_size,
+					u16 *ch_count)
+{
+	if (penv) {
+		if (buffer_size < penv->unsafe_ch_count * sizeof(u16))
+			return -ENODEV;
+		memcpy((char *)unsafe_ch_list,
+			(char *)penv->unsafe_ch_list,
+			penv->unsafe_ch_count * sizeof(u16));
+		*ch_count = penv->unsafe_ch_count;
+		return 0;
+	} else
+		return -ENODEV;
+}
+EXPORT_SYMBOL(wcnss_get_wlan_unsafe_channel);
+
 static int wcnss_smd_tx(void *data, int len)
 {
 	int ret = 0;
@@ -1288,6 +1401,80 @@
 
 
 
+static int wcnss_ctrl_open(struct inode *inode, struct file *file)
+{
+	int rc = 0;
+
+	if (!penv || penv->ctrl_device_opened)
+		return -EFAULT;
+
+	penv->ctrl_device_opened = 1;
+
+	return rc;
+}
+
+
+void process_usr_ctrl_cmd(u8 *buf, size_t len)
+{
+	u16 cmd = buf[0] << 8 | buf[1];
+
+	switch (cmd) {
+
+	case WCNSS_USR_SERIAL_NUM:
+		if (WCNSS_MIN_SERIAL_LEN > len) {
+			pr_err("%s: Invalid serial number\n", __func__);
+			return;
+		}
+		penv->serial_number = buf[2] << 24 | buf[3] << 16
+			| buf[4] << 8 | buf[5];
+		break;
+
+	case WCNSS_USR_HAS_CAL_DATA:
+		if (1 < buf[2])
+			pr_err("%s: Invalid data for cal %d\n", __func__,
+				buf[2]);
+		has_calibrated_data = buf[2];
+		break;
+
+	default:
+		pr_err("%s: Invalid command %d\n", __func__, cmd);
+		break;
+	}
+}
+
+static ssize_t wcnss_ctrl_write(struct file *fp, const char __user
+			*user_buffer, size_t count, loff_t *position)
+{
+	int rc = 0;
+	u8 buf[WCNSS_MAX_CMD_LEN];
+
+	if (!penv || !penv->ctrl_device_opened || WCNSS_MAX_CMD_LEN < count
+			|| WCNSS_MIN_CMD_LEN > count)
+		return -EFAULT;
+
+	mutex_lock(&penv->ctrl_lock);
+	rc = copy_from_user(buf, user_buffer, count);
+	if (0 == rc)
+		process_usr_ctrl_cmd(buf, count);
+
+	mutex_unlock(&penv->ctrl_lock);
+
+	return rc;
+}
+
+
+static const struct file_operations wcnss_ctrl_fops = {
+	.owner = THIS_MODULE,
+	.open = wcnss_ctrl_open,
+	.write = wcnss_ctrl_write,
+};
+
+static struct miscdevice wcnss_usr_ctrl = {
+	.minor = MISC_DYNAMIC_MINOR,
+	.name = CTRL_DEVICE,
+	.fops = &wcnss_ctrl_fops,
+};
+
 static int
 wcnss_trigger_config(struct platform_device *pdev)
 {
@@ -1390,19 +1577,17 @@
 static int wcnss_node_open(struct inode *inode, struct file *file)
 {
 	struct platform_device *pdev;
+	int rc = 0;
 
 	if (!penv)
 		return -EFAULT;
 
-	/* first open is only to trigger WCNSS platform driver */
 	if (!penv->triggered) {
 		pr_info(DEVICE " triggered by userspace\n");
 		pdev = penv->pdev;
-		return wcnss_trigger_config(pdev);
-
-	} else if (penv->device_opened) {
-		pr_info(DEVICE " already opened\n");
-		return -EBUSY;
+		rc = wcnss_trigger_config(pdev);
+		if (rc)
+			return -EFAULT;
 	}
 
 	mutex_lock(&penv->dev_lock);
@@ -1413,7 +1598,7 @@
 	penv->device_opened = 1;
 	mutex_unlock(&penv->dev_lock);
 
-	return 0;
+	return rc;
 }
 
 static ssize_t wcnss_wlan_read(struct file *fp, char __user
@@ -1458,7 +1643,7 @@
 			*user_buffer, size_t count, loff_t *position)
 {
 	int rc = 0;
-	int size = 0;
+	size_t size = 0;
 
 	if (!penv || !penv->device_opened || penv->user_cal_available)
 		return -EFAULT;
@@ -1466,7 +1651,7 @@
 	if (penv->user_cal_rcvd == 0 && count >= 4
 			&& !penv->user_cal_data) {
 		rc = copy_from_user((void *)&size, user_buffer, 4);
-		if (size > MAX_CALIBRATED_DATA_SIZE) {
+		if (!size || size > MAX_CALIBRATED_DATA_SIZE) {
 			pr_err(DEVICE " invalid size to write %d\n", size);
 			return -EFAULT;
 		}
@@ -1485,7 +1670,8 @@
 	} else if (penv->user_cal_rcvd == 0 && count < 4)
 		return -EFAULT;
 
-	if (MAX_CALIBRATED_DATA_SIZE < count + penv->user_cal_rcvd) {
+	if ((UINT32_MAX - count < penv->user_cal_rcvd) ||
+	     MAX_CALIBRATED_DATA_SIZE < count + penv->user_cal_rcvd) {
 		pr_err(DEVICE " invalid size to write %d\n", count +
 				penv->user_cal_rcvd);
 		rc = -ENOMEM;
@@ -1545,6 +1731,7 @@
 		return -ENOENT;
 
 	mutex_init(&penv->dev_lock);
+	mutex_init(&penv->ctrl_lock);
 	init_waitqueue_head(&penv->read_wait);
 
 	/*
@@ -1557,6 +1744,9 @@
 	 * place
 	 */
 	pr_info(DEVICE " probed in built-in mode\n");
+
+	misc_register(&wcnss_usr_ctrl);
+
 	return misc_register(&wcnss_misc);
 
 }
diff --git a/drivers/tty/serial/msm_serial_hs.c b/drivers/tty/serial/msm_serial_hs.c
index 61049d8..41da325 100644
--- a/drivers/tty/serial/msm_serial_hs.c
+++ b/drivers/tty/serial/msm_serial_hs.c
@@ -1973,6 +1973,12 @@
 	struct msm_hs_port *msm_uport = UARTDM_TO_MSM(uport);
 
 	spin_lock_irqsave(&uport->lock, flags);
+	if (msm_uport->is_shutdown) {
+		pr_err("%s:Clock OFF fail.UART port is closed\n", __func__);
+		spin_unlock_irqrestore(&uport->lock, flags);
+		return;
+	}
+
 	if (msm_uport->clk_state == MSM_HS_CLK_ON) {
 		msm_uport->clk_state = MSM_HS_CLK_REQUEST_OFF;
 		msm_uport->clk_req_off_state = CLK_REQ_OFF_START;
@@ -1998,6 +2004,13 @@
 	mutex_lock(&msm_uport->clk_mutex);
 	spin_lock_irqsave(&uport->lock, flags);
 
+	if (msm_uport->is_shutdown) {
+		pr_err("%s:Clock ON fail.UART port is closed\n", __func__);
+		spin_unlock_irqrestore(&uport->lock, flags);
+		mutex_unlock(&msm_uport->clk_mutex);
+		return;
+	}
+
 	switch (msm_uport->clk_state) {
 	case MSM_HS_CLK_OFF:
 		wake_lock(&msm_uport->dma_wake_lock);
@@ -2491,6 +2504,7 @@
 	uport->flags = UPF_BOOT_AUTOCONF;
 	uport->uartclk = 7372800;
 	msm_uport->imr_reg = 0x0;
+	msm_uport->is_shutdown = true;
 
 	msm_uport->clk = clk_get(&pdev->dev, "core_clk");
 	if (IS_ERR(msm_uport->clk))
diff --git a/drivers/uio/uio.c b/drivers/uio/uio.c
index 7150752..0470194 100644
--- a/drivers/uio/uio.c
+++ b/drivers/uio/uio.c
@@ -640,12 +640,26 @@
 	return 0;
 }
 
-static const struct vm_operations_struct uio_vm_ops = {
+static const struct vm_operations_struct uio_logical_vm_ops = {
 	.open = uio_vma_open,
 	.close = uio_vma_close,
 	.fault = uio_vma_fault,
 };
 
+static int uio_mmap_logical(struct vm_area_struct *vma)
+{
+	vma->vm_flags |= VM_DONTEXPAND | VM_NODUMP;
+	vma->vm_ops = &uio_logical_vm_ops;
+	uio_vma_open(vma);
+	return 0;
+}
+
+static const struct vm_operations_struct uio_physical_vm_ops = {
+#ifdef CONFIG_HAVE_IOREMAP_PROT
+	.access = generic_access_phys,
+#endif
+};
+
 static int uio_mmap_physical(struct vm_area_struct *vma)
 {
 	struct uio_device *idev = vma->vm_private_data;
@@ -658,8 +672,7 @@
 	if (vma->vm_end - vma->vm_start > mem->size)
 		return -EINVAL;
 
-	vma->vm_flags |= VM_IO | VM_RESERVED;
-
+	vma->vm_ops = &uio_physical_vm_ops;
 	vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
 
 	/*
@@ -671,6 +684,7 @@
 	 * So we just do the physical mmap without a page
 	 * offset.
 	 */
+
 	return remap_pfn_range(vma,
 			       vma->vm_start,
 			       mem->addr >> PAGE_SHIFT,
@@ -678,14 +692,6 @@
 			       vma->vm_page_prot);
 }
 
-static int uio_mmap_logical(struct vm_area_struct *vma)
-{
-	vma->vm_flags |= VM_RESERVED;
-	vma->vm_ops = &uio_vm_ops;
-	uio_vma_open(vma);
-	return 0;
-}
-
 static int uio_mmap(struct file *filep, struct vm_area_struct *vma)
 {
 	struct uio_listener *listener = filep->private_data;
diff --git a/drivers/video/au1100fb.c b/drivers/video/au1100fb.c
index 612c1c7..1d8d91a 100644
--- a/drivers/video/au1100fb.c
+++ b/drivers/video/au1100fb.c
@@ -381,8 +381,6 @@
 	vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
 	pgprot_val(vma->vm_page_prot) |= (6 << 9); //CCA=6
 
-	vma->vm_flags |= VM_IO;
-
 	return vm_iomap_memory(vma, fbdev->fb_phys, fbdev->fb_len);
 }
 
diff --git a/drivers/video/au1200fb.c b/drivers/video/au1200fb.c
index 117be3d..e2729b9 100644
--- a/drivers/video/au1200fb.c
+++ b/drivers/video/au1200fb.c
@@ -1239,11 +1239,7 @@
 	vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
 	pgprot_val(vma->vm_page_prot) |= _CACHE_MASK; /* CCA=7 */
 
-	vma->vm_flags |= VM_IO;
-
 	return vm_iomap_memory(vma, fbdev->fb_phys, fbdev->fb_len);
-
-	return 0;
 }
 
 static void set_global(u_int cmd, struct au1200_lcd_global_regs_t *pdata)
diff --git a/drivers/video/msm/mdp4_overlay.c b/drivers/video/msm/mdp4_overlay.c
index cfa0bbb..60cca2f 100644
--- a/drivers/video/msm/mdp4_overlay.c
+++ b/drivers/video/msm/mdp4_overlay.c
@@ -2834,16 +2834,13 @@
 	pr_debug("%s: the right %d shifted xscale is %d.\n",
 		 __func__, shift, xscale);
 
-	if (src_h > dst_h) {
-		yscale = src_h;
-		yscale <<= shift;
-		yscale /= dst_h;
-	} else {		/* upscale */
-		yscale = dst_h;
-		yscale <<= shift;
-		yscale /= src_h;
-	}
+	if (src_h > dst_h)
+	        yscale = src_h;
+	else
+                yscale = dst_h;
 
+        yscale <<= shift;
+        yscale /= dst_h;
 	yscale *= src_w;
 	yscale /= hsync;
 
diff --git a/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_shared_mem.c b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_shared_mem.c
index 62012b9..0d12194 100644
--- a/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_shared_mem.c
+++ b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_shared_mem.c
@@ -91,6 +91,8 @@
 #define VIDC_SM_ENC_EXT_CTRL_AU_DELIMITER_EN_SHFT    11
 #define VIDC_SM_ENC_EXT_CTRL_LONG_TERM_REF_ENABLE_BMSK 0x00000400
 #define VIDC_SM_ENC_EXT_CTRL_LONG_TERM_REF_ENABLE_SHFT 10
+#define VIDC_SM_ENC_EXT_CTRL_PIC_ORDER_ENABLE_BMSK  0x200
+#define VIDC_SM_ENC_EXT_CTRL_PIC_ORDER_ENABLE_SHFT  9
 #define VIDC_SM_ENC_EXT_CTRL_H263_CPCFC_ENABLE_BMSK  0x80
 #define VIDC_SM_ENC_EXT_CTRL_H263_CPCFC_ENABLE_SHFT  7
 #define VIDC_SM_ENC_EXT_CTRL_SPS_PPS_CONTROL_BMSK    0X100
@@ -482,7 +484,7 @@
 	*shared_mem, u32 hec_enable,
 	enum VIDC_SM_frame_skip frame_skip_mode,
 	u32 seq_hdr_in_band, u32 vbv_buffer_size, u32 cpcfc_enable,
-	u32 sps_pps_control, u32 closed_gop_enable,
+	u32 sps_pps_control, u32 pic_order_count, u32 closed_gop_enable,
 	u32 au_delim_enable, u32 vui_timing_info_enable,
 	u32 restrict_bitstream_enable, u32 ltr_enable)
 {
@@ -505,6 +507,9 @@
 			VIDC_SETFIELD((sps_pps_control) ? 1 : 0,
 			VIDC_SM_ENC_EXT_CTRL_SPS_PPS_CONTROL_SHFT,
 			VIDC_SM_ENC_EXT_CTRL_SPS_PPS_CONTROL_BMSK) |
+			VIDC_SETFIELD((pic_order_count) ? 1 : 0,
+			VIDC_SM_ENC_EXT_CTRL_PIC_ORDER_ENABLE_SHFT,
+			VIDC_SM_ENC_EXT_CTRL_PIC_ORDER_ENABLE_BMSK) |
 			VIDC_SETFIELD(closed_gop_enable,
 			VIDC_SM_ENC_EXT_CTRL_CLOSED_GOP_ENABLE_SHFT,
 			VIDC_SM_ENC_EXT_CTRL_CLOSED_GOP_ENABLE_BMSK) |
diff --git a/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_shared_mem.h b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_shared_mem.h
index 5c0db51..84281a3 100644
--- a/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_shared_mem.h
+++ b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_shared_mem.h
@@ -106,8 +106,9 @@
 	struct ddl_buf_addr *shared_mem, u32 hec_enable,
 	enum VIDC_SM_frame_skip  frame_skip_mode, u32 seq_hdr_in_band,
 	u32 vbv_buffer_size, u32 cpcfc_enable, u32 sps_pps_control,
-	u32 closed_gop_enable, u32 au_delim_enable, u32 vui_timing_info_enable,
-	u32 restrict_bitstream_enable, u32 ltr_enable);
+	u32 pic_order_count, u32 closed_gop_enable, u32 au_delim_enable,
+	u32 vui_timing_info_enable, u32 restrict_bitstream_enable,
+	u32 ltr_enable);
 void vidc_sm_set_encoder_param_change(struct ddl_buf_addr *shared_mem,
 	u32 bit_rate_chg, u32 frame_rate_chg, u32 i_period_chg);
 void vidc_sm_set_encoder_vop_time(struct ddl_buf_addr *shared_mem,
diff --git a/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_vidc.c b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_vidc.c
index d985c66..11cc1f4 100644
--- a/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_vidc.c
+++ b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_vidc.c
@@ -600,6 +600,7 @@
 	const u32 recon_bufs = 4;
 	u32 h263_cpfc_enable = false;
 	u32 scaled_frame_rate, ltr_enable;
+	u32 pic_order_count = false;
 
 	ddl_vidc_encode_set_profile_level(ddl);
 	vidc_1080p_set_encode_frame_size(encoder->frame_size.width,
@@ -620,14 +621,17 @@
 		(DDL_FRAMERATE_SCALE(DDL_INITIAL_FRAME_RATE)
 		 != scaled_frame_rate))
 		h263_cpfc_enable = true;
+	if (encoder->codec.codec == VCD_CODEC_H264)
+		pic_order_count = true;
+
 	ltr_enable = DDL_IS_LTR_ENABLED(encoder);
 	DDL_MSG_HIGH("ltr_enable = %u", ltr_enable);
 	vidc_sm_set_extended_encoder_control(&ddl->shared_mem
 		[ddl->command_channel], hdr_ext_control,
 		r_cframe_skip, false, 0,
 		h263_cpfc_enable, encoder->sps_pps.sps_pps_for_idr_enable_flag,
-		encoder->closed_gop, encoder->avc_delimiter_enable,
-		encoder->vui_timinginfo_enable,
+		pic_order_count, encoder->closed_gop, encoder->
+		avc_delimiter_enable, encoder->vui_timinginfo_enable,
 		encoder->bitstream_restrict_enable, ltr_enable);
 	if (encoder->vui_timinginfo_enable) {
 		vidc_sm_set_h264_encoder_timing_info(
diff --git a/include/linux/qrng.h b/include/linux/qrng.h
new file mode 100755
index 0000000..8c09627
--- /dev/null
+++ b/include/linux/qrng.h
@@ -0,0 +1,12 @@
+#ifndef _QRNG_H_
+#define _QRNG_H_
+
+#include <linux/types.h>
+#include <linux/ioctl.h>
+
+#define QRNG_IOC_MAGIC    0x100
+
+#define QRNG_IOCTL_RESET_BUS_BANDWIDTH\
+	_IO(QRNG_IOC_MAGIC, 1)
+
+#endif /* _QRNG_H_ */
diff --git a/include/linux/wcnss_wlan.h b/include/linux/wcnss_wlan.h
index 2180dbb..5e0b71e 100644
--- a/include/linux/wcnss_wlan.h
+++ b/include/linux/wcnss_wlan.h
@@ -34,6 +34,7 @@
 #define WCNSS_WLAN_IRQ_INVALID -1
 #define HAVE_WCNSS_RESET_INTR 1
 #define HAVE_WCNSS_CAL_DOWNLOAD 1
+#define WLAN_MAC_ADDR_SIZE (6)
 
 struct device *wcnss_wlan_get_device(void);
 struct resource *wcnss_wlan_get_memory_map(struct device *dev);
@@ -56,6 +57,7 @@
 int free_riva_power_on_lock(char *driver_name);
 unsigned int wcnss_get_serial_number(void);
 void wcnss_flush_delayed_boot_votes(void);
+int wcnss_get_wlan_mac_address(char mac_addr[WLAN_MAC_ADDR_SIZE]);
 void wcnss_allow_suspend(void);
 void wcnss_prevent_suspend(void);
 void wcnss_ssr_boot_notify(void);
@@ -65,7 +67,11 @@
 int wcnss_prealloc_put(void *ptr);
 int wcnss_device_ready(void);
 int wcnss_wlan_iris_xo_mode(void);
-
+int wcnss_set_wlan_unsafe_channel(
+				u16 *unsafe_ch_list, u16 ch_count);
+int wcnss_get_wlan_unsafe_channel(
+				u16 *unsafe_ch_list, u16 buffer_size,
+				u16 *ch_count);
 #define wcnss_wlan_get_drvdata(dev) dev_get_drvdata(dev)
 #define wcnss_wlan_set_drvdata(dev, data) dev_set_drvdata((dev), (data))
 
diff --git a/include/net/ipv6.h b/include/net/ipv6.h
index fa7af91..1fdc2df 100644
--- a/include/net/ipv6.h
+++ b/include/net/ipv6.h
@@ -253,6 +253,14 @@
 		atomic_dec(&fl->users);
 }
 
+extern void icmpv6_notify(struct sk_buff *skb, u8 type, u8 code, __be32 info);
+
+int icmpv6_push_pending_frames(struct sock *sk, struct flowi6 *fl6,
+			       struct icmp6hdr *thdr, int len);
+
+struct dst_entry *icmpv6_route_lookup(struct net *net, struct sk_buff *skb,
+				      struct sock *sk, struct flowi6 *fl6);
+
 extern int 			ip6_ra_control(struct sock *sk, int sel);
 
 extern int			ipv6_parse_hopopts(struct sk_buff *skb);
@@ -295,6 +303,18 @@
 	return __ipv6_addr_src_scope(__ipv6_addr_type(addr));
 }
 
+static inline bool __ipv6_addr_needs_scope_id(int type)
+{
+	return type & IPV6_ADDR_LINKLOCAL ||
+	       (type & IPV6_ADDR_MULTICAST &&
+		(type & (IPV6_ADDR_LOOPBACK|IPV6_ADDR_LINKLOCAL)));
+}
+
+static inline __u32 ipv6_iface_scope_id(const struct in6_addr *addr, int iface)
+{
+	return __ipv6_addr_needs_scope_id(__ipv6_addr_type(addr)) ? iface : 0;
+}
+
 static inline int ipv6_addr_cmp(const struct in6_addr *a1, const struct in6_addr *a2)
 {
 	return memcmp(a1, a2, sizeof(struct in6_addr));
diff --git a/include/net/ping.h b/include/net/ping.h
index 682b5ae..c78c083 100644
--- a/include/net/ping.h
+++ b/include/net/ping.h
@@ -13,6 +13,7 @@
 #ifndef _PING_H
 #define _PING_H
 
+#include <net/icmp.h>
 #include <net/netns/hash.h>
 
 /* PING_HTABLE_SIZE must be power of 2 */
@@ -28,6 +29,19 @@
  */
 #define GID_T_MAX (((gid_t)~0U) >> 1)
 
+/* Compatibility glue so we can support IPv6 when it's compiled as a module */
+struct pingv6_ops {
+	int (*ipv6_recv_error)(struct sock *sk, struct msghdr *msg, int len,
+			       int *addr_len);
+	int (*datagram_recv_ctl)(struct sock *sk, struct msghdr *msg,
+				 struct sk_buff *skb);
+	int (*icmpv6_err_convert)(u8 type, u8 code, int *err);
+	void (*ipv6_icmp_error)(struct sock *sk, struct sk_buff *skb, int err,
+				__be16 port, u32 info, u8 *payload);
+	int (*ipv6_chk_addr)(struct net *net, const struct in6_addr *addr,
+			     struct net_device *dev, int strict);
+};
+
 struct ping_table {
 	struct hlist_nulls_head	hash[PING_HTABLE_SIZE];
 	rwlock_t		lock;
@@ -39,10 +53,40 @@
 };
 
 extern struct proto ping_prot;
+extern struct ping_table ping_table;
+#if IS_ENABLED(CONFIG_IPV6)
+extern struct pingv6_ops pingv6_ops;
+#endif
 
+struct pingfakehdr {
+	struct icmphdr icmph;
+	struct iovec *iov;
+	sa_family_t family;
+	__wsum wcheck;
+};
 
-extern void ping_rcv(struct sk_buff *);
-extern void ping_err(struct sk_buff *, u32 info);
+int  ping_get_port(struct sock *sk, unsigned short ident);
+void ping_hash(struct sock *sk);
+void ping_unhash(struct sock *sk);
+
+int  ping_init_sock(struct sock *sk);
+void ping_close(struct sock *sk, long timeout);
+int  ping_bind(struct sock *sk, struct sockaddr *uaddr, int addr_len);
+void ping_err(struct sk_buff *skb, int offset, u32 info);
+void ping_v4_err(struct sk_buff *skb, u32 info);
+int  ping_getfrag(void *from, char *to, int offset, int fraglen, int odd,
+		  struct sk_buff *);
+
+int  ping_recvmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg,
+		  size_t len, int noblock, int flags, int *addr_len);
+int  ping_common_sendmsg(int family, struct msghdr *msg, size_t len,
+			 void *user_icmph, size_t icmph_len);
+int  ping_v4_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg,
+		     size_t len);
+int  ping_v6_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg,
+		     size_t len);
+int  ping_queue_rcv_skb(struct sock *sk, struct sk_buff *skb);
+void ping_rcv(struct sk_buff *skb);
 
 #ifdef CONFIG_PROC_FS
 extern int __init ping_proc_init(void);
@@ -50,6 +94,7 @@
 #endif
 
 void __init ping_init(void);
-
+int  __init pingv6_init(void);
+void pingv6_exit(void);
 
 #endif /* _PING_H */
diff --git a/include/net/tcp.h b/include/net/tcp.h
index 269e99f..c3481e2 100644
--- a/include/net/tcp.h
+++ b/include/net/tcp.h
@@ -130,6 +130,8 @@
 						 * valid RTT sample has been acquired,
 						 * most likely due to retrans in 3WHS.
 						 */
+/* Number of full MSS to receive before Acking RFC2581 */
+#define TCP_DELACK_SEG          1
 
 #define TCP_RESOURCE_PROBE_INTERVAL ((unsigned)(HZ/2U)) /* Maximal interval between probes
 					                 * for local resources.
@@ -255,6 +257,10 @@
 extern int sysctl_tcp_challenge_ack_limit;
 
 extern atomic_long_t tcp_memory_allocated;
+
+/* sysctl variables for controlling various tcp parameters */
+extern int sysctl_tcp_delack_seg;
+extern int sysctl_tcp_use_userconfig;
 extern struct percpu_counter tcp_sockets_allocated;
 extern int tcp_memory_pressure;
 
@@ -346,6 +352,11 @@
 extern ssize_t tcp_splice_read(struct socket *sk, loff_t *ppos,
 			       struct pipe_inode_info *pipe, size_t len,
 			       unsigned int flags);
+/* sysctl master controller */
+extern int tcp_use_userconfig_sysctl_handler(struct ctl_table *, int,
+				void __user *, size_t *, loff_t *);
+extern int tcp_proc_delayed_ack_control(struct ctl_table *, int,
+				void __user *, size_t *, loff_t *);
 
 static inline void tcp_dec_quickack_mode(struct sock *sk,
 					 const unsigned int pkts)
diff --git a/include/net/transp_v6.h b/include/net/transp_v6.h
index 6f1470f..73ea805 100644
--- a/include/net/transp_v6.h
+++ b/include/net/transp_v6.h
@@ -11,6 +11,7 @@
 extern struct proto udpv6_prot;
 extern struct proto udplitev6_prot;
 extern struct proto tcpv6_prot;
+extern struct proto pingv6_prot;
 
 struct flowi6;
 
@@ -23,6 +24,8 @@
 extern void				ipv6_frag_exit(void);
 
 /* transport protocols */
+extern int				pingv6_init(void);
+extern void				pingv6_exit(void);
 extern int				rawv6_init(void);
 extern void				rawv6_exit(void);
 extern int				udpv6_init(void);
diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
index 7ecbc70..d369e4c 100644
--- a/net/bluetooth/hci_core.c
+++ b/net/bluetooth/hci_core.c
@@ -1457,7 +1457,7 @@
 		head = p; id++;
 	}
 
-	sprintf(hdev->name, "hci%d", id);
+	snprintf(hdev->name, sizeof(hdev->name), "hci%d", id);
 	hdev->id = id;
 	list_add(&hdev->list, head);
 
diff --git a/net/ipv4/af_inet.c b/net/ipv4/af_inet.c
index de5ec03..2cdd9e3 100644
--- a/net/ipv4/af_inet.c
+++ b/net/ipv4/af_inet.c
@@ -1564,7 +1564,7 @@
 
 static const struct net_protocol icmp_protocol = {
 	.handler =	icmp_rcv,
-	.err_handler =	ping_err,
+	.err_handler =	ping_v4_err,
 	.no_policy =	1,
 	.netns_ok =	1,
 };
diff --git a/net/ipv4/fib_trie.c b/net/ipv4/fib_trie.c
index 424704a..4d62a9c 100644
--- a/net/ipv4/fib_trie.c
+++ b/net/ipv4/fib_trie.c
@@ -367,7 +367,7 @@
 
 static inline void free_leaf(struct leaf *l)
 {
-	call_rcu_bh(&l->rcu, __leaf_free_rcu);
+	call_rcu(&l->rcu, __leaf_free_rcu);
 }
 
 static inline void free_leaf_info(struct leaf_info *leaf)
diff --git a/net/ipv4/icmp.c b/net/ipv4/icmp.c
index 2cb2bf8..2e109ff 100644
--- a/net/ipv4/icmp.c
+++ b/net/ipv4/icmp.c
@@ -788,7 +788,7 @@
 	if (iph->protocol == IPPROTO_ICMP &&
 	    iph->ihl >= 5 &&
 	    pskb_may_pull(skb, (iph->ihl<<2)+8)) {
-		ping_err(skb, icmp_hdr(skb)->un.gateway);
+		ping_v4_err(skb, icmp_hdr(skb)->un.gateway);
 	}
 
 out:
diff --git a/net/ipv4/ping.c b/net/ipv4/ping.c
index e80db1e..bf075f9 100644
--- a/net/ipv4/ping.c
+++ b/net/ipv4/ping.c
@@ -33,7 +33,6 @@
 #include <linux/netdevice.h>
 #include <net/snmp.h>
 #include <net/ip.h>
-#include <net/ipv6.h>
 #include <net/icmp.h>
 #include <net/protocol.h>
 #include <linux/skbuff.h>
@@ -46,8 +45,18 @@
 #include <net/inet_common.h>
 #include <net/checksum.h>
 
+#if IS_ENABLED(CONFIG_IPV6)
+#include <linux/in6.h>
+#include <linux/icmpv6.h>
+#include <net/addrconf.h>
+#include <net/ipv6.h>
+#include <net/transp_v6.h>
+#endif
 
-static struct ping_table ping_table;
+
+struct ping_table ping_table;
+struct pingv6_ops pingv6_ops;
+EXPORT_SYMBOL_GPL(pingv6_ops);
 
 static u16 ping_port_rover;
 
@@ -57,6 +66,7 @@
 	pr_debug("hash(%d) = %d\n", num, res);
 	return res;
 }
+EXPORT_SYMBOL_GPL(ping_hash);
 
 static inline struct hlist_nulls_head *ping_hashslot(struct ping_table *table,
 					     struct net *net, unsigned num)
@@ -64,7 +74,7 @@
 	return &table->hash[ping_hashfn(net, num, PING_HTABLE_MASK)];
 }
 
-static int ping_v4_get_port(struct sock *sk, unsigned short ident)
+int ping_get_port(struct sock *sk, unsigned short ident)
 {
 	struct hlist_nulls_node *node;
 	struct hlist_nulls_head *hlist;
@@ -102,6 +112,10 @@
 		ping_portaddr_for_each_entry(sk2, node, hlist) {
 			isk2 = inet_sk(sk2);
 
+			/* BUG? Why is this reuse and not reuseaddr? ping.c
+			 * doesn't turn off SO_REUSEADDR, and it doesn't expect
+			 * that other ping processes can steal its packets.
+			 */
 			if ((isk2->inet_num == ident) &&
 			    (sk2 != sk) &&
 			    (!sk2->sk_reuse || !sk->sk_reuse))
@@ -124,17 +138,18 @@
 	write_unlock_bh(&ping_table.lock);
 	return 1;
 }
+EXPORT_SYMBOL_GPL(ping_get_port);
 
-static void ping_v4_hash(struct sock *sk)
+void ping_hash(struct sock *sk)
 {
-	pr_debug("ping_v4_hash(sk->port=%u)\n", inet_sk(sk)->inet_num);
+	pr_debug("ping_hash(sk->port=%u)\n", inet_sk(sk)->inet_num);
 	BUG(); /* "Please do not press this button again." */
 }
 
-static void ping_v4_unhash(struct sock *sk)
+void ping_unhash(struct sock *sk)
 {
 	struct inet_sock *isk = inet_sk(sk);
-	pr_debug("ping_v4_unhash(isk=%p,isk->num=%u)\n", isk, isk->inet_num);
+	pr_debug("ping_unhash(isk=%p,isk->num=%u)\n", isk, isk->inet_num);
 	if (sk_hashed(sk)) {
 		write_lock_bh(&ping_table.lock);
 		hlist_nulls_del(&sk->sk_nulls_node);
@@ -145,31 +160,61 @@
 		write_unlock_bh(&ping_table.lock);
 	}
 }
+EXPORT_SYMBOL_GPL(ping_unhash);
 
-static struct sock *ping_v4_lookup(struct net *net, __be32 saddr, __be32 daddr,
-				   u16 ident, int dif)
+static struct sock *ping_lookup(struct net *net, struct sk_buff *skb, u16 ident)
 {
 	struct hlist_nulls_head *hslot = ping_hashslot(&ping_table, net, ident);
 	struct sock *sk = NULL;
 	struct inet_sock *isk;
 	struct hlist_nulls_node *hnode;
+	int dif = skb->dev->ifindex;
 
-	pr_debug("try to find: num = %d, daddr = %pI4, dif = %d\n",
-		 (int)ident, &daddr, dif);
+	if (skb->protocol == htons(ETH_P_IP)) {
+		pr_debug("try to find: num = %d, daddr = %pI4, dif = %d\n",
+			 (int)ident, &ip_hdr(skb)->daddr, dif);
+#if IS_ENABLED(CONFIG_IPV6)
+	} else if (skb->protocol == htons(ETH_P_IPV6)) {
+		pr_debug("try to find: num = %d, daddr = %pI6c, dif = %d\n",
+			 (int)ident, &ipv6_hdr(skb)->daddr, dif);
+#endif
+	}
+
 	read_lock_bh(&ping_table.lock);
 
 	ping_portaddr_for_each_entry(sk, hnode, hslot) {
 		isk = inet_sk(sk);
 
-		pr_debug("found: %p: num = %d, daddr = %pI4, dif = %d\n", sk,
-			 (int)isk->inet_num, &isk->inet_rcv_saddr,
-			 sk->sk_bound_dev_if);
-
 		pr_debug("iterate\n");
 		if (isk->inet_num != ident)
 			continue;
-		if (isk->inet_rcv_saddr && isk->inet_rcv_saddr != daddr)
-			continue;
+
+		if (skb->protocol == htons(ETH_P_IP) &&
+		    sk->sk_family == AF_INET) {
+			pr_debug("found: %p: num=%d, daddr=%pI4, dif=%d\n", sk,
+				 (int) isk->inet_num, &isk->inet_rcv_saddr,
+				 sk->sk_bound_dev_if);
+
+			if (isk->inet_rcv_saddr &&
+			    isk->inet_rcv_saddr != ip_hdr(skb)->daddr)
+				continue;
+#if IS_ENABLED(CONFIG_IPV6)
+		} else if (skb->protocol == htons(ETH_P_IPV6) &&
+			   sk->sk_family == AF_INET6) {
+			struct ipv6_pinfo *np = inet6_sk(sk);
+
+			pr_debug("found: %p: num=%d, daddr=%pI6c, dif=%d\n", sk,
+				 (int) isk->inet_num,
+				 &inet6_sk(sk)->rcv_saddr,
+				 sk->sk_bound_dev_if);
+
+			if (!ipv6_addr_any(&np->rcv_saddr) &&
+			    !ipv6_addr_equal(&np->rcv_saddr,
+					     &ipv6_hdr(skb)->daddr))
+				continue;
+#endif
+		}
+
 		if (sk->sk_bound_dev_if && sk->sk_bound_dev_if != dif)
 			continue;
 
@@ -198,7 +243,7 @@
 }
 
 
-static int ping_init_sock(struct sock *sk)
+int ping_init_sock(struct sock *sk)
 {
 	struct net *net = sock_net(sk);
 	gid_t group = current_egid();
@@ -224,8 +269,9 @@
 
 	return -EACCES;
 }
+EXPORT_SYMBOL_GPL(ping_init_sock);
 
-static void ping_close(struct sock *sk, long timeout)
+void ping_close(struct sock *sk, long timeout)
 {
 	pr_debug("ping_close(sk=%p,sk->num=%u)\n",
 		 inet_sk(sk), inet_sk(sk)->inet_num);
@@ -233,36 +279,122 @@
 
 	sk_common_release(sk);
 }
+EXPORT_SYMBOL_GPL(ping_close);
 
+/* Checks the bind address and possibly modifies sk->sk_bound_dev_if. */
+int ping_check_bind_addr(struct sock *sk, struct inet_sock *isk,
+			 struct sockaddr *uaddr, int addr_len) {
+	struct net *net = sock_net(sk);
+	if (sk->sk_family == AF_INET) {
+		struct sockaddr_in *addr = (struct sockaddr_in *) uaddr;
+		int chk_addr_ret;
+
+		if (addr_len < sizeof(*addr))
+			return -EINVAL;
+
+		pr_debug("ping_check_bind_addr(sk=%p,addr=%pI4,port=%d)\n",
+			 sk, &addr->sin_addr.s_addr, ntohs(addr->sin_port));
+
+		chk_addr_ret = inet_addr_type(net, addr->sin_addr.s_addr);
+
+		if (addr->sin_addr.s_addr == htonl(INADDR_ANY))
+			chk_addr_ret = RTN_LOCAL;
+
+		if ((sysctl_ip_nonlocal_bind == 0 &&
+		    isk->freebind == 0 && isk->transparent == 0 &&
+		     chk_addr_ret != RTN_LOCAL) ||
+		    chk_addr_ret == RTN_MULTICAST ||
+		    chk_addr_ret == RTN_BROADCAST)
+			return -EADDRNOTAVAIL;
+
+#if IS_ENABLED(CONFIG_IPV6)
+	} else if (sk->sk_family == AF_INET6) {
+		struct sockaddr_in6 *addr = (struct sockaddr_in6 *) uaddr;
+		int addr_type, scoped, has_addr;
+		struct net_device *dev = NULL;
+
+		if (addr_len < sizeof(*addr))
+			return -EINVAL;
+
+		pr_debug("ping_check_bind_addr(sk=%p,addr=%pI6c,port=%d)\n",
+			 sk, addr->sin6_addr.s6_addr, ntohs(addr->sin6_port));
+
+		addr_type = ipv6_addr_type(&addr->sin6_addr);
+		scoped = __ipv6_addr_needs_scope_id(addr_type);
+		if ((addr_type != IPV6_ADDR_ANY &&
+		     !(addr_type & IPV6_ADDR_UNICAST)) ||
+		    (scoped && !addr->sin6_scope_id))
+			return -EINVAL;
+
+		rcu_read_lock();
+		if (addr->sin6_scope_id) {
+			dev = dev_get_by_index_rcu(net, addr->sin6_scope_id);
+			if (!dev) {
+				rcu_read_unlock();
+				return -ENODEV;
+			}
+		}
+		has_addr = pingv6_ops.ipv6_chk_addr(net, &addr->sin6_addr, dev,
+						    scoped);
+		rcu_read_unlock();
+
+		if (!(isk->freebind || isk->transparent || has_addr ||
+		      addr_type == IPV6_ADDR_ANY))
+			return -EADDRNOTAVAIL;
+
+		if (scoped)
+			sk->sk_bound_dev_if = addr->sin6_scope_id;
+#endif
+	} else {
+		return -EAFNOSUPPORT;
+	}
+	return 0;
+}
+
+void ping_set_saddr(struct sock *sk, struct sockaddr *saddr)
+{
+	if (saddr->sa_family == AF_INET) {
+		struct inet_sock *isk = inet_sk(sk);
+		struct sockaddr_in *addr = (struct sockaddr_in *) saddr;
+		isk->inet_rcv_saddr = isk->inet_saddr = addr->sin_addr.s_addr;
+#if IS_ENABLED(CONFIG_IPV6)
+	} else if (saddr->sa_family == AF_INET6) {
+		struct sockaddr_in6 *addr = (struct sockaddr_in6 *) saddr;
+		struct ipv6_pinfo *np = inet6_sk(sk);
+		np->rcv_saddr = np->saddr = addr->sin6_addr;
+#endif
+	}
+}
+
+void ping_clear_saddr(struct sock *sk, int dif)
+{
+	sk->sk_bound_dev_if = dif;
+	if (sk->sk_family == AF_INET) {
+		struct inet_sock *isk = inet_sk(sk);
+		isk->inet_rcv_saddr = isk->inet_saddr = 0;
+#if IS_ENABLED(CONFIG_IPV6)
+	} else if (sk->sk_family == AF_INET6) {
+		struct ipv6_pinfo *np = inet6_sk(sk);
+		memset(&np->rcv_saddr, 0, sizeof(np->rcv_saddr));
+		memset(&np->saddr, 0, sizeof(np->saddr));
+#endif
+	}
+}
 /*
  * We need our own bind because there are no privileged id's == local ports.
  * Moreover, we don't allow binding to multi- and broadcast addresses.
  */
 
-static int ping_bind(struct sock *sk, struct sockaddr *uaddr, int addr_len)
+int ping_bind(struct sock *sk, struct sockaddr *uaddr, int addr_len)
 {
-	struct sockaddr_in *addr = (struct sockaddr_in *)uaddr;
 	struct inet_sock *isk = inet_sk(sk);
 	unsigned short snum;
-	int chk_addr_ret;
 	int err;
+	int dif = sk->sk_bound_dev_if;
 
-	if (addr_len < sizeof(struct sockaddr_in))
-		return -EINVAL;
-
-	pr_debug("ping_v4_bind(sk=%p,sa_addr=%08x,sa_port=%d)\n",
-		 sk, addr->sin_addr.s_addr, ntohs(addr->sin_port));
-
-	chk_addr_ret = inet_addr_type(sock_net(sk), addr->sin_addr.s_addr);
-	if (addr->sin_addr.s_addr == htonl(INADDR_ANY))
-		chk_addr_ret = RTN_LOCAL;
-
-	if ((sysctl_ip_nonlocal_bind == 0 &&
-	    isk->freebind == 0 && isk->transparent == 0 &&
-	     chk_addr_ret != RTN_LOCAL) ||
-	    chk_addr_ret == RTN_MULTICAST ||
-	    chk_addr_ret == RTN_BROADCAST)
-		return -EADDRNOTAVAIL;
+	err = ping_check_bind_addr(sk, isk, uaddr, addr_len);
+	if (err)
+		return err;
 
 	lock_sock(sk);
 
@@ -271,42 +403,50 @@
 		goto out;
 
 	err = -EADDRINUSE;
-	isk->inet_rcv_saddr = isk->inet_saddr = addr->sin_addr.s_addr;
-	snum = ntohs(addr->sin_port);
-	if (ping_v4_get_port(sk, snum) != 0) {
-		isk->inet_saddr = isk->inet_rcv_saddr = 0;
+	ping_set_saddr(sk, uaddr);
+	snum = ntohs(((struct sockaddr_in *)uaddr)->sin_port);
+	if (ping_get_port(sk, snum) != 0) {
+		ping_clear_saddr(sk, dif);
 		goto out;
 	}
 
-	pr_debug("after bind(): num = %d, daddr = %pI4, dif = %d\n",
+	pr_debug("after bind(): num = %d, dif = %d\n",
 		 (int)isk->inet_num,
-		 &isk->inet_rcv_saddr,
 		 (int)sk->sk_bound_dev_if);
 
 	err = 0;
-	if (isk->inet_rcv_saddr)
+	if ((sk->sk_family == AF_INET && isk->inet_rcv_saddr) ||
+	    (sk->sk_family == AF_INET6 &&
+	     !ipv6_addr_any(&inet6_sk(sk)->rcv_saddr)))
 		sk->sk_userlocks |= SOCK_BINDADDR_LOCK;
+
 	if (snum)
 		sk->sk_userlocks |= SOCK_BINDPORT_LOCK;
 	isk->inet_sport = htons(isk->inet_num);
 	isk->inet_daddr = 0;
 	isk->inet_dport = 0;
+
+#if IS_ENABLED(CONFIG_IPV6)
+	if (sk->sk_family == AF_INET6)
+		memset(&inet6_sk(sk)->daddr, 0, sizeof(inet6_sk(sk)->daddr));
+#endif
+
 	sk_dst_reset(sk);
 out:
 	release_sock(sk);
 	pr_debug("ping_v4_bind -> %d\n", err);
 	return err;
 }
+EXPORT_SYMBOL_GPL(ping_bind);
 
 /*
  * Is this a supported type of ICMP message?
  */
 
-static inline int ping_supported(int type, int code)
+static inline int ping_supported(int family, int type, int code)
 {
-	if (type == ICMP_ECHO && code == 0)
-		return 1;
-	return 0;
+	return (family == AF_INET && type == ICMP_ECHO && code == 0) ||
+	       (family == AF_INET6 && type == ICMPV6_ECHO_REQUEST && code == 0);
 }
 
 /*
@@ -314,30 +454,44 @@
  * sort of error condition.
  */
 
-static int ping_queue_rcv_skb(struct sock *sk, struct sk_buff *skb);
-
-void ping_err(struct sk_buff *skb, u32 info)
+void ping_err(struct sk_buff *skb, int offset, u32 info)
 {
-	struct iphdr *iph = (struct iphdr *)skb->data;
-	struct icmphdr *icmph = (struct icmphdr *)(skb->data+(iph->ihl<<2));
+	int family;
+	struct icmphdr *icmph;
 	struct inet_sock *inet_sock;
-	int type = icmp_hdr(skb)->type;
-	int code = icmp_hdr(skb)->code;
+	int type;
+	int code;
 	struct net *net = dev_net(skb->dev);
 	struct sock *sk;
 	int harderr;
 	int err;
 
+	if (skb->protocol == htons(ETH_P_IP)) {
+		struct iphdr *iph = (struct iphdr *)skb->data;
+		offset = iph->ihl << 2;
+		family = AF_INET;
+		type = icmp_hdr(skb)->type;
+		code = icmp_hdr(skb)->code;
+		icmph = (struct icmphdr *)(skb->data + offset);
+	} else if (skb->protocol == htons(ETH_P_IPV6)) {
+		family = AF_INET6;
+		type = icmp6_hdr(skb)->icmp6_type;
+		code = icmp6_hdr(skb)->icmp6_code;
+		icmph = (struct icmphdr *) (skb->data + offset);
+	} else {
+		BUG();
+	}
+
 	/* We assume the packet has already been checked by icmp_unreach */
 
-	if (!ping_supported(icmph->type, icmph->code))
+	if (!ping_supported(family, icmph->type, icmph->code))
 		return;
 
-	pr_debug("ping_err(type=%04x,code=%04x,id=%04x,seq=%04x)\n", type,
-		 code, ntohs(icmph->un.echo.id), ntohs(icmph->un.echo.sequence));
+	pr_debug("ping_err(proto=0x%x,type=%d,code=%d,id=%04x,seq=%04x)\n",
+		 skb->protocol, type, code, ntohs(icmph->un.echo.id),
+		 ntohs(icmph->un.echo.sequence));
 
-	sk = ping_v4_lookup(net, iph->daddr, iph->saddr,
-			    ntohs(icmph->un.echo.id), skb->dev->ifindex);
+	sk = ping_lookup(net, skb, ntohs(icmph->un.echo.id));
 	if (sk == NULL) {
 		pr_debug("no socket, dropping\n");
 		return;	/* No socket for error */
@@ -348,70 +502,85 @@
 	harderr = 0;
 	inet_sock = inet_sk(sk);
 
-	switch (type) {
-	default:
-	case ICMP_TIME_EXCEEDED:
-		err = EHOSTUNREACH;
-		break;
-	case ICMP_SOURCE_QUENCH:
-		/* This is not a real error but ping wants to see it.
-		 * Report it with some fake errno. */
-		err = EREMOTEIO;
-		break;
-	case ICMP_PARAMETERPROB:
-		err = EPROTO;
-		harderr = 1;
-		break;
-	case ICMP_DEST_UNREACH:
-		if (code == ICMP_FRAG_NEEDED) { /* Path MTU discovery */
-			if (inet_sock->pmtudisc != IP_PMTUDISC_DONT) {
-				err = EMSGSIZE;
-				harderr = 1;
-				break;
+	if (skb->protocol == htons(ETH_P_IP)) {
+		switch (type) {
+		default:
+		case ICMP_TIME_EXCEEDED:
+			err = EHOSTUNREACH;
+			break;
+		case ICMP_SOURCE_QUENCH:
+			/* This is not a real error but ping wants to see it.
+			 * Report it with some fake errno. */
+			err = EREMOTEIO;
+			break;
+		case ICMP_PARAMETERPROB:
+			err = EPROTO;
+			harderr = 1;
+			break;
+		case ICMP_DEST_UNREACH:
+			if (code == ICMP_FRAG_NEEDED) { /* Path MTU discovery */
+				if (inet_sock->pmtudisc != IP_PMTUDISC_DONT) {
+					err = EMSGSIZE;
+					harderr = 1;
+					break;
+				}
+				goto out;
 			}
-			goto out;
+			err = EHOSTUNREACH;
+			if (code <= NR_ICMP_UNREACH) {
+				harderr = icmp_err_convert[code].fatal;
+				err = icmp_err_convert[code].errno;
+			}
+			break;
+		case ICMP_REDIRECT:
+			/* See ICMP_SOURCE_QUENCH */
+			err = EREMOTEIO;
+			break;
 		}
-		err = EHOSTUNREACH;
-		if (code <= NR_ICMP_UNREACH) {
-			harderr = icmp_err_convert[code].fatal;
-			err = icmp_err_convert[code].errno;
-		}
-		break;
-	case ICMP_REDIRECT:
-		/* See ICMP_SOURCE_QUENCH */
-		err = EREMOTEIO;
-		break;
+#if IS_ENABLED(CONFIG_IPV6)
+	} else if (skb->protocol == htons(ETH_P_IPV6)) {
+		harderr = pingv6_ops.icmpv6_err_convert(type, code, &err);
+#endif
 	}
 
 	/*
 	 *      RFC1122: OK.  Passes ICMP errors back to application, as per
 	 *	4.1.3.3.
 	 */
-	if (!inet_sock->recverr) {
+	if ((family == AF_INET && !inet_sock->recverr) ||
+	    (family == AF_INET6 && !inet6_sk(sk)->recverr)) {
 		if (!harderr || sk->sk_state != TCP_ESTABLISHED)
 			goto out;
 	} else {
-		ip_icmp_error(sk, skb, err, 0 /* no remote port */,
-			 info, (u8 *)icmph);
+		if (family == AF_INET) {
+			ip_icmp_error(sk, skb, err, 0 /* no remote port */,
+				      info, (u8 *)icmph);
+#if IS_ENABLED(CONFIG_IPV6)
+		} else if (family == AF_INET6) {
+			pingv6_ops.ipv6_icmp_error(sk, skb, err, 0,
+						   info, (u8 *)icmph);
+#endif
+		}
 	}
 	sk->sk_err = err;
 	sk->sk_error_report(sk);
 out:
 	sock_put(sk);
 }
+EXPORT_SYMBOL_GPL(ping_err);
+
+void ping_v4_err(struct sk_buff *skb, u32 info)
+{
+	ping_err(skb, 0, info);
+}
 
 /*
- *	Copy and checksum an ICMP Echo packet from user space into a buffer.
+ *	Copy and checksum an ICMP Echo packet from user space into a buffer
+ *	starting from the payload.
  */
 
-struct pingfakehdr {
-	struct icmphdr icmph;
-	struct iovec *iov;
-	__wsum wcheck;
-};
-
-static int ping_getfrag(void *from, char * to,
-			int offset, int fraglen, int odd, struct sk_buff *skb)
+int ping_getfrag(void *from, char *to,
+		 int offset, int fraglen, int odd, struct sk_buff *skb)
 {
 	struct pingfakehdr *pfh = (struct pingfakehdr *)from;
 
@@ -422,20 +591,33 @@
 			    pfh->iov, 0, fraglen - sizeof(struct icmphdr),
 			    &pfh->wcheck))
 			return -EFAULT;
-
-		return 0;
+	} else if (offset < sizeof(struct icmphdr)) {
+			BUG();
+	} else {
+		if (csum_partial_copy_fromiovecend
+				(to, pfh->iov, offset - sizeof(struct icmphdr),
+				 fraglen, &pfh->wcheck))
+			return -EFAULT;
 	}
-	if (offset < sizeof(struct icmphdr))
-		BUG();
-	if (csum_partial_copy_fromiovecend
-			(to, pfh->iov, offset - sizeof(struct icmphdr),
-			 fraglen, &pfh->wcheck))
-		return -EFAULT;
+
+#if IS_ENABLED(CONFIG_IPV6)
+	/* For IPv6, checksum each skb as we go along, as expected by
+	 * icmpv6_push_pending_frames. For IPv4, accumulate the checksum in
+	 * wcheck, it will be finalized in ping_v4_push_pending_frames.
+	 */
+	if (pfh->family == AF_INET6) {
+		skb->csum = pfh->wcheck;
+		skb->ip_summed = CHECKSUM_NONE;
+		pfh->wcheck = 0;
+	}
+#endif
+
 	return 0;
 }
+EXPORT_SYMBOL_GPL(ping_getfrag);
 
-static int ping_push_pending_frames(struct sock *sk, struct pingfakehdr *pfh,
-				    struct flowi4 *fl4)
+static int ping_v4_push_pending_frames(struct sock *sk, struct pingfakehdr *pfh,
+				       struct flowi4 *fl4)
 {
 	struct sk_buff *skb = skb_peek(&sk->sk_write_queue);
 
@@ -447,24 +629,9 @@
 	return ip_push_pending_frames(sk, fl4);
 }
 
-static int ping_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg,
-			size_t len)
-{
-	struct net *net = sock_net(sk);
-	struct flowi4 fl4;
-	struct inet_sock *inet = inet_sk(sk);
-	struct ipcm_cookie ipc;
-	struct icmphdr user_icmph;
-	struct pingfakehdr pfh;
-	struct rtable *rt = NULL;
-	struct ip_options_data opt_copy;
-	int free = 0;
-	__be32 saddr, daddr, faddr;
-	u8  tos;
-	int err;
-
-	pr_debug("ping_sendmsg(sk=%p,sk->num=%u)\n", inet, inet->inet_num);
-
+int ping_common_sendmsg(int family, struct msghdr *msg, size_t len,
+			void *user_icmph, size_t icmph_len) {
+	u8 type, code;
 
 	if (len > 0xFFFF)
 		return -EMSGSIZE;
@@ -479,15 +646,53 @@
 
 	/*
 	 *	Fetch the ICMP header provided by the userland.
-	 *	iovec is modified!
+	 *	iovec is modified! The ICMP header is consumed.
 	 */
-
-	if (memcpy_fromiovec((u8 *)&user_icmph, msg->msg_iov,
-			     sizeof(struct icmphdr)))
+	if (memcpy_fromiovec(user_icmph, msg->msg_iov, icmph_len))
 		return -EFAULT;
-	if (!ping_supported(user_icmph.type, user_icmph.code))
+
+	if (family == AF_INET) {
+		type = ((struct icmphdr *) user_icmph)->type;
+		code = ((struct icmphdr *) user_icmph)->code;
+#if IS_ENABLED(CONFIG_IPV6)
+	} else if (family == AF_INET6) {
+		type = ((struct icmp6hdr *) user_icmph)->icmp6_type;
+		code = ((struct icmp6hdr *) user_icmph)->icmp6_code;
+#endif
+	} else {
+		BUG();
+	}
+
+	if (!ping_supported(family, type, code))
 		return -EINVAL;
 
+	return 0;
+}
+EXPORT_SYMBOL_GPL(ping_common_sendmsg);
+
+int ping_v4_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg,
+		    size_t len)
+{
+	struct net *net = sock_net(sk);
+	struct flowi4 fl4;
+	struct inet_sock *inet = inet_sk(sk);
+	struct ipcm_cookie ipc;
+	struct icmphdr user_icmph;
+	struct pingfakehdr pfh;
+	struct rtable *rt = NULL;
+	struct ip_options_data opt_copy;
+	int free = 0;
+	__be32 saddr, daddr, faddr;
+	u8  tos;
+	int err;
+
+	pr_debug("ping_v4_sendmsg(sk=%p,sk->num=%u)\n", inet, inet->inet_num);
+
+	err = ping_common_sendmsg(AF_INET, msg, len, &user_icmph,
+				  sizeof(user_icmph));
+	if (err)
+		return err;
+
 	/*
 	 *	Get and verify the address.
 	 */
@@ -593,13 +798,14 @@
 	pfh.icmph.un.echo.sequence = user_icmph.un.echo.sequence;
 	pfh.iov = msg->msg_iov;
 	pfh.wcheck = 0;
+	pfh.family = AF_INET;
 
 	err = ip_append_data(sk, &fl4, ping_getfrag, &pfh, len,
 			0, &ipc, &rt, msg->msg_flags);
 	if (err)
 		ip_flush_pending_frames(sk);
 	else
-		err = ping_push_pending_frames(sk, &pfh, &fl4);
+		err = ping_v4_push_pending_frames(sk, &pfh, &fl4);
 	release_sock(sk);
 
 out:
@@ -620,10 +826,13 @@
 	goto out;
 }
 
-static int ping_recvmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg,
-			size_t len, int noblock, int flags, int *addr_len)
+int ping_recvmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg,
+		 size_t len, int noblock, int flags, int *addr_len)
 {
 	struct inet_sock *isk = inet_sk(sk);
+	int family = sk->sk_family;
+	struct sockaddr_in *sin;
+	struct sockaddr_in6 *sin6;
 	struct sk_buff *skb;
 	int copied, err;
 
@@ -633,8 +842,22 @@
 	if (flags & MSG_OOB)
 		goto out;
 
-	if (flags & MSG_ERRQUEUE)
-		return ip_recv_error(sk, msg, len, addr_len);
+	if (addr_len) {
+		if (family == AF_INET)
+			*addr_len = sizeof(*sin);
+		else if (family == AF_INET6 && addr_len)
+			*addr_len = sizeof(*sin6);
+	}
+
+	if (flags & MSG_ERRQUEUE) {
+		if (family == AF_INET) {
+			return ip_recv_error(sk, msg, len, addr_len);
+#if IS_ENABLED(CONFIG_IPV6)
+		} else if (family == AF_INET6) {
+			return pingv6_ops.ipv6_recv_error(sk, msg, len, addr_len);
+#endif
+		}
+	}
 
 	skb = skb_recv_datagram(sk, flags, noblock, &err);
 	if (!skb)
@@ -653,18 +876,41 @@
 
 	sock_recv_timestamp(msg, sk, skb);
 
-	/* Copy the address. */
-	if (msg->msg_name) {
-		struct sockaddr_in *sin = (struct sockaddr_in *)msg->msg_name;
-
+	/* Copy the address and add cmsg data. */
+	if (family == AF_INET) {
+		sin = (struct sockaddr_in *) msg->msg_name;
 		sin->sin_family = AF_INET;
 		sin->sin_port = 0 /* skb->h.uh->source */;
 		sin->sin_addr.s_addr = ip_hdr(skb)->saddr;
 		memset(sin->sin_zero, 0, sizeof(sin->sin_zero));
-		*addr_len = sizeof(*sin);
+
+		if (isk->cmsg_flags)
+			ip_cmsg_recv(msg, skb);
+
+#if IS_ENABLED(CONFIG_IPV6)
+	} else if (family == AF_INET6) {
+		struct ipv6_pinfo *np = inet6_sk(sk);
+		struct ipv6hdr *ip6 = ipv6_hdr(skb);
+		sin6 = (struct sockaddr_in6 *) msg->msg_name;
+		sin6->sin6_family = AF_INET6;
+		sin6->sin6_port = 0;
+		sin6->sin6_addr = ip6->saddr;
+
+		if (np->sndflow)
+			sin6->sin6_flowinfo =
+				*(__be32 *)ip6 & IPV6_FLOWINFO_MASK;
+
+		if (__ipv6_addr_needs_scope_id(
+		    ipv6_addr_type(&sin6->sin6_addr)))
+			sin6->sin6_scope_id = IP6CB(skb)->iif;
+
+		if (inet6_sk(sk)->rxopt.all)
+			pingv6_ops.datagram_recv_ctl(sk, msg, skb);
+#endif
+	} else {
+		BUG();
 	}
-	if (isk->cmsg_flags)
-		ip_cmsg_recv(msg, skb);
+
 	err = copied;
 
 done:
@@ -673,8 +919,9 @@
 	pr_debug("ping_recvmsg -> %d\n", err);
 	return err;
 }
+EXPORT_SYMBOL_GPL(ping_recvmsg);
 
-static int ping_queue_rcv_skb(struct sock *sk, struct sk_buff *skb)
+int ping_queue_rcv_skb(struct sock *sk, struct sk_buff *skb)
 {
 	pr_debug("ping_queue_rcv_skb(sk=%p,sk->num=%d,skb=%p)\n",
 		 inet_sk(sk), inet_sk(sk)->inet_num, skb);
@@ -685,6 +932,7 @@
 	}
 	return 0;
 }
+EXPORT_SYMBOL_GPL(ping_queue_rcv_skb);
 
 
 /*
@@ -695,10 +943,7 @@
 {
 	struct sock *sk;
 	struct net *net = dev_net(skb->dev);
-	struct iphdr *iph = ip_hdr(skb);
 	struct icmphdr *icmph = icmp_hdr(skb);
-	__be32 saddr = iph->saddr;
-	__be32 daddr = iph->daddr;
 
 	/* We assume the packet has already been checked by icmp_rcv */
 
@@ -708,8 +953,7 @@
 	/* Push ICMP header back */
 	skb_push(skb, skb->data - (u8 *)icmph);
 
-	sk = ping_v4_lookup(net, saddr, daddr, ntohs(icmph->un.echo.id),
-			    skb->dev->ifindex);
+	sk = ping_lookup(net, skb, ntohs(icmph->un.echo.id));
 	if (sk != NULL) {
 		pr_debug("rcv on socket %p\n", sk);
 		ping_queue_rcv_skb(sk, skb_get(skb));
@@ -720,6 +964,7 @@
 
 	/* We're called from icmp_rcv(). kfree_skb() is done there. */
 }
+EXPORT_SYMBOL_GPL(ping_rcv);
 
 struct proto ping_prot = {
 	.name =		"PING",
@@ -730,13 +975,13 @@
 	.disconnect =	udp_disconnect,
 	.setsockopt =	ip_setsockopt,
 	.getsockopt =	ip_getsockopt,
-	.sendmsg =	ping_sendmsg,
+	.sendmsg =	ping_v4_sendmsg,
 	.recvmsg =	ping_recvmsg,
 	.bind =		ping_bind,
 	.backlog_rcv =	ping_queue_rcv_skb,
-	.hash =		ping_v4_hash,
-	.unhash =	ping_v4_unhash,
-	.get_port =	ping_v4_get_port,
+	.hash =		ping_hash,
+	.unhash =	ping_unhash,
+	.get_port =	ping_get_port,
 	.obj_size =	sizeof(struct inet_sock),
 };
 EXPORT_SYMBOL(ping_prot);
diff --git a/net/ipv4/sysctl_net_ipv4.c b/net/ipv4/sysctl_net_ipv4.c
index 086c973..85dd613 100644
--- a/net/ipv4/sysctl_net_ipv4.c
+++ b/net/ipv4/sysctl_net_ipv4.c
@@ -38,6 +38,10 @@
 static int tcp_syn_retries_max = MAX_TCP_SYNCNT;
 static int ip_ping_group_range_min[] = { 0, 0 };
 static int ip_ping_group_range_max[] = { GID_T_MAX, GID_T_MAX };
+static int tcp_delack_seg_min = TCP_DELACK_MIN;
+static int tcp_delack_seg_max = 60;
+static int tcp_use_userconfig_min;
+static int tcp_use_userconfig_max = 1;
 
 /* Update system visible IP port range */
 static void set_local_port_range(int range[2])
@@ -710,6 +714,25 @@
 		.proc_handler	= proc_dointvec_minmax,
 		.extra1		= &zero
 	},
+	{
+		.procname       = "tcp_delack_seg",
+		.data           = &sysctl_tcp_delack_seg,
+		.maxlen         = sizeof(sysctl_tcp_delack_seg),
+		.mode           = 0644,
+		.proc_handler   = tcp_proc_delayed_ack_control,
+		.extra1         = &tcp_delack_seg_min,
+		.extra2         = &tcp_delack_seg_max,
+	},
+	{
+		.procname       = "tcp_use_userconfig",
+		.data           = &sysctl_tcp_use_userconfig,
+		.maxlen         = sizeof(sysctl_tcp_use_userconfig),
+		.mode           = 0644,
+		.proc_handler   = tcp_use_userconfig_sysctl_handler,
+		.extra1         = &tcp_use_userconfig_min,
+		.extra2         = &tcp_use_userconfig_max,
+	},
+
 	{ }
 };
 
diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c
index 2024cb8..2414019 100644
--- a/net/ipv4/tcp.c
+++ b/net/ipv4/tcp.c
@@ -296,6 +296,11 @@
 
 atomic_long_t tcp_memory_allocated;	/* Current allocated memory. */
 EXPORT_SYMBOL(tcp_memory_allocated);
+int sysctl_tcp_delack_seg __read_mostly = TCP_DELACK_SEG;
+EXPORT_SYMBOL(sysctl_tcp_delack_seg);
+
+int sysctl_tcp_use_userconfig __read_mostly;
+EXPORT_SYMBOL(sysctl_tcp_use_userconfig);
 
 /*
  * Current number of TCP sockets.
@@ -1215,8 +1220,11 @@
 		   /* Delayed ACKs frequently hit locked sockets during bulk
 		    * receive. */
 		if (icsk->icsk_ack.blocked ||
-		    /* Once-per-two-segments ACK was not sent by tcp_input.c */
-		    tp->rcv_nxt - tp->rcv_wup > icsk->icsk_ack.rcv_mss ||
+		    /* Once-per-sysctl_tcp_delack_segments
+			* ACK was not sent by tcp_input.c
+			*/
+		    tp->rcv_nxt - tp->rcv_wup > (icsk->icsk_ack.rcv_mss) *
+						 sysctl_tcp_delack_seg ||
 		    /*
 		     * If this read emptied read buffer, we send ACK, if
 		     * connection is not bidirectional, user drained
diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c
index 99eb909..fd45f8b 100644
--- a/net/ipv4/tcp_input.c
+++ b/net/ipv4/tcp_input.c
@@ -5088,7 +5088,8 @@
 	struct tcp_sock *tp = tcp_sk(sk);
 
 	    /* More than one full frame received... */
-	if (((tp->rcv_nxt - tp->rcv_wup) > inet_csk(sk)->icsk_ack.rcv_mss &&
+	if (((tp->rcv_nxt - tp->rcv_wup) > (inet_csk(sk)->icsk_ack.rcv_mss) *
+					sysctl_tcp_delack_seg &&
 	     /* ... and right edge of window advances far enough.
 	      * (tcp_recvmsg() will send ACK otherwise). Or...
 	      */
diff --git a/net/ipv4/tcp_timer.c b/net/ipv4/tcp_timer.c
index 34d4a02..750926d 100644
--- a/net/ipv4/tcp_timer.c
+++ b/net/ipv4/tcp_timer.c
@@ -36,6 +36,36 @@
 static void tcp_delack_timer(unsigned long);
 static void tcp_keepalive_timer (unsigned long data);
 
+/*Function to reset tcp_ack related sysctl on resetting master control */
+void set_tcp_default(void)
+{
+       sysctl_tcp_delack_seg  = TCP_DELACK_SEG;
+}
+
+/*sysctl handler for tcp_ack realted master control */
+int tcp_proc_delayed_ack_control(ctl_table *table, int write,
+			void __user *buffer, size_t *length, loff_t *ppos)
+{
+	int ret = proc_dointvec_minmax(table, write, buffer, length, ppos);
+	/* The ret value will be 0 if the input validation is successful
+	 * and the values are written to sysctl table. If not, the stack
+	 * will continue to work with currently configured values
+	 */
+	 return ret;
+}
+
+/*sysctl handler for tcp_ack realted master control */
+int tcp_use_userconfig_sysctl_handler(ctl_table *table, int write,
+			void __user *buffer, size_t *length, loff_t *ppos)
+{
+	int ret = proc_dointvec_minmax(table, write, buffer, length, ppos);
+	if (write && ret == 0) {
+		if (!sysctl_tcp_use_userconfig)
+			set_tcp_default();
+	}
+	return ret;
+}
+
 void tcp_init_xmit_timers(struct sock *sk)
 {
 	inet_csk_init_xmit_timers(sk, &tcp_write_timer, &tcp_delack_timer,
diff --git a/net/ipv6/Makefile b/net/ipv6/Makefile
index 686934a..753be5d 100644
--- a/net/ipv6/Makefile
+++ b/net/ipv6/Makefile
@@ -7,7 +7,7 @@
 ipv6-objs :=	af_inet6.o anycast.o ip6_output.o ip6_input.o addrconf.o \
 		addrlabel.o \
 		route.o ip6_fib.o ipv6_sockglue.o ndisc.o udp.o udplite.o \
-		raw.o protocol.o icmp.o mcast.o reassembly.o tcp_ipv6.o \
+		raw.o protocol.o icmp.o mcast.o reassembly.o tcp_ipv6.o ping.o \
 		exthdrs.o datagram.o ip6_flowlabel.o inet6_connection_sock.o
 
 ipv6-$(CONFIG_SYSCTL) = sysctl_net_ipv6.o
diff --git a/net/ipv6/af_inet6.c b/net/ipv6/af_inet6.c
index 29625e9..22ebbb9 100644
--- a/net/ipv6/af_inet6.c
+++ b/net/ipv6/af_inet6.c
@@ -49,6 +49,7 @@
 #include <net/udplite.h>
 #include <net/tcp.h>
 #include <net/ipip.h>
+#include <net/ping.h>
 #include <net/protocol.h>
 #include <net/inet_common.h>
 #include <net/route.h>
@@ -1130,6 +1131,9 @@
 	if (err)
 		goto out_unregister_udplite_proto;
 
+	err = proto_register(&pingv6_prot, 1);
+	if (err)
+		goto out_unregister_ping_proto;
 
 	/* We MUST register RAW sockets before we create the ICMP6,
 	 * IGMP6, or NDISC control sockets.
@@ -1225,6 +1229,10 @@
 	if (err)
 		goto ipv6_packet_fail;
 
+	err = pingv6_init();
+	if (err)
+		goto pingv6_fail;
+
 #ifdef CONFIG_SYSCTL
 	err = ipv6_sysctl_register();
 	if (err)
@@ -1237,6 +1245,8 @@
 sysctl_fail:
 	ipv6_packet_cleanup();
 #endif
+pingv6_fail:
+	pingv6_exit();
 ipv6_packet_fail:
 	tcpv6_exit();
 tcpv6_fail:
@@ -1284,6 +1294,8 @@
 	rtnl_unregister_all(PF_INET6);
 out_sock_register_fail:
 	rawv6_exit();
+out_unregister_ping_proto:
+	proto_unregister(&pingv6_prot);
 out_unregister_raw_proto:
 	proto_unregister(&rawv6_prot);
 out_unregister_udplite_proto:
diff --git a/net/ipv6/icmp.c b/net/ipv6/icmp.c
index dbf20f6..6262aac 100644
--- a/net/ipv6/icmp.c
+++ b/net/ipv6/icmp.c
@@ -55,6 +55,7 @@
 
 #include <net/ipv6.h>
 #include <net/ip6_checksum.h>
+#include <net/ping.h>
 #include <net/protocol.h>
 #include <net/raw.h>
 #include <net/rawv6.h>
@@ -79,10 +80,22 @@
 	return net->ipv6.icmp_sk[smp_processor_id()];
 }
 
+static void icmpv6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
+		       u8 type, u8 code, int offset, __be32 info)
+{
+	/* icmpv6_notify checks 8 bytes can be pulled, icmp6hdr is 8 bytes */
+	struct icmp6hdr *icmp6 = (struct icmp6hdr *) (skb->data + offset);
+
+	if (!(type & ICMPV6_INFOMSG_MASK))
+		if (icmp6->icmp6_type == ICMPV6_ECHO_REQUEST)
+			ping_err(skb, offset, info);
+}
+
 static int icmpv6_rcv(struct sk_buff *skb);
 
 static const struct inet6_protocol icmpv6_protocol = {
 	.handler	=	icmpv6_rcv,
+	.err_handler	=	icmpv6_err,
 	.flags		=	INET6_PROTO_NOPOLICY|INET6_PROTO_FINAL,
 };
 
@@ -217,7 +230,8 @@
 	return (*op & 0xC0) == 0x80;
 }
 
-static int icmpv6_push_pending_frames(struct sock *sk, struct flowi6 *fl6, struct icmp6hdr *thdr, int len)
+int icmpv6_push_pending_frames(struct sock *sk, struct flowi6 *fl6,
+			       struct icmp6hdr *thdr, int len)
 {
 	struct sk_buff *skb;
 	struct icmp6hdr *icmp6h;
@@ -300,8 +314,8 @@
 static inline void mip6_addr_swap(struct sk_buff *skb) {}
 #endif
 
-static struct dst_entry *icmpv6_route_lookup(struct net *net, struct sk_buff *skb,
-					     struct sock *sk, struct flowi6 *fl6)
+struct dst_entry *icmpv6_route_lookup(struct net *net, struct sk_buff *skb,
+				      struct sock *sk, struct flowi6 *fl6)
 {
 	struct dst_entry *dst, *dst2;
 	struct flowi6 fl2;
@@ -594,7 +608,7 @@
 	icmpv6_xmit_unlock(sk);
 }
 
-static void icmpv6_notify(struct sk_buff *skb, u8 type, u8 code, __be32 info)
+void icmpv6_notify(struct sk_buff *skb, u8 type, u8 code, __be32 info)
 {
 	const struct inet6_protocol *ipprot;
 	int inner_offset;
@@ -687,7 +701,8 @@
 		skb->csum = ~csum_unfold(csum_ipv6_magic(saddr, daddr, skb->len,
 					     IPPROTO_ICMPV6, 0));
 		if (__skb_checksum_complete(skb)) {
-			LIMIT_NETDEBUG(KERN_DEBUG "ICMPv6 checksum failed [%pI6 > %pI6]\n",
+			LIMIT_NETDEBUG(KERN_DEBUG
+				       "ICMPv6 checksum failed [%pI6c > %pI6c]\n",
 				       saddr, daddr);
 			goto discard_it;
 		}
@@ -708,7 +723,7 @@
 		break;
 
 	case ICMPV6_ECHO_REPLY:
-		/* we couldn't care less */
+		ping_rcv(skb);
 		break;
 
 	case ICMPV6_PKT_TOOBIG:
diff --git a/net/ipv6/ping.c b/net/ipv6/ping.c
new file mode 100644
index 0000000..3ad1092
--- /dev/null
+++ b/net/ipv6/ping.c
@@ -0,0 +1,223 @@
+/*
+ * INET		An implementation of the TCP/IP protocol suite for the LINUX
+ *		operating system.  INET is implemented using the  BSD Socket
+ *		interface as the means of communication with the user level.
+ *
+ *		"Ping" sockets
+ *
+ *		This program is free software; you can redistribute it and/or
+ *		modify it under the terms of the GNU General Public License
+ *		as published by the Free Software Foundation; either version
+ *		2 of the License, or (at your option) any later version.
+ *
+ * Based on ipv4/ping.c code.
+ *
+ * Authors:	Lorenzo Colitti (IPv6 support)
+ *		Vasiliy Kulikov / Openwall (IPv4 implementation, for Linux 2.6),
+ *		Pavel Kankovsky (IPv4 implementation, for Linux 2.4.32)
+ *
+ */
+
+#include <net/addrconf.h>
+#include <net/ipv6.h>
+#include <net/ip6_route.h>
+#include <net/protocol.h>
+#include <net/udp.h>
+#include <net/transp_v6.h>
+#include <net/ping.h>
+#include <linux/module.h>
+
+struct proto pingv6_prot = {
+	.name =		"PINGv6",
+	.owner =	THIS_MODULE,
+	.init =		ping_init_sock,
+	.close =	ping_close,
+	.connect =	ip6_datagram_connect,
+	.disconnect =	udp_disconnect,
+	.setsockopt =	ipv6_setsockopt,
+	.getsockopt =	ipv6_getsockopt,
+	.sendmsg =	ping_v6_sendmsg,
+	.recvmsg =	ping_recvmsg,
+	.bind =		ping_bind,
+	.backlog_rcv =	ping_queue_rcv_skb,
+	.hash =		ping_hash,
+	.unhash =	ping_unhash,
+	.get_port =	ping_get_port,
+	.obj_size =	sizeof(struct raw6_sock),
+};
+EXPORT_SYMBOL_GPL(pingv6_prot);
+
+static struct inet_protosw pingv6_protosw = {
+	.type =      SOCK_DGRAM,
+	.protocol =  IPPROTO_ICMPV6,
+	.prot =      &pingv6_prot,
+	.ops =       &inet6_dgram_ops,
+	.no_check =  UDP_CSUM_DEFAULT,
+	.flags =     INET_PROTOSW_REUSE,
+};
+
+
+/* Compatibility glue so we can support IPv6 when it's compiled as a module */
+int dummy_ipv6_recv_error(struct sock *sk, struct msghdr *msg, int len,
+			  int *addr_len)
+{
+	return -EAFNOSUPPORT;
+}
+int dummy_datagram_recv_ctl(struct sock *sk, struct msghdr *msg,
+				 struct sk_buff *skb)
+{
+	return -EAFNOSUPPORT;
+}
+int dummy_icmpv6_err_convert(u8 type, u8 code, int *err)
+{
+	return -EAFNOSUPPORT;
+}
+void dummy_ipv6_icmp_error(struct sock *sk, struct sk_buff *skb, int err,
+			    __be16 port, u32 info, u8 *payload) {}
+int dummy_ipv6_chk_addr(struct net *net, const struct in6_addr *addr,
+			struct net_device *dev, int strict)
+{
+	return 0;
+}
+
+int __init pingv6_init(void)
+{
+	pingv6_ops.ipv6_recv_error = ipv6_recv_error;
+	pingv6_ops.datagram_recv_ctl = datagram_recv_ctl;
+	pingv6_ops.icmpv6_err_convert = icmpv6_err_convert;
+	pingv6_ops.ipv6_icmp_error = ipv6_icmp_error;
+	pingv6_ops.ipv6_chk_addr = ipv6_chk_addr;
+	return inet6_register_protosw(&pingv6_protosw);
+}
+
+/* This never gets called because it's not possible to unload the ipv6 module,
+ * but just in case.
+ */
+void pingv6_exit(void)
+{
+	pingv6_ops.ipv6_recv_error = dummy_ipv6_recv_error;
+	pingv6_ops.datagram_recv_ctl = dummy_datagram_recv_ctl;
+	pingv6_ops.icmpv6_err_convert = dummy_icmpv6_err_convert;
+	pingv6_ops.ipv6_icmp_error = dummy_ipv6_icmp_error;
+	pingv6_ops.ipv6_chk_addr = dummy_ipv6_chk_addr;
+	inet6_unregister_protosw(&pingv6_protosw);
+}
+
+int ping_v6_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg,
+		    size_t len)
+{
+	struct inet_sock *inet = inet_sk(sk);
+	struct ipv6_pinfo *np = inet6_sk(sk);
+	struct icmp6hdr user_icmph;
+	int addr_type;
+	struct in6_addr *daddr;
+	int iif = 0;
+	struct flowi6 fl6;
+	int err;
+	int hlimit;
+	struct dst_entry *dst;
+	struct rt6_info *rt;
+	struct pingfakehdr pfh;
+
+	pr_debug("ping_v6_sendmsg(sk=%p,sk->num=%u)\n", inet, inet->inet_num);
+
+	err = ping_common_sendmsg(AF_INET6, msg, len, &user_icmph,
+				  sizeof(user_icmph));
+	if (err)
+		return err;
+
+	if (msg->msg_name) {
+		struct sockaddr_in6 *u = (struct sockaddr_in6 *) msg->msg_name;
+		if (msg->msg_namelen < sizeof(struct sockaddr_in6) ||
+		    u->sin6_family != AF_INET6) {
+			return -EINVAL;
+		}
+		if (sk->sk_bound_dev_if &&
+		    sk->sk_bound_dev_if != u->sin6_scope_id) {
+			return -EINVAL;
+		}
+		daddr = &(u->sin6_addr);
+		iif = u->sin6_scope_id;
+	} else {
+		if (sk->sk_state != TCP_ESTABLISHED)
+			return -EDESTADDRREQ;
+		daddr = &np->daddr;
+	}
+
+	if (!iif)
+		iif = sk->sk_bound_dev_if;
+
+	addr_type = ipv6_addr_type(daddr);
+	if (__ipv6_addr_needs_scope_id(addr_type) && !iif)
+		return -EINVAL;
+	if (addr_type & IPV6_ADDR_MAPPED)
+		return -EINVAL;
+
+	/* TODO: use ip6_datagram_send_ctl to get options from cmsg */
+
+	memset(&fl6, 0, sizeof(fl6));
+
+	fl6.flowi6_proto = IPPROTO_ICMPV6;
+	fl6.saddr = np->saddr;
+	fl6.daddr = *daddr;
+	fl6.fl6_icmp_type = user_icmph.icmp6_type;
+	fl6.fl6_icmp_code = user_icmph.icmp6_code;
+	security_sk_classify_flow(sk, flowi6_to_flowi(&fl6));
+
+	if (!fl6.flowi6_oif && ipv6_addr_is_multicast(&fl6.daddr))
+		fl6.flowi6_oif = np->mcast_oif;
+	else if (!fl6.flowi6_oif)
+		fl6.flowi6_oif = np->ucast_oif;
+
+	dst = ip6_sk_dst_lookup_flow(sk, &fl6,  daddr, 1);
+	if (IS_ERR(dst))
+		return PTR_ERR(dst);
+	rt = (struct rt6_info *) dst;
+
+	np = inet6_sk(sk);
+	if (!np)
+		return -EBADF;
+
+	if (!fl6.flowi6_oif && ipv6_addr_is_multicast(&fl6.daddr))
+		fl6.flowi6_oif = np->mcast_oif;
+	else if (!fl6.flowi6_oif)
+		fl6.flowi6_oif = np->ucast_oif;
+
+	pfh.icmph.type = user_icmph.icmp6_type;
+	pfh.icmph.code = user_icmph.icmp6_code;
+	pfh.icmph.checksum = 0;
+	pfh.icmph.un.echo.id = inet->inet_sport;
+	pfh.icmph.un.echo.sequence = user_icmph.icmp6_sequence;
+	pfh.iov = msg->msg_iov;
+	pfh.wcheck = 0;
+	pfh.family = AF_INET6;
+
+	if (ipv6_addr_is_multicast(&fl6.daddr))
+		hlimit = np->mcast_hops;
+	else
+		hlimit = np->hop_limit;
+	if (hlimit < 0)
+		hlimit = ip6_dst_hoplimit(dst);
+
+	lock_sock(sk);
+	err = ip6_append_data(sk, ping_getfrag, &pfh, len,
+			      0, hlimit,
+			      np->tclass, NULL, &fl6, rt,
+			      MSG_DONTWAIT, np->dontfrag);
+
+	if (err) {
+		ICMP6_INC_STATS_BH(sock_net(sk), rt->rt6i_idev,
+				   ICMP6_MIB_OUTERRORS);
+		ip6_flush_pending_frames(sk);
+	} else {
+		err = icmpv6_push_pending_frames(sk, &fl6,
+						 (struct icmp6hdr *) &pfh.icmph,
+						 len);
+	}
+	release_sock(sk);
+
+	if (err)
+		return err;
+
+	return len;
+}
diff --git a/sound/soc/msm/msm8930.c b/sound/soc/msm/msm8930.c
index 8948962..c6aeffb 100644
--- a/sound/soc/msm/msm8930.c
+++ b/sound/soc/msm/msm8930.c
@@ -703,7 +703,7 @@
 #undef S
 #define S(X, Y) ((SITAR_MBHC_CAL_PLUG_TYPE_PTR(sitar_cal)->X) = (Y))
 	S(v_no_mic, 30);
-	S(v_hs_max, 1500);
+	S(v_hs_max, 1650);
 #undef S
 #define S(X, Y) ((SITAR_MBHC_CAL_BTN_DET_PTR(sitar_cal)->X) = (Y))
 	S(c[0], 62);