Merge branch 'staging-next' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/staging

* 'staging-next' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/staging: (466 commits)
  net/hyperv: Add support for jumbo frame up to 64KB
  net/hyperv: Add NETVSP protocol version negotiation
  net/hyperv: Remove unnecessary kmap_atomic in netvsc driver
  staging/rtl8192e: Register against lib80211
  staging/rtl8192e: Convert to lib80211_crypt_info
  staging/rtl8192e: Convert to lib80211_crypt_data and lib80211_crypt_ops
  staging/rtl8192e: Add lib80211.h to rtllib.h
  staging/mei: add watchdog device registration wrappers
  drm/omap: GEM, deal with cache
  staging: vt6656: int.c, int.h: Change return of function to void
  staging: usbip: removed unused definitions from header
  staging: usbip: removed dead code from receive function
  staging:iio: Drop {mark,unmark}_in_use callbacks
  staging:iio: Drop buffer mark_param_change callback
  staging:iio: Drop the unused buffer enable() and is_enabled() callbacks
  staging:iio: Drop buffer busy flag
  staging:iio: Make sure a device is only opened once at a time
  staging:iio: Disallow modifying buffer size when buffer is enabled
  staging:iio: Disallow changing scan elements in all buffered modes
  staging:iio: Use iio_buffer_enabled instead of open coding it
  ...

Fix up conflict in drivers/staging/iio/adc/ad799x_core.c (removal of
module_init due to using module_i2c_driver() helper, next to removal of
MODULE_ALIAS due to using MODULE_DEVICE_TABLE instead).
diff --git a/Documentation/devicetree/bindings/nvec/nvec_nvidia.txt b/Documentation/devicetree/bindings/nvec/nvec_nvidia.txt
new file mode 100644
index 0000000..5aeee53
--- /dev/null
+++ b/Documentation/devicetree/bindings/nvec/nvec_nvidia.txt
@@ -0,0 +1,9 @@
+NVIDIA compliant embedded controller
+
+Required properties:
+- compatible : should be "nvidia,nvec".
+- reg : the iomem of the i2c slave controller
+- interrupts : the interrupt line of the i2c slave controller
+- clock-frequency : the frequency of the i2c bus
+- gpios : the gpio used for ec request
+- slave-addr: the i2c address of the slave controller
diff --git a/MAINTAINERS b/MAINTAINERS
index 1e7d904..78b078e 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -184,11 +184,6 @@
 F:	Documentation/filesystems/9p.txt
 F:	fs/9p/
 
-A2232 SERIAL BOARD DRIVER
-L:	linux-m68k@lists.linux-m68k.org
-S:	Orphan
-F:	drivers/staging/generic_serial/ser_a2232*
-
 AACRAID SCSI RAID DRIVER
 M:	Adaptec OEM Raid Solutions <aacraid@adaptec.com>
 L:	linux-scsi@vger.kernel.org
@@ -1587,7 +1582,7 @@
 M:	Kan Yan	<kanyan@broadcom.com>
 L:	linux-wireless@vger.kernel.org
 S:	Supported
-F:	drivers/staging/brcm80211/
+F:	drivers/net/wireless/brcm80211/
 
 BROADCOM BNX2FC 10 GIGABIT FCOE DRIVER
 M:	Bhanu Prakash Gollapudi <bprakash@broadcom.com>
@@ -1891,12 +1886,6 @@
 S:	Maintained
 F:	drivers/platform/x86/compal-laptop.c
 
-COMPUTONE INTELLIPORT MULTIPORT CARD
-W:	http://www.wittsend.com/computone.html
-S:	Orphan
-F:	Documentation/serial/computone.txt
-F:	drivers/staging/tty/ip2/
-
 CONEXANT ACCESSRUNNER USB DRIVER
 M:	Simon Arlott <cxacru@fire.lp0.eu>
 L:	accessrunner-general@lists.sourceforge.net
@@ -2200,15 +2189,6 @@
 F:	include/linux/device-mapper.h
 F:	include/linux/dm-*.h
 
-DIGI INTL. EPCA DRIVER
-M:	"Digi International, Inc" <Eng.Linux@digi.com>
-L:	Eng.Linux@digi.com
-W:	http://www.digi.com
-S:	Orphan
-F:	Documentation/serial/digiepca.txt
-F:	drivers/staging/tty/epca*
-F:	drivers/staging/tty/digi*
-
 DIOLAN U2C-12 I2C DRIVER
 M:	Guenter Roeck <guenter.roeck@ericsson.com>
 L:	linux-i2c@vger.kernel.org
@@ -5555,11 +5535,6 @@
 S:	Maintained
 F:	drivers/memstick/host/r592.*
 
-RISCOM8 DRIVER
-S:	Orphan
-F:	Documentation/serial/riscom8.txt
-F:	drivers/staging/tty/riscom8*
-
 ROCKETPORT DRIVER
 P:	Comtrol Corp.
 W:	http://www.comtrol.com
@@ -6222,11 +6197,6 @@
 F:	arch/arm/mach-spear6xx/spear600.c
 F:	arch/arm/mach-spear6xx/spear600_evb.c
 
-SPECIALIX IO8+ MULTIPORT SERIAL CARD DRIVER
-S:	Orphan
-F:	Documentation/serial/specialix.txt
-F:	drivers/staging/tty/specialix*
-
 SPI SUBSYSTEM
 M:	Grant Likely <grant.likely@secretlab.ca>
 L:	spi-devel-general@lists.sourceforge.net
@@ -6304,11 +6274,6 @@
 S:	Odd Fixes
 F:	drivers/staging/crystalhd/
 
-STAGING - CYPRESS WESTBRIDGE SUPPORT
-M:	David Cross <david.cross@cypress.com>
-S:	Odd Fixes
-F:	drivers/staging/westbridge/
-
 STAGING - ECHO CANCELLER
 M:	Steve Underwood <steveu@coppice.org>
 M:	David Rowe <david@rowetel.com>
@@ -6414,7 +6379,7 @@
 F:	drivers/staging/winbond/
 
 STAGING - XGI Z7,Z9,Z11 PCI DISPLAY DRIVER
-M:	Arnaud Patard <apatard@mandriva.com>
+M:	Arnaud Patard <arnaud.patard@rtp-net.org>
 S:	Odd Fixes
 F:	drivers/staging/xgifb/
 
diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig
index 9845afb..b982854 100644
--- a/drivers/net/Kconfig
+++ b/drivers/net/Kconfig
@@ -342,4 +342,6 @@
 	  To compile this driver as a module, choose M here: the
 	  module will be called vmxnet3.
 
+source "drivers/net/hyperv/Kconfig"
+
 endif # NETDEVICES
diff --git a/drivers/net/Makefile b/drivers/net/Makefile
index 1988881..a6b8ce1 100644
--- a/drivers/net/Makefile
+++ b/drivers/net/Makefile
@@ -68,3 +68,5 @@
 obj-$(CONFIG_USB_ZD1201)        += usb/
 obj-$(CONFIG_USB_IPHETH)        += usb/
 obj-$(CONFIG_USB_CDC_PHONET)   += usb/
+
+obj-$(CONFIG_HYPERV_NET) += hyperv/
diff --git a/drivers/net/hyperv/Kconfig b/drivers/net/hyperv/Kconfig
new file mode 100644
index 0000000..936968d
--- /dev/null
+++ b/drivers/net/hyperv/Kconfig
@@ -0,0 +1,5 @@
+config HYPERV_NET
+	tristate "Microsoft Hyper-V virtual network driver"
+	depends on HYPERV
+	help
+	  Select this option to enable the Hyper-V virtual network driver.
diff --git a/drivers/net/hyperv/Makefile b/drivers/net/hyperv/Makefile
new file mode 100644
index 0000000..c8a6682
--- /dev/null
+++ b/drivers/net/hyperv/Makefile
@@ -0,0 +1,3 @@
+obj-$(CONFIG_HYPERV_NET) += hv_netvsc.o
+
+hv_netvsc-y := netvsc_drv.o netvsc.o rndis_filter.o
diff --git a/drivers/staging/hv/hyperv_net.h b/drivers/net/hyperv/hyperv_net.h
similarity index 91%
rename from drivers/staging/hv/hyperv_net.h
rename to drivers/net/hyperv/hyperv_net.h
index ac1ec84..dec5836 100644
--- a/drivers/staging/hv/hyperv_net.h
+++ b/drivers/net/hyperv/hyperv_net.h
@@ -39,9 +39,6 @@
 	u32 count;
 };
 
-/* The number of pages which are enough to cover jumbo frame buffer. */
-#define NETVSC_PACKET_MAXPAGE		4
-
 /*
  * Represent netvsc packet which contains 1 RNDIS and 1 ethernet frame
  * within the RNDIS
@@ -77,8 +74,9 @@
 
 	u32 total_data_buflen;
 	/* Points to the send/receive buffer where the ethernet frame is */
+	void *data;
 	u32 page_buf_cnt;
-	struct hv_page_buffer page_buf[NETVSC_PACKET_MAXPAGE];
+	struct hv_page_buffer page_buf[0];
 };
 
 struct netvsc_device_info {
@@ -87,6 +85,27 @@
 	int  ring_size;
 };
 
+enum rndis_device_state {
+	RNDIS_DEV_UNINITIALIZED = 0,
+	RNDIS_DEV_INITIALIZING,
+	RNDIS_DEV_INITIALIZED,
+	RNDIS_DEV_DATAINITIALIZED,
+};
+
+struct rndis_device {
+	struct netvsc_device *net_dev;
+
+	enum rndis_device_state state;
+	bool link_state;
+	atomic_t new_req_id;
+
+	spinlock_t request_lock;
+	struct list_head req_list;
+
+	unsigned char hw_mac_adr[ETH_ALEN];
+};
+
+
 /* Interface */
 int netvsc_device_add(struct hv_device *device, void *additional_info);
 int netvsc_device_remove(struct hv_device *device);
@@ -109,11 +128,13 @@
 int rndis_filter_send(struct hv_device *dev,
 			struct hv_netvsc_packet *pkt);
 
+int rndis_filter_set_packet_filter(struct rndis_device *dev, u32 new_filter);
+
+
 #define NVSP_INVALID_PROTOCOL_VERSION	((u32)0xFFFFFFFF)
 
 #define NVSP_PROTOCOL_VERSION_1		2
-#define NVSP_MIN_PROTOCOL_VERSION	NVSP_PROTOCOL_VERSION_1
-#define NVSP_MAX_PROTOCOL_VERSION	NVSP_PROTOCOL_VERSION_1
+#define NVSP_PROTOCOL_VERSION_2		0x30002
 
 enum {
 	NVSP_MSG_TYPE_NONE = 0,
@@ -138,11 +159,36 @@
 	NVSP_MSG1_TYPE_SEND_RNDIS_PKT,
 	NVSP_MSG1_TYPE_SEND_RNDIS_PKT_COMPLETE,
 
-	/*
-	 * This should be set to the number of messages for the version with
-	 * the maximum number of messages.
-	 */
-	NVSP_NUM_MSG_PER_VERSION		= 9,
+	/* Version 2 messages */
+	NVSP_MSG2_TYPE_SEND_CHIMNEY_DELEGATED_BUF,
+	NVSP_MSG2_TYPE_SEND_CHIMNEY_DELEGATED_BUF_COMP,
+	NVSP_MSG2_TYPE_REVOKE_CHIMNEY_DELEGATED_BUF,
+
+	NVSP_MSG2_TYPE_RESUME_CHIMNEY_RX_INDICATION,
+
+	NVSP_MSG2_TYPE_TERMINATE_CHIMNEY,
+	NVSP_MSG2_TYPE_TERMINATE_CHIMNEY_COMP,
+
+	NVSP_MSG2_TYPE_INDICATE_CHIMNEY_EVENT,
+
+	NVSP_MSG2_TYPE_SEND_CHIMNEY_PKT,
+	NVSP_MSG2_TYPE_SEND_CHIMNEY_PKT_COMP,
+
+	NVSP_MSG2_TYPE_POST_CHIMNEY_RECV_REQ,
+	NVSP_MSG2_TYPE_POST_CHIMNEY_RECV_REQ_COMP,
+
+	NVSP_MSG2_TYPE_ALLOC_RXBUF,
+	NVSP_MSG2_TYPE_ALLOC_RXBUF_COMP,
+
+	NVSP_MSG2_TYPE_FREE_RXBUF,
+
+	NVSP_MSG2_TYPE_SEND_VMQ_RNDIS_PKT,
+	NVSP_MSG2_TYPE_SEND_VMQ_RNDIS_PKT_COMP,
+
+	NVSP_MSG2_TYPE_SEND_NDIS_CONFIG,
+
+	NVSP_MSG2_TYPE_ALLOC_CHIMNEY_HANDLE,
+	NVSP_MSG2_TYPE_ALLOC_CHIMNEY_HANDLE_COMP,
 };
 
 enum {
@@ -153,6 +199,7 @@
 	NVSP_STAT_PROTOCOL_TOO_OLD,
 	NVSP_STAT_INVALID_RNDIS_PKT,
 	NVSP_STAT_BUSY,
+	NVSP_STAT_PROTOCOL_UNSUPPORTED,
 	NVSP_STAT_MAX,
 };
 
@@ -337,9 +384,69 @@
 						send_rndis_pkt_complete;
 } __packed;
 
+
+/*
+ * Network VSP protocol version 2 messages:
+ */
+struct nvsp_2_vsc_capability {
+	union {
+		u64 data;
+		struct {
+			u64 vmq:1;
+			u64 chimney:1;
+			u64 sriov:1;
+			u64 ieee8021q:1;
+			u64 correlation_id:1;
+		};
+	};
+} __packed;
+
+struct nvsp_2_send_ndis_config {
+	u32 mtu;
+	u32 reserved;
+	struct nvsp_2_vsc_capability capability;
+} __packed;
+
+/* Allocate receive buffer */
+struct nvsp_2_alloc_rxbuf {
+	/* Allocation ID to match the allocation request and response */
+	u32 alloc_id;
+
+	/* Length of the VM shared memory receive buffer that needs to
+	 * be allocated
+	 */
+	u32 len;
+} __packed;
+
+/* Allocate receive buffer complete */
+struct nvsp_2_alloc_rxbuf_comp {
+	/* The NDIS_STATUS code for buffer allocation */
+	u32 status;
+
+	u32 alloc_id;
+
+	/* GPADL handle for the allocated receive buffer */
+	u32 gpadl_handle;
+
+	/* Receive buffer ID */
+	u64 recv_buf_id;
+} __packed;
+
+struct nvsp_2_free_rxbuf {
+	u64 recv_buf_id;
+} __packed;
+
+union nvsp_2_message_uber {
+	struct nvsp_2_send_ndis_config send_ndis_config;
+	struct nvsp_2_alloc_rxbuf alloc_rxbuf;
+	struct nvsp_2_alloc_rxbuf_comp alloc_rxbuf_comp;
+	struct nvsp_2_free_rxbuf free_rxbuf;
+} __packed;
+
 union nvsp_all_messages {
 	union nvsp_message_init_uber init_msg;
 	union nvsp_1_message_uber v1_msg;
+	union nvsp_2_message_uber v2_msg;
 } __packed;
 
 /* ALL Messages */
@@ -349,12 +456,9 @@
 } __packed;
 
 
+#define NETVSC_MTU 65536
 
-
-/* #define NVSC_MIN_PROTOCOL_VERSION		1 */
-/* #define NVSC_MAX_PROTOCOL_VERSION		1 */
-
-#define NETVSC_RECEIVE_BUFFER_SIZE		(1024*1024)	/* 1MB */
+#define NETVSC_RECEIVE_BUFFER_SIZE		(1024*1024*2)	/* 2MB */
 
 #define NETVSC_RECEIVE_BUFFER_ID		0xcafe
 
@@ -369,7 +473,10 @@
 struct netvsc_device {
 	struct hv_device *dev;
 
+	u32 nvsp_version;
+
 	atomic_t num_outstanding_sends;
+	bool start_remove;
 	bool destroy;
 	/*
 	 * List of free preallocated hv_netvsc_packet to represent receive
diff --git a/drivers/staging/hv/netvsc.c b/drivers/net/hyperv/netvsc.c
similarity index 90%
rename from drivers/staging/hv/netvsc.c
rename to drivers/net/hyperv/netvsc.c
index b902579..8965b45 100644
--- a/drivers/staging/hv/netvsc.c
+++ b/drivers/net/hyperv/netvsc.c
@@ -28,6 +28,7 @@
 #include <linux/io.h>
 #include <linux/slab.h>
 #include <linux/netdevice.h>
+#include <linux/if_ether.h>
 
 #include "hyperv_net.h"
 
@@ -41,7 +42,7 @@
 	if (!net_device)
 		return NULL;
 
-
+	net_device->start_remove = false;
 	net_device->destroy = false;
 	net_device->dev = device;
 	net_device->ndev = ndev;
@@ -230,19 +231,16 @@
 	net_device->recv_section_cnt = init_packet->msg.
 		v1_msg.send_recv_buf_complete.num_sections;
 
-	net_device->recv_section = kmalloc(net_device->recv_section_cnt
-		* sizeof(struct nvsp_1_receive_buffer_section), GFP_KERNEL);
+	net_device->recv_section = kmemdup(
+		init_packet->msg.v1_msg.send_recv_buf_complete.sections,
+		net_device->recv_section_cnt *
+		sizeof(struct nvsp_1_receive_buffer_section),
+		GFP_KERNEL);
 	if (net_device->recv_section == NULL) {
 		ret = -EINVAL;
 		goto cleanup;
 	}
 
-	memcpy(net_device->recv_section,
-		init_packet->msg.v1_msg.
-	       send_recv_buf_complete.sections,
-		net_device->recv_section_cnt *
-	       sizeof(struct nvsp_1_receive_buffer_section));
-
 	/*
 	 * For 1st release, there should only be 1 section that represents the
 	 * entire receive buffer
@@ -263,9 +261,57 @@
 }
 
 
-static int netvsc_connect_vsp(struct hv_device *device)
+/* Negotiate NVSP protocol version */
+static int negotiate_nvsp_ver(struct hv_device *device,
+			      struct netvsc_device *net_device,
+			      struct nvsp_message *init_packet,
+			      u32 nvsp_ver)
 {
 	int ret, t;
+
+	memset(init_packet, 0, sizeof(struct nvsp_message));
+	init_packet->hdr.msg_type = NVSP_MSG_TYPE_INIT;
+	init_packet->msg.init_msg.init.min_protocol_ver = nvsp_ver;
+	init_packet->msg.init_msg.init.max_protocol_ver = nvsp_ver;
+
+	/* Send the init request */
+	ret = vmbus_sendpacket(device->channel, init_packet,
+			       sizeof(struct nvsp_message),
+			       (unsigned long)init_packet,
+			       VM_PKT_DATA_INBAND,
+			       VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED);
+
+	if (ret != 0)
+		return ret;
+
+	t = wait_for_completion_timeout(&net_device->channel_init_wait, 5*HZ);
+
+	if (t == 0)
+		return -ETIMEDOUT;
+
+	if (init_packet->msg.init_msg.init_complete.status !=
+	    NVSP_STAT_SUCCESS)
+		return -EINVAL;
+
+	if (nvsp_ver != NVSP_PROTOCOL_VERSION_2)
+		return 0;
+
+	/* NVSPv2 only: Send NDIS config */
+	memset(init_packet, 0, sizeof(struct nvsp_message));
+	init_packet->hdr.msg_type = NVSP_MSG2_TYPE_SEND_NDIS_CONFIG;
+	init_packet->msg.v2_msg.send_ndis_config.mtu = net_device->ndev->mtu;
+
+	ret = vmbus_sendpacket(device->channel, init_packet,
+				sizeof(struct nvsp_message),
+				(unsigned long)init_packet,
+				VM_PKT_DATA_INBAND, 0);
+
+	return ret;
+}
+
+static int netvsc_connect_vsp(struct hv_device *device)
+{
+	int ret;
 	struct netvsc_device *net_device;
 	struct nvsp_message *init_packet;
 	int ndis_version;
@@ -278,41 +324,20 @@
 
 	init_packet = &net_device->channel_init_pkt;
 
-	memset(init_packet, 0, sizeof(struct nvsp_message));
-	init_packet->hdr.msg_type = NVSP_MSG_TYPE_INIT;
-	init_packet->msg.init_msg.init.min_protocol_ver =
-		NVSP_MIN_PROTOCOL_VERSION;
-	init_packet->msg.init_msg.init.max_protocol_ver =
-		NVSP_MAX_PROTOCOL_VERSION;
-
-	/* Send the init request */
-	ret = vmbus_sendpacket(device->channel, init_packet,
-			       sizeof(struct nvsp_message),
-			       (unsigned long)init_packet,
-			       VM_PKT_DATA_INBAND,
-			       VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED);
-
-	if (ret != 0)
-		goto cleanup;
-
-	t = wait_for_completion_timeout(&net_device->channel_init_wait, 5*HZ);
-
-	if (t == 0) {
-		ret = -ETIMEDOUT;
-		goto cleanup;
-	}
-
-	if (init_packet->msg.init_msg.init_complete.status !=
-	    NVSP_STAT_SUCCESS) {
-		ret = -EINVAL;
-		goto cleanup;
-	}
-
-	if (init_packet->msg.init_msg.init_complete.
-	    negotiated_protocol_ver != NVSP_PROTOCOL_VERSION_1) {
+	/* Negotiate the latest NVSP protocol supported */
+	if (negotiate_nvsp_ver(device, net_device, init_packet,
+			       NVSP_PROTOCOL_VERSION_2) == 0) {
+		net_device->nvsp_version = NVSP_PROTOCOL_VERSION_2;
+	} else if (negotiate_nvsp_ver(device, net_device, init_packet,
+				    NVSP_PROTOCOL_VERSION_1) == 0) {
+		net_device->nvsp_version = NVSP_PROTOCOL_VERSION_1;
+	} else {
 		ret = -EPROTO;
 		goto cleanup;
 	}
+
+	pr_debug("Negotiated NVSP version:%x\n", net_device->nvsp_version);
+
 	/* Send the ndis version */
 	memset(init_packet, 0, sizeof(struct nvsp_message));
 
@@ -438,6 +463,9 @@
 			nvsc_packet->completion.send.send_completion_ctx);
 
 		atomic_dec(&net_device->num_outstanding_sends);
+
+		if (netif_queue_stopped(ndev) && !net_device->start_remove)
+			netif_wake_queue(ndev);
 	} else {
 		netdev_err(ndev, "Unknown send completion packet type- "
 			   "%d received!!\n", nvsp_packet->hdr.msg_type);
@@ -488,11 +516,16 @@
 
 	}
 
-	if (ret != 0)
+	if (ret == 0) {
+		atomic_inc(&net_device->num_outstanding_sends);
+	} else if (ret == -EAGAIN) {
+		netif_stop_queue(ndev);
+		if (atomic_read(&net_device->num_outstanding_sends) < 1)
+			netif_wake_queue(ndev);
+	} else {
 		netdev_err(ndev, "Unable to send packet %p ret %d\n",
 			   packet, ret);
-	else
-		atomic_inc(&net_device->num_outstanding_sends);
+	}
 
 	return ret;
 }
@@ -598,12 +631,10 @@
 	struct vmtransfer_page_packet_header *vmxferpage_packet;
 	struct nvsp_message *nvsp_packet;
 	struct hv_netvsc_packet *netvsc_packet = NULL;
-	unsigned long start;
-	unsigned long end, end_virtual;
 	/* struct netvsc_driver *netvscDriver; */
 	struct xferpage_packet *xferpage_packet = NULL;
-	int i, j;
-	int count = 0, bytes_remain = 0;
+	int i;
+	int count = 0;
 	unsigned long flags;
 	struct net_device *ndev;
 
@@ -712,53 +743,10 @@
 		netvsc_packet->completion.recv.recv_completion_tid =
 					vmxferpage_packet->d.trans_id;
 
+		netvsc_packet->data = (void *)((unsigned long)net_device->
+			recv_buf + vmxferpage_packet->ranges[i].byte_offset);
 		netvsc_packet->total_data_buflen =
 					vmxferpage_packet->ranges[i].byte_count;
-		netvsc_packet->page_buf_cnt = 1;
-
-		netvsc_packet->page_buf[0].len =
-					vmxferpage_packet->ranges[i].byte_count;
-
-		start = virt_to_phys((void *)((unsigned long)net_device->
-		recv_buf + vmxferpage_packet->ranges[i].byte_offset));
-
-		netvsc_packet->page_buf[0].pfn = start >> PAGE_SHIFT;
-		end_virtual = (unsigned long)net_device->recv_buf
-		    + vmxferpage_packet->ranges[i].byte_offset
-		    + vmxferpage_packet->ranges[i].byte_count - 1;
-		end = virt_to_phys((void *)end_virtual);
-
-		/* Calculate the page relative offset */
-		netvsc_packet->page_buf[0].offset =
-			vmxferpage_packet->ranges[i].byte_offset &
-			(PAGE_SIZE - 1);
-		if ((end >> PAGE_SHIFT) != (start >> PAGE_SHIFT)) {
-			/* Handle frame across multiple pages: */
-			netvsc_packet->page_buf[0].len =
-				(netvsc_packet->page_buf[0].pfn <<
-				 PAGE_SHIFT)
-				+ PAGE_SIZE - start;
-			bytes_remain = netvsc_packet->total_data_buflen -
-					netvsc_packet->page_buf[0].len;
-			for (j = 1; j < NETVSC_PACKET_MAXPAGE; j++) {
-				netvsc_packet->page_buf[j].offset = 0;
-				if (bytes_remain <= PAGE_SIZE) {
-					netvsc_packet->page_buf[j].len =
-						bytes_remain;
-					bytes_remain = 0;
-				} else {
-					netvsc_packet->page_buf[j].len =
-						PAGE_SIZE;
-					bytes_remain -= PAGE_SIZE;
-				}
-				netvsc_packet->page_buf[j].pfn =
-				    virt_to_phys((void *)(end_virtual -
-						bytes_remain)) >> PAGE_SHIFT;
-				netvsc_packet->page_buf_cnt++;
-				if (bytes_remain == 0)
-					break;
-			}
-		}
 
 		/* Pass it to the upper layer */
 		rndis_filter_receive(device, netvsc_packet);
diff --git a/drivers/staging/hv/netvsc_drv.c b/drivers/net/hyperv/netvsc_drv.c
similarity index 77%
rename from drivers/staging/hv/netvsc_drv.c
rename to drivers/net/hyperv/netvsc_drv.c
index 93b0e91..462d05f 100644
--- a/drivers/staging/hv/netvsc_drv.c
+++ b/drivers/net/hyperv/netvsc_drv.c
@@ -43,24 +43,59 @@
 struct net_device_context {
 	/* point back to our device context */
 	struct hv_device *device_ctx;
-	atomic_t avail;
 	struct delayed_work dwork;
 };
 
 
-#define PACKET_PAGES_LOWATER  8
-/* Need this many pages to handle worst case fragmented packet */
-#define PACKET_PAGES_HIWATER  (MAX_SKB_FRAGS + 2)
-
 static int ring_size = 128;
 module_param(ring_size, int, S_IRUGO);
 MODULE_PARM_DESC(ring_size, "Ring buffer size (# of pages)");
 
-/* no-op so the netdev core doesn't return -EINVAL when modifying the the
- * multicast address list in SIOCADDMULTI. hv is setup to get all multicast
- * when it calls RndisFilterOnOpen() */
+struct set_multicast_work {
+	struct work_struct work;
+	struct net_device *net;
+};
+
+static void do_set_multicast(struct work_struct *w)
+{
+	struct set_multicast_work *swk =
+		container_of(w, struct set_multicast_work, work);
+	struct net_device *net = swk->net;
+
+	struct net_device_context *ndevctx = netdev_priv(net);
+	struct netvsc_device *nvdev;
+	struct rndis_device *rdev;
+
+	nvdev = hv_get_drvdata(ndevctx->device_ctx);
+	if (nvdev == NULL)
+		return;
+
+	rdev = nvdev->extension;
+	if (rdev == NULL)
+		return;
+
+	if (net->flags & IFF_PROMISC)
+		rndis_filter_set_packet_filter(rdev,
+			NDIS_PACKET_TYPE_PROMISCUOUS);
+	else
+		rndis_filter_set_packet_filter(rdev,
+			NDIS_PACKET_TYPE_BROADCAST |
+			NDIS_PACKET_TYPE_ALL_MULTICAST |
+			NDIS_PACKET_TYPE_DIRECTED);
+
+	kfree(w);
+}
+
 static void netvsc_set_multicast_list(struct net_device *net)
 {
+	struct set_multicast_work *swk =
+		kmalloc(sizeof(struct set_multicast_work), GFP_ATOMIC);
+	if (swk == NULL)
+		return;
+
+	swk->net = net;
+	INIT_WORK(&swk->work, do_set_multicast);
+	schedule_work(&swk->work);
 }
 
 static int netvsc_open(struct net_device *net)
@@ -104,18 +139,8 @@
 
 	kfree(packet);
 
-	if (skb) {
-		struct net_device *net = skb->dev;
-		struct net_device_context *net_device_ctx = netdev_priv(net);
-		unsigned int num_pages = skb_shinfo(skb)->nr_frags + 2;
-
+	if (skb)
 		dev_kfree_skb_any(skb);
-
-		atomic_add(num_pages, &net_device_ctx->avail);
-		if (atomic_read(&net_device_ctx->avail) >=
-				PACKET_PAGES_HIWATER)
-			netif_wake_queue(net);
-	}
 }
 
 static int netvsc_start_xmit(struct sk_buff *skb, struct net_device *net)
@@ -123,12 +148,12 @@
 	struct net_device_context *net_device_ctx = netdev_priv(net);
 	struct hv_netvsc_packet *packet;
 	int ret;
-	unsigned int i, num_pages;
+	unsigned int i, num_pages, npg_data;
 
-	/* Add 1 for skb->data and additional one for RNDIS */
-	num_pages = skb_shinfo(skb)->nr_frags + 1 + 1;
-	if (num_pages > atomic_read(&net_device_ctx->avail))
-		return NETDEV_TX_BUSY;
+	/* Add multipage for skb->data and additional one for RNDIS */
+	npg_data = (((unsigned long)skb->data + skb_headlen(skb) - 1)
+		>> PAGE_SHIFT) - ((unsigned long)skb->data >> PAGE_SHIFT) + 1;
+	num_pages = skb_shinfo(skb)->nr_frags + npg_data + 1;
 
 	/* Allocate a netvsc packet based on # of frags. */
 	packet = kzalloc(sizeof(struct hv_netvsc_packet) +
@@ -151,21 +176,36 @@
 	packet->page_buf_cnt = num_pages;
 
 	/* Initialize it from the skb */
-	packet->total_data_buflen	= skb->len;
+	packet->total_data_buflen = skb->len;
 
 	/* Start filling in the page buffers starting after RNDIS buffer. */
 	packet->page_buf[1].pfn = virt_to_phys(skb->data) >> PAGE_SHIFT;
 	packet->page_buf[1].offset
 		= (unsigned long)skb->data & (PAGE_SIZE - 1);
-	packet->page_buf[1].len = skb_headlen(skb);
+	if (npg_data == 1)
+		packet->page_buf[1].len = skb_headlen(skb);
+	else
+		packet->page_buf[1].len = PAGE_SIZE
+			- packet->page_buf[1].offset;
+
+	for (i = 2; i <= npg_data; i++) {
+		packet->page_buf[i].pfn = virt_to_phys(skb->data
+			+ PAGE_SIZE * (i-1)) >> PAGE_SHIFT;
+		packet->page_buf[i].offset = 0;
+		packet->page_buf[i].len = PAGE_SIZE;
+	}
+	if (npg_data > 1)
+		packet->page_buf[npg_data].len = (((unsigned long)skb->data
+			+ skb_headlen(skb) - 1) & (PAGE_SIZE - 1)) + 1;
 
 	/* Additional fragments are after SKB data */
 	for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) {
 		const skb_frag_t *f = &skb_shinfo(skb)->frags[i];
 
-		packet->page_buf[i+2].pfn = page_to_pfn(skb_frag_page(f));
-		packet->page_buf[i+2].offset = f->page_offset;
-		packet->page_buf[i+2].len = skb_frag_size(f);
+		packet->page_buf[i+npg_data+1].pfn =
+			page_to_pfn(skb_frag_page(f));
+		packet->page_buf[i+npg_data+1].offset = f->page_offset;
+		packet->page_buf[i+npg_data+1].len = skb_frag_size(f);
 	}
 
 	/* Set the completion routine */
@@ -178,10 +218,6 @@
 	if (ret == 0) {
 		net->stats.tx_bytes += skb->len;
 		net->stats.tx_packets++;
-
-		atomic_sub(num_pages, &net_device_ctx->avail);
-		if (atomic_read(&net_device_ctx->avail) < PACKET_PAGES_LOWATER)
-			netif_stop_queue(net);
 	} else {
 		/* we are shutting down or bus overloaded, just drop packet */
 		net->stats.tx_dropped++;
@@ -232,9 +268,6 @@
 {
 	struct net_device *net = dev_get_drvdata(&device_obj->device);
 	struct sk_buff *skb;
-	void *data;
-	int i;
-	unsigned long flags;
 	struct netvsc_device *net_device;
 
 	net_device = hv_get_drvdata(device_obj);
@@ -253,27 +286,12 @@
 		return 0;
 	}
 
-	/* for kmap_atomic */
-	local_irq_save(flags);
-
 	/*
 	 * Copy to skb. This copy is needed here since the memory pointed by
 	 * hv_netvsc_packet cannot be deallocated
 	 */
-	for (i = 0; i < packet->page_buf_cnt; i++) {
-		data = kmap_atomic(pfn_to_page(packet->page_buf[i].pfn),
-					       KM_IRQ1);
-		data = (void *)(unsigned long)data +
-				packet->page_buf[i].offset;
-
-		memcpy(skb_put(skb, packet->page_buf[i].len), data,
-		       packet->page_buf[i].len);
-
-		kunmap_atomic((void *)((unsigned long)data -
-				       packet->page_buf[i].offset), KM_IRQ1);
-	}
-
-	local_irq_restore(flags);
+	memcpy(skb_put(skb, packet->total_data_buflen), packet->data,
+		packet->total_data_buflen);
 
 	skb->protocol = eth_type_trans(skb, net);
 	skb->ip_summed = CHECKSUM_NONE;
@@ -299,6 +317,39 @@
 	strcpy(info->fw_version, "N/A");
 }
 
+static int netvsc_change_mtu(struct net_device *ndev, int mtu)
+{
+	struct net_device_context *ndevctx = netdev_priv(ndev);
+	struct hv_device *hdev =  ndevctx->device_ctx;
+	struct netvsc_device *nvdev = hv_get_drvdata(hdev);
+	struct netvsc_device_info device_info;
+	int limit = ETH_DATA_LEN;
+
+	if (nvdev == NULL || nvdev->destroy)
+		return -ENODEV;
+
+	if (nvdev->nvsp_version == NVSP_PROTOCOL_VERSION_2)
+		limit = NETVSC_MTU;
+
+	if (mtu < 68 || mtu > limit)
+		return -EINVAL;
+
+	nvdev->start_remove = true;
+	cancel_delayed_work_sync(&ndevctx->dwork);
+	netif_stop_queue(ndev);
+	rndis_filter_device_remove(hdev);
+
+	ndev->mtu = mtu;
+
+	ndevctx->device_ctx = hdev;
+	hv_set_drvdata(hdev, ndev);
+	device_info.ring_size = ring_size;
+	rndis_filter_device_add(hdev, &device_info);
+	netif_wake_queue(ndev);
+
+	return 0;
+}
+
 static const struct ethtool_ops ethtool_ops = {
 	.get_drvinfo	= netvsc_get_drvinfo,
 	.get_link	= ethtool_op_get_link,
@@ -309,7 +360,7 @@
 	.ndo_stop =			netvsc_close,
 	.ndo_start_xmit =		netvsc_start_xmit,
 	.ndo_set_rx_mode =		netvsc_set_multicast_list,
-	.ndo_change_mtu =		eth_change_mtu,
+	.ndo_change_mtu =		netvsc_change_mtu,
 	.ndo_validate_addr =		eth_validate_addr,
 	.ndo_set_mac_address =		eth_mac_addr,
 };
@@ -351,7 +402,6 @@
 
 	net_device_ctx = netdev_priv(net);
 	net_device_ctx->device_ctx = dev;
-	atomic_set(&net_device_ctx->avail, ring_size);
 	hv_set_drvdata(dev, net);
 	INIT_DELAYED_WORK(&net_device_ctx->dwork, netvsc_send_garp);
 
@@ -403,6 +453,8 @@
 		return 0;
 	}
 
+	net_device->start_remove = true;
+
 	ndev_ctx = netdev_priv(net);
 	cancel_delayed_work_sync(&ndev_ctx->dwork);
 
diff --git a/drivers/staging/hv/rndis_filter.c b/drivers/net/hyperv/rndis_filter.c
similarity index 94%
rename from drivers/staging/hv/rndis_filter.c
rename to drivers/net/hyperv/rndis_filter.c
index bafccb3..da181f9 100644
--- a/drivers/staging/hv/rndis_filter.c
+++ b/drivers/net/hyperv/rndis_filter.c
@@ -30,26 +30,6 @@
 #include "hyperv_net.h"
 
 
-enum rndis_device_state {
-	RNDIS_DEV_UNINITIALIZED = 0,
-	RNDIS_DEV_INITIALIZING,
-	RNDIS_DEV_INITIALIZED,
-	RNDIS_DEV_DATAINITIALIZED,
-};
-
-struct rndis_device {
-	struct netvsc_device *net_dev;
-
-	enum rndis_device_state state;
-	bool link_state;
-	atomic_t new_req_id;
-
-	spinlock_t request_lock;
-	struct list_head req_list;
-
-	unsigned char hw_mac_adr[ETH_ALEN];
-};
-
 struct rndis_request {
 	struct list_head list_ent;
 	struct completion  wait_event;
@@ -329,7 +309,6 @@
 {
 	struct rndis_packet *rndis_pkt;
 	u32 data_offset;
-	int i;
 
 	rndis_pkt = &msg->msg.pkt;
 
@@ -342,17 +321,7 @@
 	data_offset = RNDIS_HEADER_SIZE + rndis_pkt->data_offset;
 
 	pkt->total_data_buflen -= data_offset;
-	pkt->page_buf[0].offset += data_offset;
-	pkt->page_buf[0].len -= data_offset;
-
-	/* Drop the 0th page, if rndis data go beyond page boundary */
-	if (pkt->page_buf[0].offset >= PAGE_SIZE) {
-		pkt->page_buf[1].offset = pkt->page_buf[0].offset - PAGE_SIZE;
-		pkt->page_buf[1].len -= pkt->page_buf[1].offset;
-		pkt->page_buf_cnt--;
-		for (i = 0; i < pkt->page_buf_cnt; i++)
-			pkt->page_buf[i] = pkt->page_buf[i+1];
-	}
+	pkt->data = (void *)((unsigned long)pkt->data + data_offset);
 
 	pkt->is_data_pkt = true;
 
@@ -387,11 +356,7 @@
 		return -ENODEV;
 	}
 
-	rndis_hdr = (struct rndis_message *)kmap_atomic(
-			pfn_to_page(pkt->page_buf[0].pfn), KM_IRQ0);
-
-	rndis_hdr = (void *)((unsigned long)rndis_hdr +
-			pkt->page_buf[0].offset);
+	rndis_hdr = pkt->data;
 
 	/* Make sure we got a valid rndis message */
 	if ((rndis_hdr->ndis_msg_type != REMOTE_NDIS_PACKET_MSG) &&
@@ -407,8 +372,6 @@
 			sizeof(struct rndis_message) :
 			rndis_hdr->msg_len);
 
-	kunmap_atomic(rndis_hdr - pkt->page_buf[0].offset, KM_IRQ0);
-
 	dump_rndis_message(dev, &rndis_msg);
 
 	switch (rndis_msg.ndis_msg_type) {
@@ -522,8 +485,7 @@
 	return ret;
 }
 
-static int rndis_filter_set_packet_filter(struct rndis_device *dev,
-				      u32 new_filter)
+int rndis_filter_set_packet_filter(struct rndis_device *dev, u32 new_filter)
 {
 	struct rndis_request *request;
 	struct rndis_set_request *set;
diff --git a/drivers/staging/Kconfig b/drivers/staging/Kconfig
index 25cdff3..21e2f4b 100644
--- a/drivers/staging/Kconfig
+++ b/drivers/staging/Kconfig
@@ -72,8 +72,6 @@
 
 source "drivers/staging/serqt_usb2/Kconfig"
 
-source "drivers/staging/spectra/Kconfig"
-
 source "drivers/staging/quatech_usb2/Kconfig"
 
 source "drivers/staging/vt6655/Kconfig"
@@ -116,8 +114,6 @@
 
 source "drivers/staging/ft1000/Kconfig"
 
-source "drivers/staging/intel_sst/Kconfig"
-
 source "drivers/staging/speakup/Kconfig"
 
 source "drivers/staging/cptm1217/Kconfig"
@@ -132,4 +128,8 @@
 
 source "drivers/staging/media/Kconfig"
 
+source "drivers/staging/omapdrm/Kconfig"
+
+source "drivers/staging/android/Kconfig"
+
 endif # STAGING
diff --git a/drivers/staging/Makefile b/drivers/staging/Makefile
index a25f3f2..7c5808d 100644
--- a/drivers/staging/Makefile
+++ b/drivers/staging/Makefile
@@ -21,7 +21,6 @@
 obj-$(CONFIG_R8712U)		+= rtl8712/
 obj-$(CONFIG_RTS_PSTOR)		+= rts_pstor/
 obj-$(CONFIG_RTS5139)		+= rts5139/
-obj-$(CONFIG_SPECTRA)		+= spectra/
 obj-$(CONFIG_TRANZPORT)		+= frontier/
 obj-$(CONFIG_POHMELFS)		+= pohmelfs/
 obj-$(CONFIG_IDE_PHISON)	+= phison/
@@ -50,10 +49,11 @@
 obj-$(CONFIG_USB_ENESTORAGE)	+= keucr/
 obj-$(CONFIG_BCM_WIMAX)		+= bcm/
 obj-$(CONFIG_FT1000)		+= ft1000/
-obj-$(CONFIG_SND_INTEL_SST)	+= intel_sst/
 obj-$(CONFIG_SPEAKUP)		+= speakup/
 obj-$(CONFIG_TOUCHSCREEN_CLEARPAD_TM1217)	+= cptm1217/
 obj-$(CONFIG_TOUCHSCREEN_SYNAPTICS_I2C_RMI4)	+= ste_rmi4/
 obj-$(CONFIG_DRM_PSB)		+= gma500/
 obj-$(CONFIG_INTEL_MEI)		+= mei/
 obj-$(CONFIG_MFD_NVEC)		+= nvec/
+obj-$(CONFIG_DRM_OMAP)		+= omapdrm/
+obj-$(CONFIG_ANDROID)		+= android/
diff --git a/drivers/staging/android/Kconfig b/drivers/staging/android/Kconfig
new file mode 100644
index 0000000..becf711
--- /dev/null
+++ b/drivers/staging/android/Kconfig
@@ -0,0 +1,110 @@
+menu "Android"
+
+config ANDROID
+	bool "Android Drivers"
+	default N
+	---help---
+	  Enable support for various drivers needed on the Android platform
+
+if ANDROID
+
+config ANDROID_BINDER_IPC
+	bool "Android Binder IPC Driver"
+	default n
+
+config ASHMEM
+	bool "Enable the Anonymous Shared Memory Subsystem"
+	default n
+	depends on SHMEM || TINY_SHMEM
+	help
+	  The ashmem subsystem is a new shared memory allocator, similar to
+	  POSIX SHM but with different behavior and sporting a simpler
+	  file-based API.
+
+config ANDROID_LOGGER
+	tristate "Android log driver"
+	default n
+
+config ANDROID_RAM_CONSOLE
+	bool "Android RAM buffer console"
+	default n
+
+config ANDROID_RAM_CONSOLE_ENABLE_VERBOSE
+	bool "Enable verbose console messages on Android RAM console"
+	default y
+	depends on ANDROID_RAM_CONSOLE
+
+menuconfig ANDROID_RAM_CONSOLE_ERROR_CORRECTION
+	bool "Android RAM Console Enable error correction"
+	default n
+	depends on ANDROID_RAM_CONSOLE
+	depends on !ANDROID_RAM_CONSOLE_EARLY_INIT
+	select REED_SOLOMON
+	select REED_SOLOMON_ENC8
+	select REED_SOLOMON_DEC8
+
+if ANDROID_RAM_CONSOLE_ERROR_CORRECTION
+
+config ANDROID_RAM_CONSOLE_ERROR_CORRECTION_DATA_SIZE
+	int "Android RAM Console Data data size"
+	default 128
+	help
+	  Must be a power of 2.
+
+config ANDROID_RAM_CONSOLE_ERROR_CORRECTION_ECC_SIZE
+	int "Android RAM Console ECC size"
+	default 16
+
+config ANDROID_RAM_CONSOLE_ERROR_CORRECTION_SYMBOL_SIZE
+	int "Android RAM Console Symbol size"
+	default 8
+
+config ANDROID_RAM_CONSOLE_ERROR_CORRECTION_POLYNOMIAL
+	hex "Android RAM Console Polynomial"
+	default 0x19 if (ANDROID_RAM_CONSOLE_ERROR_CORRECTION_SYMBOL_SIZE = 4)
+	default 0x29 if (ANDROID_RAM_CONSOLE_ERROR_CORRECTION_SYMBOL_SIZE = 5)
+	default 0x61 if (ANDROID_RAM_CONSOLE_ERROR_CORRECTION_SYMBOL_SIZE = 6)
+	default 0x89 if (ANDROID_RAM_CONSOLE_ERROR_CORRECTION_SYMBOL_SIZE = 7)
+	default 0x11d if (ANDROID_RAM_CONSOLE_ERROR_CORRECTION_SYMBOL_SIZE = 8)
+
+endif # ANDROID_RAM_CONSOLE_ERROR_CORRECTION
+
+config ANDROID_RAM_CONSOLE_EARLY_INIT
+	bool "Start Android RAM console early"
+	default n
+	depends on ANDROID_RAM_CONSOLE
+
+config ANDROID_RAM_CONSOLE_EARLY_ADDR
+	hex "Android RAM console virtual address"
+	default 0
+	depends on ANDROID_RAM_CONSOLE_EARLY_INIT
+
+config ANDROID_RAM_CONSOLE_EARLY_SIZE
+	hex "Android RAM console buffer size"
+	default 0
+	depends on ANDROID_RAM_CONSOLE_EARLY_INIT
+
+config ANDROID_TIMED_OUTPUT
+	bool "Timed output class driver"
+	default y
+
+config ANDROID_TIMED_GPIO
+	tristate "Android timed gpio driver"
+	depends on GENERIC_GPIO && ANDROID_TIMED_OUTPUT
+	default n
+
+config ANDROID_LOW_MEMORY_KILLER
+	bool "Android Low Memory Killer"
+	default N
+	---help---
+	  Register processes to be killed when memory is low
+
+config ANDROID_PMEM
+	bool "Android pmem allocator"
+	depends on ARM
+
+source "drivers/staging/android/switch/Kconfig"
+
+endif # if ANDROID
+
+endmenu
diff --git a/drivers/staging/android/Makefile b/drivers/staging/android/Makefile
new file mode 100644
index 0000000..eaed1ff
--- /dev/null
+++ b/drivers/staging/android/Makefile
@@ -0,0 +1,9 @@
+obj-$(CONFIG_ANDROID_BINDER_IPC)	+= binder.o
+obj-$(CONFIG_ASHMEM)			+= ashmem.o
+obj-$(CONFIG_ANDROID_LOGGER)		+= logger.o
+obj-$(CONFIG_ANDROID_RAM_CONSOLE)	+= ram_console.o
+obj-$(CONFIG_ANDROID_TIMED_OUTPUT)	+= timed_output.o
+obj-$(CONFIG_ANDROID_TIMED_GPIO)	+= timed_gpio.o
+obj-$(CONFIG_ANDROID_LOW_MEMORY_KILLER)	+= lowmemorykiller.o
+obj-$(CONFIG_ANDROID_PMEM)		+= pmem.o
+obj-$(CONFIG_ANDROID_SWITCH)		+= switch/
diff --git a/drivers/staging/android/TODO b/drivers/staging/android/TODO
new file mode 100644
index 0000000..e59c5be
--- /dev/null
+++ b/drivers/staging/android/TODO
@@ -0,0 +1,10 @@
+TODO:
+	- checkpatch.pl cleanups
+	- sparse fixes
+	- rename files to be not so "generic"
+	- make sure things build as modules properly
+	- add proper arch dependancies as needed
+	- audit userspace interfaces to make sure they are sane
+
+Please send patches to Greg Kroah-Hartman <greg@kroah.com> and Cc:
+Brian Swetland <swetland@google.com>
diff --git a/drivers/staging/android/android_pmem.h b/drivers/staging/android/android_pmem.h
new file mode 100644
index 0000000..f633621
--- /dev/null
+++ b/drivers/staging/android/android_pmem.h
@@ -0,0 +1,93 @@
+/* include/linux/android_pmem.h
+ *
+ * Copyright (C) 2007 Google, Inc.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of 
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#ifndef _ANDROID_PMEM_H_
+#define _ANDROID_PMEM_H_
+
+#define PMEM_IOCTL_MAGIC 'p'
+#define PMEM_GET_PHYS		_IOW(PMEM_IOCTL_MAGIC, 1, unsigned int)
+#define PMEM_MAP		_IOW(PMEM_IOCTL_MAGIC, 2, unsigned int)
+#define PMEM_GET_SIZE		_IOW(PMEM_IOCTL_MAGIC, 3, unsigned int)
+#define PMEM_UNMAP		_IOW(PMEM_IOCTL_MAGIC, 4, unsigned int)
+/* This ioctl will allocate pmem space, backing the file, it will fail
+ * if the file already has an allocation, pass it the len as the argument
+ * to the ioctl */
+#define PMEM_ALLOCATE		_IOW(PMEM_IOCTL_MAGIC, 5, unsigned int)
+/* This will connect a one pmem file to another, pass the file that is already
+ * backed in memory as the argument to the ioctl
+ */
+#define PMEM_CONNECT		_IOW(PMEM_IOCTL_MAGIC, 6, unsigned int)
+/* Returns the total size of the pmem region it is sent to as a pmem_region
+ * struct (with offset set to 0). 
+ */
+#define PMEM_GET_TOTAL_SIZE	_IOW(PMEM_IOCTL_MAGIC, 7, unsigned int)
+#define PMEM_CACHE_FLUSH	_IOW(PMEM_IOCTL_MAGIC, 8, unsigned int)
+
+struct android_pmem_platform_data
+{
+	const char* name;
+	/* starting physical address of memory region */
+	unsigned long start;
+	/* size of memory region */
+	unsigned long size;
+	/* set to indicate the region should not be managed with an allocator */
+	unsigned no_allocator;
+	/* set to indicate maps of this region should be cached, if a mix of
+	 * cached and uncached is desired, set this and open the device with
+	 * O_SYNC to get an uncached region */
+	unsigned cached;
+	/* The MSM7k has bits to enable a write buffer in the bus controller*/
+	unsigned buffered;
+};
+
+struct pmem_region {
+	unsigned long offset;
+	unsigned long len;
+};
+
+#ifdef CONFIG_ANDROID_PMEM
+int is_pmem_file(struct file *file);
+int get_pmem_file(int fd, unsigned long *start, unsigned long *vstart,
+		  unsigned long *end, struct file **filp);
+int get_pmem_user_addr(struct file *file, unsigned long *start,
+		       unsigned long *end);
+void put_pmem_file(struct file* file);
+void flush_pmem_file(struct file *file, unsigned long start, unsigned long len);
+int pmem_setup(struct android_pmem_platform_data *pdata,
+	       long (*ioctl)(struct file *, unsigned int, unsigned long),
+	       int (*release)(struct inode *, struct file *));
+int pmem_remap(struct pmem_region *region, struct file *file,
+	       unsigned operation);
+
+#else
+static inline int is_pmem_file(struct file *file) { return 0; }
+static inline int get_pmem_file(int fd, unsigned long *start,
+				unsigned long *vstart, unsigned long *end,
+				struct file **filp) { return -ENOSYS; }
+static inline int get_pmem_user_addr(struct file *file, unsigned long *start,
+				     unsigned long *end) { return -ENOSYS; }
+static inline void put_pmem_file(struct file* file) { return; }
+static inline void flush_pmem_file(struct file *file, unsigned long start,
+				   unsigned long len) { return; }
+static inline int pmem_setup(struct android_pmem_platform_data *pdata,
+	      long (*ioctl)(struct file *, unsigned int, unsigned long),
+	      int (*release)(struct inode *, struct file *)) { return -ENOSYS; }
+
+static inline int pmem_remap(struct pmem_region *region, struct file *file,
+			     unsigned operation) { return -ENOSYS; }
+#endif
+
+#endif //_ANDROID_PPP_H_
+
diff --git a/drivers/staging/android/ashmem.c b/drivers/staging/android/ashmem.c
new file mode 100644
index 0000000..99052bf
--- /dev/null
+++ b/drivers/staging/android/ashmem.c
@@ -0,0 +1,752 @@
+/* mm/ashmem.c
+**
+** Anonymous Shared Memory Subsystem, ashmem
+**
+** Copyright (C) 2008 Google, Inc.
+**
+** Robert Love <rlove@google.com>
+**
+** This software is licensed under the terms of the GNU General Public
+** License version 2, as published by the Free Software Foundation, and
+** may be copied, distributed, and modified under those terms.
+**
+** This program is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+** GNU General Public License for more details.
+*/
+
+#include <linux/module.h>
+#include <linux/file.h>
+#include <linux/fs.h>
+#include <linux/miscdevice.h>
+#include <linux/security.h>
+#include <linux/mm.h>
+#include <linux/mman.h>
+#include <linux/uaccess.h>
+#include <linux/personality.h>
+#include <linux/bitops.h>
+#include <linux/mutex.h>
+#include <linux/shmem_fs.h>
+#include "ashmem.h"
+
+#define ASHMEM_NAME_PREFIX "dev/ashmem/"
+#define ASHMEM_NAME_PREFIX_LEN (sizeof(ASHMEM_NAME_PREFIX) - 1)
+#define ASHMEM_FULL_NAME_LEN (ASHMEM_NAME_LEN + ASHMEM_NAME_PREFIX_LEN)
+
+/*
+ * ashmem_area - anonymous shared memory area
+ * Lifecycle: From our parent file's open() until its release()
+ * Locking: Protected by `ashmem_mutex'
+ * Big Note: Mappings do NOT pin this structure; it dies on close()
+ */
+struct ashmem_area {
+	char name[ASHMEM_FULL_NAME_LEN]; /* optional name in /proc/pid/maps */
+	struct list_head unpinned_list;	 /* list of all ashmem areas */
+	struct file *file;		 /* the shmem-based backing file */
+	size_t size;			 /* size of the mapping, in bytes */
+	unsigned long prot_mask;	 /* allowed prot bits, as vm_flags */
+};
+
+/*
+ * ashmem_range - represents an interval of unpinned (evictable) pages
+ * Lifecycle: From unpin to pin
+ * Locking: Protected by `ashmem_mutex'
+ */
+struct ashmem_range {
+	struct list_head lru;		/* entry in LRU list */
+	struct list_head unpinned;	/* entry in its area's unpinned list */
+	struct ashmem_area *asma;	/* associated area */
+	size_t pgstart;			/* starting page, inclusive */
+	size_t pgend;			/* ending page, inclusive */
+	unsigned int purged;		/* ASHMEM_NOT or ASHMEM_WAS_PURGED */
+};
+
+/* LRU list of unpinned pages, protected by ashmem_mutex */
+static LIST_HEAD(ashmem_lru_list);
+
+/* Count of pages on our LRU list, protected by ashmem_mutex */
+static unsigned long lru_count;
+
+/*
+ * ashmem_mutex - protects the list of and each individual ashmem_area
+ *
+ * Lock Ordering: ashmex_mutex -> i_mutex -> i_alloc_sem
+ */
+static DEFINE_MUTEX(ashmem_mutex);
+
+static struct kmem_cache *ashmem_area_cachep __read_mostly;
+static struct kmem_cache *ashmem_range_cachep __read_mostly;
+
+#define range_size(range) \
+	((range)->pgend - (range)->pgstart + 1)
+
+#define range_on_lru(range) \
+	((range)->purged == ASHMEM_NOT_PURGED)
+
+#define page_range_subsumes_range(range, start, end) \
+	(((range)->pgstart >= (start)) && ((range)->pgend <= (end)))
+
+#define page_range_subsumed_by_range(range, start, end) \
+	(((range)->pgstart <= (start)) && ((range)->pgend >= (end)))
+
+#define page_in_range(range, page) \
+	(((range)->pgstart <= (page)) && ((range)->pgend >= (page)))
+
+#define page_range_in_range(range, start, end) \
+	(page_in_range(range, start) || page_in_range(range, end) || \
+		page_range_subsumes_range(range, start, end))
+
+#define range_before_page(range, page) \
+	((range)->pgend < (page))
+
+#define PROT_MASK		(PROT_EXEC | PROT_READ | PROT_WRITE)
+
+static inline void lru_add(struct ashmem_range *range)
+{
+	list_add_tail(&range->lru, &ashmem_lru_list);
+	lru_count += range_size(range);
+}
+
+static inline void lru_del(struct ashmem_range *range)
+{
+	list_del(&range->lru);
+	lru_count -= range_size(range);
+}
+
+/*
+ * range_alloc - allocate and initialize a new ashmem_range structure
+ *
+ * 'asma' - associated ashmem_area
+ * 'prev_range' - the previous ashmem_range in the sorted asma->unpinned list
+ * 'purged' - initial purge value (ASMEM_NOT_PURGED or ASHMEM_WAS_PURGED)
+ * 'start' - starting page, inclusive
+ * 'end' - ending page, inclusive
+ *
+ * Caller must hold ashmem_mutex.
+ */
+static int range_alloc(struct ashmem_area *asma,
+		       struct ashmem_range *prev_range, unsigned int purged,
+		       size_t start, size_t end)
+{
+	struct ashmem_range *range;
+
+	range = kmem_cache_zalloc(ashmem_range_cachep, GFP_KERNEL);
+	if (unlikely(!range))
+		return -ENOMEM;
+
+	range->asma = asma;
+	range->pgstart = start;
+	range->pgend = end;
+	range->purged = purged;
+
+	list_add_tail(&range->unpinned, &prev_range->unpinned);
+
+	if (range_on_lru(range))
+		lru_add(range);
+
+	return 0;
+}
+
+static void range_del(struct ashmem_range *range)
+{
+	list_del(&range->unpinned);
+	if (range_on_lru(range))
+		lru_del(range);
+	kmem_cache_free(ashmem_range_cachep, range);
+}
+
+/*
+ * range_shrink - shrinks a range
+ *
+ * Caller must hold ashmem_mutex.
+ */
+static inline void range_shrink(struct ashmem_range *range,
+				size_t start, size_t end)
+{
+	size_t pre = range_size(range);
+
+	range->pgstart = start;
+	range->pgend = end;
+
+	if (range_on_lru(range))
+		lru_count -= pre - range_size(range);
+}
+
+static int ashmem_open(struct inode *inode, struct file *file)
+{
+	struct ashmem_area *asma;
+	int ret;
+
+	ret = generic_file_open(inode, file);
+	if (unlikely(ret))
+		return ret;
+
+	asma = kmem_cache_zalloc(ashmem_area_cachep, GFP_KERNEL);
+	if (unlikely(!asma))
+		return -ENOMEM;
+
+	INIT_LIST_HEAD(&asma->unpinned_list);
+	memcpy(asma->name, ASHMEM_NAME_PREFIX, ASHMEM_NAME_PREFIX_LEN);
+	asma->prot_mask = PROT_MASK;
+	file->private_data = asma;
+
+	return 0;
+}
+
+static int ashmem_release(struct inode *ignored, struct file *file)
+{
+	struct ashmem_area *asma = file->private_data;
+	struct ashmem_range *range, *next;
+
+	mutex_lock(&ashmem_mutex);
+	list_for_each_entry_safe(range, next, &asma->unpinned_list, unpinned)
+		range_del(range);
+	mutex_unlock(&ashmem_mutex);
+
+	if (asma->file)
+		fput(asma->file);
+	kmem_cache_free(ashmem_area_cachep, asma);
+
+	return 0;
+}
+
+static ssize_t ashmem_read(struct file *file, char __user *buf,
+			   size_t len, loff_t *pos)
+{
+	struct ashmem_area *asma = file->private_data;
+	int ret = 0;
+
+	mutex_lock(&ashmem_mutex);
+
+	/* If size is not set, or set to 0, always return EOF. */
+	if (asma->size == 0)
+		goto out;
+
+	if (!asma->file) {
+		ret = -EBADF;
+		goto out;
+	}
+
+	ret = asma->file->f_op->read(asma->file, buf, len, pos);
+	if (ret < 0)
+		goto out;
+
+	/** Update backing file pos, since f_ops->read() doesn't */
+	asma->file->f_pos = *pos;
+
+out:
+	mutex_unlock(&ashmem_mutex);
+	return ret;
+}
+
+static loff_t ashmem_llseek(struct file *file, loff_t offset, int origin)
+{
+	struct ashmem_area *asma = file->private_data;
+	int ret;
+
+	mutex_lock(&ashmem_mutex);
+
+	if (asma->size == 0) {
+		ret = -EINVAL;
+		goto out;
+	}
+
+	if (!asma->file) {
+		ret = -EBADF;
+		goto out;
+	}
+
+	ret = asma->file->f_op->llseek(asma->file, offset, origin);
+	if (ret < 0)
+		goto out;
+
+	/** Copy f_pos from backing file, since f_ops->llseek() sets it */
+	file->f_pos = asma->file->f_pos;
+
+out:
+	mutex_unlock(&ashmem_mutex);
+	return ret;
+}
+
+static inline unsigned long calc_vm_may_flags(unsigned long prot)
+{
+	return _calc_vm_trans(prot, PROT_READ,  VM_MAYREAD) |
+	       _calc_vm_trans(prot, PROT_WRITE, VM_MAYWRITE) |
+	       _calc_vm_trans(prot, PROT_EXEC,  VM_MAYEXEC);
+}
+
+static int ashmem_mmap(struct file *file, struct vm_area_struct *vma)
+{
+	struct ashmem_area *asma = file->private_data;
+	int ret = 0;
+
+	mutex_lock(&ashmem_mutex);
+
+	/* user needs to SET_SIZE before mapping */
+	if (unlikely(!asma->size)) {
+		ret = -EINVAL;
+		goto out;
+	}
+
+	/* requested protection bits must match our allowed protection mask */
+	if (unlikely((vma->vm_flags & ~calc_vm_prot_bits(asma->prot_mask)) &
+		     calc_vm_prot_bits(PROT_MASK))) {
+		ret = -EPERM;
+		goto out;
+	}
+	vma->vm_flags &= ~calc_vm_may_flags(~asma->prot_mask);
+
+	if (!asma->file) {
+		char *name = ASHMEM_NAME_DEF;
+		struct file *vmfile;
+
+		if (asma->name[ASHMEM_NAME_PREFIX_LEN] != '\0')
+			name = asma->name;
+
+		/* ... and allocate the backing shmem file */
+		vmfile = shmem_file_setup(name, asma->size, vma->vm_flags);
+		if (unlikely(IS_ERR(vmfile))) {
+			ret = PTR_ERR(vmfile);
+			goto out;
+		}
+		asma->file = vmfile;
+	}
+	get_file(asma->file);
+
+	/*
+	 * XXX - Reworked to use shmem_zero_setup() instead of 
+	 * shmem_set_file while we're in staging. -jstultz
+	 */
+	if (vma->vm_flags & VM_SHARED) {
+		ret = shmem_zero_setup(vma);
+		if (ret) {
+			fput(asma->file);
+			goto out;
+		}
+	}
+
+	if (vma->vm_file)
+		fput(vma->vm_file);
+	vma->vm_file = asma->file;
+	vma->vm_flags |= VM_CAN_NONLINEAR;
+
+out:
+	mutex_unlock(&ashmem_mutex);
+	return ret;
+}
+
+/*
+ * ashmem_shrink - our cache shrinker, called from mm/vmscan.c :: shrink_slab
+ *
+ * 'nr_to_scan' is the number of objects (pages) to prune, or 0 to query how
+ * many objects (pages) we have in total.
+ *
+ * 'gfp_mask' is the mask of the allocation that got us into this mess.
+ *
+ * Return value is the number of objects (pages) remaining, or -1 if we cannot
+ * proceed without risk of deadlock (due to gfp_mask).
+ *
+ * We approximate LRU via least-recently-unpinned, jettisoning unpinned partial
+ * chunks of ashmem regions LRU-wise one-at-a-time until we hit 'nr_to_scan'
+ * pages freed.
+ */
+static int ashmem_shrink(struct shrinker *s, struct shrink_control *sc)
+{
+	struct ashmem_range *range, *next;
+
+	/* We might recurse into filesystem code, so bail out if necessary */
+	if (sc->nr_to_scan && !(sc->gfp_mask & __GFP_FS))
+		return -1;
+	if (!sc->nr_to_scan)
+		return lru_count;
+
+	mutex_lock(&ashmem_mutex);
+	list_for_each_entry_safe(range, next, &ashmem_lru_list, lru) {
+		struct inode *inode = range->asma->file->f_dentry->d_inode;
+		loff_t start = range->pgstart * PAGE_SIZE;
+		loff_t end = (range->pgend + 1) * PAGE_SIZE - 1;
+
+		vmtruncate_range(inode, start, end);
+		range->purged = ASHMEM_WAS_PURGED;
+		lru_del(range);
+
+		sc->nr_to_scan -= range_size(range);
+		if (sc->nr_to_scan <= 0)
+			break;
+	}
+	mutex_unlock(&ashmem_mutex);
+
+	return lru_count;
+}
+
+static struct shrinker ashmem_shrinker = {
+	.shrink = ashmem_shrink,
+	.seeks = DEFAULT_SEEKS * 4,
+};
+
+static int set_prot_mask(struct ashmem_area *asma, unsigned long prot)
+{
+	int ret = 0;
+
+	mutex_lock(&ashmem_mutex);
+
+	/* the user can only remove, not add, protection bits */
+	if (unlikely((asma->prot_mask & prot) != prot)) {
+		ret = -EINVAL;
+		goto out;
+	}
+
+	/* does the application expect PROT_READ to imply PROT_EXEC? */
+	if ((prot & PROT_READ) && (current->personality & READ_IMPLIES_EXEC))
+		prot |= PROT_EXEC;
+
+	asma->prot_mask = prot;
+
+out:
+	mutex_unlock(&ashmem_mutex);
+	return ret;
+}
+
+static int set_name(struct ashmem_area *asma, void __user *name)
+{
+	int ret = 0;
+
+	mutex_lock(&ashmem_mutex);
+
+	/* cannot change an existing mapping's name */
+	if (unlikely(asma->file)) {
+		ret = -EINVAL;
+		goto out;
+	}
+
+	if (unlikely(copy_from_user(asma->name + ASHMEM_NAME_PREFIX_LEN,
+				    name, ASHMEM_NAME_LEN)))
+		ret = -EFAULT;
+	asma->name[ASHMEM_FULL_NAME_LEN-1] = '\0';
+
+out:
+	mutex_unlock(&ashmem_mutex);
+
+	return ret;
+}
+
+static int get_name(struct ashmem_area *asma, void __user *name)
+{
+	int ret = 0;
+
+	mutex_lock(&ashmem_mutex);
+	if (asma->name[ASHMEM_NAME_PREFIX_LEN] != '\0') {
+		size_t len;
+
+		/*
+		 * Copying only `len', instead of ASHMEM_NAME_LEN, bytes
+		 * prevents us from revealing one user's stack to another.
+		 */
+		len = strlen(asma->name + ASHMEM_NAME_PREFIX_LEN) + 1;
+		if (unlikely(copy_to_user(name,
+				asma->name + ASHMEM_NAME_PREFIX_LEN, len)))
+			ret = -EFAULT;
+	} else {
+		if (unlikely(copy_to_user(name, ASHMEM_NAME_DEF,
+					  sizeof(ASHMEM_NAME_DEF))))
+			ret = -EFAULT;
+	}
+	mutex_unlock(&ashmem_mutex);
+
+	return ret;
+}
+
+/*
+ * ashmem_pin - pin the given ashmem region, returning whether it was
+ * previously purged (ASHMEM_WAS_PURGED) or not (ASHMEM_NOT_PURGED).
+ *
+ * Caller must hold ashmem_mutex.
+ */
+static int ashmem_pin(struct ashmem_area *asma, size_t pgstart, size_t pgend)
+{
+	struct ashmem_range *range, *next;
+	int ret = ASHMEM_NOT_PURGED;
+
+	list_for_each_entry_safe(range, next, &asma->unpinned_list, unpinned) {
+		/* moved past last applicable page; we can short circuit */
+		if (range_before_page(range, pgstart))
+			break;
+
+		/*
+		 * The user can ask us to pin pages that span multiple ranges,
+		 * or to pin pages that aren't even unpinned, so this is messy.
+		 *
+		 * Four cases:
+		 * 1. The requested range subsumes an existing range, so we
+		 *    just remove the entire matching range.
+		 * 2. The requested range overlaps the start of an existing
+		 *    range, so we just update that range.
+		 * 3. The requested range overlaps the end of an existing
+		 *    range, so we just update that range.
+		 * 4. The requested range punches a hole in an existing range,
+		 *    so we have to update one side of the range and then
+		 *    create a new range for the other side.
+		 */
+		if (page_range_in_range(range, pgstart, pgend)) {
+			ret |= range->purged;
+
+			/* Case #1: Easy. Just nuke the whole thing. */
+			if (page_range_subsumes_range(range, pgstart, pgend)) {
+				range_del(range);
+				continue;
+			}
+
+			/* Case #2: We overlap from the start, so adjust it */
+			if (range->pgstart >= pgstart) {
+				range_shrink(range, pgend + 1, range->pgend);
+				continue;
+			}
+
+			/* Case #3: We overlap from the rear, so adjust it */
+			if (range->pgend <= pgend) {
+				range_shrink(range, range->pgstart, pgstart-1);
+				continue;
+			}
+
+			/*
+			 * Case #4: We eat a chunk out of the middle. A bit
+			 * more complicated, we allocate a new range for the
+			 * second half and adjust the first chunk's endpoint.
+			 */
+			range_alloc(asma, range, range->purged,
+				    pgend + 1, range->pgend);
+			range_shrink(range, range->pgstart, pgstart - 1);
+			break;
+		}
+	}
+
+	return ret;
+}
+
+/*
+ * ashmem_unpin - unpin the given range of pages. Returns zero on success.
+ *
+ * Caller must hold ashmem_mutex.
+ */
+static int ashmem_unpin(struct ashmem_area *asma, size_t pgstart, size_t pgend)
+{
+	struct ashmem_range *range, *next;
+	unsigned int purged = ASHMEM_NOT_PURGED;
+
+restart:
+	list_for_each_entry_safe(range, next, &asma->unpinned_list, unpinned) {
+		/* short circuit: this is our insertion point */
+		if (range_before_page(range, pgstart))
+			break;
+
+		/*
+		 * The user can ask us to unpin pages that are already entirely
+		 * or partially pinned. We handle those two cases here.
+		 */
+		if (page_range_subsumed_by_range(range, pgstart, pgend))
+			return 0;
+		if (page_range_in_range(range, pgstart, pgend)) {
+			pgstart = min_t(size_t, range->pgstart, pgstart),
+			pgend = max_t(size_t, range->pgend, pgend);
+			purged |= range->purged;
+			range_del(range);
+			goto restart;
+		}
+	}
+
+	return range_alloc(asma, range, purged, pgstart, pgend);
+}
+
+/*
+ * ashmem_get_pin_status - Returns ASHMEM_IS_UNPINNED if _any_ pages in the
+ * given interval are unpinned and ASHMEM_IS_PINNED otherwise.
+ *
+ * Caller must hold ashmem_mutex.
+ */
+static int ashmem_get_pin_status(struct ashmem_area *asma, size_t pgstart,
+				 size_t pgend)
+{
+	struct ashmem_range *range;
+	int ret = ASHMEM_IS_PINNED;
+
+	list_for_each_entry(range, &asma->unpinned_list, unpinned) {
+		if (range_before_page(range, pgstart))
+			break;
+		if (page_range_in_range(range, pgstart, pgend)) {
+			ret = ASHMEM_IS_UNPINNED;
+			break;
+		}
+	}
+
+	return ret;
+}
+
+static int ashmem_pin_unpin(struct ashmem_area *asma, unsigned long cmd,
+			    void __user *p)
+{
+	struct ashmem_pin pin;
+	size_t pgstart, pgend;
+	int ret = -EINVAL;
+
+	if (unlikely(!asma->file))
+		return -EINVAL;
+
+	if (unlikely(copy_from_user(&pin, p, sizeof(pin))))
+		return -EFAULT;
+
+	/* per custom, you can pass zero for len to mean "everything onward" */
+	if (!pin.len)
+		pin.len = PAGE_ALIGN(asma->size) - pin.offset;
+
+	if (unlikely((pin.offset | pin.len) & ~PAGE_MASK))
+		return -EINVAL;
+
+	if (unlikely(((__u32) -1) - pin.offset < pin.len))
+		return -EINVAL;
+
+	if (unlikely(PAGE_ALIGN(asma->size) < pin.offset + pin.len))
+		return -EINVAL;
+
+	pgstart = pin.offset / PAGE_SIZE;
+	pgend = pgstart + (pin.len / PAGE_SIZE) - 1;
+
+	mutex_lock(&ashmem_mutex);
+
+	switch (cmd) {
+	case ASHMEM_PIN:
+		ret = ashmem_pin(asma, pgstart, pgend);
+		break;
+	case ASHMEM_UNPIN:
+		ret = ashmem_unpin(asma, pgstart, pgend);
+		break;
+	case ASHMEM_GET_PIN_STATUS:
+		ret = ashmem_get_pin_status(asma, pgstart, pgend);
+		break;
+	}
+
+	mutex_unlock(&ashmem_mutex);
+
+	return ret;
+}
+
+static long ashmem_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
+{
+	struct ashmem_area *asma = file->private_data;
+	long ret = -ENOTTY;
+
+	switch (cmd) {
+	case ASHMEM_SET_NAME:
+		ret = set_name(asma, (void __user *) arg);
+		break;
+	case ASHMEM_GET_NAME:
+		ret = get_name(asma, (void __user *) arg);
+		break;
+	case ASHMEM_SET_SIZE:
+		ret = -EINVAL;
+		if (!asma->file) {
+			ret = 0;
+			asma->size = (size_t) arg;
+		}
+		break;
+	case ASHMEM_GET_SIZE:
+		ret = asma->size;
+		break;
+	case ASHMEM_SET_PROT_MASK:
+		ret = set_prot_mask(asma, arg);
+		break;
+	case ASHMEM_GET_PROT_MASK:
+		ret = asma->prot_mask;
+		break;
+	case ASHMEM_PIN:
+	case ASHMEM_UNPIN:
+	case ASHMEM_GET_PIN_STATUS:
+		ret = ashmem_pin_unpin(asma, cmd, (void __user *) arg);
+		break;
+	case ASHMEM_PURGE_ALL_CACHES:
+		ret = -EPERM;
+		if (capable(CAP_SYS_ADMIN)) {
+			struct shrink_control sc = {
+				.gfp_mask = GFP_KERNEL,
+				.nr_to_scan = 0,
+			};
+			ret = ashmem_shrink(&ashmem_shrinker, &sc);
+			sc.nr_to_scan = ret;
+			ashmem_shrink(&ashmem_shrinker, &sc);
+		}
+		break;
+	}
+
+	return ret;
+}
+
+static struct file_operations ashmem_fops = {
+	.owner = THIS_MODULE,
+	.open = ashmem_open,
+	.release = ashmem_release,
+	.read = ashmem_read,
+	.llseek = ashmem_llseek,
+	.mmap = ashmem_mmap,
+	.unlocked_ioctl = ashmem_ioctl,
+	.compat_ioctl = ashmem_ioctl,
+};
+
+static struct miscdevice ashmem_misc = {
+	.minor = MISC_DYNAMIC_MINOR,
+	.name = "ashmem",
+	.fops = &ashmem_fops,
+};
+
+static int __init ashmem_init(void)
+{
+	int ret;
+
+	ashmem_area_cachep = kmem_cache_create("ashmem_area_cache",
+					  sizeof(struct ashmem_area),
+					  0, 0, NULL);
+	if (unlikely(!ashmem_area_cachep)) {
+		printk(KERN_ERR "ashmem: failed to create slab cache\n");
+		return -ENOMEM;
+	}
+
+	ashmem_range_cachep = kmem_cache_create("ashmem_range_cache",
+					  sizeof(struct ashmem_range),
+					  0, 0, NULL);
+	if (unlikely(!ashmem_range_cachep)) {
+		printk(KERN_ERR "ashmem: failed to create slab cache\n");
+		return -ENOMEM;
+	}
+
+	ret = misc_register(&ashmem_misc);
+	if (unlikely(ret)) {
+		printk(KERN_ERR "ashmem: failed to register misc device!\n");
+		return ret;
+	}
+
+	register_shrinker(&ashmem_shrinker);
+
+	printk(KERN_INFO "ashmem: initialized\n");
+
+	return 0;
+}
+
+static void __exit ashmem_exit(void)
+{
+	int ret;
+
+	unregister_shrinker(&ashmem_shrinker);
+
+	ret = misc_deregister(&ashmem_misc);
+	if (unlikely(ret))
+		printk(KERN_ERR "ashmem: failed to unregister misc device!\n");
+
+	kmem_cache_destroy(ashmem_range_cachep);
+	kmem_cache_destroy(ashmem_area_cachep);
+
+	printk(KERN_INFO "ashmem: unloaded\n");
+}
+
+module_init(ashmem_init);
+module_exit(ashmem_exit);
+
+MODULE_LICENSE("GPL");
diff --git a/drivers/staging/android/ashmem.h b/drivers/staging/android/ashmem.h
new file mode 100644
index 0000000..1976b10
--- /dev/null
+++ b/drivers/staging/android/ashmem.h
@@ -0,0 +1,48 @@
+/*
+ * include/linux/ashmem.h
+ *
+ * Copyright 2008 Google Inc.
+ * Author: Robert Love
+ *
+ * This file is dual licensed.  It may be redistributed and/or modified
+ * under the terms of the Apache 2.0 License OR version 2 of the GNU
+ * General Public License.
+ */
+
+#ifndef _LINUX_ASHMEM_H
+#define _LINUX_ASHMEM_H
+
+#include <linux/limits.h>
+#include <linux/ioctl.h>
+
+#define ASHMEM_NAME_LEN		256
+
+#define ASHMEM_NAME_DEF		"dev/ashmem"
+
+/* Return values from ASHMEM_PIN: Was the mapping purged while unpinned? */
+#define ASHMEM_NOT_PURGED	0
+#define ASHMEM_WAS_PURGED	1
+
+/* Return values from ASHMEM_GET_PIN_STATUS: Is the mapping pinned? */
+#define ASHMEM_IS_UNPINNED	0
+#define ASHMEM_IS_PINNED	1
+
+struct ashmem_pin {
+	__u32 offset;	/* offset into region, in bytes, page-aligned */
+	__u32 len;	/* length forward from offset, in bytes, page-aligned */
+};
+
+#define __ASHMEMIOC		0x77
+
+#define ASHMEM_SET_NAME		_IOW(__ASHMEMIOC, 1, char[ASHMEM_NAME_LEN])
+#define ASHMEM_GET_NAME		_IOR(__ASHMEMIOC, 2, char[ASHMEM_NAME_LEN])
+#define ASHMEM_SET_SIZE		_IOW(__ASHMEMIOC, 3, size_t)
+#define ASHMEM_GET_SIZE		_IO(__ASHMEMIOC, 4)
+#define ASHMEM_SET_PROT_MASK	_IOW(__ASHMEMIOC, 5, unsigned long)
+#define ASHMEM_GET_PROT_MASK	_IO(__ASHMEMIOC, 6)
+#define ASHMEM_PIN		_IOW(__ASHMEMIOC, 7, struct ashmem_pin)
+#define ASHMEM_UNPIN		_IOW(__ASHMEMIOC, 8, struct ashmem_pin)
+#define ASHMEM_GET_PIN_STATUS	_IO(__ASHMEMIOC, 9)
+#define ASHMEM_PURGE_ALL_CACHES	_IO(__ASHMEMIOC, 10)
+
+#endif	/* _LINUX_ASHMEM_H */
diff --git a/drivers/staging/android/binder.c b/drivers/staging/android/binder.c
new file mode 100644
index 0000000..7491801
--- /dev/null
+++ b/drivers/staging/android/binder.c
@@ -0,0 +1,3600 @@
+/* binder.c
+ *
+ * Android IPC Subsystem
+ *
+ * Copyright (C) 2007-2008 Google, Inc.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include <asm/cacheflush.h>
+#include <linux/fdtable.h>
+#include <linux/file.h>
+#include <linux/fs.h>
+#include <linux/list.h>
+#include <linux/miscdevice.h>
+#include <linux/mm.h>
+#include <linux/module.h>
+#include <linux/mutex.h>
+#include <linux/nsproxy.h>
+#include <linux/poll.h>
+#include <linux/debugfs.h>
+#include <linux/rbtree.h>
+#include <linux/sched.h>
+#include <linux/seq_file.h>
+#include <linux/uaccess.h>
+#include <linux/vmalloc.h>
+#include <linux/slab.h>
+
+#include "binder.h"
+
+static DEFINE_MUTEX(binder_lock);
+static DEFINE_MUTEX(binder_deferred_lock);
+
+static HLIST_HEAD(binder_procs);
+static HLIST_HEAD(binder_deferred_list);
+static HLIST_HEAD(binder_dead_nodes);
+
+static struct dentry *binder_debugfs_dir_entry_root;
+static struct dentry *binder_debugfs_dir_entry_proc;
+static struct binder_node *binder_context_mgr_node;
+static uid_t binder_context_mgr_uid = -1;
+static int binder_last_id;
+static struct workqueue_struct *binder_deferred_workqueue;
+
+#define BINDER_DEBUG_ENTRY(name) \
+static int binder_##name##_open(struct inode *inode, struct file *file) \
+{ \
+	return single_open(file, binder_##name##_show, inode->i_private); \
+} \
+\
+static const struct file_operations binder_##name##_fops = { \
+	.owner = THIS_MODULE, \
+	.open = binder_##name##_open, \
+	.read = seq_read, \
+	.llseek = seq_lseek, \
+	.release = single_release, \
+}
+
+static int binder_proc_show(struct seq_file *m, void *unused);
+BINDER_DEBUG_ENTRY(proc);
+
+/* This is only defined in include/asm-arm/sizes.h */
+#ifndef SZ_1K
+#define SZ_1K                               0x400
+#endif
+
+#ifndef SZ_4M
+#define SZ_4M                               0x400000
+#endif
+
+#define FORBIDDEN_MMAP_FLAGS                (VM_WRITE)
+
+#define BINDER_SMALL_BUF_SIZE (PAGE_SIZE * 64)
+
+enum {
+	BINDER_DEBUG_USER_ERROR             = 1U << 0,
+	BINDER_DEBUG_FAILED_TRANSACTION     = 1U << 1,
+	BINDER_DEBUG_DEAD_TRANSACTION       = 1U << 2,
+	BINDER_DEBUG_OPEN_CLOSE             = 1U << 3,
+	BINDER_DEBUG_DEAD_BINDER            = 1U << 4,
+	BINDER_DEBUG_DEATH_NOTIFICATION     = 1U << 5,
+	BINDER_DEBUG_READ_WRITE             = 1U << 6,
+	BINDER_DEBUG_USER_REFS              = 1U << 7,
+	BINDER_DEBUG_THREADS                = 1U << 8,
+	BINDER_DEBUG_TRANSACTION            = 1U << 9,
+	BINDER_DEBUG_TRANSACTION_COMPLETE   = 1U << 10,
+	BINDER_DEBUG_FREE_BUFFER            = 1U << 11,
+	BINDER_DEBUG_INTERNAL_REFS          = 1U << 12,
+	BINDER_DEBUG_BUFFER_ALLOC           = 1U << 13,
+	BINDER_DEBUG_PRIORITY_CAP           = 1U << 14,
+	BINDER_DEBUG_BUFFER_ALLOC_ASYNC     = 1U << 15,
+};
+static uint32_t binder_debug_mask = BINDER_DEBUG_USER_ERROR |
+	BINDER_DEBUG_FAILED_TRANSACTION | BINDER_DEBUG_DEAD_TRANSACTION;
+module_param_named(debug_mask, binder_debug_mask, uint, S_IWUSR | S_IRUGO);
+
+static int binder_debug_no_lock;
+module_param_named(proc_no_lock, binder_debug_no_lock, bool, S_IWUSR | S_IRUGO);
+
+static DECLARE_WAIT_QUEUE_HEAD(binder_user_error_wait);
+static int binder_stop_on_user_error;
+
+static int binder_set_stop_on_user_error(const char *val,
+					 struct kernel_param *kp)
+{
+	int ret;
+	ret = param_set_int(val, kp);
+	if (binder_stop_on_user_error < 2)
+		wake_up(&binder_user_error_wait);
+	return ret;
+}
+module_param_call(stop_on_user_error, binder_set_stop_on_user_error,
+	param_get_int, &binder_stop_on_user_error, S_IWUSR | S_IRUGO);
+
+#define binder_debug(mask, x...) \
+	do { \
+		if (binder_debug_mask & mask) \
+			printk(KERN_INFO x); \
+	} while (0)
+
+#define binder_user_error(x...) \
+	do { \
+		if (binder_debug_mask & BINDER_DEBUG_USER_ERROR) \
+			printk(KERN_INFO x); \
+		if (binder_stop_on_user_error) \
+			binder_stop_on_user_error = 2; \
+	} while (0)
+
+enum binder_stat_types {
+	BINDER_STAT_PROC,
+	BINDER_STAT_THREAD,
+	BINDER_STAT_NODE,
+	BINDER_STAT_REF,
+	BINDER_STAT_DEATH,
+	BINDER_STAT_TRANSACTION,
+	BINDER_STAT_TRANSACTION_COMPLETE,
+	BINDER_STAT_COUNT
+};
+
+struct binder_stats {
+	int br[_IOC_NR(BR_FAILED_REPLY) + 1];
+	int bc[_IOC_NR(BC_DEAD_BINDER_DONE) + 1];
+	int obj_created[BINDER_STAT_COUNT];
+	int obj_deleted[BINDER_STAT_COUNT];
+};
+
+static struct binder_stats binder_stats;
+
+static inline void binder_stats_deleted(enum binder_stat_types type)
+{
+	binder_stats.obj_deleted[type]++;
+}
+
+static inline void binder_stats_created(enum binder_stat_types type)
+{
+	binder_stats.obj_created[type]++;
+}
+
+struct binder_transaction_log_entry {
+	int debug_id;
+	int call_type;
+	int from_proc;
+	int from_thread;
+	int target_handle;
+	int to_proc;
+	int to_thread;
+	int to_node;
+	int data_size;
+	int offsets_size;
+};
+struct binder_transaction_log {
+	int next;
+	int full;
+	struct binder_transaction_log_entry entry[32];
+};
+static struct binder_transaction_log binder_transaction_log;
+static struct binder_transaction_log binder_transaction_log_failed;
+
+static struct binder_transaction_log_entry *binder_transaction_log_add(
+	struct binder_transaction_log *log)
+{
+	struct binder_transaction_log_entry *e;
+	e = &log->entry[log->next];
+	memset(e, 0, sizeof(*e));
+	log->next++;
+	if (log->next == ARRAY_SIZE(log->entry)) {
+		log->next = 0;
+		log->full = 1;
+	}
+	return e;
+}
+
+struct binder_work {
+	struct list_head entry;
+	enum {
+		BINDER_WORK_TRANSACTION = 1,
+		BINDER_WORK_TRANSACTION_COMPLETE,
+		BINDER_WORK_NODE,
+		BINDER_WORK_DEAD_BINDER,
+		BINDER_WORK_DEAD_BINDER_AND_CLEAR,
+		BINDER_WORK_CLEAR_DEATH_NOTIFICATION,
+	} type;
+};
+
+struct binder_node {
+	int debug_id;
+	struct binder_work work;
+	union {
+		struct rb_node rb_node;
+		struct hlist_node dead_node;
+	};
+	struct binder_proc *proc;
+	struct hlist_head refs;
+	int internal_strong_refs;
+	int local_weak_refs;
+	int local_strong_refs;
+	void __user *ptr;
+	void __user *cookie;
+	unsigned has_strong_ref:1;
+	unsigned pending_strong_ref:1;
+	unsigned has_weak_ref:1;
+	unsigned pending_weak_ref:1;
+	unsigned has_async_transaction:1;
+	unsigned accept_fds:1;
+	unsigned min_priority:8;
+	struct list_head async_todo;
+};
+
+struct binder_ref_death {
+	struct binder_work work;
+	void __user *cookie;
+};
+
+struct binder_ref {
+	/* Lookups needed: */
+	/*   node + proc => ref (transaction) */
+	/*   desc + proc => ref (transaction, inc/dec ref) */
+	/*   node => refs + procs (proc exit) */
+	int debug_id;
+	struct rb_node rb_node_desc;
+	struct rb_node rb_node_node;
+	struct hlist_node node_entry;
+	struct binder_proc *proc;
+	struct binder_node *node;
+	uint32_t desc;
+	int strong;
+	int weak;
+	struct binder_ref_death *death;
+};
+
+struct binder_buffer {
+	struct list_head entry; /* free and allocated entries by addesss */
+	struct rb_node rb_node; /* free entry by size or allocated entry */
+				/* by address */
+	unsigned free:1;
+	unsigned allow_user_free:1;
+	unsigned async_transaction:1;
+	unsigned debug_id:29;
+
+	struct binder_transaction *transaction;
+
+	struct binder_node *target_node;
+	size_t data_size;
+	size_t offsets_size;
+	uint8_t data[0];
+};
+
+enum binder_deferred_state {
+	BINDER_DEFERRED_PUT_FILES    = 0x01,
+	BINDER_DEFERRED_FLUSH        = 0x02,
+	BINDER_DEFERRED_RELEASE      = 0x04,
+};
+
+struct binder_proc {
+	struct hlist_node proc_node;
+	struct rb_root threads;
+	struct rb_root nodes;
+	struct rb_root refs_by_desc;
+	struct rb_root refs_by_node;
+	int pid;
+	struct vm_area_struct *vma;
+	struct task_struct *tsk;
+	struct files_struct *files;
+	struct hlist_node deferred_work_node;
+	int deferred_work;
+	void *buffer;
+	ptrdiff_t user_buffer_offset;
+
+	struct list_head buffers;
+	struct rb_root free_buffers;
+	struct rb_root allocated_buffers;
+	size_t free_async_space;
+
+	struct page **pages;
+	size_t buffer_size;
+	uint32_t buffer_free;
+	struct list_head todo;
+	wait_queue_head_t wait;
+	struct binder_stats stats;
+	struct list_head delivered_death;
+	int max_threads;
+	int requested_threads;
+	int requested_threads_started;
+	int ready_threads;
+	long default_priority;
+	struct dentry *debugfs_entry;
+};
+
+enum {
+	BINDER_LOOPER_STATE_REGISTERED  = 0x01,
+	BINDER_LOOPER_STATE_ENTERED     = 0x02,
+	BINDER_LOOPER_STATE_EXITED      = 0x04,
+	BINDER_LOOPER_STATE_INVALID     = 0x08,
+	BINDER_LOOPER_STATE_WAITING     = 0x10,
+	BINDER_LOOPER_STATE_NEED_RETURN = 0x20
+};
+
+struct binder_thread {
+	struct binder_proc *proc;
+	struct rb_node rb_node;
+	int pid;
+	int looper;
+	struct binder_transaction *transaction_stack;
+	struct list_head todo;
+	uint32_t return_error; /* Write failed, return error code in read buf */
+	uint32_t return_error2; /* Write failed, return error code in read */
+		/* buffer. Used when sending a reply to a dead process that */
+		/* we are also waiting on */
+	wait_queue_head_t wait;
+	struct binder_stats stats;
+};
+
+struct binder_transaction {
+	int debug_id;
+	struct binder_work work;
+	struct binder_thread *from;
+	struct binder_transaction *from_parent;
+	struct binder_proc *to_proc;
+	struct binder_thread *to_thread;
+	struct binder_transaction *to_parent;
+	unsigned need_reply:1;
+	/* unsigned is_dead:1; */	/* not used at the moment */
+
+	struct binder_buffer *buffer;
+	unsigned int	code;
+	unsigned int	flags;
+	long	priority;
+	long	saved_priority;
+	uid_t	sender_euid;
+};
+
+static void
+binder_defer_work(struct binder_proc *proc, enum binder_deferred_state defer);
+
+/*
+ * copied from get_unused_fd_flags
+ */
+int task_get_unused_fd_flags(struct binder_proc *proc, int flags)
+{
+	struct files_struct *files = proc->files;
+	int fd, error;
+	struct fdtable *fdt;
+	unsigned long rlim_cur;
+	unsigned long irqs;
+
+	if (files == NULL)
+		return -ESRCH;
+
+	error = -EMFILE;
+	spin_lock(&files->file_lock);
+
+repeat:
+	fdt = files_fdtable(files);
+	fd = find_next_zero_bit(fdt->open_fds->fds_bits, fdt->max_fds,
+				files->next_fd);
+
+	/*
+	 * N.B. For clone tasks sharing a files structure, this test
+	 * will limit the total number of files that can be opened.
+	 */
+	rlim_cur = 0;
+	if (lock_task_sighand(proc->tsk, &irqs)) {
+		rlim_cur = proc->tsk->signal->rlim[RLIMIT_NOFILE].rlim_cur;
+		unlock_task_sighand(proc->tsk, &irqs);
+	}
+	if (fd >= rlim_cur)
+		goto out;
+
+	/* Do we need to expand the fd array or fd set?  */
+	error = expand_files(files, fd);
+	if (error < 0)
+		goto out;
+
+	if (error) {
+		/*
+		 * If we needed to expand the fs array we
+		 * might have blocked - try again.
+		 */
+		error = -EMFILE;
+		goto repeat;
+	}
+
+	FD_SET(fd, fdt->open_fds);
+	if (flags & O_CLOEXEC)
+		FD_SET(fd, fdt->close_on_exec);
+	else
+		FD_CLR(fd, fdt->close_on_exec);
+	files->next_fd = fd + 1;
+#if 1
+	/* Sanity check */
+	if (fdt->fd[fd] != NULL) {
+		printk(KERN_WARNING "get_unused_fd: slot %d not NULL!\n", fd);
+		fdt->fd[fd] = NULL;
+	}
+#endif
+	error = fd;
+
+out:
+	spin_unlock(&files->file_lock);
+	return error;
+}
+
+/*
+ * copied from fd_install
+ */
+static void task_fd_install(
+	struct binder_proc *proc, unsigned int fd, struct file *file)
+{
+	struct files_struct *files = proc->files;
+	struct fdtable *fdt;
+
+	if (files == NULL)
+		return;
+
+	spin_lock(&files->file_lock);
+	fdt = files_fdtable(files);
+	BUG_ON(fdt->fd[fd] != NULL);
+	rcu_assign_pointer(fdt->fd[fd], file);
+	spin_unlock(&files->file_lock);
+}
+
+/*
+ * copied from __put_unused_fd in open.c
+ */
+static void __put_unused_fd(struct files_struct *files, unsigned int fd)
+{
+	struct fdtable *fdt = files_fdtable(files);
+	__FD_CLR(fd, fdt->open_fds);
+	if (fd < files->next_fd)
+		files->next_fd = fd;
+}
+
+/*
+ * copied from sys_close
+ */
+static long task_close_fd(struct binder_proc *proc, unsigned int fd)
+{
+	struct file *filp;
+	struct files_struct *files = proc->files;
+	struct fdtable *fdt;
+	int retval;
+
+	if (files == NULL)
+		return -ESRCH;
+
+	spin_lock(&files->file_lock);
+	fdt = files_fdtable(files);
+	if (fd >= fdt->max_fds)
+		goto out_unlock;
+	filp = fdt->fd[fd];
+	if (!filp)
+		goto out_unlock;
+	rcu_assign_pointer(fdt->fd[fd], NULL);
+	FD_CLR(fd, fdt->close_on_exec);
+	__put_unused_fd(files, fd);
+	spin_unlock(&files->file_lock);
+	retval = filp_close(filp, files);
+
+	/* can't restart close syscall because file table entry was cleared */
+	if (unlikely(retval == -ERESTARTSYS ||
+		     retval == -ERESTARTNOINTR ||
+		     retval == -ERESTARTNOHAND ||
+		     retval == -ERESTART_RESTARTBLOCK))
+		retval = -EINTR;
+
+	return retval;
+
+out_unlock:
+	spin_unlock(&files->file_lock);
+	return -EBADF;
+}
+
+static void binder_set_nice(long nice)
+{
+	long min_nice;
+	if (can_nice(current, nice)) {
+		set_user_nice(current, nice);
+		return;
+	}
+	min_nice = 20 - current->signal->rlim[RLIMIT_NICE].rlim_cur;
+	binder_debug(BINDER_DEBUG_PRIORITY_CAP,
+		     "binder: %d: nice value %ld not allowed use "
+		     "%ld instead\n", current->pid, nice, min_nice);
+	set_user_nice(current, min_nice);
+	if (min_nice < 20)
+		return;
+	binder_user_error("binder: %d RLIMIT_NICE not set\n", current->pid);
+}
+
+static size_t binder_buffer_size(struct binder_proc *proc,
+				 struct binder_buffer *buffer)
+{
+	if (list_is_last(&buffer->entry, &proc->buffers))
+		return proc->buffer + proc->buffer_size - (void *)buffer->data;
+	else
+		return (size_t)list_entry(buffer->entry.next,
+			struct binder_buffer, entry) - (size_t)buffer->data;
+}
+
+static void binder_insert_free_buffer(struct binder_proc *proc,
+				      struct binder_buffer *new_buffer)
+{
+	struct rb_node **p = &proc->free_buffers.rb_node;
+	struct rb_node *parent = NULL;
+	struct binder_buffer *buffer;
+	size_t buffer_size;
+	size_t new_buffer_size;
+
+	BUG_ON(!new_buffer->free);
+
+	new_buffer_size = binder_buffer_size(proc, new_buffer);
+
+	binder_debug(BINDER_DEBUG_BUFFER_ALLOC,
+		     "binder: %d: add free buffer, size %zd, "
+		     "at %p\n", proc->pid, new_buffer_size, new_buffer);
+
+	while (*p) {
+		parent = *p;
+		buffer = rb_entry(parent, struct binder_buffer, rb_node);
+		BUG_ON(!buffer->free);
+
+		buffer_size = binder_buffer_size(proc, buffer);
+
+		if (new_buffer_size < buffer_size)
+			p = &parent->rb_left;
+		else
+			p = &parent->rb_right;
+	}
+	rb_link_node(&new_buffer->rb_node, parent, p);
+	rb_insert_color(&new_buffer->rb_node, &proc->free_buffers);
+}
+
+static void binder_insert_allocated_buffer(struct binder_proc *proc,
+					   struct binder_buffer *new_buffer)
+{
+	struct rb_node **p = &proc->allocated_buffers.rb_node;
+	struct rb_node *parent = NULL;
+	struct binder_buffer *buffer;
+
+	BUG_ON(new_buffer->free);
+
+	while (*p) {
+		parent = *p;
+		buffer = rb_entry(parent, struct binder_buffer, rb_node);
+		BUG_ON(buffer->free);
+
+		if (new_buffer < buffer)
+			p = &parent->rb_left;
+		else if (new_buffer > buffer)
+			p = &parent->rb_right;
+		else
+			BUG();
+	}
+	rb_link_node(&new_buffer->rb_node, parent, p);
+	rb_insert_color(&new_buffer->rb_node, &proc->allocated_buffers);
+}
+
+static struct binder_buffer *binder_buffer_lookup(struct binder_proc *proc,
+						  void __user *user_ptr)
+{
+	struct rb_node *n = proc->allocated_buffers.rb_node;
+	struct binder_buffer *buffer;
+	struct binder_buffer *kern_ptr;
+
+	kern_ptr = user_ptr - proc->user_buffer_offset
+		- offsetof(struct binder_buffer, data);
+
+	while (n) {
+		buffer = rb_entry(n, struct binder_buffer, rb_node);
+		BUG_ON(buffer->free);
+
+		if (kern_ptr < buffer)
+			n = n->rb_left;
+		else if (kern_ptr > buffer)
+			n = n->rb_right;
+		else
+			return buffer;
+	}
+	return NULL;
+}
+
+static int binder_update_page_range(struct binder_proc *proc, int allocate,
+				    void *start, void *end,
+				    struct vm_area_struct *vma)
+{
+	void *page_addr;
+	unsigned long user_page_addr;
+	struct vm_struct tmp_area;
+	struct page **page;
+	struct mm_struct *mm;
+
+	binder_debug(BINDER_DEBUG_BUFFER_ALLOC,
+		     "binder: %d: %s pages %p-%p\n", proc->pid,
+		     allocate ? "allocate" : "free", start, end);
+
+	if (end <= start)
+		return 0;
+
+	if (vma)
+		mm = NULL;
+	else
+		mm = get_task_mm(proc->tsk);
+
+	if (mm) {
+		down_write(&mm->mmap_sem);
+		vma = proc->vma;
+	}
+
+	if (allocate == 0)
+		goto free_range;
+
+	if (vma == NULL) {
+		printk(KERN_ERR "binder: %d: binder_alloc_buf failed to "
+		       "map pages in userspace, no vma\n", proc->pid);
+		goto err_no_vma;
+	}
+
+	for (page_addr = start; page_addr < end; page_addr += PAGE_SIZE) {
+		int ret;
+		struct page **page_array_ptr;
+		page = &proc->pages[(page_addr - proc->buffer) / PAGE_SIZE];
+
+		BUG_ON(*page);
+		*page = alloc_page(GFP_KERNEL | __GFP_ZERO);
+		if (*page == NULL) {
+			printk(KERN_ERR "binder: %d: binder_alloc_buf failed "
+			       "for page at %p\n", proc->pid, page_addr);
+			goto err_alloc_page_failed;
+		}
+		tmp_area.addr = page_addr;
+		tmp_area.size = PAGE_SIZE + PAGE_SIZE /* guard page? */;
+		page_array_ptr = page;
+		ret = map_vm_area(&tmp_area, PAGE_KERNEL, &page_array_ptr);
+		if (ret) {
+			printk(KERN_ERR "binder: %d: binder_alloc_buf failed "
+			       "to map page at %p in kernel\n",
+			       proc->pid, page_addr);
+			goto err_map_kernel_failed;
+		}
+		user_page_addr =
+			(uintptr_t)page_addr + proc->user_buffer_offset;
+		ret = vm_insert_page(vma, user_page_addr, page[0]);
+		if (ret) {
+			printk(KERN_ERR "binder: %d: binder_alloc_buf failed "
+			       "to map page at %lx in userspace\n",
+			       proc->pid, user_page_addr);
+			goto err_vm_insert_page_failed;
+		}
+		/* vm_insert_page does not seem to increment the refcount */
+	}
+	if (mm) {
+		up_write(&mm->mmap_sem);
+		mmput(mm);
+	}
+	return 0;
+
+free_range:
+	for (page_addr = end - PAGE_SIZE; page_addr >= start;
+	     page_addr -= PAGE_SIZE) {
+		page = &proc->pages[(page_addr - proc->buffer) / PAGE_SIZE];
+		if (vma)
+			zap_page_range(vma, (uintptr_t)page_addr +
+				proc->user_buffer_offset, PAGE_SIZE, NULL);
+err_vm_insert_page_failed:
+		unmap_kernel_range((unsigned long)page_addr, PAGE_SIZE);
+err_map_kernel_failed:
+		__free_page(*page);
+		*page = NULL;
+err_alloc_page_failed:
+		;
+	}
+err_no_vma:
+	if (mm) {
+		up_write(&mm->mmap_sem);
+		mmput(mm);
+	}
+	return -ENOMEM;
+}
+
+static struct binder_buffer *binder_alloc_buf(struct binder_proc *proc,
+					      size_t data_size,
+					      size_t offsets_size, int is_async)
+{
+	struct rb_node *n = proc->free_buffers.rb_node;
+	struct binder_buffer *buffer;
+	size_t buffer_size;
+	struct rb_node *best_fit = NULL;
+	void *has_page_addr;
+	void *end_page_addr;
+	size_t size;
+
+	if (proc->vma == NULL) {
+		printk(KERN_ERR "binder: %d: binder_alloc_buf, no vma\n",
+		       proc->pid);
+		return NULL;
+	}
+
+	size = ALIGN(data_size, sizeof(void *)) +
+		ALIGN(offsets_size, sizeof(void *));
+
+	if (size < data_size || size < offsets_size) {
+		binder_user_error("binder: %d: got transaction with invalid "
+			"size %zd-%zd\n", proc->pid, data_size, offsets_size);
+		return NULL;
+	}
+
+	if (is_async &&
+	    proc->free_async_space < size + sizeof(struct binder_buffer)) {
+		binder_debug(BINDER_DEBUG_BUFFER_ALLOC,
+			     "binder: %d: binder_alloc_buf size %zd"
+			     "failed, no async space left\n", proc->pid, size);
+		return NULL;
+	}
+
+	while (n) {
+		buffer = rb_entry(n, struct binder_buffer, rb_node);
+		BUG_ON(!buffer->free);
+		buffer_size = binder_buffer_size(proc, buffer);
+
+		if (size < buffer_size) {
+			best_fit = n;
+			n = n->rb_left;
+		} else if (size > buffer_size)
+			n = n->rb_right;
+		else {
+			best_fit = n;
+			break;
+		}
+	}
+	if (best_fit == NULL) {
+		printk(KERN_ERR "binder: %d: binder_alloc_buf size %zd failed, "
+		       "no address space\n", proc->pid, size);
+		return NULL;
+	}
+	if (n == NULL) {
+		buffer = rb_entry(best_fit, struct binder_buffer, rb_node);
+		buffer_size = binder_buffer_size(proc, buffer);
+	}
+
+	binder_debug(BINDER_DEBUG_BUFFER_ALLOC,
+		     "binder: %d: binder_alloc_buf size %zd got buff"
+		     "er %p size %zd\n", proc->pid, size, buffer, buffer_size);
+
+	has_page_addr =
+		(void *)(((uintptr_t)buffer->data + buffer_size) & PAGE_MASK);
+	if (n == NULL) {
+		if (size + sizeof(struct binder_buffer) + 4 >= buffer_size)
+			buffer_size = size; /* no room for other buffers */
+		else
+			buffer_size = size + sizeof(struct binder_buffer);
+	}
+	end_page_addr =
+		(void *)PAGE_ALIGN((uintptr_t)buffer->data + buffer_size);
+	if (end_page_addr > has_page_addr)
+		end_page_addr = has_page_addr;
+	if (binder_update_page_range(proc, 1,
+	    (void *)PAGE_ALIGN((uintptr_t)buffer->data), end_page_addr, NULL))
+		return NULL;
+
+	rb_erase(best_fit, &proc->free_buffers);
+	buffer->free = 0;
+	binder_insert_allocated_buffer(proc, buffer);
+	if (buffer_size != size) {
+		struct binder_buffer *new_buffer = (void *)buffer->data + size;
+		list_add(&new_buffer->entry, &buffer->entry);
+		new_buffer->free = 1;
+		binder_insert_free_buffer(proc, new_buffer);
+	}
+	binder_debug(BINDER_DEBUG_BUFFER_ALLOC,
+		     "binder: %d: binder_alloc_buf size %zd got "
+		     "%p\n", proc->pid, size, buffer);
+	buffer->data_size = data_size;
+	buffer->offsets_size = offsets_size;
+	buffer->async_transaction = is_async;
+	if (is_async) {
+		proc->free_async_space -= size + sizeof(struct binder_buffer);
+		binder_debug(BINDER_DEBUG_BUFFER_ALLOC_ASYNC,
+			     "binder: %d: binder_alloc_buf size %zd "
+			     "async free %zd\n", proc->pid, size,
+			     proc->free_async_space);
+	}
+
+	return buffer;
+}
+
+static void *buffer_start_page(struct binder_buffer *buffer)
+{
+	return (void *)((uintptr_t)buffer & PAGE_MASK);
+}
+
+static void *buffer_end_page(struct binder_buffer *buffer)
+{
+	return (void *)(((uintptr_t)(buffer + 1) - 1) & PAGE_MASK);
+}
+
+static void binder_delete_free_buffer(struct binder_proc *proc,
+				      struct binder_buffer *buffer)
+{
+	struct binder_buffer *prev, *next = NULL;
+	int free_page_end = 1;
+	int free_page_start = 1;
+
+	BUG_ON(proc->buffers.next == &buffer->entry);
+	prev = list_entry(buffer->entry.prev, struct binder_buffer, entry);
+	BUG_ON(!prev->free);
+	if (buffer_end_page(prev) == buffer_start_page(buffer)) {
+		free_page_start = 0;
+		if (buffer_end_page(prev) == buffer_end_page(buffer))
+			free_page_end = 0;
+		binder_debug(BINDER_DEBUG_BUFFER_ALLOC,
+			     "binder: %d: merge free, buffer %p "
+			     "share page with %p\n", proc->pid, buffer, prev);
+	}
+
+	if (!list_is_last(&buffer->entry, &proc->buffers)) {
+		next = list_entry(buffer->entry.next,
+				  struct binder_buffer, entry);
+		if (buffer_start_page(next) == buffer_end_page(buffer)) {
+			free_page_end = 0;
+			if (buffer_start_page(next) ==
+			    buffer_start_page(buffer))
+				free_page_start = 0;
+			binder_debug(BINDER_DEBUG_BUFFER_ALLOC,
+				     "binder: %d: merge free, buffer"
+				     " %p share page with %p\n", proc->pid,
+				     buffer, prev);
+		}
+	}
+	list_del(&buffer->entry);
+	if (free_page_start || free_page_end) {
+		binder_debug(BINDER_DEBUG_BUFFER_ALLOC,
+			     "binder: %d: merge free, buffer %p do "
+			     "not share page%s%s with with %p or %p\n",
+			     proc->pid, buffer, free_page_start ? "" : " end",
+			     free_page_end ? "" : " start", prev, next);
+		binder_update_page_range(proc, 0, free_page_start ?
+			buffer_start_page(buffer) : buffer_end_page(buffer),
+			(free_page_end ? buffer_end_page(buffer) :
+			buffer_start_page(buffer)) + PAGE_SIZE, NULL);
+	}
+}
+
+static void binder_free_buf(struct binder_proc *proc,
+			    struct binder_buffer *buffer)
+{
+	size_t size, buffer_size;
+
+	buffer_size = binder_buffer_size(proc, buffer);
+
+	size = ALIGN(buffer->data_size, sizeof(void *)) +
+		ALIGN(buffer->offsets_size, sizeof(void *));
+
+	binder_debug(BINDER_DEBUG_BUFFER_ALLOC,
+		     "binder: %d: binder_free_buf %p size %zd buffer"
+		     "_size %zd\n", proc->pid, buffer, size, buffer_size);
+
+	BUG_ON(buffer->free);
+	BUG_ON(size > buffer_size);
+	BUG_ON(buffer->transaction != NULL);
+	BUG_ON((void *)buffer < proc->buffer);
+	BUG_ON((void *)buffer > proc->buffer + proc->buffer_size);
+
+	if (buffer->async_transaction) {
+		proc->free_async_space += size + sizeof(struct binder_buffer);
+
+		binder_debug(BINDER_DEBUG_BUFFER_ALLOC_ASYNC,
+			     "binder: %d: binder_free_buf size %zd "
+			     "async free %zd\n", proc->pid, size,
+			     proc->free_async_space);
+	}
+
+	binder_update_page_range(proc, 0,
+		(void *)PAGE_ALIGN((uintptr_t)buffer->data),
+		(void *)(((uintptr_t)buffer->data + buffer_size) & PAGE_MASK),
+		NULL);
+	rb_erase(&buffer->rb_node, &proc->allocated_buffers);
+	buffer->free = 1;
+	if (!list_is_last(&buffer->entry, &proc->buffers)) {
+		struct binder_buffer *next = list_entry(buffer->entry.next,
+						struct binder_buffer, entry);
+		if (next->free) {
+			rb_erase(&next->rb_node, &proc->free_buffers);
+			binder_delete_free_buffer(proc, next);
+		}
+	}
+	if (proc->buffers.next != &buffer->entry) {
+		struct binder_buffer *prev = list_entry(buffer->entry.prev,
+						struct binder_buffer, entry);
+		if (prev->free) {
+			binder_delete_free_buffer(proc, buffer);
+			rb_erase(&prev->rb_node, &proc->free_buffers);
+			buffer = prev;
+		}
+	}
+	binder_insert_free_buffer(proc, buffer);
+}
+
+static struct binder_node *binder_get_node(struct binder_proc *proc,
+					   void __user *ptr)
+{
+	struct rb_node *n = proc->nodes.rb_node;
+	struct binder_node *node;
+
+	while (n) {
+		node = rb_entry(n, struct binder_node, rb_node);
+
+		if (ptr < node->ptr)
+			n = n->rb_left;
+		else if (ptr > node->ptr)
+			n = n->rb_right;
+		else
+			return node;
+	}
+	return NULL;
+}
+
+static struct binder_node *binder_new_node(struct binder_proc *proc,
+					   void __user *ptr,
+					   void __user *cookie)
+{
+	struct rb_node **p = &proc->nodes.rb_node;
+	struct rb_node *parent = NULL;
+	struct binder_node *node;
+
+	while (*p) {
+		parent = *p;
+		node = rb_entry(parent, struct binder_node, rb_node);
+
+		if (ptr < node->ptr)
+			p = &(*p)->rb_left;
+		else if (ptr > node->ptr)
+			p = &(*p)->rb_right;
+		else
+			return NULL;
+	}
+
+	node = kzalloc(sizeof(*node), GFP_KERNEL);
+	if (node == NULL)
+		return NULL;
+	binder_stats_created(BINDER_STAT_NODE);
+	rb_link_node(&node->rb_node, parent, p);
+	rb_insert_color(&node->rb_node, &proc->nodes);
+	node->debug_id = ++binder_last_id;
+	node->proc = proc;
+	node->ptr = ptr;
+	node->cookie = cookie;
+	node->work.type = BINDER_WORK_NODE;
+	INIT_LIST_HEAD(&node->work.entry);
+	INIT_LIST_HEAD(&node->async_todo);
+	binder_debug(BINDER_DEBUG_INTERNAL_REFS,
+		     "binder: %d:%d node %d u%p c%p created\n",
+		     proc->pid, current->pid, node->debug_id,
+		     node->ptr, node->cookie);
+	return node;
+}
+
+static int binder_inc_node(struct binder_node *node, int strong, int internal,
+			   struct list_head *target_list)
+{
+	if (strong) {
+		if (internal) {
+			if (target_list == NULL &&
+			    node->internal_strong_refs == 0 &&
+			    !(node == binder_context_mgr_node &&
+			    node->has_strong_ref)) {
+				printk(KERN_ERR "binder: invalid inc strong "
+					"node for %d\n", node->debug_id);
+				return -EINVAL;
+			}
+			node->internal_strong_refs++;
+		} else
+			node->local_strong_refs++;
+		if (!node->has_strong_ref && target_list) {
+			list_del_init(&node->work.entry);
+			list_add_tail(&node->work.entry, target_list);
+		}
+	} else {
+		if (!internal)
+			node->local_weak_refs++;
+		if (!node->has_weak_ref && list_empty(&node->work.entry)) {
+			if (target_list == NULL) {
+				printk(KERN_ERR "binder: invalid inc weak node "
+					"for %d\n", node->debug_id);
+				return -EINVAL;
+			}
+			list_add_tail(&node->work.entry, target_list);
+		}
+	}
+	return 0;
+}
+
+static int binder_dec_node(struct binder_node *node, int strong, int internal)
+{
+	if (strong) {
+		if (internal)
+			node->internal_strong_refs--;
+		else
+			node->local_strong_refs--;
+		if (node->local_strong_refs || node->internal_strong_refs)
+			return 0;
+	} else {
+		if (!internal)
+			node->local_weak_refs--;
+		if (node->local_weak_refs || !hlist_empty(&node->refs))
+			return 0;
+	}
+	if (node->proc && (node->has_strong_ref || node->has_weak_ref)) {
+		if (list_empty(&node->work.entry)) {
+			list_add_tail(&node->work.entry, &node->proc->todo);
+			wake_up_interruptible(&node->proc->wait);
+		}
+	} else {
+		if (hlist_empty(&node->refs) && !node->local_strong_refs &&
+		    !node->local_weak_refs) {
+			list_del_init(&node->work.entry);
+			if (node->proc) {
+				rb_erase(&node->rb_node, &node->proc->nodes);
+				binder_debug(BINDER_DEBUG_INTERNAL_REFS,
+					     "binder: refless node %d deleted\n",
+					     node->debug_id);
+			} else {
+				hlist_del(&node->dead_node);
+				binder_debug(BINDER_DEBUG_INTERNAL_REFS,
+					     "binder: dead node %d deleted\n",
+					     node->debug_id);
+			}
+			kfree(node);
+			binder_stats_deleted(BINDER_STAT_NODE);
+		}
+	}
+
+	return 0;
+}
+
+
+static struct binder_ref *binder_get_ref(struct binder_proc *proc,
+					 uint32_t desc)
+{
+	struct rb_node *n = proc->refs_by_desc.rb_node;
+	struct binder_ref *ref;
+
+	while (n) {
+		ref = rb_entry(n, struct binder_ref, rb_node_desc);
+
+		if (desc < ref->desc)
+			n = n->rb_left;
+		else if (desc > ref->desc)
+			n = n->rb_right;
+		else
+			return ref;
+	}
+	return NULL;
+}
+
+static struct binder_ref *binder_get_ref_for_node(struct binder_proc *proc,
+						  struct binder_node *node)
+{
+	struct rb_node *n;
+	struct rb_node **p = &proc->refs_by_node.rb_node;
+	struct rb_node *parent = NULL;
+	struct binder_ref *ref, *new_ref;
+
+	while (*p) {
+		parent = *p;
+		ref = rb_entry(parent, struct binder_ref, rb_node_node);
+
+		if (node < ref->node)
+			p = &(*p)->rb_left;
+		else if (node > ref->node)
+			p = &(*p)->rb_right;
+		else
+			return ref;
+	}
+	new_ref = kzalloc(sizeof(*ref), GFP_KERNEL);
+	if (new_ref == NULL)
+		return NULL;
+	binder_stats_created(BINDER_STAT_REF);
+	new_ref->debug_id = ++binder_last_id;
+	new_ref->proc = proc;
+	new_ref->node = node;
+	rb_link_node(&new_ref->rb_node_node, parent, p);
+	rb_insert_color(&new_ref->rb_node_node, &proc->refs_by_node);
+
+	new_ref->desc = (node == binder_context_mgr_node) ? 0 : 1;
+	for (n = rb_first(&proc->refs_by_desc); n != NULL; n = rb_next(n)) {
+		ref = rb_entry(n, struct binder_ref, rb_node_desc);
+		if (ref->desc > new_ref->desc)
+			break;
+		new_ref->desc = ref->desc + 1;
+	}
+
+	p = &proc->refs_by_desc.rb_node;
+	while (*p) {
+		parent = *p;
+		ref = rb_entry(parent, struct binder_ref, rb_node_desc);
+
+		if (new_ref->desc < ref->desc)
+			p = &(*p)->rb_left;
+		else if (new_ref->desc > ref->desc)
+			p = &(*p)->rb_right;
+		else
+			BUG();
+	}
+	rb_link_node(&new_ref->rb_node_desc, parent, p);
+	rb_insert_color(&new_ref->rb_node_desc, &proc->refs_by_desc);
+	if (node) {
+		hlist_add_head(&new_ref->node_entry, &node->refs);
+
+		binder_debug(BINDER_DEBUG_INTERNAL_REFS,
+			     "binder: %d new ref %d desc %d for "
+			     "node %d\n", proc->pid, new_ref->debug_id,
+			     new_ref->desc, node->debug_id);
+	} else {
+		binder_debug(BINDER_DEBUG_INTERNAL_REFS,
+			     "binder: %d new ref %d desc %d for "
+			     "dead node\n", proc->pid, new_ref->debug_id,
+			      new_ref->desc);
+	}
+	return new_ref;
+}
+
+static void binder_delete_ref(struct binder_ref *ref)
+{
+	binder_debug(BINDER_DEBUG_INTERNAL_REFS,
+		     "binder: %d delete ref %d desc %d for "
+		     "node %d\n", ref->proc->pid, ref->debug_id,
+		     ref->desc, ref->node->debug_id);
+
+	rb_erase(&ref->rb_node_desc, &ref->proc->refs_by_desc);
+	rb_erase(&ref->rb_node_node, &ref->proc->refs_by_node);
+	if (ref->strong)
+		binder_dec_node(ref->node, 1, 1);
+	hlist_del(&ref->node_entry);
+	binder_dec_node(ref->node, 0, 1);
+	if (ref->death) {
+		binder_debug(BINDER_DEBUG_DEAD_BINDER,
+			     "binder: %d delete ref %d desc %d "
+			     "has death notification\n", ref->proc->pid,
+			     ref->debug_id, ref->desc);
+		list_del(&ref->death->work.entry);
+		kfree(ref->death);
+		binder_stats_deleted(BINDER_STAT_DEATH);
+	}
+	kfree(ref);
+	binder_stats_deleted(BINDER_STAT_REF);
+}
+
+static int binder_inc_ref(struct binder_ref *ref, int strong,
+			  struct list_head *target_list)
+{
+	int ret;
+	if (strong) {
+		if (ref->strong == 0) {
+			ret = binder_inc_node(ref->node, 1, 1, target_list);
+			if (ret)
+				return ret;
+		}
+		ref->strong++;
+	} else {
+		if (ref->weak == 0) {
+			ret = binder_inc_node(ref->node, 0, 1, target_list);
+			if (ret)
+				return ret;
+		}
+		ref->weak++;
+	}
+	return 0;
+}
+
+
+static int binder_dec_ref(struct binder_ref *ref, int strong)
+{
+	if (strong) {
+		if (ref->strong == 0) {
+			binder_user_error("binder: %d invalid dec strong, "
+					  "ref %d desc %d s %d w %d\n",
+					  ref->proc->pid, ref->debug_id,
+					  ref->desc, ref->strong, ref->weak);
+			return -EINVAL;
+		}
+		ref->strong--;
+		if (ref->strong == 0) {
+			int ret;
+			ret = binder_dec_node(ref->node, strong, 1);
+			if (ret)
+				return ret;
+		}
+	} else {
+		if (ref->weak == 0) {
+			binder_user_error("binder: %d invalid dec weak, "
+					  "ref %d desc %d s %d w %d\n",
+					  ref->proc->pid, ref->debug_id,
+					  ref->desc, ref->strong, ref->weak);
+			return -EINVAL;
+		}
+		ref->weak--;
+	}
+	if (ref->strong == 0 && ref->weak == 0)
+		binder_delete_ref(ref);
+	return 0;
+}
+
+static void binder_pop_transaction(struct binder_thread *target_thread,
+				   struct binder_transaction *t)
+{
+	if (target_thread) {
+		BUG_ON(target_thread->transaction_stack != t);
+		BUG_ON(target_thread->transaction_stack->from != target_thread);
+		target_thread->transaction_stack =
+			target_thread->transaction_stack->from_parent;
+		t->from = NULL;
+	}
+	t->need_reply = 0;
+	if (t->buffer)
+		t->buffer->transaction = NULL;
+	kfree(t);
+	binder_stats_deleted(BINDER_STAT_TRANSACTION);
+}
+
+static void binder_send_failed_reply(struct binder_transaction *t,
+				     uint32_t error_code)
+{
+	struct binder_thread *target_thread;
+	BUG_ON(t->flags & TF_ONE_WAY);
+	while (1) {
+		target_thread = t->from;
+		if (target_thread) {
+			if (target_thread->return_error != BR_OK &&
+			   target_thread->return_error2 == BR_OK) {
+				target_thread->return_error2 =
+					target_thread->return_error;
+				target_thread->return_error = BR_OK;
+			}
+			if (target_thread->return_error == BR_OK) {
+				binder_debug(BINDER_DEBUG_FAILED_TRANSACTION,
+					     "binder: send failed reply for "
+					     "transaction %d to %d:%d\n",
+					      t->debug_id, target_thread->proc->pid,
+					      target_thread->pid);
+
+				binder_pop_transaction(target_thread, t);
+				target_thread->return_error = error_code;
+				wake_up_interruptible(&target_thread->wait);
+			} else {
+				printk(KERN_ERR "binder: reply failed, target "
+					"thread, %d:%d, has error code %d "
+					"already\n", target_thread->proc->pid,
+					target_thread->pid,
+					target_thread->return_error);
+			}
+			return;
+		} else {
+			struct binder_transaction *next = t->from_parent;
+
+			binder_debug(BINDER_DEBUG_FAILED_TRANSACTION,
+				     "binder: send failed reply "
+				     "for transaction %d, target dead\n",
+				     t->debug_id);
+
+			binder_pop_transaction(target_thread, t);
+			if (next == NULL) {
+				binder_debug(BINDER_DEBUG_DEAD_BINDER,
+					     "binder: reply failed,"
+					     " no target thread at root\n");
+				return;
+			}
+			t = next;
+			binder_debug(BINDER_DEBUG_DEAD_BINDER,
+				     "binder: reply failed, no target "
+				     "thread -- retry %d\n", t->debug_id);
+		}
+	}
+}
+
+static void binder_transaction_buffer_release(struct binder_proc *proc,
+					      struct binder_buffer *buffer,
+					      size_t *failed_at)
+{
+	size_t *offp, *off_end;
+	int debug_id = buffer->debug_id;
+
+	binder_debug(BINDER_DEBUG_TRANSACTION,
+		     "binder: %d buffer release %d, size %zd-%zd, failed at %p\n",
+		     proc->pid, buffer->debug_id,
+		     buffer->data_size, buffer->offsets_size, failed_at);
+
+	if (buffer->target_node)
+		binder_dec_node(buffer->target_node, 1, 0);
+
+	offp = (size_t *)(buffer->data + ALIGN(buffer->data_size, sizeof(void *)));
+	if (failed_at)
+		off_end = failed_at;
+	else
+		off_end = (void *)offp + buffer->offsets_size;
+	for (; offp < off_end; offp++) {
+		struct flat_binder_object *fp;
+		if (*offp > buffer->data_size - sizeof(*fp) ||
+		    buffer->data_size < sizeof(*fp) ||
+		    !IS_ALIGNED(*offp, sizeof(void *))) {
+			printk(KERN_ERR "binder: transaction release %d bad"
+					"offset %zd, size %zd\n", debug_id,
+					*offp, buffer->data_size);
+			continue;
+		}
+		fp = (struct flat_binder_object *)(buffer->data + *offp);
+		switch (fp->type) {
+		case BINDER_TYPE_BINDER:
+		case BINDER_TYPE_WEAK_BINDER: {
+			struct binder_node *node = binder_get_node(proc, fp->binder);
+			if (node == NULL) {
+				printk(KERN_ERR "binder: transaction release %d"
+				       " bad node %p\n", debug_id, fp->binder);
+				break;
+			}
+			binder_debug(BINDER_DEBUG_TRANSACTION,
+				     "        node %d u%p\n",
+				     node->debug_id, node->ptr);
+			binder_dec_node(node, fp->type == BINDER_TYPE_BINDER, 0);
+		} break;
+		case BINDER_TYPE_HANDLE:
+		case BINDER_TYPE_WEAK_HANDLE: {
+			struct binder_ref *ref = binder_get_ref(proc, fp->handle);
+			if (ref == NULL) {
+				printk(KERN_ERR "binder: transaction release %d"
+				       " bad handle %ld\n", debug_id,
+				       fp->handle);
+				break;
+			}
+			binder_debug(BINDER_DEBUG_TRANSACTION,
+				     "        ref %d desc %d (node %d)\n",
+				     ref->debug_id, ref->desc, ref->node->debug_id);
+			binder_dec_ref(ref, fp->type == BINDER_TYPE_HANDLE);
+		} break;
+
+		case BINDER_TYPE_FD:
+			binder_debug(BINDER_DEBUG_TRANSACTION,
+				     "        fd %ld\n", fp->handle);
+			if (failed_at)
+				task_close_fd(proc, fp->handle);
+			break;
+
+		default:
+			printk(KERN_ERR "binder: transaction release %d bad "
+			       "object type %lx\n", debug_id, fp->type);
+			break;
+		}
+	}
+}
+
+static void binder_transaction(struct binder_proc *proc,
+			       struct binder_thread *thread,
+			       struct binder_transaction_data *tr, int reply)
+{
+	struct binder_transaction *t;
+	struct binder_work *tcomplete;
+	size_t *offp, *off_end;
+	struct binder_proc *target_proc;
+	struct binder_thread *target_thread = NULL;
+	struct binder_node *target_node = NULL;
+	struct list_head *target_list;
+	wait_queue_head_t *target_wait;
+	struct binder_transaction *in_reply_to = NULL;
+	struct binder_transaction_log_entry *e;
+	uint32_t return_error;
+
+	e = binder_transaction_log_add(&binder_transaction_log);
+	e->call_type = reply ? 2 : !!(tr->flags & TF_ONE_WAY);
+	e->from_proc = proc->pid;
+	e->from_thread = thread->pid;
+	e->target_handle = tr->target.handle;
+	e->data_size = tr->data_size;
+	e->offsets_size = tr->offsets_size;
+
+	if (reply) {
+		in_reply_to = thread->transaction_stack;
+		if (in_reply_to == NULL) {
+			binder_user_error("binder: %d:%d got reply transaction "
+					  "with no transaction stack\n",
+					  proc->pid, thread->pid);
+			return_error = BR_FAILED_REPLY;
+			goto err_empty_call_stack;
+		}
+		binder_set_nice(in_reply_to->saved_priority);
+		if (in_reply_to->to_thread != thread) {
+			binder_user_error("binder: %d:%d got reply transaction "
+				"with bad transaction stack,"
+				" transaction %d has target %d:%d\n",
+				proc->pid, thread->pid, in_reply_to->debug_id,
+				in_reply_to->to_proc ?
+				in_reply_to->to_proc->pid : 0,
+				in_reply_to->to_thread ?
+				in_reply_to->to_thread->pid : 0);
+			return_error = BR_FAILED_REPLY;
+			in_reply_to = NULL;
+			goto err_bad_call_stack;
+		}
+		thread->transaction_stack = in_reply_to->to_parent;
+		target_thread = in_reply_to->from;
+		if (target_thread == NULL) {
+			return_error = BR_DEAD_REPLY;
+			goto err_dead_binder;
+		}
+		if (target_thread->transaction_stack != in_reply_to) {
+			binder_user_error("binder: %d:%d got reply transaction "
+				"with bad target transaction stack %d, "
+				"expected %d\n",
+				proc->pid, thread->pid,
+				target_thread->transaction_stack ?
+				target_thread->transaction_stack->debug_id : 0,
+				in_reply_to->debug_id);
+			return_error = BR_FAILED_REPLY;
+			in_reply_to = NULL;
+			target_thread = NULL;
+			goto err_dead_binder;
+		}
+		target_proc = target_thread->proc;
+	} else {
+		if (tr->target.handle) {
+			struct binder_ref *ref;
+			ref = binder_get_ref(proc, tr->target.handle);
+			if (ref == NULL) {
+				binder_user_error("binder: %d:%d got "
+					"transaction to invalid handle\n",
+					proc->pid, thread->pid);
+				return_error = BR_FAILED_REPLY;
+				goto err_invalid_target_handle;
+			}
+			target_node = ref->node;
+		} else {
+			target_node = binder_context_mgr_node;
+			if (target_node == NULL) {
+				return_error = BR_DEAD_REPLY;
+				goto err_no_context_mgr_node;
+			}
+		}
+		e->to_node = target_node->debug_id;
+		target_proc = target_node->proc;
+		if (target_proc == NULL) {
+			return_error = BR_DEAD_REPLY;
+			goto err_dead_binder;
+		}
+		if (!(tr->flags & TF_ONE_WAY) && thread->transaction_stack) {
+			struct binder_transaction *tmp;
+			tmp = thread->transaction_stack;
+			if (tmp->to_thread != thread) {
+				binder_user_error("binder: %d:%d got new "
+					"transaction with bad transaction stack"
+					", transaction %d has target %d:%d\n",
+					proc->pid, thread->pid, tmp->debug_id,
+					tmp->to_proc ? tmp->to_proc->pid : 0,
+					tmp->to_thread ?
+					tmp->to_thread->pid : 0);
+				return_error = BR_FAILED_REPLY;
+				goto err_bad_call_stack;
+			}
+			while (tmp) {
+				if (tmp->from && tmp->from->proc == target_proc)
+					target_thread = tmp->from;
+				tmp = tmp->from_parent;
+			}
+		}
+	}
+	if (target_thread) {
+		e->to_thread = target_thread->pid;
+		target_list = &target_thread->todo;
+		target_wait = &target_thread->wait;
+	} else {
+		target_list = &target_proc->todo;
+		target_wait = &target_proc->wait;
+	}
+	e->to_proc = target_proc->pid;
+
+	/* TODO: reuse incoming transaction for reply */
+	t = kzalloc(sizeof(*t), GFP_KERNEL);
+	if (t == NULL) {
+		return_error = BR_FAILED_REPLY;
+		goto err_alloc_t_failed;
+	}
+	binder_stats_created(BINDER_STAT_TRANSACTION);
+
+	tcomplete = kzalloc(sizeof(*tcomplete), GFP_KERNEL);
+	if (tcomplete == NULL) {
+		return_error = BR_FAILED_REPLY;
+		goto err_alloc_tcomplete_failed;
+	}
+	binder_stats_created(BINDER_STAT_TRANSACTION_COMPLETE);
+
+	t->debug_id = ++binder_last_id;
+	e->debug_id = t->debug_id;
+
+	if (reply)
+		binder_debug(BINDER_DEBUG_TRANSACTION,
+			     "binder: %d:%d BC_REPLY %d -> %d:%d, "
+			     "data %p-%p size %zd-%zd\n",
+			     proc->pid, thread->pid, t->debug_id,
+			     target_proc->pid, target_thread->pid,
+			     tr->data.ptr.buffer, tr->data.ptr.offsets,
+			     tr->data_size, tr->offsets_size);
+	else
+		binder_debug(BINDER_DEBUG_TRANSACTION,
+			     "binder: %d:%d BC_TRANSACTION %d -> "
+			     "%d - node %d, data %p-%p size %zd-%zd\n",
+			     proc->pid, thread->pid, t->debug_id,
+			     target_proc->pid, target_node->debug_id,
+			     tr->data.ptr.buffer, tr->data.ptr.offsets,
+			     tr->data_size, tr->offsets_size);
+
+	if (!reply && !(tr->flags & TF_ONE_WAY))
+		t->from = thread;
+	else
+		t->from = NULL;
+	t->sender_euid = proc->tsk->cred->euid;
+	t->to_proc = target_proc;
+	t->to_thread = target_thread;
+	t->code = tr->code;
+	t->flags = tr->flags;
+	t->priority = task_nice(current);
+	t->buffer = binder_alloc_buf(target_proc, tr->data_size,
+		tr->offsets_size, !reply && (t->flags & TF_ONE_WAY));
+	if (t->buffer == NULL) {
+		return_error = BR_FAILED_REPLY;
+		goto err_binder_alloc_buf_failed;
+	}
+	t->buffer->allow_user_free = 0;
+	t->buffer->debug_id = t->debug_id;
+	t->buffer->transaction = t;
+	t->buffer->target_node = target_node;
+	if (target_node)
+		binder_inc_node(target_node, 1, 0, NULL);
+
+	offp = (size_t *)(t->buffer->data + ALIGN(tr->data_size, sizeof(void *)));
+
+	if (copy_from_user(t->buffer->data, tr->data.ptr.buffer, tr->data_size)) {
+		binder_user_error("binder: %d:%d got transaction with invalid "
+			"data ptr\n", proc->pid, thread->pid);
+		return_error = BR_FAILED_REPLY;
+		goto err_copy_data_failed;
+	}
+	if (copy_from_user(offp, tr->data.ptr.offsets, tr->offsets_size)) {
+		binder_user_error("binder: %d:%d got transaction with invalid "
+			"offsets ptr\n", proc->pid, thread->pid);
+		return_error = BR_FAILED_REPLY;
+		goto err_copy_data_failed;
+	}
+	if (!IS_ALIGNED(tr->offsets_size, sizeof(size_t))) {
+		binder_user_error("binder: %d:%d got transaction with "
+			"invalid offsets size, %zd\n",
+			proc->pid, thread->pid, tr->offsets_size);
+		return_error = BR_FAILED_REPLY;
+		goto err_bad_offset;
+	}
+	off_end = (void *)offp + tr->offsets_size;
+	for (; offp < off_end; offp++) {
+		struct flat_binder_object *fp;
+		if (*offp > t->buffer->data_size - sizeof(*fp) ||
+		    t->buffer->data_size < sizeof(*fp) ||
+		    !IS_ALIGNED(*offp, sizeof(void *))) {
+			binder_user_error("binder: %d:%d got transaction with "
+				"invalid offset, %zd\n",
+				proc->pid, thread->pid, *offp);
+			return_error = BR_FAILED_REPLY;
+			goto err_bad_offset;
+		}
+		fp = (struct flat_binder_object *)(t->buffer->data + *offp);
+		switch (fp->type) {
+		case BINDER_TYPE_BINDER:
+		case BINDER_TYPE_WEAK_BINDER: {
+			struct binder_ref *ref;
+			struct binder_node *node = binder_get_node(proc, fp->binder);
+			if (node == NULL) {
+				node = binder_new_node(proc, fp->binder, fp->cookie);
+				if (node == NULL) {
+					return_error = BR_FAILED_REPLY;
+					goto err_binder_new_node_failed;
+				}
+				node->min_priority = fp->flags & FLAT_BINDER_FLAG_PRIORITY_MASK;
+				node->accept_fds = !!(fp->flags & FLAT_BINDER_FLAG_ACCEPTS_FDS);
+			}
+			if (fp->cookie != node->cookie) {
+				binder_user_error("binder: %d:%d sending u%p "
+					"node %d, cookie mismatch %p != %p\n",
+					proc->pid, thread->pid,
+					fp->binder, node->debug_id,
+					fp->cookie, node->cookie);
+				goto err_binder_get_ref_for_node_failed;
+			}
+			ref = binder_get_ref_for_node(target_proc, node);
+			if (ref == NULL) {
+				return_error = BR_FAILED_REPLY;
+				goto err_binder_get_ref_for_node_failed;
+			}
+			if (fp->type == BINDER_TYPE_BINDER)
+				fp->type = BINDER_TYPE_HANDLE;
+			else
+				fp->type = BINDER_TYPE_WEAK_HANDLE;
+			fp->handle = ref->desc;
+			binder_inc_ref(ref, fp->type == BINDER_TYPE_HANDLE,
+				       &thread->todo);
+
+			binder_debug(BINDER_DEBUG_TRANSACTION,
+				     "        node %d u%p -> ref %d desc %d\n",
+				     node->debug_id, node->ptr, ref->debug_id,
+				     ref->desc);
+		} break;
+		case BINDER_TYPE_HANDLE:
+		case BINDER_TYPE_WEAK_HANDLE: {
+			struct binder_ref *ref = binder_get_ref(proc, fp->handle);
+			if (ref == NULL) {
+				binder_user_error("binder: %d:%d got "
+					"transaction with invalid "
+					"handle, %ld\n", proc->pid,
+					thread->pid, fp->handle);
+				return_error = BR_FAILED_REPLY;
+				goto err_binder_get_ref_failed;
+			}
+			if (ref->node->proc == target_proc) {
+				if (fp->type == BINDER_TYPE_HANDLE)
+					fp->type = BINDER_TYPE_BINDER;
+				else
+					fp->type = BINDER_TYPE_WEAK_BINDER;
+				fp->binder = ref->node->ptr;
+				fp->cookie = ref->node->cookie;
+				binder_inc_node(ref->node, fp->type == BINDER_TYPE_BINDER, 0, NULL);
+				binder_debug(BINDER_DEBUG_TRANSACTION,
+					     "        ref %d desc %d -> node %d u%p\n",
+					     ref->debug_id, ref->desc, ref->node->debug_id,
+					     ref->node->ptr);
+			} else {
+				struct binder_ref *new_ref;
+				new_ref = binder_get_ref_for_node(target_proc, ref->node);
+				if (new_ref == NULL) {
+					return_error = BR_FAILED_REPLY;
+					goto err_binder_get_ref_for_node_failed;
+				}
+				fp->handle = new_ref->desc;
+				binder_inc_ref(new_ref, fp->type == BINDER_TYPE_HANDLE, NULL);
+				binder_debug(BINDER_DEBUG_TRANSACTION,
+					     "        ref %d desc %d -> ref %d desc %d (node %d)\n",
+					     ref->debug_id, ref->desc, new_ref->debug_id,
+					     new_ref->desc, ref->node->debug_id);
+			}
+		} break;
+
+		case BINDER_TYPE_FD: {
+			int target_fd;
+			struct file *file;
+
+			if (reply) {
+				if (!(in_reply_to->flags & TF_ACCEPT_FDS)) {
+					binder_user_error("binder: %d:%d got reply with fd, %ld, but target does not allow fds\n",
+						proc->pid, thread->pid, fp->handle);
+					return_error = BR_FAILED_REPLY;
+					goto err_fd_not_allowed;
+				}
+			} else if (!target_node->accept_fds) {
+				binder_user_error("binder: %d:%d got transaction with fd, %ld, but target does not allow fds\n",
+					proc->pid, thread->pid, fp->handle);
+				return_error = BR_FAILED_REPLY;
+				goto err_fd_not_allowed;
+			}
+
+			file = fget(fp->handle);
+			if (file == NULL) {
+				binder_user_error("binder: %d:%d got transaction with invalid fd, %ld\n",
+					proc->pid, thread->pid, fp->handle);
+				return_error = BR_FAILED_REPLY;
+				goto err_fget_failed;
+			}
+			target_fd = task_get_unused_fd_flags(target_proc, O_CLOEXEC);
+			if (target_fd < 0) {
+				fput(file);
+				return_error = BR_FAILED_REPLY;
+				goto err_get_unused_fd_failed;
+			}
+			task_fd_install(target_proc, target_fd, file);
+			binder_debug(BINDER_DEBUG_TRANSACTION,
+				     "        fd %ld -> %d\n", fp->handle, target_fd);
+			/* TODO: fput? */
+			fp->handle = target_fd;
+		} break;
+
+		default:
+			binder_user_error("binder: %d:%d got transactio"
+				"n with invalid object type, %lx\n",
+				proc->pid, thread->pid, fp->type);
+			return_error = BR_FAILED_REPLY;
+			goto err_bad_object_type;
+		}
+	}
+	if (reply) {
+		BUG_ON(t->buffer->async_transaction != 0);
+		binder_pop_transaction(target_thread, in_reply_to);
+	} else if (!(t->flags & TF_ONE_WAY)) {
+		BUG_ON(t->buffer->async_transaction != 0);
+		t->need_reply = 1;
+		t->from_parent = thread->transaction_stack;
+		thread->transaction_stack = t;
+	} else {
+		BUG_ON(target_node == NULL);
+		BUG_ON(t->buffer->async_transaction != 1);
+		if (target_node->has_async_transaction) {
+			target_list = &target_node->async_todo;
+			target_wait = NULL;
+		} else
+			target_node->has_async_transaction = 1;
+	}
+	t->work.type = BINDER_WORK_TRANSACTION;
+	list_add_tail(&t->work.entry, target_list);
+	tcomplete->type = BINDER_WORK_TRANSACTION_COMPLETE;
+	list_add_tail(&tcomplete->entry, &thread->todo);
+	if (target_wait)
+		wake_up_interruptible(target_wait);
+	return;
+
+err_get_unused_fd_failed:
+err_fget_failed:
+err_fd_not_allowed:
+err_binder_get_ref_for_node_failed:
+err_binder_get_ref_failed:
+err_binder_new_node_failed:
+err_bad_object_type:
+err_bad_offset:
+err_copy_data_failed:
+	binder_transaction_buffer_release(target_proc, t->buffer, offp);
+	t->buffer->transaction = NULL;
+	binder_free_buf(target_proc, t->buffer);
+err_binder_alloc_buf_failed:
+	kfree(tcomplete);
+	binder_stats_deleted(BINDER_STAT_TRANSACTION_COMPLETE);
+err_alloc_tcomplete_failed:
+	kfree(t);
+	binder_stats_deleted(BINDER_STAT_TRANSACTION);
+err_alloc_t_failed:
+err_bad_call_stack:
+err_empty_call_stack:
+err_dead_binder:
+err_invalid_target_handle:
+err_no_context_mgr_node:
+	binder_debug(BINDER_DEBUG_FAILED_TRANSACTION,
+		     "binder: %d:%d transaction failed %d, size %zd-%zd\n",
+		     proc->pid, thread->pid, return_error,
+		     tr->data_size, tr->offsets_size);
+
+	{
+		struct binder_transaction_log_entry *fe;
+		fe = binder_transaction_log_add(&binder_transaction_log_failed);
+		*fe = *e;
+	}
+
+	BUG_ON(thread->return_error != BR_OK);
+	if (in_reply_to) {
+		thread->return_error = BR_TRANSACTION_COMPLETE;
+		binder_send_failed_reply(in_reply_to, return_error);
+	} else
+		thread->return_error = return_error;
+}
+
+int binder_thread_write(struct binder_proc *proc, struct binder_thread *thread,
+			void __user *buffer, int size, signed long *consumed)
+{
+	uint32_t cmd;
+	void __user *ptr = buffer + *consumed;
+	void __user *end = buffer + size;
+
+	while (ptr < end && thread->return_error == BR_OK) {
+		if (get_user(cmd, (uint32_t __user *)ptr))
+			return -EFAULT;
+		ptr += sizeof(uint32_t);
+		if (_IOC_NR(cmd) < ARRAY_SIZE(binder_stats.bc)) {
+			binder_stats.bc[_IOC_NR(cmd)]++;
+			proc->stats.bc[_IOC_NR(cmd)]++;
+			thread->stats.bc[_IOC_NR(cmd)]++;
+		}
+		switch (cmd) {
+		case BC_INCREFS:
+		case BC_ACQUIRE:
+		case BC_RELEASE:
+		case BC_DECREFS: {
+			uint32_t target;
+			struct binder_ref *ref;
+			const char *debug_string;
+
+			if (get_user(target, (uint32_t __user *)ptr))
+				return -EFAULT;
+			ptr += sizeof(uint32_t);
+			if (target == 0 && binder_context_mgr_node &&
+			    (cmd == BC_INCREFS || cmd == BC_ACQUIRE)) {
+				ref = binder_get_ref_for_node(proc,
+					       binder_context_mgr_node);
+				if (ref->desc != target) {
+					binder_user_error("binder: %d:"
+						"%d tried to acquire "
+						"reference to desc 0, "
+						"got %d instead\n",
+						proc->pid, thread->pid,
+						ref->desc);
+				}
+			} else
+				ref = binder_get_ref(proc, target);
+			if (ref == NULL) {
+				binder_user_error("binder: %d:%d refcou"
+					"nt change on invalid ref %d\n",
+					proc->pid, thread->pid, target);
+				break;
+			}
+			switch (cmd) {
+			case BC_INCREFS:
+				debug_string = "IncRefs";
+				binder_inc_ref(ref, 0, NULL);
+				break;
+			case BC_ACQUIRE:
+				debug_string = "Acquire";
+				binder_inc_ref(ref, 1, NULL);
+				break;
+			case BC_RELEASE:
+				debug_string = "Release";
+				binder_dec_ref(ref, 1);
+				break;
+			case BC_DECREFS:
+			default:
+				debug_string = "DecRefs";
+				binder_dec_ref(ref, 0);
+				break;
+			}
+			binder_debug(BINDER_DEBUG_USER_REFS,
+				     "binder: %d:%d %s ref %d desc %d s %d w %d for node %d\n",
+				     proc->pid, thread->pid, debug_string, ref->debug_id,
+				     ref->desc, ref->strong, ref->weak, ref->node->debug_id);
+			break;
+		}
+		case BC_INCREFS_DONE:
+		case BC_ACQUIRE_DONE: {
+			void __user *node_ptr;
+			void *cookie;
+			struct binder_node *node;
+
+			if (get_user(node_ptr, (void * __user *)ptr))
+				return -EFAULT;
+			ptr += sizeof(void *);
+			if (get_user(cookie, (void * __user *)ptr))
+				return -EFAULT;
+			ptr += sizeof(void *);
+			node = binder_get_node(proc, node_ptr);
+			if (node == NULL) {
+				binder_user_error("binder: %d:%d "
+					"%s u%p no match\n",
+					proc->pid, thread->pid,
+					cmd == BC_INCREFS_DONE ?
+					"BC_INCREFS_DONE" :
+					"BC_ACQUIRE_DONE",
+					node_ptr);
+				break;
+			}
+			if (cookie != node->cookie) {
+				binder_user_error("binder: %d:%d %s u%p node %d"
+					" cookie mismatch %p != %p\n",
+					proc->pid, thread->pid,
+					cmd == BC_INCREFS_DONE ?
+					"BC_INCREFS_DONE" : "BC_ACQUIRE_DONE",
+					node_ptr, node->debug_id,
+					cookie, node->cookie);
+				break;
+			}
+			if (cmd == BC_ACQUIRE_DONE) {
+				if (node->pending_strong_ref == 0) {
+					binder_user_error("binder: %d:%d "
+						"BC_ACQUIRE_DONE node %d has "
+						"no pending acquire request\n",
+						proc->pid, thread->pid,
+						node->debug_id);
+					break;
+				}
+				node->pending_strong_ref = 0;
+			} else {
+				if (node->pending_weak_ref == 0) {
+					binder_user_error("binder: %d:%d "
+						"BC_INCREFS_DONE node %d has "
+						"no pending increfs request\n",
+						proc->pid, thread->pid,
+						node->debug_id);
+					break;
+				}
+				node->pending_weak_ref = 0;
+			}
+			binder_dec_node(node, cmd == BC_ACQUIRE_DONE, 0);
+			binder_debug(BINDER_DEBUG_USER_REFS,
+				     "binder: %d:%d %s node %d ls %d lw %d\n",
+				     proc->pid, thread->pid,
+				     cmd == BC_INCREFS_DONE ? "BC_INCREFS_DONE" : "BC_ACQUIRE_DONE",
+				     node->debug_id, node->local_strong_refs, node->local_weak_refs);
+			break;
+		}
+		case BC_ATTEMPT_ACQUIRE:
+			printk(KERN_ERR "binder: BC_ATTEMPT_ACQUIRE not supported\n");
+			return -EINVAL;
+		case BC_ACQUIRE_RESULT:
+			printk(KERN_ERR "binder: BC_ACQUIRE_RESULT not supported\n");
+			return -EINVAL;
+
+		case BC_FREE_BUFFER: {
+			void __user *data_ptr;
+			struct binder_buffer *buffer;
+
+			if (get_user(data_ptr, (void * __user *)ptr))
+				return -EFAULT;
+			ptr += sizeof(void *);
+
+			buffer = binder_buffer_lookup(proc, data_ptr);
+			if (buffer == NULL) {
+				binder_user_error("binder: %d:%d "
+					"BC_FREE_BUFFER u%p no match\n",
+					proc->pid, thread->pid, data_ptr);
+				break;
+			}
+			if (!buffer->allow_user_free) {
+				binder_user_error("binder: %d:%d "
+					"BC_FREE_BUFFER u%p matched "
+					"unreturned buffer\n",
+					proc->pid, thread->pid, data_ptr);
+				break;
+			}
+			binder_debug(BINDER_DEBUG_FREE_BUFFER,
+				     "binder: %d:%d BC_FREE_BUFFER u%p found buffer %d for %s transaction\n",
+				     proc->pid, thread->pid, data_ptr, buffer->debug_id,
+				     buffer->transaction ? "active" : "finished");
+
+			if (buffer->transaction) {
+				buffer->transaction->buffer = NULL;
+				buffer->transaction = NULL;
+			}
+			if (buffer->async_transaction && buffer->target_node) {
+				BUG_ON(!buffer->target_node->has_async_transaction);
+				if (list_empty(&buffer->target_node->async_todo))
+					buffer->target_node->has_async_transaction = 0;
+				else
+					list_move_tail(buffer->target_node->async_todo.next, &thread->todo);
+			}
+			binder_transaction_buffer_release(proc, buffer, NULL);
+			binder_free_buf(proc, buffer);
+			break;
+		}
+
+		case BC_TRANSACTION:
+		case BC_REPLY: {
+			struct binder_transaction_data tr;
+
+			if (copy_from_user(&tr, ptr, sizeof(tr)))
+				return -EFAULT;
+			ptr += sizeof(tr);
+			binder_transaction(proc, thread, &tr, cmd == BC_REPLY);
+			break;
+		}
+
+		case BC_REGISTER_LOOPER:
+			binder_debug(BINDER_DEBUG_THREADS,
+				     "binder: %d:%d BC_REGISTER_LOOPER\n",
+				     proc->pid, thread->pid);
+			if (thread->looper & BINDER_LOOPER_STATE_ENTERED) {
+				thread->looper |= BINDER_LOOPER_STATE_INVALID;
+				binder_user_error("binder: %d:%d ERROR:"
+					" BC_REGISTER_LOOPER called "
+					"after BC_ENTER_LOOPER\n",
+					proc->pid, thread->pid);
+			} else if (proc->requested_threads == 0) {
+				thread->looper |= BINDER_LOOPER_STATE_INVALID;
+				binder_user_error("binder: %d:%d ERROR:"
+					" BC_REGISTER_LOOPER called "
+					"without request\n",
+					proc->pid, thread->pid);
+			} else {
+				proc->requested_threads--;
+				proc->requested_threads_started++;
+			}
+			thread->looper |= BINDER_LOOPER_STATE_REGISTERED;
+			break;
+		case BC_ENTER_LOOPER:
+			binder_debug(BINDER_DEBUG_THREADS,
+				     "binder: %d:%d BC_ENTER_LOOPER\n",
+				     proc->pid, thread->pid);
+			if (thread->looper & BINDER_LOOPER_STATE_REGISTERED) {
+				thread->looper |= BINDER_LOOPER_STATE_INVALID;
+				binder_user_error("binder: %d:%d ERROR:"
+					" BC_ENTER_LOOPER called after "
+					"BC_REGISTER_LOOPER\n",
+					proc->pid, thread->pid);
+			}
+			thread->looper |= BINDER_LOOPER_STATE_ENTERED;
+			break;
+		case BC_EXIT_LOOPER:
+			binder_debug(BINDER_DEBUG_THREADS,
+				     "binder: %d:%d BC_EXIT_LOOPER\n",
+				     proc->pid, thread->pid);
+			thread->looper |= BINDER_LOOPER_STATE_EXITED;
+			break;
+
+		case BC_REQUEST_DEATH_NOTIFICATION:
+		case BC_CLEAR_DEATH_NOTIFICATION: {
+			uint32_t target;
+			void __user *cookie;
+			struct binder_ref *ref;
+			struct binder_ref_death *death;
+
+			if (get_user(target, (uint32_t __user *)ptr))
+				return -EFAULT;
+			ptr += sizeof(uint32_t);
+			if (get_user(cookie, (void __user * __user *)ptr))
+				return -EFAULT;
+			ptr += sizeof(void *);
+			ref = binder_get_ref(proc, target);
+			if (ref == NULL) {
+				binder_user_error("binder: %d:%d %s "
+					"invalid ref %d\n",
+					proc->pid, thread->pid,
+					cmd == BC_REQUEST_DEATH_NOTIFICATION ?
+					"BC_REQUEST_DEATH_NOTIFICATION" :
+					"BC_CLEAR_DEATH_NOTIFICATION",
+					target);
+				break;
+			}
+
+			binder_debug(BINDER_DEBUG_DEATH_NOTIFICATION,
+				     "binder: %d:%d %s %p ref %d desc %d s %d w %d for node %d\n",
+				     proc->pid, thread->pid,
+				     cmd == BC_REQUEST_DEATH_NOTIFICATION ?
+				     "BC_REQUEST_DEATH_NOTIFICATION" :
+				     "BC_CLEAR_DEATH_NOTIFICATION",
+				     cookie, ref->debug_id, ref->desc,
+				     ref->strong, ref->weak, ref->node->debug_id);
+
+			if (cmd == BC_REQUEST_DEATH_NOTIFICATION) {
+				if (ref->death) {
+					binder_user_error("binder: %d:%"
+						"d BC_REQUEST_DEATH_NOTI"
+						"FICATION death notific"
+						"ation already set\n",
+						proc->pid, thread->pid);
+					break;
+				}
+				death = kzalloc(sizeof(*death), GFP_KERNEL);
+				if (death == NULL) {
+					thread->return_error = BR_ERROR;
+					binder_debug(BINDER_DEBUG_FAILED_TRANSACTION,
+						     "binder: %d:%d "
+						     "BC_REQUEST_DEATH_NOTIFICATION failed\n",
+						     proc->pid, thread->pid);
+					break;
+				}
+				binder_stats_created(BINDER_STAT_DEATH);
+				INIT_LIST_HEAD(&death->work.entry);
+				death->cookie = cookie;
+				ref->death = death;
+				if (ref->node->proc == NULL) {
+					ref->death->work.type = BINDER_WORK_DEAD_BINDER;
+					if (thread->looper & (BINDER_LOOPER_STATE_REGISTERED | BINDER_LOOPER_STATE_ENTERED)) {
+						list_add_tail(&ref->death->work.entry, &thread->todo);
+					} else {
+						list_add_tail(&ref->death->work.entry, &proc->todo);
+						wake_up_interruptible(&proc->wait);
+					}
+				}
+			} else {
+				if (ref->death == NULL) {
+					binder_user_error("binder: %d:%"
+						"d BC_CLEAR_DEATH_NOTIFI"
+						"CATION death notificat"
+						"ion not active\n",
+						proc->pid, thread->pid);
+					break;
+				}
+				death = ref->death;
+				if (death->cookie != cookie) {
+					binder_user_error("binder: %d:%"
+						"d BC_CLEAR_DEATH_NOTIFI"
+						"CATION death notificat"
+						"ion cookie mismatch "
+						"%p != %p\n",
+						proc->pid, thread->pid,
+						death->cookie, cookie);
+					break;
+				}
+				ref->death = NULL;
+				if (list_empty(&death->work.entry)) {
+					death->work.type = BINDER_WORK_CLEAR_DEATH_NOTIFICATION;
+					if (thread->looper & (BINDER_LOOPER_STATE_REGISTERED | BINDER_LOOPER_STATE_ENTERED)) {
+						list_add_tail(&death->work.entry, &thread->todo);
+					} else {
+						list_add_tail(&death->work.entry, &proc->todo);
+						wake_up_interruptible(&proc->wait);
+					}
+				} else {
+					BUG_ON(death->work.type != BINDER_WORK_DEAD_BINDER);
+					death->work.type = BINDER_WORK_DEAD_BINDER_AND_CLEAR;
+				}
+			}
+		} break;
+		case BC_DEAD_BINDER_DONE: {
+			struct binder_work *w;
+			void __user *cookie;
+			struct binder_ref_death *death = NULL;
+			if (get_user(cookie, (void __user * __user *)ptr))
+				return -EFAULT;
+
+			ptr += sizeof(void *);
+			list_for_each_entry(w, &proc->delivered_death, entry) {
+				struct binder_ref_death *tmp_death = container_of(w, struct binder_ref_death, work);
+				if (tmp_death->cookie == cookie) {
+					death = tmp_death;
+					break;
+				}
+			}
+			binder_debug(BINDER_DEBUG_DEAD_BINDER,
+				     "binder: %d:%d BC_DEAD_BINDER_DONE %p found %p\n",
+				     proc->pid, thread->pid, cookie, death);
+			if (death == NULL) {
+				binder_user_error("binder: %d:%d BC_DEAD"
+					"_BINDER_DONE %p not found\n",
+					proc->pid, thread->pid, cookie);
+				break;
+			}
+
+			list_del_init(&death->work.entry);
+			if (death->work.type == BINDER_WORK_DEAD_BINDER_AND_CLEAR) {
+				death->work.type = BINDER_WORK_CLEAR_DEATH_NOTIFICATION;
+				if (thread->looper & (BINDER_LOOPER_STATE_REGISTERED | BINDER_LOOPER_STATE_ENTERED)) {
+					list_add_tail(&death->work.entry, &thread->todo);
+				} else {
+					list_add_tail(&death->work.entry, &proc->todo);
+					wake_up_interruptible(&proc->wait);
+				}
+			}
+		} break;
+
+		default:
+			printk(KERN_ERR "binder: %d:%d unknown command %d\n",
+			       proc->pid, thread->pid, cmd);
+			return -EINVAL;
+		}
+		*consumed = ptr - buffer;
+	}
+	return 0;
+}
+
+void binder_stat_br(struct binder_proc *proc, struct binder_thread *thread,
+		    uint32_t cmd)
+{
+	if (_IOC_NR(cmd) < ARRAY_SIZE(binder_stats.br)) {
+		binder_stats.br[_IOC_NR(cmd)]++;
+		proc->stats.br[_IOC_NR(cmd)]++;
+		thread->stats.br[_IOC_NR(cmd)]++;
+	}
+}
+
+static int binder_has_proc_work(struct binder_proc *proc,
+				struct binder_thread *thread)
+{
+	return !list_empty(&proc->todo) ||
+		(thread->looper & BINDER_LOOPER_STATE_NEED_RETURN);
+}
+
+static int binder_has_thread_work(struct binder_thread *thread)
+{
+	return !list_empty(&thread->todo) || thread->return_error != BR_OK ||
+		(thread->looper & BINDER_LOOPER_STATE_NEED_RETURN);
+}
+
+static int binder_thread_read(struct binder_proc *proc,
+			      struct binder_thread *thread,
+			      void  __user *buffer, int size,
+			      signed long *consumed, int non_block)
+{
+	void __user *ptr = buffer + *consumed;
+	void __user *end = buffer + size;
+
+	int ret = 0;
+	int wait_for_proc_work;
+
+	if (*consumed == 0) {
+		if (put_user(BR_NOOP, (uint32_t __user *)ptr))
+			return -EFAULT;
+		ptr += sizeof(uint32_t);
+	}
+
+retry:
+	wait_for_proc_work = thread->transaction_stack == NULL &&
+				list_empty(&thread->todo);
+
+	if (thread->return_error != BR_OK && ptr < end) {
+		if (thread->return_error2 != BR_OK) {
+			if (put_user(thread->return_error2, (uint32_t __user *)ptr))
+				return -EFAULT;
+			ptr += sizeof(uint32_t);
+			if (ptr == end)
+				goto done;
+			thread->return_error2 = BR_OK;
+		}
+		if (put_user(thread->return_error, (uint32_t __user *)ptr))
+			return -EFAULT;
+		ptr += sizeof(uint32_t);
+		thread->return_error = BR_OK;
+		goto done;
+	}
+
+
+	thread->looper |= BINDER_LOOPER_STATE_WAITING;
+	if (wait_for_proc_work)
+		proc->ready_threads++;
+	mutex_unlock(&binder_lock);
+	if (wait_for_proc_work) {
+		if (!(thread->looper & (BINDER_LOOPER_STATE_REGISTERED |
+					BINDER_LOOPER_STATE_ENTERED))) {
+			binder_user_error("binder: %d:%d ERROR: Thread waiting "
+				"for process work before calling BC_REGISTER_"
+				"LOOPER or BC_ENTER_LOOPER (state %x)\n",
+				proc->pid, thread->pid, thread->looper);
+			wait_event_interruptible(binder_user_error_wait,
+						 binder_stop_on_user_error < 2);
+		}
+		binder_set_nice(proc->default_priority);
+		if (non_block) {
+			if (!binder_has_proc_work(proc, thread))
+				ret = -EAGAIN;
+		} else
+			ret = wait_event_interruptible_exclusive(proc->wait, binder_has_proc_work(proc, thread));
+	} else {
+		if (non_block) {
+			if (!binder_has_thread_work(thread))
+				ret = -EAGAIN;
+		} else
+			ret = wait_event_interruptible(thread->wait, binder_has_thread_work(thread));
+	}
+	mutex_lock(&binder_lock);
+	if (wait_for_proc_work)
+		proc->ready_threads--;
+	thread->looper &= ~BINDER_LOOPER_STATE_WAITING;
+
+	if (ret)
+		return ret;
+
+	while (1) {
+		uint32_t cmd;
+		struct binder_transaction_data tr;
+		struct binder_work *w;
+		struct binder_transaction *t = NULL;
+
+		if (!list_empty(&thread->todo))
+			w = list_first_entry(&thread->todo, struct binder_work, entry);
+		else if (!list_empty(&proc->todo) && wait_for_proc_work)
+			w = list_first_entry(&proc->todo, struct binder_work, entry);
+		else {
+			if (ptr - buffer == 4 && !(thread->looper & BINDER_LOOPER_STATE_NEED_RETURN)) /* no data added */
+				goto retry;
+			break;
+		}
+
+		if (end - ptr < sizeof(tr) + 4)
+			break;
+
+		switch (w->type) {
+		case BINDER_WORK_TRANSACTION: {
+			t = container_of(w, struct binder_transaction, work);
+		} break;
+		case BINDER_WORK_TRANSACTION_COMPLETE: {
+			cmd = BR_TRANSACTION_COMPLETE;
+			if (put_user(cmd, (uint32_t __user *)ptr))
+				return -EFAULT;
+			ptr += sizeof(uint32_t);
+
+			binder_stat_br(proc, thread, cmd);
+			binder_debug(BINDER_DEBUG_TRANSACTION_COMPLETE,
+				     "binder: %d:%d BR_TRANSACTION_COMPLETE\n",
+				     proc->pid, thread->pid);
+
+			list_del(&w->entry);
+			kfree(w);
+			binder_stats_deleted(BINDER_STAT_TRANSACTION_COMPLETE);
+		} break;
+		case BINDER_WORK_NODE: {
+			struct binder_node *node = container_of(w, struct binder_node, work);
+			uint32_t cmd = BR_NOOP;
+			const char *cmd_name;
+			int strong = node->internal_strong_refs || node->local_strong_refs;
+			int weak = !hlist_empty(&node->refs) || node->local_weak_refs || strong;
+			if (weak && !node->has_weak_ref) {
+				cmd = BR_INCREFS;
+				cmd_name = "BR_INCREFS";
+				node->has_weak_ref = 1;
+				node->pending_weak_ref = 1;
+				node->local_weak_refs++;
+			} else if (strong && !node->has_strong_ref) {
+				cmd = BR_ACQUIRE;
+				cmd_name = "BR_ACQUIRE";
+				node->has_strong_ref = 1;
+				node->pending_strong_ref = 1;
+				node->local_strong_refs++;
+			} else if (!strong && node->has_strong_ref) {
+				cmd = BR_RELEASE;
+				cmd_name = "BR_RELEASE";
+				node->has_strong_ref = 0;
+			} else if (!weak && node->has_weak_ref) {
+				cmd = BR_DECREFS;
+				cmd_name = "BR_DECREFS";
+				node->has_weak_ref = 0;
+			}
+			if (cmd != BR_NOOP) {
+				if (put_user(cmd, (uint32_t __user *)ptr))
+					return -EFAULT;
+				ptr += sizeof(uint32_t);
+				if (put_user(node->ptr, (void * __user *)ptr))
+					return -EFAULT;
+				ptr += sizeof(void *);
+				if (put_user(node->cookie, (void * __user *)ptr))
+					return -EFAULT;
+				ptr += sizeof(void *);
+
+				binder_stat_br(proc, thread, cmd);
+				binder_debug(BINDER_DEBUG_USER_REFS,
+					     "binder: %d:%d %s %d u%p c%p\n",
+					     proc->pid, thread->pid, cmd_name, node->debug_id, node->ptr, node->cookie);
+			} else {
+				list_del_init(&w->entry);
+				if (!weak && !strong) {
+					binder_debug(BINDER_DEBUG_INTERNAL_REFS,
+						     "binder: %d:%d node %d u%p c%p deleted\n",
+						     proc->pid, thread->pid, node->debug_id,
+						     node->ptr, node->cookie);
+					rb_erase(&node->rb_node, &proc->nodes);
+					kfree(node);
+					binder_stats_deleted(BINDER_STAT_NODE);
+				} else {
+					binder_debug(BINDER_DEBUG_INTERNAL_REFS,
+						     "binder: %d:%d node %d u%p c%p state unchanged\n",
+						     proc->pid, thread->pid, node->debug_id, node->ptr,
+						     node->cookie);
+				}
+			}
+		} break;
+		case BINDER_WORK_DEAD_BINDER:
+		case BINDER_WORK_DEAD_BINDER_AND_CLEAR:
+		case BINDER_WORK_CLEAR_DEATH_NOTIFICATION: {
+			struct binder_ref_death *death;
+			uint32_t cmd;
+
+			death = container_of(w, struct binder_ref_death, work);
+			if (w->type == BINDER_WORK_CLEAR_DEATH_NOTIFICATION)
+				cmd = BR_CLEAR_DEATH_NOTIFICATION_DONE;
+			else
+				cmd = BR_DEAD_BINDER;
+			if (put_user(cmd, (uint32_t __user *)ptr))
+				return -EFAULT;
+			ptr += sizeof(uint32_t);
+			if (put_user(death->cookie, (void * __user *)ptr))
+				return -EFAULT;
+			ptr += sizeof(void *);
+			binder_debug(BINDER_DEBUG_DEATH_NOTIFICATION,
+				     "binder: %d:%d %s %p\n",
+				      proc->pid, thread->pid,
+				      cmd == BR_DEAD_BINDER ?
+				      "BR_DEAD_BINDER" :
+				      "BR_CLEAR_DEATH_NOTIFICATION_DONE",
+				      death->cookie);
+
+			if (w->type == BINDER_WORK_CLEAR_DEATH_NOTIFICATION) {
+				list_del(&w->entry);
+				kfree(death);
+				binder_stats_deleted(BINDER_STAT_DEATH);
+			} else
+				list_move(&w->entry, &proc->delivered_death);
+			if (cmd == BR_DEAD_BINDER)
+				goto done; /* DEAD_BINDER notifications can cause transactions */
+		} break;
+		}
+
+		if (!t)
+			continue;
+
+		BUG_ON(t->buffer == NULL);
+		if (t->buffer->target_node) {
+			struct binder_node *target_node = t->buffer->target_node;
+			tr.target.ptr = target_node->ptr;
+			tr.cookie =  target_node->cookie;
+			t->saved_priority = task_nice(current);
+			if (t->priority < target_node->min_priority &&
+			    !(t->flags & TF_ONE_WAY))
+				binder_set_nice(t->priority);
+			else if (!(t->flags & TF_ONE_WAY) ||
+				 t->saved_priority > target_node->min_priority)
+				binder_set_nice(target_node->min_priority);
+			cmd = BR_TRANSACTION;
+		} else {
+			tr.target.ptr = NULL;
+			tr.cookie = NULL;
+			cmd = BR_REPLY;
+		}
+		tr.code = t->code;
+		tr.flags = t->flags;
+		tr.sender_euid = t->sender_euid;
+
+		if (t->from) {
+			struct task_struct *sender = t->from->proc->tsk;
+			tr.sender_pid = task_tgid_nr_ns(sender,
+							current->nsproxy->pid_ns);
+		} else {
+			tr.sender_pid = 0;
+		}
+
+		tr.data_size = t->buffer->data_size;
+		tr.offsets_size = t->buffer->offsets_size;
+		tr.data.ptr.buffer = (void *)t->buffer->data +
+					proc->user_buffer_offset;
+		tr.data.ptr.offsets = tr.data.ptr.buffer +
+					ALIGN(t->buffer->data_size,
+					    sizeof(void *));
+
+		if (put_user(cmd, (uint32_t __user *)ptr))
+			return -EFAULT;
+		ptr += sizeof(uint32_t);
+		if (copy_to_user(ptr, &tr, sizeof(tr)))
+			return -EFAULT;
+		ptr += sizeof(tr);
+
+		binder_stat_br(proc, thread, cmd);
+		binder_debug(BINDER_DEBUG_TRANSACTION,
+			     "binder: %d:%d %s %d %d:%d, cmd %d"
+			     "size %zd-%zd ptr %p-%p\n",
+			     proc->pid, thread->pid,
+			     (cmd == BR_TRANSACTION) ? "BR_TRANSACTION" :
+			     "BR_REPLY",
+			     t->debug_id, t->from ? t->from->proc->pid : 0,
+			     t->from ? t->from->pid : 0, cmd,
+			     t->buffer->data_size, t->buffer->offsets_size,
+			     tr.data.ptr.buffer, tr.data.ptr.offsets);
+
+		list_del(&t->work.entry);
+		t->buffer->allow_user_free = 1;
+		if (cmd == BR_TRANSACTION && !(t->flags & TF_ONE_WAY)) {
+			t->to_parent = thread->transaction_stack;
+			t->to_thread = thread;
+			thread->transaction_stack = t;
+		} else {
+			t->buffer->transaction = NULL;
+			kfree(t);
+			binder_stats_deleted(BINDER_STAT_TRANSACTION);
+		}
+		break;
+	}
+
+done:
+
+	*consumed = ptr - buffer;
+	if (proc->requested_threads + proc->ready_threads == 0 &&
+	    proc->requested_threads_started < proc->max_threads &&
+	    (thread->looper & (BINDER_LOOPER_STATE_REGISTERED |
+	     BINDER_LOOPER_STATE_ENTERED)) /* the user-space code fails to */
+	     /*spawn a new thread if we leave this out */) {
+		proc->requested_threads++;
+		binder_debug(BINDER_DEBUG_THREADS,
+			     "binder: %d:%d BR_SPAWN_LOOPER\n",
+			     proc->pid, thread->pid);
+		if (put_user(BR_SPAWN_LOOPER, (uint32_t __user *)buffer))
+			return -EFAULT;
+	}
+	return 0;
+}
+
+static void binder_release_work(struct list_head *list)
+{
+	struct binder_work *w;
+	while (!list_empty(list)) {
+		w = list_first_entry(list, struct binder_work, entry);
+		list_del_init(&w->entry);
+		switch (w->type) {
+		case BINDER_WORK_TRANSACTION: {
+			struct binder_transaction *t;
+
+			t = container_of(w, struct binder_transaction, work);
+			if (t->buffer->target_node && !(t->flags & TF_ONE_WAY))
+				binder_send_failed_reply(t, BR_DEAD_REPLY);
+		} break;
+		case BINDER_WORK_TRANSACTION_COMPLETE: {
+			kfree(w);
+			binder_stats_deleted(BINDER_STAT_TRANSACTION_COMPLETE);
+		} break;
+		default:
+			break;
+		}
+	}
+
+}
+
+static struct binder_thread *binder_get_thread(struct binder_proc *proc)
+{
+	struct binder_thread *thread = NULL;
+	struct rb_node *parent = NULL;
+	struct rb_node **p = &proc->threads.rb_node;
+
+	while (*p) {
+		parent = *p;
+		thread = rb_entry(parent, struct binder_thread, rb_node);
+
+		if (current->pid < thread->pid)
+			p = &(*p)->rb_left;
+		else if (current->pid > thread->pid)
+			p = &(*p)->rb_right;
+		else
+			break;
+	}
+	if (*p == NULL) {
+		thread = kzalloc(sizeof(*thread), GFP_KERNEL);
+		if (thread == NULL)
+			return NULL;
+		binder_stats_created(BINDER_STAT_THREAD);
+		thread->proc = proc;
+		thread->pid = current->pid;
+		init_waitqueue_head(&thread->wait);
+		INIT_LIST_HEAD(&thread->todo);
+		rb_link_node(&thread->rb_node, parent, p);
+		rb_insert_color(&thread->rb_node, &proc->threads);
+		thread->looper |= BINDER_LOOPER_STATE_NEED_RETURN;
+		thread->return_error = BR_OK;
+		thread->return_error2 = BR_OK;
+	}
+	return thread;
+}
+
+static int binder_free_thread(struct binder_proc *proc,
+			      struct binder_thread *thread)
+{
+	struct binder_transaction *t;
+	struct binder_transaction *send_reply = NULL;
+	int active_transactions = 0;
+
+	rb_erase(&thread->rb_node, &proc->threads);
+	t = thread->transaction_stack;
+	if (t && t->to_thread == thread)
+		send_reply = t;
+	while (t) {
+		active_transactions++;
+		binder_debug(BINDER_DEBUG_DEAD_TRANSACTION,
+			     "binder: release %d:%d transaction %d "
+			     "%s, still active\n", proc->pid, thread->pid,
+			     t->debug_id,
+			     (t->to_thread == thread) ? "in" : "out");
+
+		if (t->to_thread == thread) {
+			t->to_proc = NULL;
+			t->to_thread = NULL;
+			if (t->buffer) {
+				t->buffer->transaction = NULL;
+				t->buffer = NULL;
+			}
+			t = t->to_parent;
+		} else if (t->from == thread) {
+			t->from = NULL;
+			t = t->from_parent;
+		} else
+			BUG();
+	}
+	if (send_reply)
+		binder_send_failed_reply(send_reply, BR_DEAD_REPLY);
+	binder_release_work(&thread->todo);
+	kfree(thread);
+	binder_stats_deleted(BINDER_STAT_THREAD);
+	return active_transactions;
+}
+
+static unsigned int binder_poll(struct file *filp,
+				struct poll_table_struct *wait)
+{
+	struct binder_proc *proc = filp->private_data;
+	struct binder_thread *thread = NULL;
+	int wait_for_proc_work;
+
+	mutex_lock(&binder_lock);
+	thread = binder_get_thread(proc);
+
+	wait_for_proc_work = thread->transaction_stack == NULL &&
+		list_empty(&thread->todo) && thread->return_error == BR_OK;
+	mutex_unlock(&binder_lock);
+
+	if (wait_for_proc_work) {
+		if (binder_has_proc_work(proc, thread))
+			return POLLIN;
+		poll_wait(filp, &proc->wait, wait);
+		if (binder_has_proc_work(proc, thread))
+			return POLLIN;
+	} else {
+		if (binder_has_thread_work(thread))
+			return POLLIN;
+		poll_wait(filp, &thread->wait, wait);
+		if (binder_has_thread_work(thread))
+			return POLLIN;
+	}
+	return 0;
+}
+
+static long binder_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
+{
+	int ret;
+	struct binder_proc *proc = filp->private_data;
+	struct binder_thread *thread;
+	unsigned int size = _IOC_SIZE(cmd);
+	void __user *ubuf = (void __user *)arg;
+
+	/*printk(KERN_INFO "binder_ioctl: %d:%d %x %lx\n", proc->pid, current->pid, cmd, arg);*/
+
+	ret = wait_event_interruptible(binder_user_error_wait, binder_stop_on_user_error < 2);
+	if (ret)
+		return ret;
+
+	mutex_lock(&binder_lock);
+	thread = binder_get_thread(proc);
+	if (thread == NULL) {
+		ret = -ENOMEM;
+		goto err;
+	}
+
+	switch (cmd) {
+	case BINDER_WRITE_READ: {
+		struct binder_write_read bwr;
+		if (size != sizeof(struct binder_write_read)) {
+			ret = -EINVAL;
+			goto err;
+		}
+		if (copy_from_user(&bwr, ubuf, sizeof(bwr))) {
+			ret = -EFAULT;
+			goto err;
+		}
+		binder_debug(BINDER_DEBUG_READ_WRITE,
+			     "binder: %d:%d write %ld at %08lx, read %ld at %08lx\n",
+			     proc->pid, thread->pid, bwr.write_size, bwr.write_buffer,
+			     bwr.read_size, bwr.read_buffer);
+
+		if (bwr.write_size > 0) {
+			ret = binder_thread_write(proc, thread, (void __user *)bwr.write_buffer, bwr.write_size, &bwr.write_consumed);
+			if (ret < 0) {
+				bwr.read_consumed = 0;
+				if (copy_to_user(ubuf, &bwr, sizeof(bwr)))
+					ret = -EFAULT;
+				goto err;
+			}
+		}
+		if (bwr.read_size > 0) {
+			ret = binder_thread_read(proc, thread, (void __user *)bwr.read_buffer, bwr.read_size, &bwr.read_consumed, filp->f_flags & O_NONBLOCK);
+			if (!list_empty(&proc->todo))
+				wake_up_interruptible(&proc->wait);
+			if (ret < 0) {
+				if (copy_to_user(ubuf, &bwr, sizeof(bwr)))
+					ret = -EFAULT;
+				goto err;
+			}
+		}
+		binder_debug(BINDER_DEBUG_READ_WRITE,
+			     "binder: %d:%d wrote %ld of %ld, read return %ld of %ld\n",
+			     proc->pid, thread->pid, bwr.write_consumed, bwr.write_size,
+			     bwr.read_consumed, bwr.read_size);
+		if (copy_to_user(ubuf, &bwr, sizeof(bwr))) {
+			ret = -EFAULT;
+			goto err;
+		}
+		break;
+	}
+	case BINDER_SET_MAX_THREADS:
+		if (copy_from_user(&proc->max_threads, ubuf, sizeof(proc->max_threads))) {
+			ret = -EINVAL;
+			goto err;
+		}
+		break;
+	case BINDER_SET_CONTEXT_MGR:
+		if (binder_context_mgr_node != NULL) {
+			printk(KERN_ERR "binder: BINDER_SET_CONTEXT_MGR already set\n");
+			ret = -EBUSY;
+			goto err;
+		}
+		if (binder_context_mgr_uid != -1) {
+			if (binder_context_mgr_uid != current->cred->euid) {
+				printk(KERN_ERR "binder: BINDER_SET_"
+				       "CONTEXT_MGR bad uid %d != %d\n",
+				       current->cred->euid,
+				       binder_context_mgr_uid);
+				ret = -EPERM;
+				goto err;
+			}
+		} else
+			binder_context_mgr_uid = current->cred->euid;
+		binder_context_mgr_node = binder_new_node(proc, NULL, NULL);
+		if (binder_context_mgr_node == NULL) {
+			ret = -ENOMEM;
+			goto err;
+		}
+		binder_context_mgr_node->local_weak_refs++;
+		binder_context_mgr_node->local_strong_refs++;
+		binder_context_mgr_node->has_strong_ref = 1;
+		binder_context_mgr_node->has_weak_ref = 1;
+		break;
+	case BINDER_THREAD_EXIT:
+		binder_debug(BINDER_DEBUG_THREADS, "binder: %d:%d exit\n",
+			     proc->pid, thread->pid);
+		binder_free_thread(proc, thread);
+		thread = NULL;
+		break;
+	case BINDER_VERSION:
+		if (size != sizeof(struct binder_version)) {
+			ret = -EINVAL;
+			goto err;
+		}
+		if (put_user(BINDER_CURRENT_PROTOCOL_VERSION, &((struct binder_version *)ubuf)->protocol_version)) {
+			ret = -EINVAL;
+			goto err;
+		}
+		break;
+	default:
+		ret = -EINVAL;
+		goto err;
+	}
+	ret = 0;
+err:
+	if (thread)
+		thread->looper &= ~BINDER_LOOPER_STATE_NEED_RETURN;
+	mutex_unlock(&binder_lock);
+	wait_event_interruptible(binder_user_error_wait, binder_stop_on_user_error < 2);
+	if (ret && ret != -ERESTARTSYS)
+		printk(KERN_INFO "binder: %d:%d ioctl %x %lx returned %d\n", proc->pid, current->pid, cmd, arg, ret);
+	return ret;
+}
+
+static void binder_vma_open(struct vm_area_struct *vma)
+{
+	struct binder_proc *proc = vma->vm_private_data;
+	binder_debug(BINDER_DEBUG_OPEN_CLOSE,
+		     "binder: %d open vm area %lx-%lx (%ld K) vma %lx pagep %lx\n",
+		     proc->pid, vma->vm_start, vma->vm_end,
+		     (vma->vm_end - vma->vm_start) / SZ_1K, vma->vm_flags,
+		     (unsigned long)pgprot_val(vma->vm_page_prot));
+	dump_stack();
+}
+
+static void binder_vma_close(struct vm_area_struct *vma)
+{
+	struct binder_proc *proc = vma->vm_private_data;
+	binder_debug(BINDER_DEBUG_OPEN_CLOSE,
+		     "binder: %d close vm area %lx-%lx (%ld K) vma %lx pagep %lx\n",
+		     proc->pid, vma->vm_start, vma->vm_end,
+		     (vma->vm_end - vma->vm_start) / SZ_1K, vma->vm_flags,
+		     (unsigned long)pgprot_val(vma->vm_page_prot));
+	proc->vma = NULL;
+	binder_defer_work(proc, BINDER_DEFERRED_PUT_FILES);
+}
+
+static struct vm_operations_struct binder_vm_ops = {
+	.open = binder_vma_open,
+	.close = binder_vma_close,
+};
+
+static int binder_mmap(struct file *filp, struct vm_area_struct *vma)
+{
+	int ret;
+	struct vm_struct *area;
+	struct binder_proc *proc = filp->private_data;
+	const char *failure_string;
+	struct binder_buffer *buffer;
+
+	if ((vma->vm_end - vma->vm_start) > SZ_4M)
+		vma->vm_end = vma->vm_start + SZ_4M;
+
+	binder_debug(BINDER_DEBUG_OPEN_CLOSE,
+		     "binder_mmap: %d %lx-%lx (%ld K) vma %lx pagep %lx\n",
+		     proc->pid, vma->vm_start, vma->vm_end,
+		     (vma->vm_end - vma->vm_start) / SZ_1K, vma->vm_flags,
+		     (unsigned long)pgprot_val(vma->vm_page_prot));
+
+	if (vma->vm_flags & FORBIDDEN_MMAP_FLAGS) {
+		ret = -EPERM;
+		failure_string = "bad vm_flags";
+		goto err_bad_arg;
+	}
+	vma->vm_flags = (vma->vm_flags | VM_DONTCOPY) & ~VM_MAYWRITE;
+
+	if (proc->buffer) {
+		ret = -EBUSY;
+		failure_string = "already mapped";
+		goto err_already_mapped;
+	}
+
+	area = get_vm_area(vma->vm_end - vma->vm_start, VM_IOREMAP);
+	if (area == NULL) {
+		ret = -ENOMEM;
+		failure_string = "get_vm_area";
+		goto err_get_vm_area_failed;
+	}
+	proc->buffer = area->addr;
+	proc->user_buffer_offset = vma->vm_start - (uintptr_t)proc->buffer;
+
+#ifdef CONFIG_CPU_CACHE_VIPT
+	if (cache_is_vipt_aliasing()) {
+		while (CACHE_COLOUR((vma->vm_start ^ (uint32_t)proc->buffer))) {
+			printk(KERN_INFO "binder_mmap: %d %lx-%lx maps %p bad alignment\n", proc->pid, vma->vm_start, vma->vm_end, proc->buffer);
+			vma->vm_start += PAGE_SIZE;
+		}
+	}
+#endif
+	proc->pages = kzalloc(sizeof(proc->pages[0]) * ((vma->vm_end - vma->vm_start) / PAGE_SIZE), GFP_KERNEL);
+	if (proc->pages == NULL) {
+		ret = -ENOMEM;
+		failure_string = "alloc page array";
+		goto err_alloc_pages_failed;
+	}
+	proc->buffer_size = vma->vm_end - vma->vm_start;
+
+	vma->vm_ops = &binder_vm_ops;
+	vma->vm_private_data = proc;
+
+	if (binder_update_page_range(proc, 1, proc->buffer, proc->buffer + PAGE_SIZE, vma)) {
+		ret = -ENOMEM;
+		failure_string = "alloc small buf";
+		goto err_alloc_small_buf_failed;
+	}
+	buffer = proc->buffer;
+	INIT_LIST_HEAD(&proc->buffers);
+	list_add(&buffer->entry, &proc->buffers);
+	buffer->free = 1;
+	binder_insert_free_buffer(proc, buffer);
+	proc->free_async_space = proc->buffer_size / 2;
+	barrier();
+	proc->files = get_files_struct(current);
+	proc->vma = vma;
+
+	/*printk(KERN_INFO "binder_mmap: %d %lx-%lx maps %p\n",
+		 proc->pid, vma->vm_start, vma->vm_end, proc->buffer);*/
+	return 0;
+
+err_alloc_small_buf_failed:
+	kfree(proc->pages);
+	proc->pages = NULL;
+err_alloc_pages_failed:
+	vfree(proc->buffer);
+	proc->buffer = NULL;
+err_get_vm_area_failed:
+err_already_mapped:
+err_bad_arg:
+	printk(KERN_ERR "binder_mmap: %d %lx-%lx %s failed %d\n",
+	       proc->pid, vma->vm_start, vma->vm_end, failure_string, ret);
+	return ret;
+}
+
+static int binder_open(struct inode *nodp, struct file *filp)
+{
+	struct binder_proc *proc;
+
+	binder_debug(BINDER_DEBUG_OPEN_CLOSE, "binder_open: %d:%d\n",
+		     current->group_leader->pid, current->pid);
+
+	proc = kzalloc(sizeof(*proc), GFP_KERNEL);
+	if (proc == NULL)
+		return -ENOMEM;
+	get_task_struct(current);
+	proc->tsk = current;
+	INIT_LIST_HEAD(&proc->todo);
+	init_waitqueue_head(&proc->wait);
+	proc->default_priority = task_nice(current);
+	mutex_lock(&binder_lock);
+	binder_stats_created(BINDER_STAT_PROC);
+	hlist_add_head(&proc->proc_node, &binder_procs);
+	proc->pid = current->group_leader->pid;
+	INIT_LIST_HEAD(&proc->delivered_death);
+	filp->private_data = proc;
+	mutex_unlock(&binder_lock);
+
+	if (binder_debugfs_dir_entry_proc) {
+		char strbuf[11];
+		snprintf(strbuf, sizeof(strbuf), "%u", proc->pid);
+		proc->debugfs_entry = debugfs_create_file(strbuf, S_IRUGO,
+			binder_debugfs_dir_entry_proc, proc, &binder_proc_fops);
+	}
+
+	return 0;
+}
+
+static int binder_flush(struct file *filp, fl_owner_t id)
+{
+	struct binder_proc *proc = filp->private_data;
+
+	binder_defer_work(proc, BINDER_DEFERRED_FLUSH);
+
+	return 0;
+}
+
+static void binder_deferred_flush(struct binder_proc *proc)
+{
+	struct rb_node *n;
+	int wake_count = 0;
+	for (n = rb_first(&proc->threads); n != NULL; n = rb_next(n)) {
+		struct binder_thread *thread = rb_entry(n, struct binder_thread, rb_node);
+		thread->looper |= BINDER_LOOPER_STATE_NEED_RETURN;
+		if (thread->looper & BINDER_LOOPER_STATE_WAITING) {
+			wake_up_interruptible(&thread->wait);
+			wake_count++;
+		}
+	}
+	wake_up_interruptible_all(&proc->wait);
+
+	binder_debug(BINDER_DEBUG_OPEN_CLOSE,
+		     "binder_flush: %d woke %d threads\n", proc->pid,
+		     wake_count);
+}
+
+static int binder_release(struct inode *nodp, struct file *filp)
+{
+	struct binder_proc *proc = filp->private_data;
+	debugfs_remove(proc->debugfs_entry);
+	binder_defer_work(proc, BINDER_DEFERRED_RELEASE);
+
+	return 0;
+}
+
+static void binder_deferred_release(struct binder_proc *proc)
+{
+	struct hlist_node *pos;
+	struct binder_transaction *t;
+	struct rb_node *n;
+	int threads, nodes, incoming_refs, outgoing_refs, buffers, active_transactions, page_count;
+
+	BUG_ON(proc->vma);
+	BUG_ON(proc->files);
+
+	hlist_del(&proc->proc_node);
+	if (binder_context_mgr_node && binder_context_mgr_node->proc == proc) {
+		binder_debug(BINDER_DEBUG_DEAD_BINDER,
+			     "binder_release: %d context_mgr_node gone\n",
+			     proc->pid);
+		binder_context_mgr_node = NULL;
+	}
+
+	threads = 0;
+	active_transactions = 0;
+	while ((n = rb_first(&proc->threads))) {
+		struct binder_thread *thread = rb_entry(n, struct binder_thread, rb_node);
+		threads++;
+		active_transactions += binder_free_thread(proc, thread);
+	}
+	nodes = 0;
+	incoming_refs = 0;
+	while ((n = rb_first(&proc->nodes))) {
+		struct binder_node *node = rb_entry(n, struct binder_node, rb_node);
+
+		nodes++;
+		rb_erase(&node->rb_node, &proc->nodes);
+		list_del_init(&node->work.entry);
+		if (hlist_empty(&node->refs)) {
+			kfree(node);
+			binder_stats_deleted(BINDER_STAT_NODE);
+		} else {
+			struct binder_ref *ref;
+			int death = 0;
+
+			node->proc = NULL;
+			node->local_strong_refs = 0;
+			node->local_weak_refs = 0;
+			hlist_add_head(&node->dead_node, &binder_dead_nodes);
+
+			hlist_for_each_entry(ref, pos, &node->refs, node_entry) {
+				incoming_refs++;
+				if (ref->death) {
+					death++;
+					if (list_empty(&ref->death->work.entry)) {
+						ref->death->work.type = BINDER_WORK_DEAD_BINDER;
+						list_add_tail(&ref->death->work.entry, &ref->proc->todo);
+						wake_up_interruptible(&ref->proc->wait);
+					} else
+						BUG();
+				}
+			}
+			binder_debug(BINDER_DEBUG_DEAD_BINDER,
+				     "binder: node %d now dead, "
+				     "refs %d, death %d\n", node->debug_id,
+				     incoming_refs, death);
+		}
+	}
+	outgoing_refs = 0;
+	while ((n = rb_first(&proc->refs_by_desc))) {
+		struct binder_ref *ref = rb_entry(n, struct binder_ref,
+						  rb_node_desc);
+		outgoing_refs++;
+		binder_delete_ref(ref);
+	}
+	binder_release_work(&proc->todo);
+	buffers = 0;
+
+	while ((n = rb_first(&proc->allocated_buffers))) {
+		struct binder_buffer *buffer = rb_entry(n, struct binder_buffer,
+							rb_node);
+		t = buffer->transaction;
+		if (t) {
+			t->buffer = NULL;
+			buffer->transaction = NULL;
+			printk(KERN_ERR "binder: release proc %d, "
+			       "transaction %d, not freed\n",
+			       proc->pid, t->debug_id);
+			/*BUG();*/
+		}
+		binder_free_buf(proc, buffer);
+		buffers++;
+	}
+
+	binder_stats_deleted(BINDER_STAT_PROC);
+
+	page_count = 0;
+	if (proc->pages) {
+		int i;
+		for (i = 0; i < proc->buffer_size / PAGE_SIZE; i++) {
+			if (proc->pages[i]) {
+				void *page_addr = proc->buffer + i * PAGE_SIZE;
+				binder_debug(BINDER_DEBUG_BUFFER_ALLOC,
+					     "binder_release: %d: "
+					     "page %d at %p not freed\n",
+					     proc->pid, i,
+					     page_addr);
+				unmap_kernel_range((unsigned long)page_addr,
+					PAGE_SIZE);
+				__free_page(proc->pages[i]);
+				page_count++;
+			}
+		}
+		kfree(proc->pages);
+		vfree(proc->buffer);
+	}
+
+	put_task_struct(proc->tsk);
+
+	binder_debug(BINDER_DEBUG_OPEN_CLOSE,
+		     "binder_release: %d threads %d, nodes %d (ref %d), "
+		     "refs %d, active transactions %d, buffers %d, "
+		     "pages %d\n",
+		     proc->pid, threads, nodes, incoming_refs, outgoing_refs,
+		     active_transactions, buffers, page_count);
+
+	kfree(proc);
+}
+
+static void binder_deferred_func(struct work_struct *work)
+{
+	struct binder_proc *proc;
+	struct files_struct *files;
+
+	int defer;
+	do {
+		mutex_lock(&binder_lock);
+		mutex_lock(&binder_deferred_lock);
+		if (!hlist_empty(&binder_deferred_list)) {
+			proc = hlist_entry(binder_deferred_list.first,
+					struct binder_proc, deferred_work_node);
+			hlist_del_init(&proc->deferred_work_node);
+			defer = proc->deferred_work;
+			proc->deferred_work = 0;
+		} else {
+			proc = NULL;
+			defer = 0;
+		}
+		mutex_unlock(&binder_deferred_lock);
+
+		files = NULL;
+		if (defer & BINDER_DEFERRED_PUT_FILES) {
+			files = proc->files;
+			if (files)
+				proc->files = NULL;
+		}
+
+		if (defer & BINDER_DEFERRED_FLUSH)
+			binder_deferred_flush(proc);
+
+		if (defer & BINDER_DEFERRED_RELEASE)
+			binder_deferred_release(proc); /* frees proc */
+
+		mutex_unlock(&binder_lock);
+		if (files)
+			put_files_struct(files);
+	} while (proc);
+}
+static DECLARE_WORK(binder_deferred_work, binder_deferred_func);
+
+static void
+binder_defer_work(struct binder_proc *proc, enum binder_deferred_state defer)
+{
+	mutex_lock(&binder_deferred_lock);
+	proc->deferred_work |= defer;
+	if (hlist_unhashed(&proc->deferred_work_node)) {
+		hlist_add_head(&proc->deferred_work_node,
+				&binder_deferred_list);
+		queue_work(binder_deferred_workqueue, &binder_deferred_work);
+	}
+	mutex_unlock(&binder_deferred_lock);
+}
+
+static void print_binder_transaction(struct seq_file *m, const char *prefix,
+				     struct binder_transaction *t)
+{
+	seq_printf(m,
+		   "%s %d: %p from %d:%d to %d:%d code %x flags %x pri %ld r%d",
+		   prefix, t->debug_id, t,
+		   t->from ? t->from->proc->pid : 0,
+		   t->from ? t->from->pid : 0,
+		   t->to_proc ? t->to_proc->pid : 0,
+		   t->to_thread ? t->to_thread->pid : 0,
+		   t->code, t->flags, t->priority, t->need_reply);
+	if (t->buffer == NULL) {
+		seq_puts(m, " buffer free\n");
+		return;
+	}
+	if (t->buffer->target_node)
+		seq_printf(m, " node %d",
+			   t->buffer->target_node->debug_id);
+	seq_printf(m, " size %zd:%zd data %p\n",
+		   t->buffer->data_size, t->buffer->offsets_size,
+		   t->buffer->data);
+}
+
+static void print_binder_buffer(struct seq_file *m, const char *prefix,
+				struct binder_buffer *buffer)
+{
+	seq_printf(m, "%s %d: %p size %zd:%zd %s\n",
+		   prefix, buffer->debug_id, buffer->data,
+		   buffer->data_size, buffer->offsets_size,
+		   buffer->transaction ? "active" : "delivered");
+}
+
+static void print_binder_work(struct seq_file *m, const char *prefix,
+			      const char *transaction_prefix,
+			      struct binder_work *w)
+{
+	struct binder_node *node;
+	struct binder_transaction *t;
+
+	switch (w->type) {
+	case BINDER_WORK_TRANSACTION:
+		t = container_of(w, struct binder_transaction, work);
+		print_binder_transaction(m, transaction_prefix, t);
+		break;
+	case BINDER_WORK_TRANSACTION_COMPLETE:
+		seq_printf(m, "%stransaction complete\n", prefix);
+		break;
+	case BINDER_WORK_NODE:
+		node = container_of(w, struct binder_node, work);
+		seq_printf(m, "%snode work %d: u%p c%p\n",
+			   prefix, node->debug_id, node->ptr, node->cookie);
+		break;
+	case BINDER_WORK_DEAD_BINDER:
+		seq_printf(m, "%shas dead binder\n", prefix);
+		break;
+	case BINDER_WORK_DEAD_BINDER_AND_CLEAR:
+		seq_printf(m, "%shas cleared dead binder\n", prefix);
+		break;
+	case BINDER_WORK_CLEAR_DEATH_NOTIFICATION:
+		seq_printf(m, "%shas cleared death notification\n", prefix);
+		break;
+	default:
+		seq_printf(m, "%sunknown work: type %d\n", prefix, w->type);
+		break;
+	}
+}
+
+static void print_binder_thread(struct seq_file *m,
+				struct binder_thread *thread,
+				int print_always)
+{
+	struct binder_transaction *t;
+	struct binder_work *w;
+	size_t start_pos = m->count;
+	size_t header_pos;
+
+	seq_printf(m, "  thread %d: l %02x\n", thread->pid, thread->looper);
+	header_pos = m->count;
+	t = thread->transaction_stack;
+	while (t) {
+		if (t->from == thread) {
+			print_binder_transaction(m,
+						 "    outgoing transaction", t);
+			t = t->from_parent;
+		} else if (t->to_thread == thread) {
+			print_binder_transaction(m,
+						 "    incoming transaction", t);
+			t = t->to_parent;
+		} else {
+			print_binder_transaction(m, "    bad transaction", t);
+			t = NULL;
+		}
+	}
+	list_for_each_entry(w, &thread->todo, entry) {
+		print_binder_work(m, "    ", "    pending transaction", w);
+	}
+	if (!print_always && m->count == header_pos)
+		m->count = start_pos;
+}
+
+static void print_binder_node(struct seq_file *m, struct binder_node *node)
+{
+	struct binder_ref *ref;
+	struct hlist_node *pos;
+	struct binder_work *w;
+	int count;
+
+	count = 0;
+	hlist_for_each_entry(ref, pos, &node->refs, node_entry)
+		count++;
+
+	seq_printf(m, "  node %d: u%p c%p hs %d hw %d ls %d lw %d is %d iw %d",
+		   node->debug_id, node->ptr, node->cookie,
+		   node->has_strong_ref, node->has_weak_ref,
+		   node->local_strong_refs, node->local_weak_refs,
+		   node->internal_strong_refs, count);
+	if (count) {
+		seq_puts(m, " proc");
+		hlist_for_each_entry(ref, pos, &node->refs, node_entry)
+			seq_printf(m, " %d", ref->proc->pid);
+	}
+	seq_puts(m, "\n");
+	list_for_each_entry(w, &node->async_todo, entry)
+		print_binder_work(m, "    ",
+				  "    pending async transaction", w);
+}
+
+static void print_binder_ref(struct seq_file *m, struct binder_ref *ref)
+{
+	seq_printf(m, "  ref %d: desc %d %snode %d s %d w %d d %p\n",
+		   ref->debug_id, ref->desc, ref->node->proc ? "" : "dead ",
+		   ref->node->debug_id, ref->strong, ref->weak, ref->death);
+}
+
+static void print_binder_proc(struct seq_file *m,
+			      struct binder_proc *proc, int print_all)
+{
+	struct binder_work *w;
+	struct rb_node *n;
+	size_t start_pos = m->count;
+	size_t header_pos;
+
+	seq_printf(m, "proc %d\n", proc->pid);
+	header_pos = m->count;
+
+	for (n = rb_first(&proc->threads); n != NULL; n = rb_next(n))
+		print_binder_thread(m, rb_entry(n, struct binder_thread,
+						rb_node), print_all);
+	for (n = rb_first(&proc->nodes); n != NULL; n = rb_next(n)) {
+		struct binder_node *node = rb_entry(n, struct binder_node,
+						    rb_node);
+		if (print_all || node->has_async_transaction)
+			print_binder_node(m, node);
+	}
+	if (print_all) {
+		for (n = rb_first(&proc->refs_by_desc);
+		     n != NULL;
+		     n = rb_next(n))
+			print_binder_ref(m, rb_entry(n, struct binder_ref,
+						     rb_node_desc));
+	}
+	for (n = rb_first(&proc->allocated_buffers); n != NULL; n = rb_next(n))
+		print_binder_buffer(m, "  buffer",
+				    rb_entry(n, struct binder_buffer, rb_node));
+	list_for_each_entry(w, &proc->todo, entry)
+		print_binder_work(m, "  ", "  pending transaction", w);
+	list_for_each_entry(w, &proc->delivered_death, entry) {
+		seq_puts(m, "  has delivered dead binder\n");
+		break;
+	}
+	if (!print_all && m->count == header_pos)
+		m->count = start_pos;
+}
+
+static const char *binder_return_strings[] = {
+	"BR_ERROR",
+	"BR_OK",
+	"BR_TRANSACTION",
+	"BR_REPLY",
+	"BR_ACQUIRE_RESULT",
+	"BR_DEAD_REPLY",
+	"BR_TRANSACTION_COMPLETE",
+	"BR_INCREFS",
+	"BR_ACQUIRE",
+	"BR_RELEASE",
+	"BR_DECREFS",
+	"BR_ATTEMPT_ACQUIRE",
+	"BR_NOOP",
+	"BR_SPAWN_LOOPER",
+	"BR_FINISHED",
+	"BR_DEAD_BINDER",
+	"BR_CLEAR_DEATH_NOTIFICATION_DONE",
+	"BR_FAILED_REPLY"
+};
+
+static const char *binder_command_strings[] = {
+	"BC_TRANSACTION",
+	"BC_REPLY",
+	"BC_ACQUIRE_RESULT",
+	"BC_FREE_BUFFER",
+	"BC_INCREFS",
+	"BC_ACQUIRE",
+	"BC_RELEASE",
+	"BC_DECREFS",
+	"BC_INCREFS_DONE",
+	"BC_ACQUIRE_DONE",
+	"BC_ATTEMPT_ACQUIRE",
+	"BC_REGISTER_LOOPER",
+	"BC_ENTER_LOOPER",
+	"BC_EXIT_LOOPER",
+	"BC_REQUEST_DEATH_NOTIFICATION",
+	"BC_CLEAR_DEATH_NOTIFICATION",
+	"BC_DEAD_BINDER_DONE"
+};
+
+static const char *binder_objstat_strings[] = {
+	"proc",
+	"thread",
+	"node",
+	"ref",
+	"death",
+	"transaction",
+	"transaction_complete"
+};
+
+static void print_binder_stats(struct seq_file *m, const char *prefix,
+			       struct binder_stats *stats)
+{
+	int i;
+
+	BUILD_BUG_ON(ARRAY_SIZE(stats->bc) !=
+		     ARRAY_SIZE(binder_command_strings));
+	for (i = 0; i < ARRAY_SIZE(stats->bc); i++) {
+		if (stats->bc[i])
+			seq_printf(m, "%s%s: %d\n", prefix,
+				   binder_command_strings[i], stats->bc[i]);
+	}
+
+	BUILD_BUG_ON(ARRAY_SIZE(stats->br) !=
+		     ARRAY_SIZE(binder_return_strings));
+	for (i = 0; i < ARRAY_SIZE(stats->br); i++) {
+		if (stats->br[i])
+			seq_printf(m, "%s%s: %d\n", prefix,
+				   binder_return_strings[i], stats->br[i]);
+	}
+
+	BUILD_BUG_ON(ARRAY_SIZE(stats->obj_created) !=
+		     ARRAY_SIZE(binder_objstat_strings));
+	BUILD_BUG_ON(ARRAY_SIZE(stats->obj_created) !=
+		     ARRAY_SIZE(stats->obj_deleted));
+	for (i = 0; i < ARRAY_SIZE(stats->obj_created); i++) {
+		if (stats->obj_created[i] || stats->obj_deleted[i])
+			seq_printf(m, "%s%s: active %d total %d\n", prefix,
+				binder_objstat_strings[i],
+				stats->obj_created[i] - stats->obj_deleted[i],
+				stats->obj_created[i]);
+	}
+}
+
+static void print_binder_proc_stats(struct seq_file *m,
+				    struct binder_proc *proc)
+{
+	struct binder_work *w;
+	struct rb_node *n;
+	int count, strong, weak;
+
+	seq_printf(m, "proc %d\n", proc->pid);
+	count = 0;
+	for (n = rb_first(&proc->threads); n != NULL; n = rb_next(n))
+		count++;
+	seq_printf(m, "  threads: %d\n", count);
+	seq_printf(m, "  requested threads: %d+%d/%d\n"
+			"  ready threads %d\n"
+			"  free async space %zd\n", proc->requested_threads,
+			proc->requested_threads_started, proc->max_threads,
+			proc->ready_threads, proc->free_async_space);
+	count = 0;
+	for (n = rb_first(&proc->nodes); n != NULL; n = rb_next(n))
+		count++;
+	seq_printf(m, "  nodes: %d\n", count);
+	count = 0;
+	strong = 0;
+	weak = 0;
+	for (n = rb_first(&proc->refs_by_desc); n != NULL; n = rb_next(n)) {
+		struct binder_ref *ref = rb_entry(n, struct binder_ref,
+						  rb_node_desc);
+		count++;
+		strong += ref->strong;
+		weak += ref->weak;
+	}
+	seq_printf(m, "  refs: %d s %d w %d\n", count, strong, weak);
+
+	count = 0;
+	for (n = rb_first(&proc->allocated_buffers); n != NULL; n = rb_next(n))
+		count++;
+	seq_printf(m, "  buffers: %d\n", count);
+
+	count = 0;
+	list_for_each_entry(w, &proc->todo, entry) {
+		switch (w->type) {
+		case BINDER_WORK_TRANSACTION:
+			count++;
+			break;
+		default:
+			break;
+		}
+	}
+	seq_printf(m, "  pending transactions: %d\n", count);
+
+	print_binder_stats(m, "  ", &proc->stats);
+}
+
+
+static int binder_state_show(struct seq_file *m, void *unused)
+{
+	struct binder_proc *proc;
+	struct hlist_node *pos;
+	struct binder_node *node;
+	int do_lock = !binder_debug_no_lock;
+
+	if (do_lock)
+		mutex_lock(&binder_lock);
+
+	seq_puts(m, "binder state:\n");
+
+	if (!hlist_empty(&binder_dead_nodes))
+		seq_puts(m, "dead nodes:\n");
+	hlist_for_each_entry(node, pos, &binder_dead_nodes, dead_node)
+		print_binder_node(m, node);
+
+	hlist_for_each_entry(proc, pos, &binder_procs, proc_node)
+		print_binder_proc(m, proc, 1);
+	if (do_lock)
+		mutex_unlock(&binder_lock);
+	return 0;
+}
+
+static int binder_stats_show(struct seq_file *m, void *unused)
+{
+	struct binder_proc *proc;
+	struct hlist_node *pos;
+	int do_lock = !binder_debug_no_lock;
+
+	if (do_lock)
+		mutex_lock(&binder_lock);
+
+	seq_puts(m, "binder stats:\n");
+
+	print_binder_stats(m, "", &binder_stats);
+
+	hlist_for_each_entry(proc, pos, &binder_procs, proc_node)
+		print_binder_proc_stats(m, proc);
+	if (do_lock)
+		mutex_unlock(&binder_lock);
+	return 0;
+}
+
+static int binder_transactions_show(struct seq_file *m, void *unused)
+{
+	struct binder_proc *proc;
+	struct hlist_node *pos;
+	int do_lock = !binder_debug_no_lock;
+
+	if (do_lock)
+		mutex_lock(&binder_lock);
+
+	seq_puts(m, "binder transactions:\n");
+	hlist_for_each_entry(proc, pos, &binder_procs, proc_node)
+		print_binder_proc(m, proc, 0);
+	if (do_lock)
+		mutex_unlock(&binder_lock);
+	return 0;
+}
+
+static int binder_proc_show(struct seq_file *m, void *unused)
+{
+	struct binder_proc *proc = m->private;
+	int do_lock = !binder_debug_no_lock;
+
+	if (do_lock)
+		mutex_lock(&binder_lock);
+	seq_puts(m, "binder proc state:\n");
+	print_binder_proc(m, proc, 1);
+	if (do_lock)
+		mutex_unlock(&binder_lock);
+	return 0;
+}
+
+static void print_binder_transaction_log_entry(struct seq_file *m,
+					struct binder_transaction_log_entry *e)
+{
+	seq_printf(m,
+		   "%d: %s from %d:%d to %d:%d node %d handle %d size %d:%d\n",
+		   e->debug_id, (e->call_type == 2) ? "reply" :
+		   ((e->call_type == 1) ? "async" : "call "), e->from_proc,
+		   e->from_thread, e->to_proc, e->to_thread, e->to_node,
+		   e->target_handle, e->data_size, e->offsets_size);
+}
+
+static int binder_transaction_log_show(struct seq_file *m, void *unused)
+{
+	struct binder_transaction_log *log = m->private;
+	int i;
+
+	if (log->full) {
+		for (i = log->next; i < ARRAY_SIZE(log->entry); i++)
+			print_binder_transaction_log_entry(m, &log->entry[i]);
+	}
+	for (i = 0; i < log->next; i++)
+		print_binder_transaction_log_entry(m, &log->entry[i]);
+	return 0;
+}
+
+static const struct file_operations binder_fops = {
+	.owner = THIS_MODULE,
+	.poll = binder_poll,
+	.unlocked_ioctl = binder_ioctl,
+	.mmap = binder_mmap,
+	.open = binder_open,
+	.flush = binder_flush,
+	.release = binder_release,
+};
+
+static struct miscdevice binder_miscdev = {
+	.minor = MISC_DYNAMIC_MINOR,
+	.name = "binder",
+	.fops = &binder_fops
+};
+
+BINDER_DEBUG_ENTRY(state);
+BINDER_DEBUG_ENTRY(stats);
+BINDER_DEBUG_ENTRY(transactions);
+BINDER_DEBUG_ENTRY(transaction_log);
+
+static int __init binder_init(void)
+{
+	int ret;
+
+	binder_deferred_workqueue = create_singlethread_workqueue("binder");
+	if (!binder_deferred_workqueue)
+		return -ENOMEM;
+
+	binder_debugfs_dir_entry_root = debugfs_create_dir("binder", NULL);
+	if (binder_debugfs_dir_entry_root)
+		binder_debugfs_dir_entry_proc = debugfs_create_dir("proc",
+						 binder_debugfs_dir_entry_root);
+	ret = misc_register(&binder_miscdev);
+	if (binder_debugfs_dir_entry_root) {
+		debugfs_create_file("state",
+				    S_IRUGO,
+				    binder_debugfs_dir_entry_root,
+				    NULL,
+				    &binder_state_fops);
+		debugfs_create_file("stats",
+				    S_IRUGO,
+				    binder_debugfs_dir_entry_root,
+				    NULL,
+				    &binder_stats_fops);
+		debugfs_create_file("transactions",
+				    S_IRUGO,
+				    binder_debugfs_dir_entry_root,
+				    NULL,
+				    &binder_transactions_fops);
+		debugfs_create_file("transaction_log",
+				    S_IRUGO,
+				    binder_debugfs_dir_entry_root,
+				    &binder_transaction_log,
+				    &binder_transaction_log_fops);
+		debugfs_create_file("failed_transaction_log",
+				    S_IRUGO,
+				    binder_debugfs_dir_entry_root,
+				    &binder_transaction_log_failed,
+				    &binder_transaction_log_fops);
+	}
+	return ret;
+}
+
+device_initcall(binder_init);
+
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/staging/android/binder.h b/drivers/staging/android/binder.h
new file mode 100644
index 0000000..25ab6f2
--- /dev/null
+++ b/drivers/staging/android/binder.h
@@ -0,0 +1,330 @@
+/*
+ * Copyright (C) 2008 Google, Inc.
+ *
+ * Based on, but no longer compatible with, the original
+ * OpenBinder.org binder driver interface, which is:
+ *
+ * Copyright (c) 2005 Palmsource, Inc.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#ifndef _LINUX_BINDER_H
+#define _LINUX_BINDER_H
+
+#include <linux/ioctl.h>
+
+#define B_PACK_CHARS(c1, c2, c3, c4) \
+	((((c1)<<24)) | (((c2)<<16)) | (((c3)<<8)) | (c4))
+#define B_TYPE_LARGE 0x85
+
+enum {
+	BINDER_TYPE_BINDER	= B_PACK_CHARS('s', 'b', '*', B_TYPE_LARGE),
+	BINDER_TYPE_WEAK_BINDER	= B_PACK_CHARS('w', 'b', '*', B_TYPE_LARGE),
+	BINDER_TYPE_HANDLE	= B_PACK_CHARS('s', 'h', '*', B_TYPE_LARGE),
+	BINDER_TYPE_WEAK_HANDLE	= B_PACK_CHARS('w', 'h', '*', B_TYPE_LARGE),
+	BINDER_TYPE_FD		= B_PACK_CHARS('f', 'd', '*', B_TYPE_LARGE),
+};
+
+enum {
+	FLAT_BINDER_FLAG_PRIORITY_MASK = 0xff,
+	FLAT_BINDER_FLAG_ACCEPTS_FDS = 0x100,
+};
+
+/*
+ * This is the flattened representation of a Binder object for transfer
+ * between processes.  The 'offsets' supplied as part of a binder transaction
+ * contains offsets into the data where these structures occur.  The Binder
+ * driver takes care of re-writing the structure type and data as it moves
+ * between processes.
+ */
+struct flat_binder_object {
+	/* 8 bytes for large_flat_header. */
+	unsigned long		type;
+	unsigned long		flags;
+
+	/* 8 bytes of data. */
+	union {
+		void		*binder;	/* local object */
+		signed long	handle;		/* remote object */
+	};
+
+	/* extra data associated with local object */
+	void			*cookie;
+};
+
+/*
+ * On 64-bit platforms where user code may run in 32-bits the driver must
+ * translate the buffer (and local binder) addresses apropriately.
+ */
+
+struct binder_write_read {
+	signed long	write_size;	/* bytes to write */
+	signed long	write_consumed;	/* bytes consumed by driver */
+	unsigned long	write_buffer;
+	signed long	read_size;	/* bytes to read */
+	signed long	read_consumed;	/* bytes consumed by driver */
+	unsigned long	read_buffer;
+};
+
+/* Use with BINDER_VERSION, driver fills in fields. */
+struct binder_version {
+	/* driver protocol version -- increment with incompatible change */
+	signed long	protocol_version;
+};
+
+/* This is the current protocol version. */
+#define BINDER_CURRENT_PROTOCOL_VERSION 7
+
+#define BINDER_WRITE_READ		_IOWR('b', 1, struct binder_write_read)
+#define	BINDER_SET_IDLE_TIMEOUT		_IOW('b', 3, int64_t)
+#define	BINDER_SET_MAX_THREADS		_IOW('b', 5, size_t)
+#define	BINDER_SET_IDLE_PRIORITY	_IOW('b', 6, int)
+#define	BINDER_SET_CONTEXT_MGR		_IOW('b', 7, int)
+#define	BINDER_THREAD_EXIT		_IOW('b', 8, int)
+#define BINDER_VERSION			_IOWR('b', 9, struct binder_version)
+
+/*
+ * NOTE: Two special error codes you should check for when calling
+ * in to the driver are:
+ *
+ * EINTR -- The operation has been interupted.  This should be
+ * handled by retrying the ioctl() until a different error code
+ * is returned.
+ *
+ * ECONNREFUSED -- The driver is no longer accepting operations
+ * from your process.  That is, the process is being destroyed.
+ * You should handle this by exiting from your process.  Note
+ * that once this error code is returned, all further calls to
+ * the driver from any thread will return this same code.
+ */
+
+enum transaction_flags {
+	TF_ONE_WAY	= 0x01,	/* this is a one-way call: async, no return */
+	TF_ROOT_OBJECT	= 0x04,	/* contents are the component's root object */
+	TF_STATUS_CODE	= 0x08,	/* contents are a 32-bit status code */
+	TF_ACCEPT_FDS	= 0x10,	/* allow replies with file descriptors */
+};
+
+struct binder_transaction_data {
+	/* The first two are only used for bcTRANSACTION and brTRANSACTION,
+	 * identifying the target and contents of the transaction.
+	 */
+	union {
+		size_t	handle;	/* target descriptor of command transaction */
+		void	*ptr;	/* target descriptor of return transaction */
+	} target;
+	void		*cookie;	/* target object cookie */
+	unsigned int	code;		/* transaction command */
+
+	/* General information about the transaction. */
+	unsigned int	flags;
+	pid_t		sender_pid;
+	uid_t		sender_euid;
+	size_t		data_size;	/* number of bytes of data */
+	size_t		offsets_size;	/* number of bytes of offsets */
+
+	/* If this transaction is inline, the data immediately
+	 * follows here; otherwise, it ends with a pointer to
+	 * the data buffer.
+	 */
+	union {
+		struct {
+			/* transaction data */
+			const void	*buffer;
+			/* offsets from buffer to flat_binder_object structs */
+			const void	*offsets;
+		} ptr;
+		uint8_t	buf[8];
+	} data;
+};
+
+struct binder_ptr_cookie {
+	void *ptr;
+	void *cookie;
+};
+
+struct binder_pri_desc {
+	int priority;
+	int desc;
+};
+
+struct binder_pri_ptr_cookie {
+	int priority;
+	void *ptr;
+	void *cookie;
+};
+
+enum BinderDriverReturnProtocol {
+	BR_ERROR = _IOR('r', 0, int),
+	/*
+	 * int: error code
+	 */
+
+	BR_OK = _IO('r', 1),
+	/* No parameters! */
+
+	BR_TRANSACTION = _IOR('r', 2, struct binder_transaction_data),
+	BR_REPLY = _IOR('r', 3, struct binder_transaction_data),
+	/*
+	 * binder_transaction_data: the received command.
+	 */
+
+	BR_ACQUIRE_RESULT = _IOR('r', 4, int),
+	/*
+	 * not currently supported
+	 * int: 0 if the last bcATTEMPT_ACQUIRE was not successful.
+	 * Else the remote object has acquired a primary reference.
+	 */
+
+	BR_DEAD_REPLY = _IO('r', 5),
+	/*
+	 * The target of the last transaction (either a bcTRANSACTION or
+	 * a bcATTEMPT_ACQUIRE) is no longer with us.  No parameters.
+	 */
+
+	BR_TRANSACTION_COMPLETE = _IO('r', 6),
+	/*
+	 * No parameters... always refers to the last transaction requested
+	 * (including replies).  Note that this will be sent even for
+	 * asynchronous transactions.
+	 */
+
+	BR_INCREFS = _IOR('r', 7, struct binder_ptr_cookie),
+	BR_ACQUIRE = _IOR('r', 8, struct binder_ptr_cookie),
+	BR_RELEASE = _IOR('r', 9, struct binder_ptr_cookie),
+	BR_DECREFS = _IOR('r', 10, struct binder_ptr_cookie),
+	/*
+	 * void *:	ptr to binder
+	 * void *: cookie for binder
+	 */
+
+	BR_ATTEMPT_ACQUIRE = _IOR('r', 11, struct binder_pri_ptr_cookie),
+	/*
+	 * not currently supported
+	 * int:	priority
+	 * void *: ptr to binder
+	 * void *: cookie for binder
+	 */
+
+	BR_NOOP = _IO('r', 12),
+	/*
+	 * No parameters.  Do nothing and examine the next command.  It exists
+	 * primarily so that we can replace it with a BR_SPAWN_LOOPER command.
+	 */
+
+	BR_SPAWN_LOOPER = _IO('r', 13),
+	/*
+	 * No parameters.  The driver has determined that a process has no
+	 * threads waiting to service incomming transactions.  When a process
+	 * receives this command, it must spawn a new service thread and
+	 * register it via bcENTER_LOOPER.
+	 */
+
+	BR_FINISHED = _IO('r', 14),
+	/*
+	 * not currently supported
+	 * stop threadpool thread
+	 */
+
+	BR_DEAD_BINDER = _IOR('r', 15, void *),
+	/*
+	 * void *: cookie
+	 */
+	BR_CLEAR_DEATH_NOTIFICATION_DONE = _IOR('r', 16, void *),
+	/*
+	 * void *: cookie
+	 */
+
+	BR_FAILED_REPLY = _IO('r', 17),
+	/*
+	 * The the last transaction (either a bcTRANSACTION or
+	 * a bcATTEMPT_ACQUIRE) failed (e.g. out of memory).  No parameters.
+	 */
+};
+
+enum BinderDriverCommandProtocol {
+	BC_TRANSACTION = _IOW('c', 0, struct binder_transaction_data),
+	BC_REPLY = _IOW('c', 1, struct binder_transaction_data),
+	/*
+	 * binder_transaction_data: the sent command.
+	 */
+
+	BC_ACQUIRE_RESULT = _IOW('c', 2, int),
+	/*
+	 * not currently supported
+	 * int:  0 if the last BR_ATTEMPT_ACQUIRE was not successful.
+	 * Else you have acquired a primary reference on the object.
+	 */
+
+	BC_FREE_BUFFER = _IOW('c', 3, int),
+	/*
+	 * void *: ptr to transaction data received on a read
+	 */
+
+	BC_INCREFS = _IOW('c', 4, int),
+	BC_ACQUIRE = _IOW('c', 5, int),
+	BC_RELEASE = _IOW('c', 6, int),
+	BC_DECREFS = _IOW('c', 7, int),
+	/*
+	 * int:	descriptor
+	 */
+
+	BC_INCREFS_DONE = _IOW('c', 8, struct binder_ptr_cookie),
+	BC_ACQUIRE_DONE = _IOW('c', 9, struct binder_ptr_cookie),
+	/*
+	 * void *: ptr to binder
+	 * void *: cookie for binder
+	 */
+
+	BC_ATTEMPT_ACQUIRE = _IOW('c', 10, struct binder_pri_desc),
+	/*
+	 * not currently supported
+	 * int: priority
+	 * int: descriptor
+	 */
+
+	BC_REGISTER_LOOPER = _IO('c', 11),
+	/*
+	 * No parameters.
+	 * Register a spawned looper thread with the device.
+	 */
+
+	BC_ENTER_LOOPER = _IO('c', 12),
+	BC_EXIT_LOOPER = _IO('c', 13),
+	/*
+	 * No parameters.
+	 * These two commands are sent as an application-level thread
+	 * enters and exits the binder loop, respectively.  They are
+	 * used so the binder can have an accurate count of the number
+	 * of looping threads it has available.
+	 */
+
+	BC_REQUEST_DEATH_NOTIFICATION = _IOW('c', 14, struct binder_ptr_cookie),
+	/*
+	 * void *: ptr to binder
+	 * void *: cookie
+	 */
+
+	BC_CLEAR_DEATH_NOTIFICATION = _IOW('c', 15, struct binder_ptr_cookie),
+	/*
+	 * void *: ptr to binder
+	 * void *: cookie
+	 */
+
+	BC_DEAD_BINDER_DONE = _IOW('c', 16, void *),
+	/*
+	 * void *: cookie
+	 */
+};
+
+#endif /* _LINUX_BINDER_H */
+
diff --git a/drivers/staging/android/logger.c b/drivers/staging/android/logger.c
new file mode 100644
index 0000000..ffc2d04
--- /dev/null
+++ b/drivers/staging/android/logger.c
@@ -0,0 +1,616 @@
+/*
+ * drivers/misc/logger.c
+ *
+ * A Logging Subsystem
+ *
+ * Copyright (C) 2007-2008 Google, Inc.
+ *
+ * Robert Love <rlove@google.com>
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/sched.h>
+#include <linux/module.h>
+#include <linux/fs.h>
+#include <linux/miscdevice.h>
+#include <linux/uaccess.h>
+#include <linux/poll.h>
+#include <linux/slab.h>
+#include <linux/time.h>
+#include "logger.h"
+
+#include <asm/ioctls.h>
+
+/*
+ * struct logger_log - represents a specific log, such as 'main' or 'radio'
+ *
+ * This structure lives from module insertion until module removal, so it does
+ * not need additional reference counting. The structure is protected by the
+ * mutex 'mutex'.
+ */
+struct logger_log {
+	unsigned char		*buffer;/* the ring buffer itself */
+	struct miscdevice	misc;	/* misc device representing the log */
+	wait_queue_head_t	wq;	/* wait queue for readers */
+	struct list_head	readers; /* this log's readers */
+	struct mutex		mutex;	/* mutex protecting buffer */
+	size_t			w_off;	/* current write head offset */
+	size_t			head;	/* new readers start here */
+	size_t			size;	/* size of the log */
+};
+
+/*
+ * struct logger_reader - a logging device open for reading
+ *
+ * This object lives from open to release, so we don't need additional
+ * reference counting. The structure is protected by log->mutex.
+ */
+struct logger_reader {
+	struct logger_log	*log;	/* associated log */
+	struct list_head	list;	/* entry in logger_log's list */
+	size_t			r_off;	/* current read head offset */
+};
+
+/* logger_offset - returns index 'n' into the log via (optimized) modulus */
+#define logger_offset(n)	((n) & (log->size - 1))
+
+/*
+ * file_get_log - Given a file structure, return the associated log
+ *
+ * This isn't aesthetic. We have several goals:
+ *
+ *	1) Need to quickly obtain the associated log during an I/O operation
+ *	2) Readers need to maintain state (logger_reader)
+ *	3) Writers need to be very fast (open() should be a near no-op)
+ *
+ * In the reader case, we can trivially go file->logger_reader->logger_log.
+ * For a writer, we don't want to maintain a logger_reader, so we just go
+ * file->logger_log. Thus what file->private_data points at depends on whether
+ * or not the file was opened for reading. This function hides that dirtiness.
+ */
+static inline struct logger_log *file_get_log(struct file *file)
+{
+	if (file->f_mode & FMODE_READ) {
+		struct logger_reader *reader = file->private_data;
+		return reader->log;
+	} else
+		return file->private_data;
+}
+
+/*
+ * get_entry_len - Grabs the length of the payload of the next entry starting
+ * from 'off'.
+ *
+ * Caller needs to hold log->mutex.
+ */
+static __u32 get_entry_len(struct logger_log *log, size_t off)
+{
+	__u16 val;
+
+	switch (log->size - off) {
+	case 1:
+		memcpy(&val, log->buffer + off, 1);
+		memcpy(((char *) &val) + 1, log->buffer, 1);
+		break;
+	default:
+		memcpy(&val, log->buffer + off, 2);
+	}
+
+	return sizeof(struct logger_entry) + val;
+}
+
+/*
+ * do_read_log_to_user - reads exactly 'count' bytes from 'log' into the
+ * user-space buffer 'buf'. Returns 'count' on success.
+ *
+ * Caller must hold log->mutex.
+ */
+static ssize_t do_read_log_to_user(struct logger_log *log,
+				   struct logger_reader *reader,
+				   char __user *buf,
+				   size_t count)
+{
+	size_t len;
+
+	/*
+	 * We read from the log in two disjoint operations. First, we read from
+	 * the current read head offset up to 'count' bytes or to the end of
+	 * the log, whichever comes first.
+	 */
+	len = min(count, log->size - reader->r_off);
+	if (copy_to_user(buf, log->buffer + reader->r_off, len))
+		return -EFAULT;
+
+	/*
+	 * Second, we read any remaining bytes, starting back at the head of
+	 * the log.
+	 */
+	if (count != len)
+		if (copy_to_user(buf + len, log->buffer, count - len))
+			return -EFAULT;
+
+	reader->r_off = logger_offset(reader->r_off + count);
+
+	return count;
+}
+
+/*
+ * logger_read - our log's read() method
+ *
+ * Behavior:
+ *
+ *	- O_NONBLOCK works
+ *	- If there are no log entries to read, blocks until log is written to
+ *	- Atomically reads exactly one log entry
+ *
+ * Optimal read size is LOGGER_ENTRY_MAX_LEN. Will set errno to EINVAL if read
+ * buffer is insufficient to hold next entry.
+ */
+static ssize_t logger_read(struct file *file, char __user *buf,
+			   size_t count, loff_t *pos)
+{
+	struct logger_reader *reader = file->private_data;
+	struct logger_log *log = reader->log;
+	ssize_t ret;
+	DEFINE_WAIT(wait);
+
+start:
+	while (1) {
+		prepare_to_wait(&log->wq, &wait, TASK_INTERRUPTIBLE);
+
+		mutex_lock(&log->mutex);
+		ret = (log->w_off == reader->r_off);
+		mutex_unlock(&log->mutex);
+		if (!ret)
+			break;
+
+		if (file->f_flags & O_NONBLOCK) {
+			ret = -EAGAIN;
+			break;
+		}
+
+		if (signal_pending(current)) {
+			ret = -EINTR;
+			break;
+		}
+
+		schedule();
+	}
+
+	finish_wait(&log->wq, &wait);
+	if (ret)
+		return ret;
+
+	mutex_lock(&log->mutex);
+
+	/* is there still something to read or did we race? */
+	if (unlikely(log->w_off == reader->r_off)) {
+		mutex_unlock(&log->mutex);
+		goto start;
+	}
+
+	/* get the size of the next entry */
+	ret = get_entry_len(log, reader->r_off);
+	if (count < ret) {
+		ret = -EINVAL;
+		goto out;
+	}
+
+	/* get exactly one entry from the log */
+	ret = do_read_log_to_user(log, reader, buf, ret);
+
+out:
+	mutex_unlock(&log->mutex);
+
+	return ret;
+}
+
+/*
+ * get_next_entry - return the offset of the first valid entry at least 'len'
+ * bytes after 'off'.
+ *
+ * Caller must hold log->mutex.
+ */
+static size_t get_next_entry(struct logger_log *log, size_t off, size_t len)
+{
+	size_t count = 0;
+
+	do {
+		size_t nr = get_entry_len(log, off);
+		off = logger_offset(off + nr);
+		count += nr;
+	} while (count < len);
+
+	return off;
+}
+
+/*
+ * clock_interval - is a < c < b in mod-space? Put another way, does the line
+ * from a to b cross c?
+ */
+static inline int clock_interval(size_t a, size_t b, size_t c)
+{
+	if (b < a) {
+		if (a < c || b >= c)
+			return 1;
+	} else {
+		if (a < c && b >= c)
+			return 1;
+	}
+
+	return 0;
+}
+
+/*
+ * fix_up_readers - walk the list of all readers and "fix up" any who were
+ * lapped by the writer; also do the same for the default "start head".
+ * We do this by "pulling forward" the readers and start head to the first
+ * entry after the new write head.
+ *
+ * The caller needs to hold log->mutex.
+ */
+static void fix_up_readers(struct logger_log *log, size_t len)
+{
+	size_t old = log->w_off;
+	size_t new = logger_offset(old + len);
+	struct logger_reader *reader;
+
+	if (clock_interval(old, new, log->head))
+		log->head = get_next_entry(log, log->head, len);
+
+	list_for_each_entry(reader, &log->readers, list)
+		if (clock_interval(old, new, reader->r_off))
+			reader->r_off = get_next_entry(log, reader->r_off, len);
+}
+
+/*
+ * do_write_log - writes 'len' bytes from 'buf' to 'log'
+ *
+ * The caller needs to hold log->mutex.
+ */
+static void do_write_log(struct logger_log *log, const void *buf, size_t count)
+{
+	size_t len;
+
+	len = min(count, log->size - log->w_off);
+	memcpy(log->buffer + log->w_off, buf, len);
+
+	if (count != len)
+		memcpy(log->buffer, buf + len, count - len);
+
+	log->w_off = logger_offset(log->w_off + count);
+
+}
+
+/*
+ * do_write_log_user - writes 'len' bytes from the user-space buffer 'buf' to
+ * the log 'log'
+ *
+ * The caller needs to hold log->mutex.
+ *
+ * Returns 'count' on success, negative error code on failure.
+ */
+static ssize_t do_write_log_from_user(struct logger_log *log,
+				      const void __user *buf, size_t count)
+{
+	size_t len;
+
+	len = min(count, log->size - log->w_off);
+	if (len && copy_from_user(log->buffer + log->w_off, buf, len))
+		return -EFAULT;
+
+	if (count != len)
+		if (copy_from_user(log->buffer, buf + len, count - len))
+			return -EFAULT;
+
+	log->w_off = logger_offset(log->w_off + count);
+
+	return count;
+}
+
+/*
+ * logger_aio_write - our write method, implementing support for write(),
+ * writev(), and aio_write(). Writes are our fast path, and we try to optimize
+ * them above all else.
+ */
+ssize_t logger_aio_write(struct kiocb *iocb, const struct iovec *iov,
+			 unsigned long nr_segs, loff_t ppos)
+{
+	struct logger_log *log = file_get_log(iocb->ki_filp);
+	size_t orig = log->w_off;
+	struct logger_entry header;
+	struct timespec now;
+	ssize_t ret = 0;
+
+	now = current_kernel_time();
+
+	header.pid = current->tgid;
+	header.tid = current->pid;
+	header.sec = now.tv_sec;
+	header.nsec = now.tv_nsec;
+	header.len = min_t(size_t, iocb->ki_left, LOGGER_ENTRY_MAX_PAYLOAD);
+
+	/* null writes succeed, return zero */
+	if (unlikely(!header.len))
+		return 0;
+
+	mutex_lock(&log->mutex);
+
+	/*
+	 * Fix up any readers, pulling them forward to the first readable
+	 * entry after (what will be) the new write offset. We do this now
+	 * because if we partially fail, we can end up with clobbered log
+	 * entries that encroach on readable buffer.
+	 */
+	fix_up_readers(log, sizeof(struct logger_entry) + header.len);
+
+	do_write_log(log, &header, sizeof(struct logger_entry));
+
+	while (nr_segs-- > 0) {
+		size_t len;
+		ssize_t nr;
+
+		/* figure out how much of this vector we can keep */
+		len = min_t(size_t, iov->iov_len, header.len - ret);
+
+		/* write out this segment's payload */
+		nr = do_write_log_from_user(log, iov->iov_base, len);
+		if (unlikely(nr < 0)) {
+			log->w_off = orig;
+			mutex_unlock(&log->mutex);
+			return nr;
+		}
+
+		iov++;
+		ret += nr;
+	}
+
+	mutex_unlock(&log->mutex);
+
+	/* wake up any blocked readers */
+	wake_up_interruptible(&log->wq);
+
+	return ret;
+}
+
+static struct logger_log *get_log_from_minor(int);
+
+/*
+ * logger_open - the log's open() file operation
+ *
+ * Note how near a no-op this is in the write-only case. Keep it that way!
+ */
+static int logger_open(struct inode *inode, struct file *file)
+{
+	struct logger_log *log;
+	int ret;
+
+	ret = nonseekable_open(inode, file);
+	if (ret)
+		return ret;
+
+	log = get_log_from_minor(MINOR(inode->i_rdev));
+	if (!log)
+		return -ENODEV;
+
+	if (file->f_mode & FMODE_READ) {
+		struct logger_reader *reader;
+
+		reader = kmalloc(sizeof(struct logger_reader), GFP_KERNEL);
+		if (!reader)
+			return -ENOMEM;
+
+		reader->log = log;
+		INIT_LIST_HEAD(&reader->list);
+
+		mutex_lock(&log->mutex);
+		reader->r_off = log->head;
+		list_add_tail(&reader->list, &log->readers);
+		mutex_unlock(&log->mutex);
+
+		file->private_data = reader;
+	} else
+		file->private_data = log;
+
+	return 0;
+}
+
+/*
+ * logger_release - the log's release file operation
+ *
+ * Note this is a total no-op in the write-only case. Keep it that way!
+ */
+static int logger_release(struct inode *ignored, struct file *file)
+{
+	if (file->f_mode & FMODE_READ) {
+		struct logger_reader *reader = file->private_data;
+		list_del(&reader->list);
+		kfree(reader);
+	}
+
+	return 0;
+}
+
+/*
+ * logger_poll - the log's poll file operation, for poll/select/epoll
+ *
+ * Note we always return POLLOUT, because you can always write() to the log.
+ * Note also that, strictly speaking, a return value of POLLIN does not
+ * guarantee that the log is readable without blocking, as there is a small
+ * chance that the writer can lap the reader in the interim between poll()
+ * returning and the read() request.
+ */
+static unsigned int logger_poll(struct file *file, poll_table *wait)
+{
+	struct logger_reader *reader;
+	struct logger_log *log;
+	unsigned int ret = POLLOUT | POLLWRNORM;
+
+	if (!(file->f_mode & FMODE_READ))
+		return ret;
+
+	reader = file->private_data;
+	log = reader->log;
+
+	poll_wait(file, &log->wq, wait);
+
+	mutex_lock(&log->mutex);
+	if (log->w_off != reader->r_off)
+		ret |= POLLIN | POLLRDNORM;
+	mutex_unlock(&log->mutex);
+
+	return ret;
+}
+
+static long logger_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
+{
+	struct logger_log *log = file_get_log(file);
+	struct logger_reader *reader;
+	long ret = -ENOTTY;
+
+	mutex_lock(&log->mutex);
+
+	switch (cmd) {
+	case LOGGER_GET_LOG_BUF_SIZE:
+		ret = log->size;
+		break;
+	case LOGGER_GET_LOG_LEN:
+		if (!(file->f_mode & FMODE_READ)) {
+			ret = -EBADF;
+			break;
+		}
+		reader = file->private_data;
+		if (log->w_off >= reader->r_off)
+			ret = log->w_off - reader->r_off;
+		else
+			ret = (log->size - reader->r_off) + log->w_off;
+		break;
+	case LOGGER_GET_NEXT_ENTRY_LEN:
+		if (!(file->f_mode & FMODE_READ)) {
+			ret = -EBADF;
+			break;
+		}
+		reader = file->private_data;
+		if (log->w_off != reader->r_off)
+			ret = get_entry_len(log, reader->r_off);
+		else
+			ret = 0;
+		break;
+	case LOGGER_FLUSH_LOG:
+		if (!(file->f_mode & FMODE_WRITE)) {
+			ret = -EBADF;
+			break;
+		}
+		list_for_each_entry(reader, &log->readers, list)
+			reader->r_off = log->w_off;
+		log->head = log->w_off;
+		ret = 0;
+		break;
+	}
+
+	mutex_unlock(&log->mutex);
+
+	return ret;
+}
+
+static const struct file_operations logger_fops = {
+	.owner = THIS_MODULE,
+	.read = logger_read,
+	.aio_write = logger_aio_write,
+	.poll = logger_poll,
+	.unlocked_ioctl = logger_ioctl,
+	.compat_ioctl = logger_ioctl,
+	.open = logger_open,
+	.release = logger_release,
+};
+
+/*
+ * Defines a log structure with name 'NAME' and a size of 'SIZE' bytes, which
+ * must be a power of two, greater than LOGGER_ENTRY_MAX_LEN, and less than
+ * LONG_MAX minus LOGGER_ENTRY_MAX_LEN.
+ */
+#define DEFINE_LOGGER_DEVICE(VAR, NAME, SIZE) \
+static unsigned char _buf_ ## VAR[SIZE]; \
+static struct logger_log VAR = { \
+	.buffer = _buf_ ## VAR, \
+	.misc = { \
+		.minor = MISC_DYNAMIC_MINOR, \
+		.name = NAME, \
+		.fops = &logger_fops, \
+		.parent = NULL, \
+	}, \
+	.wq = __WAIT_QUEUE_HEAD_INITIALIZER(VAR .wq), \
+	.readers = LIST_HEAD_INIT(VAR .readers), \
+	.mutex = __MUTEX_INITIALIZER(VAR .mutex), \
+	.w_off = 0, \
+	.head = 0, \
+	.size = SIZE, \
+};
+
+DEFINE_LOGGER_DEVICE(log_main, LOGGER_LOG_MAIN, 256*1024)
+DEFINE_LOGGER_DEVICE(log_events, LOGGER_LOG_EVENTS, 256*1024)
+DEFINE_LOGGER_DEVICE(log_radio, LOGGER_LOG_RADIO, 256*1024)
+DEFINE_LOGGER_DEVICE(log_system, LOGGER_LOG_SYSTEM, 256*1024)
+
+static struct logger_log *get_log_from_minor(int minor)
+{
+	if (log_main.misc.minor == minor)
+		return &log_main;
+	if (log_events.misc.minor == minor)
+		return &log_events;
+	if (log_radio.misc.minor == minor)
+		return &log_radio;
+	if (log_system.misc.minor == minor)
+		return &log_system;
+	return NULL;
+}
+
+static int __init init_log(struct logger_log *log)
+{
+	int ret;
+
+	ret = misc_register(&log->misc);
+	if (unlikely(ret)) {
+		printk(KERN_ERR "logger: failed to register misc "
+		       "device for log '%s'!\n", log->misc.name);
+		return ret;
+	}
+
+	printk(KERN_INFO "logger: created %luK log '%s'\n",
+	       (unsigned long) log->size >> 10, log->misc.name);
+
+	return 0;
+}
+
+static int __init logger_init(void)
+{
+	int ret;
+
+	ret = init_log(&log_main);
+	if (unlikely(ret))
+		goto out;
+
+	ret = init_log(&log_events);
+	if (unlikely(ret))
+		goto out;
+
+	ret = init_log(&log_radio);
+	if (unlikely(ret))
+		goto out;
+
+	ret = init_log(&log_system);
+	if (unlikely(ret))
+		goto out;
+
+out:
+	return ret;
+}
+device_initcall(logger_init);
diff --git a/drivers/staging/android/logger.h b/drivers/staging/android/logger.h
new file mode 100644
index 0000000..2cb06e9
--- /dev/null
+++ b/drivers/staging/android/logger.h
@@ -0,0 +1,49 @@
+/* include/linux/logger.h
+ *
+ * Copyright (C) 2007-2008 Google, Inc.
+ * Author: Robert Love <rlove@android.com>
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#ifndef _LINUX_LOGGER_H
+#define _LINUX_LOGGER_H
+
+#include <linux/types.h>
+#include <linux/ioctl.h>
+
+struct logger_entry {
+	__u16		len;	/* length of the payload */
+	__u16		__pad;	/* no matter what, we get 2 bytes of padding */
+	__s32		pid;	/* generating process's pid */
+	__s32		tid;	/* generating process's tid */
+	__s32		sec;	/* seconds since Epoch */
+	__s32		nsec;	/* nanoseconds */
+	char		msg[0];	/* the entry's payload */
+};
+
+#define LOGGER_LOG_RADIO	"log_radio"	/* radio-related messages */
+#define LOGGER_LOG_EVENTS	"log_events"	/* system/hardware events */
+#define LOGGER_LOG_SYSTEM	"log_system"	/* system/framework messages */
+#define LOGGER_LOG_MAIN		"log_main"	/* everything else */
+
+#define LOGGER_ENTRY_MAX_LEN		(4*1024)
+#define LOGGER_ENTRY_MAX_PAYLOAD	\
+	(LOGGER_ENTRY_MAX_LEN - sizeof(struct logger_entry))
+
+#define __LOGGERIO	0xAE
+
+#define LOGGER_GET_LOG_BUF_SIZE		_IO(__LOGGERIO, 1) /* size of log */
+#define LOGGER_GET_LOG_LEN		_IO(__LOGGERIO, 2) /* used log len */
+#define LOGGER_GET_NEXT_ENTRY_LEN	_IO(__LOGGERIO, 3) /* next entry len */
+#define LOGGER_FLUSH_LOG		_IO(__LOGGERIO, 4) /* flush log */
+
+#endif /* _LINUX_LOGGER_H */
diff --git a/drivers/staging/android/lowmemorykiller.c b/drivers/staging/android/lowmemorykiller.c
new file mode 100644
index 0000000..2d8d2b7
--- /dev/null
+++ b/drivers/staging/android/lowmemorykiller.c
@@ -0,0 +1,219 @@
+/* drivers/misc/lowmemorykiller.c
+ *
+ * The lowmemorykiller driver lets user-space specify a set of memory thresholds
+ * where processes with a range of oom_adj values will get killed. Specify the
+ * minimum oom_adj values in /sys/module/lowmemorykiller/parameters/adj and the
+ * number of free pages in /sys/module/lowmemorykiller/parameters/minfree. Both
+ * files take a comma separated list of numbers in ascending order.
+ *
+ * For example, write "0,8" to /sys/module/lowmemorykiller/parameters/adj and
+ * "1024,4096" to /sys/module/lowmemorykiller/parameters/minfree to kill
+ * processes with a oom_adj value of 8 or higher when the free memory drops
+ * below 4096 pages and kill processes with a oom_adj value of 0 or higher
+ * when the free memory drops below 1024 pages.
+ *
+ * The driver considers memory used for caches to be free, but if a large
+ * percentage of the cached memory is locked this can be very inaccurate
+ * and processes may not get killed until the normal oom killer is triggered.
+ *
+ * Copyright (C) 2007-2008 Google, Inc.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/mm.h>
+#include <linux/oom.h>
+#include <linux/sched.h>
+#include <linux/profile.h>
+#include <linux/notifier.h>
+
+static uint32_t lowmem_debug_level = 2;
+static int lowmem_adj[6] = {
+	0,
+	1,
+	6,
+	12,
+};
+static int lowmem_adj_size = 4;
+static size_t lowmem_minfree[6] = {
+	3 * 512,	/* 6MB */
+	2 * 1024,	/* 8MB */
+	4 * 1024,	/* 16MB */
+	16 * 1024,	/* 64MB */
+};
+static int lowmem_minfree_size = 4;
+
+static struct task_struct *lowmem_deathpending;
+
+#define lowmem_print(level, x...)			\
+	do {						\
+		if (lowmem_debug_level >= (level))	\
+			printk(x);			\
+	} while (0)
+
+static int
+task_notify_func(struct notifier_block *self, unsigned long val, void *data);
+
+static struct notifier_block task_nb = {
+	.notifier_call	= task_notify_func,
+};
+
+static int
+task_notify_func(struct notifier_block *self, unsigned long val, void *data)
+{
+	struct task_struct *task = data;
+	if (task == lowmem_deathpending) {
+		lowmem_deathpending = NULL;
+		task_handoff_unregister(&task_nb);
+	}
+	return NOTIFY_OK;
+}
+
+static int lowmem_shrink(struct shrinker *s, struct shrink_control *sc)
+{
+	struct task_struct *p;
+	struct task_struct *selected = NULL;
+	int rem = 0;
+	int tasksize;
+	int i;
+	int min_adj = OOM_ADJUST_MAX + 1;
+	int selected_tasksize = 0;
+	int selected_oom_adj;
+	int array_size = ARRAY_SIZE(lowmem_adj);
+	int other_free = global_page_state(NR_FREE_PAGES);
+	int other_file = global_page_state(NR_FILE_PAGES) -
+						global_page_state(NR_SHMEM);
+
+	/*
+	 * If we already have a death outstanding, then
+	 * bail out right away; indicating to vmscan
+	 * that we have nothing further to offer on
+	 * this pass.
+	 *
+	 * Note: Currently you need CONFIG_PROFILING
+	 * for this to work correctly.
+	 */
+	if (lowmem_deathpending)
+		return 0;
+
+	if (lowmem_adj_size < array_size)
+		array_size = lowmem_adj_size;
+	if (lowmem_minfree_size < array_size)
+		array_size = lowmem_minfree_size;
+	for (i = 0; i < array_size; i++) {
+		if (other_free < lowmem_minfree[i] &&
+		    other_file < lowmem_minfree[i]) {
+			min_adj = lowmem_adj[i];
+			break;
+		}
+	}
+	if (sc->nr_to_scan > 0)
+		lowmem_print(3, "lowmem_shrink %lu, %x, ofree %d %d, ma %d\n",
+				sc->nr_to_scan, sc->gfp_mask, other_free,
+				other_file, min_adj);
+	rem = global_page_state(NR_ACTIVE_ANON) +
+		global_page_state(NR_ACTIVE_FILE) +
+		global_page_state(NR_INACTIVE_ANON) +
+		global_page_state(NR_INACTIVE_FILE);
+	if (sc->nr_to_scan <= 0 || min_adj == OOM_ADJUST_MAX + 1) {
+		lowmem_print(5, "lowmem_shrink %lu, %x, return %d\n",
+			     sc->nr_to_scan, sc->gfp_mask, rem);
+		return rem;
+	}
+	selected_oom_adj = min_adj;
+
+	read_lock(&tasklist_lock);
+	for_each_process(p) {
+		struct mm_struct *mm;
+		struct signal_struct *sig;
+		int oom_adj;
+
+		task_lock(p);
+		mm = p->mm;
+		sig = p->signal;
+		if (!mm || !sig) {
+			task_unlock(p);
+			continue;
+		}
+		oom_adj = sig->oom_adj;
+		if (oom_adj < min_adj) {
+			task_unlock(p);
+			continue;
+		}
+		tasksize = get_mm_rss(mm);
+		task_unlock(p);
+		if (tasksize <= 0)
+			continue;
+		if (selected) {
+			if (oom_adj < selected_oom_adj)
+				continue;
+			if (oom_adj == selected_oom_adj &&
+			    tasksize <= selected_tasksize)
+				continue;
+		}
+		selected = p;
+		selected_tasksize = tasksize;
+		selected_oom_adj = oom_adj;
+		lowmem_print(2, "select %d (%s), adj %d, size %d, to kill\n",
+			     p->pid, p->comm, oom_adj, tasksize);
+	}
+	if (selected) {
+		lowmem_print(1, "send sigkill to %d (%s), adj %d, size %d\n",
+			     selected->pid, selected->comm,
+			     selected_oom_adj, selected_tasksize);
+		/*
+		 * If CONFIG_PROFILING is off, then task_handoff_register()
+		 * is a nop. In that case we don't want to stall the killer
+		 * by setting lowmem_deathpending.
+		 */
+#ifdef CONFIG_PROFILING
+		lowmem_deathpending = selected;
+		task_handoff_register(&task_nb);
+#endif
+		force_sig(SIGKILL, selected);
+		rem -= selected_tasksize;
+	}
+	lowmem_print(4, "lowmem_shrink %lu, %x, return %d\n",
+		     sc->nr_to_scan, sc->gfp_mask, rem);
+	read_unlock(&tasklist_lock);
+	return rem;
+}
+
+static struct shrinker lowmem_shrinker = {
+	.shrink = lowmem_shrink,
+	.seeks = DEFAULT_SEEKS * 16
+};
+
+static int __init lowmem_init(void)
+{
+	register_shrinker(&lowmem_shrinker);
+	return 0;
+}
+
+static void __exit lowmem_exit(void)
+{
+	unregister_shrinker(&lowmem_shrinker);
+}
+
+module_param_named(cost, lowmem_shrinker.seeks, int, S_IRUGO | S_IWUSR);
+module_param_array_named(adj, lowmem_adj, int, &lowmem_adj_size,
+			 S_IRUGO | S_IWUSR);
+module_param_array_named(minfree, lowmem_minfree, uint, &lowmem_minfree_size,
+			 S_IRUGO | S_IWUSR);
+module_param_named(debug_level, lowmem_debug_level, uint, S_IRUGO | S_IWUSR);
+
+module_init(lowmem_init);
+module_exit(lowmem_exit);
+
+MODULE_LICENSE("GPL");
+
diff --git a/drivers/staging/android/pmem.c b/drivers/staging/android/pmem.c
new file mode 100644
index 0000000..7d97032
--- /dev/null
+++ b/drivers/staging/android/pmem.c
@@ -0,0 +1,1345 @@
+/* pmem.c
+ *
+ * Copyright (C) 2007 Google, Inc.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include <linux/miscdevice.h>
+#include <linux/platform_device.h>
+#include <linux/fs.h>
+#include <linux/file.h>
+#include <linux/mm.h>
+#include <linux/list.h>
+#include <linux/mutex.h>
+#include <linux/debugfs.h>
+#include <linux/mempolicy.h>
+#include <linux/sched.h>
+#include <asm/io.h>
+#include <asm/uaccess.h>
+#include <asm/cacheflush.h>
+#include "android_pmem.h"
+
+#define PMEM_MAX_DEVICES 10
+#define PMEM_MAX_ORDER 128
+#define PMEM_MIN_ALLOC PAGE_SIZE
+
+#define PMEM_DEBUG 1
+
+/* indicates that a refernce to this file has been taken via get_pmem_file,
+ * the file should not be released until put_pmem_file is called */
+#define PMEM_FLAGS_BUSY 0x1
+/* indicates that this is a suballocation of a larger master range */
+#define PMEM_FLAGS_CONNECTED 0x1 << 1
+/* indicates this is a master and not a sub allocation and that it is mmaped */
+#define PMEM_FLAGS_MASTERMAP 0x1 << 2
+/* submap and unsubmap flags indicate:
+ * 00: subregion has never been mmaped
+ * 10: subregion has been mmaped, reference to the mm was taken
+ * 11: subretion has ben released, refernece to the mm still held
+ * 01: subretion has been released, reference to the mm has been released
+ */
+#define PMEM_FLAGS_SUBMAP 0x1 << 3
+#define PMEM_FLAGS_UNSUBMAP 0x1 << 4
+
+
+struct pmem_data {
+	/* in alloc mode: an index into the bitmap
+	 * in no_alloc mode: the size of the allocation */
+	int index;
+	/* see flags above for descriptions */
+	unsigned int flags;
+	/* protects this data field, if the mm_mmap sem will be held at the
+	 * same time as this sem, the mm sem must be taken first (as this is
+	 * the order for vma_open and vma_close ops */
+	struct rw_semaphore sem;
+	/* info about the mmaping process */
+	struct vm_area_struct *vma;
+	/* task struct of the mapping process */
+	struct task_struct *task;
+	/* process id of teh mapping process */
+	pid_t pid;
+	/* file descriptor of the master */
+	int master_fd;
+	/* file struct of the master */
+	struct file *master_file;
+	/* a list of currently available regions if this is a suballocation */
+	struct list_head region_list;
+	/* a linked list of data so we can access them for debugging */
+	struct list_head list;
+#if PMEM_DEBUG
+	int ref;
+#endif
+};
+
+struct pmem_bits {
+	unsigned allocated:1;		/* 1 if allocated, 0 if free */
+	unsigned order:7;		/* size of the region in pmem space */
+};
+
+struct pmem_region_node {
+	struct pmem_region region;
+	struct list_head list;
+};
+
+#define PMEM_DEBUG_MSGS 0
+#if PMEM_DEBUG_MSGS
+#define DLOG(fmt,args...) \
+	do { printk(KERN_INFO "[%s:%s:%d] "fmt, __FILE__, __func__, __LINE__, \
+		    ##args); } \
+	while (0)
+#else
+#define DLOG(x...) do {} while (0)
+#endif
+
+struct pmem_info {
+	struct miscdevice dev;
+	/* physical start address of the remaped pmem space */
+	unsigned long base;
+	/* vitual start address of the remaped pmem space */
+	unsigned char __iomem *vbase;
+	/* total size of the pmem space */
+	unsigned long size;
+	/* number of entries in the pmem space */
+	unsigned long num_entries;
+	/* pfn of the garbage page in memory */
+	unsigned long garbage_pfn;
+	/* index of the garbage page in the pmem space */
+	int garbage_index;
+	/* the bitmap for the region indicating which entries are allocated
+	 * and which are free */
+	struct pmem_bits *bitmap;
+	/* indicates the region should not be managed with an allocator */
+	unsigned no_allocator;
+	/* indicates maps of this region should be cached, if a mix of
+	 * cached and uncached is desired, set this and open the device with
+	 * O_SYNC to get an uncached region */
+	unsigned cached;
+	unsigned buffered;
+	/* in no_allocator mode the first mapper gets the whole space and sets
+	 * this flag */
+	unsigned allocated;
+	/* for debugging, creates a list of pmem file structs, the
+	 * data_list_lock should be taken before pmem_data->sem if both are
+	 * needed */
+	struct mutex data_list_lock;
+	struct list_head data_list;
+	/* pmem_sem protects the bitmap array
+	 * a write lock should be held when modifying entries in bitmap
+	 * a read lock should be held when reading data from bits or
+	 * dereferencing a pointer into bitmap
+	 *
+	 * pmem_data->sem protects the pmem data of a particular file
+	 * Many of the function that require the pmem_data->sem have a non-
+	 * locking version for when the caller is already holding that sem.
+	 *
+	 * IF YOU TAKE BOTH LOCKS TAKE THEM IN THIS ORDER:
+	 * down(pmem_data->sem) => down(bitmap_sem)
+	 */
+	struct rw_semaphore bitmap_sem;
+
+	long (*ioctl)(struct file *, unsigned int, unsigned long);
+	int (*release)(struct inode *, struct file *);
+};
+
+static struct pmem_info pmem[PMEM_MAX_DEVICES];
+static int id_count;
+
+#define PMEM_IS_FREE(id, index) !(pmem[id].bitmap[index].allocated)
+#define PMEM_ORDER(id, index) pmem[id].bitmap[index].order
+#define PMEM_BUDDY_INDEX(id, index) (index ^ (1 << PMEM_ORDER(id, index)))
+#define PMEM_NEXT_INDEX(id, index) (index + (1 << PMEM_ORDER(id, index)))
+#define PMEM_OFFSET(index) (index * PMEM_MIN_ALLOC)
+#define PMEM_START_ADDR(id, index) (PMEM_OFFSET(index) + pmem[id].base)
+#define PMEM_LEN(id, index) ((1 << PMEM_ORDER(id, index)) * PMEM_MIN_ALLOC)
+#define PMEM_END_ADDR(id, index) (PMEM_START_ADDR(id, index) + \
+	PMEM_LEN(id, index))
+#define PMEM_START_VADDR(id, index) (PMEM_OFFSET(id, index) + pmem[id].vbase)
+#define PMEM_END_VADDR(id, index) (PMEM_START_VADDR(id, index) + \
+	PMEM_LEN(id, index))
+#define PMEM_REVOKED(data) (data->flags & PMEM_FLAGS_REVOKED)
+#define PMEM_IS_PAGE_ALIGNED(addr) (!((addr) & (~PAGE_MASK)))
+#define PMEM_IS_SUBMAP(data) ((data->flags & PMEM_FLAGS_SUBMAP) && \
+	(!(data->flags & PMEM_FLAGS_UNSUBMAP)))
+
+static int pmem_release(struct inode *, struct file *);
+static int pmem_mmap(struct file *, struct vm_area_struct *);
+static int pmem_open(struct inode *, struct file *);
+static long pmem_ioctl(struct file *, unsigned int, unsigned long);
+
+struct file_operations pmem_fops = {
+	.release = pmem_release,
+	.mmap = pmem_mmap,
+	.open = pmem_open,
+	.unlocked_ioctl = pmem_ioctl,
+};
+
+static int get_id(struct file *file)
+{
+	return MINOR(file->f_dentry->d_inode->i_rdev);
+}
+
+int is_pmem_file(struct file *file)
+{
+	int id;
+
+	if (unlikely(!file || !file->f_dentry || !file->f_dentry->d_inode))
+		return 0;
+	id = get_id(file);
+	if (unlikely(id >= PMEM_MAX_DEVICES))
+		return 0;
+	if (unlikely(file->f_dentry->d_inode->i_rdev !=
+	     MKDEV(MISC_MAJOR, pmem[id].dev.minor)))
+		return 0;
+	return 1;
+}
+
+static int has_allocation(struct file *file)
+{
+	struct pmem_data *data;
+	/* check is_pmem_file first if not accessed via pmem_file_ops */
+
+	if (unlikely(!file->private_data))
+		return 0;
+	data = (struct pmem_data *)file->private_data;
+	if (unlikely(data->index < 0))
+		return 0;
+	return 1;
+}
+
+static int is_master_owner(struct file *file)
+{
+	struct file *master_file;
+	struct pmem_data *data;
+	int put_needed, ret = 0;
+
+	if (!is_pmem_file(file) || !has_allocation(file))
+		return 0;
+	data = (struct pmem_data *)file->private_data;
+	if (PMEM_FLAGS_MASTERMAP & data->flags)
+		return 1;
+	master_file = fget_light(data->master_fd, &put_needed);
+	if (master_file && data->master_file == master_file)
+		ret = 1;
+	fput_light(master_file, put_needed);
+	return ret;
+}
+
+static int pmem_free(int id, int index)
+{
+	/* caller should hold the write lock on pmem_sem! */
+	int buddy, curr = index;
+	DLOG("index %d\n", index);
+
+	if (pmem[id].no_allocator) {
+		pmem[id].allocated = 0;
+		return 0;
+	}
+	/* clean up the bitmap, merging any buddies */
+	pmem[id].bitmap[curr].allocated = 0;
+	/* find a slots buddy Buddy# = Slot# ^ (1 << order)
+	 * if the buddy is also free merge them
+	 * repeat until the buddy is not free or end of the bitmap is reached
+	 */
+	do {
+		buddy = PMEM_BUDDY_INDEX(id, curr);
+		if (PMEM_IS_FREE(id, buddy) &&
+				PMEM_ORDER(id, buddy) == PMEM_ORDER(id, curr)) {
+			PMEM_ORDER(id, buddy)++;
+			PMEM_ORDER(id, curr)++;
+			curr = min(buddy, curr);
+		} else {
+			break;
+		}
+	} while (curr < pmem[id].num_entries);
+
+	return 0;
+}
+
+static void pmem_revoke(struct file *file, struct pmem_data *data);
+
+static int pmem_release(struct inode *inode, struct file *file)
+{
+	struct pmem_data *data = (struct pmem_data *)file->private_data;
+	struct pmem_region_node *region_node;
+	struct list_head *elt, *elt2;
+	int id = get_id(file), ret = 0;
+
+
+	mutex_lock(&pmem[id].data_list_lock);
+	/* if this file is a master, revoke all the memory in the connected
+	 *  files */
+	if (PMEM_FLAGS_MASTERMAP & data->flags) {
+		struct pmem_data *sub_data;
+		list_for_each(elt, &pmem[id].data_list) {
+			sub_data = list_entry(elt, struct pmem_data, list);
+			down_read(&sub_data->sem);
+			if (PMEM_IS_SUBMAP(sub_data) &&
+			    file == sub_data->master_file) {
+				up_read(&sub_data->sem);
+				pmem_revoke(file, sub_data);
+			}  else
+				up_read(&sub_data->sem);
+		}
+	}
+	list_del(&data->list);
+	mutex_unlock(&pmem[id].data_list_lock);
+
+
+	down_write(&data->sem);
+
+	/* if its not a conencted file and it has an allocation, free it */
+	if (!(PMEM_FLAGS_CONNECTED & data->flags) && has_allocation(file)) {
+		down_write(&pmem[id].bitmap_sem);
+		ret = pmem_free(id, data->index);
+		up_write(&pmem[id].bitmap_sem);
+	}
+
+	/* if this file is a submap (mapped, connected file), downref the
+	 * task struct */
+	if (PMEM_FLAGS_SUBMAP & data->flags)
+		if (data->task) {
+			put_task_struct(data->task);
+			data->task = NULL;
+		}
+
+	file->private_data = NULL;
+
+	list_for_each_safe(elt, elt2, &data->region_list) {
+		region_node = list_entry(elt, struct pmem_region_node, list);
+		list_del(elt);
+		kfree(region_node);
+	}
+	BUG_ON(!list_empty(&data->region_list));
+
+	up_write(&data->sem);
+	kfree(data);
+	if (pmem[id].release)
+		ret = pmem[id].release(inode, file);
+
+	return ret;
+}
+
+static int pmem_open(struct inode *inode, struct file *file)
+{
+	struct pmem_data *data;
+	int id = get_id(file);
+	int ret = 0;
+
+	DLOG("current %u file %p(%d)\n", current->pid, file, file_count(file));
+	/* setup file->private_data to indicate its unmapped */
+	/*  you can only open a pmem device one time */
+	if (file->private_data != NULL)
+		return -1;
+	data = kmalloc(sizeof(struct pmem_data), GFP_KERNEL);
+	if (!data) {
+		printk("pmem: unable to allocate memory for pmem metadata.");
+		return -1;
+	}
+	data->flags = 0;
+	data->index = -1;
+	data->task = NULL;
+	data->vma = NULL;
+	data->pid = 0;
+	data->master_file = NULL;
+#if PMEM_DEBUG
+	data->ref = 0;
+#endif
+	INIT_LIST_HEAD(&data->region_list);
+	init_rwsem(&data->sem);
+
+	file->private_data = data;
+	INIT_LIST_HEAD(&data->list);
+
+	mutex_lock(&pmem[id].data_list_lock);
+	list_add(&data->list, &pmem[id].data_list);
+	mutex_unlock(&pmem[id].data_list_lock);
+	return ret;
+}
+
+static unsigned long pmem_order(unsigned long len)
+{
+	int i;
+
+	len = (len + PMEM_MIN_ALLOC - 1)/PMEM_MIN_ALLOC;
+	len--;
+	for (i = 0; i < sizeof(len)*8; i++)
+		if (len >> i == 0)
+			break;
+	return i;
+}
+
+static int pmem_allocate(int id, unsigned long len)
+{
+	/* caller should hold the write lock on pmem_sem! */
+	/* return the corresponding pdata[] entry */
+	int curr = 0;
+	int end = pmem[id].num_entries;
+	int best_fit = -1;
+	unsigned long order = pmem_order(len);
+
+	if (pmem[id].no_allocator) {
+		DLOG("no allocator");
+		if ((len > pmem[id].size) || pmem[id].allocated)
+			return -1;
+		pmem[id].allocated = 1;
+		return len;
+	}
+
+	if (order > PMEM_MAX_ORDER)
+		return -1;
+	DLOG("order %lx\n", order);
+
+	/* look through the bitmap:
+	 * 	if you find a free slot of the correct order use it
+	 * 	otherwise, use the best fit (smallest with size > order) slot
+	 */
+	while (curr < end) {
+		if (PMEM_IS_FREE(id, curr)) {
+			if (PMEM_ORDER(id, curr) == (unsigned char)order) {
+				/* set the not free bit and clear others */
+				best_fit = curr;
+				break;
+			}
+			if (PMEM_ORDER(id, curr) > (unsigned char)order &&
+			    (best_fit < 0 ||
+			     PMEM_ORDER(id, curr) < PMEM_ORDER(id, best_fit)))
+				best_fit = curr;
+		}
+		curr = PMEM_NEXT_INDEX(id, curr);
+	}
+
+	/* if best_fit < 0, there are no suitable slots,
+	 * return an error
+	 */
+	if (best_fit < 0) {
+		printk("pmem: no space left to allocate!\n");
+		return -1;
+	}
+
+	/* now partition the best fit:
+	 * 	split the slot into 2 buddies of order - 1
+	 * 	repeat until the slot is of the correct order
+	 */
+	while (PMEM_ORDER(id, best_fit) > (unsigned char)order) {
+		int buddy;
+		PMEM_ORDER(id, best_fit) -= 1;
+		buddy = PMEM_BUDDY_INDEX(id, best_fit);
+		PMEM_ORDER(id, buddy) = PMEM_ORDER(id, best_fit);
+	}
+	pmem[id].bitmap[best_fit].allocated = 1;
+	return best_fit;
+}
+
+static pgprot_t pmem_access_prot(struct file *file, pgprot_t vma_prot)
+{
+	int id = get_id(file);
+#ifdef pgprot_noncached
+	if (pmem[id].cached == 0 || file->f_flags & O_SYNC)
+		return pgprot_noncached(vma_prot);
+#endif
+#ifdef pgprot_ext_buffered
+	else if (pmem[id].buffered)
+		return pgprot_ext_buffered(vma_prot);
+#endif
+	return vma_prot;
+}
+
+static unsigned long pmem_start_addr(int id, struct pmem_data *data)
+{
+	if (pmem[id].no_allocator)
+		return PMEM_START_ADDR(id, 0);
+	else
+		return PMEM_START_ADDR(id, data->index);
+
+}
+
+static void *pmem_start_vaddr(int id, struct pmem_data *data)
+{
+	return pmem_start_addr(id, data) - pmem[id].base + pmem[id].vbase;
+}
+
+static unsigned long pmem_len(int id, struct pmem_data *data)
+{
+	if (pmem[id].no_allocator)
+		return data->index;
+	else
+		return PMEM_LEN(id, data->index);
+}
+
+static int pmem_map_garbage(int id, struct vm_area_struct *vma,
+			    struct pmem_data *data, unsigned long offset,
+			    unsigned long len)
+{
+	int i, garbage_pages = len >> PAGE_SHIFT;
+
+	vma->vm_flags |= VM_IO | VM_RESERVED | VM_PFNMAP | VM_SHARED | VM_WRITE;
+	for (i = 0; i < garbage_pages; i++) {
+		if (vm_insert_pfn(vma, vma->vm_start + offset + (i * PAGE_SIZE),
+		    pmem[id].garbage_pfn))
+			return -EAGAIN;
+	}
+	return 0;
+}
+
+static int pmem_unmap_pfn_range(int id, struct vm_area_struct *vma,
+				struct pmem_data *data, unsigned long offset,
+				unsigned long len)
+{
+	int garbage_pages;
+	DLOG("unmap offset %lx len %lx\n", offset, len);
+
+	BUG_ON(!PMEM_IS_PAGE_ALIGNED(len));
+
+	garbage_pages = len >> PAGE_SHIFT;
+	zap_page_range(vma, vma->vm_start + offset, len, NULL);
+	pmem_map_garbage(id, vma, data, offset, len);
+	return 0;
+}
+
+static int pmem_map_pfn_range(int id, struct vm_area_struct *vma,
+			      struct pmem_data *data, unsigned long offset,
+			      unsigned long len)
+{
+	DLOG("map offset %lx len %lx\n", offset, len);
+	BUG_ON(!PMEM_IS_PAGE_ALIGNED(vma->vm_start));
+	BUG_ON(!PMEM_IS_PAGE_ALIGNED(vma->vm_end));
+	BUG_ON(!PMEM_IS_PAGE_ALIGNED(len));
+	BUG_ON(!PMEM_IS_PAGE_ALIGNED(offset));
+
+	if (io_remap_pfn_range(vma, vma->vm_start + offset,
+		(pmem_start_addr(id, data) + offset) >> PAGE_SHIFT,
+		len, vma->vm_page_prot)) {
+		return -EAGAIN;
+	}
+	return 0;
+}
+
+static int pmem_remap_pfn_range(int id, struct vm_area_struct *vma,
+			      struct pmem_data *data, unsigned long offset,
+			      unsigned long len)
+{
+	/* hold the mm semp for the vma you are modifying when you call this */
+	BUG_ON(!vma);
+	zap_page_range(vma, vma->vm_start + offset, len, NULL);
+	return pmem_map_pfn_range(id, vma, data, offset, len);
+}
+
+static void pmem_vma_open(struct vm_area_struct *vma)
+{
+	struct file *file = vma->vm_file;
+	struct pmem_data *data = file->private_data;
+	int id = get_id(file);
+	/* this should never be called as we don't support copying pmem
+	 * ranges via fork */
+	BUG_ON(!has_allocation(file));
+	down_write(&data->sem);
+	/* remap the garbage pages, forkers don't get access to the data */
+	pmem_unmap_pfn_range(id, vma, data, 0, vma->vm_start - vma->vm_end);
+	up_write(&data->sem);
+}
+
+static void pmem_vma_close(struct vm_area_struct *vma)
+{
+	struct file *file = vma->vm_file;
+	struct pmem_data *data = file->private_data;
+
+	DLOG("current %u ppid %u file %p count %d\n", current->pid,
+	     current->parent->pid, file, file_count(file));
+	if (unlikely(!is_pmem_file(file) || !has_allocation(file))) {
+		printk(KERN_WARNING "pmem: something is very wrong, you are "
+		       "closing a vm backing an allocation that doesn't "
+		       "exist!\n");
+		return;
+	}
+	down_write(&data->sem);
+	if (data->vma == vma) {
+		data->vma = NULL;
+		if ((data->flags & PMEM_FLAGS_CONNECTED) &&
+		    (data->flags & PMEM_FLAGS_SUBMAP))
+			data->flags |= PMEM_FLAGS_UNSUBMAP;
+	}
+	/* the kernel is going to free this vma now anyway */
+	up_write(&data->sem);
+}
+
+static struct vm_operations_struct vm_ops = {
+	.open = pmem_vma_open,
+	.close = pmem_vma_close,
+};
+
+static int pmem_mmap(struct file *file, struct vm_area_struct *vma)
+{
+	struct pmem_data *data;
+	int index;
+	unsigned long vma_size =  vma->vm_end - vma->vm_start;
+	int ret = 0, id = get_id(file);
+
+	if (vma->vm_pgoff || !PMEM_IS_PAGE_ALIGNED(vma_size)) {
+#if PMEM_DEBUG
+		printk(KERN_ERR "pmem: mmaps must be at offset zero, aligned"
+				" and a multiple of pages_size.\n");
+#endif
+		return -EINVAL;
+	}
+
+	data = (struct pmem_data *)file->private_data;
+	down_write(&data->sem);
+	/* check this file isn't already mmaped, for submaps check this file
+	 * has never been mmaped */
+	if ((data->flags & PMEM_FLAGS_SUBMAP) ||
+	    (data->flags & PMEM_FLAGS_UNSUBMAP)) {
+#if PMEM_DEBUG
+		printk(KERN_ERR "pmem: you can only mmap a pmem file once, "
+		       "this file is already mmaped. %x\n", data->flags);
+#endif
+		ret = -EINVAL;
+		goto error;
+	}
+	/* if file->private_data == unalloced, alloc*/
+	if (data && data->index == -1) {
+		down_write(&pmem[id].bitmap_sem);
+		index = pmem_allocate(id, vma->vm_end - vma->vm_start);
+		up_write(&pmem[id].bitmap_sem);
+		data->index = index;
+	}
+	/* either no space was available or an error occured */
+	if (!has_allocation(file)) {
+		ret = -EINVAL;
+		printk("pmem: could not find allocation for map.\n");
+		goto error;
+	}
+
+	if (pmem_len(id, data) < vma_size) {
+#if PMEM_DEBUG
+		printk(KERN_WARNING "pmem: mmap size [%lu] does not match"
+		       "size of backing region [%lu].\n", vma_size,
+		       pmem_len(id, data));
+#endif
+		ret = -EINVAL;
+		goto error;
+	}
+
+	vma->vm_pgoff = pmem_start_addr(id, data) >> PAGE_SHIFT;
+	vma->vm_page_prot = pmem_access_prot(file, vma->vm_page_prot);
+
+	if (data->flags & PMEM_FLAGS_CONNECTED) {
+		struct pmem_region_node *region_node;
+		struct list_head *elt;
+		if (pmem_map_garbage(id, vma, data, 0, vma_size)) {
+			printk("pmem: mmap failed in kernel!\n");
+			ret = -EAGAIN;
+			goto error;
+		}
+		list_for_each(elt, &data->region_list) {
+			region_node = list_entry(elt, struct pmem_region_node,
+						 list);
+			DLOG("remapping file: %p %lx %lx\n", file,
+				region_node->region.offset,
+				region_node->region.len);
+			if (pmem_remap_pfn_range(id, vma, data,
+						 region_node->region.offset,
+						 region_node->region.len)) {
+				ret = -EAGAIN;
+				goto error;
+			}
+		}
+		data->flags |= PMEM_FLAGS_SUBMAP;
+		get_task_struct(current->group_leader);
+		data->task = current->group_leader;
+		data->vma = vma;
+#if PMEM_DEBUG
+		data->pid = current->pid;
+#endif
+		DLOG("submmapped file %p vma %p pid %u\n", file, vma,
+		     current->pid);
+	} else {
+		if (pmem_map_pfn_range(id, vma, data, 0, vma_size)) {
+			printk(KERN_INFO "pmem: mmap failed in kernel!\n");
+			ret = -EAGAIN;
+			goto error;
+		}
+		data->flags |= PMEM_FLAGS_MASTERMAP;
+		data->pid = current->pid;
+	}
+	vma->vm_ops = &vm_ops;
+error:
+	up_write(&data->sem);
+	return ret;
+}
+
+/* the following are the api for accessing pmem regions by other drivers
+ * from inside the kernel */
+int get_pmem_user_addr(struct file *file, unsigned long *start,
+		   unsigned long *len)
+{
+	struct pmem_data *data;
+	if (!is_pmem_file(file) || !has_allocation(file)) {
+#if PMEM_DEBUG
+		printk(KERN_INFO "pmem: requested pmem data from invalid"
+				  "file.\n");
+#endif
+		return -1;
+	}
+	data = (struct pmem_data *)file->private_data;
+	down_read(&data->sem);
+	if (data->vma) {
+		*start = data->vma->vm_start;
+		*len = data->vma->vm_end - data->vma->vm_start;
+	} else {
+		*start = 0;
+		*len = 0;
+	}
+	up_read(&data->sem);
+	return 0;
+}
+
+int get_pmem_addr(struct file *file, unsigned long *start,
+		  unsigned long *vstart, unsigned long *len)
+{
+	struct pmem_data *data;
+	int id;
+
+	if (!is_pmem_file(file) || !has_allocation(file)) {
+		return -1;
+	}
+
+	data = (struct pmem_data *)file->private_data;
+	if (data->index == -1) {
+#if PMEM_DEBUG
+		printk(KERN_INFO "pmem: requested pmem data from file with no "
+		       "allocation.\n");
+		return -1;
+#endif
+	}
+	id = get_id(file);
+
+	down_read(&data->sem);
+	*start = pmem_start_addr(id, data);
+	*len = pmem_len(id, data);
+	*vstart = (unsigned long)pmem_start_vaddr(id, data);
+	up_read(&data->sem);
+#if PMEM_DEBUG
+	down_write(&data->sem);
+	data->ref++;
+	up_write(&data->sem);
+#endif
+	return 0;
+}
+
+int get_pmem_file(int fd, unsigned long *start, unsigned long *vstart,
+		  unsigned long *len, struct file **filp)
+{
+	struct file *file;
+
+	file = fget(fd);
+	if (unlikely(file == NULL)) {
+		printk(KERN_INFO "pmem: requested data from file descriptor "
+		       "that doesn't exist.");
+		return -1;
+	}
+
+	if (get_pmem_addr(file, start, vstart, len))
+		goto end;
+
+	if (filp)
+		*filp = file;
+	return 0;
+end:
+	fput(file);
+	return -1;
+}
+
+void put_pmem_file(struct file *file)
+{
+	struct pmem_data *data;
+	int id;
+
+	if (!is_pmem_file(file))
+		return;
+	id = get_id(file);
+	data = (struct pmem_data *)file->private_data;
+#if PMEM_DEBUG
+	down_write(&data->sem);
+	if (data->ref == 0) {
+		printk("pmem: pmem_put > pmem_get %s (pid %d)\n",
+		       pmem[id].dev.name, data->pid);
+		BUG();
+	}
+	data->ref--;
+	up_write(&data->sem);
+#endif
+	fput(file);
+}
+
+void flush_pmem_file(struct file *file, unsigned long offset, unsigned long len)
+{
+	struct pmem_data *data;
+	int id;
+	void *vaddr;
+	struct pmem_region_node *region_node;
+	struct list_head *elt;
+	void *flush_start, *flush_end;
+
+	if (!is_pmem_file(file) || !has_allocation(file)) {
+		return;
+	}
+
+	id = get_id(file);
+	data = (struct pmem_data *)file->private_data;
+	if (!pmem[id].cached || file->f_flags & O_SYNC)
+		return;
+
+	down_read(&data->sem);
+	vaddr = pmem_start_vaddr(id, data);
+	/* if this isn't a submmapped file, flush the whole thing */
+	if (unlikely(!(data->flags & PMEM_FLAGS_CONNECTED))) {
+		dmac_flush_range(vaddr, vaddr + pmem_len(id, data));
+		goto end;
+	}
+	/* otherwise, flush the region of the file we are drawing */
+	list_for_each(elt, &data->region_list) {
+		region_node = list_entry(elt, struct pmem_region_node, list);
+		if ((offset >= region_node->region.offset) &&
+		    ((offset + len) <= (region_node->region.offset +
+			region_node->region.len))) {
+			flush_start = vaddr + region_node->region.offset;
+			flush_end = flush_start + region_node->region.len;
+			dmac_flush_range(flush_start, flush_end);
+			break;
+		}
+	}
+end:
+	up_read(&data->sem);
+}
+
+static int pmem_connect(unsigned long connect, struct file *file)
+{
+	struct pmem_data *data = (struct pmem_data *)file->private_data;
+	struct pmem_data *src_data;
+	struct file *src_file;
+	int ret = 0, put_needed;
+
+	down_write(&data->sem);
+	/* retrieve the src file and check it is a pmem file with an alloc */
+	src_file = fget_light(connect, &put_needed);
+	DLOG("connect %p to %p\n", file, src_file);
+	if (!src_file) {
+		printk("pmem: src file not found!\n");
+		ret = -EINVAL;
+		goto err_no_file;
+	}
+	if (unlikely(!is_pmem_file(src_file) || !has_allocation(src_file))) {
+		printk(KERN_INFO "pmem: src file is not a pmem file or has no "
+		       "alloc!\n");
+		ret = -EINVAL;
+		goto err_bad_file;
+	}
+	src_data = (struct pmem_data *)src_file->private_data;
+
+	if (has_allocation(file) && (data->index != src_data->index)) {
+		printk("pmem: file is already mapped but doesn't match this"
+		       " src_file!\n");
+		ret = -EINVAL;
+		goto err_bad_file;
+	}
+	data->index = src_data->index;
+	data->flags |= PMEM_FLAGS_CONNECTED;
+	data->master_fd = connect;
+	data->master_file = src_file;
+
+err_bad_file:
+	fput_light(src_file, put_needed);
+err_no_file:
+	up_write(&data->sem);
+	return ret;
+}
+
+static void pmem_unlock_data_and_mm(struct pmem_data *data,
+				    struct mm_struct *mm)
+{
+	up_write(&data->sem);
+	if (mm != NULL) {
+		up_write(&mm->mmap_sem);
+		mmput(mm);
+	}
+}
+
+static int pmem_lock_data_and_mm(struct file *file, struct pmem_data *data,
+				 struct mm_struct **locked_mm)
+{
+	int ret = 0;
+	struct mm_struct *mm = NULL;
+	*locked_mm = NULL;
+lock_mm:
+	down_read(&data->sem);
+	if (PMEM_IS_SUBMAP(data)) {
+		mm = get_task_mm(data->task);
+		if (!mm) {
+#if PMEM_DEBUG
+			printk("pmem: can't remap task is gone!\n");
+#endif
+			up_read(&data->sem);
+			return -1;
+		}
+	}
+	up_read(&data->sem);
+
+	if (mm)
+		down_write(&mm->mmap_sem);
+
+	down_write(&data->sem);
+	/* check that the file didn't get mmaped before we could take the
+	 * data sem, this should be safe b/c you can only submap each file
+	 * once */
+	if (PMEM_IS_SUBMAP(data) && !mm) {
+		pmem_unlock_data_and_mm(data, mm);
+		up_write(&data->sem);
+		goto lock_mm;
+	}
+	/* now check that vma.mm is still there, it could have been
+	 * deleted by vma_close before we could get the data->sem */
+	if ((data->flags & PMEM_FLAGS_UNSUBMAP) && (mm != NULL)) {
+		/* might as well release this */
+		if (data->flags & PMEM_FLAGS_SUBMAP) {
+			put_task_struct(data->task);
+			data->task = NULL;
+			/* lower the submap flag to show the mm is gone */
+			data->flags &= ~(PMEM_FLAGS_SUBMAP);
+		}
+		pmem_unlock_data_and_mm(data, mm);
+		return -1;
+	}
+	*locked_mm = mm;
+	return ret;
+}
+
+int pmem_remap(struct pmem_region *region, struct file *file,
+		      unsigned operation)
+{
+	int ret;
+	struct pmem_region_node *region_node;
+	struct mm_struct *mm = NULL;
+	struct list_head *elt, *elt2;
+	int id = get_id(file);
+	struct pmem_data *data = (struct pmem_data *)file->private_data;
+
+	/* pmem region must be aligned on a page boundry */
+	if (unlikely(!PMEM_IS_PAGE_ALIGNED(region->offset) ||
+		 !PMEM_IS_PAGE_ALIGNED(region->len))) {
+#if PMEM_DEBUG
+		printk("pmem: request for unaligned pmem suballocation "
+		       "%lx %lx\n", region->offset, region->len);
+#endif
+		return -EINVAL;
+	}
+
+	/* if userspace requests a region of len 0, there's nothing to do */
+	if (region->len == 0)
+		return 0;
+
+	/* lock the mm and data */
+	ret = pmem_lock_data_and_mm(file, data, &mm);
+	if (ret)
+		return 0;
+
+	/* only the owner of the master file can remap the client fds
+	 * that back in it */
+	if (!is_master_owner(file)) {
+#if PMEM_DEBUG
+		printk("pmem: remap requested from non-master process\n");
+#endif
+		ret = -EINVAL;
+		goto err;
+	}
+
+	/* check that the requested range is within the src allocation */
+	if (unlikely((region->offset > pmem_len(id, data)) ||
+		     (region->len > pmem_len(id, data)) ||
+		     (region->offset + region->len > pmem_len(id, data)))) {
+#if PMEM_DEBUG
+		printk(KERN_INFO "pmem: suballoc doesn't fit in src_file!\n");
+#endif
+		ret = -EINVAL;
+		goto err;
+	}
+
+	if (operation == PMEM_MAP) {
+		region_node = kmalloc(sizeof(struct pmem_region_node),
+			      GFP_KERNEL);
+		if (!region_node) {
+			ret = -ENOMEM;
+#if PMEM_DEBUG
+			printk(KERN_INFO "No space to allocate metadata!");
+#endif
+			goto err;
+		}
+		region_node->region = *region;
+		list_add(&region_node->list, &data->region_list);
+	} else if (operation == PMEM_UNMAP) {
+		int found = 0;
+		list_for_each_safe(elt, elt2, &data->region_list) {
+			region_node = list_entry(elt, struct pmem_region_node,
+				      list);
+			if (region->len == 0 ||
+			    (region_node->region.offset == region->offset &&
+			    region_node->region.len == region->len)) {
+				list_del(elt);
+				kfree(region_node);
+				found = 1;
+			}
+		}
+		if (!found) {
+#if PMEM_DEBUG
+			printk("pmem: Unmap region does not map any mapped "
+				"region!");
+#endif
+			ret = -EINVAL;
+			goto err;
+		}
+	}
+
+	if (data->vma && PMEM_IS_SUBMAP(data)) {
+		if (operation == PMEM_MAP)
+			ret = pmem_remap_pfn_range(id, data->vma, data,
+						   region->offset, region->len);
+		else if (operation == PMEM_UNMAP)
+			ret = pmem_unmap_pfn_range(id, data->vma, data,
+						   region->offset, region->len);
+	}
+
+err:
+	pmem_unlock_data_and_mm(data, mm);
+	return ret;
+}
+
+static void pmem_revoke(struct file *file, struct pmem_data *data)
+{
+	struct pmem_region_node *region_node;
+	struct list_head *elt, *elt2;
+	struct mm_struct *mm = NULL;
+	int id = get_id(file);
+	int ret = 0;
+
+	data->master_file = NULL;
+	ret = pmem_lock_data_and_mm(file, data, &mm);
+	/* if lock_data_and_mm fails either the task that mapped the fd, or
+	 * the vma that mapped it have already gone away, nothing more
+	 * needs to be done */
+	if (ret)
+		return;
+	/* unmap everything */
+	/* delete the regions and region list nothing is mapped any more */
+	if (data->vma)
+		list_for_each_safe(elt, elt2, &data->region_list) {
+			region_node = list_entry(elt, struct pmem_region_node,
+						 list);
+			pmem_unmap_pfn_range(id, data->vma, data,
+					     region_node->region.offset,
+					     region_node->region.len);
+			list_del(elt);
+			kfree(region_node);
+	}
+	/* delete the master file */
+	pmem_unlock_data_and_mm(data, mm);
+}
+
+static void pmem_get_size(struct pmem_region *region, struct file *file)
+{
+	struct pmem_data *data = (struct pmem_data *)file->private_data;
+	int id = get_id(file);
+
+	if (!has_allocation(file)) {
+		region->offset = 0;
+		region->len = 0;
+		return;
+	} else {
+		region->offset = pmem_start_addr(id, data);
+		region->len = pmem_len(id, data);
+	}
+	DLOG("offset %lx len %lx\n", region->offset, region->len);
+}
+
+
+static long pmem_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
+{
+	struct pmem_data *data;
+	int id = get_id(file);
+
+	switch (cmd) {
+	case PMEM_GET_PHYS:
+		{
+			struct pmem_region region;
+			DLOG("get_phys\n");
+			if (!has_allocation(file)) {
+				region.offset = 0;
+				region.len = 0;
+			} else {
+				data = (struct pmem_data *)file->private_data;
+				region.offset = pmem_start_addr(id, data);
+				region.len = pmem_len(id, data);
+			}
+			printk(KERN_INFO "pmem: request for physical address of pmem region "
+					"from process %d.\n", current->pid);
+			if (copy_to_user((void __user *)arg, &region,
+						sizeof(struct pmem_region)))
+				return -EFAULT;
+			break;
+		}
+	case PMEM_MAP:
+		{
+			struct pmem_region region;
+			if (copy_from_user(&region, (void __user *)arg,
+						sizeof(struct pmem_region)))
+				return -EFAULT;
+			data = (struct pmem_data *)file->private_data;
+			return pmem_remap(&region, file, PMEM_MAP);
+		}
+		break;
+	case PMEM_UNMAP:
+		{
+			struct pmem_region region;
+			if (copy_from_user(&region, (void __user *)arg,
+						sizeof(struct pmem_region)))
+				return -EFAULT;
+			data = (struct pmem_data *)file->private_data;
+			return pmem_remap(&region, file, PMEM_UNMAP);
+			break;
+		}
+	case PMEM_GET_SIZE:
+		{
+			struct pmem_region region;
+			DLOG("get_size\n");
+			pmem_get_size(&region, file);
+			if (copy_to_user((void __user *)arg, &region,
+						sizeof(struct pmem_region)))
+				return -EFAULT;
+			break;
+		}
+	case PMEM_GET_TOTAL_SIZE:
+		{
+			struct pmem_region region;
+			DLOG("get total size\n");
+			region.offset = 0;
+			get_id(file);
+			region.len = pmem[id].size;
+			if (copy_to_user((void __user *)arg, &region,
+						sizeof(struct pmem_region)))
+				return -EFAULT;
+			break;
+		}
+	case PMEM_ALLOCATE:
+		{
+			if (has_allocation(file))
+				return -EINVAL;
+			data = (struct pmem_data *)file->private_data;
+			data->index = pmem_allocate(id, arg);
+			break;
+		}
+	case PMEM_CONNECT:
+		DLOG("connect\n");
+		return pmem_connect(arg, file);
+		break;
+	case PMEM_CACHE_FLUSH:
+		{
+			struct pmem_region region;
+			DLOG("flush\n");
+			if (copy_from_user(&region, (void __user *)arg,
+					   sizeof(struct pmem_region)))
+				return -EFAULT;
+			flush_pmem_file(file, region.offset, region.len);
+			break;
+		}
+	default:
+		if (pmem[id].ioctl)
+			return pmem[id].ioctl(file, cmd, arg);
+		return -EINVAL;
+	}
+	return 0;
+}
+
+#if PMEM_DEBUG
+static ssize_t debug_open(struct inode *inode, struct file *file)
+{
+	file->private_data = inode->i_private;
+	return 0;
+}
+
+static ssize_t debug_read(struct file *file, char __user *buf, size_t count,
+			  loff_t *ppos)
+{
+	struct list_head *elt, *elt2;
+	struct pmem_data *data;
+	struct pmem_region_node *region_node;
+	int id = (int)file->private_data;
+	const int debug_bufmax = 4096;
+	static char buffer[4096];
+	int n = 0;
+
+	DLOG("debug open\n");
+	n = scnprintf(buffer, debug_bufmax,
+		      "pid #: mapped regions (offset, len) (offset,len)...\n");
+
+	mutex_lock(&pmem[id].data_list_lock);
+	list_for_each(elt, &pmem[id].data_list) {
+		data = list_entry(elt, struct pmem_data, list);
+		down_read(&data->sem);
+		n += scnprintf(buffer + n, debug_bufmax - n, "pid %u:",
+				data->pid);
+		list_for_each(elt2, &data->region_list) {
+			region_node = list_entry(elt2, struct pmem_region_node,
+				      list);
+			n += scnprintf(buffer + n, debug_bufmax - n,
+					"(%lx,%lx) ",
+					region_node->region.offset,
+					region_node->region.len);
+		}
+		n += scnprintf(buffer + n, debug_bufmax - n, "\n");
+		up_read(&data->sem);
+	}
+	mutex_unlock(&pmem[id].data_list_lock);
+
+	n++;
+	buffer[n] = 0;
+	return simple_read_from_buffer(buf, count, ppos, buffer, n);
+}
+
+static struct file_operations debug_fops = {
+	.read = debug_read,
+	.open = debug_open,
+};
+#endif
+
+#if 0
+static struct miscdevice pmem_dev = {
+	.name = "pmem",
+	.fops = &pmem_fops,
+};
+#endif
+
+int pmem_setup(struct android_pmem_platform_data *pdata,
+	       long (*ioctl)(struct file *, unsigned int, unsigned long),
+	       int (*release)(struct inode *, struct file *))
+{
+	int err = 0;
+	int i, index = 0;
+	int id = id_count;
+	id_count++;
+
+	pmem[id].no_allocator = pdata->no_allocator;
+	pmem[id].cached = pdata->cached;
+	pmem[id].buffered = pdata->buffered;
+	pmem[id].base = pdata->start;
+	pmem[id].size = pdata->size;
+	pmem[id].ioctl = ioctl;
+	pmem[id].release = release;
+	init_rwsem(&pmem[id].bitmap_sem);
+	mutex_init(&pmem[id].data_list_lock);
+	INIT_LIST_HEAD(&pmem[id].data_list);
+	pmem[id].dev.name = pdata->name;
+	pmem[id].dev.minor = id;
+	pmem[id].dev.fops = &pmem_fops;
+	printk(KERN_INFO "%s: %d init\n", pdata->name, pdata->cached);
+
+	err = misc_register(&pmem[id].dev);
+	if (err) {
+		printk(KERN_ALERT "Unable to register pmem driver!\n");
+		goto err_cant_register_device;
+	}
+	pmem[id].num_entries = pmem[id].size / PMEM_MIN_ALLOC;
+
+	pmem[id].bitmap = kmalloc(pmem[id].num_entries *
+				  sizeof(struct pmem_bits), GFP_KERNEL);
+	if (!pmem[id].bitmap)
+		goto err_no_mem_for_metadata;
+
+	memset(pmem[id].bitmap, 0, sizeof(struct pmem_bits) *
+					  pmem[id].num_entries);
+
+	for (i = sizeof(pmem[id].num_entries) * 8 - 1; i >= 0; i--) {
+		if ((pmem[id].num_entries) &  1<<i) {
+			PMEM_ORDER(id, index) = i;
+			index = PMEM_NEXT_INDEX(id, index);
+		}
+	}
+
+	if (pmem[id].cached)
+		pmem[id].vbase = ioremap_cached(pmem[id].base,
+						pmem[id].size);
+#ifdef ioremap_ext_buffered
+	else if (pmem[id].buffered)
+		pmem[id].vbase = ioremap_ext_buffered(pmem[id].base,
+						      pmem[id].size);
+#endif
+	else
+		pmem[id].vbase = ioremap(pmem[id].base, pmem[id].size);
+
+	if (pmem[id].vbase == 0)
+		goto error_cant_remap;
+
+	pmem[id].garbage_pfn = page_to_pfn(alloc_page(GFP_KERNEL));
+	if (pmem[id].no_allocator)
+		pmem[id].allocated = 0;
+
+#if PMEM_DEBUG
+	debugfs_create_file(pdata->name, S_IFREG | S_IRUGO, NULL, (void *)id,
+			    &debug_fops);
+#endif
+	return 0;
+error_cant_remap:
+	kfree(pmem[id].bitmap);
+err_no_mem_for_metadata:
+	misc_deregister(&pmem[id].dev);
+err_cant_register_device:
+	return -1;
+}
+
+static int pmem_probe(struct platform_device *pdev)
+{
+	struct android_pmem_platform_data *pdata;
+
+	if (!pdev || !pdev->dev.platform_data) {
+		printk(KERN_ALERT "Unable to probe pmem!\n");
+		return -1;
+	}
+	pdata = pdev->dev.platform_data;
+	return pmem_setup(pdata, NULL, NULL);
+}
+
+
+static int pmem_remove(struct platform_device *pdev)
+{
+	int id = pdev->id;
+	__free_page(pfn_to_page(pmem[id].garbage_pfn));
+	misc_deregister(&pmem[id].dev);
+	return 0;
+}
+
+static struct platform_driver pmem_driver = {
+	.probe = pmem_probe,
+	.remove = pmem_remove,
+	.driver = { .name = "android_pmem" }
+};
+
+
+static int __init pmem_init(void)
+{
+	return platform_driver_register(&pmem_driver);
+}
+
+static void __exit pmem_exit(void)
+{
+	platform_driver_unregister(&pmem_driver);
+}
+
+module_init(pmem_init);
+module_exit(pmem_exit);
+
diff --git a/drivers/staging/android/ram_console.c b/drivers/staging/android/ram_console.c
new file mode 100644
index 0000000..6d4d679
--- /dev/null
+++ b/drivers/staging/android/ram_console.c
@@ -0,0 +1,443 @@
+/* drivers/android/ram_console.c
+ *
+ * Copyright (C) 2007-2008 Google, Inc.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include <linux/console.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/proc_fs.h>
+#include <linux/string.h>
+#include <linux/uaccess.h>
+#include <linux/io.h>
+#include "ram_console.h"
+
+#ifdef CONFIG_ANDROID_RAM_CONSOLE_ERROR_CORRECTION
+#include <linux/rslib.h>
+#endif
+
+struct ram_console_buffer {
+	uint32_t    sig;
+	uint32_t    start;
+	uint32_t    size;
+	uint8_t     data[0];
+};
+
+#define RAM_CONSOLE_SIG (0x43474244) /* DBGC */
+
+#ifdef CONFIG_ANDROID_RAM_CONSOLE_EARLY_INIT
+static char __initdata
+	ram_console_old_log_init_buffer[CONFIG_ANDROID_RAM_CONSOLE_EARLY_SIZE];
+#endif
+static char *ram_console_old_log;
+static size_t ram_console_old_log_size;
+
+static struct ram_console_buffer *ram_console_buffer;
+static size_t ram_console_buffer_size;
+#ifdef CONFIG_ANDROID_RAM_CONSOLE_ERROR_CORRECTION
+static char *ram_console_par_buffer;
+static struct rs_control *ram_console_rs_decoder;
+static int ram_console_corrected_bytes;
+static int ram_console_bad_blocks;
+#define ECC_BLOCK_SIZE CONFIG_ANDROID_RAM_CONSOLE_ERROR_CORRECTION_DATA_SIZE
+#define ECC_SIZE CONFIG_ANDROID_RAM_CONSOLE_ERROR_CORRECTION_ECC_SIZE
+#define ECC_SYMSIZE CONFIG_ANDROID_RAM_CONSOLE_ERROR_CORRECTION_SYMBOL_SIZE
+#define ECC_POLY CONFIG_ANDROID_RAM_CONSOLE_ERROR_CORRECTION_POLYNOMIAL
+#endif
+
+#ifdef CONFIG_ANDROID_RAM_CONSOLE_ERROR_CORRECTION
+static void ram_console_encode_rs8(uint8_t *data, size_t len, uint8_t *ecc)
+{
+	int i;
+	uint16_t par[ECC_SIZE];
+	/* Initialize the parity buffer */
+	memset(par, 0, sizeof(par));
+	encode_rs8(ram_console_rs_decoder, data, len, par, 0);
+	for (i = 0; i < ECC_SIZE; i++)
+		ecc[i] = par[i];
+}
+
+static int ram_console_decode_rs8(void *data, size_t len, uint8_t *ecc)
+{
+	int i;
+	uint16_t par[ECC_SIZE];
+	for (i = 0; i < ECC_SIZE; i++)
+		par[i] = ecc[i];
+	return decode_rs8(ram_console_rs_decoder, data, par, len,
+				NULL, 0, NULL, 0, NULL);
+}
+#endif
+
+static void ram_console_update(const char *s, unsigned int count)
+{
+	struct ram_console_buffer *buffer = ram_console_buffer;
+#ifdef CONFIG_ANDROID_RAM_CONSOLE_ERROR_CORRECTION
+	uint8_t *buffer_end = buffer->data + ram_console_buffer_size;
+	uint8_t *block;
+	uint8_t *par;
+	int size = ECC_BLOCK_SIZE;
+#endif
+	memcpy(buffer->data + buffer->start, s, count);
+#ifdef CONFIG_ANDROID_RAM_CONSOLE_ERROR_CORRECTION
+	block = buffer->data + (buffer->start & ~(ECC_BLOCK_SIZE - 1));
+	par = ram_console_par_buffer +
+	      (buffer->start / ECC_BLOCK_SIZE) * ECC_SIZE;
+	do {
+		if (block + ECC_BLOCK_SIZE > buffer_end)
+			size = buffer_end - block;
+		ram_console_encode_rs8(block, size, par);
+		block += ECC_BLOCK_SIZE;
+		par += ECC_SIZE;
+	} while (block < buffer->data + buffer->start + count);
+#endif
+}
+
+static void ram_console_update_header(void)
+{
+#ifdef CONFIG_ANDROID_RAM_CONSOLE_ERROR_CORRECTION
+	struct ram_console_buffer *buffer = ram_console_buffer;
+	uint8_t *par;
+	par = ram_console_par_buffer +
+	      DIV_ROUND_UP(ram_console_buffer_size, ECC_BLOCK_SIZE) * ECC_SIZE;
+	ram_console_encode_rs8((uint8_t *)buffer, sizeof(*buffer), par);
+#endif
+}
+
+static void
+ram_console_write(struct console *console, const char *s, unsigned int count)
+{
+	int rem;
+	struct ram_console_buffer *buffer = ram_console_buffer;
+
+	if (count > ram_console_buffer_size) {
+		s += count - ram_console_buffer_size;
+		count = ram_console_buffer_size;
+	}
+	rem = ram_console_buffer_size - buffer->start;
+	if (rem < count) {
+		ram_console_update(s, rem);
+		s += rem;
+		count -= rem;
+		buffer->start = 0;
+		buffer->size = ram_console_buffer_size;
+	}
+	ram_console_update(s, count);
+
+	buffer->start += count;
+	if (buffer->size < ram_console_buffer_size)
+		buffer->size += count;
+	ram_console_update_header();
+}
+
+static struct console ram_console = {
+	.name	= "ram",
+	.write	= ram_console_write,
+	.flags	= CON_PRINTBUFFER | CON_ENABLED,
+	.index	= -1,
+};
+
+void ram_console_enable_console(int enabled)
+{
+	if (enabled)
+		ram_console.flags |= CON_ENABLED;
+	else
+		ram_console.flags &= ~CON_ENABLED;
+}
+
+static void __init
+ram_console_save_old(struct ram_console_buffer *buffer, const char *bootinfo,
+	char *dest)
+{
+	size_t old_log_size = buffer->size;
+	size_t bootinfo_size = 0;
+	size_t total_size = old_log_size;
+	char *ptr;
+	const char *bootinfo_label = "Boot info:\n";
+
+#ifdef CONFIG_ANDROID_RAM_CONSOLE_ERROR_CORRECTION
+	uint8_t *block;
+	uint8_t *par;
+	char strbuf[80];
+	int strbuf_len = 0;
+
+	block = buffer->data;
+	par = ram_console_par_buffer;
+	while (block < buffer->data + buffer->size) {
+		int numerr;
+		int size = ECC_BLOCK_SIZE;
+		if (block + size > buffer->data + ram_console_buffer_size)
+			size = buffer->data + ram_console_buffer_size - block;
+		numerr = ram_console_decode_rs8(block, size, par);
+		if (numerr > 0) {
+#if 0
+			printk(KERN_INFO "ram_console: error in block %p, %d\n",
+			       block, numerr);
+#endif
+			ram_console_corrected_bytes += numerr;
+		} else if (numerr < 0) {
+#if 0
+			printk(KERN_INFO "ram_console: uncorrectable error in "
+			       "block %p\n", block);
+#endif
+			ram_console_bad_blocks++;
+		}
+		block += ECC_BLOCK_SIZE;
+		par += ECC_SIZE;
+	}
+	if (ram_console_corrected_bytes || ram_console_bad_blocks)
+		strbuf_len = snprintf(strbuf, sizeof(strbuf),
+			"\n%d Corrected bytes, %d unrecoverable blocks\n",
+			ram_console_corrected_bytes, ram_console_bad_blocks);
+	else
+		strbuf_len = snprintf(strbuf, sizeof(strbuf),
+				      "\nNo errors detected\n");
+	if (strbuf_len >= sizeof(strbuf))
+		strbuf_len = sizeof(strbuf) - 1;
+	total_size += strbuf_len;
+#endif
+
+	if (bootinfo)
+		bootinfo_size = strlen(bootinfo) + strlen(bootinfo_label);
+	total_size += bootinfo_size;
+
+	if (dest == NULL) {
+		dest = kmalloc(total_size, GFP_KERNEL);
+		if (dest == NULL) {
+			printk(KERN_ERR
+			       "ram_console: failed to allocate buffer\n");
+			return;
+		}
+	}
+
+	ram_console_old_log = dest;
+	ram_console_old_log_size = total_size;
+	memcpy(ram_console_old_log,
+	       &buffer->data[buffer->start], buffer->size - buffer->start);
+	memcpy(ram_console_old_log + buffer->size - buffer->start,
+	       &buffer->data[0], buffer->start);
+	ptr = ram_console_old_log + old_log_size;
+#ifdef CONFIG_ANDROID_RAM_CONSOLE_ERROR_CORRECTION
+	memcpy(ptr, strbuf, strbuf_len);
+	ptr += strbuf_len;
+#endif
+	if (bootinfo) {
+		memcpy(ptr, bootinfo_label, strlen(bootinfo_label));
+		ptr += strlen(bootinfo_label);
+		memcpy(ptr, bootinfo, bootinfo_size);
+		ptr += bootinfo_size;
+	}
+}
+
+static int __init ram_console_init(struct ram_console_buffer *buffer,
+				   size_t buffer_size, const char *bootinfo,
+				   char *old_buf)
+{
+#ifdef CONFIG_ANDROID_RAM_CONSOLE_ERROR_CORRECTION
+	int numerr;
+	uint8_t *par;
+#endif
+	ram_console_buffer = buffer;
+	ram_console_buffer_size =
+		buffer_size - sizeof(struct ram_console_buffer);
+
+	if (ram_console_buffer_size > buffer_size) {
+		pr_err("ram_console: buffer %p, invalid size %zu, "
+		       "datasize %zu\n", buffer, buffer_size,
+		       ram_console_buffer_size);
+		return 0;
+	}
+
+#ifdef CONFIG_ANDROID_RAM_CONSOLE_ERROR_CORRECTION
+	ram_console_buffer_size -= (DIV_ROUND_UP(ram_console_buffer_size,
+						ECC_BLOCK_SIZE) + 1) * ECC_SIZE;
+
+	if (ram_console_buffer_size > buffer_size) {
+		pr_err("ram_console: buffer %p, invalid size %zu, "
+		       "non-ecc datasize %zu\n",
+		       buffer, buffer_size, ram_console_buffer_size);
+		return 0;
+	}
+
+	ram_console_par_buffer = buffer->data + ram_console_buffer_size;
+
+
+	/* first consecutive root is 0
+	 * primitive element to generate roots = 1
+	 */
+	ram_console_rs_decoder = init_rs(ECC_SYMSIZE, ECC_POLY, 0, 1, ECC_SIZE);
+	if (ram_console_rs_decoder == NULL) {
+		printk(KERN_INFO "ram_console: init_rs failed\n");
+		return 0;
+	}
+
+	ram_console_corrected_bytes = 0;
+	ram_console_bad_blocks = 0;
+
+	par = ram_console_par_buffer +
+	      DIV_ROUND_UP(ram_console_buffer_size, ECC_BLOCK_SIZE) * ECC_SIZE;
+
+	numerr = ram_console_decode_rs8(buffer, sizeof(*buffer), par);
+	if (numerr > 0) {
+		printk(KERN_INFO "ram_console: error in header, %d\n", numerr);
+		ram_console_corrected_bytes += numerr;
+	} else if (numerr < 0) {
+		printk(KERN_INFO
+		       "ram_console: uncorrectable error in header\n");
+		ram_console_bad_blocks++;
+	}
+#endif
+
+	if (buffer->sig == RAM_CONSOLE_SIG) {
+		if (buffer->size > ram_console_buffer_size
+		    || buffer->start > buffer->size)
+			printk(KERN_INFO "ram_console: found existing invalid "
+			       "buffer, size %d, start %d\n",
+			       buffer->size, buffer->start);
+		else {
+			printk(KERN_INFO "ram_console: found existing buffer, "
+			       "size %d, start %d\n",
+			       buffer->size, buffer->start);
+			ram_console_save_old(buffer, bootinfo, old_buf);
+		}
+	} else {
+		printk(KERN_INFO "ram_console: no valid data in buffer "
+		       "(sig = 0x%08x)\n", buffer->sig);
+	}
+
+	buffer->sig = RAM_CONSOLE_SIG;
+	buffer->start = 0;
+	buffer->size = 0;
+
+	register_console(&ram_console);
+#ifdef CONFIG_ANDROID_RAM_CONSOLE_ENABLE_VERBOSE
+	console_verbose();
+#endif
+	return 0;
+}
+
+#ifdef CONFIG_ANDROID_RAM_CONSOLE_EARLY_INIT
+static int __init ram_console_early_init(void)
+{
+	return ram_console_init((struct ram_console_buffer *)
+		CONFIG_ANDROID_RAM_CONSOLE_EARLY_ADDR,
+		CONFIG_ANDROID_RAM_CONSOLE_EARLY_SIZE,
+		NULL,
+		ram_console_old_log_init_buffer);
+}
+#else
+static int ram_console_driver_probe(struct platform_device *pdev)
+{
+	struct resource *res = pdev->resource;
+	size_t start;
+	size_t buffer_size;
+	void *buffer;
+	const char *bootinfo = NULL;
+	struct ram_console_platform_data *pdata = pdev->dev.platform_data;
+
+	if (res == NULL || pdev->num_resources != 1 ||
+	    !(res->flags & IORESOURCE_MEM)) {
+		printk(KERN_ERR "ram_console: invalid resource, %p %d flags "
+		       "%lx\n", res, pdev->num_resources, res ? res->flags : 0);
+		return -ENXIO;
+	}
+	buffer_size = res->end - res->start + 1;
+	start = res->start;
+	printk(KERN_INFO "ram_console: got buffer at %zx, size %zx\n",
+	       start, buffer_size);
+	buffer = ioremap(res->start, buffer_size);
+	if (buffer == NULL) {
+		printk(KERN_ERR "ram_console: failed to map memory\n");
+		return -ENOMEM;
+	}
+
+	if (pdata)
+		bootinfo = pdata->bootinfo;
+
+	return ram_console_init(buffer, buffer_size, bootinfo, NULL/* allocate */);
+}
+
+static struct platform_driver ram_console_driver = {
+	.probe = ram_console_driver_probe,
+	.driver		= {
+		.name	= "ram_console",
+	},
+};
+
+static int __init ram_console_module_init(void)
+{
+	int err;
+	err = platform_driver_register(&ram_console_driver);
+	return err;
+}
+#endif
+
+static ssize_t ram_console_read_old(struct file *file, char __user *buf,
+				    size_t len, loff_t *offset)
+{
+	loff_t pos = *offset;
+	ssize_t count;
+
+	if (pos >= ram_console_old_log_size)
+		return 0;
+
+	count = min(len, (size_t)(ram_console_old_log_size - pos));
+	if (copy_to_user(buf, ram_console_old_log + pos, count))
+		return -EFAULT;
+
+	*offset += count;
+	return count;
+}
+
+static const struct file_operations ram_console_file_ops = {
+	.owner = THIS_MODULE,
+	.read = ram_console_read_old,
+};
+
+static int __init ram_console_late_init(void)
+{
+	struct proc_dir_entry *entry;
+
+	if (ram_console_old_log == NULL)
+		return 0;
+#ifdef CONFIG_ANDROID_RAM_CONSOLE_EARLY_INIT
+	ram_console_old_log = kmalloc(ram_console_old_log_size, GFP_KERNEL);
+	if (ram_console_old_log == NULL) {
+		printk(KERN_ERR
+		       "ram_console: failed to allocate buffer for old log\n");
+		ram_console_old_log_size = 0;
+		return 0;
+	}
+	memcpy(ram_console_old_log,
+	       ram_console_old_log_init_buffer, ram_console_old_log_size);
+#endif
+	entry = create_proc_entry("last_kmsg", S_IFREG | S_IRUGO, NULL);
+	if (!entry) {
+		printk(KERN_ERR "ram_console: failed to create proc entry\n");
+		kfree(ram_console_old_log);
+		ram_console_old_log = NULL;
+		return 0;
+	}
+
+	entry->proc_fops = &ram_console_file_ops;
+	entry->size = ram_console_old_log_size;
+	return 0;
+}
+
+#ifdef CONFIG_ANDROID_RAM_CONSOLE_EARLY_INIT
+console_initcall(ram_console_early_init);
+#else
+postcore_initcall(ram_console_module_init);
+#endif
+late_initcall(ram_console_late_init);
+
diff --git a/drivers/staging/android/ram_console.h b/drivers/staging/android/ram_console.h
new file mode 100644
index 0000000..9f1125c
--- /dev/null
+++ b/drivers/staging/android/ram_console.h
@@ -0,0 +1,22 @@
+/*
+ * Copyright (C) 2010 Google, Inc.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#ifndef _INCLUDE_LINUX_PLATFORM_DATA_RAM_CONSOLE_H_
+#define _INCLUDE_LINUX_PLATFORM_DATA_RAM_CONSOLE_H_
+
+struct ram_console_platform_data {
+	const char *bootinfo;
+};
+
+#endif /* _INCLUDE_LINUX_PLATFORM_DATA_RAM_CONSOLE_H_ */
diff --git a/drivers/staging/android/switch/Kconfig b/drivers/staging/android/switch/Kconfig
new file mode 100644
index 0000000..36846f6
--- /dev/null
+++ b/drivers/staging/android/switch/Kconfig
@@ -0,0 +1,11 @@
+menuconfig ANDROID_SWITCH
+	tristate "Android Switch class support"
+	help
+	  Say Y here to enable Android switch class support. This allows
+	  monitoring switches by userspace via sysfs and uevent.
+
+config ANDROID_SWITCH_GPIO
+	tristate "Android GPIO Switch support"
+	depends on GENERIC_GPIO && ANDROID_SWITCH
+	help
+	  Say Y here to enable GPIO based switch support.
diff --git a/drivers/staging/android/switch/Makefile b/drivers/staging/android/switch/Makefile
new file mode 100644
index 0000000..d76bfdc
--- /dev/null
+++ b/drivers/staging/android/switch/Makefile
@@ -0,0 +1,4 @@
+# Android Switch Class Driver
+obj-$(CONFIG_ANDROID_SWITCH)		+= switch_class.o
+obj-$(CONFIG_ANDROID_SWITCH_GPIO)	+= switch_gpio.o
+
diff --git a/drivers/staging/android/switch/switch.h b/drivers/staging/android/switch/switch.h
new file mode 100644
index 0000000..4fcb310
--- /dev/null
+++ b/drivers/staging/android/switch/switch.h
@@ -0,0 +1,53 @@
+/*
+ *  Switch class driver
+ *
+ * Copyright (C) 2008 Google, Inc.
+ * Author: Mike Lockwood <lockwood@android.com>
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+*/
+
+#ifndef __LINUX_SWITCH_H__
+#define __LINUX_SWITCH_H__
+
+struct switch_dev {
+	const char	*name;
+	struct device	*dev;
+	int		index;
+	int		state;
+
+	ssize_t	(*print_name)(struct switch_dev *sdev, char *buf);
+	ssize_t	(*print_state)(struct switch_dev *sdev, char *buf);
+};
+
+struct gpio_switch_platform_data {
+	const char *name;
+	unsigned	gpio;
+
+	/* if NULL, switch_dev.name will be printed */
+	const char *name_on;
+	const char *name_off;
+	/* if NULL, "0" or "1" will be printed */
+	const char *state_on;
+	const char *state_off;
+};
+
+extern int switch_dev_register(struct switch_dev *sdev);
+extern void switch_dev_unregister(struct switch_dev *sdev);
+
+static inline int switch_get_state(struct switch_dev *sdev)
+{
+	return sdev->state;
+}
+
+extern void switch_set_state(struct switch_dev *sdev, int state);
+
+#endif /* __LINUX_SWITCH_H__ */
diff --git a/drivers/staging/android/switch/switch_class.c b/drivers/staging/android/switch/switch_class.c
new file mode 100644
index 0000000..7468044
--- /dev/null
+++ b/drivers/staging/android/switch/switch_class.c
@@ -0,0 +1,174 @@
+/*
+ * switch_class.c
+ *
+ * Copyright (C) 2008 Google, Inc.
+ * Author: Mike Lockwood <lockwood@android.com>
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+*/
+
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/init.h>
+#include <linux/device.h>
+#include <linux/fs.h>
+#include <linux/err.h>
+#include "switch.h"
+
+struct class *switch_class;
+static atomic_t device_count;
+
+static ssize_t state_show(struct device *dev, struct device_attribute *attr,
+		char *buf)
+{
+	struct switch_dev *sdev = (struct switch_dev *)
+		dev_get_drvdata(dev);
+
+	if (sdev->print_state) {
+		int ret = sdev->print_state(sdev, buf);
+		if (ret >= 0)
+			return ret;
+	}
+	return sprintf(buf, "%d\n", sdev->state);
+}
+
+static ssize_t name_show(struct device *dev, struct device_attribute *attr,
+		char *buf)
+{
+	struct switch_dev *sdev = (struct switch_dev *)
+		dev_get_drvdata(dev);
+
+	if (sdev->print_name) {
+		int ret = sdev->print_name(sdev, buf);
+		if (ret >= 0)
+			return ret;
+	}
+	return sprintf(buf, "%s\n", sdev->name);
+}
+
+static DEVICE_ATTR(state, S_IRUGO | S_IWUSR, state_show, NULL);
+static DEVICE_ATTR(name, S_IRUGO | S_IWUSR, name_show, NULL);
+
+void switch_set_state(struct switch_dev *sdev, int state)
+{
+	char name_buf[120];
+	char state_buf[120];
+	char *prop_buf;
+	char *envp[3];
+	int env_offset = 0;
+	int length;
+
+	if (sdev->state != state) {
+		sdev->state = state;
+
+		prop_buf = (char *)get_zeroed_page(GFP_KERNEL);
+		if (prop_buf) {
+			length = name_show(sdev->dev, NULL, prop_buf);
+			if (length > 0) {
+				if (prop_buf[length - 1] == '\n')
+					prop_buf[length - 1] = 0;
+				snprintf(name_buf, sizeof(name_buf),
+					"SWITCH_NAME=%s", prop_buf);
+				envp[env_offset++] = name_buf;
+			}
+			length = state_show(sdev->dev, NULL, prop_buf);
+			if (length > 0) {
+				if (prop_buf[length - 1] == '\n')
+					prop_buf[length - 1] = 0;
+				snprintf(state_buf, sizeof(state_buf),
+					"SWITCH_STATE=%s", prop_buf);
+				envp[env_offset++] = state_buf;
+			}
+			envp[env_offset] = NULL;
+			kobject_uevent_env(&sdev->dev->kobj, KOBJ_CHANGE, envp);
+			free_page((unsigned long)prop_buf);
+		} else {
+			printk(KERN_ERR "out of memory in switch_set_state\n");
+			kobject_uevent(&sdev->dev->kobj, KOBJ_CHANGE);
+		}
+	}
+}
+EXPORT_SYMBOL_GPL(switch_set_state);
+
+static int create_switch_class(void)
+{
+	if (!switch_class) {
+		switch_class = class_create(THIS_MODULE, "switch");
+		if (IS_ERR(switch_class))
+			return PTR_ERR(switch_class);
+		atomic_set(&device_count, 0);
+	}
+
+	return 0;
+}
+
+int switch_dev_register(struct switch_dev *sdev)
+{
+	int ret;
+
+	if (!switch_class) {
+		ret = create_switch_class();
+		if (ret < 0)
+			return ret;
+	}
+
+	sdev->index = atomic_inc_return(&device_count);
+	sdev->dev = device_create(switch_class, NULL,
+		MKDEV(0, sdev->index), NULL, sdev->name);
+	if (IS_ERR(sdev->dev))
+		return PTR_ERR(sdev->dev);
+
+	ret = device_create_file(sdev->dev, &dev_attr_state);
+	if (ret < 0)
+		goto err_create_file_1;
+	ret = device_create_file(sdev->dev, &dev_attr_name);
+	if (ret < 0)
+		goto err_create_file_2;
+
+	dev_set_drvdata(sdev->dev, sdev);
+	sdev->state = 0;
+	return 0;
+
+err_create_file_2:
+	device_remove_file(sdev->dev, &dev_attr_state);
+err_create_file_1:
+	device_destroy(switch_class, MKDEV(0, sdev->index));
+	printk(KERN_ERR "switch: Failed to register driver %s\n", sdev->name);
+
+	return ret;
+}
+EXPORT_SYMBOL_GPL(switch_dev_register);
+
+void switch_dev_unregister(struct switch_dev *sdev)
+{
+	device_remove_file(sdev->dev, &dev_attr_name);
+	device_remove_file(sdev->dev, &dev_attr_state);
+	device_destroy(switch_class, MKDEV(0, sdev->index));
+	dev_set_drvdata(sdev->dev, NULL);
+}
+EXPORT_SYMBOL_GPL(switch_dev_unregister);
+
+static int __init switch_class_init(void)
+{
+	return create_switch_class();
+}
+
+static void __exit switch_class_exit(void)
+{
+	class_destroy(switch_class);
+}
+
+module_init(switch_class_init);
+module_exit(switch_class_exit);
+
+MODULE_AUTHOR("Mike Lockwood <lockwood@android.com>");
+MODULE_DESCRIPTION("Switch class driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/staging/android/switch/switch_gpio.c b/drivers/staging/android/switch/switch_gpio.c
new file mode 100644
index 0000000..38b2c2f
--- /dev/null
+++ b/drivers/staging/android/switch/switch_gpio.c
@@ -0,0 +1,172 @@
+/*
+ * switch_gpio.c
+ *
+ * Copyright (C) 2008 Google, Inc.
+ * Author: Mike Lockwood <lockwood@android.com>
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+*/
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+#include <linux/workqueue.h>
+#include <linux/gpio.h>
+#include "switch.h"
+
+struct gpio_switch_data {
+	struct switch_dev sdev;
+	unsigned gpio;
+	const char *name_on;
+	const char *name_off;
+	const char *state_on;
+	const char *state_off;
+	int irq;
+	struct work_struct work;
+};
+
+static void gpio_switch_work(struct work_struct *work)
+{
+	int state;
+	struct gpio_switch_data	*data =
+		container_of(work, struct gpio_switch_data, work);
+
+	state = gpio_get_value(data->gpio);
+	switch_set_state(&data->sdev, state);
+}
+
+static irqreturn_t gpio_irq_handler(int irq, void *dev_id)
+{
+	struct gpio_switch_data *switch_data =
+	    (struct gpio_switch_data *)dev_id;
+
+	schedule_work(&switch_data->work);
+	return IRQ_HANDLED;
+}
+
+static ssize_t switch_gpio_print_state(struct switch_dev *sdev, char *buf)
+{
+	struct gpio_switch_data	*switch_data =
+		container_of(sdev, struct gpio_switch_data, sdev);
+	const char *state;
+	if (switch_get_state(sdev))
+		state = switch_data->state_on;
+	else
+		state = switch_data->state_off;
+
+	if (state)
+		return sprintf(buf, "%s\n", state);
+	return -1;
+}
+
+static int gpio_switch_probe(struct platform_device *pdev)
+{
+	struct gpio_switch_platform_data *pdata = pdev->dev.platform_data;
+	struct gpio_switch_data *switch_data;
+	int ret = 0;
+
+	if (!pdata)
+		return -EBUSY;
+
+	switch_data = kzalloc(sizeof(struct gpio_switch_data), GFP_KERNEL);
+	if (!switch_data)
+		return -ENOMEM;
+
+	switch_data->sdev.name = pdata->name;
+	switch_data->gpio = pdata->gpio;
+	switch_data->name_on = pdata->name_on;
+	switch_data->name_off = pdata->name_off;
+	switch_data->state_on = pdata->state_on;
+	switch_data->state_off = pdata->state_off;
+	switch_data->sdev.print_state = switch_gpio_print_state;
+
+	ret = switch_dev_register(&switch_data->sdev);
+	if (ret < 0)
+		goto err_switch_dev_register;
+
+	ret = gpio_request(switch_data->gpio, pdev->name);
+	if (ret < 0)
+		goto err_request_gpio;
+
+	ret = gpio_direction_input(switch_data->gpio);
+	if (ret < 0)
+		goto err_set_gpio_input;
+
+	INIT_WORK(&switch_data->work, gpio_switch_work);
+
+	switch_data->irq = gpio_to_irq(switch_data->gpio);
+	if (switch_data->irq < 0) {
+		ret = switch_data->irq;
+		goto err_detect_irq_num_failed;
+	}
+
+	ret = request_irq(switch_data->irq, gpio_irq_handler,
+			  IRQF_TRIGGER_LOW, pdev->name, switch_data);
+	if (ret < 0)
+		goto err_request_irq;
+
+	/* Perform initial detection */
+	gpio_switch_work(&switch_data->work);
+
+	return 0;
+
+err_request_irq:
+err_detect_irq_num_failed:
+err_set_gpio_input:
+	gpio_free(switch_data->gpio);
+err_request_gpio:
+	switch_dev_unregister(&switch_data->sdev);
+err_switch_dev_register:
+	kfree(switch_data);
+
+	return ret;
+}
+
+static int __devexit gpio_switch_remove(struct platform_device *pdev)
+{
+	struct gpio_switch_data *switch_data = platform_get_drvdata(pdev);
+
+	cancel_work_sync(&switch_data->work);
+	gpio_free(switch_data->gpio);
+	switch_dev_unregister(&switch_data->sdev);
+	kfree(switch_data);
+
+	return 0;
+}
+
+static struct platform_driver gpio_switch_driver = {
+	.probe		= gpio_switch_probe,
+	.remove		= __devexit_p(gpio_switch_remove),
+	.driver		= {
+		.name	= "switch-gpio",
+		.owner	= THIS_MODULE,
+	},
+};
+
+static int __init gpio_switch_init(void)
+{
+	return platform_driver_register(&gpio_switch_driver);
+}
+
+static void __exit gpio_switch_exit(void)
+{
+	platform_driver_unregister(&gpio_switch_driver);
+}
+
+module_init(gpio_switch_init);
+module_exit(gpio_switch_exit);
+
+MODULE_AUTHOR("Mike Lockwood <lockwood@android.com>");
+MODULE_DESCRIPTION("GPIO Switch driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/staging/android/timed_gpio.c b/drivers/staging/android/timed_gpio.c
new file mode 100644
index 0000000..a64481c
--- /dev/null
+++ b/drivers/staging/android/timed_gpio.c
@@ -0,0 +1,176 @@
+/* drivers/misc/timed_gpio.c
+ *
+ * Copyright (C) 2008 Google, Inc.
+ * Author: Mike Lockwood <lockwood@android.com>
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+#include <linux/hrtimer.h>
+#include <linux/err.h>
+#include <linux/gpio.h>
+
+#include "timed_output.h"
+#include "timed_gpio.h"
+
+
+struct timed_gpio_data {
+	struct timed_output_dev dev;
+	struct hrtimer timer;
+	spinlock_t lock;
+	unsigned 	gpio;
+	int 		max_timeout;
+	u8 		active_low;
+};
+
+static enum hrtimer_restart gpio_timer_func(struct hrtimer *timer)
+{
+	struct timed_gpio_data *data =
+		container_of(timer, struct timed_gpio_data, timer);
+
+	gpio_direction_output(data->gpio, data->active_low ? 1 : 0);
+	return HRTIMER_NORESTART;
+}
+
+static int gpio_get_time(struct timed_output_dev *dev)
+{
+	struct timed_gpio_data	*data =
+		container_of(dev, struct timed_gpio_data, dev);
+
+	if (hrtimer_active(&data->timer)) {
+		ktime_t r = hrtimer_get_remaining(&data->timer);
+		struct timeval t = ktime_to_timeval(r);
+		return t.tv_sec * 1000 + t.tv_usec / 1000;
+	} else
+		return 0;
+}
+
+static void gpio_enable(struct timed_output_dev *dev, int value)
+{
+	struct timed_gpio_data	*data =
+		container_of(dev, struct timed_gpio_data, dev);
+	unsigned long	flags;
+
+	spin_lock_irqsave(&data->lock, flags);
+
+	/* cancel previous timer and set GPIO according to value */
+	hrtimer_cancel(&data->timer);
+	gpio_direction_output(data->gpio, data->active_low ? !value : !!value);
+
+	if (value > 0) {
+		if (value > data->max_timeout)
+			value = data->max_timeout;
+
+		hrtimer_start(&data->timer,
+			ktime_set(value / 1000, (value % 1000) * 1000000),
+			HRTIMER_MODE_REL);
+	}
+
+	spin_unlock_irqrestore(&data->lock, flags);
+}
+
+static int timed_gpio_probe(struct platform_device *pdev)
+{
+	struct timed_gpio_platform_data *pdata = pdev->dev.platform_data;
+	struct timed_gpio *cur_gpio;
+	struct timed_gpio_data *gpio_data, *gpio_dat;
+	int i, j, ret = 0;
+
+	if (!pdata)
+		return -EBUSY;
+
+	gpio_data = kzalloc(sizeof(struct timed_gpio_data) * pdata->num_gpios,
+			GFP_KERNEL);
+	if (!gpio_data)
+		return -ENOMEM;
+
+	for (i = 0; i < pdata->num_gpios; i++) {
+		cur_gpio = &pdata->gpios[i];
+		gpio_dat = &gpio_data[i];
+
+		hrtimer_init(&gpio_dat->timer, CLOCK_MONOTONIC,
+				HRTIMER_MODE_REL);
+		gpio_dat->timer.function = gpio_timer_func;
+		spin_lock_init(&gpio_dat->lock);
+
+		gpio_dat->dev.name = cur_gpio->name;
+		gpio_dat->dev.get_time = gpio_get_time;
+		gpio_dat->dev.enable = gpio_enable;
+		ret = gpio_request(cur_gpio->gpio, cur_gpio->name);
+		if (ret >= 0) {
+			ret = timed_output_dev_register(&gpio_dat->dev);
+			if (ret < 0)
+				gpio_free(cur_gpio->gpio);
+		}
+		if (ret < 0) {
+			for (j = 0; j < i; j++) {
+				timed_output_dev_unregister(&gpio_data[i].dev);
+				gpio_free(gpio_data[i].gpio);
+			}
+			kfree(gpio_data);
+			return ret;
+		}
+
+		gpio_dat->gpio = cur_gpio->gpio;
+		gpio_dat->max_timeout = cur_gpio->max_timeout;
+		gpio_dat->active_low = cur_gpio->active_low;
+		gpio_direction_output(gpio_dat->gpio, gpio_dat->active_low);
+	}
+
+	platform_set_drvdata(pdev, gpio_data);
+
+	return 0;
+}
+
+static int timed_gpio_remove(struct platform_device *pdev)
+{
+	struct timed_gpio_platform_data *pdata = pdev->dev.platform_data;
+	struct timed_gpio_data *gpio_data = platform_get_drvdata(pdev);
+	int i;
+
+	for (i = 0; i < pdata->num_gpios; i++) {
+		timed_output_dev_unregister(&gpio_data[i].dev);
+		gpio_free(gpio_data[i].gpio);
+	}
+
+	kfree(gpio_data);
+
+	return 0;
+}
+
+static struct platform_driver timed_gpio_driver = {
+	.probe		= timed_gpio_probe,
+	.remove		= timed_gpio_remove,
+	.driver		= {
+		.name		= TIMED_GPIO_NAME,
+		.owner		= THIS_MODULE,
+	},
+};
+
+static int __init timed_gpio_init(void)
+{
+	return platform_driver_register(&timed_gpio_driver);
+}
+
+static void __exit timed_gpio_exit(void)
+{
+	platform_driver_unregister(&timed_gpio_driver);
+}
+
+module_init(timed_gpio_init);
+module_exit(timed_gpio_exit);
+
+MODULE_AUTHOR("Mike Lockwood <lockwood@android.com>");
+MODULE_DESCRIPTION("timed gpio driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/staging/android/timed_gpio.h b/drivers/staging/android/timed_gpio.h
new file mode 100644
index 0000000..a0e15f8
--- /dev/null
+++ b/drivers/staging/android/timed_gpio.h
@@ -0,0 +1,33 @@
+/* include/linux/timed_gpio.h
+ *
+ * Copyright (C) 2008 Google, Inc.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+*/
+
+#ifndef _LINUX_TIMED_GPIO_H
+#define _LINUX_TIMED_GPIO_H
+
+#define TIMED_GPIO_NAME "timed-gpio"
+
+struct timed_gpio {
+	const char *name;
+	unsigned 	gpio;
+	int		max_timeout;
+	u8 		active_low;
+};
+
+struct timed_gpio_platform_data {
+	int 		num_gpios;
+	struct timed_gpio *gpios;
+};
+
+#endif
diff --git a/drivers/staging/android/timed_output.c b/drivers/staging/android/timed_output.c
new file mode 100644
index 0000000..f373422
--- /dev/null
+++ b/drivers/staging/android/timed_output.c
@@ -0,0 +1,123 @@
+/* drivers/misc/timed_output.c
+ *
+ * Copyright (C) 2009 Google, Inc.
+ * Author: Mike Lockwood <lockwood@android.com>
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/device.h>
+#include <linux/fs.h>
+#include <linux/err.h>
+
+#include "timed_output.h"
+
+static struct class *timed_output_class;
+static atomic_t device_count;
+
+static ssize_t enable_show(struct device *dev, struct device_attribute *attr,
+		char *buf)
+{
+	struct timed_output_dev *tdev = dev_get_drvdata(dev);
+	int remaining = tdev->get_time(tdev);
+
+	return sprintf(buf, "%d\n", remaining);
+}
+
+static ssize_t enable_store(
+		struct device *dev, struct device_attribute *attr,
+		const char *buf, size_t size)
+{
+	struct timed_output_dev *tdev = dev_get_drvdata(dev);
+	int value;
+
+	if (sscanf(buf, "%d", &value) != 1)
+		return -EINVAL;
+
+	tdev->enable(tdev, value);
+
+	return size;
+}
+
+static DEVICE_ATTR(enable, S_IRUGO | S_IWUSR, enable_show, enable_store);
+
+static int create_timed_output_class(void)
+{
+	if (!timed_output_class) {
+		timed_output_class = class_create(THIS_MODULE, "timed_output");
+		if (IS_ERR(timed_output_class))
+			return PTR_ERR(timed_output_class);
+		atomic_set(&device_count, 0);
+	}
+
+	return 0;
+}
+
+int timed_output_dev_register(struct timed_output_dev *tdev)
+{
+	int ret;
+
+	if (!tdev || !tdev->name || !tdev->enable || !tdev->get_time)
+		return -EINVAL;
+
+	ret = create_timed_output_class();
+	if (ret < 0)
+		return ret;
+
+	tdev->index = atomic_inc_return(&device_count);
+	tdev->dev = device_create(timed_output_class, NULL,
+		MKDEV(0, tdev->index), NULL, tdev->name);
+	if (IS_ERR(tdev->dev))
+		return PTR_ERR(tdev->dev);
+
+	ret = device_create_file(tdev->dev, &dev_attr_enable);
+	if (ret < 0)
+		goto err_create_file;
+
+	dev_set_drvdata(tdev->dev, tdev);
+	tdev->state = 0;
+	return 0;
+
+err_create_file:
+	device_destroy(timed_output_class, MKDEV(0, tdev->index));
+	printk(KERN_ERR "timed_output: Failed to register driver %s\n",
+			tdev->name);
+
+	return ret;
+}
+EXPORT_SYMBOL_GPL(timed_output_dev_register);
+
+void timed_output_dev_unregister(struct timed_output_dev *tdev)
+{
+	device_remove_file(tdev->dev, &dev_attr_enable);
+	device_destroy(timed_output_class, MKDEV(0, tdev->index));
+	dev_set_drvdata(tdev->dev, NULL);
+}
+EXPORT_SYMBOL_GPL(timed_output_dev_unregister);
+
+static int __init timed_output_init(void)
+{
+	return create_timed_output_class();
+}
+
+static void __exit timed_output_exit(void)
+{
+	class_destroy(timed_output_class);
+}
+
+module_init(timed_output_init);
+module_exit(timed_output_exit);
+
+MODULE_AUTHOR("Mike Lockwood <lockwood@android.com>");
+MODULE_DESCRIPTION("timed output class driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/staging/android/timed_output.h b/drivers/staging/android/timed_output.h
new file mode 100644
index 0000000..ec907ab
--- /dev/null
+++ b/drivers/staging/android/timed_output.h
@@ -0,0 +1,37 @@
+/* include/linux/timed_output.h
+ *
+ * Copyright (C) 2008 Google, Inc.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+*/
+
+#ifndef _LINUX_TIMED_OUTPUT_H
+#define _LINUX_TIMED_OUTPUT_H
+
+struct timed_output_dev {
+	const char	*name;
+
+	/* enable the output and set the timer */
+	void	(*enable)(struct timed_output_dev *sdev, int timeout);
+
+	/* returns the current number of milliseconds remaining on the timer */
+	int		(*get_time)(struct timed_output_dev *sdev);
+
+	/* private data */
+	struct device	*dev;
+	int		index;
+	int		state;
+};
+
+extern int timed_output_dev_register(struct timed_output_dev *dev);
+extern void timed_output_dev_unregister(struct timed_output_dev *dev);
+
+#endif
diff --git a/drivers/staging/asus_oled/asus_oled.c b/drivers/staging/asus_oled/asus_oled.c
index 7bb7da7..e77e4e0 100644
--- a/drivers/staging/asus_oled/asus_oled.c
+++ b/drivers/staging/asus_oled/asus_oled.c
@@ -201,7 +201,7 @@
 	struct usb_interface *intf = to_usb_interface(dev);
 	struct asus_oled_dev *odev = usb_get_intfdata(intf);
 	unsigned long value;
-	if (strict_strtoul(buf, 10, &value))
+	if (kstrtoul(buf, 10, &value))
 		return -EINVAL;
 
 	enable_oled(odev, value);
@@ -217,7 +217,7 @@
 		(struct asus_oled_dev *) dev_get_drvdata(device);
 	unsigned long value;
 
-	if (strict_strtoul(buf, 10, &value))
+	if (kstrtoul(buf, 10, &value))
 		return -EINVAL;
 
 	enable_oled(odev, value);
diff --git a/drivers/staging/bcm/Bcmchar.c b/drivers/staging/bcm/Bcmchar.c
index 2fa658e..179707b 100644
--- a/drivers/staging/bcm/Bcmchar.c
+++ b/drivers/staging/bcm/Bcmchar.c
@@ -161,6 +161,7 @@
 	INT Status = STATUS_FAILURE;
 	int timeout = 0;
 	IOCTL_BUFFER IoBuffer;
+	int bytes;
 
 	BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "Parameters Passed to control IOCTL cmd=0x%X arg=0x%lX", cmd, arg);
 
@@ -230,11 +231,16 @@
 		if (!temp_buff)
 			return -ENOMEM;
 
-		Status = rdmalt(Adapter, (UINT)sRdmBuffer.Register,
+		bytes = rdmalt(Adapter, (UINT)sRdmBuffer.Register,
 				(PUINT)temp_buff, Bufflen);
-		if (Status == STATUS_SUCCESS) {
-			if (copy_to_user(IoBuffer.OutputBuffer, temp_buff, IoBuffer.OutputLength))
-				Status = -EFAULT;
+		if (bytes > 0) {
+			Status = STATUS_SUCCESS;
+			if (copy_to_user(IoBuffer.OutputBuffer, temp_buff, bytes)) {
+				kfree(temp_buff);
+				return -EFAULT;
+			}
+		} else {
+			Status = bytes;
 		}
 
 		kfree(temp_buff);
@@ -302,7 +308,11 @@
 		if (copy_from_user(&sRdmBuffer, IoBuffer.InputBuffer, IoBuffer.InputLength))
 			return -EFAULT;
 
-		/* FIXME: don't trust user supplied length */
+		if (IoBuffer.OutputLength > USHRT_MAX ||
+			IoBuffer.OutputLength == 0) {
+			return -EINVAL;
+		}
+
 		temp_buff = kmalloc(IoBuffer.OutputLength, GFP_KERNEL);
 		if (!temp_buff)
 			return STATUS_FAILURE;
@@ -318,11 +328,17 @@
 		}
 
 		uiTempVar = sRdmBuffer.Register & EEPROM_REJECT_MASK;
-		Status = rdmaltWithLock(Adapter, (UINT)sRdmBuffer.Register, (PUINT)temp_buff, IoBuffer.OutputLength);
+		bytes = rdmaltWithLock(Adapter, (UINT)sRdmBuffer.Register, (PUINT)temp_buff, IoBuffer.OutputLength);
 
-		if (Status == STATUS_SUCCESS)
-			if (copy_to_user(IoBuffer.OutputBuffer, temp_buff, IoBuffer.OutputLength))
-				Status = -EFAULT;
+		if (bytes > 0) {
+			Status = STATUS_SUCCESS;
+			if (copy_to_user(IoBuffer.OutputBuffer, temp_buff, bytes)) {
+				kfree(temp_buff);
+				return -EFAULT;
+			}
+		} else {
+			Status = bytes;
+		}
 
 		kfree(temp_buff);
 		break;
@@ -437,12 +453,14 @@
 			}
 		}
 
-		Status = rdmaltWithLock(Adapter, (UINT)GPIO_MODE_REGISTER, (PUINT)ucResetValue, sizeof(UINT));
-
-		if (STATUS_SUCCESS != Status) {
+		bytes = rdmaltWithLock(Adapter, (UINT)GPIO_MODE_REGISTER, (PUINT)ucResetValue, sizeof(UINT));
+		if (bytes < 0) {
+			Status = bytes;
 			BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,
 					"GPIO_MODE_REGISTER read failed");
 			break;
+		} else {
+			Status = STATUS_SUCCESS;
 		}
 
 		/* Set the gpio mode register to output */
@@ -519,12 +537,15 @@
 		uiBit = gpio_info.uiGpioNumber;
 
 		/* Set the gpio output register */
-		Status = rdmaltWithLock(Adapter, (UINT)GPIO_PIN_STATE_REGISTER,
+		bytes = rdmaltWithLock(Adapter, (UINT)GPIO_PIN_STATE_REGISTER,
 					(PUINT)ucRead, sizeof(UINT));
 
-		if (Status != STATUS_SUCCESS) {
+		if (bytes < 0) {
+			Status = bytes;
 			BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "RDM Failed\n");
 			return Status;
+		} else {
+			Status = STATUS_SUCCESS;
 		}
 	}
 	break;
@@ -590,11 +611,14 @@
 		}
 
 		if (pgpio_multi_info[WIMAX_IDX].uiGPIOMask) {
-			Status = rdmaltWithLock(Adapter, (UINT)GPIO_PIN_STATE_REGISTER, (PUINT)ucResetValue, sizeof(UINT));
+			bytes = rdmaltWithLock(Adapter, (UINT)GPIO_PIN_STATE_REGISTER, (PUINT)ucResetValue, sizeof(UINT));
 
-			if (Status != STATUS_SUCCESS) {
+			if (bytes < 0) {
+				Status = bytes;
 				BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "RDM to GPIO_PIN_STATE_REGISTER Failed.");
 				return Status;
+			} else {
+				Status = STATUS_SUCCESS;
 			}
 
 			pgpio_multi_info[WIMAX_IDX].uiGPIOValue = (*(UINT *)ucResetValue &
@@ -605,7 +629,7 @@
 		if (Status) {
 			BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0,
 					"Failed while copying Content to IOBufer for user space err:%d", Status);
-			break;
+			return -EFAULT;
 		}
 	}
 	break;
@@ -629,11 +653,14 @@
 		if (copy_from_user(&gpio_multi_mode, IoBuffer.InputBuffer, IoBuffer.InputLength))
 			return -EFAULT;
 
-		Status = rdmaltWithLock(Adapter, (UINT)GPIO_MODE_REGISTER, (PUINT)ucResetValue, sizeof(UINT));
+		bytes = rdmaltWithLock(Adapter, (UINT)GPIO_MODE_REGISTER, (PUINT)ucResetValue, sizeof(UINT));
 
-		if (STATUS_SUCCESS != Status) {
+		if (bytes < 0) {
+			Status = bytes;
 			BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Read of GPIO_MODE_REGISTER failed");
 			return Status;
+		} else {
+			Status = STATUS_SUCCESS;
 		}
 
 		/* Validating the request */
@@ -678,7 +705,7 @@
 		if (Status) {
 			BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0,
 					"Failed while copying Content to IOBufer for user space err:%d", Status);
-			break;
+			return -EFAULT;
 		}
 	}
 	break;
@@ -706,9 +733,8 @@
 			return -ENOMEM;
 
 		if (copy_from_user(pvBuffer, IoBuffer.InputBuffer, IoBuffer.InputLength)) {
-			Status = -EFAULT;
 			kfree(pvBuffer);
-			break;
+			return -EFAULT;
 		}
 
 		down(&Adapter->LowPowerModeSync);
@@ -733,8 +759,7 @@
 	}
 
 	case IOCTL_BCM_BUFFER_DOWNLOAD_START: {
-		INT NVMAccess = down_trylock(&Adapter->NVMRdmWrmLock);
-		if (NVMAccess) {
+		if (down_trylock(&Adapter->NVMRdmWrmLock)) {
 			BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,
 					"IOCTL_BCM_CHIP_RESET not allowed as EEPROM Read/Write is in progress\n");
 			return -EACCES;
@@ -743,157 +768,162 @@
 		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0,
 				"Starting the firmware download PID =0x%x!!!!\n", current->pid);
 
-		if (!down_trylock(&Adapter->fw_download_sema)) {
-			Adapter->bBinDownloaded = FALSE;
-			Adapter->fw_download_process_pid = current->pid;
-			Adapter->bCfgDownloaded = FALSE;
-			Adapter->fw_download_done = FALSE;
-			netif_carrier_off(Adapter->dev);
-			netif_stop_queue(Adapter->dev);
-			Status = reset_card_proc(Adapter);
-			if (Status) {
-				pr_err(PFX "%s: reset_card_proc Failed!\n", Adapter->dev->name);
-				up(&Adapter->fw_download_sema);
-				up(&Adapter->NVMRdmWrmLock);
-				break;
-			}
-			mdelay(10);
-		} else {
-			Status = -EBUSY;
+		if (down_trylock(&Adapter->fw_download_sema))
+			return -EBUSY;
+
+		Adapter->bBinDownloaded = FALSE;
+		Adapter->fw_download_process_pid = current->pid;
+		Adapter->bCfgDownloaded = FALSE;
+		Adapter->fw_download_done = FALSE;
+		netif_carrier_off(Adapter->dev);
+		netif_stop_queue(Adapter->dev);
+		Status = reset_card_proc(Adapter);
+		if (Status) {
+			pr_err(PFX "%s: reset_card_proc Failed!\n", Adapter->dev->name);
+			up(&Adapter->fw_download_sema);
+			up(&Adapter->NVMRdmWrmLock);
+			return Status;
 		}
+		mdelay(10);
 
 		up(&Adapter->NVMRdmWrmLock);
-		break;
+		return Status;
 	}
 
 	case IOCTL_BCM_BUFFER_DOWNLOAD: {
 		FIRMWARE_INFO *psFwInfo = NULL;
 		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Starting the firmware download PID =0x%x!!!!\n", current->pid);
-		do {
-			if (!down_trylock(&Adapter->fw_download_sema)) {
-				BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0,
-						"Invalid way to download buffer. Use Start and then call this!!!\n");
-				Status = -EINVAL;
-				break;
-			}
 
-			/* Copy Ioctl Buffer structure */
-			if (copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER)))
-				return -EFAULT;
-
+		if (!down_trylock(&Adapter->fw_download_sema)) {
 			BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0,
-					"Length for FW DLD is : %lx\n", IoBuffer.InputLength);
+					"Invalid way to download buffer. Use Start and then call this!!!\n");
+			up(&Adapter->fw_download_sema);
+			Status = -EINVAL;
+			return Status;
+		}
 
-			if (IoBuffer.InputLength > sizeof(FIRMWARE_INFO))
-				return -EINVAL;
+		/* Copy Ioctl Buffer structure */
+		if (copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER))) {
+			up(&Adapter->fw_download_sema);
+			return -EFAULT;
+		}
 
-			psFwInfo = kmalloc(sizeof(*psFwInfo), GFP_KERNEL);
-			if (!psFwInfo)
-				return -ENOMEM;
+		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0,
+				"Length for FW DLD is : %lx\n", IoBuffer.InputLength);
 
-			if (copy_from_user(psFwInfo, IoBuffer.InputBuffer, IoBuffer.InputLength))
-				return -EFAULT;
+		if (IoBuffer.InputLength > sizeof(FIRMWARE_INFO)) {
+			up(&Adapter->fw_download_sema);
+			return -EINVAL;
+		}
 
-			if (!psFwInfo->pvMappedFirmwareAddress ||
-				(psFwInfo->u32FirmwareLength == 0)) {
+		psFwInfo = kmalloc(sizeof(*psFwInfo), GFP_KERNEL);
+		if (!psFwInfo) {
+			up(&Adapter->fw_download_sema);
+			return -ENOMEM;
+		}
 
-				BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Something else is wrong %lu\n",
-						psFwInfo->u32FirmwareLength);
-				Status = -EINVAL;
-				break;
+		if (copy_from_user(psFwInfo, IoBuffer.InputBuffer, IoBuffer.InputLength)) {
+			up(&Adapter->fw_download_sema);
+			return -EFAULT;
+		}
+
+		if (!psFwInfo->pvMappedFirmwareAddress ||
+			(psFwInfo->u32FirmwareLength == 0)) {
+
+			BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Something else is wrong %lu\n",
+					psFwInfo->u32FirmwareLength);
+			up(&Adapter->fw_download_sema);
+			Status = -EINVAL;
+			return Status;
+		}
+
+		Status = bcm_ioctl_fw_download(Adapter, psFwInfo);
+
+		if (Status != STATUS_SUCCESS) {
+			if (psFwInfo->u32StartingAddress == CONFIG_BEGIN_ADDR)
+				BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "IOCTL: Configuration File Upload Failed\n");
+			else
+				BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0,	"IOCTL: Firmware File Upload Failed\n");
+
+			/* up(&Adapter->fw_download_sema); */
+
+			if (Adapter->LEDInfo.led_thread_running & BCM_LED_THREAD_RUNNING_ACTIVELY) {
+				Adapter->DriverState = DRIVER_INIT;
+				Adapter->LEDInfo.bLedInitDone = FALSE;
+				wake_up(&Adapter->LEDInfo.notify_led_event);
 			}
-
-			Status = bcm_ioctl_fw_download(Adapter, psFwInfo);
-
-			if (Status != STATUS_SUCCESS) {
-				if (psFwInfo->u32StartingAddress == CONFIG_BEGIN_ADDR)
-					BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "IOCTL: Configuration File Upload Failed\n");
-				else
-					BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0,	"IOCTL: Firmware File Upload Failed\n");
-
-				/* up(&Adapter->fw_download_sema); */
-
-				if (Adapter->LEDInfo.led_thread_running & BCM_LED_THREAD_RUNNING_ACTIVELY) {
-					Adapter->DriverState = DRIVER_INIT;
-					Adapter->LEDInfo.bLedInitDone = FALSE;
-					wake_up(&Adapter->LEDInfo.notify_led_event);
-				}
-			}
-			break;
-
-		} while (0);
+		}
 
 		if (Status != STATUS_SUCCESS)
 			up(&Adapter->fw_download_sema);
 
 		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, OSAL_DBG, DBG_LVL_ALL, "IOCTL: Firmware File Uploaded\n");
 		kfree(psFwInfo);
-		break;
+		return Status;
 	}
 
 	case IOCTL_BCM_BUFFER_DOWNLOAD_STOP: {
-		INT NVMAccess = down_trylock(&Adapter->NVMRdmWrmLock);
+		if (!down_trylock(&Adapter->fw_download_sema)) {
+			up(&Adapter->fw_download_sema);
+			return -EINVAL;
+		}
 
-		if (NVMAccess) {
+		if (down_trylock(&Adapter->NVMRdmWrmLock)) {
 			BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0,
 					"FW download blocked as EEPROM Read/Write is in progress\n");
 			up(&Adapter->fw_download_sema);
 			return -EACCES;
 		}
 
-		if (down_trylock(&Adapter->fw_download_sema)) {
-			Adapter->bBinDownloaded = TRUE;
-			Adapter->bCfgDownloaded = TRUE;
-			atomic_set(&Adapter->CurrNumFreeTxDesc, 0);
-			Adapter->CurrNumRecvDescs = 0;
-			Adapter->downloadDDR = 0;
+		Adapter->bBinDownloaded = TRUE;
+		Adapter->bCfgDownloaded = TRUE;
+		atomic_set(&Adapter->CurrNumFreeTxDesc, 0);
+		Adapter->CurrNumRecvDescs = 0;
+		Adapter->downloadDDR = 0;
 
-			/* setting the Mips to Run */
-			Status = run_card_proc(Adapter);
+		/* setting the Mips to Run */
+		Status = run_card_proc(Adapter);
 
-			if (Status) {
-				BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Firm Download Failed\n");
-				up(&Adapter->fw_download_sema);
-				up(&Adapter->NVMRdmWrmLock);
-				break;
-			} else {
-				BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG,
-						DBG_LVL_ALL, "Firm Download Over...\n");
-			}
-
-			mdelay(10);
-
-			/* Wait for MailBox Interrupt */
-			if (StartInterruptUrb((PS_INTERFACE_ADAPTER)Adapter->pvInterfaceAdapter))
-				BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Unable to send interrupt...\n");
-
-			timeout = 5*HZ;
-			Adapter->waiting_to_fw_download_done = FALSE;
-			wait_event_timeout(Adapter->ioctl_fw_dnld_wait_queue,
-					Adapter->waiting_to_fw_download_done, timeout);
-			Adapter->fw_download_process_pid = INVALID_PID;
-			Adapter->fw_download_done = TRUE;
-			atomic_set(&Adapter->CurrNumFreeTxDesc, 0);
-			Adapter->CurrNumRecvDescs = 0;
-			Adapter->PrevNumRecvDescs = 0;
-			atomic_set(&Adapter->cntrlpktCnt, 0);
-			Adapter->LinkUpStatus = 0;
-			Adapter->LinkStatus = 0;
-
-			if (Adapter->LEDInfo.led_thread_running & BCM_LED_THREAD_RUNNING_ACTIVELY) {
-				Adapter->DriverState = FW_DOWNLOAD_DONE;
-				wake_up(&Adapter->LEDInfo.notify_led_event);
-			}
-
-			if (!timeout)
-				Status = -ENODEV;
+		if (Status) {
+			BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Firm Download Failed\n");
+			up(&Adapter->fw_download_sema);
+			up(&Adapter->NVMRdmWrmLock);
+			return Status;
 		} else {
-			Status = -EINVAL;
+			BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG,
+					DBG_LVL_ALL, "Firm Download Over...\n");
 		}
 
+		mdelay(10);
+
+		/* Wait for MailBox Interrupt */
+		if (StartInterruptUrb((PS_INTERFACE_ADAPTER)Adapter->pvInterfaceAdapter))
+			BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Unable to send interrupt...\n");
+
+		timeout = 5*HZ;
+		Adapter->waiting_to_fw_download_done = FALSE;
+		wait_event_timeout(Adapter->ioctl_fw_dnld_wait_queue,
+				Adapter->waiting_to_fw_download_done, timeout);
+		Adapter->fw_download_process_pid = INVALID_PID;
+		Adapter->fw_download_done = TRUE;
+		atomic_set(&Adapter->CurrNumFreeTxDesc, 0);
+		Adapter->CurrNumRecvDescs = 0;
+		Adapter->PrevNumRecvDescs = 0;
+		atomic_set(&Adapter->cntrlpktCnt, 0);
+		Adapter->LinkUpStatus = 0;
+		Adapter->LinkStatus = 0;
+
+		if (Adapter->LEDInfo.led_thread_running & BCM_LED_THREAD_RUNNING_ACTIVELY) {
+			Adapter->DriverState = FW_DOWNLOAD_DONE;
+			wake_up(&Adapter->LEDInfo.notify_led_event);
+		}
+
+		if (!timeout)
+			Status = -ENODEV;
+
 		up(&Adapter->fw_download_sema);
 		up(&Adapter->NVMRdmWrmLock);
-		break;
+		return Status;
 	}
 
 	case IOCTL_BE_BUCKET_SIZE:
@@ -969,11 +999,15 @@
 	}
 
 	case IOCTL_BCM_GET_DRIVER_VERSION: {
+		ulong len;
+
 		/* Copy Ioctl Buffer structure */
 		if (copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER)))
 			return -EFAULT;
 
-		if (copy_to_user(IoBuffer.OutputBuffer, VER_FILEVERSION_STR, IoBuffer.OutputLength))
+		len = min_t(ulong, IoBuffer.OutputLength, strlen(VER_FILEVERSION_STR) + 1);
+
+		if (copy_to_user(IoBuffer.OutputBuffer, VER_FILEVERSION_STR, len))
 			return -EFAULT;
 		Status = STATUS_SUCCESS;
 		break;
@@ -985,8 +1019,7 @@
 		/* Copy Ioctl Buffer structure */
 		if (copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER))) {
 			BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "copy_from_user failed..\n");
-			Status = -EFAULT;
-			break;
+			return -EFAULT;
 		}
 
 		if (IoBuffer.OutputLength != sizeof(link_state)) {
@@ -1001,8 +1034,7 @@
 
 		if (copy_to_user(IoBuffer.OutputBuffer, &link_state, min_t(size_t, sizeof(link_state), IoBuffer.OutputLength))) {
 			BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Copy_to_user Failed..\n");
-			Status = -EFAULT;
-			break;
+			return -EFAULT;
 		}
 		Status = STATUS_SUCCESS;
 		break;
@@ -1068,8 +1100,10 @@
 		GetDroppedAppCntrlPktMibs(temp_buff, pTarang);
 
 		if (Status != STATUS_FAILURE)
-			if (copy_to_user(IoBuffer.OutputBuffer, temp_buff, sizeof(S_MIBS_HOST_STATS_MIBS)))
-				Status = -EFAULT;
+			if (copy_to_user(IoBuffer.OutputBuffer, temp_buff, sizeof(S_MIBS_HOST_STATS_MIBS))) {
+				kfree(temp_buff);
+				return -EFAULT;
+			}
 
 		kfree(temp_buff);
 		break;
@@ -1103,7 +1137,9 @@
 		if (copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER)))
 			return -EFAULT;
 
-		/* FIXME: restrict length */
+		if (IoBuffer.InputLength < sizeof(ULONG) * 2)
+			return -EINVAL;
+
 		pvBuffer = kmalloc(IoBuffer.InputLength, GFP_KERNEL);
 		if (!pvBuffer)
 			return -ENOMEM;
@@ -1111,8 +1147,7 @@
 		/* Get WrmBuffer structure */
 		if (copy_from_user(pvBuffer, IoBuffer.InputBuffer, IoBuffer.InputLength)) {
 			kfree(pvBuffer);
-			Status = -EFAULT;
-			break;
+			return -EFAULT;
 		}
 
 		pBulkBuffer = (PBULKWRM_BUFFER)pvBuffer;
@@ -1242,8 +1277,7 @@
 		memset(&tv1, 0, sizeof(struct timeval));
 		if ((Adapter->eNVMType == NVM_FLASH) && (Adapter->uiFlashLayoutMajorVersion == 0)) {
 			BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "The Flash Control Section is Corrupted. Hence Rejection on NVM Read/Write\n");
-			Status = -EFAULT;
-			break;
+			return -EFAULT;
 		}
 
 		if (IsFlash2x(Adapter)) {
@@ -1252,7 +1286,7 @@
 				(Adapter->eActiveDSD != DSD2)) {
 
 				BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "No DSD is active..hence NVM Command is blocked");
-				return STATUS_FAILURE ;
+				return STATUS_FAILURE;
 			}
 		}
 
@@ -1271,8 +1305,7 @@
 
 		if ((stNVMReadWrite.uiOffset + stNVMReadWrite.uiNumBytes) > Adapter->uiNVMDSDSize) {
 			/* BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Can't allow access beyond NVM Size: 0x%x 0x%x\n", stNVMReadWrite.uiOffset, stNVMReadWrite.uiNumBytes); */
-			Status = STATUS_FAILURE;
-			break;
+			return STATUS_FAILURE;
 		}
 
 		pReadData = kzalloc(stNVMReadWrite.uiNumBytes, GFP_KERNEL);
@@ -1280,9 +1313,8 @@
 			return -ENOMEM;
 
 		if (copy_from_user(pReadData, stNVMReadWrite.pBuffer, stNVMReadWrite.uiNumBytes)) {
-			Status = -EFAULT;
 			kfree(pReadData);
-			break;
+			return -EFAULT;
 		}
 
 		do_gettimeofday(&tv0);
@@ -1309,7 +1341,7 @@
 
 			if (copy_to_user(stNVMReadWrite.pBuffer, pReadData, stNVMReadWrite.uiNumBytes)) {
 				kfree(pReadData);
-				Status = -EFAULT;
+				return -EFAULT;
 			}
 		} else {
 			down(&Adapter->NVMRdmWrmLock);
@@ -1377,9 +1409,8 @@
 		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, " timetaken by Write/read :%ld msec\n", (tv1.tv_sec - tv0.tv_sec)*1000 + (tv1.tv_usec - tv0.tv_usec)/1000);
 
 		kfree(pReadData);
-		Status = STATUS_SUCCESS;
+		return STATUS_SUCCESS;
 	}
-	break;
 
 	case IOCTL_BCM_FLASH2X_SECTION_READ: {
 		FLASH2X_READWRITE sFlash2xRead = {0};
@@ -1456,7 +1487,9 @@
 			Status = copy_to_user(OutPutBuff, pReadBuff, ReadBytes);
 			if (Status) {
 				BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "Copy to use failed with status :%d", Status);
-				break;
+				up(&Adapter->NVMRdmWrmLock);
+				kfree(pReadBuff);
+				return -EFAULT;
 			}
 			NOB = NOB - ReadBytes;
 			if (NOB) {
@@ -1548,7 +1581,9 @@
 			Status = copy_from_user(pWriteBuff, InputAddr, WriteBytes);
 			if (Status) {
 				BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Copy to user failed with status :%d", Status);
-				break;
+				up(&Adapter->NVMRdmWrmLock);
+				kfree(pWriteBuff);
+				return -EFAULT;
 			}
 			BCM_DEBUG_PRINT_BUFFER(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, pWriteBuff, WriteBytes);
 
@@ -1608,8 +1643,10 @@
 
 		BcmGetFlash2xSectionalBitMap(Adapter, psFlash2xBitMap);
 		up(&Adapter->NVMRdmWrmLock);
-		if (copy_to_user(IoBuffer.OutputBuffer, psFlash2xBitMap, sizeof(FLASH2X_BITMAP)))
-			Status = -EFAULT;
+		if (copy_to_user(IoBuffer.OutputBuffer, psFlash2xBitMap, sizeof(FLASH2X_BITMAP))) {
+			kfree(psFlash2xBitMap);
+			return -EFAULT;
+		}
 
 		kfree(psFlash2xBitMap);
 	}
@@ -1627,13 +1664,13 @@
 		Status = copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER));
 		if (Status) {
 			BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Copy of IOCTL BUFFER failed");
-			return Status;
+			return -EFAULT;
 		}
 
 		Status = copy_from_user(&eFlash2xSectionVal, IoBuffer.InputBuffer, sizeof(INT));
 		if (Status) {
 			BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Copy of flash section val failed");
-			return Status;
+			return -EFAULT;
 		}
 
 		down(&Adapter->NVMRdmWrmLock);
@@ -1677,13 +1714,13 @@
 		Status = copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER));
 		if (Status) {
 			BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Copy of IOCTL BUFFER failed Status :%d", Status);
-			return Status;
+			return -EFAULT;
 		}
 
 		Status = copy_from_user(&sCopySectStrut, IoBuffer.InputBuffer, sizeof(FLASH2X_COPY_SECTION));
 		if (Status) {
 			BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Copy of Copy_Section_Struct failed with Status :%d", Status);
-			return Status;
+			return -EFAULT;
 		}
 
 		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "Source SEction :%x", sCopySectStrut.SrcSection);
@@ -1744,7 +1781,7 @@
 		Status = copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER));
 		if (Status) {
 			BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Copy of IOCTL BUFFER failed");
-			break;
+			return -EFAULT;
 		}
 
 		if (Adapter->eNVMType != NVM_FLASH) {
@@ -1783,12 +1820,12 @@
 		Status = copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER));
 		if (Status) {
 			BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Copy of IOCTL BUFFER failed");
-			return Status;
+			return -EFAULT;
 		}
 		Status = copy_from_user(&eFlash2xSectionVal, IoBuffer.InputBuffer, sizeof(INT));
 		if (Status) {
 			BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Copy of flash section val failed");
-			return Status;
+			return -EFAULT;
 		}
 
 		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "Read Section :%d", eFlash2xSectionVal);
@@ -1830,8 +1867,7 @@
 		/* Copy Ioctl Buffer structure */
 		if (copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER))) {
 			BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "copy_from_user 1 failed\n");
-			Status = -EFAULT;
-			break;
+			return -EFAULT;
 		}
 
 		if (copy_from_user(&stNVMRead, IoBuffer.OutputBuffer, sizeof(NVM_READWRITE)))
@@ -1886,7 +1922,9 @@
 			Status = copy_to_user(OutPutBuff, pReadBuff, ReadBytes);
 			if (Status) {
 				BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Copy to use failed with status :%d", Status);
-				break;
+				up(&Adapter->NVMRdmWrmLock);
+				kfree(pReadBuff);
+				return -EFAULT;
 			}
 			NOB = NOB - ReadBytes;
 			if (NOB) {
@@ -1907,8 +1945,7 @@
 		Status = copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER));
 		if (Status) {
 			BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "copy of Ioctl buffer is failed from user space");
-			Status = -EFAULT;
-			break;
+			return -EFAULT;
 		}
 
 		if (IoBuffer.InputLength != sizeof(unsigned long)) {
@@ -1919,8 +1956,7 @@
 		Status = copy_from_user(&RxCntrlMsgBitMask, IoBuffer.InputBuffer, IoBuffer.InputLength);
 		if (Status) {
 			BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "copy of control bit mask failed from user space");
-			Status = -EFAULT;
-			break;
+			return -EFAULT;
 		}
 		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "\n Got user defined cntrl msg bit mask :%lx", RxCntrlMsgBitMask);
 		pTarang->RxCntrlMsgBitMask = RxCntrlMsgBitMask;
diff --git a/drivers/staging/bcm/HandleControlPacket.c b/drivers/staging/bcm/HandleControlPacket.c
index 2b1e9e1..b058e30 100644
--- a/drivers/staging/bcm/HandleControlPacket.c
+++ b/drivers/staging/bcm/HandleControlPacket.c
@@ -1,195 +1,208 @@
 /**
-@file HandleControlPacket.c
-This file contains the routines to deal with
-sending and receiving of control packets.
-*/
+ * @file HandleControlPacket.c
+ * This file contains the routines to deal with
+ * sending and receiving of control packets.
+ */
 #include "headers.h"
 
 /**
-When a control packet is received, analyze the
-"status" and call appropriate response function.
-Enqueue the control packet for Application.
-@return None
-*/
+ * When a control packet is received, analyze the
+ * "status" and call appropriate response function.
+ * Enqueue the control packet for Application.
+ * @return None
+ */
 static VOID handle_rx_control_packet(PMINI_ADAPTER Adapter, struct sk_buff *skb)
 {
-	PPER_TARANG_DATA	pTarang = NULL;
+	PPER_TARANG_DATA pTarang = NULL;
 	BOOLEAN HighPriorityMessage = FALSE;
-	struct sk_buff * newPacket = NULL;
+	struct sk_buff *newPacket = NULL;
 	CHAR cntrl_msg_mask_bit = 0;
-	BOOLEAN drop_pkt_flag = TRUE ;
+	BOOLEAN drop_pkt_flag = TRUE;
 	USHORT usStatus = *(PUSHORT)(skb->data);
 
 	if (netif_msg_pktdata(Adapter))
 		print_hex_dump(KERN_DEBUG, PFX "rx control: ", DUMP_PREFIX_NONE,
-			       16, 1, skb->data, skb->len, 0);
+				16, 1, skb->data, skb->len, 0);
 
-	switch(usStatus)
-	{
-		case CM_RESPONSES:               // 0xA0
-			BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CP_CTRL_PKT, DBG_LVL_ALL, "MAC Version Seems to be Non Multi-Classifier, rejected by Driver");
-			HighPriorityMessage = TRUE ;
-			break;
-		case CM_CONTROL_NEWDSX_MULTICLASSIFIER_RESP:
-			HighPriorityMessage = TRUE ;
-			if(Adapter->LinkStatus==LINKUP_DONE)
-			{
-				CmControlResponseMessage(Adapter,(skb->data +sizeof(USHORT)));
-			}
-			break;
-		case LINK_CONTROL_RESP:          //0xA2
-		case STATUS_RSP:          //0xA1
-			BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CP_CTRL_PKT, DBG_LVL_ALL,"LINK_CONTROL_RESP");
-			HighPriorityMessage = TRUE ;
-			LinkControlResponseMessage(Adapter,(skb->data + sizeof(USHORT)));
-			break;
-		case STATS_POINTER_RESP:       //0xA6
-			HighPriorityMessage = TRUE ;
-			StatisticsResponse(Adapter, (skb->data + sizeof(USHORT)));
-			break;
-		case IDLE_MODE_STATUS:			//0xA3
-			BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, CP_CTRL_PKT, DBG_LVL_ALL,"IDLE_MODE_STATUS Type Message Got from F/W");
-			InterfaceIdleModeRespond(Adapter, (PUINT)(skb->data +
-						sizeof(USHORT)));
-			HighPriorityMessage = TRUE ;
-			break;
+	switch (usStatus) {
+	case CM_RESPONSES:               /* 0xA0 */
+		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CP_CTRL_PKT,
+			DBG_LVL_ALL,
+			"MAC Version Seems to be Non Multi-Classifier, rejected by Driver");
+		HighPriorityMessage = TRUE;
+		break;
+	case CM_CONTROL_NEWDSX_MULTICLASSIFIER_RESP:
+		HighPriorityMessage = TRUE;
+		if (Adapter->LinkStatus == LINKUP_DONE)
+			CmControlResponseMessage(Adapter,
+				(skb->data + sizeof(USHORT)));
+		break;
+	case LINK_CONTROL_RESP:          /* 0xA2 */
+	case STATUS_RSP:                 /* 0xA1 */
+		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CP_CTRL_PKT,
+			DBG_LVL_ALL, "LINK_CONTROL_RESP");
+		HighPriorityMessage = TRUE;
+		LinkControlResponseMessage(Adapter,
+			(skb->data + sizeof(USHORT)));
+		break;
+	case STATS_POINTER_RESP:         /* 0xA6 */
+		HighPriorityMessage = TRUE;
+		StatisticsResponse(Adapter, (skb->data + sizeof(USHORT)));
+		break;
+	case IDLE_MODE_STATUS:           /* 0xA3 */
+		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CP_CTRL_PKT,
+			DBG_LVL_ALL,
+			"IDLE_MODE_STATUS Type Message Got from F/W");
+		InterfaceIdleModeRespond(Adapter, (PUINT)(skb->data +
+					sizeof(USHORT)));
+		HighPriorityMessage = TRUE;
+		break;
 
-		case AUTH_SS_HOST_MSG:
-			HighPriorityMessage = TRUE ;
-			break;
+	case AUTH_SS_HOST_MSG:
+		HighPriorityMessage = TRUE;
+		break;
 
-	 	default:
-			BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CP_CTRL_PKT, DBG_LVL_ALL,"Got Default Response");
-			/* Let the Application Deal with This Packet */
-			break;
+	default:
+		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CP_CTRL_PKT,
+			DBG_LVL_ALL, "Got Default Response");
+		/* Let the Application Deal with This Packet */
+		break;
 	}
 
-	//Queue The Control Packet to The Application Queues
+	/* Queue The Control Packet to The Application Queues */
 	down(&Adapter->RxAppControlQueuelock);
 
-	for (pTarang = Adapter->pTarangs; pTarang; pTarang = pTarang->next)
-    {
-       	if(Adapter->device_removed)
-		{
+	for (pTarang = Adapter->pTarangs; pTarang; pTarang = pTarang->next) {
+		if (Adapter->device_removed)
 			break;
-		}
 
-		drop_pkt_flag = TRUE ;
+		drop_pkt_flag = TRUE;
 		/*
-			There are cntrl msg from A0 to AC. It has been mapped to 0 to C bit in the cntrl mask.
-			Also, by default AD to BF has been masked to the rest of the bits... which wil be ON by default.
-			if mask bit is enable to particular pkt status, send it out to app else stop it.
-		*/
+		 * There are cntrl msg from A0 to AC. It has been mapped to 0 to
+		 * C bit in the cntrl mask.
+		 * Also, by default AD to BF has been masked to the rest of the
+		 * bits... which wil be ON by default.
+		 * if mask bit is enable to particular pkt status, send it out
+		 * to app else stop it.
+		 */
 		cntrl_msg_mask_bit = (usStatus & 0x1F);
-		//printk("\ninew  msg  mask bit which is disable in mask:%X", cntrl_msg_mask_bit);
-		if(pTarang->RxCntrlMsgBitMask & (1<<cntrl_msg_mask_bit))
-				drop_pkt_flag = FALSE;
+		/*
+		 * printk("\ninew  msg  mask bit which is disable in mask:%X",
+		 *	cntrl_msg_mask_bit);
+		 */
+		if (pTarang->RxCntrlMsgBitMask & (1 << cntrl_msg_mask_bit))
+			drop_pkt_flag = FALSE;
 
-		if ((drop_pkt_flag == TRUE)  || (pTarang->AppCtrlQueueLen > MAX_APP_QUEUE_LEN) ||
-					((pTarang->AppCtrlQueueLen > MAX_APP_QUEUE_LEN/2) && (HighPriorityMessage == FALSE)))
-		{
+		if ((drop_pkt_flag == TRUE) ||
+				(pTarang->AppCtrlQueueLen > MAX_APP_QUEUE_LEN)
+				|| ((pTarang->AppCtrlQueueLen >
+					MAX_APP_QUEUE_LEN / 2) &&
+				    (HighPriorityMessage == FALSE))) {
 			/*
-				Assumption:-
-				1. every tarang manages it own dropped pkt statitistics
-				2. Total packet dropped per tarang will be equal to the sum of all types of dropped
-					pkt by that tarang only.
-
-			*/
-			switch(*(PUSHORT)skb->data)
-			{
-				case CM_RESPONSES:
-					pTarang->stDroppedAppCntrlMsgs.cm_responses++;
-					break;
-				case CM_CONTROL_NEWDSX_MULTICLASSIFIER_RESP:
-				 pTarang->stDroppedAppCntrlMsgs.cm_control_newdsx_multiclassifier_resp++;
-					 break;
-				case LINK_CONTROL_RESP:
-					pTarang->stDroppedAppCntrlMsgs.link_control_resp++;
-					break;
-				case STATUS_RSP:
-					pTarang->stDroppedAppCntrlMsgs.status_rsp++;
-					break;
-				case STATS_POINTER_RESP:
-					pTarang->stDroppedAppCntrlMsgs.stats_pointer_resp++;
-					break;
-				case IDLE_MODE_STATUS:
-					pTarang->stDroppedAppCntrlMsgs.idle_mode_status++ ;
-					break;
-				case AUTH_SS_HOST_MSG:
-					pTarang->stDroppedAppCntrlMsgs.auth_ss_host_msg++ ;
-					break;
+			 * Assumption:-
+			 * 1. every tarang manages it own dropped pkt
+			 *    statitistics
+			 * 2. Total packet dropped per tarang will be equal to
+			 *    the sum of all types of dropped pkt by that
+			 *    tarang only.
+			 */
+			switch (*(PUSHORT)skb->data) {
+			case CM_RESPONSES:
+				pTarang->stDroppedAppCntrlMsgs.cm_responses++;
+				break;
+			case CM_CONTROL_NEWDSX_MULTICLASSIFIER_RESP:
+				pTarang->stDroppedAppCntrlMsgs.cm_control_newdsx_multiclassifier_resp++;
+				break;
+			case LINK_CONTROL_RESP:
+				pTarang->stDroppedAppCntrlMsgs.link_control_resp++;
+				break;
+			case STATUS_RSP:
+				pTarang->stDroppedAppCntrlMsgs.status_rsp++;
+				break;
+			case STATS_POINTER_RESP:
+				pTarang->stDroppedAppCntrlMsgs.stats_pointer_resp++;
+				break;
+			case IDLE_MODE_STATUS:
+				pTarang->stDroppedAppCntrlMsgs.idle_mode_status++;
+				break;
+			case AUTH_SS_HOST_MSG:
+				pTarang->stDroppedAppCntrlMsgs.auth_ss_host_msg++;
+				break;
 			default:
-					pTarang->stDroppedAppCntrlMsgs.low_priority_message++ ;
-					break;
+				pTarang->stDroppedAppCntrlMsgs.low_priority_message++;
+				break;
 			}
 
 			continue;
 		}
 
-        newPacket = skb_clone(skb, GFP_KERNEL);
-        if (!newPacket)
-           break;
-        ENQUEUEPACKET(pTarang->RxAppControlHead,pTarang->RxAppControlTail,
-				newPacket);
-        pTarang->AppCtrlQueueLen++;
-    }
+		newPacket = skb_clone(skb, GFP_KERNEL);
+		if (!newPacket)
+			break;
+		ENQUEUEPACKET(pTarang->RxAppControlHead,
+				pTarang->RxAppControlTail, newPacket);
+		pTarang->AppCtrlQueueLen++;
+	}
 	up(&Adapter->RxAppControlQueuelock);
-    wake_up(&Adapter->process_read_wait_queue);
-    dev_kfree_skb(skb);
-	BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CP_CTRL_PKT, DBG_LVL_ALL, "After wake_up_interruptible");
+	wake_up(&Adapter->process_read_wait_queue);
+	dev_kfree_skb(skb);
+	BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CP_CTRL_PKT, DBG_LVL_ALL,
+			"After wake_up_interruptible");
 }
 
 /**
-@ingroup ctrl_pkt_functions
-Thread to handle control pkt reception
-*/
-int control_packet_handler  (PMINI_ADAPTER Adapter  /**< pointer to adapter object*/
-						)
+ * @ingroup ctrl_pkt_functions
+ * Thread to handle control pkt reception
+ */
+int control_packet_handler(PMINI_ADAPTER Adapter /* pointer to adapter object*/)
 {
-	struct sk_buff *ctrl_packet= NULL;
+	struct sk_buff *ctrl_packet = NULL;
 	unsigned long flags = 0;
-	//struct timeval tv ;
-	//int *puiBuffer = NULL ;
-	BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, CP_CTRL_PKT, DBG_LVL_ALL, "Entering to make thread wait on control packet event!");
-	while(1)
-	{
+	/* struct timeval tv; */
+	/* int *puiBuffer = NULL; */
+	BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CP_CTRL_PKT, DBG_LVL_ALL,
+		"Entering to make thread wait on control packet event!");
+	while (1) {
 		wait_event_interruptible(Adapter->process_rx_cntrlpkt,
-								 atomic_read(&Adapter->cntrlpktCnt) ||
-								 Adapter->bWakeUpDevice ||
-								 kthread_should_stop()
-								);
+			atomic_read(&Adapter->cntrlpktCnt) ||
+			Adapter->bWakeUpDevice ||
+			kthread_should_stop());
 
 
-		if(kthread_should_stop())
-		{
-			BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, CP_CTRL_PKT, DBG_LVL_ALL, "Exiting \n");
+		if (kthread_should_stop()) {
+			BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CP_CTRL_PKT,
+				DBG_LVL_ALL, "Exiting\n");
 			return 0;
 		}
-		if(TRUE == Adapter->bWakeUpDevice)
-		{
+		if (TRUE == Adapter->bWakeUpDevice) {
 			Adapter->bWakeUpDevice = FALSE;
-			if((FALSE == Adapter->bTriedToWakeUpFromlowPowerMode) &&
-				((TRUE == Adapter->IdleMode)|| (TRUE == Adapter->bShutStatus)))
-			{
-				BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, CP_CTRL_PKT, DBG_LVL_ALL, "Calling InterfaceAbortIdlemode\n");
-	//			Adapter->bTriedToWakeUpFromlowPowerMode = TRUE;
-				InterfaceIdleModeWakeup (Adapter);
+			if ((FALSE == Adapter->bTriedToWakeUpFromlowPowerMode)
+					&& ((TRUE == Adapter->IdleMode) ||
+					    (TRUE == Adapter->bShutStatus))) {
+				BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS,
+					CP_CTRL_PKT, DBG_LVL_ALL,
+					"Calling InterfaceAbortIdlemode\n");
+				/*
+				 * Adapter->bTriedToWakeUpFromlowPowerMode
+				 *					= TRUE;
+				 */
+				InterfaceIdleModeWakeup(Adapter);
 			}
 			continue;
 		}
 
-		while(atomic_read(&Adapter->cntrlpktCnt))
-		{
+		while (atomic_read(&Adapter->cntrlpktCnt)) {
 			spin_lock_irqsave(&Adapter->control_queue_lock, flags);
 			ctrl_packet = Adapter->RxControlHead;
-			if(ctrl_packet)
-			{
-				DEQUEUEPACKET(Adapter->RxControlHead,Adapter->RxControlTail);
-//				Adapter->RxControlHead=ctrl_packet->next;
+			if (ctrl_packet) {
+				DEQUEUEPACKET(Adapter->RxControlHead,
+					Adapter->RxControlTail);
+				/* Adapter->RxControlHead=ctrl_packet->next; */
 			}
 
-			spin_unlock_irqrestore (&Adapter->control_queue_lock, flags);
-		 	handle_rx_control_packet(Adapter, ctrl_packet);
+			spin_unlock_irqrestore(&Adapter->control_queue_lock,
+						flags);
+			handle_rx_control_packet(Adapter, ctrl_packet);
 			atomic_dec(&Adapter->cntrlpktCnt);
 		}
 
@@ -201,22 +214,22 @@
 INT flushAllAppQ(void)
 {
 	PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(gblpnetdev);
-	PPER_TARANG_DATA	pTarang = NULL;
+	PPER_TARANG_DATA pTarang = NULL;
 	struct sk_buff *PacketToDrop = NULL;
-	for(pTarang = Adapter->pTarangs; pTarang; pTarang = pTarang->next)
-	{
-		while(pTarang->RxAppControlHead != NULL)
-		{
-			PacketToDrop=pTarang->RxAppControlHead;
-			DEQUEUEPACKET(pTarang->RxAppControlHead,pTarang->RxAppControlTail);
+	for (pTarang = Adapter->pTarangs; pTarang; pTarang = pTarang->next) {
+		while (pTarang->RxAppControlHead != NULL) {
+			PacketToDrop = pTarang->RxAppControlHead;
+			DEQUEUEPACKET(pTarang->RxAppControlHead,
+					pTarang->RxAppControlTail);
 			dev_kfree_skb(PacketToDrop);
 		}
 		pTarang->AppCtrlQueueLen = 0;
-		//dropped contrl packet statistics also should be reset.
-		memset((PVOID)&pTarang->stDroppedAppCntrlMsgs, 0, sizeof(S_MIBS_DROPPED_APP_CNTRL_MESSAGES));
+		/* dropped contrl packet statistics also should be reset. */
+		memset((PVOID)&pTarang->stDroppedAppCntrlMsgs, 0,
+			sizeof(S_MIBS_DROPPED_APP_CNTRL_MESSAGES));
 
 	}
-	return STATUS_SUCCESS ;
+	return STATUS_SUCCESS;
 }
 
 
diff --git a/drivers/staging/bcm/InterfaceDld.c b/drivers/staging/bcm/InterfaceDld.c
index bcd86bb..65c352f 100644
--- a/drivers/staging/bcm/InterfaceDld.c
+++ b/drivers/staging/bcm/InterfaceDld.c
@@ -62,6 +62,7 @@
 	static int fw_down;
 	INT Status = STATUS_SUCCESS;
 	PS_INTERFACE_ADAPTER psIntfAdapter = (PS_INTERFACE_ADAPTER)arg;
+	int bytes;
 
 	buff = kmalloc(MAX_TRANSFER_CTRL_BYTE_USB, GFP_DMA);
 	buff_readback = kmalloc(MAX_TRANSFER_CTRL_BYTE_USB , GFP_DMA);
@@ -94,8 +95,9 @@
 			break;
 		}
 
-		Status = InterfaceRDM(psIntfAdapter, on_chip_loc, buff_readback, len);
-		if (Status) {
+		bytes = InterfaceRDM(psIntfAdapter, on_chip_loc, buff_readback, len);
+		if (bytes < 0) {
+			Status = bytes;
 			BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "RDM of len %d Failed! %d", len, reg);
 			goto exit;
 		}
@@ -302,6 +304,7 @@
 	UINT len = u32FirmwareLength;
 	INT retval = STATUS_SUCCESS;
 	PUCHAR readbackbuff = kzalloc(MAX_TRANSFER_CTRL_BYTE_USB, GFP_KERNEL);
+	int bytes;
 
 	if (NULL == readbackbuff) {
 		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "MEMORY ALLOCATION FAILED");
@@ -310,9 +313,10 @@
 
 	while (u32FirmwareLength && !retval) {
 		len = MIN_VAL(u32FirmwareLength, MAX_TRANSFER_CTRL_BYTE_USB);
-		retval = rdm(Adapter, u32StartingAddress, readbackbuff, len);
+		bytes = rdm(Adapter, u32StartingAddress, readbackbuff, len);
 
-		if (retval) {
+		if (bytes < 0) {
+			retval = bytes;
 			BCM_DEBUG_PRINT(Adapter, DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "rdm failed with status %d", retval);
 			break;
 		}
diff --git a/drivers/staging/bcm/InterfaceIdleMode.c b/drivers/staging/bcm/InterfaceIdleMode.c
index 96fa4ea..faeb03e 100644
--- a/drivers/staging/bcm/InterfaceIdleMode.c
+++ b/drivers/staging/bcm/InterfaceIdleMode.c
@@ -46,6 +46,7 @@
 {
 	int	status = STATUS_SUCCESS;
 	unsigned int	uiRegRead = 0;
+	int bytes;
 
 	BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, IDLE_MODE, DBG_LVL_ALL,"SubType of Message :0x%X", ntohl(*puiBuffer));
 
@@ -77,16 +78,16 @@
 			else if(Adapter->ulPowerSaveMode != DEVICE_POWERSAVE_MODE_AS_PROTOCOL_IDLE_MODE)
 			{
 				//clear on read Register
-				status = rdmalt(Adapter, DEVICE_INT_OUT_EP_REG0, &uiRegRead, sizeof(uiRegRead));
-				if(status)
-				{
+				bytes = rdmalt(Adapter, DEVICE_INT_OUT_EP_REG0, &uiRegRead, sizeof(uiRegRead));
+				if (bytes < 0) {
+					status = bytes;
 					BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "rdm failed while clearing H/W Abort Reg0");
 					return status;
 				}
 				//clear on read Register
-				status = rdmalt (Adapter, DEVICE_INT_OUT_EP_REG1, &uiRegRead, sizeof(uiRegRead));
-				if(status)
-				{
+				bytes = rdmalt(Adapter, DEVICE_INT_OUT_EP_REG1, &uiRegRead, sizeof(uiRegRead));
+				if (bytes < 0) {
+					status = bytes;
 					BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "rdm failed while clearing H/W Abort	Reg1");
 					return status;
 				}
@@ -117,9 +118,9 @@
 					Adapter->chip_id== BCS220_3)
 			{
 
-				status = rdmalt(Adapter, HPM_CONFIG_MSW, &uiRegRead, sizeof(uiRegRead));
-				if(status)
-				{
+				bytes = rdmalt(Adapter, HPM_CONFIG_MSW, &uiRegRead, sizeof(uiRegRead));
+				if (bytes < 0) {
+					status = bytes;
 					BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, IDLE_MODE, DBG_LVL_ALL, "rdm failed while Reading HPM_CONFIG_LDO145 Reg 0\n");
 					return status;
 				}
@@ -266,6 +267,8 @@
 {
 	unsigned int uiRegVal = 0;
 	INT Status = 0;
+	int bytes;
+
 	if(Adapter->ulPowerSaveMode == DEVICE_POWERSAVE_MODE_AS_MANUAL_CLOCK_GATING)
 	{
 		// clear idlemode interrupt.
@@ -282,16 +285,16 @@
 	{
 
         //clear Interrupt EP registers.
-		Status = rdmalt(Adapter,DEVICE_INT_OUT_EP_REG0, &uiRegVal, sizeof(uiRegVal));
-		if(Status)
-		{
+		bytes = rdmalt(Adapter,DEVICE_INT_OUT_EP_REG0, &uiRegVal, sizeof(uiRegVal));
+		if (bytes < 0) {
+			Status = bytes;
 			BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"RDM of DEVICE_INT_OUT_EP_REG0 failed with Err :%d", Status);
 			return;
 		}
 
-        Status = rdmalt(Adapter,DEVICE_INT_OUT_EP_REG1, &uiRegVal, sizeof(uiRegVal));
-		if(Status)
-		{
+		bytes = rdmalt(Adapter,DEVICE_INT_OUT_EP_REG1, &uiRegVal, sizeof(uiRegVal));
+		if (bytes < 0) {
+			Status = bytes;
 			BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"RDM of DEVICE_INT_OUT_EP_REG1 failed with Err :%d", Status);
 			return;
 		}
diff --git a/drivers/staging/bcm/InterfaceInit.c b/drivers/staging/bcm/InterfaceInit.c
index a09d351..8e3c586 100644
--- a/drivers/staging/bcm/InterfaceInit.c
+++ b/drivers/staging/bcm/InterfaceInit.c
@@ -68,7 +68,7 @@
 static void ConfigureEndPointTypesThroughEEPROM(PMINI_ADAPTER Adapter)
 {
 	unsigned long ulReg = 0;
-	int ret;
+	int bytes;
 
 	/* Program EP2 MAX_PKT_SIZE */
 	ulReg = ntohl(EP2_MPS_REG);
@@ -94,8 +94,8 @@
 	BeceemEEPROMBulkWrite(Adapter, (PUCHAR)&ulReg, 0x140, 4, TRUE);
 
 	/* Program TX EP as interrupt(Alternate Setting) */
-	ret = rdmalt(Adapter, 0x0F0110F8, (u32 *)&ulReg, sizeof(u32));
-	if (ret) {
+	bytes = rdmalt(Adapter, 0x0F0110F8, (u32 *)&ulReg, sizeof(u32));
+	if (bytes < 0) {
 		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL,
 			"reading of Tx EP failed\n");
 		return;
@@ -430,6 +430,7 @@
 	int usedIntOutForBulkTransfer = 0 ;
 	BOOLEAN bBcm16 = FALSE;
 	UINT uiData = 0;
+	int bytes;
 
 	/* Store the usb dev into interface adapter */
 	psIntfAdapter->udev = usb_get_dev(interface_to_usbdev(psIntfAdapter->interface));
@@ -438,9 +439,10 @@
 	psIntfAdapter->psAdapter->interface_rdm = BcmRDM;
 	psIntfAdapter->psAdapter->interface_wrm = BcmWRM;
 
-	retval = rdmalt(psIntfAdapter->psAdapter, CHIP_ID_REG,
+	bytes = rdmalt(psIntfAdapter->psAdapter, CHIP_ID_REG,
 			(u32 *)&(psIntfAdapter->psAdapter->chip_id), sizeof(u32));
-	if (retval) {
+	if (bytes < 0) {
+		retval = bytes;
 		BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, DBG_TYPE_PRINTK, 0, 0, "CHIP ID Read Failed\n");
 		return retval;
 	}
diff --git a/drivers/staging/bcm/InterfaceMisc.c b/drivers/staging/bcm/InterfaceMisc.c
index 61f878b..2218fae 100644
--- a/drivers/staging/bcm/InterfaceMisc.c
+++ b/drivers/staging/bcm/InterfaceMisc.c
@@ -5,7 +5,7 @@
 		PVOID buff,
 		INT len)
 {
-	int retval = 0;
+	int bytes;
 	USHORT usRetries = 0;
 
 	if (psIntfAdapter == NULL) {
@@ -30,7 +30,7 @@
 	psIntfAdapter->psAdapter->DeviceAccess = TRUE;
 
 	do {
-		retval = usb_control_msg(psIntfAdapter->udev,
+		bytes = usb_control_msg(psIntfAdapter->udev,
 					usb_rcvctrlpipe(psIntfAdapter->udev, 0),
 					0x02,
 					0xC2,
@@ -41,22 +41,20 @@
 					5000);
 
 		usRetries++;
-		if (-ENODEV == retval) {
+		if (-ENODEV == bytes) {
 			psIntfAdapter->psAdapter->device_removed = TRUE;
 			break;
 		}
 
-	} while ((retval < 0) && (usRetries < MAX_RDM_WRM_RETIRES));
+	} while ((bytes < 0) && (usRetries < MAX_RDM_WRM_RETIRES));
 
-	if (retval < 0)	{
-		BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, DBG_TYPE_OTHERS, RDM, DBG_LVL_ALL, "RDM failed status :%d, retires :%d", retval, usRetries);
-		psIntfAdapter->psAdapter->DeviceAccess = FALSE;
-		return retval;
-	} else {
-		BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, DBG_TYPE_OTHERS, RDM, DBG_LVL_ALL, "RDM sent %d", retval);
-		psIntfAdapter->psAdapter->DeviceAccess = FALSE;
-		return STATUS_SUCCESS;
-	}
+	if (bytes < 0)
+		BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, DBG_TYPE_OTHERS, RDM, DBG_LVL_ALL, "RDM failed status :%d, retires :%d", bytes, usRetries);
+	else
+		BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, DBG_TYPE_OTHERS, RDM, DBG_LVL_ALL, "RDM sent %d", bytes);
+
+	psIntfAdapter->psAdapter->DeviceAccess = FALSE;
+	return bytes;
 }
 
 INT InterfaceWRM(PS_INTERFACE_ADAPTER psIntfAdapter,
diff --git a/drivers/staging/bcm/Misc.c b/drivers/staging/bcm/Misc.c
index e9f29d5..c7725e1 100644
--- a/drivers/staging/bcm/Misc.c
+++ b/drivers/staging/bcm/Misc.c
@@ -814,6 +814,7 @@
 	PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(gblpnetdev);
 	PS_INTERFACE_ADAPTER psIntfAdapter = NULL;
 	unsigned int value = 0, uiResetValue = 0;
+	int bytes;
 
 	psIntfAdapter = ((PS_INTERFACE_ADAPTER)(ps_adapter->pvInterfaceAdapter));
 	ps_adapter->bDDRInitDone = FALSE;
@@ -848,8 +849,9 @@
 			ps_adapter->chip_id == BCS250_BC ||
 			ps_adapter->chip_id == BCS220_3) {
 
-			retval = rdmalt(ps_adapter, HPM_CONFIG_LDO145, &value, sizeof(value));
-			if (retval < 0) {
+			bytes = rdmalt(ps_adapter, HPM_CONFIG_LDO145, &value, sizeof(value));
+			if (bytes < 0) {
+				retval = bytes;
 				BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "read failed with status :%d", retval);
 				goto err_exit;
 			}
@@ -862,8 +864,9 @@
 			}
 		}
 	} else {
-		retval = rdmalt(ps_adapter, 0x0f007018, &value, sizeof(value));
-		if (retval < 0) {
+		bytes = rdmalt(ps_adapter, 0x0f007018, &value, sizeof(value));
+		if (bytes < 0) {
+			retval = bytes;
 			BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "read failed with status :%d", retval);
 			goto err_exit;
 		}
@@ -925,11 +928,16 @@
 
 int run_card_proc(PMINI_ADAPTER ps_adapter)
 {
+	int status = STATUS_SUCCESS;
+	int bytes;
+
 	unsigned int value = 0;
 	{
-		if (rdmalt(ps_adapter, CLOCK_RESET_CNTRL_REG_1, &value, sizeof(value)) < 0) {
+		bytes = rdmalt(ps_adapter, CLOCK_RESET_CNTRL_REG_1, &value, sizeof(value));
+		if (bytes < 0) {
+			status = bytes;
 			BCM_DEBUG_PRINT(ps_adapter, DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "%s:%d\n", __func__, __LINE__);
-			return STATUS_FAILURE;
+			return status;
 		}
 
 		if (ps_adapter->bFlashBoot)
@@ -942,7 +950,7 @@
 			return STATUS_FAILURE;
 		}
 	}
-	return STATUS_SUCCESS;
+	return status;
 }
 
 int InitCardAndDownloadFirmware(PMINI_ADAPTER ps_adapter)
@@ -1215,6 +1223,7 @@
 	int status = 0, i = 0;
 	unsigned int temp = 0;
 	unsigned char *pucmacaddr = kmalloc(MAC_ADDRESS_SIZE, GFP_KERNEL);
+	int bytes;
 
 	if (!pucmacaddr) {
 		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "No Buffers to Read the EEPROM Address\n");
@@ -1231,8 +1240,9 @@
 	}
 
 	for (i = 0; i < MAC_ADDRESS_SIZE; i++) {
-		status = rdmalt(Adapter, EEPROM_READ_DATA_Q_REG, &temp, sizeof(temp));
-		if (status != STATUS_SUCCESS) {
+		bytes = rdmalt(Adapter, EEPROM_READ_DATA_Q_REG, &temp, sizeof(temp));
+		if (bytes < 0) {
+			status = bytes;
 			BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "rdm Failed..\n");
 			kfree(pucmacaddr);
 			pucmacaddr = NULL;
@@ -1574,11 +1584,13 @@
 {
 	INT iIndex = 0;
 	u32 uibuff[MAX_TARGET_DSX_BUFFERS];
+	int bytes;
 
 	if (!atomic_read(&Adapter->uiMBupdate))
 		return;
 
-	if (rdmaltWithLock(Adapter, TARGET_SFID_TXDESC_MAP_LOC, (PUINT)uibuff, sizeof(UINT) * MAX_TARGET_DSX_BUFFERS) < 0) {
+	bytes = rdmaltWithLock(Adapter, TARGET_SFID_TXDESC_MAP_LOC, (PUINT)uibuff, sizeof(UINT) * MAX_TARGET_DSX_BUFFERS);
+	if (bytes < 0) {
 		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "rdm failed\n");
 		return;
 	}
diff --git a/drivers/staging/bcm/hostmibs.c b/drivers/staging/bcm/hostmibs.c
index c13ea5c..101c4e3 100644
--- a/drivers/staging/bcm/hostmibs.c
+++ b/drivers/staging/bcm/hostmibs.c
@@ -1,4 +1,3 @@
-
 /*
  * File Name: hostmibs.c
  *
@@ -6,73 +5,72 @@
  *
  * Abstract: This file contains the routines to copy the statistics used by
  * the driver to the Host MIBS structure and giving the same to Application.
- *
  */
+
 #include "headers.h"
 
-INT  ProcessGetHostMibs(PMINI_ADAPTER Adapter, S_MIBS_HOST_STATS_MIBS *pstHostMibs)
+INT ProcessGetHostMibs(PMINI_ADAPTER Adapter, S_MIBS_HOST_STATS_MIBS *pstHostMibs)
 {
-	S_SERVICEFLOW_ENTRY    *pstServiceFlowEntry = NULL;
-	S_PHS_RULE             *pstPhsRule          = NULL;
-	S_CLASSIFIER_TABLE     *pstClassifierTable  = NULL;
-	S_CLASSIFIER_ENTRY     *pstClassifierRule   = NULL;
-	PPHS_DEVICE_EXTENSION  pDeviceExtension     = (PPHS_DEVICE_EXTENSION)&Adapter->stBCMPhsContext;
+	S_SERVICEFLOW_ENTRY *pstServiceFlowEntry = NULL;
+	S_PHS_RULE *pstPhsRule = NULL;
+	S_CLASSIFIER_TABLE *pstClassifierTable = NULL;
+	S_CLASSIFIER_ENTRY *pstClassifierRule = NULL;
+	PPHS_DEVICE_EXTENSION pDeviceExtension = (PPHS_DEVICE_EXTENSION) &Adapter->stBCMPhsContext;
 
-	UINT nClassifierIndex = 0, nPhsTableIndex = 0,nSfIndex = 0, uiIndex = 0;
+	UINT nClassifierIndex = 0, nPhsTableIndex = 0, nSfIndex = 0, uiIndex = 0;
 
-	if(pDeviceExtension == NULL)
-	{
-		BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, HOST_MIBS, DBG_LVL_ALL, "Invalid Device Extension\n");
+	if (pDeviceExtension == NULL) {
+		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, HOST_MIBS, DBG_LVL_ALL, "Invalid Device Extension\n");
 		return STATUS_FAILURE;
 	}
 
-	//Copy the classifier Table
-	for(nClassifierIndex=0; nClassifierIndex < MAX_CLASSIFIERS;
-			nClassifierIndex++)
-	{
-		if(Adapter->astClassifierTable[nClassifierIndex].bUsed == TRUE)
-			memcpy((PVOID)&pstHostMibs->astClassifierTable[nClassifierIndex],
-				(PVOID)&Adapter->astClassifierTable[nClassifierIndex],
-				sizeof(S_MIBS_CLASSIFIER_RULE));
+	/* Copy the classifier Table */
+	for (nClassifierIndex = 0; nClassifierIndex < MAX_CLASSIFIERS; nClassifierIndex++) {
+		if (Adapter->astClassifierTable[nClassifierIndex].bUsed == TRUE)
+			memcpy((PVOID) & pstHostMibs->
+			       astClassifierTable[nClassifierIndex],
+			       (PVOID) & Adapter->
+			       astClassifierTable[nClassifierIndex],
+			       sizeof(S_MIBS_CLASSIFIER_RULE));
 	}
 
-  //Copy the SF Table
-	for(nSfIndex=0; nSfIndex < NO_OF_QUEUES ; nSfIndex++)
-	{
-	if(Adapter->PackInfo[nSfIndex].bValid)
-	{
-			memcpy((PVOID)&pstHostMibs->astSFtable[nSfIndex],(PVOID)&Adapter->PackInfo[nSfIndex],sizeof(S_MIBS_SERVICEFLOW_TABLE));
-	}
-	else
-	{
-		//if index in not valid, don't process this for the PHS table. Go For the next entry.
-		continue ;
-	}
-
-		//Retrieve the SFID Entry Index for requested Service Flow
-		if(PHS_INVALID_TABLE_INDEX == GetServiceFlowEntry(pDeviceExtension->pstServiceFlowPhsRulesTable,
-						  Adapter->PackInfo[nSfIndex].usVCID_Value ,&pstServiceFlowEntry))
-		{
-
-		continue;
+	/* Copy the SF Table */
+	for (nSfIndex = 0; nSfIndex < NO_OF_QUEUES; nSfIndex++) {
+		if (Adapter->PackInfo[nSfIndex].bValid) {
+			memcpy((PVOID) & pstHostMibs->astSFtable[nSfIndex],
+			       (PVOID) & Adapter->PackInfo[nSfIndex],
+			       sizeof(S_MIBS_SERVICEFLOW_TABLE));
+		} else {
+			/* If index in not valid,
+			 * don't process this for the PHS table.
+			 * Go For the next entry.
+			 */
+			continue;
 		}
 
+		/* Retrieve the SFID Entry Index for requested Service Flow */
+		if (PHS_INVALID_TABLE_INDEX ==
+		    GetServiceFlowEntry(pDeviceExtension->
+					pstServiceFlowPhsRulesTable,
+					Adapter->PackInfo[nSfIndex].
+					usVCID_Value, &pstServiceFlowEntry))
+
+			continue;
+
 		pstClassifierTable = pstServiceFlowEntry->pstClassifierTable;
 
-
-		for(uiIndex = 0; uiIndex < MAX_PHSRULE_PER_SF; uiIndex++)
-		{
+		for (uiIndex = 0; uiIndex < MAX_PHSRULE_PER_SF; uiIndex++) {
 			pstClassifierRule = &pstClassifierTable->stActivePhsRulesList[uiIndex];
 
-		if(pstClassifierRule->bUsed)
-		{
-			pstPhsRule = pstClassifierRule->pstPhsRule;
+			if (pstClassifierRule->bUsed) {
+				pstPhsRule = pstClassifierRule->pstPhsRule;
 
-			pstHostMibs->astPhsRulesTable[nPhsTableIndex].ulSFID = Adapter->PackInfo[nSfIndex].ulSFID;
+				pstHostMibs->astPhsRulesTable[nPhsTableIndex].
+				    ulSFID = Adapter->PackInfo[nSfIndex].ulSFID;
 
-			memcpy(&pstHostMibs->astPhsRulesTable[nPhsTableIndex].u8PHSI,
-						&pstPhsRule->u8PHSI,
-						sizeof(S_PHS_RULE));
+				memcpy(&pstHostMibs->
+				       astPhsRulesTable[nPhsTableIndex].u8PHSI,
+				       &pstPhsRule->u8PHSI, sizeof(S_PHS_RULE));
 				nPhsTableIndex++;
 
 			}
@@ -81,65 +79,63 @@
 
 	}
 
-
-	//copy other Host Statistics parameters
+	/* Copy other Host Statistics parameters */
 	pstHostMibs->stHostInfo.GoodTransmits = Adapter->dev->stats.tx_packets;
 	pstHostMibs->stHostInfo.GoodReceives = Adapter->dev->stats.rx_packets;
-	pstHostMibs->stHostInfo.CurrNumFreeDesc =
-			atomic_read(&Adapter->CurrNumFreeTxDesc);
+	pstHostMibs->stHostInfo.CurrNumFreeDesc = atomic_read(&Adapter->CurrNumFreeTxDesc);
 	pstHostMibs->stHostInfo.BEBucketSize = Adapter->BEBucketSize;
 	pstHostMibs->stHostInfo.rtPSBucketSize = Adapter->rtPSBucketSize;
 	pstHostMibs->stHostInfo.TimerActive = Adapter->TimerActive;
 	pstHostMibs->stHostInfo.u32TotalDSD = Adapter->u32TotalDSD;
 
-	memcpy(pstHostMibs->stHostInfo.aTxPktSizeHist,Adapter->aTxPktSizeHist,sizeof(UINT32)*MIBS_MAX_HIST_ENTRIES);
-	memcpy(pstHostMibs->stHostInfo.aRxPktSizeHist,Adapter->aRxPktSizeHist,sizeof(UINT32)*MIBS_MAX_HIST_ENTRIES);
+	memcpy(pstHostMibs->stHostInfo.aTxPktSizeHist, Adapter->aTxPktSizeHist, sizeof(UINT32) * MIBS_MAX_HIST_ENTRIES);
+	memcpy(pstHostMibs->stHostInfo.aRxPktSizeHist, Adapter->aRxPktSizeHist, sizeof(UINT32) * MIBS_MAX_HIST_ENTRIES);
 
 	return STATUS_SUCCESS;
 }
 
-
 VOID GetDroppedAppCntrlPktMibs(S_MIBS_HOST_STATS_MIBS *pstHostMibs, const PPER_TARANG_DATA pTarang)
 {
 	memcpy(&(pstHostMibs->stDroppedAppCntrlMsgs),
-	       &(pTarang->stDroppedAppCntrlMsgs),sizeof(S_MIBS_DROPPED_APP_CNTRL_MESSAGES));
+	       &(pTarang->stDroppedAppCntrlMsgs),
+	       sizeof(S_MIBS_DROPPED_APP_CNTRL_MESSAGES));
 }
 
-
-VOID CopyMIBSExtendedSFParameters(PMINI_ADAPTER Adapter,
-		CServiceFlowParamSI *psfLocalSet, UINT uiSearchRuleIndex)
+VOID CopyMIBSExtendedSFParameters(PMINI_ADAPTER Adapter, CServiceFlowParamSI *psfLocalSet, UINT uiSearchRuleIndex)
 {
-	Adapter->PackInfo[uiSearchRuleIndex].stMibsExtServiceFlowTable.wmanIfSfid = psfLocalSet->u32SFID;
-	Adapter->PackInfo[uiSearchRuleIndex].stMibsExtServiceFlowTable.wmanIfCmnCpsMaxSustainedRate = psfLocalSet->u32MaxSustainedTrafficRate;
-	Adapter->PackInfo[uiSearchRuleIndex].stMibsExtServiceFlowTable.wmanIfCmnCpsMaxTrafficBurst = psfLocalSet->u32MaxTrafficBurst;
-	Adapter->PackInfo[uiSearchRuleIndex].stMibsExtServiceFlowTable.wmanIfCmnCpsMinReservedRate = psfLocalSet->u32MinReservedTrafficRate;
-	Adapter->PackInfo[uiSearchRuleIndex].stMibsExtServiceFlowTable.wmanIfCmnCpsToleratedJitter = psfLocalSet->u32ToleratedJitter;
-	Adapter->PackInfo[uiSearchRuleIndex].stMibsExtServiceFlowTable.wmanIfCmnCpsMaxLatency = psfLocalSet->u32MaximumLatency;
-	Adapter->PackInfo[uiSearchRuleIndex].stMibsExtServiceFlowTable.wmanIfCmnCpsFixedVsVariableSduInd = psfLocalSet->u8FixedLengthVSVariableLengthSDUIndicator;
-	Adapter->PackInfo[uiSearchRuleIndex].stMibsExtServiceFlowTable.wmanIfCmnCpsFixedVsVariableSduInd = ntohl(Adapter->PackInfo[uiSearchRuleIndex].stMibsExtServiceFlowTable.wmanIfCmnCpsFixedVsVariableSduInd);
-	Adapter->PackInfo[uiSearchRuleIndex].stMibsExtServiceFlowTable.wmanIfCmnCpsSduSize = psfLocalSet->u8SDUSize;
-	Adapter->PackInfo[uiSearchRuleIndex].stMibsExtServiceFlowTable.wmanIfCmnCpsSduSize = ntohl(Adapter->PackInfo[uiSearchRuleIndex].stMibsExtServiceFlowTable.wmanIfCmnCpsSduSize);
-	Adapter->PackInfo[uiSearchRuleIndex].stMibsExtServiceFlowTable.wmanIfCmnCpsSfSchedulingType = psfLocalSet->u8ServiceFlowSchedulingType;
-	Adapter->PackInfo[uiSearchRuleIndex].stMibsExtServiceFlowTable.wmanIfCmnCpsSfSchedulingType = ntohl(Adapter->PackInfo[uiSearchRuleIndex].stMibsExtServiceFlowTable.wmanIfCmnCpsSfSchedulingType);
-	Adapter->PackInfo[uiSearchRuleIndex].stMibsExtServiceFlowTable.wmanIfCmnCpsArqEnable = psfLocalSet->u8ARQEnable;
-	Adapter->PackInfo[uiSearchRuleIndex].stMibsExtServiceFlowTable.wmanIfCmnCpsArqEnable = ntohl(Adapter->PackInfo[uiSearchRuleIndex].stMibsExtServiceFlowTable.wmanIfCmnCpsArqEnable);
-	Adapter->PackInfo[uiSearchRuleIndex].stMibsExtServiceFlowTable.wmanIfCmnCpsArqWindowSize = ntohs(psfLocalSet->u16ARQWindowSize);
-	Adapter->PackInfo[uiSearchRuleIndex].stMibsExtServiceFlowTable.wmanIfCmnCpsArqWindowSize = ntohl(Adapter->PackInfo[uiSearchRuleIndex].stMibsExtServiceFlowTable.wmanIfCmnCpsArqWindowSize);
-	Adapter->PackInfo[uiSearchRuleIndex].stMibsExtServiceFlowTable.wmanIfCmnCpsArqBlockLifetime = ntohs(psfLocalSet->u16ARQBlockLifeTime);
-	Adapter->PackInfo[uiSearchRuleIndex].stMibsExtServiceFlowTable.wmanIfCmnCpsArqBlockLifetime = ntohl(Adapter->PackInfo[uiSearchRuleIndex].stMibsExtServiceFlowTable.wmanIfCmnCpsArqBlockLifetime);
-	Adapter->PackInfo[uiSearchRuleIndex].stMibsExtServiceFlowTable.wmanIfCmnCpsArqSyncLossTimeout = ntohs(psfLocalSet->u16ARQSyncLossTimeOut);
-	Adapter->PackInfo[uiSearchRuleIndex].stMibsExtServiceFlowTable.wmanIfCmnCpsArqSyncLossTimeout = ntohl(Adapter->PackInfo[uiSearchRuleIndex].stMibsExtServiceFlowTable.wmanIfCmnCpsArqSyncLossTimeout);
-	Adapter->PackInfo[uiSearchRuleIndex].stMibsExtServiceFlowTable.wmanIfCmnCpsArqDeliverInOrder = psfLocalSet->u8ARQDeliverInOrder;
-	Adapter->PackInfo[uiSearchRuleIndex].stMibsExtServiceFlowTable.wmanIfCmnCpsArqDeliverInOrder = ntohl(Adapter->PackInfo[uiSearchRuleIndex].stMibsExtServiceFlowTable.wmanIfCmnCpsArqDeliverInOrder);
-	Adapter->PackInfo[uiSearchRuleIndex].stMibsExtServiceFlowTable.wmanIfCmnCpsArqRxPurgeTimeout = ntohs(psfLocalSet->u16ARQRxPurgeTimeOut);
-	Adapter->PackInfo[uiSearchRuleIndex].stMibsExtServiceFlowTable.wmanIfCmnCpsArqRxPurgeTimeout = ntohl(Adapter->PackInfo[uiSearchRuleIndex].stMibsExtServiceFlowTable.wmanIfCmnCpsArqRxPurgeTimeout);
-	Adapter->PackInfo[uiSearchRuleIndex].stMibsExtServiceFlowTable.wmanIfCmnCpsArqBlockSize = ntohs(psfLocalSet->u16ARQBlockSize);
-	Adapter->PackInfo[uiSearchRuleIndex].stMibsExtServiceFlowTable.wmanIfCmnCpsArqBlockSize = ntohl(Adapter->PackInfo[uiSearchRuleIndex].stMibsExtServiceFlowTable.wmanIfCmnCpsArqBlockSize);
-	Adapter->PackInfo[uiSearchRuleIndex].stMibsExtServiceFlowTable.wmanIfCmnCpsReqTxPolicy = psfLocalSet->u8RequesttransmissionPolicy;
-	Adapter->PackInfo[uiSearchRuleIndex].stMibsExtServiceFlowTable.wmanIfCmnCpsReqTxPolicy = ntohl(Adapter->PackInfo[uiSearchRuleIndex].stMibsExtServiceFlowTable.wmanIfCmnCpsReqTxPolicy);
-	Adapter->PackInfo[uiSearchRuleIndex].stMibsExtServiceFlowTable.wmanIfCmnSfCsSpecification = psfLocalSet->u8CSSpecification;
-	Adapter->PackInfo[uiSearchRuleIndex].stMibsExtServiceFlowTable.wmanIfCmnSfCsSpecification = ntohl(Adapter->PackInfo[uiSearchRuleIndex].stMibsExtServiceFlowTable.wmanIfCmnSfCsSpecification);
-	Adapter->PackInfo[uiSearchRuleIndex].stMibsExtServiceFlowTable.wmanIfCmnCpsTargetSaid = ntohs(psfLocalSet->u16TargetSAID);
-	Adapter->PackInfo[uiSearchRuleIndex].stMibsExtServiceFlowTable.wmanIfCmnCpsTargetSaid = ntohl(Adapter->PackInfo[uiSearchRuleIndex].stMibsExtServiceFlowTable.wmanIfCmnCpsTargetSaid);
+	S_MIBS_EXTSERVICEFLOW_PARAMETERS *t = &Adapter->PackInfo[uiSearchRuleIndex].stMibsExtServiceFlowTable;
+
+	t->wmanIfSfid = psfLocalSet->u32SFID;
+	t->wmanIfCmnCpsMaxSustainedRate = psfLocalSet->u32MaxSustainedTrafficRate;
+	t->wmanIfCmnCpsMaxTrafficBurst = psfLocalSet->u32MaxTrafficBurst;
+	t->wmanIfCmnCpsMinReservedRate = psfLocalSet->u32MinReservedTrafficRate;
+	t->wmanIfCmnCpsToleratedJitter = psfLocalSet->u32ToleratedJitter;
+	t->wmanIfCmnCpsMaxLatency = psfLocalSet->u32MaximumLatency;
+	t->wmanIfCmnCpsFixedVsVariableSduInd = psfLocalSet->u8FixedLengthVSVariableLengthSDUIndicator;
+	t->wmanIfCmnCpsFixedVsVariableSduInd = ntohl(t->wmanIfCmnCpsFixedVsVariableSduInd);
+	t->wmanIfCmnCpsSduSize = psfLocalSet->u8SDUSize;
+	t->wmanIfCmnCpsSduSize = ntohl(t->wmanIfCmnCpsSduSize);
+	t->wmanIfCmnCpsSfSchedulingType = psfLocalSet->u8ServiceFlowSchedulingType;
+	t->wmanIfCmnCpsSfSchedulingType = ntohl(t->wmanIfCmnCpsSfSchedulingType);
+	t->wmanIfCmnCpsArqEnable = psfLocalSet->u8ARQEnable;
+	t->wmanIfCmnCpsArqEnable = ntohl(t->wmanIfCmnCpsArqEnable);
+	t->wmanIfCmnCpsArqWindowSize = ntohs(psfLocalSet->u16ARQWindowSize);
+	t->wmanIfCmnCpsArqWindowSize = ntohl(t->wmanIfCmnCpsArqWindowSize);
+	t->wmanIfCmnCpsArqBlockLifetime = ntohs(psfLocalSet->u16ARQBlockLifeTime);
+	t->wmanIfCmnCpsArqBlockLifetime = ntohl(t->wmanIfCmnCpsArqBlockLifetime);
+	t->wmanIfCmnCpsArqSyncLossTimeout = ntohs(psfLocalSet->u16ARQSyncLossTimeOut);
+	t->wmanIfCmnCpsArqSyncLossTimeout = ntohl(t->wmanIfCmnCpsArqSyncLossTimeout);
+	t->wmanIfCmnCpsArqDeliverInOrder = psfLocalSet->u8ARQDeliverInOrder;
+	t->wmanIfCmnCpsArqDeliverInOrder = ntohl(t->wmanIfCmnCpsArqDeliverInOrder);
+	t->wmanIfCmnCpsArqRxPurgeTimeout = ntohs(psfLocalSet->u16ARQRxPurgeTimeOut);
+	t->wmanIfCmnCpsArqRxPurgeTimeout = ntohl(t->wmanIfCmnCpsArqRxPurgeTimeout);
+	t->wmanIfCmnCpsArqBlockSize = ntohs(psfLocalSet->u16ARQBlockSize);
+	t->wmanIfCmnCpsArqBlockSize = ntohl(t->wmanIfCmnCpsArqBlockSize);
+	t->wmanIfCmnCpsReqTxPolicy = psfLocalSet->u8RequesttransmissionPolicy;
+	t->wmanIfCmnCpsReqTxPolicy = ntohl(t->wmanIfCmnCpsReqTxPolicy);
+	t->wmanIfCmnSfCsSpecification = psfLocalSet->u8CSSpecification;
+	t->wmanIfCmnSfCsSpecification = ntohl(t->wmanIfCmnSfCsSpecification);
+	t->wmanIfCmnCpsTargetSaid = ntohs(psfLocalSet->u16TargetSAID);
+	t->wmanIfCmnCpsTargetSaid = ntohl(t->wmanIfCmnCpsTargetSaid);
 
 }
diff --git a/drivers/staging/bcm/led_control.c b/drivers/staging/bcm/led_control.c
index 16e939f..c7f4886 100644
--- a/drivers/staging/bcm/led_control.c
+++ b/drivers/staging/bcm/led_control.c
@@ -5,65 +5,69 @@
 
 static B_UINT16 CFG_CalculateChecksum(B_UINT8 *pu8Buffer, B_UINT32 u32Size)
 {
-	B_UINT16 	u16CheckSum=0;
-	while(u32Size--) {
+	B_UINT16 u16CheckSum = 0;
+	while (u32Size--) {
 		u16CheckSum += (B_UINT8)~(*pu8Buffer);
-	    pu8Buffer++;
+		pu8Buffer++;
 	}
 	return u16CheckSum;
 }
+
 BOOLEAN IsReqGpioIsLedInNVM(PMINI_ADAPTER Adapter, UINT gpios)
 {
-	INT Status ;
-	Status = (Adapter->gpioBitMap & gpios) ^ gpios ;
-	if(Status)
+	INT Status;
+	Status = (Adapter->gpioBitMap & gpios) ^ gpios;
+	if (Status)
 		return FALSE;
 	else
 		return TRUE;
 }
 
-static INT LED_Blink(PMINI_ADAPTER Adapter, UINT GPIO_Num, UCHAR uiLedIndex, ULONG timeout, INT num_of_time, LedEventInfo_t currdriverstate)
+static INT LED_Blink(PMINI_ADAPTER Adapter, UINT GPIO_Num, UCHAR uiLedIndex,
+		ULONG timeout, INT num_of_time, LedEventInfo_t currdriverstate)
 {
 	int Status = STATUS_SUCCESS;
 	BOOLEAN bInfinite = FALSE;
 
-	/*Check if num_of_time is -ve. If yes, blink led in infinite loop*/
-	if(num_of_time < 0)
-	{
+	/* Check if num_of_time is -ve. If yes, blink led in infinite loop */
+	if (num_of_time < 0) {
 		bInfinite = TRUE;
 		num_of_time = 1;
 	}
-	while(num_of_time)
-	{
-
-		if(currdriverstate == Adapter->DriverState)
+	while (num_of_time) {
+		if (currdriverstate == Adapter->DriverState)
 			TURN_ON_LED(GPIO_Num, uiLedIndex);
 
-		/*Wait for timeout after setting on the LED*/
-		Status = wait_event_interruptible_timeout(Adapter->LEDInfo.notify_led_event,
-					currdriverstate != Adapter->DriverState || kthread_should_stop(),
-					msecs_to_jiffies(timeout));
+		/* Wait for timeout after setting on the LED */
+		Status = wait_event_interruptible_timeout(
+				Adapter->LEDInfo.notify_led_event,
+				currdriverstate != Adapter->DriverState ||
+					kthread_should_stop(),
+				msecs_to_jiffies(timeout));
 
-		if(kthread_should_stop())
-		{
-			BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, LED_DUMP_INFO, DBG_LVL_ALL, "Led thread got signal to exit..hence exiting");
-			Adapter->LEDInfo.led_thread_running= BCM_LED_THREAD_DISABLED;
+		if (kthread_should_stop()) {
+			BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, LED_DUMP_INFO,
+				DBG_LVL_ALL,
+				"Led thread got signal to exit..hence exiting");
+			Adapter->LEDInfo.led_thread_running =
+					BCM_LED_THREAD_DISABLED;
 			TURN_OFF_LED(GPIO_Num, uiLedIndex);
-			Status=EVENT_SIGNALED;
+			Status = EVENT_SIGNALED;
 			break;
 		}
-		if(Status)
-		{
+		if (Status) {
 			TURN_OFF_LED(GPIO_Num, uiLedIndex);
-			Status=EVENT_SIGNALED;
+			Status = EVENT_SIGNALED;
 			break;
 		}
 
 		TURN_OFF_LED(GPIO_Num, uiLedIndex);
-		Status = wait_event_interruptible_timeout(Adapter->LEDInfo.notify_led_event,
-					currdriverstate!= Adapter->DriverState || kthread_should_stop(),
-					msecs_to_jiffies(timeout));
-		if(bInfinite == FALSE)
+		Status = wait_event_interruptible_timeout(
+				Adapter->LEDInfo.notify_led_event,
+				currdriverstate != Adapter->DriverState ||
+					kthread_should_stop(),
+				msecs_to_jiffies(timeout));
+		if (bInfinite == FALSE)
 			num_of_time--;
 	}
 	return Status;
@@ -71,19 +75,19 @@
 
 static INT ScaleRateofTransfer(ULONG rate)
 {
-	if(rate <= 3)
+	if (rate <= 3)
 		return rate;
-	else if((rate > 3) && (rate <= 100))
+	else if ((rate > 3) && (rate <= 100))
 		return 5;
-	else if((rate > 100) && (rate <= 200))
+	else if ((rate > 100) && (rate <= 200))
 		return 6;
-	else if((rate > 200) && (rate <= 300))
+	else if ((rate > 200) && (rate <= 300))
 		return 7;
-	else if((rate > 300) && (rate <= 400))
+	else if ((rate > 300) && (rate <= 400))
 		return 8;
-	else if((rate > 400) && (rate <= 500))
+	else if ((rate > 400) && (rate <= 500))
 		return 9;
-	else if((rate > 500) && (rate <= 600))
+	else if ((rate > 500) && (rate <= 600))
 		return 10;
 	else
 		return MAX_NUM_OF_BLINKS;
@@ -92,215 +96,232 @@
 
 
 static INT LED_Proportional_Blink(PMINI_ADAPTER Adapter, UCHAR GPIO_Num_tx,
-		UCHAR uiTxLedIndex, UCHAR GPIO_Num_rx, UCHAR uiRxLedIndex, LedEventInfo_t currdriverstate)
+		UCHAR uiTxLedIndex, UCHAR GPIO_Num_rx, UCHAR uiRxLedIndex,
+		LedEventInfo_t currdriverstate)
 {
-	/* Initial values of TX and RX packets*/
+	/* Initial values of TX and RX packets */
 	ULONG64 Initial_num_of_packts_tx = 0, Initial_num_of_packts_rx = 0;
-	/*values of TX and RX packets after 1 sec*/
+	/* values of TX and RX packets after 1 sec */
 	ULONG64 Final_num_of_packts_tx = 0, Final_num_of_packts_rx = 0;
-	/*Rate of transfer of Tx and Rx in 1 sec*/
+	/* Rate of transfer of Tx and Rx in 1 sec */
 	ULONG64 rate_of_transfer_tx = 0, rate_of_transfer_rx = 0;
 	int Status = STATUS_SUCCESS;
 	INT num_of_time = 0, num_of_time_tx = 0, num_of_time_rx = 0;
 	UINT remDelay = 0;
 	BOOLEAN bBlinkBothLED = TRUE;
-	//UINT GPIO_num = DISABLE_GPIO_NUM;
+	/* UINT GPIO_num = DISABLE_GPIO_NUM; */
 	ulong timeout = 0;
 
-	/*Read initial value of packets sent/received */
+	/* Read initial value of packets sent/received */
 	Initial_num_of_packts_tx = Adapter->dev->stats.tx_packets;
 	Initial_num_of_packts_rx = Adapter->dev->stats.rx_packets;
 
-	/*Scale the rate of transfer to no of blinks.*/
-	num_of_time_tx= ScaleRateofTransfer((ULONG)rate_of_transfer_tx);
-	num_of_time_rx= ScaleRateofTransfer((ULONG)rate_of_transfer_rx);
+	/* Scale the rate of transfer to no of blinks. */
+	num_of_time_tx = ScaleRateofTransfer((ULONG)rate_of_transfer_tx);
+	num_of_time_rx = ScaleRateofTransfer((ULONG)rate_of_transfer_rx);
 
-	while((Adapter->device_removed == FALSE))
-	{
+	while ((Adapter->device_removed == FALSE)) {
 		timeout = 50;
-		/*Blink Tx and Rx LED when both Tx and Rx is in normal bandwidth*/
-		if(bBlinkBothLED)
-		{
-			/*Assign minimum number of blinks of either Tx or Rx.*/
-			if(num_of_time_tx > num_of_time_rx)
-				num_of_time = num_of_time_rx;
-			else
-				num_of_time = num_of_time_tx;
-			if(num_of_time > 0)
-			{
-				/*Blink both Tx and Rx LEDs*/
-				if(LED_Blink(Adapter, 1<<GPIO_Num_tx, uiTxLedIndex, timeout, num_of_time,currdriverstate)
-							== EVENT_SIGNALED)
-				{
-					return EVENT_SIGNALED;
-				}
-				if(LED_Blink(Adapter, 1<<GPIO_Num_rx, uiRxLedIndex, timeout, num_of_time,currdriverstate)
-							== EVENT_SIGNALED)
-				{
-					return EVENT_SIGNALED;
-				}
-
-			}
-
-			if(num_of_time == num_of_time_tx)
-			{
-				/*Blink pending rate of Rx*/
-				if(LED_Blink(Adapter, (1 << GPIO_Num_rx), uiRxLedIndex, timeout,
-						num_of_time_rx-num_of_time,currdriverstate) == EVENT_SIGNALED)
-				{
-					return EVENT_SIGNALED;
-				}
-				num_of_time = num_of_time_rx;
-			}
-			else
-			{
-				/*Blink pending rate of Tx*/
-				if(LED_Blink(Adapter, 1<<GPIO_Num_tx, uiTxLedIndex, timeout,
-					num_of_time_tx-num_of_time,currdriverstate) == EVENT_SIGNALED)
-				{
-					return EVENT_SIGNALED;
-				}
-				num_of_time = num_of_time_tx;
-			}
-		}
-		else
-		{
-			if(num_of_time == num_of_time_tx)
-			{
-				/*Blink pending rate of Rx*/
-				if(LED_Blink(Adapter, 1<<GPIO_Num_tx, uiTxLedIndex, timeout, num_of_time,currdriverstate)
-							== EVENT_SIGNALED)
-				{
-					return EVENT_SIGNALED;
-				}
-			}
-			else
-			{
-				/*Blink pending rate of Tx*/
-				if(LED_Blink(Adapter, 1<<GPIO_Num_rx, uiRxLedIndex, timeout,
-						num_of_time,currdriverstate) == EVENT_SIGNALED)
-				{
-					return EVENT_SIGNALED;
-				}
-			}
-		}
-		/* If Tx/Rx rate is less than maximum blinks per second,
-			 * wait till delay completes to 1 second
+		/*
+		 * Blink Tx and Rx LED when both Tx and Rx is
+		 * in normal bandwidth
+		 */
+		if (bBlinkBothLED) {
+			/*
+			 * Assign minimum number of blinks of
+			 * either Tx or Rx.
 			 */
-		remDelay = MAX_NUM_OF_BLINKS - num_of_time;
-		if(remDelay > 0)
-		{
-			timeout= 100 * remDelay;
-			Status = wait_event_interruptible_timeout(Adapter->LEDInfo.notify_led_event,
-						currdriverstate!= Adapter->DriverState ||kthread_should_stop() ,
-						msecs_to_jiffies (timeout));
+			if (num_of_time_tx > num_of_time_rx)
+				num_of_time = num_of_time_rx;
+			else
+				num_of_time = num_of_time_tx;
+			if (num_of_time > 0) {
+				/* Blink both Tx and Rx LEDs */
+				if (LED_Blink(Adapter, 1 << GPIO_Num_tx,
+						uiTxLedIndex, timeout,
+						num_of_time, currdriverstate)
+							== EVENT_SIGNALED)
+					return EVENT_SIGNALED;
 
-			if(kthread_should_stop())
-			{
-				BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, LED_DUMP_INFO, DBG_LVL_ALL, "Led thread got signal to exit..hence exiting");
-				Adapter->LEDInfo.led_thread_running= BCM_LED_THREAD_DISABLED;
-				return EVENT_SIGNALED;
+				if (LED_Blink(Adapter, 1 << GPIO_Num_rx,
+						uiRxLedIndex, timeout,
+						num_of_time, currdriverstate)
+							== EVENT_SIGNALED)
+					return EVENT_SIGNALED;
+
 			}
-			if(Status)
-				return EVENT_SIGNALED;
-		}
 
-		/*Turn off both Tx and Rx LEDs before next second*/
-		TURN_OFF_LED(1<<GPIO_Num_tx, uiTxLedIndex);
-		TURN_OFF_LED(1<<GPIO_Num_rx, uiTxLedIndex);
+			if (num_of_time == num_of_time_tx) {
+				/* Blink pending rate of Rx */
+				if (LED_Blink(Adapter, (1 << GPIO_Num_rx),
+						uiRxLedIndex, timeout,
+						num_of_time_rx-num_of_time,
+						currdriverstate)
+							== EVENT_SIGNALED)
+					return EVENT_SIGNALED;
+
+				num_of_time = num_of_time_rx;
+			} else {
+				/* Blink pending rate of Tx */
+				if (LED_Blink(Adapter, 1 << GPIO_Num_tx,
+						uiTxLedIndex, timeout,
+						num_of_time_tx-num_of_time,
+						currdriverstate)
+							== EVENT_SIGNALED)
+					return EVENT_SIGNALED;
+
+				num_of_time = num_of_time_tx;
+			}
+		} else {
+			if (num_of_time == num_of_time_tx) {
+				/* Blink pending rate of Rx */
+				if (LED_Blink(Adapter, 1 << GPIO_Num_tx,
+						uiTxLedIndex, timeout,
+						num_of_time, currdriverstate)
+							== EVENT_SIGNALED)
+					return EVENT_SIGNALED;
+			} else {
+				/* Blink pending rate of Tx */
+				if (LED_Blink(Adapter, 1 << GPIO_Num_rx,
+						uiRxLedIndex, timeout,
+						num_of_time, currdriverstate)
+							== EVENT_SIGNALED)
+					return EVENT_SIGNALED;
+			}
+		}
 
 		/*
- 		 * Read the Tx & Rx packets transmission after 1 second and
- 		 * calculate rate of transfer
- 		 */
+		 * If Tx/Rx rate is less than maximum blinks per second,
+		 * wait till delay completes to 1 second
+		 */
+		remDelay = MAX_NUM_OF_BLINKS - num_of_time;
+		if (remDelay > 0) {
+			timeout = 100 * remDelay;
+			Status = wait_event_interruptible_timeout(
+					Adapter->LEDInfo.notify_led_event,
+					currdriverstate != Adapter->DriverState
+						|| kthread_should_stop(),
+					msecs_to_jiffies(timeout));
+
+			if (kthread_should_stop()) {
+				BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS,
+					LED_DUMP_INFO, DBG_LVL_ALL,
+					"Led thread got signal to exit..hence exiting");
+				Adapter->LEDInfo.led_thread_running =
+						BCM_LED_THREAD_DISABLED;
+				return EVENT_SIGNALED;
+			}
+			if (Status)
+				return EVENT_SIGNALED;
+		}
+
+		/* Turn off both Tx and Rx LEDs before next second */
+		TURN_OFF_LED(1 << GPIO_Num_tx, uiTxLedIndex);
+		TURN_OFF_LED(1 << GPIO_Num_rx, uiTxLedIndex);
+
+		/*
+		 * Read the Tx & Rx packets transmission after 1 second and
+		 * calculate rate of transfer
+		 */
 		Final_num_of_packts_tx = Adapter->dev->stats.tx_packets;
 		Final_num_of_packts_rx = Adapter->dev->stats.rx_packets;
 
-		rate_of_transfer_tx = Final_num_of_packts_tx - Initial_num_of_packts_tx;
-		rate_of_transfer_rx = Final_num_of_packts_rx - Initial_num_of_packts_rx;
+		rate_of_transfer_tx = Final_num_of_packts_tx -
+						Initial_num_of_packts_tx;
+		rate_of_transfer_rx = Final_num_of_packts_rx -
+						Initial_num_of_packts_rx;
 
-		/*Read initial value of packets sent/received */
+		/* Read initial value of packets sent/received */
 		Initial_num_of_packts_tx = Final_num_of_packts_tx;
-		Initial_num_of_packts_rx = Final_num_of_packts_rx ;
+		Initial_num_of_packts_rx = Final_num_of_packts_rx;
 
-		/*Scale the rate of transfer to no of blinks.*/
-		num_of_time_tx= ScaleRateofTransfer((ULONG)rate_of_transfer_tx);
-		num_of_time_rx= ScaleRateofTransfer((ULONG)rate_of_transfer_rx);
+		/* Scale the rate of transfer to no of blinks. */
+		num_of_time_tx =
+			ScaleRateofTransfer((ULONG)rate_of_transfer_tx);
+		num_of_time_rx =
+			ScaleRateofTransfer((ULONG)rate_of_transfer_rx);
 
 	}
 	return Status;
 }
 
-
-//-----------------------------------------------------------------------------
-// Procedure:   ValidateDSDParamsChecksum
-//
-// Description: Reads DSD Params and validates checkusm.
-//
-// Arguments:
-//      Adapter - Pointer to Adapter structure.
-//      ulParamOffset - Start offset of the DSD parameter to be read and validated.
-//      usParamLen - Length of the DSD Parameter.
-//
-// Returns:
-//  <OSAL_STATUS_CODE>
-//-----------------------------------------------------------------------------
-
-static INT ValidateDSDParamsChecksum(
-													PMINI_ADAPTER Adapter,
-													ULONG  ulParamOffset,
-													USHORT usParamLen )
+/*
+ * -----------------------------------------------------------------------------
+ * Procedure:   ValidateDSDParamsChecksum
+ *
+ * Description: Reads DSD Params and validates checkusm.
+ *
+ * Arguments:
+ *      Adapter - Pointer to Adapter structure.
+ *      ulParamOffset - Start offset of the DSD parameter to be read and
+ *			validated.
+ *      usParamLen - Length of the DSD Parameter.
+ *
+ * Returns:
+ *  <OSAL_STATUS_CODE>
+ * -----------------------------------------------------------------------------
+ */
+static INT ValidateDSDParamsChecksum(PMINI_ADAPTER Adapter, ULONG ulParamOffset,
+					USHORT usParamLen)
 {
 	INT Status = STATUS_SUCCESS;
-	PUCHAR puBuffer 		    = NULL;
-	USHORT usChksmOrg		    = 0;
+	PUCHAR puBuffer = NULL;
+	USHORT usChksmOrg = 0;
 	USHORT usChecksumCalculated = 0;
 
-	BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, LED_DUMP_INFO, DBG_LVL_ALL,"LED Thread:ValidateDSDParamsChecksum: 0x%lx 0x%X",ulParamOffset, usParamLen);
+	BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, LED_DUMP_INFO, DBG_LVL_ALL,
+		"LED Thread:ValidateDSDParamsChecksum: 0x%lx 0x%X",
+		ulParamOffset, usParamLen);
 
 	puBuffer = kmalloc(usParamLen, GFP_KERNEL);
-	if(!puBuffer)
-	{
-		BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, LED_DUMP_INFO, DBG_LVL_ALL,"LED Thread: ValidateDSDParamsChecksum Allocation failed");
+	if (!puBuffer) {
+		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, LED_DUMP_INFO,
+			DBG_LVL_ALL,
+			"LED Thread: ValidateDSDParamsChecksum Allocation failed");
 		return -ENOMEM;
 
 	}
 
-    //
-    //	Read the DSD data from the parameter offset.
-    //
-	if(STATUS_SUCCESS != BeceemNVMRead(Adapter,(PUINT)puBuffer,ulParamOffset,usParamLen))
-	{
-		BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, LED_DUMP_INFO, DBG_LVL_ALL,"LED Thread: ValidateDSDParamsChecksum BeceemNVMRead failed");
-		Status=STATUS_IMAGE_CHECKSUM_MISMATCH;
+	/* Read the DSD data from the parameter offset. */
+	if (STATUS_SUCCESS != BeceemNVMRead(Adapter, (PUINT)puBuffer,
+			ulParamOffset, usParamLen)) {
+		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, LED_DUMP_INFO,
+			DBG_LVL_ALL,
+			"LED Thread: ValidateDSDParamsChecksum BeceemNVMRead failed");
+		Status = STATUS_IMAGE_CHECKSUM_MISMATCH;
 		goto exit;
 	}
 
-	//
-	//	Calculate the checksum of the data read from the DSD parameter.
-	//
-	usChecksumCalculated = CFG_CalculateChecksum(puBuffer,usParamLen);
-	BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, LED_DUMP_INFO, DBG_LVL_ALL,"LED Thread: usCheckSumCalculated = 0x%x\n", usChecksumCalculated);
+	/* Calculate the checksum of the data read from the DSD parameter. */
+	usChecksumCalculated = CFG_CalculateChecksum(puBuffer, usParamLen);
+	BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, LED_DUMP_INFO, DBG_LVL_ALL,
+		"LED Thread: usCheckSumCalculated = 0x%x\n",
+		usChecksumCalculated);
 
-	//
-	//	End of the DSD parameter will have a TWO bytes checksum stored in it. Read it and compare with the calculated
-	//	Checksum.
-	//
-	if(STATUS_SUCCESS != BeceemNVMRead(Adapter,(PUINT)&usChksmOrg,ulParamOffset+usParamLen,2))
-	{
-		BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, LED_DUMP_INFO, DBG_LVL_ALL,"LED Thread: ValidateDSDParamsChecksum BeceemNVMRead failed");
-		Status=STATUS_IMAGE_CHECKSUM_MISMATCH;
+	/*
+	 * End of the DSD parameter will have a TWO bytes checksum stored in it.
+	 * Read it and compare with the calculated Checksum.
+	 */
+	if (STATUS_SUCCESS != BeceemNVMRead(Adapter, (PUINT)&usChksmOrg,
+			ulParamOffset+usParamLen, 2)) {
+		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, LED_DUMP_INFO,
+			DBG_LVL_ALL,
+			"LED Thread: ValidateDSDParamsChecksum BeceemNVMRead failed");
+		Status = STATUS_IMAGE_CHECKSUM_MISMATCH;
 		goto exit;
 	}
 	usChksmOrg = ntohs(usChksmOrg);
-	BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, LED_DUMP_INFO, DBG_LVL_ALL,"LED Thread: usChksmOrg = 0x%x", usChksmOrg);
+	BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, LED_DUMP_INFO, DBG_LVL_ALL,
+		"LED Thread: usChksmOrg = 0x%x", usChksmOrg);
 
-	//
-	//  	Compare the checksum calculated with the checksum read from DSD section
-	//
-	if(usChecksumCalculated ^ usChksmOrg)
-	{
-		BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, LED_DUMP_INFO, DBG_LVL_ALL,"LED Thread: ValidateDSDParamsChecksum: Checksums don't match");
+	/*
+	 * Compare the checksum calculated with the checksum read
+	 * from DSD section
+	 */
+	if (usChecksumCalculated ^ usChksmOrg) {
+		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, LED_DUMP_INFO,
+			DBG_LVL_ALL,
+			"LED Thread: ValidateDSDParamsChecksum: Checksums don't match");
 		Status = STATUS_IMAGE_CHECKSUM_MISMATCH;
 		goto exit;
 	}
@@ -311,523 +332,526 @@
 }
 
 
-//-----------------------------------------------------------------------------
-// Procedure:   ValidateHWParmStructure
-//
-// Description: Validates HW Parameters.
-//
-// Arguments:
-//      Adapter - Pointer to Adapter structure.
-//      ulHwParamOffset - Start offset of the HW parameter Section to be read and validated.
-//
-// Returns:
-//  <OSAL_STATUS_CODE>
-//-----------------------------------------------------------------------------
-
+/*
+ * -----------------------------------------------------------------------------
+ * Procedure:   ValidateHWParmStructure
+ *
+ * Description: Validates HW Parameters.
+ *
+ * Arguments:
+ *      Adapter - Pointer to Adapter structure.
+ *      ulHwParamOffset - Start offset of the HW parameter Section to be read
+ *				and validated.
+ *
+ * Returns:
+ *  <OSAL_STATUS_CODE>
+ * -----------------------------------------------------------------------------
+ */
 static INT ValidateHWParmStructure(PMINI_ADAPTER Adapter, ULONG ulHwParamOffset)
 {
 
-	INT Status = STATUS_SUCCESS ;
+	INT Status = STATUS_SUCCESS;
 	USHORT HwParamLen = 0;
-	// Add DSD start offset to the hwParamOffset to get the actual address.
+	/*
+	 * Add DSD start offset to the hwParamOffset to get
+	 * the actual address.
+	 */
 	ulHwParamOffset += DSD_START_OFFSET;
 
-	/*Read the Length of HW_PARAM structure*/
-	BeceemNVMRead(Adapter,(PUINT)&HwParamLen,ulHwParamOffset,2);
+	/* Read the Length of HW_PARAM structure */
+	BeceemNVMRead(Adapter, (PUINT)&HwParamLen, ulHwParamOffset, 2);
 	HwParamLen = ntohs(HwParamLen);
-	if(0==HwParamLen || HwParamLen > Adapter->uiNVMDSDSize)
-	{
+	if (0 == HwParamLen || HwParamLen > Adapter->uiNVMDSDSize)
 		return STATUS_IMAGE_CHECKSUM_MISMATCH;
-	}
 
-	BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, LED_DUMP_INFO, DBG_LVL_ALL, "LED Thread:HwParamLen = 0x%x", HwParamLen);
-	Status =ValidateDSDParamsChecksum(Adapter,ulHwParamOffset,HwParamLen);
+	BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, LED_DUMP_INFO, DBG_LVL_ALL,
+		"LED Thread:HwParamLen = 0x%x", HwParamLen);
+	Status = ValidateDSDParamsChecksum(Adapter, ulHwParamOffset,
+						HwParamLen);
 	return Status;
 } /* ValidateHWParmStructure() */
 
-static int ReadLEDInformationFromEEPROM(PMINI_ADAPTER Adapter, UCHAR GPIO_Array[])
+static int ReadLEDInformationFromEEPROM(PMINI_ADAPTER Adapter,
+					UCHAR GPIO_Array[])
 {
 	int Status = STATUS_SUCCESS;
 
-	ULONG  dwReadValue 		= 0;
-	USHORT usHwParamData 	= 0;
-	USHORT usEEPROMVersion  = 0;
-	UCHAR  ucIndex 			= 0;
-	UCHAR  ucGPIOInfo[32] 	= {0};
+	ULONG  dwReadValue	= 0;
+	USHORT usHwParamData	= 0;
+	USHORT usEEPROMVersion	= 0;
+	UCHAR  ucIndex		= 0;
+	UCHAR  ucGPIOInfo[32]	= {0};
 
-	BeceemNVMRead(Adapter,(PUINT)&usEEPROMVersion,EEPROM_VERSION_OFFSET,2);
+	BeceemNVMRead(Adapter, (PUINT)&usEEPROMVersion,
+			EEPROM_VERSION_OFFSET, 2);
 
-	BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, LED_DUMP_INFO, DBG_LVL_ALL,"usEEPROMVersion: Minor:0x%X Major:0x%x",usEEPROMVersion&0xFF, ((usEEPROMVersion>>8)&0xFF));
+	BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, LED_DUMP_INFO, DBG_LVL_ALL,
+		"usEEPROMVersion: Minor:0x%X Major:0x%x",
+		usEEPROMVersion&0xFF, ((usEEPROMVersion>>8)&0xFF));
 
 
-	if(((usEEPROMVersion>>8)&0xFF) < EEPROM_MAP5_MAJORVERSION)
-	{
-		BeceemNVMRead(Adapter,(PUINT)&usHwParamData,EEPROM_HW_PARAM_POINTER_ADDRESS,2);
+	if (((usEEPROMVersion>>8)&0xFF) < EEPROM_MAP5_MAJORVERSION) {
+		BeceemNVMRead(Adapter, (PUINT)&usHwParamData,
+			EEPROM_HW_PARAM_POINTER_ADDRESS, 2);
 		usHwParamData = ntohs(usHwParamData);
 		dwReadValue   = usHwParamData;
-	}
-	else
-	{
-		//
-		// Validate Compatibility section and then read HW param if compatibility section is valid.
-		//
+	} else {
+		/*
+		 * Validate Compatibility section and then read HW param
+		 * if compatibility section is valid.
+		 */
 		Status = ValidateDSDParamsChecksum(Adapter,
-			                   DSD_START_OFFSET,
-			                   COMPATIBILITY_SECTION_LENGTH_MAP5);
+				DSD_START_OFFSET,
+				COMPATIBILITY_SECTION_LENGTH_MAP5);
 
-		if(Status != STATUS_SUCCESS)
-		{
+		if (Status != STATUS_SUCCESS)
 			return Status;
-		}
-		BeceemNVMRead(Adapter,(PUINT)&dwReadValue,EEPROM_HW_PARAM_POINTER_ADDRRES_MAP5,4);
+
+		BeceemNVMRead(Adapter, (PUINT)&dwReadValue,
+			EEPROM_HW_PARAM_POINTER_ADDRRES_MAP5, 4);
 		dwReadValue = ntohl(dwReadValue);
 	}
 
 
-	BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, LED_DUMP_INFO, DBG_LVL_ALL,"LED Thread: Start address of HW_PARAM structure = 0x%lx",dwReadValue);
-
-	//
-	// Validate if the address read out is within the DSD.
-	// Adapter->uiNVMDSDSize gives whole DSD size inclusive of Autoinit.
-	// lower limit should be above DSD_START_OFFSET and
-	// upper limit should be below (Adapter->uiNVMDSDSize-DSD_START_OFFSET)
-	//
-	if(dwReadValue < DSD_START_OFFSET ||
-	   dwReadValue > (Adapter->uiNVMDSDSize-DSD_START_OFFSET))
-	{
-		return STATUS_IMAGE_CHECKSUM_MISMATCH;
-	}
-
-	Status = ValidateHWParmStructure(Adapter, dwReadValue);
-	if(Status){
-		return Status;
-	}
+	BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, LED_DUMP_INFO, DBG_LVL_ALL,
+		"LED Thread: Start address of HW_PARAM structure = 0x%lx",
+		dwReadValue);
 
 	/*
-	  Add DSD_START_OFFSET to the offset read from the EEPROM.
-	  This will give the actual start HW Parameters start address.
-	  To read GPIO section, add GPIO offset further.
-	*/
+	 * Validate if the address read out is within the DSD.
+	 * Adapter->uiNVMDSDSize gives whole DSD size inclusive of Autoinit.
+	 * lower limit should be above DSD_START_OFFSET and
+	 * upper limit should be below (Adapter->uiNVMDSDSize-DSD_START_OFFSET)
+	 */
+	if (dwReadValue < DSD_START_OFFSET ||
+			dwReadValue > (Adapter->uiNVMDSDSize-DSD_START_OFFSET))
+		return STATUS_IMAGE_CHECKSUM_MISMATCH;
 
-	dwReadValue += DSD_START_OFFSET; // = start address of hw param section.
-	dwReadValue += GPIO_SECTION_START_OFFSET; // = GPIO start offset within HW Param section.
+	Status = ValidateHWParmStructure(Adapter, dwReadValue);
+	if (Status)
+		return Status;
 
-	/* Read the GPIO values for 32 GPIOs from EEPROM and map the function
- 	 * number to GPIO pin number to GPIO_Array
- 	 */
-	BeceemNVMRead(Adapter, (UINT *)ucGPIOInfo,dwReadValue,32);
-	for(ucIndex = 0; ucIndex < 32; ucIndex++)
-	 {
+	/*
+	 * Add DSD_START_OFFSET to the offset read from the EEPROM.
+	 * This will give the actual start HW Parameters start address.
+	 * To read GPIO section, add GPIO offset further.
+	 */
 
-		 switch(ucGPIOInfo[ucIndex])
-			{
-				case RED_LED:
-				{
-				 	GPIO_Array[RED_LED] = ucIndex;
-				 	Adapter->gpioBitMap |= (1<<ucIndex);
-					break;
-				}
-				case BLUE_LED:
-				{
-					GPIO_Array[BLUE_LED] = ucIndex;
-					Adapter->gpioBitMap |= (1<<ucIndex);
-					break;
-				}
-				case YELLOW_LED:
-				{
-					 GPIO_Array[YELLOW_LED] = ucIndex;
-					 Adapter->gpioBitMap |= (1<<ucIndex);
-					 break;
-				}
-				case GREEN_LED:
-				{
-					GPIO_Array[GREEN_LED] = ucIndex;
-				 	Adapter->gpioBitMap |= (1<<ucIndex);
-					break;
-				}
-				default:
-					break;
-			}
+	dwReadValue +=
+		DSD_START_OFFSET; /* = start address of hw param section. */
+	dwReadValue += GPIO_SECTION_START_OFFSET;
+			/* = GPIO start offset within HW Param section. */
 
+	/*
+	 * Read the GPIO values for 32 GPIOs from EEPROM and map the function
+	 * number to GPIO pin number to GPIO_Array
+	 */
+	BeceemNVMRead(Adapter, (UINT *)ucGPIOInfo, dwReadValue, 32);
+	for (ucIndex = 0; ucIndex < 32; ucIndex++) {
+
+		switch (ucGPIOInfo[ucIndex]) {
+		case RED_LED:
+			GPIO_Array[RED_LED] = ucIndex;
+			Adapter->gpioBitMap |= (1 << ucIndex);
+			break;
+		case BLUE_LED:
+			GPIO_Array[BLUE_LED] = ucIndex;
+			Adapter->gpioBitMap |= (1 << ucIndex);
+			break;
+		case YELLOW_LED:
+			GPIO_Array[YELLOW_LED] = ucIndex;
+			Adapter->gpioBitMap |= (1 << ucIndex);
+			break;
+		case GREEN_LED:
+			GPIO_Array[GREEN_LED] = ucIndex;
+			Adapter->gpioBitMap |= (1 << ucIndex);
+			break;
+		default:
+			break;
 		}
-		BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, LED_DUMP_INFO, DBG_LVL_ALL,"GPIO's bit map correspond to LED :0x%X",Adapter->gpioBitMap);
-	 return Status;
+
+	}
+	BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, LED_DUMP_INFO, DBG_LVL_ALL,
+		"GPIO's bit map correspond to LED :0x%X", Adapter->gpioBitMap);
+	return Status;
 }
 
 
-static int ReadConfigFileStructure(PMINI_ADAPTER Adapter, BOOLEAN *bEnableThread)
+static int ReadConfigFileStructure(PMINI_ADAPTER Adapter,
+					BOOLEAN *bEnableThread)
 {
 	int Status = STATUS_SUCCESS;
-	UCHAR GPIO_Array[NUM_OF_LEDS+1]; /*Array to store GPIO numbers from EEPROM*/
+	/* Array to store GPIO numbers from EEPROM */
+	UCHAR GPIO_Array[NUM_OF_LEDS+1];
 	UINT uiIndex = 0;
 	UINT uiNum_of_LED_Type = 0;
 	PUCHAR puCFGData	= NULL;
 	UCHAR bData = 0;
 	memset(GPIO_Array, DISABLE_GPIO_NUM, NUM_OF_LEDS+1);
 
-	if(!Adapter->pstargetparams || IS_ERR(Adapter->pstargetparams))
-	{
-		BCM_DEBUG_PRINT (Adapter,DBG_TYPE_OTHERS, LED_DUMP_INFO, DBG_LVL_ALL, "Target Params not Avail.\n");
+	if (!Adapter->pstargetparams || IS_ERR(Adapter->pstargetparams)) {
+		BCM_DEBUG_PRINT (Adapter, DBG_TYPE_OTHERS, LED_DUMP_INFO,
+			DBG_LVL_ALL, "Target Params not Avail.\n");
 		return -ENOENT;
 	}
 
-	/*Populate GPIO_Array with GPIO numbers for LED functions*/
-	/*Read the GPIO numbers from EEPROM*/
+	/* Populate GPIO_Array with GPIO numbers for LED functions */
+	/* Read the GPIO numbers from EEPROM */
 	Status = ReadLEDInformationFromEEPROM(Adapter, GPIO_Array);
-	if(Status == STATUS_IMAGE_CHECKSUM_MISMATCH)
-	{
+	if (Status == STATUS_IMAGE_CHECKSUM_MISMATCH) {
 		*bEnableThread = FALSE;
 		return STATUS_SUCCESS;
-	}
-	else if(Status)
-	{
+	} else if (Status) {
 		*bEnableThread = FALSE;
 		return Status;
 	}
-  /*
-     * CONFIG file read successfully. Deallocate the memory of
-     * uiFileNameBufferSize
-     */
-	BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, LED_DUMP_INFO, DBG_LVL_ALL,"LED Thread: Config file read successfully\n");
+
+	/*
+	 * CONFIG file read successfully. Deallocate the memory of
+	 * uiFileNameBufferSize
+	 */
+	BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, LED_DUMP_INFO, DBG_LVL_ALL,
+		"LED Thread: Config file read successfully\n");
 	puCFGData = (PUCHAR) &Adapter->pstargetparams->HostDrvrConfig1;
 
 	/*
- 	 * Offset for HostDrvConfig1, HostDrvConfig2, HostDrvConfig3 which
- 	 * will have the information of LED type, LED on state for different
- 	 * driver state and LED blink state.
- 	 */
+	 * Offset for HostDrvConfig1, HostDrvConfig2, HostDrvConfig3 which
+	 * will have the information of LED type, LED on state for different
+	 * driver state and LED blink state.
+	 */
 
-	for(uiIndex = 0; uiIndex < NUM_OF_LEDS; uiIndex++)
-	{
+	for (uiIndex = 0; uiIndex < NUM_OF_LEDS; uiIndex++) {
 		bData = *puCFGData;
 
-		/*Check Bit 8 for polarity. If it is set, polarity is reverse polarity*/
-		if(bData & 0x80)
-		{
+		/*
+		 * Check Bit 8 for polarity. If it is set,
+		 * polarity is reverse polarity
+		 */
+		if (bData & 0x80) {
 			Adapter->LEDInfo.LEDState[uiIndex].BitPolarity = 0;
-			/*unset the bit 8*/
+			/* unset the bit 8 */
 			bData = bData & 0x7f;
 		}
 
 		Adapter->LEDInfo.LEDState[uiIndex].LED_Type = bData;
-		if(bData <= NUM_OF_LEDS)
-			Adapter->LEDInfo.LEDState[uiIndex].GPIO_Num = GPIO_Array[bData];
+		if (bData <= NUM_OF_LEDS)
+			Adapter->LEDInfo.LEDState[uiIndex].GPIO_Num =
+							GPIO_Array[bData];
 		else
-			Adapter->LEDInfo.LEDState[uiIndex].GPIO_Num = DISABLE_GPIO_NUM;
+			Adapter->LEDInfo.LEDState[uiIndex].GPIO_Num =
+							DISABLE_GPIO_NUM;
 
 		puCFGData++;
 		bData = *puCFGData;
 		Adapter->LEDInfo.LEDState[uiIndex].LED_On_State = bData;
 		puCFGData++;
 		bData = *puCFGData;
-		Adapter->LEDInfo.LEDState[uiIndex].LED_Blink_State= bData;
+		Adapter->LEDInfo.LEDState[uiIndex].LED_Blink_State = bData;
 		puCFGData++;
 	}
 
-	/*Check if all the LED settings are disabled. If it is disabled, dont launch the LED control thread.*/
-	for(uiIndex = 0; uiIndex<NUM_OF_LEDS; uiIndex++)
-	{
-		if((Adapter->LEDInfo.LEDState[uiIndex].LED_Type == DISABLE_GPIO_NUM) ||
-	 		(Adapter->LEDInfo.LEDState[uiIndex].LED_Type == 0x7f) ||
+	/*
+	 * Check if all the LED settings are disabled. If it is disabled,
+	 * dont launch the LED control thread.
+	 */
+	for (uiIndex = 0; uiIndex < NUM_OF_LEDS; uiIndex++) {
+		if ((Adapter->LEDInfo.LEDState[uiIndex].LED_Type == DISABLE_GPIO_NUM) ||
+			(Adapter->LEDInfo.LEDState[uiIndex].LED_Type == 0x7f) ||
 			(Adapter->LEDInfo.LEDState[uiIndex].LED_Type == 0))
 			uiNum_of_LED_Type++;
 	}
-	if(uiNum_of_LED_Type >= NUM_OF_LEDS)
+	if (uiNum_of_LED_Type >= NUM_OF_LEDS)
 		*bEnableThread = FALSE;
 
 	return Status;
 }
-//--------------------------------------------------------------------------
-// Procedure:   LedGpioInit
-//
-// Description: Initializes LED GPIOs. Makes the LED GPIOs to OUTPUT mode and make the
-//			  initial state to be OFF.
-//
-// Arguments:
-//      Adapter - Pointer to MINI_ADAPTER structure.
-//
-// Returns: VOID
-//
-//-----------------------------------------------------------------------------
 
+/*
+ * -----------------------------------------------------------------------------
+ * Procedure:   LedGpioInit
+ *
+ * Description: Initializes LED GPIOs. Makes the LED GPIOs to OUTPUT mode
+ *			  and make the initial state to be OFF.
+ *
+ * Arguments:
+ *      Adapter - Pointer to MINI_ADAPTER structure.
+ *
+ * Returns: VOID
+ *
+ * -----------------------------------------------------------------------------
+ */
 static VOID LedGpioInit(PMINI_ADAPTER Adapter)
 {
 	UINT uiResetValue = 0;
 	UINT uiIndex      = 0;
 
 	/* Set all LED GPIO Mode to output mode */
-	if(rdmalt(Adapter, GPIO_MODE_REGISTER, &uiResetValue, sizeof(uiResetValue)) <0)
-		BCM_DEBUG_PRINT (Adapter,DBG_TYPE_OTHERS, LED_DUMP_INFO, DBG_LVL_ALL,"LED Thread: RDM Failed\n");
-	for(uiIndex = 0; uiIndex < NUM_OF_LEDS; uiIndex++)
-	{
-		if(Adapter->LEDInfo.LEDState[uiIndex].GPIO_Num != DISABLE_GPIO_NUM)
+	if (rdmalt(Adapter, GPIO_MODE_REGISTER, &uiResetValue,
+			sizeof(uiResetValue)) < 0)
+		BCM_DEBUG_PRINT (Adapter, DBG_TYPE_OTHERS, LED_DUMP_INFO,
+			DBG_LVL_ALL, "LED Thread: RDM Failed\n");
+	for (uiIndex = 0; uiIndex < NUM_OF_LEDS; uiIndex++) {
+		if (Adapter->LEDInfo.LEDState[uiIndex].GPIO_Num !=
+				DISABLE_GPIO_NUM)
 			uiResetValue |= (1 << Adapter->LEDInfo.LEDState[uiIndex].GPIO_Num);
-		TURN_OFF_LED(1<<Adapter->LEDInfo.LEDState[uiIndex].GPIO_Num,uiIndex);
+		TURN_OFF_LED(1 << Adapter->LEDInfo.LEDState[uiIndex].GPIO_Num,
+				uiIndex);
 	}
-	if(wrmalt(Adapter, GPIO_MODE_REGISTER, &uiResetValue, sizeof(uiResetValue)) < 0)
-		BCM_DEBUG_PRINT (Adapter,DBG_TYPE_OTHERS, LED_DUMP_INFO, DBG_LVL_ALL,"LED Thread: WRM Failed\n");
+	if (wrmalt(Adapter, GPIO_MODE_REGISTER, &uiResetValue,
+			sizeof(uiResetValue)) < 0)
+		BCM_DEBUG_PRINT (Adapter, DBG_TYPE_OTHERS, LED_DUMP_INFO,
+			DBG_LVL_ALL, "LED Thread: WRM Failed\n");
 
-	Adapter->LEDInfo.bIdle_led_off =  FALSE;
+	Adapter->LEDInfo.bIdle_led_off = FALSE;
 }
-//-----------------------------------------------------------------------------
 
-static INT BcmGetGPIOPinInfo(PMINI_ADAPTER Adapter, UCHAR *GPIO_num_tx, UCHAR *GPIO_num_rx ,UCHAR *uiLedTxIndex, UCHAR *uiLedRxIndex,LedEventInfo_t currdriverstate)
+static INT BcmGetGPIOPinInfo(PMINI_ADAPTER Adapter, UCHAR *GPIO_num_tx,
+		UCHAR *GPIO_num_rx, UCHAR *uiLedTxIndex, UCHAR *uiLedRxIndex,
+		LedEventInfo_t currdriverstate)
 {
 	UINT uiIndex = 0;
 
 	*GPIO_num_tx = DISABLE_GPIO_NUM;
 	*GPIO_num_rx = DISABLE_GPIO_NUM;
 
-	for(uiIndex = 0; uiIndex < NUM_OF_LEDS; uiIndex++)
-	{
+	for (uiIndex = 0; uiIndex < NUM_OF_LEDS; uiIndex++) {
 
-		if((currdriverstate == NORMAL_OPERATION)||
-			(currdriverstate == IDLEMODE_EXIT)||
-			(currdriverstate == FW_DOWNLOAD))
-		{
-			if(Adapter->LEDInfo.LEDState[uiIndex].LED_Blink_State & currdriverstate)
-			{
-				if(Adapter->LEDInfo.LEDState[uiIndex].GPIO_Num != DISABLE_GPIO_NUM)
-				{
-					if(*GPIO_num_tx == DISABLE_GPIO_NUM)
-					{
+		if ((currdriverstate == NORMAL_OPERATION) ||
+				(currdriverstate == IDLEMODE_EXIT) ||
+				(currdriverstate == FW_DOWNLOAD)) {
+			if (Adapter->LEDInfo.LEDState[uiIndex].LED_Blink_State &
+					currdriverstate) {
+				if (Adapter->LEDInfo.LEDState[uiIndex].GPIO_Num
+						!= DISABLE_GPIO_NUM) {
+					if (*GPIO_num_tx == DISABLE_GPIO_NUM) {
 						*GPIO_num_tx = Adapter->LEDInfo.LEDState[uiIndex].GPIO_Num;
 						*uiLedTxIndex = uiIndex;
-					}
-					else
-					{
+					} else {
 						*GPIO_num_rx = Adapter->LEDInfo.LEDState[uiIndex].GPIO_Num;
 						*uiLedRxIndex = uiIndex;
 					}
 				}
 			}
-		}
-		else
-		{
-			if(Adapter->LEDInfo.LEDState[uiIndex].LED_On_State & currdriverstate)
-			{
-				if(Adapter->LEDInfo.LEDState[uiIndex].GPIO_Num != DISABLE_GPIO_NUM)
-				{
+		} else {
+			if (Adapter->LEDInfo.LEDState[uiIndex].LED_On_State
+					& currdriverstate) {
+				if (Adapter->LEDInfo.LEDState[uiIndex].GPIO_Num
+						!= DISABLE_GPIO_NUM) {
 					*GPIO_num_tx = Adapter->LEDInfo.LEDState[uiIndex].GPIO_Num;
 					*uiLedTxIndex = uiIndex;
 				}
 			}
 		}
 	}
-	return STATUS_SUCCESS ;
+	return STATUS_SUCCESS;
 }
 static VOID LEDControlThread(PMINI_ADAPTER Adapter)
 {
 	UINT uiIndex = 0;
 	UCHAR GPIO_num = 0;
-	UCHAR uiLedIndex = 0 ;
+	UCHAR uiLedIndex = 0;
 	UINT uiResetValue = 0;
 	LedEventInfo_t currdriverstate = 0;
 	ulong timeout = 0;
 
 	INT Status = 0;
 
-	UCHAR  dummyGPIONum = 0;
-	UCHAR  dummyIndex = 0;
+	UCHAR dummyGPIONum = 0;
+	UCHAR dummyIndex = 0;
 
-	//currdriverstate = Adapter->DriverState;
+	/* currdriverstate = Adapter->DriverState; */
 	Adapter->LEDInfo.bIdleMode_tx_from_host = FALSE;
 
-	/*Wait till event is triggered*/
-	//wait_event(Adapter->LEDInfo.notify_led_event,
-			//	currdriverstate!= Adapter->DriverState);
+	/*
+	 * Wait till event is triggered
+	 *
+	 * wait_event(Adapter->LEDInfo.notify_led_event,
+	 *	currdriverstate!= Adapter->DriverState);
+	 */
 
-	GPIO_num = DISABLE_GPIO_NUM ;
+	GPIO_num = DISABLE_GPIO_NUM;
 
-	while(TRUE)
-	{
-		/*Wait till event is triggered*/
-		if( (GPIO_num == DISABLE_GPIO_NUM)
+	while (TRUE) {
+		/* Wait till event is triggered */
+		if ((GPIO_num == DISABLE_GPIO_NUM)
 						||
-			((currdriverstate != FW_DOWNLOAD) &&
-			 (currdriverstate != NORMAL_OPERATION) &&
-			 (currdriverstate != LOWPOWER_MODE_ENTER))
-			 			||
-			 (currdriverstate == LED_THREAD_INACTIVE)	)
-		{
-			Status = wait_event_interruptible(Adapter->LEDInfo.notify_led_event,
-				currdriverstate != Adapter->DriverState || kthread_should_stop());
+				((currdriverstate != FW_DOWNLOAD) &&
+				 (currdriverstate != NORMAL_OPERATION) &&
+				 (currdriverstate != LOWPOWER_MODE_ENTER))
+						||
+				(currdriverstate == LED_THREAD_INACTIVE))
+			Status = wait_event_interruptible(
+					Adapter->LEDInfo.notify_led_event,
+					currdriverstate != Adapter->DriverState
+						|| kthread_should_stop());
+
+		if (kthread_should_stop() || Adapter->device_removed) {
+			BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, LED_DUMP_INFO,
+				DBG_LVL_ALL,
+				"Led thread got signal to exit..hence exiting");
+			Adapter->LEDInfo.led_thread_running =
+						BCM_LED_THREAD_DISABLED;
+			TURN_OFF_LED(1 << GPIO_num, uiLedIndex);
+			return; /* STATUS_FAILURE; */
 		}
 
-		if(kthread_should_stop() || Adapter->device_removed )
-		{
-			BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, LED_DUMP_INFO, DBG_LVL_ALL, "Led thread got signal to exit..hence exiting");
-			Adapter->LEDInfo.led_thread_running = BCM_LED_THREAD_DISABLED;
-			TURN_OFF_LED(1<<GPIO_num, uiLedIndex);
-			return ;//STATUS_FAILURE;
-		}
+		if (GPIO_num != DISABLE_GPIO_NUM)
+			TURN_OFF_LED(1 << GPIO_num, uiLedIndex);
 
-		if(GPIO_num != DISABLE_GPIO_NUM)
-		{
-			TURN_OFF_LED(1<<GPIO_num, uiLedIndex);
-		}
-
-		if(Adapter->LEDInfo.bLedInitDone == FALSE)
-		{
+		if (Adapter->LEDInfo.bLedInitDone == FALSE) {
 			LedGpioInit(Adapter);
 			Adapter->LEDInfo.bLedInitDone = TRUE;
 		}
 
-		switch(Adapter->DriverState)
-		{
-			case DRIVER_INIT:
-			{
-				currdriverstate = DRIVER_INIT;//Adapter->DriverState;
-				BcmGetGPIOPinInfo(Adapter, &GPIO_num, &dummyGPIONum, &uiLedIndex, &dummyIndex, currdriverstate);
+		switch (Adapter->DriverState) {
+		case DRIVER_INIT:
+			currdriverstate = DRIVER_INIT;
+					/* Adapter->DriverState; */
+			BcmGetGPIOPinInfo(Adapter, &GPIO_num, &dummyGPIONum,
+				&uiLedIndex, &dummyIndex, currdriverstate);
 
-				if(GPIO_num  != DISABLE_GPIO_NUM)
-				{
-					TURN_ON_LED(1<<GPIO_num, uiLedIndex);
-				}
+			if (GPIO_num != DISABLE_GPIO_NUM)
+				TURN_ON_LED(1 << GPIO_num, uiLedIndex);
+
+			break;
+		case FW_DOWNLOAD:
+			/*
+			 * BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS,
+			 *	LED_DUMP_INFO, DBG_LVL_ALL,
+			 *	"LED Thread: FW_DN_DONE called\n");
+			 */
+			currdriverstate = FW_DOWNLOAD;
+			BcmGetGPIOPinInfo(Adapter, &GPIO_num, &dummyGPIONum,
+				&uiLedIndex, &dummyIndex, currdriverstate);
+
+			if (GPIO_num != DISABLE_GPIO_NUM) {
+				timeout = 50;
+				LED_Blink(Adapter, 1 << GPIO_num, uiLedIndex,
+					timeout, -1, currdriverstate);
 			}
 			break;
-			case FW_DOWNLOAD:
-			{
-				//BCM_DEBUG_PRINT (Adapter,DBG_TYPE_OTHERS, LED_DUMP_INFO, DBG_LVL_ALL,"LED Thread: FW_DN_DONE called\n");
-				currdriverstate = FW_DOWNLOAD;
-				BcmGetGPIOPinInfo(Adapter, &GPIO_num, &dummyGPIONum,  &uiLedIndex, &dummyIndex, currdriverstate);
-
-				if(GPIO_num != DISABLE_GPIO_NUM)
-				{
-					timeout = 50;
-					LED_Blink(Adapter, 1<<GPIO_num, uiLedIndex, timeout, -1,currdriverstate);
-				}
-			}
-			break;
-			case FW_DOWNLOAD_DONE:
-			{
-				currdriverstate = FW_DOWNLOAD_DONE;
-				BcmGetGPIOPinInfo(Adapter, &GPIO_num, &dummyGPIONum, &uiLedIndex, &dummyIndex,currdriverstate);
-				if(GPIO_num != DISABLE_GPIO_NUM)
-				{
-					TURN_ON_LED(1<<GPIO_num, uiLedIndex);
-				}
-			}
+		case FW_DOWNLOAD_DONE:
+			currdriverstate = FW_DOWNLOAD_DONE;
+			BcmGetGPIOPinInfo(Adapter, &GPIO_num, &dummyGPIONum,
+				&uiLedIndex, &dummyIndex, currdriverstate);
+			if (GPIO_num != DISABLE_GPIO_NUM)
+				TURN_ON_LED(1 << GPIO_num, uiLedIndex);
 			break;
 
-			case SHUTDOWN_EXIT:
-			//no break, continue to NO_NETWORK_ENTRY state as well.
-
-			case NO_NETWORK_ENTRY:
-			{
-				currdriverstate = NO_NETWORK_ENTRY;
-				BcmGetGPIOPinInfo(Adapter, &GPIO_num, &dummyGPIONum, &uiLedIndex,&dummyGPIONum,currdriverstate);
-				if(GPIO_num != DISABLE_GPIO_NUM)
-				{
-					TURN_ON_LED(1<<GPIO_num, uiLedIndex);
-				}
-			}
+		case SHUTDOWN_EXIT:
+			/*
+			 * no break, continue to NO_NETWORK_ENTRY
+			 * state as well.
+			 */
+		case NO_NETWORK_ENTRY:
+			currdriverstate = NO_NETWORK_ENTRY;
+			BcmGetGPIOPinInfo(Adapter, &GPIO_num, &dummyGPIONum,
+				&uiLedIndex, &dummyGPIONum, currdriverstate);
+			if (GPIO_num != DISABLE_GPIO_NUM)
+				TURN_ON_LED(1 << GPIO_num, uiLedIndex);
 			break;
-			case NORMAL_OPERATION:
+		case NORMAL_OPERATION:
 			{
 				UCHAR GPIO_num_tx = DISABLE_GPIO_NUM;
 				UCHAR GPIO_num_rx = DISABLE_GPIO_NUM;
 				UCHAR uiLEDTx = 0;
 				UCHAR uiLEDRx = 0;
 				currdriverstate = NORMAL_OPERATION;
-				Adapter->LEDInfo.bIdle_led_off =  FALSE;
+				Adapter->LEDInfo.bIdle_led_off = FALSE;
 
-				BcmGetGPIOPinInfo(Adapter, &GPIO_num_tx, &GPIO_num_rx, &uiLEDTx,&uiLEDRx,currdriverstate);
-				if((GPIO_num_tx == DISABLE_GPIO_NUM) && (GPIO_num_rx == DISABLE_GPIO_NUM))
-				{
-					GPIO_num = DISABLE_GPIO_NUM ;
-				}
-				else
-				{
-					/*If single LED is selected, use same for both Tx and Rx*/
-					if(GPIO_num_tx == DISABLE_GPIO_NUM)
-					{
+				BcmGetGPIOPinInfo(Adapter, &GPIO_num_tx,
+					&GPIO_num_rx, &uiLEDTx, &uiLEDRx,
+					currdriverstate);
+				if ((GPIO_num_tx == DISABLE_GPIO_NUM) &&
+						(GPIO_num_rx ==
+						 DISABLE_GPIO_NUM)) {
+					GPIO_num = DISABLE_GPIO_NUM;
+				} else {
+					/*
+					 * If single LED is selected, use same
+					 * for both Tx and Rx
+					 */
+					if (GPIO_num_tx == DISABLE_GPIO_NUM) {
 						GPIO_num_tx = GPIO_num_rx;
 						uiLEDTx = uiLEDRx;
-					}
-					else if(GPIO_num_rx == DISABLE_GPIO_NUM)
-					{
+					} else if (GPIO_num_rx ==
+							DISABLE_GPIO_NUM) {
 						GPIO_num_rx = GPIO_num_tx;
 						uiLEDRx = uiLEDTx;
 					}
-				/*Blink the LED in proportionate to Tx and Rx transmissions.*/
-					LED_Proportional_Blink(Adapter, GPIO_num_tx, uiLEDTx, GPIO_num_rx, uiLEDRx,currdriverstate);
+					/*
+					 * Blink the LED in proportionate
+					 * to Tx and Rx transmissions.
+					 */
+					LED_Proportional_Blink(Adapter,
+						GPIO_num_tx, uiLEDTx,
+						GPIO_num_rx, uiLEDRx,
+						currdriverstate);
 				}
 			}
 			break;
-			case LOWPOWER_MODE_ENTER:
-			{
-				currdriverstate  = LOWPOWER_MODE_ENTER;
-				if( DEVICE_POWERSAVE_MODE_AS_MANUAL_CLOCK_GATING == Adapter->ulPowerSaveMode)
-				{
-					/* Turn OFF all the LED */
-					uiResetValue = 0;
-					for(uiIndex =0; uiIndex < NUM_OF_LEDS; uiIndex++)
-					{
-						if(Adapter->LEDInfo.LEDState[uiIndex].GPIO_Num != DISABLE_GPIO_NUM)
-						TURN_OFF_LED((1<<Adapter->LEDInfo.LEDState[uiIndex].GPIO_Num),uiIndex);
-					}
+		case LOWPOWER_MODE_ENTER:
+			currdriverstate = LOWPOWER_MODE_ENTER;
+			if (DEVICE_POWERSAVE_MODE_AS_MANUAL_CLOCK_GATING ==
+					Adapter->ulPowerSaveMode) {
+				/* Turn OFF all the LED */
+				uiResetValue = 0;
+				for (uiIndex = 0; uiIndex < NUM_OF_LEDS; uiIndex++) {
+					if (Adapter->LEDInfo.LEDState[uiIndex].GPIO_Num != DISABLE_GPIO_NUM)
+						TURN_OFF_LED((1 << Adapter->LEDInfo.LEDState[uiIndex].GPIO_Num), uiIndex);
+				}
 
-				}
-				/* Turn off LED And WAKE-UP for Sendinf IDLE mode ACK */
-				Adapter->LEDInfo.bLedInitDone = FALSE;
-				Adapter->LEDInfo.bIdle_led_off =  TRUE;
-				wake_up(&Adapter->LEDInfo.idleModeSyncEvent);
-				GPIO_num = DISABLE_GPIO_NUM;
-				break;
 			}
-			case IDLEMODE_CONTINUE:
-			{
-				currdriverstate = IDLEMODE_CONTINUE;
-				GPIO_num = DISABLE_GPIO_NUM;
+			/* Turn off LED And WAKE-UP for Sendinf IDLE mode ACK */
+			Adapter->LEDInfo.bLedInitDone = FALSE;
+			Adapter->LEDInfo.bIdle_led_off = TRUE;
+			wake_up(&Adapter->LEDInfo.idleModeSyncEvent);
+			GPIO_num = DISABLE_GPIO_NUM;
+			break;
+		case IDLEMODE_CONTINUE:
+			currdriverstate = IDLEMODE_CONTINUE;
+			GPIO_num = DISABLE_GPIO_NUM;
+			break;
+		case IDLEMODE_EXIT:
+			break;
+		case DRIVER_HALT:
+			currdriverstate = DRIVER_HALT;
+			GPIO_num = DISABLE_GPIO_NUM;
+			for (uiIndex = 0; uiIndex < NUM_OF_LEDS; uiIndex++) {
+				if (Adapter->LEDInfo.LEDState[uiIndex].GPIO_Num
+						!= DISABLE_GPIO_NUM)
+					TURN_OFF_LED((1 << Adapter->LEDInfo.LEDState[uiIndex].GPIO_Num), uiIndex);
+			}
+			/* Adapter->DriverState = DRIVER_INIT; */
+			break;
+		case LED_THREAD_INACTIVE:
+			BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, LED_DUMP_INFO,
+				DBG_LVL_ALL, "InActivating LED thread...");
+			currdriverstate = LED_THREAD_INACTIVE;
+			Adapter->LEDInfo.led_thread_running =
+					BCM_LED_THREAD_RUNNING_INACTIVELY;
+			Adapter->LEDInfo.bLedInitDone = FALSE;
+			/* disable ALL LED */
+			for (uiIndex = 0; uiIndex < NUM_OF_LEDS; uiIndex++) {
+				if (Adapter->LEDInfo.LEDState[uiIndex].GPIO_Num
+						!= DISABLE_GPIO_NUM)
+					TURN_OFF_LED((1 << Adapter->LEDInfo.LEDState[uiIndex].GPIO_Num), uiIndex);
 			}
 			break;
-			case IDLEMODE_EXIT:
-			{
-			}
-			break;
-			case DRIVER_HALT:
-			{
-				currdriverstate = DRIVER_HALT;
-				GPIO_num = DISABLE_GPIO_NUM;
-				for(uiIndex = 0; uiIndex < NUM_OF_LEDS; uiIndex++)
-				{
-					if(Adapter->LEDInfo.LEDState[uiIndex].GPIO_Num !=
-						DISABLE_GPIO_NUM)
-						TURN_OFF_LED((1<<Adapter->LEDInfo.LEDState[uiIndex].GPIO_Num),uiIndex);
-				}
-				//Adapter->DriverState = DRIVER_INIT;
-			}
-			break;
-			case LED_THREAD_INACTIVE :
-			{
-				BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, LED_DUMP_INFO, DBG_LVL_ALL,"InActivating LED thread...");
-				currdriverstate = LED_THREAD_INACTIVE;
-				Adapter->LEDInfo.led_thread_running = BCM_LED_THREAD_RUNNING_INACTIVELY ;
-				Adapter->LEDInfo.bLedInitDone = FALSE ;
-				//disable ALL LED
-				for(uiIndex = 0; uiIndex < NUM_OF_LEDS; uiIndex++)
-				{
-					if(Adapter->LEDInfo.LEDState[uiIndex].GPIO_Num !=
-						DISABLE_GPIO_NUM)
-						TURN_OFF_LED((1<<Adapter->LEDInfo.LEDState[uiIndex].GPIO_Num),uiIndex);
-				}
-			}
-			break;
-			case LED_THREAD_ACTIVE :
-			{
-				BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, LED_DUMP_INFO, DBG_LVL_ALL,"Activating LED thread again...");
-				if(Adapter->LinkUpStatus == FALSE)
-					Adapter->DriverState = NO_NETWORK_ENTRY;
-				else
-					Adapter->DriverState = NORMAL_OPERATION;
+		case LED_THREAD_ACTIVE:
+			BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, LED_DUMP_INFO,
+				DBG_LVL_ALL, "Activating LED thread again...");
+			if (Adapter->LinkUpStatus == FALSE)
+				Adapter->DriverState = NO_NETWORK_ENTRY;
+			else
+				Adapter->DriverState = NORMAL_OPERATION;
 
-				Adapter->LEDInfo.led_thread_running = BCM_LED_THREAD_RUNNING_ACTIVELY ;
-			}
+			Adapter->LEDInfo.led_thread_running =
+					BCM_LED_THREAD_RUNNING_ACTIVELY;
 			break;
-			//return;
-			default:
-				break;
+			/* return; */
+		default:
+			break;
 		}
 	}
 	Adapter->LEDInfo.led_thread_running = BCM_LED_THREAD_DISABLED;
@@ -839,49 +863,54 @@
 	BOOLEAN bEnableThread = TRUE;
 	UCHAR uiIndex = 0;
 
-	/*Initially set BitPolarity to normal polarity. The bit 8 of LED type
- * 	  is used to change the polarity of the LED.*/
+	/*
+	 * Initially set BitPolarity to normal polarity. The bit 8 of LED type
+	 * is used to change the polarity of the LED.
+	 */
 
-	for(uiIndex = 0; uiIndex < NUM_OF_LEDS; uiIndex++) {
+	for (uiIndex = 0; uiIndex < NUM_OF_LEDS; uiIndex++)
 		Adapter->LEDInfo.LEDState[uiIndex].BitPolarity = 1;
-	}
 
-	/*Read the LED settings of CONFIG file and map it to GPIO numbers in EEPROM*/
+	/*
+	 * Read the LED settings of CONFIG file and map it
+	 * to GPIO numbers in EEPROM
+	 */
 	Status = ReadConfigFileStructure(Adapter, &bEnableThread);
-	if(STATUS_SUCCESS != Status)
-	{
-		BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, LED_DUMP_INFO, DBG_LVL_ALL,"LED Thread: FAILED in ReadConfigFileStructure\n");
+	if (STATUS_SUCCESS != Status) {
+		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, LED_DUMP_INFO,
+			DBG_LVL_ALL,
+			"LED Thread: FAILED in ReadConfigFileStructure\n");
 		return Status;
 	}
 
-	if(Adapter->LEDInfo.led_thread_running)
-	{
-		if(bEnableThread)
+	if (Adapter->LEDInfo.led_thread_running) {
+		if (bEnableThread) {
 			;
-		else
-		{
+		} else {
 			Adapter->DriverState = DRIVER_HALT;
 			wake_up(&Adapter->LEDInfo.notify_led_event);
-			Adapter->LEDInfo.led_thread_running = BCM_LED_THREAD_DISABLED;
+			Adapter->LEDInfo.led_thread_running =
+						BCM_LED_THREAD_DISABLED;
 		}
 
-	}
-
-	else if(bEnableThread)
-	{
-		/*Create secondary thread to handle the LEDs*/
+	} else if (bEnableThread) {
+		/* Create secondary thread to handle the LEDs */
 		init_waitqueue_head(&Adapter->LEDInfo.notify_led_event);
 		init_waitqueue_head(&Adapter->LEDInfo.idleModeSyncEvent);
-		Adapter->LEDInfo.led_thread_running = BCM_LED_THREAD_RUNNING_ACTIVELY;
-		Adapter->LEDInfo.bIdle_led_off =  FALSE;
-		Adapter->LEDInfo.led_cntrl_threadid = kthread_run((int (*)(void *))
-            LEDControlThread, Adapter, "led_control_thread");
-		if(IS_ERR(Adapter->LEDInfo.led_cntrl_threadid))
-    	{
-        	BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, LED_DUMP_INFO, DBG_LVL_ALL, "Not able to spawn Kernel Thread\n");
-			Adapter->LEDInfo.led_thread_running = BCM_LED_THREAD_DISABLED;
-        	return PTR_ERR(Adapter->LEDInfo.led_cntrl_threadid);
-    	}
+		Adapter->LEDInfo.led_thread_running =
+					BCM_LED_THREAD_RUNNING_ACTIVELY;
+		Adapter->LEDInfo.bIdle_led_off = FALSE;
+		Adapter->LEDInfo.led_cntrl_threadid =
+			kthread_run((int (*)(void *)) LEDControlThread,
+			Adapter, "led_control_thread");
+		if (IS_ERR(Adapter->LEDInfo.led_cntrl_threadid)) {
+			BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, LED_DUMP_INFO,
+				DBG_LVL_ALL,
+				"Not able to spawn Kernel Thread\n");
+			Adapter->LEDInfo.led_thread_running =
+				BCM_LED_THREAD_DISABLED;
+			return PTR_ERR(Adapter->LEDInfo.led_cntrl_threadid);
+		}
 	}
 	return Status;
 }
diff --git a/drivers/staging/bcm/nvm.c b/drivers/staging/bcm/nvm.c
index 3de0daf..7d703cb 100644
--- a/drivers/staging/bcm/nvm.c
+++ b/drivers/staging/bcm/nvm.c
@@ -78,7 +78,7 @@
 	{
 		value=0;
 		uiStatus = 0 ;
-		rdmalt( Adapter, EEPROM_SPI_Q_STATUS1_REG,&uiStatus, sizeof(uiStatus));
+		rdmalt(Adapter, EEPROM_SPI_Q_STATUS1_REG, &uiStatus, sizeof(uiStatus));
 		if(Adapter->device_removed == TRUE)
 		{
 			BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Modem has got removed hence exiting....");
@@ -93,7 +93,7 @@
 			wrmalt( Adapter, EEPROM_SPI_Q_STATUS1_REG, &value, sizeof(value));
 
 			value =0;
-			rdmalt(Adapter, EEPROM_READ_DATAQ_REG,&value, sizeof(value));
+			rdmalt(Adapter, EEPROM_READ_DATAQ_REG, &value, sizeof(value));
 			uiData = (UCHAR)value;
 
 			break;
@@ -102,8 +102,8 @@
 		dwRetries-- ;
 		if ( dwRetries == 0 )
 		{
-			 rdmalt(Adapter, EEPROM_SPI_Q_STATUS1_REG,&value, sizeof(value));
-			 rdmalt(Adapter, EEPROM_SPI_Q_STATUS_REG,&value1, sizeof(value1));
+			 rdmalt(Adapter, EEPROM_SPI_Q_STATUS1_REG, &value, sizeof(value));
+			 rdmalt(Adapter, EEPROM_SPI_Q_STATUS_REG, &value1, sizeof(value1));
 			 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"0x3004 = %x 0x3008 = %x, retries = %d failed.\n",value,value1,  MAX_EEPROM_RETRIES*RETRIES_PER_DELAY);
 			return uiData;
 		}
@@ -158,7 +158,7 @@
 		{
 
 		uiStatus = 0;
-		rdmalt( Adapter, EEPROM_SPI_Q_STATUS1_REG, &uiStatus, sizeof(uiStatus));
+		rdmalt(Adapter, EEPROM_SPI_Q_STATUS1_REG, &uiStatus, sizeof(uiStatus));
 		if(Adapter->device_removed == TRUE)
 		{
 			BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Modem has got Removed.hence exiting from loop...");
@@ -202,8 +202,8 @@
 		{
 			value=0;
 			value1=0;
-			rdmalt(Adapter, EEPROM_SPI_Q_STATUS1_REG,&value, sizeof(value));
-			rdmalt(Adapter, EEPROM_SPI_Q_STATUS_REG,&value1, sizeof(value1));
+			rdmalt(Adapter, EEPROM_SPI_Q_STATUS1_REG, &value, sizeof(value));
+			rdmalt(Adapter, EEPROM_SPI_Q_STATUS_REG, &value1, sizeof(value1));
 			BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "dwNumWords %d 0x3004 = %x 0x3008 = %x  retries = %d failed.\n", dwNumWords, value,  value1,  MAX_EEPROM_RETRIES*RETRIES_PER_DELAY);
 			return STATUS_FAILURE;
 		}
@@ -217,22 +217,22 @@
 		pvalue = (PUCHAR)(pdwData + dwIndex);
 
 		value =0;
-		rdmalt(Adapter, EEPROM_READ_DATAQ_REG,&value, sizeof(value));
+		rdmalt(Adapter, EEPROM_READ_DATAQ_REG, &value, sizeof(value));
 
 		pvalue[0] = value;
 
 		value = 0;
-		rdmalt(Adapter, EEPROM_READ_DATAQ_REG,&value, sizeof(value));
+		rdmalt(Adapter, EEPROM_READ_DATAQ_REG, &value, sizeof(value));
 
 		pvalue[1] = value;
 
 		value =0;
-		rdmalt(Adapter, EEPROM_READ_DATAQ_REG,&value, sizeof(value));
+		rdmalt(Adapter, EEPROM_READ_DATAQ_REG, &value, sizeof(value));
 
 		pvalue[2] = value;
 
 		value = 0;
-		rdmalt(Adapter, EEPROM_READ_DATAQ_REG,&value, sizeof(value));
+		rdmalt(Adapter, EEPROM_READ_DATAQ_REG, &value, sizeof(value));
 
 		pvalue[3] = value;
 	}
@@ -445,6 +445,7 @@
 	UINT uiBytesToRead = uiNumBytes;
 	INT Status = 0;
 	UINT uiPartOffset = 0;
+	int bytes;
 
 	if(Adapter->device_removed )
 	{
@@ -469,9 +470,9 @@
 		uiBytesToRead = MAX_RW_SIZE - (uiOffset%MAX_RW_SIZE);
 		uiBytesToRead = MIN(uiNumBytes,uiBytesToRead);
 
-		if(rdm(Adapter,uiPartOffset, (PCHAR)pBuffer+uiIndex,uiBytesToRead))
-		{
-			Status = -1;
+		bytes = rdm(Adapter, uiPartOffset, (PCHAR)pBuffer+uiIndex, uiBytesToRead);
+		if (bytes < 0) {
+			Status = bytes;
 			Adapter->SelectedChip = RESET_CHIP_SELECT;
 			return Status;
 		}
@@ -488,9 +489,9 @@
 
 		uiBytesToRead = MIN(uiNumBytes,MAX_RW_SIZE);
 
-		if(rdm(Adapter,uiPartOffset, (PCHAR)pBuffer+uiIndex,uiBytesToRead))
-		{
-			Status = -1;
+		bytes = rdm(Adapter, uiPartOffset, (PCHAR)pBuffer+uiIndex, uiBytesToRead);
+		if (bytes < 0) {
+			Status = bytes;
 			break;
 		}
 
@@ -613,6 +614,7 @@
 	UINT iIndex = 0, iRetries = 0;
 	UINT uiStatus = 0;
 	UINT value;
+	int bytes;
 
 	for(iIndex=0;iIndex<numOfSectors;iIndex++)
 	{
@@ -632,10 +634,11 @@
 				return STATUS_FAILURE;
 			}
 
-			if(rdmalt(Adapter, FLASH_SPI_READQ_REG, &uiStatus, sizeof(uiStatus)) < 0 )
-			{
-				BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Reading status of FLASH_SPI_READQ_REG fails");
-				return STATUS_FAILURE;
+			bytes = rdmalt(Adapter, FLASH_SPI_READQ_REG, &uiStatus, sizeof(uiStatus));
+			if (bytes < 0) {
+				uiStatus = bytes;
+				BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Reading status of FLASH_SPI_READQ_REG fails");
+				return uiStatus;
 			}
 			iRetries++;
 			//After every try lets make the CPU free for 10 ms. generally time taken by the
@@ -679,6 +682,7 @@
 
 	UINT value;
 	ULONG ulData = *(PUCHAR)pData;
+	int bytes;
 
 //
 // need not write 0xFF because write requires an erase and erase will
@@ -720,10 +724,11 @@
 			return STATUS_FAILURE;
 	  	}
 	  	//__udelay(1);
-	  	if(rdmalt(Adapter, FLASH_SPI_READQ_REG, &uiStatus, sizeof(uiStatus)) < 0)
-	  	{
-	  		BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Reading status of FLASH_SPI_READQ_REG fails");
-			return STATUS_FAILURE;
+		bytes = rdmalt(Adapter, FLASH_SPI_READQ_REG, &uiStatus, sizeof(uiStatus));
+		if (bytes < 0) {
+			uiStatus = bytes;
+			BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Reading status of FLASH_SPI_READQ_REG fails");
+			return uiStatus;
 		}
 	  	iRetries--;
 		if( iRetries && ((iRetries % FLASH_PER_RETRIES_DELAY) == 0))
@@ -771,6 +776,7 @@
 
 	UINT value;
 	UINT uiErasePattern[4] = {0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF};
+	int bytes;
 //
 // need not write 0xFFFFFFFF because write requires an erase and erase will
 // make whole sector 0xFFFFFFFF.
@@ -803,10 +809,11 @@
 			return STATUS_FAILURE;
 	  	}
 	  	//__udelay(1);
-	  	if(rdmalt(Adapter, FLASH_SPI_READQ_REG, &uiStatus, sizeof(uiStatus)) < 0 )
-	  	{
-	  		BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Reading status of FLASH_SPI_READQ_REG fails");
-			return STATUS_FAILURE;
+		bytes = rdmalt(Adapter, FLASH_SPI_READQ_REG, &uiStatus, sizeof(uiStatus));
+		if (bytes < 0) {
+			uiStatus = bytes;
+			BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Reading status of FLASH_SPI_READQ_REG fails");
+			return uiStatus;
 		}
 
 		iRetries--;
@@ -849,6 +856,7 @@
 	INT  iRetries = MAX_FLASH_RETRIES * FLASH_PER_RETRIES_DELAY; //3
 	ULONG ulData  = *(PUCHAR)pData;
 	UINT value;
+	int bytes;
 
 //
 // need not write 0xFFFFFFFF because write requires an erase and erase will
@@ -891,10 +899,11 @@
 			return STATUS_FAILURE;
 		}
 		//__udelay(1);
-		if(rdmalt(Adapter, FLASH_SPI_READQ_REG, &uiStatus, sizeof(uiStatus)) < 0)
-		{
-			BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Reading status of FLASH_SPI_READQ_REG fails");
-			return STATUS_FAILURE;
+		bytes = rdmalt(Adapter, FLASH_SPI_READQ_REG, &uiStatus, sizeof(uiStatus));
+		if (bytes < 0) {
+			uiStatus = bytes;
+			BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Reading status of FLASH_SPI_READQ_REG fails");
+			return uiStatus;
 		}
 
 		iRetries--;
@@ -935,6 +944,7 @@
 	//UINT uiReadBack = 0;
 	UINT value;
 	UINT uiErasePattern[4] = {0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF};
+	int bytes;
 
 //
 // need not write 0xFFFFFFFF because write requires an erase and erase will
@@ -967,10 +977,11 @@
 			return STATUS_FAILURE;
 	  	}
 	  	//__udelay(1);
-	  	if(rdmalt(Adapter, FLASH_SPI_READQ_REG, &uiStatus, sizeof(uiStatus)) < 0)
-	  	{
-	  		BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Reading status of FLASH_SPI_READQ_REG fails");
-			return STATUS_FAILURE;
+		bytes = rdmalt(Adapter, FLASH_SPI_READQ_REG, &uiStatus, sizeof(uiStatus));
+		if (bytes < 0) {
+			uiStatus = bytes;
+			BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Reading status of FLASH_SPI_READQ_REG fails");
+			return uiStatus;
 		}
 	  	iRetries--;
 		//this will ensure that in there will be no changes in the current path.
@@ -1841,7 +1852,7 @@
 	 * What we are checking if the previous write has completed, and this
 	 * may take time. We should wait till the Empty bit is set. */
 	uiStatus = 0;
-	rdmalt( Adapter, EEPROM_SPI_Q_STATUS1_REG,&uiStatus, sizeof(uiStatus)) ;
+	rdmalt(Adapter, EEPROM_SPI_Q_STATUS1_REG, &uiStatus, sizeof(uiStatus));
 	while ( ( uiStatus & EEPROM_WRITE_QUEUE_EMPTY ) == 0 )
 	{
 		uiRetries--;
@@ -1855,7 +1866,7 @@
 					msleep(1);
 
 		uiStatus = 0;
-		rdmalt( Adapter, EEPROM_SPI_Q_STATUS1_REG,&uiStatus, sizeof(uiStatus)) ;
+		rdmalt(Adapter, EEPROM_SPI_Q_STATUS1_REG, &uiStatus, sizeof(uiStatus));
 		if(Adapter->device_removed == TRUE)
 		{
 			BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Modem got removed hence exiting from loop....");
@@ -2500,7 +2511,7 @@
 // Read SPI READQ REG. The output will be WWXXYYZZ.
 // The ID is 3Bytes long and is WWXXYY. ZZ needs to be Ignored.
 //
-	rdmalt(Adapter, FLASH_SPI_READQ_REG,(PUINT)&ulRDID, sizeof(ulRDID));
+	rdmalt(Adapter, FLASH_SPI_READQ_REG, (PUINT)&ulRDID, sizeof(ulRDID));
 
 	return (ulRDID >>8);
 
@@ -4735,8 +4746,8 @@
 	Adapter->SelectedChip = ChipNum ;
 
 	//bit[13..12]  will select the appropriate chip
-	rdmalt(Adapter,FLASH_CONFIG_REG, &FlashConfig, 4);
-	rdmalt(Adapter,FLASH_GPIO_CONFIG_REG, &GPIOConfig, 4);
+	rdmalt(Adapter, FLASH_CONFIG_REG, &FlashConfig, 4);
+	rdmalt(Adapter, FLASH_GPIO_CONFIG_REG, &GPIOConfig, 4);
 
 	{
 		switch(ChipNum)
diff --git a/drivers/staging/comedi/comedi_fops.c b/drivers/staging/comedi/comedi_fops.c
index 5e78c77..0d18d80 100644
--- a/drivers/staging/comedi/comedi_fops.c
+++ b/drivers/staging/comedi/comedi_fops.c
@@ -1479,10 +1479,10 @@
 
 	dev_file_info = comedi_get_device_file_info(minor);
 	if (dev_file_info == NULL)
-	        return -ENODEV;
+		return -ENODEV;
 	dev = dev_file_info->device;
 	if (dev == NULL)
-	        return -ENODEV;
+		return -ENODEV;
 
 	mutex_lock(&dev->mutex);
 	if (!dev->attached) {
@@ -1556,10 +1556,10 @@
 	dev_file_info = comedi_get_device_file_info(minor);
 
 	if (dev_file_info == NULL)
-	        return -ENODEV;
+		return -ENODEV;
 	dev = dev_file_info->device;
 	if (dev == NULL)
-	        return -ENODEV;
+		return -ENODEV;
 
 	mutex_lock(&dev->mutex);
 	if (!dev->attached) {
@@ -1610,10 +1610,10 @@
 	dev_file_info = comedi_get_device_file_info(minor);
 
 	if (dev_file_info == NULL)
-	        return -ENODEV;
+		return -ENODEV;
 	dev = dev_file_info->device;
 	if (dev == NULL)
-	        return -ENODEV;
+		return -ENODEV;
 
 	if (!dev->attached) {
 		DPRINTK("no driver configured on comedi%i\n", dev->minor);
@@ -1721,10 +1721,10 @@
 	dev_file_info = comedi_get_device_file_info(minor);
 
 	if (dev_file_info == NULL)
-	        return -ENODEV;
+		return -ENODEV;
 	dev = dev_file_info->device;
 	if (dev == NULL)
-	        return -ENODEV;
+		return -ENODEV;
 
 	if (!dev->attached) {
 		DPRINTK("no driver configured on comedi%i\n", dev->minor);
@@ -1931,10 +1931,10 @@
 	dev_file_info = comedi_get_device_file_info(minor);
 
 	if (dev_file_info == NULL)
-	        return -ENODEV;
+		return -ENODEV;
 	dev = dev_file_info->device;
 	if (dev == NULL)
-	        return -ENODEV;
+		return -ENODEV;
 
 	mutex_lock(&dev->mutex);
 
@@ -1973,10 +1973,10 @@
 	dev_file_info = comedi_get_device_file_info(minor);
 
 	if (dev_file_info == NULL)
-	        return -ENODEV;
+		return -ENODEV;
 	dev = dev_file_info->device;
 	if (dev == NULL)
-	        return -ENODEV;
+		return -ENODEV;
 
 	return fasync_helper(fd, file, on, &dev->async_queue);
 }
@@ -2479,18 +2479,18 @@
 					const char *buf, size_t count)
 {
 	struct comedi_device_file_info *info = dev_get_drvdata(dev);
-	unsigned long new_max_size_kb;
-	uint64_t new_max_size;
+	unsigned int new_max_size_kb;
+	unsigned int new_max_size;
+	int ret;
 	struct comedi_subdevice *const read_subdevice =
 	    comedi_get_read_subdevice(info);
 
-	if (strict_strtoul(buf, 10, &new_max_size_kb))
+	ret = kstrtouint(buf, 10, &new_max_size_kb);
+	if (ret)
+		return ret;
+	if (new_max_size_kb > (UINT_MAX / bytes_per_kibi))
 		return -EINVAL;
-	if (new_max_size_kb != (uint32_t) new_max_size_kb)
-		return -EINVAL;
-	new_max_size = ((uint64_t) new_max_size_kb) * bytes_per_kibi;
-	if (new_max_size != (uint32_t) new_max_size)
-		return -EINVAL;
+	new_max_size = new_max_size_kb * bytes_per_kibi;
 
 	mutex_lock(&info->device->mutex);
 	if (read_subdevice == NULL ||
@@ -2540,19 +2540,19 @@
 				    const char *buf, size_t count)
 {
 	struct comedi_device_file_info *info = dev_get_drvdata(dev);
-	unsigned long new_size_kb;
-	uint64_t new_size;
+	unsigned int new_size_kb;
+	unsigned int new_size;
 	int retval;
+	int ret;
 	struct comedi_subdevice *const read_subdevice =
 	    comedi_get_read_subdevice(info);
 
-	if (strict_strtoul(buf, 10, &new_size_kb))
+	ret = kstrtouint(buf, 10, &new_size_kb);
+	if (ret)
+		return ret;
+	if (new_size_kb > (UINT_MAX / bytes_per_kibi))
 		return -EINVAL;
-	if (new_size_kb != (uint32_t) new_size_kb)
-		return -EINVAL;
-	new_size = ((uint64_t) new_size_kb) * bytes_per_kibi;
-	if (new_size != (uint32_t) new_size)
-		return -EINVAL;
+	new_size = new_size_kb * bytes_per_kibi;
 
 	mutex_lock(&info->device->mutex);
 	if (read_subdevice == NULL ||
@@ -2606,18 +2606,18 @@
 					 const char *buf, size_t count)
 {
 	struct comedi_device_file_info *info = dev_get_drvdata(dev);
-	unsigned long new_max_size_kb;
-	uint64_t new_max_size;
+	unsigned int new_max_size_kb;
+	unsigned int new_max_size;
+	int ret;
 	struct comedi_subdevice *const write_subdevice =
 	    comedi_get_write_subdevice(info);
 
-	if (strict_strtoul(buf, 10, &new_max_size_kb))
+	ret = kstrtouint(buf, 10, &new_max_size_kb);
+	if (ret)
+		return ret;
+	if (new_max_size_kb > (UINT_MAX / bytes_per_kibi))
 		return -EINVAL;
-	if (new_max_size_kb != (uint32_t) new_max_size_kb)
-		return -EINVAL;
-	new_max_size = ((uint64_t) new_max_size_kb) * bytes_per_kibi;
-	if (new_max_size != (uint32_t) new_max_size)
-		return -EINVAL;
+	new_max_size = new_max_size_kb * bytes_per_kibi;
 
 	mutex_lock(&info->device->mutex);
 	if (write_subdevice == NULL ||
@@ -2667,19 +2667,19 @@
 				     const char *buf, size_t count)
 {
 	struct comedi_device_file_info *info = dev_get_drvdata(dev);
-	unsigned long new_size_kb;
-	uint64_t new_size;
+	unsigned int new_size_kb;
+	unsigned int new_size;
 	int retval;
+	int ret;
 	struct comedi_subdevice *const write_subdevice =
 	    comedi_get_write_subdevice(info);
 
-	if (strict_strtoul(buf, 10, &new_size_kb))
-		return -EINVAL;
-	if (new_size_kb != (uint32_t) new_size_kb)
+	ret = kstrtouint(buf, 10, &new_size_kb);
+	if (ret)
+		return ret;
+	if (new_size_kb > (UINT_MAX / bytes_per_kibi))
 		return -EINVAL;
 	new_size = ((uint64_t) new_size_kb) * bytes_per_kibi;
-	if (new_size != (uint32_t) new_size)
-		return -EINVAL;
 
 	mutex_lock(&info->device->mutex);
 	if (write_subdevice == NULL ||
diff --git a/drivers/staging/comedi/drivers/addi-data/addi_common.c b/drivers/staging/comedi/drivers/addi-data/addi_common.c
index 6fb7594..ca5bd9b8 100644
--- a/drivers/staging/comedi/drivers/addi-data/addi_common.c
+++ b/drivers/staging/comedi/drivers/addi-data/addi_common.c
@@ -145,78 +145,77 @@
 
 static DEFINE_PCI_DEVICE_TABLE(addi_apci_tbl) = {
 #ifdef CONFIG_APCI_3120
-	{APCI3120_BOARD_VENDOR_ID, 0x818D, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+	{PCI_DEVICE(APCI3120_BOARD_VENDOR_ID, 0x818D)},
 #endif
 #ifdef CONFIG_APCI_1032
-	{APCI1032_BOARD_VENDOR_ID, 0x1003, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+	{PCI_DEVICE(APCI1032_BOARD_VENDOR_ID, 0x1003)},
 #endif
 #ifdef CONFIG_APCI_1516
-	{APCI1516_BOARD_VENDOR_ID, 0x1001, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+	{PCI_DEVICE(APCI1516_BOARD_VENDOR_ID, 0x1001)},
 #endif
 #ifdef CONFIG_APCI_2016
-	{APCI2016_BOARD_VENDOR_ID, 0x1002, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+	{PCI_DEVICE(APCI2016_BOARD_VENDOR_ID, 0x1002)},
 #endif
 #ifdef CONFIG_APCI_2032
-	{APCI2032_BOARD_VENDOR_ID, 0x1004, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+	{PCI_DEVICE(APCI2032_BOARD_VENDOR_ID, 0x1004)},
 #endif
 #ifdef CONFIG_APCI_2200
-	{APCI2200_BOARD_VENDOR_ID, 0x1005, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+	{PCI_DEVICE(APCI2200_BOARD_VENDOR_ID, 0x1005)},
 #endif
 #ifdef CONFIG_APCI_1564
-	{APCI1564_BOARD_VENDOR_ID, 0x1006, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+	{PCI_DEVICE(APCI1564_BOARD_VENDOR_ID, 0x1006)},
 #endif
 #ifdef CONFIG_APCI_1500
-	{APCI1500_BOARD_VENDOR_ID, 0x80fc, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+	{PCI_DEVICE(APCI1500_BOARD_VENDOR_ID, 0x80fc)},
 #endif
 #ifdef CONFIG_APCI_3001
-	{APCI3120_BOARD_VENDOR_ID, 0x828D, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+	{PCI_DEVICE(APCI3120_BOARD_VENDOR_ID, 0x828D)},
 #endif
 #ifdef CONFIG_APCI_3501
-	{APCI3501_BOARD_VENDOR_ID, 0x3001, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+	{PCI_DEVICE(APCI3501_BOARD_VENDOR_ID, 0x3001)},
 #endif
 #ifdef CONFIG_APCI_035
-	{APCI035_BOARD_VENDOR_ID, 0x0300, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+	{PCI_DEVICE(APCI035_BOARD_VENDOR_ID,  0x0300)},
 #endif
 #ifdef CONFIG_APCI_3200
-	{APCI3200_BOARD_VENDOR_ID, 0x3000, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+	{PCI_DEVICE(APCI3200_BOARD_VENDOR_ID, 0x3000)},
 #endif
 #ifdef CONFIG_APCI_3300
-	{APCI3200_BOARD_VENDOR_ID, 0x3007, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+	{PCI_DEVICE(APCI3200_BOARD_VENDOR_ID, 0x3007)},
 #endif
 #ifdef CONFIG_APCI_1710
-	{APCI1710_BOARD_VENDOR_ID, APCI1710_BOARD_DEVICE_ID,
-		PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+	{PCI_DEVICE(APCI1710_BOARD_VENDOR_ID, APCI1710_BOARD_DEVICE_ID)},
 #endif
 #ifdef CONFIG_APCI_16XX
-	{0x15B8, 0x1009, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
-	{0x15B8, 0x100A, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+	{PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, 0x1009)},
+	{PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, 0x100A)},
 #endif
 #ifdef CONFIG_APCI_3XXX
-	{0x15B8, 0x3010, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
-	{0x15B8, 0x300F, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
-	{0x15B8, 0x300E, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
-	{0x15B8, 0x3013, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
-	{0x15B8, 0x3014, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
-	{0x15B8, 0x3015, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
-	{0x15B8, 0x3016, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
-	{0x15B8, 0x3017, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
-	{0x15B8, 0x3018, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
-	{0x15B8, 0x3019, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
-	{0x15B8, 0x301A, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
-	{0x15B8, 0x301B, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
-	{0x15B8, 0x301C, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
-	{0x15B8, 0x301D, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
-	{0x15B8, 0x301E, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
-	{0x15B8, 0x301F, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
-	{0x15B8, 0x3020, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
-	{0x15B8, 0x3021, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
-	{0x15B8, 0x3022, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
-	{0x15B8, 0x3023, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
-	{0x15B8, 0x300B, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
-	{0x15B8, 0x3002, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
-	{0x15B8, 0x3003, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
-	{0x15B8, 0x3004, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
-	{0x15B8, 0x3024, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+	{PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, 0x3010)},
+	{PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, 0x300F)},
+	{PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, 0x300E)},
+	{PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, 0x3013)},
+	{PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, 0x3014)},
+	{PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, 0x3015)},
+	{PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, 0x3016)},
+	{PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, 0x3017)},
+	{PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, 0x3018)},
+	{PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, 0x3019)},
+	{PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, 0x301A)},
+	{PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, 0x301B)},
+	{PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, 0x301C)},
+	{PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, 0x301D)},
+	{PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, 0x301E)},
+	{PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, 0x301F)},
+	{PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, 0x3020)},
+	{PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, 0x3021)},
+	{PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, 0x3022)},
+	{PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, 0x3023)},
+	{PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, 0x300B)},
+	{PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, 0x3002)},
+	{PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, 0x3003)},
+	{PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, 0x3004)},
+	{PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, 0x3024)},
 #endif
 	{0}
 };
@@ -1019,7 +1018,7 @@
 #endif
 #ifdef CONFIG_APCI_16XX
 	{"apci1648",
-			0x15B8,
+			PCI_VENDOR_ID_ADDIDATA,
 			0x1009,
 			128,
 			0,
@@ -1075,7 +1074,7 @@
 		i_APCI16XX_InsnBitsWriteTTLIO},
 
 	{"apci1696",
-			0x15B8,
+			PCI_VENDOR_ID_ADDIDATA,
 			0x100A,
 			128,
 			0,
@@ -1132,7 +1131,7 @@
 #endif
 #ifdef CONFIG_APCI_3XXX
 	{"apci3000-16",
-			0x15B8,
+			PCI_VENDOR_ID_ADDIDATA,
 			0x3010,
 			256,
 			256,
@@ -1188,7 +1187,7 @@
 		i_APCI3XXX_InsnWriteTTLIO},
 
 	{"apci3000-8",
-			0x15B8,
+			PCI_VENDOR_ID_ADDIDATA,
 			0x300F,
 			256,
 			256,
@@ -1244,7 +1243,7 @@
 		i_APCI3XXX_InsnWriteTTLIO},
 
 	{"apci3000-4",
-			0x15B8,
+			PCI_VENDOR_ID_ADDIDATA,
 			0x300E,
 			256,
 			256,
@@ -1300,7 +1299,7 @@
 		i_APCI3XXX_InsnWriteTTLIO},
 
 	{"apci3006-16",
-			0x15B8,
+			PCI_VENDOR_ID_ADDIDATA,
 			0x3013,
 			256,
 			256,
@@ -1356,7 +1355,7 @@
 		i_APCI3XXX_InsnWriteTTLIO},
 
 	{"apci3006-8",
-			0x15B8,
+			PCI_VENDOR_ID_ADDIDATA,
 			0x3014,
 			256,
 			256,
@@ -1412,7 +1411,7 @@
 		i_APCI3XXX_InsnWriteTTLIO},
 
 	{"apci3006-4",
-			0x15B8,
+			PCI_VENDOR_ID_ADDIDATA,
 			0x3015,
 			256,
 			256,
@@ -1468,7 +1467,7 @@
 		i_APCI3XXX_InsnWriteTTLIO},
 
 	{"apci3010-16",
-			0x15B8,
+			PCI_VENDOR_ID_ADDIDATA,
 			0x3016,
 			256,
 			256,
@@ -1524,7 +1523,7 @@
 		i_APCI3XXX_InsnWriteTTLIO},
 
 	{"apci3010-8",
-			0x15B8,
+			PCI_VENDOR_ID_ADDIDATA,
 			0x3017,
 			256,
 			256,
@@ -1580,7 +1579,7 @@
 		i_APCI3XXX_InsnWriteTTLIO},
 
 	{"apci3010-4",
-			0x15B8,
+			PCI_VENDOR_ID_ADDIDATA,
 			0x3018,
 			256,
 			256,
@@ -1636,7 +1635,7 @@
 		i_APCI3XXX_InsnWriteTTLIO},
 
 	{"apci3016-16",
-			0x15B8,
+			PCI_VENDOR_ID_ADDIDATA,
 			0x3019,
 			256,
 			256,
@@ -1692,7 +1691,7 @@
 		i_APCI3XXX_InsnWriteTTLIO},
 
 	{"apci3016-8",
-			0x15B8,
+			PCI_VENDOR_ID_ADDIDATA,
 			0x301A,
 			256,
 			256,
@@ -1748,7 +1747,7 @@
 		i_APCI3XXX_InsnWriteTTLIO},
 
 	{"apci3016-4",
-			0x15B8,
+			PCI_VENDOR_ID_ADDIDATA,
 			0x301B,
 			256,
 			256,
@@ -1804,7 +1803,7 @@
 		i_APCI3XXX_InsnWriteTTLIO},
 
 	{"apci3100-16-4",
-			0x15B8,
+			PCI_VENDOR_ID_ADDIDATA,
 			0x301C,
 			256,
 			256,
@@ -1860,7 +1859,7 @@
 		i_APCI3XXX_InsnWriteTTLIO},
 
 	{"apci3100-8-4",
-			0x15B8,
+			PCI_VENDOR_ID_ADDIDATA,
 			0x301D,
 			256,
 			256,
@@ -1916,7 +1915,7 @@
 		i_APCI3XXX_InsnWriteTTLIO},
 
 	{"apci3106-16-4",
-			0x15B8,
+			PCI_VENDOR_ID_ADDIDATA,
 			0x301E,
 			256,
 			256,
@@ -1972,7 +1971,7 @@
 		i_APCI3XXX_InsnWriteTTLIO},
 
 	{"apci3106-8-4",
-			0x15B8,
+			PCI_VENDOR_ID_ADDIDATA,
 			0x301F,
 			256,
 			256,
@@ -2028,7 +2027,7 @@
 		i_APCI3XXX_InsnWriteTTLIO},
 
 	{"apci3110-16-4",
-			0x15B8,
+			PCI_VENDOR_ID_ADDIDATA,
 			0x3020,
 			256,
 			256,
@@ -2084,7 +2083,7 @@
 		i_APCI3XXX_InsnWriteTTLIO},
 
 	{"apci3110-8-4",
-			0x15B8,
+			PCI_VENDOR_ID_ADDIDATA,
 			0x3021,
 			256,
 			256,
@@ -2140,7 +2139,7 @@
 		i_APCI3XXX_InsnWriteTTLIO},
 
 	{"apci3116-16-4",
-			0x15B8,
+			PCI_VENDOR_ID_ADDIDATA,
 			0x3022,
 			256,
 			256,
@@ -2196,7 +2195,7 @@
 		i_APCI3XXX_InsnWriteTTLIO},
 
 	{"apci3116-8-4",
-			0x15B8,
+			PCI_VENDOR_ID_ADDIDATA,
 			0x3023,
 			256,
 			256,
@@ -2252,7 +2251,7 @@
 		i_APCI3XXX_InsnWriteTTLIO},
 
 	{"apci3003",
-			0x15B8,
+			PCI_VENDOR_ID_ADDIDATA,
 			0x300B,
 			256,
 			256,
@@ -2307,7 +2306,7 @@
 		NULL},
 
 	{"apci3002-16",
-			0x15B8,
+			PCI_VENDOR_ID_ADDIDATA,
 			0x3002,
 			256,
 			256,
@@ -2362,7 +2361,7 @@
 		NULL},
 
 	{"apci3002-8",
-			0x15B8,
+			PCI_VENDOR_ID_ADDIDATA,
 			0x3003,
 			256,
 			256,
@@ -2417,7 +2416,7 @@
 		NULL},
 
 	{"apci3002-4",
-			0x15B8,
+			PCI_VENDOR_ID_ADDIDATA,
 			0x3004,
 			256,
 			256,
@@ -2472,7 +2471,7 @@
 		NULL},
 
 	{"apci3500",
-			0x15B8,
+			PCI_VENDOR_ID_ADDIDATA,
 			0x3024,
 			256,
 			256,
diff --git a/drivers/staging/comedi/drivers/adl_pci7230.c b/drivers/staging/comedi/drivers/adl_pci7230.c
index 72a7258..20d5705 100644
--- a/drivers/staging/comedi/drivers/adl_pci7230.c
+++ b/drivers/staging/comedi/drivers/adl_pci7230.c
@@ -44,15 +44,7 @@
 #define PCI_DEVICE_ID_PCI7230 0x7230
 
 static DEFINE_PCI_DEVICE_TABLE(adl_pci7230_pci_table) = {
-	{
-		PCI_VENDOR_ID_ADLINK,
-		PCI_DEVICE_ID_PCI7230,
-		PCI_ANY_ID,
-		PCI_ANY_ID,
-		0,
-		0,
-		0
-	},
+	{ PCI_DEVICE(PCI_VENDOR_ID_ADLINK, PCI_DEVICE_ID_PCI7230) },
 	{0}
 };
 
diff --git a/drivers/staging/comedi/drivers/adl_pci7296.c b/drivers/staging/comedi/drivers/adl_pci7296.c
index f28fe6b..9a232053 100644
--- a/drivers/staging/comedi/drivers/adl_pci7296.c
+++ b/drivers/staging/comedi/drivers/adl_pci7296.c
@@ -49,10 +49,8 @@
 #define PCI_DEVICE_ID_PCI7296 0x7296
 
 static DEFINE_PCI_DEVICE_TABLE(adl_pci7296_pci_table) = {
-	{
-	PCI_VENDOR_ID_ADLINK, PCI_DEVICE_ID_PCI7296, PCI_ANY_ID,
-		    PCI_ANY_ID, 0, 0, 0}, {
-	0}
+	{ PCI_DEVICE(PCI_VENDOR_ID_ADLINK, PCI_DEVICE_ID_PCI7296) },
+	{0}
 };
 
 MODULE_DEVICE_TABLE(pci, adl_pci7296_pci_table);
diff --git a/drivers/staging/comedi/drivers/adl_pci7432.c b/drivers/staging/comedi/drivers/adl_pci7432.c
index 262da7b..86ee219 100644
--- a/drivers/staging/comedi/drivers/adl_pci7432.c
+++ b/drivers/staging/comedi/drivers/adl_pci7432.c
@@ -44,10 +44,8 @@
 #define PCI_DEVICE_ID_PCI7432 0x7432
 
 static DEFINE_PCI_DEVICE_TABLE(adl_pci7432_pci_table) = {
-	{
-	PCI_VENDOR_ID_ADLINK, PCI_DEVICE_ID_PCI7432, PCI_ANY_ID,
-		    PCI_ANY_ID, 0, 0, 0}, {
-	0}
+	{ PCI_DEVICE(PCI_VENDOR_ID_ADLINK, PCI_DEVICE_ID_PCI7432) },
+	{0}
 };
 
 MODULE_DEVICE_TABLE(pci, adl_pci7432_pci_table);
diff --git a/drivers/staging/comedi/drivers/adl_pci8164.c b/drivers/staging/comedi/drivers/adl_pci8164.c
index 767a594..3b83d65 100644
--- a/drivers/staging/comedi/drivers/adl_pci8164.c
+++ b/drivers/staging/comedi/drivers/adl_pci8164.c
@@ -57,10 +57,8 @@
 #define PCI_DEVICE_ID_PCI8164 0x8164
 
 static DEFINE_PCI_DEVICE_TABLE(adl_pci8164_pci_table) = {
-	{
-	PCI_VENDOR_ID_ADLINK, PCI_DEVICE_ID_PCI8164, PCI_ANY_ID,
-		    PCI_ANY_ID, 0, 0, 0}, {
-	0}
+	{ PCI_DEVICE(PCI_VENDOR_ID_ADLINK, PCI_DEVICE_ID_PCI8164) },
+	{0}
 };
 
 MODULE_DEVICE_TABLE(pci, adl_pci8164_pci_table);
diff --git a/drivers/staging/comedi/drivers/adl_pci9111.c b/drivers/staging/comedi/drivers/adl_pci9111.c
index fc48bae..2a9bd88 100644
--- a/drivers/staging/comedi/drivers/adl_pci9111.c
+++ b/drivers/staging/comedi/drivers/adl_pci9111.c
@@ -311,10 +311,8 @@
 };
 
 static DEFINE_PCI_DEVICE_TABLE(pci9111_pci_table) = {
-	{ PCI_VENDOR_ID_ADLINK, PCI9111_HR_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID,
-	  0, 0, 0 },
-	/* { PCI_VENDOR_ID_ADLINK, PCI9111_HG_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID,
-	 *   0, 0, 0 }, */
+	{ PCI_DEVICE(PCI_VENDOR_ID_ADLINK, PCI9111_HR_DEVICE_ID) },
+	/* { PCI_DEVICE(PCI_VENDOR_ID_ADLINK, PCI9111_HG_DEVICE_ID) }, */
 	{ 0 }
 };
 
diff --git a/drivers/staging/comedi/drivers/adv_pci1710.c b/drivers/staging/comedi/drivers/adv_pci1710.c
index da2b75b..8318c82 100644
--- a/drivers/staging/comedi/drivers/adv_pci1710.c
+++ b/drivers/staging/comedi/drivers/adv_pci1710.c
@@ -1382,16 +1382,14 @@
 	int i;
 	int board_index;
 
-	printk("comedi%d: adv_pci1710: ", dev->minor);
+	dev_info(dev->hw_dev, "comedi%d: adv_pci1710:\n", dev->minor);
 
 	opt_bus = it->options[0];
 	opt_slot = it->options[1];
 
 	ret = alloc_private(dev, sizeof(struct pci1710_private));
-	if (ret < 0) {
-		printk(" - Allocation failed!\n");
+	if (ret < 0)
 		return -ENOMEM;
-	}
 
 	/* Look for matching PCI device */
 	errstr = "not found!";
@@ -1436,10 +1434,10 @@
 
 	if (!pcidev) {
 		if (opt_bus || opt_slot) {
-			printk(" - Card at b:s %d:%d %s\n",
-			       opt_bus, opt_slot, errstr);
+			dev_err(dev->hw_dev, "- Card at b:s %d:%d %s\n",
+				opt_bus, opt_slot, errstr);
 		} else {
-			printk(" - Card %s\n", errstr);
+			dev_err(dev->hw_dev, "- Card %s\n", errstr);
 		}
 		return -EIO;
 	}
@@ -1450,8 +1448,8 @@
 	irq = pcidev->irq;
 	iobase = pci_resource_start(pcidev, 2);
 
-	printk(", b:s:f=%d:%d:%d, io=0x%4lx", pci_bus, pci_slot, pci_func,
-	       iobase);
+	dev_dbg(dev->hw_dev, "b:s:f=%d:%d:%d, io=0x%4lx\n", pci_bus, pci_slot,
+		pci_func, iobase);
 
 	dev->iobase = iobase;
 
@@ -1471,10 +1469,8 @@
 		n_subdevices++;
 
 	ret = alloc_subdevices(dev, n_subdevices);
-	if (ret < 0) {
-		printk(" - Allocation failed!\n");
+	if (ret < 0)
 		return ret;
-	}
 
 	pci1710_reset(dev);
 
@@ -1483,24 +1479,20 @@
 			if (request_irq(irq, interrupt_service_pci1710,
 					IRQF_SHARED, "Advantech PCI-1710",
 					dev)) {
-				printk
-				    (", unable to allocate IRQ %d, DISABLING IT",
-				     irq);
+				dev_dbg(dev->hw_dev, "unable to allocate IRQ %d, DISABLING IT",
+					irq);
 				irq = 0;	/* Can't use IRQ */
 			} else {
-				printk(", irq=%u", irq);
+				dev_dbg(dev->hw_dev, "irq=%u", irq);
 			}
 		} else {
-			printk(", IRQ disabled");
+			dev_dbg(dev->hw_dev, "IRQ disabled");
 		}
 	} else {
 		irq = 0;
 	}
 
 	dev->irq = irq;
-
-	printk(".\n");
-
 	subdev = 0;
 
 	if (this_board->n_aichan) {
diff --git a/drivers/staging/comedi/drivers/adv_pci_dio.c b/drivers/staging/comedi/drivers/adv_pci_dio.c
index 69334f6..537e585 100644
--- a/drivers/staging/comedi/drivers/adv_pci_dio.c
+++ b/drivers/staging/comedi/drivers/adv_pci_dio.c
@@ -1106,13 +1106,10 @@
 	unsigned long iobase;
 	struct pci_dev *pcidev = NULL;
 
-	printk("comedi%d: adv_pci_dio: ", dev->minor);
 
 	ret = alloc_private(dev, sizeof(struct pci_dio_private));
-	if (ret < 0) {
-		printk(", Error: Cann't allocate private memory!\n");
+	if (ret < 0)
 		return -ENOMEM;
-	}
 
 	for_each_pci_dev(pcidev) {
 		/*  loop through cards supported by this driver */
@@ -1140,19 +1137,18 @@
 	}
 
 	if (!dev->board_ptr) {
-		printk(", Error: Requested type of the card was not found!\n");
+		dev_err(dev->hw_dev, "Error: Requested type of the card was not found!\n");
 		return -EIO;
 	}
 
 	if (comedi_pci_enable(pcidev, driver_pci_dio.driver_name)) {
-		printk
-		    (", Error: Can't enable PCI device and request regions!\n");
+		dev_err(dev->hw_dev, "Error: Can't enable PCI device and request regions!\n");
 		return -EIO;
 	}
 	iobase = pci_resource_start(pcidev, this_board->main_pci_region);
-	printk(", b:s:f=%d:%d:%d, io=0x%4lx",
-	       pcidev->bus->number, PCI_SLOT(pcidev->devfn),
-	       PCI_FUNC(pcidev->devfn), iobase);
+	dev_dbg(dev->hw_dev, "b:s:f=%d:%d:%d, io=0x%4lx\n",
+		pcidev->bus->number, PCI_SLOT(pcidev->devfn),
+		PCI_FUNC(pcidev->devfn), iobase);
 
 	dev->iobase = iobase;
 	dev->board_name = this_board->name;
@@ -1177,15 +1173,10 @@
 	}
 
 	ret = alloc_subdevices(dev, n_subdevices);
-	if (ret < 0) {
-		printk(", Error: Cann't allocate subdevice memory!\n");
+	if (ret < 0)
 		return ret;
-	}
-
-	printk(".\n");
 
 	subdev = 0;
-
 	for (i = 0; i < MAX_DI_SUBDEVS; i++)
 		if (this_board->sdi[i].chans) {
 			s = dev->subdevices + subdev;
diff --git a/drivers/staging/comedi/drivers/amplc_dio200.c b/drivers/staging/comedi/drivers/amplc_dio200.c
index 93bbe4e..566cc44 100644
--- a/drivers/staging/comedi/drivers/amplc_dio200.c
+++ b/drivers/staging/comedi/drivers/amplc_dio200.c
@@ -421,12 +421,9 @@
 
 #ifdef CONFIG_COMEDI_PCI
 static DEFINE_PCI_DEVICE_TABLE(dio200_pci_table) = {
-	{
-	PCI_VENDOR_ID_AMPLICON, PCI_DEVICE_ID_AMPLICON_PCI215,
-		    PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, {
-	PCI_VENDOR_ID_AMPLICON, PCI_DEVICE_ID_AMPLICON_PCI272,
-		    PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, {
-	0}
+	{ PCI_DEVICE(PCI_VENDOR_ID_AMPLICON, PCI_DEVICE_ID_AMPLICON_PCI215) },
+	{ PCI_DEVICE(PCI_VENDOR_ID_AMPLICON, PCI_DEVICE_ID_AMPLICON_PCI272) },
+	{0}
 };
 
 MODULE_DEVICE_TABLE(pci, dio200_pci_table);
diff --git a/drivers/staging/comedi/drivers/amplc_pc236.c b/drivers/staging/comedi/drivers/amplc_pc236.c
index 48246cd..7972cad 100644
--- a/drivers/staging/comedi/drivers/amplc_pc236.c
+++ b/drivers/staging/comedi/drivers/amplc_pc236.c
@@ -134,10 +134,8 @@
 
 #ifdef CONFIG_COMEDI_PCI
 static DEFINE_PCI_DEVICE_TABLE(pc236_pci_table) = {
-	{
-	PCI_VENDOR_ID_AMPLICON, PCI_DEVICE_ID_AMPLICON_PCI236,
-		    PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, {
-	0}
+	{ PCI_DEVICE(PCI_VENDOR_ID_AMPLICON, PCI_DEVICE_ID_AMPLICON_PCI236) },
+	{0}
 };
 
 MODULE_DEVICE_TABLE(pci, pc236_pci_table);
diff --git a/drivers/staging/comedi/drivers/amplc_pc263.c b/drivers/staging/comedi/drivers/amplc_pc263.c
index 8a33880..191ac0d 100644
--- a/drivers/staging/comedi/drivers/amplc_pc263.c
+++ b/drivers/staging/comedi/drivers/amplc_pc263.c
@@ -101,10 +101,8 @@
 
 #ifdef CONFIG_COMEDI_PCI
 static DEFINE_PCI_DEVICE_TABLE(pc263_pci_table) = {
-	{
-	PCI_VENDOR_ID_AMPLICON, PCI_DEVICE_ID_AMPLICON_PCI263,
-		    PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, {
-	0}
+	{ PCI_DEVICE(PCI_VENDOR_ID_AMPLICON, PCI_DEVICE_ID_AMPLICON_PCI263) },
+	{0}
 };
 
 MODULE_DEVICE_TABLE(pci, pc263_pci_table);
diff --git a/drivers/staging/comedi/drivers/amplc_pci224.c b/drivers/staging/comedi/drivers/amplc_pci224.c
index 1b5ba1c..b278917 100644
--- a/drivers/staging/comedi/drivers/amplc_pci224.c
+++ b/drivers/staging/comedi/drivers/amplc_pci224.c
@@ -384,12 +384,9 @@
  */
 
 static DEFINE_PCI_DEVICE_TABLE(pci224_pci_table) = {
-	{
-	PCI_VENDOR_ID_AMPLICON, PCI_DEVICE_ID_AMPLICON_PCI224,
-		    PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, {
-	PCI_VENDOR_ID_AMPLICON, PCI_DEVICE_ID_AMPLICON_PCI234,
-		    PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, {
-	0}
+	{ PCI_DEVICE(PCI_VENDOR_ID_AMPLICON, PCI_DEVICE_ID_AMPLICON_PCI224) },
+	{ PCI_DEVICE(PCI_VENDOR_ID_AMPLICON, PCI_DEVICE_ID_AMPLICON_PCI234) },
+	{0}
 };
 
 MODULE_DEVICE_TABLE(pci, pci224_pci_table);
diff --git a/drivers/staging/comedi/drivers/amplc_pci230.c b/drivers/staging/comedi/drivers/amplc_pci230.c
index 7edeb11..5389795 100644
--- a/drivers/staging/comedi/drivers/amplc_pci230.c
+++ b/drivers/staging/comedi/drivers/amplc_pci230.c
@@ -501,12 +501,9 @@
 };
 
 static DEFINE_PCI_DEVICE_TABLE(pci230_pci_table) = {
-	{
-	PCI_VENDOR_ID_AMPLICON, PCI_DEVICE_ID_PCI230, PCI_ANY_ID,
-		    PCI_ANY_ID, 0, 0, 0}, {
-	PCI_VENDOR_ID_AMPLICON, PCI_DEVICE_ID_PCI260, PCI_ANY_ID,
-		    PCI_ANY_ID, 0, 0, 0}, {
-	0}
+	{ PCI_DEVICE(PCI_VENDOR_ID_AMPLICON, PCI_DEVICE_ID_PCI230) },
+	{ PCI_DEVICE(PCI_VENDOR_ID_AMPLICON, PCI_DEVICE_ID_PCI260) },
+	{0}
 };
 
 MODULE_DEVICE_TABLE(pci, pci230_pci_table);
diff --git a/drivers/staging/comedi/drivers/cb_das16_cs.c b/drivers/staging/comedi/drivers/cb_das16_cs.c
index e171c56..49404f4 100644
--- a/drivers/staging/comedi/drivers/cb_das16_cs.c
+++ b/drivers/staging/comedi/drivers/cb_das16_cs.c
@@ -99,7 +99,7 @@
 	.detach = das16cs_detach,
 };
 
-static struct pcmcia_device *cur_dev = NULL;
+static struct pcmcia_device *cur_dev;
 
 static const struct comedi_lrange das16cs_ai_range = { 4, {
 							   RANGE(-10, 10),
@@ -150,7 +150,7 @@
 			return das16cs_boards + i;
 	}
 
-	printk("unknown board!\n");
+	dev_dbg(dev->hw_dev, "unknown board!\n");
 
 	return NULL;
 }
@@ -163,20 +163,19 @@
 	int ret;
 	int i;
 
-	printk("comedi%d: cb_das16_cs: ", dev->minor);
+	dev_dbg(dev->hw_dev, "comedi%d: cb_das16_cs: attached\n", dev->minor);
 
 	link = cur_dev;		/* XXX hack */
 	if (!link)
 		return -EIO;
 
 	dev->iobase = link->resource[0]->start;
-	printk("I/O base=0x%04lx ", dev->iobase);
+	dev_dbg(dev->hw_dev, "I/O base=0x%04lx\n", dev->iobase);
 
-	printk("fingerprint:\n");
+	dev_dbg(dev->hw_dev, "fingerprint:\n");
 	for (i = 0; i < 48; i += 2)
-		printk("%04x ", inw(dev->iobase + i));
+		dev_dbg(dev->hw_dev, "%04x\n", inw(dev->iobase + i));
 
-	printk("\n");
 
 	ret = request_irq(link->irq, das16cs_interrupt,
 			  IRQF_SHARED, "cb_das16_cs", dev);
@@ -185,7 +184,7 @@
 
 	dev->irq = link->irq;
 
-	printk("irq=%u ", dev->irq);
+	dev_dbg(dev->hw_dev, "irq=%u\n", dev->irq);
 
 	dev->board_ptr = das16cs_probe(dev, link);
 	if (!dev->board_ptr)
@@ -252,14 +251,13 @@
 		s->type = COMEDI_SUBD_UNUSED;
 	}
 
-	printk("attached\n");
 
 	return 1;
 }
 
 static int das16cs_detach(struct comedi_device *dev)
 {
-	printk("comedi%d: das16cs: remove\n", dev->minor);
+	dev_dbg(dev->hw_dev, "comedi%d: das16cs: remove\n", dev->minor);
 
 	if (dev->irq)
 		free_irq(dev->irq, dev);
@@ -312,7 +310,7 @@
 				break;
 		}
 		if (to == TIMEOUT) {
-			printk("cb_das16_cs: ai timeout\n");
+			dev_dbg(dev->hw_dev, "cb_das16_cs: ai timeout\n");
 			return -ETIME;
 		}
 		data[i] = (unsigned short)inw(dev->iobase + 0);
diff --git a/drivers/staging/comedi/drivers/cb_pcidas.c b/drivers/staging/comedi/drivers/cb_pcidas.c
index 61968a5..7e4ffcf 100644
--- a/drivers/staging/comedi/drivers/cb_pcidas.c
+++ b/drivers/staging/comedi/drivers/cb_pcidas.c
@@ -565,8 +565,6 @@
 	int index;
 	int i;
 
-	printk("comedi%d: cb_pcidas: ", dev->minor);
-
 /*
  * Allocate the private structure area.
  */
@@ -576,7 +574,6 @@
 /*
  * Probe the device to determine what device in the series it is.
  */
-	printk("\n");
 
 	for_each_pci_dev(pcidev) {
 		/*  is it not a computer boards card? */
@@ -600,20 +597,20 @@
 		}
 	}
 
-	printk("No supported ComputerBoards/MeasurementComputing card found on "
-	       "requested position\n");
+	dev_err(dev->hw_dev, "No supported ComputerBoards/MeasurementComputing card found on requested position\n");
 	return -EIO;
 
 found:
 
-	printk("Found %s on bus %i, slot %i\n", cb_pcidas_boards[index].name,
-	       pcidev->bus->number, PCI_SLOT(pcidev->devfn));
+	dev_dbg(dev->hw_dev, "Found %s on bus %i, slot %i\n",
+		cb_pcidas_boards[index].name, pcidev->bus->number,
+		PCI_SLOT(pcidev->devfn));
 
 	/*
 	 * Enable PCI device and reserve I/O ports.
 	 */
 	if (comedi_pci_enable(pcidev, "cb_pcidas")) {
-		printk(" Failed to enable PCI device and request regions\n");
+		dev_err(dev->hw_dev, "Failed to enable PCI device and request regions\n");
 		return -EIO;
 	}
 	/*
@@ -639,7 +636,8 @@
 	/*  get irq */
 	if (request_irq(devpriv->pci_dev->irq, cb_pcidas_interrupt,
 			IRQF_SHARED, "cb_pcidas", dev)) {
-		printk(" unable to allocate irq %d\n", devpriv->pci_dev->irq);
+		dev_dbg(dev->hw_dev, "unable to allocate irq %d\n",
+			devpriv->pci_dev->irq);
 		return -EINVAL;
 	}
 	dev->irq = devpriv->pci_dev->irq;
@@ -768,7 +766,6 @@
  */
 static int cb_pcidas_detach(struct comedi_device *dev)
 {
-	printk("comedi%d: cb_pcidas: remove\n", dev->minor);
 
 	if (devpriv) {
 		if (devpriv->s5933_config) {
@@ -776,8 +773,8 @@
 			outl(INTCSR_INBOX_INTR_STATUS,
 			     devpriv->s5933_config + AMCC_OP_REG_INTCSR);
 #ifdef CB_PCIDAS_DEBUG
-			printk("detaching, incsr is 0x%x\n",
-			       inl(devpriv->s5933_config + AMCC_OP_REG_INTCSR));
+			dev_dbg(dev->hw_dev, "detaching, incsr is 0x%x\n",
+				inl(devpriv->s5933_config + AMCC_OP_REG_INTCSR));
 #endif
 		}
 	}
@@ -858,7 +855,8 @@
 	unsigned int source = data[1];
 
 	if (source >= num_calibration_sources) {
-		printk("invalid calibration source: %i\n", source);
+		dev_err(dev->hw_dev, "invalid calibration source: %i\n",
+			source);
 		return -EINVAL;
 	}
 
@@ -1279,7 +1277,7 @@
 	outw(bits, devpriv->control_status + ADCMUX_CONT);
 
 #ifdef CB_PCIDAS_DEBUG
-	printk("comedi: sent 0x%x to adcmux control\n", bits);
+	dev_dbg(dev->hw_dev, "comedi: sent 0x%x to adcmux control\n", bits);
 #endif
 
 	/*  load counters */
@@ -1306,7 +1304,8 @@
 		devpriv->adc_fifo_bits |= INT_FHF;	/* interrupt fifo half full */
 	}
 #ifdef CB_PCIDAS_DEBUG
-	printk("comedi: adc_fifo_bits are 0x%x\n", devpriv->adc_fifo_bits);
+	dev_dbg(dev->hw_dev, "comedi: adc_fifo_bits are 0x%x\n",
+		devpriv->adc_fifo_bits);
 #endif
 	/*  enable (and clear) interrupts */
 	outw(devpriv->adc_fifo_bits | EOAI | INT | LADFUL,
@@ -1332,7 +1331,7 @@
 		bits |= BURSTE;
 	outw(bits, devpriv->control_status + TRIG_CONTSTAT);
 #ifdef CB_PCIDAS_DEBUG
-	printk("comedi: sent 0x%x to trig control\n", bits);
+	dev_dbg(dev->hw_dev, "comedi: sent 0x%x to trig control\n", bits);
 #endif
 
 	return 0;
@@ -1549,7 +1548,8 @@
 	spin_lock_irqsave(&dev->spinlock, flags);
 	devpriv->adc_fifo_bits |= DAEMIE | DAHFIE;
 #ifdef CB_PCIDAS_DEBUG
-	printk("comedi: adc_fifo_bits are 0x%x\n", devpriv->adc_fifo_bits);
+	dev_dbg(dev->hw_dev, "comedi: adc_fifo_bits are 0x%x\n",
+		devpriv->adc_fifo_bits);
 #endif
 	/*  enable and clear interrupts */
 	outw(devpriv->adc_fifo_bits | DAEMI | DAHFI,
@@ -1559,7 +1559,8 @@
 	devpriv->ao_control_bits |= DAC_START | DACEN | DAC_EMPTY;
 	outw(devpriv->ao_control_bits, devpriv->control_status + DAC_CSR);
 #ifdef CB_PCIDAS_DEBUG
-	printk("comedi: sent 0x%x to dac control\n", devpriv->ao_control_bits);
+	dev_dbg(dev->hw_dev, "comedi: sent 0x%x to dac control\n",
+		devpriv->ao_control_bits);
 #endif
 	spin_unlock_irqrestore(&dev->spinlock, flags);
 
@@ -1587,8 +1588,9 @@
 
 	s5933_status = inl(devpriv->s5933_config + AMCC_OP_REG_INTCSR);
 #ifdef CB_PCIDAS_DEBUG
-	printk("intcsr 0x%x\n", s5933_status);
-	printk("mbef 0x%x\n", inl(devpriv->s5933_config + AMCC_OP_REG_MBEF));
+	dev_dbg(dev->hw_dev, "intcsr 0x%x\n", s5933_status);
+	dev_dbg(dev->hw_dev, "mbef 0x%x\n",
+		inl(devpriv->s5933_config + AMCC_OP_REG_MBEF));
 #endif
 
 	if ((INTCSR_INTR_ASSERTED & s5933_status) == 0)
diff --git a/drivers/staging/comedi/drivers/cb_pcidas64.c b/drivers/staging/comedi/drivers/cb_pcidas64.c
index 1e324198..c9e8c47 100644
--- a/drivers/staging/comedi/drivers/cb_pcidas64.c
+++ b/drivers/staging/comedi/drivers/cb_pcidas64.c
@@ -1739,8 +1739,6 @@
 	uint32_t local_range, local_decode;
 	int retval;
 
-	printk("comedi%d: cb_pcidas64\n", dev->minor);
-
 /*
  * Allocate the private structure area.
  */
@@ -1781,12 +1779,11 @@
 		return -EIO;
 	}
 
-	printk("Found %s on bus %i, slot %i\n", board(dev)->name,
-	       pcidev->bus->number, PCI_SLOT(pcidev->devfn));
+	dev_dbg(dev->hw_dev, "Found %s on bus %i, slot %i\n", board(dev)->name,
+		pcidev->bus->number, PCI_SLOT(pcidev->devfn));
 
 	if (comedi_pci_enable(pcidev, driver_cb_pcidas.driver_name)) {
-		printk(KERN_WARNING
-		       " failed to enable PCI device and request regions\n");
+		dev_warn(dev->hw_dev, "failed to enable PCI device and request regions\n");
 		return -EIO;
 	}
 	pci_set_master(pcidev);
@@ -1814,7 +1811,7 @@
 
 	if (!priv(dev)->plx9080_iobase || !priv(dev)->main_iobase
 	    || !priv(dev)->dio_counter_iobase) {
-		printk(" failed to remap io memory\n");
+		dev_warn(dev->hw_dev, "failed to remap io memory\n");
 		return -ENOMEM;
 	}
 
@@ -1850,17 +1847,19 @@
 
 	priv(dev)->hw_revision =
 	    hw_revision(dev, readw(priv(dev)->main_iobase + HW_STATUS_REG));
-	printk(" stc hardware revision %i\n", priv(dev)->hw_revision);
+	dev_dbg(dev->hw_dev, "stc hardware revision %i\n",
+		priv(dev)->hw_revision);
 	init_plx9080(dev);
 	init_stc_registers(dev);
 	/*  get irq */
 	if (request_irq(pcidev->irq, handle_interrupt, IRQF_SHARED,
 			"cb_pcidas64", dev)) {
-		printk(" unable to allocate irq %u\n", pcidev->irq);
+		dev_dbg(dev->hw_dev, "unable to allocate irq %u\n",
+			pcidev->irq);
 		return -EINVAL;
 	}
 	dev->irq = pcidev->irq;
-	printk(" irq %u\n", dev->irq);
+	dev_dbg(dev->hw_dev, "irq %u\n", dev->irq);
 
 	retval = setup_subdevices(dev);
 	if (retval < 0)
@@ -1882,8 +1881,6 @@
 {
 	unsigned int i;
 
-	printk("comedi%d: cb_pcidas: remove\n", dev->minor);
-
 	if (dev->irq)
 		free_irq(dev->irq, dev);
 	if (priv(dev)) {
@@ -2093,7 +2090,8 @@
 	else
 		num_calibration_sources = 8;
 	if (source >= num_calibration_sources) {
-		printk("invalid calibration source: %i\n", source);
+		dev_dbg(dev->hw_dev, "invalid calibration source: %i\n",
+			source);
 		return -EINVAL;
 	}
 
@@ -2924,7 +2922,7 @@
 		}
 
 		if (num_samples < 0) {
-			printk(" cb_pcidas64: bug! num_samples < 0\n");
+			dev_err(dev->hw_dev, "cb_pcidas64: bug! num_samples < 0\n");
 			break;
 		}
 
diff --git a/drivers/staging/comedi/drivers/cb_pcidda.c b/drivers/staging/comedi/drivers/cb_pcidda.c
index 49102b3..abba220 100644
--- a/drivers/staging/comedi/drivers/cb_pcidda.c
+++ b/drivers/staging/comedi/drivers/cb_pcidda.c
@@ -282,7 +282,6 @@
 	struct pci_dev *pcidev = NULL;
 	int index;
 
-	printk("comedi%d: cb_pcidda: ", dev->minor);
 
 /*
  * Allocate the private structure area.
@@ -293,7 +292,6 @@
 /*
  * Probe the device to determine what device in the series it is.
  */
-	printk("\n");
 
 	for_each_pci_dev(pcidev) {
 		if (pcidev->vendor == PCI_VENDOR_ID_CB) {
@@ -312,22 +310,21 @@
 		}
 	}
 	if (!pcidev) {
-		printk
-		    ("Not a ComputerBoards/MeasurementComputing card on requested position\n");
+		dev_err(dev->hw_dev, "Not a ComputerBoards/MeasurementComputing card on requested position\n");
 		return -EIO;
 	}
 found:
 	devpriv->pci_dev = pcidev;
 	dev->board_ptr = cb_pcidda_boards + index;
 	/*  "thisboard" macro can be used from here. */
-	printk("Found %s at requested position\n", thisboard->name);
+	dev_dbg(dev->hw_dev, "Found %s at requested position\n",
+		thisboard->name);
 
 	/*
 	 * Enable PCI device and request regions.
 	 */
 	if (comedi_pci_enable(pcidev, thisboard->name)) {
-		printk
-		    ("cb_pcidda: failed to enable PCI device and request regions\n");
+		dev_err(dev->hw_dev, "cb_pcidda: failed to enable PCI device and request regions\n");
 		return -EIO;
 	}
 
@@ -377,12 +374,11 @@
 	s = dev->subdevices + 2;
 	subdev_8255_init(dev, s, NULL, devpriv->digitalio + PORT2A);
 
-	printk(" eeprom:");
+	dev_dbg(dev->hw_dev, "eeprom:\n");
 	for (index = 0; index < EEPROM_SIZE; index++) {
 		devpriv->eeprom_data[index] = cb_pcidda_read_eeprom(dev, index);
-		printk(" %i:0x%x ", index, devpriv->eeprom_data[index]);
+		dev_dbg(dev->hw_dev, "%i:0x%x\n", index, devpriv->eeprom_data[index]);
 	}
-	printk("\n");
 
 	/*  set calibrations dacs */
 	for (index = 0; index < thisboard->ao_chans; index++)
@@ -417,8 +413,6 @@
 		subdev_8255_cleanup(dev, dev->subdevices + 2);
 	}
 
-	printk("comedi%d: cb_pcidda: remove\n", dev->minor);
-
 	return 0;
 }
 
diff --git a/drivers/staging/comedi/drivers/cb_pcidio.c b/drivers/staging/comedi/drivers/cb_pcidio.c
index 79477a5..8f32152 100644
--- a/drivers/staging/comedi/drivers/cb_pcidio.c
+++ b/drivers/staging/comedi/drivers/cb_pcidio.c
@@ -184,8 +184,6 @@
 	int index;
 	int i;
 
-	printk("comedi%d: cb_pcidio: \n", dev->minor);
-
 /*
  * Allocate the private structure area.  alloc_private() is a
  * convenient macro defined in comedidev.h.
@@ -223,8 +221,7 @@
 		}
 	}
 
-	printk("No supported ComputerBoards/MeasurementComputing card found on "
-	       "requested position\n");
+	dev_err(dev->hw_dev, "No supported ComputerBoards/MeasurementComputing card found on requested position\n");
 	return -EIO;
 
 found:
@@ -236,14 +233,12 @@
 	dev->board_name = thisboard->name;
 
 	devpriv->pci_dev = pcidev;
-	printk("Found %s on bus %i, slot %i\n", thisboard->name,
-	       devpriv->pci_dev->bus->number,
-	       PCI_SLOT(devpriv->pci_dev->devfn));
-	if (comedi_pci_enable(pcidev, thisboard->name)) {
-		printk
-		    ("cb_pcidio: failed to enable PCI device and request regions\n");
+	dev_dbg(dev->hw_dev, "Found %s on bus %i, slot %i\n", thisboard->name,
+		devpriv->pci_dev->bus->number,
+		PCI_SLOT(devpriv->pci_dev->devfn));
+	if (comedi_pci_enable(pcidev, thisboard->name))
 		return -EIO;
-	}
+
 	devpriv->dio_reg_base
 	    =
 	    pci_resource_start(devpriv->pci_dev,
@@ -259,11 +254,10 @@
 	for (i = 0; i < thisboard->n_8255; i++) {
 		subdev_8255_init(dev, dev->subdevices + i,
 				 NULL, devpriv->dio_reg_base + i * 4);
-		printk(" subdev %d: base = 0x%lx\n", i,
-		       devpriv->dio_reg_base + i * 4);
+		dev_dbg(dev->hw_dev, "subdev %d: base = 0x%lx\n", i,
+			devpriv->dio_reg_base + i * 4);
 	}
 
-	printk("attached\n");
 	return 1;
 }
 
@@ -277,7 +271,6 @@
  */
 static int pcidio_detach(struct comedi_device *dev)
 {
-	printk("comedi%d: cb_pcidio: remove\n", dev->minor);
 	if (devpriv) {
 		if (devpriv->pci_dev) {
 			if (devpriv->dio_reg_base)
diff --git a/drivers/staging/comedi/drivers/cb_pcimdas.c b/drivers/staging/comedi/drivers/cb_pcimdas.c
index b1b832b..8ba6942 100644
--- a/drivers/staging/comedi/drivers/cb_pcimdas.c
+++ b/drivers/staging/comedi/drivers/cb_pcimdas.c
@@ -212,8 +212,6 @@
 	int index;
 	/* int i; */
 
-	printk("comedi%d: cb_pcimdas: ", dev->minor);
-
 /*
  * Allocate the private structure area.
  */
@@ -223,7 +221,6 @@
 /*
  * Probe the device to determine what device in the series it is.
  */
-	printk("\n");
 
 	for_each_pci_dev(pcidev) {
 		/*  is it not a computer boards card? */
@@ -248,26 +245,26 @@
 		}
 	}
 
-	printk("No supported ComputerBoards/MeasurementComputing card found on "
-	       "requested position\n");
+	dev_err(dev->hw_dev, "No supported ComputerBoards/MeasurementComputing card found on requested position\n");
 	return -EIO;
 
 found:
 
-	printk("Found %s on bus %i, slot %i\n", cb_pcimdas_boards[index].name,
-	       pcidev->bus->number, PCI_SLOT(pcidev->devfn));
+	dev_dbg(dev->hw_dev, "Found %s on bus %i, slot %i\n",
+		cb_pcimdas_boards[index].name, pcidev->bus->number,
+		PCI_SLOT(pcidev->devfn));
 
 	/*  Warn about non-tested features */
 	switch (thisboard->device_id) {
 	case 0x56:
 		break;
 	default:
-		printk("THIS CARD IS UNSUPPORTED.\n"
-		       "PLEASE REPORT USAGE TO <mocelet@sucs.org>\n");
+		dev_dbg(dev->hw_dev, "THIS CARD IS UNSUPPORTED.\n"
+			"PLEASE REPORT USAGE TO <mocelet@sucs.org>\n");
 	}
 
 	if (comedi_pci_enable(pcidev, "cb_pcimdas")) {
-		printk(" Failed to enable PCI device and request regions\n");
+		dev_err(dev->hw_dev, "Failed to enable PCI device and request regions\n");
 		return -EIO;
 	}
 
@@ -277,13 +274,11 @@
 	devpriv->BADR3 = pci_resource_start(devpriv->pci_dev, 3);
 	devpriv->BADR4 = pci_resource_start(devpriv->pci_dev, 4);
 
-#ifdef CBPCIMDAS_DEBUG
-	printk("devpriv->BADR0 = 0x%lx\n", devpriv->BADR0);
-	printk("devpriv->BADR1 = 0x%lx\n", devpriv->BADR1);
-	printk("devpriv->BADR2 = 0x%lx\n", devpriv->BADR2);
-	printk("devpriv->BADR3 = 0x%lx\n", devpriv->BADR3);
-	printk("devpriv->BADR4 = 0x%lx\n", devpriv->BADR4);
-#endif
+	dev_dbg(dev->hw_dev, "devpriv->BADR0 = 0x%lx\n", devpriv->BADR0);
+	dev_dbg(dev->hw_dev, "devpriv->BADR1 = 0x%lx\n", devpriv->BADR1);
+	dev_dbg(dev->hw_dev, "devpriv->BADR2 = 0x%lx\n", devpriv->BADR2);
+	dev_dbg(dev->hw_dev, "devpriv->BADR3 = 0x%lx\n", devpriv->BADR3);
+	dev_dbg(dev->hw_dev, "devpriv->BADR4 = 0x%lx\n", devpriv->BADR4);
 
 /* Dont support IRQ yet */
 /*  get irq */
@@ -333,8 +328,6 @@
 	else
 		s->type = COMEDI_SUBD_UNUSED;
 
-	printk("attached\n");
-
 	return 1;
 }
 
@@ -348,16 +341,19 @@
  */
 static int cb_pcimdas_detach(struct comedi_device *dev)
 {
-#ifdef CBPCIMDAS_DEBUG
 	if (devpriv) {
-		printk("devpriv->BADR0 = 0x%lx\n", devpriv->BADR0);
-		printk("devpriv->BADR1 = 0x%lx\n", devpriv->BADR1);
-		printk("devpriv->BADR2 = 0x%lx\n", devpriv->BADR2);
-		printk("devpriv->BADR3 = 0x%lx\n", devpriv->BADR3);
-		printk("devpriv->BADR4 = 0x%lx\n", devpriv->BADR4);
+		dev_dbg(dev->hw_dev, "devpriv->BADR0 = 0x%lx\n",
+			devpriv->BADR0);
+		dev_dbg(dev->hw_dev, "devpriv->BADR1 = 0x%lx\n",
+			devpriv->BADR1);
+		dev_dbg(dev->hw_dev, "devpriv->BADR2 = 0x%lx\n",
+			devpriv->BADR2);
+		dev_dbg(dev->hw_dev, "devpriv->BADR3 = 0x%lx\n",
+			devpriv->BADR3);
+		dev_dbg(dev->hw_dev, "devpriv->BADR4 = 0x%lx\n",
+			devpriv->BADR4);
 	}
-#endif
-	printk("comedi%d: cb_pcimdas: remove\n", dev->minor);
+
 	if (dev->irq)
 		free_irq(dev->irq, dev);
 	if (devpriv) {
diff --git a/drivers/staging/comedi/drivers/cb_pcimdda.c b/drivers/staging/comedi/drivers/cb_pcimdda.c
index 8c981a8..40bddfa 100644
--- a/drivers/staging/comedi/drivers/cb_pcimdda.c
+++ b/drivers/staging/comedi/drivers/cb_pcimdda.c
@@ -105,7 +105,8 @@
 	int ao_bits;
 	int dio_chans;
 	int dio_method;
-	int dio_offset;		/* how many bytes into the BADR are the DIO ports */
+	/* how many bytes into the BADR are the DIO ports */
+	int dio_offset;
 	int regs_badrindex;	/* IO Region for the control, analog output,
 				   and DIO registers */
 	int reg_sz;		/* number of bytes of registers in io region */
@@ -144,17 +145,18 @@
 /* Please add your PCI vendor ID to comedidev.h, and it will be forwarded
  * upstream. */
 static DEFINE_PCI_DEVICE_TABLE(pci_table) = {
-	{
-	PCI_VENDOR_ID_COMPUTERBOARDS, PCI_ID_PCIM_DDA06_16, PCI_ANY_ID,
-		    PCI_ANY_ID, 0, 0, 0}, {
-	0}
+	{ PCI_DEVICE(PCI_VENDOR_ID_COMPUTERBOARDS, PCI_ID_PCIM_DDA06_16) },
+	{0}
 };
 
 MODULE_DEVICE_TABLE(pci, pci_table);
 
-/* this structure is for data unique to this hardware driver.  If
-   several hardware drivers keep similar information in this structure,
-   feel free to suggest moving the variable to the struct comedi_device struct.  */
+/*
+ * this structure is for data unique to this hardware driver.  If
+ * several hardware drivers keep similar information in this structure,
+ * feel free to suggest moving the variable to the struct comedi_device
+ * struct.
+ */
 struct board_private_struct {
 	unsigned long registers;	/* set by probe */
 	unsigned long dio_registers;
@@ -335,7 +337,10 @@
 	if (thisboard->dio_chans) {
 		switch (thisboard->dio_method) {
 		case DIO_8255:
-			/* this is a straight 8255, so register us with the 8255 driver */
+			/*
+			 * this is a straight 8255, so register us with
+			 * the 8255 driver
+			 */
 			subdev_8255_init(dev, s, NULL, devpriv->dio_registers);
 			devpriv->attached_to_8255 = 1;
 			break;
@@ -436,8 +441,11 @@
 
 	for (i = 0; i < insn->n; i++) {
 		inw(devpriv->registers + chan * 2);
-		/* should I set data[i] to the result of the actual read on the register
-		   or the cached unsigned int in devpriv->ao_readback[]? */
+		/*
+		 * should I set data[i] to the result of the actual read
+		 * on the register or the cached unsigned int in
+		 * devpriv->ao_readback[]?
+		 */
 		data[i] = devpriv->ao_readback[chan];
 	}
 
diff --git a/drivers/staging/comedi/drivers/contec_pci_dio.c b/drivers/staging/comedi/drivers/contec_pci_dio.c
index 871f109..e3659bd 100644
--- a/drivers/staging/comedi/drivers/contec_pci_dio.c
+++ b/drivers/staging/comedi/drivers/contec_pci_dio.c
@@ -57,10 +57,9 @@
 
 #define PCI_DEVICE_ID_PIO1616L 0x8172
 static DEFINE_PCI_DEVICE_TABLE(contec_pci_table) = {
-	{
-	PCI_VENDOR_ID_CONTEC, PCI_DEVICE_ID_PIO1616L, PCI_ANY_ID,
-		    PCI_ANY_ID, 0, 0, PIO1616L}, {
-	0}
+	{ PCI_DEVICE(PCI_VENDOR_ID_CONTEC, PCI_DEVICE_ID_PIO1616L),
+		.driver_data = PIO1616L },
+	{0}
 };
 
 MODULE_DEVICE_TABLE(pci, contec_pci_table);
@@ -197,8 +196,8 @@
 			       struct comedi_insn *insn, unsigned int *data)
 {
 
-	printk("contec_do_insn_bits called\n");
-	printk(" data: %d %d\n", data[0], data[1]);
+	dev_dbg(dev->hw_dev, "contec_do_insn_bits called\n");
+	dev_dbg(dev->hw_dev, "data: %d %d\n", data[0], data[1]);
 
 	if (insn->n != 2)
 		return -EINVAL;
@@ -206,8 +205,8 @@
 	if (data[0]) {
 		s->state &= ~data[0];
 		s->state |= data[0] & data[1];
-		printk("  out: %d on %lx\n", s->state,
-		       dev->iobase + thisboard->out_offs);
+		dev_dbg(dev->hw_dev, "out: %d on %lx\n", s->state,
+			dev->iobase + thisboard->out_offs);
 		outw(s->state, dev->iobase + thisboard->out_offs);
 	}
 	return 2;
@@ -218,8 +217,8 @@
 			       struct comedi_insn *insn, unsigned int *data)
 {
 
-	printk("contec_di_insn_bits called\n");
-	printk(" data: %d %d\n", data[0], data[1]);
+	dev_dbg(dev->hw_dev, "contec_di_insn_bits called\n");
+	dev_dbg(dev->hw_dev, "data: %d %d\n", data[0], data[1]);
 
 	if (insn->n != 2)
 		return -EINVAL;
diff --git a/drivers/staging/comedi/drivers/daqboard2000.c b/drivers/staging/comedi/drivers/daqboard2000.c
index 82be77d..e61c6a8 100644
--- a/drivers/staging/comedi/drivers/daqboard2000.c
+++ b/drivers/staging/comedi/drivers/daqboard2000.c
@@ -325,9 +325,8 @@
 #define this_board ((const struct daq200_boardtype *)dev->board_ptr)
 
 static DEFINE_PCI_DEVICE_TABLE(daqboard2000_pci_table) = {
-	{
-	0x1616, 0x0409, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, {
-	0}
+	{ PCI_DEVICE(0x1616, 0x0409) },
+	{0}
 };
 
 MODULE_DEVICE_TABLE(pci, daqboard2000_pci_table);
@@ -430,16 +429,14 @@
 		/* Enable reading from the scanlist FIFO */
 		fpga->acqControl = DAQBOARD2000_SeqStartScanList;
 		for (timeout = 0; timeout < 20; timeout++) {
-			if (fpga->acqControl & DAQBOARD2000_AcqConfigPipeFull) {
+			if (fpga->acqControl & DAQBOARD2000_AcqConfigPipeFull)
 				break;
-			}
 			/* udelay(2); */
 		}
 		fpga->acqControl = DAQBOARD2000_AdcPacerEnable;
 		for (timeout = 0; timeout < 20; timeout++) {
-			if (fpga->acqControl & DAQBOARD2000_AcqLogicScanning) {
+			if (fpga->acqControl & DAQBOARD2000_AcqLogicScanning)
 				break;
-			}
 			/* udelay(2); */
 		}
 		for (timeout = 0; timeout < 20; timeout++) {
@@ -465,9 +462,8 @@
 	int i;
 	int chan = CR_CHAN(insn->chanspec);
 
-	for (i = 0; i < insn->n; i++) {
+	for (i = 0; i < insn->n; i++)
 		data[i] = devpriv->ao_readback[chan];
-	}
 
 	return i;
 }
@@ -490,9 +486,8 @@
 		/* fpga->dacControl = (chan + 2) * 0x0010 | 0x0001; udelay(1000); */
 		fpga->dacSetting[chan] = data[i];
 		for (timeout = 0; timeout < 20; timeout++) {
-			if ((fpga->dacControl & ((chan + 1) * 0x0010)) == 0) {
+			if ((fpga->dacControl & ((chan + 1) * 0x0010)) == 0)
 				break;
-			}
 			/* udelay(2); */
 		}
 		devpriv->ao_readback[chan] = data[i];
@@ -507,7 +502,7 @@
 
 static void daqboard2000_resetLocalBus(struct comedi_device *dev)
 {
-	printk("daqboard2000_resetLocalBus\n");
+	dev_dbg(dev->hw_dev, "daqboard2000_resetLocalBus\n");
 	writel(DAQBOARD2000_SECRLocalBusHi, devpriv->plx + 0x6c);
 	udelay(10000);
 	writel(DAQBOARD2000_SECRLocalBusLo, devpriv->plx + 0x6c);
@@ -516,7 +511,7 @@
 
 static void daqboard2000_reloadPLX(struct comedi_device *dev)
 {
-	printk("daqboard2000_reloadPLX\n");
+	dev_dbg(dev->hw_dev, "daqboard2000_reloadPLX\n");
 	writel(DAQBOARD2000_SECRReloadLo, devpriv->plx + 0x6c);
 	udelay(10000);
 	writel(DAQBOARD2000_SECRReloadHi, devpriv->plx + 0x6c);
@@ -527,7 +522,7 @@
 
 static void daqboard2000_pulseProgPin(struct comedi_device *dev)
 {
-	printk("daqboard2000_pulseProgPin 1\n");
+	dev_dbg(dev->hw_dev, "daqboard2000_pulseProgPin 1\n");
 	writel(DAQBOARD2000_SECRProgPinHi, devpriv->plx + 0x6c);
 	udelay(10000);
 	writel(DAQBOARD2000_SECRProgPinLo, devpriv->plx + 0x6c);
@@ -579,14 +574,14 @@
 	secr = readl(devpriv->plx + 0x6c);
 	if (!(secr & DAQBOARD2000_EEPROM_PRESENT)) {
 #ifdef DEBUG_EEPROM
-		printk("no serial eeprom\n");
+		dev_dbg(dev->hw_dev, "no serial eeprom\n");
 #endif
 		return -EIO;
 	}
 
 	for (retry = 0; retry < 3; retry++) {
 #ifdef DEBUG_EEPROM
-		printk("Programming EEPROM try %x\n", retry);
+		dev_dbg(dev->hw_dev, "Programming EEPROM try %x\n", retry);
 #endif
 
 		daqboard2000_resetLocalBus(dev);
@@ -597,7 +592,8 @@
 				if (cpld_array[i] == 0xff
 				    && cpld_array[i + 1] == 0x20) {
 #ifdef DEBUG_EEPROM
-					printk("Preamble found at %d\n", i);
+					dev_dbg(dev->hw_dev, "Preamble found at %d\n",
+						i);
 #endif
 					break;
 				}
@@ -605,13 +601,12 @@
 			for (; i < len; i += 2) {
 				int data =
 				    (cpld_array[i] << 8) + cpld_array[i + 1];
-				if (!daqboard2000_writeCPLD(dev, data)) {
+				if (!daqboard2000_writeCPLD(dev, data))
 					break;
-				}
 			}
 			if (i >= len) {
 #ifdef DEBUG_EEPROM
-				printk("Programmed\n");
+				dev_dbg(dev->hw_dev, "Programmed\n");
 #endif
 				daqboard2000_resetLocalBus(dev);
 				daqboard2000_reloadPLX(dev);
@@ -658,9 +653,8 @@
 	/*  Set the + reference dac value in the FPGA */
 	fpga->refDacs = 0x80 | DAQBOARD2000_PosRefDacSelect;
 	for (timeout = 0; timeout < 20; timeout++) {
-		if ((fpga->dacControl & DAQBOARD2000_RefBusy) == 0) {
+		if ((fpga->dacControl & DAQBOARD2000_RefBusy) == 0)
 			break;
-		}
 		udelay(2);
 	}
 /*  printk("DAQBOARD2000_PosRefDacSelect %d\n", timeout);*/
@@ -668,9 +662,8 @@
 	/*  Set the - reference dac value in the FPGA */
 	fpga->refDacs = 0x80 | DAQBOARD2000_NegRefDacSelect;
 	for (timeout = 0; timeout < 20; timeout++) {
-		if ((fpga->dacControl & DAQBOARD2000_RefBusy) == 0) {
+		if ((fpga->dacControl & DAQBOARD2000_RefBusy) == 0)
 			break;
-		}
 		udelay(2);
 	}
 /*  printk("DAQBOARD2000_NegRefDacSelect %d\n", timeout);*/
@@ -737,15 +730,13 @@
 	unsigned int aux_len;
 	int bus, slot;
 
-	printk("comedi%d: daqboard2000:", dev->minor);
-
 	bus = it->options[0];
 	slot = it->options[1];
 
 	result = alloc_private(dev, sizeof(struct daqboard2000_private));
-	if (result < 0) {
+	if (result < 0)
 		return -ENOMEM;
-	}
+
 	for (card = pci_get_device(0x1616, 0x0409, NULL);
 	     card != NULL; card = pci_get_device(0x1616, 0x0409, card)) {
 		if (bus || slot) {
@@ -759,10 +750,10 @@
 	}
 	if (!card) {
 		if (bus || slot)
-			printk(" no daqboard2000 found at bus/slot: %d/%d\n",
-			       bus, slot);
+			dev_err(dev->hw_dev, "no daqboard2000 found at bus/slot: %d/%d\n",
+				bus, slot);
 		else
-			printk(" no daqboard2000 found\n");
+			dev_err(dev->hw_dev, "no daqboard2000 found\n");
 		return -EIO;
 	} else {
 		u32 id;
@@ -772,7 +763,8 @@
 		      subsystem_device << 16) | card->subsystem_vendor;
 		for (i = 0; i < n_boardtypes; i++) {
 			if (boardtypes[i].id == id) {
-				printk(" %s", boardtypes[i].name);
+				dev_dbg(dev->hw_dev, "%s\n",
+					boardtypes[i].name);
 				dev->board_ptr = boardtypes + i;
 			}
 		}
@@ -786,7 +778,7 @@
 
 	result = comedi_pci_enable(card, "daqboard2000");
 	if (result < 0) {
-		printk(" failed to enable PCI device and request regions\n");
+		dev_err(dev->hw_dev, "failed to enable PCI device and request regions\n");
 		return -EIO;
 	}
 	devpriv->got_regions = 1;
@@ -794,9 +786,8 @@
 	    ioremap(pci_resource_start(card, 0), DAQBOARD2000_PLX_SIZE);
 	devpriv->daq =
 	    ioremap(pci_resource_start(card, 2), DAQBOARD2000_DAQ_SIZE);
-	if (!devpriv->plx || !devpriv->daq) {
+	if (!devpriv->plx || !devpriv->daq)
 		return -ENOMEM;
-	}
 
 	result = alloc_subdevices(dev, 3);
 	if (result < 0)
@@ -817,7 +808,7 @@
 	if (aux_data && aux_len) {
 		result = initialize_daqboard2000(dev, aux_data, aux_len);
 	} else {
-		printk("no FPGA initialization code, aborting\n");
+		dev_dbg(dev->hw_dev, "no FPGA initialization code, aborting\n");
 		result = -EIO;
 	}
 	if (result < 0)
@@ -857,30 +848,26 @@
 	result = subdev_8255_init(dev, s, daqboard2000_8255_cb,
 				  (unsigned long)(dev->iobase + 0x40));
 
-	printk("\n");
 out:
 	return result;
 }
 
 static int daqboard2000_detach(struct comedi_device *dev)
 {
-	printk("comedi%d: daqboard2000: remove\n", dev->minor);
-
 	if (dev->subdevices)
 		subdev_8255_cleanup(dev, dev->subdevices + 2);
 
-	if (dev->irq) {
+	if (dev->irq)
 		free_irq(dev->irq, dev);
-	}
+
 	if (devpriv) {
 		if (devpriv->daq)
 			iounmap(devpriv->daq);
 		if (devpriv->plx)
 			iounmap(devpriv->plx);
 		if (devpriv->pci_dev) {
-			if (devpriv->got_regions) {
+			if (devpriv->got_regions)
 				comedi_pci_disable(devpriv->pci_dev);
-			}
 			pci_dev_put(devpriv->pci_dev);
 		}
 	}
diff --git a/drivers/staging/comedi/drivers/das08.c b/drivers/staging/comedi/drivers/das08.c
index 3141dc8..c2dd0ed 100644
--- a/drivers/staging/comedi/drivers/das08.c
+++ b/drivers/staging/comedi/drivers/das08.c
@@ -506,10 +506,8 @@
 
 #ifdef CONFIG_COMEDI_PCI
 static DEFINE_PCI_DEVICE_TABLE(das08_pci_table) = {
-	{
-	PCI_VENDOR_ID_COMPUTERBOARDS, PCI_DEVICE_ID_PCIDAS08,
-		    PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, {
-	0}
+	{ PCI_DEVICE(PCI_VENDOR_ID_COMPUTERBOARDS, PCI_DEVICE_ID_PCIDAS08) },
+	{0}
 };
 
 MODULE_DEVICE_TABLE(pci, das08_pci_table);
diff --git a/drivers/staging/comedi/drivers/das08_cs.c b/drivers/staging/comedi/drivers/das08_cs.c
index 6d91d30..4ad398a 100644
--- a/drivers/staging/comedi/drivers/das08_cs.c
+++ b/drivers/staging/comedi/drivers/das08_cs.c
@@ -79,22 +79,20 @@
 	if (ret < 0)
 		return ret;
 
-	printk("comedi%d: das08_cs: ", dev->minor);
+	dev_info(dev->hw_dev, "comedi%d: das08_cs:\n", dev->minor);
 	/*  deal with a pci board */
 
 	if (thisboard->bustype == pcmcia) {
 		if (link == NULL) {
-			printk(" no pcmcia cards found\n");
+			dev_err(dev->hw_dev, "no pcmcia cards found\n");
 			return -EIO;
 		}
 		iobase = link->resource[0]->start;
 	} else {
-		printk(" bug! board does not have PCMCIA bustype\n");
+		dev_err(dev->hw_dev, "bug! board does not have PCMCIA bustype\n");
 		return -EINVAL;
 	}
 
-	printk("\n");
-
 	return das08_common_attach(dev, iobase);
 }
 
diff --git a/drivers/staging/comedi/drivers/das16m1.c b/drivers/staging/comedi/drivers/das16m1.c
index a5ce3b2..5376e71 100644
--- a/drivers/staging/comedi/drivers/das16m1.c
+++ b/drivers/staging/comedi/drivers/das16m1.c
@@ -384,20 +384,20 @@
 	byte = 0;
 	/* if we are using external start trigger (also board dislikes having
 	 * both start and conversion triggers external simultaneously) */
-	if (cmd->start_src == TRIG_EXT && cmd->convert_src != TRIG_EXT) {
+	if (cmd->start_src == TRIG_EXT && cmd->convert_src != TRIG_EXT)
 		byte |= EXT_TRIG_BIT;
-	}
+
 	outb(byte, dev->iobase + DAS16M1_CS);
 	/* clear interrupt bit */
 	outb(0, dev->iobase + DAS16M1_CLEAR_INTR);
 
 	/* enable interrupts and internal pacer */
 	devpriv->control_state &= ~PACER_MASK;
-	if (cmd->convert_src == TRIG_TIMER) {
+	if (cmd->convert_src == TRIG_TIMER)
 		devpriv->control_state |= INT_PACER;
-	} else {
+	else
 		devpriv->control_state |= EXT_PACER;
-	}
+
 	devpriv->control_state |= INTE;
 	outb(devpriv->control_state, dev->iobase + DAS16M1_INTR_CONTROL);
 
@@ -531,9 +531,8 @@
 {
 	unsigned int i;
 
-	for (i = 0; i < num_elements; i++) {
+	for (i = 0; i < num_elements; i++)
 		array[i] = munge_sample(array[i]);
-	}
 }
 
 static void das16m1_handler(struct comedi_device *dev, unsigned int status)
@@ -668,25 +667,20 @@
 
 	iobase = it->options[0];
 
-	printk("comedi%d: das16m1:", dev->minor);
-
 	ret = alloc_private(dev, sizeof(struct das16m1_private_struct));
 	if (ret < 0)
 		return ret;
 
 	dev->board_name = thisboard->name;
 
-	printk(" io 0x%lx-0x%lx 0x%lx-0x%lx",
-	       iobase, iobase + DAS16M1_SIZE,
-	       iobase + DAS16M1_82C55, iobase + DAS16M1_82C55 + DAS16M1_SIZE2);
 	if (!request_region(iobase, DAS16M1_SIZE, driver_das16m1.driver_name)) {
-		printk(" I/O port conflict\n");
+		comedi_error(dev, "I/O port conflict\n");
 		return -EIO;
 	}
 	if (!request_region(iobase + DAS16M1_82C55, DAS16M1_SIZE2,
 			    driver_das16m1.driver_name)) {
 		release_region(iobase, DAS16M1_SIZE);
-		printk(" I/O port conflict\n");
+		comedi_error(dev, "I/O port conflict\n");
 		return -EIO;
 	}
 	dev->iobase = iobase;
@@ -697,17 +691,17 @@
 	if (das16m1_irq_bits(irq) >= 0) {
 		ret = request_irq(irq, das16m1_interrupt, 0,
 				  driver_das16m1.driver_name, dev);
-		if (ret < 0) {
-			printk(", irq unavailable\n");
+		if (ret < 0)
 			return ret;
-		}
 		dev->irq = irq;
-		printk(", irq %u\n", irq);
+		printk
+		    ("irq %u\n", irq);
 	} else if (irq == 0) {
-		printk(", no irq\n");
+		printk
+		    (", no irq\n");
 	} else {
-		printk(", invalid irq\n"
-		       " valid irqs are 2, 3, 5, 7, 10, 11, 12, or 15\n");
+		comedi_error(dev, "invalid irq\n"
+			     " valid irqs are 2, 3, 5, 7, 10, 11, 12, or 15\n");
 		return -EINVAL;
 	}
 
@@ -771,7 +765,6 @@
 
 static int das16m1_detach(struct comedi_device *dev)
 {
-	printk("comedi%d: das16m1: remove\n", dev->minor);
 
 /* das16m1_reset(dev); */
 
diff --git a/drivers/staging/comedi/drivers/das1800.c b/drivers/staging/comedi/drivers/das1800.c
index a6df30b..99ada5a 100644
--- a/drivers/staging/comedi/drivers/das1800.c
+++ b/drivers/staging/comedi/drivers/das1800.c
@@ -573,22 +573,23 @@
 			devpriv->dma_bits |= DMA_CH7_CH5;
 			break;
 		default:
-			printk(" only supports dma channels 5 through 7\n"
-			       " Dual dma only allows the following combinations:\n"
-			       " dma 5,6 / 6,7 / or 7,5\n");
+			dev_err(dev->hw_dev, " only supports dma channels 5 through 7\n"
+				" Dual dma only allows the following combinations:\n"
+				" dma 5,6 / 6,7 / or 7,5\n");
 			return -EINVAL;
 			break;
 		}
 		if (request_dma(dma0, driver_das1800.driver_name)) {
-			printk(" failed to allocate dma channel %i\n", dma0);
+			dev_err(dev->hw_dev, "failed to allocate dma channel %i\n",
+				dma0);
 			return -EINVAL;
 		}
 		devpriv->dma0 = dma0;
 		devpriv->dma_current = dma0;
 		if (dma1) {
 			if (request_dma(dma1, driver_das1800.driver_name)) {
-				printk(" failed to allocate dma channel %i\n",
-				       dma1);
+				dev_err(dev->hw_dev, "failed to allocate dma channel %i\n",
+					dma1);
 				return -EINVAL;
 			}
 			devpriv->dma1 = dma1;
@@ -631,20 +632,20 @@
 	if (alloc_private(dev, sizeof(struct das1800_private)) < 0)
 		return -ENOMEM;
 
-	printk("comedi%d: %s: io 0x%lx", dev->minor, driver_das1800.driver_name,
-	       iobase);
+	printk(KERN_DEBUG "comedi%d: %s: io 0x%lx", dev->minor,
+	       driver_das1800.driver_name, iobase);
 	if (irq) {
-		printk(", irq %u", irq);
+		printk(KERN_CONT ", irq %u", irq);
 		if (dma0) {
-			printk(", dma %u", dma0);
+			printk(KERN_CONT ", dma %u", dma0);
 			if (dma1)
-				printk(" and %u", dma1);
+				printk(KERN_CONT " and %u", dma1);
 		}
 	}
-	printk("\n");
+	printk(KERN_CONT "\n");
 
 	if (iobase == 0) {
-		printk(" io base address required\n");
+		dev_err(dev->hw_dev, "io base address required\n");
 		return -EINVAL;
 	}
 
@@ -659,7 +660,7 @@
 
 	board = das1800_probe(dev);
 	if (board < 0) {
-		printk(" unable to determine board type\n");
+		dev_err(dev->hw_dev, "unable to determine board type\n");
 		return -ENODEV;
 	}
 
@@ -683,7 +684,8 @@
 	if (irq) {
 		if (request_irq(irq, das1800_interrupt, 0,
 				driver_das1800.driver_name, dev)) {
-			printk(" unable to allocate irq %u\n", irq);
+			dev_dbg(dev->hw_dev, "unable to allocate irq %u\n",
+				irq);
 			return -EINVAL;
 		}
 	}
@@ -712,7 +714,7 @@
 		devpriv->irq_dma_bits |= 0x38;
 		break;
 	default:
-		printk(" irq out of range\n");
+		dev_err(dev->hw_dev, "irq out of range\n");
 		return -EINVAL;
 		break;
 	}
@@ -813,8 +815,8 @@
 		kfree(devpriv->ai_buf1);
 	}
 
-	printk("comedi%d: %s: remove\n", dev->minor,
-	       driver_das1800.driver_name);
+	dev_dbg(dev->hw_dev, "comedi%d: %s: remove\n", dev->minor,
+		driver_das1800.driver_name);
 
 	return 0;
 };
@@ -833,8 +835,8 @@
 	case 0x3:
 		if (board == das1801st_da || board == das1802st_da ||
 		    board == das1701st_da || board == das1702st_da) {
-			printk(" Board model: %s\n",
-			       das1800_boards[board].name);
+			dev_dbg(dev->hw_dev, "Board model: %s\n",
+				das1800_boards[board].name);
 			return board;
 		}
 		printk
@@ -843,8 +845,8 @@
 		break;
 	case 0x4:
 		if (board == das1802hr_da || board == das1702hr_da) {
-			printk(" Board model: %s\n",
-			       das1800_boards[board].name);
+			dev_dbg(dev->hw_dev, "Board model: %s\n",
+				das1800_boards[board].name);
 			return board;
 		}
 		printk
@@ -854,8 +856,8 @@
 	case 0x5:
 		if (board == das1801ao || board == das1802ao ||
 		    board == das1701ao || board == das1702ao) {
-			printk(" Board model: %s\n",
-			       das1800_boards[board].name);
+			dev_dbg(dev->hw_dev, "Board model: %s\n",
+				das1800_boards[board].name);
 			return board;
 		}
 		printk
@@ -864,18 +866,19 @@
 		break;
 	case 0x6:
 		if (board == das1802hr || board == das1702hr) {
-			printk(" Board model: %s\n",
-			       das1800_boards[board].name);
+			dev_dbg(dev->hw_dev, "Board model: %s\n",
+				das1800_boards[board].name);
 			return board;
 		}
-		printk(" Board model (probed, not recommended): das-1802hr\n");
+		printk
+		    (" Board model (probed, not recommended): das-1802hr\n");
 		return das1802hr;
 		break;
 	case 0x7:
 		if (board == das1801st || board == das1802st ||
 		    board == das1701st || board == das1702st) {
-			printk(" Board model: %s\n",
-			       das1800_boards[board].name);
+			dev_dbg(dev->hw_dev, "Board model: %s\n",
+				das1800_boards[board].name);
 			return board;
 		}
 		printk
@@ -884,8 +887,8 @@
 		break;
 	case 0x8:
 		if (board == das1801hc || board == das1802hc) {
-			printk(" Board model: %s\n",
-			       das1800_boards[board].name);
+			dev_dbg(dev->hw_dev, "Board model: %s\n",
+				das1800_boards[board].name);
 			return board;
 		}
 		printk
diff --git a/drivers/staging/comedi/drivers/das6402.c b/drivers/staging/comedi/drivers/das6402.c
index 6328f52..f256841 100644
--- a/drivers/staging/comedi/drivers/das6402.c
+++ b/drivers/staging/comedi/drivers/das6402.c
@@ -171,7 +171,7 @@
 	struct comedi_subdevice *s = dev->subdevices;
 
 	if (!dev->attached || devpriv->das6402_ignoreirq) {
-		printk("das6402: BUG: spurious interrupt\n");
+		dev_warn(dev->hw_dev, "BUG: spurious interrupt\n");
 		return IRQ_HANDLED;
 	}
 #ifdef DEBUG
@@ -228,9 +228,7 @@
 	 */
 
 	devpriv->das6402_ignoreirq = 1;
-#ifdef DEBUG
-	printk("das6402: Stopping acquisition\n");
-#endif
+	dev_dbg(dev->hw_dev, "Stopping acquisition\n");
 	devpriv->das6402_ignoreirq = 1;
 	outb_p(0x02, dev->iobase + 10);	/* disable external trigging */
 	outw_p(SCANL, dev->iobase + 2);	/* resets the card fifo */
@@ -246,10 +244,7 @@
 			    struct comedi_subdevice *s, comedi_trig * it)
 {
 	devpriv->das6402_ignoreirq = 1;
-
-#ifdef DEBUG
-	printk("das6402: Starting acquisition\n");
-#endif
+	dev_dbg(dev->hw_dev, "Starting acquisition\n");
 	outb_p(0x03, dev->iobase + 10);	/* enable external trigging */
 	outw_p(SCANL, dev->iobase + 2);	/* resets the card fifo */
 	outb_p(IRQ | CONVSRC | BURSTEN | INTE, dev->iobase + 9);
@@ -329,10 +324,8 @@
 	if (iobase == 0)
 		iobase = 0x300;
 
-	printk("comedi%d: das6402: 0x%04lx", dev->minor, iobase);
-
 	if (!request_region(iobase, DAS6402_SIZE, "das6402")) {
-		printk(" I/O port conflict\n");
+		dev_err(dev->hw_dev, "I/O port conflict\n");
 		return -EIO;
 	}
 	dev->iobase = iobase;
@@ -340,14 +333,12 @@
 	/* should do a probe here */
 
 	irq = it->options[0];
-	printk(" ( irq = %u )", irq);
+	dev_dbg(dev->hw_dev, "( irq = %u )\n", irq);
 	ret = request_irq(irq, intr_handler, 0, "das6402", dev);
-	if (ret < 0) {
-		printk("irq conflict\n");
+	if (ret < 0)
 		return ret;
-	}
-	dev->irq = irq;
 
+	dev->irq = irq;
 	ret = alloc_private(dev, sizeof(struct das6402_private));
 	if (ret < 0)
 		return ret;
diff --git a/drivers/staging/comedi/drivers/das800.c b/drivers/staging/comedi/drivers/das800.c
index 96d41ad..6e347b4 100644
--- a/drivers/staging/comedi/drivers/das800.c
+++ b/drivers/staging/comedi/drivers/das800.c
@@ -296,47 +296,47 @@
 	switch (id_bits) {
 	case 0x0:
 		if (board == das800) {
-			printk(" Board model: DAS-800\n");
+			dev_dbg(dev->hw_dev, "Board model: DAS-800\n");
 			return board;
 		}
 		if (board == ciodas800) {
-			printk(" Board model: CIO-DAS800\n");
+			dev_dbg(dev->hw_dev, "Board model: CIO-DAS800\n");
 			return board;
 		}
-		printk(" Board model (probed): DAS-800\n");
+		dev_dbg(dev->hw_dev, "Board model (probed): DAS-800\n");
 		return das800;
 		break;
 	case 0x2:
 		if (board == das801) {
-			printk(" Board model: DAS-801\n");
+			dev_dbg(dev->hw_dev, "Board model: DAS-801\n");
 			return board;
 		}
 		if (board == ciodas801) {
-			printk(" Board model: CIO-DAS801\n");
+			dev_dbg(dev->hw_dev, "Board model: CIO-DAS801\n");
 			return board;
 		}
-		printk(" Board model (probed): DAS-801\n");
+		dev_dbg(dev->hw_dev, "Board model (probed): DAS-801\n");
 		return das801;
 		break;
 	case 0x3:
 		if (board == das802) {
-			printk(" Board model: DAS-802\n");
+			dev_dbg(dev->hw_dev, "Board model: DAS-802\n");
 			return board;
 		}
 		if (board == ciodas802) {
-			printk(" Board model: CIO-DAS802\n");
+			dev_dbg(dev->hw_dev, "Board model: CIO-DAS802\n");
 			return board;
 		}
 		if (board == ciodas80216) {
-			printk(" Board model: CIO-DAS802/16\n");
+			dev_dbg(dev->hw_dev, "Board model: CIO-DAS802/16\n");
 			return board;
 		}
-		printk(" Board model (probed): DAS-802\n");
+		dev_dbg(dev->hw_dev, "Board model (probed): DAS-802\n");
 		return das802;
 		break;
 	default:
-		printk(" Board model: probe returned 0x%x (unknown)\n",
-		       id_bits);
+		dev_dbg(dev->hw_dev, "Board model: probe returned 0x%x (unknown)\n",
+			id_bits);
 		return board;
 		break;
 	}
@@ -466,42 +466,43 @@
 	unsigned long irq_flags;
 	int board;
 
-	printk("comedi%d: das800: io 0x%lx", dev->minor, iobase);
+	dev_info(dev->hw_dev, "comedi%d: das800: io 0x%lx\n", dev->minor,
+		 iobase);
 	if (irq)
-		printk(", irq %u", irq);
-	printk("\n");
+		dev_dbg(dev->hw_dev, "irq %u\n", irq);
 
 	/* allocate and initialize dev->private */
 	if (alloc_private(dev, sizeof(struct das800_private)) < 0)
 		return -ENOMEM;
 
 	if (iobase == 0) {
-		printk("io base address required for das800\n");
+		dev_err(dev->hw_dev, "io base address required for das800\n");
 		return -EINVAL;
 	}
 
 	/* check if io addresses are available */
 	if (!request_region(iobase, DAS800_SIZE, "das800")) {
-		printk("I/O port conflict\n");
+		dev_err(dev->hw_dev, "I/O port conflict\n");
 		return -EIO;
 	}
 	dev->iobase = iobase;
 
 	board = das800_probe(dev);
 	if (board < 0) {
-		printk("unable to determine board type\n");
+		dev_dbg(dev->hw_dev, "unable to determine board type\n");
 		return -ENODEV;
 	}
 	dev->board_ptr = das800_boards + board;
 
 	/* grab our IRQ */
 	if (irq == 1 || irq > 7) {
-		printk("irq out of range\n");
+		dev_err(dev->hw_dev, "irq out of range\n");
 		return -EINVAL;
 	}
 	if (irq) {
 		if (request_irq(irq, das800_interrupt, 0, "das800", dev)) {
-			printk("unable to allocate irq %u\n", irq);
+			dev_err(dev->hw_dev, "unable to allocate irq %u\n",
+				irq);
 			return -EINVAL;
 		}
 	}
@@ -557,7 +558,7 @@
 
 static int das800_detach(struct comedi_device *dev)
 {
-	printk("comedi%d: das800: remove\n", dev->minor);
+	dev_info(dev->hw_dev, "comedi%d: das800: remove\n", dev->minor);
 
 	/* only free stuff if it has been allocated by _attach */
 	if (dev->iobase)
diff --git a/drivers/staging/comedi/drivers/dt3000.c b/drivers/staging/comedi/drivers/dt3000.c
index 6170f7b..0a7979e5 100644
--- a/drivers/staging/comedi/drivers/dt3000.c
+++ b/drivers/staging/comedi/drivers/dt3000.c
@@ -352,7 +352,8 @@
 	if ((status & DT3000_COMPLETION_MASK) == DT3000_NOERROR)
 		return 0;
 
-	printk("dt3k_send_cmd() timeout/error status=0x%04x\n", status);
+	dev_dbg(dev->hw_dev, "dt3k_send_cmd() timeout/error status=0x%04x\n",
+		status);
 
 	return -ETIME;
 }
@@ -383,7 +384,7 @@
 	dt3k_send_cmd(dev, CMD_WRITESINGLE);
 }
 
-static int debug_n_ints = 0;
+static int debug_n_ints;
 
 /* FIXME! Assumes shared interrupt is for this card. */
 /* What's this debug_n_ints stuff? Obviously needs some work... */
@@ -429,12 +430,12 @@
 static void debug_intr_flags(unsigned int flags)
 {
 	int i;
-	printk("dt3k: intr_flags:");
+	printk(KERN_DEBUG "dt3k: intr_flags:");
 	for (i = 0; i < 8; i++) {
 		if (flags & (1 << i))
-			printk(" %s", intr_flags[i]);
+			printk(KERN_CONT " %s", intr_flags[i]);
 	}
-	printk("\n");
+	printk(KERN_CONT "\n");
 }
 #endif
 
@@ -452,7 +453,7 @@
 	if (count < 0)
 		count += AI_FIFO_DEPTH;
 
-	printk("reading %d samples\n", count);
+	dev_dbg(dev->hw_dev, "reading %d samples\n", count);
 
 	rear = devpriv->ai_rear;
 
@@ -640,7 +641,7 @@
 	int ret;
 	unsigned int mode;
 
-	printk("dt3k_ai_cmd:\n");
+	dev_dbg(dev->hw_dev, "dt3k_ai_cmd:\n");
 	for (i = 0; i < cmd->chanlist_len; i++) {
 		chan = CR_CHAN(cmd->chanlist[i]);
 		range = CR_RANGE(cmd->chanlist[i]);
@@ -651,15 +652,15 @@
 	aref = CR_AREF(cmd->chanlist[0]);
 
 	writew(cmd->scan_end_arg, devpriv->io_addr + DPR_Params(0));
-	printk("param[0]=0x%04x\n", cmd->scan_end_arg);
+	dev_dbg(dev->hw_dev, "param[0]=0x%04x\n", cmd->scan_end_arg);
 
 	if (cmd->convert_src == TRIG_TIMER) {
 		divider = dt3k_ns_to_timer(50, &cmd->convert_arg,
 					   cmd->flags & TRIG_ROUND_MASK);
 		writew((divider >> 16), devpriv->io_addr + DPR_Params(1));
-		printk("param[1]=0x%04x\n", divider >> 16);
+		dev_dbg(dev->hw_dev, "param[1]=0x%04x\n", divider >> 16);
 		writew((divider & 0xffff), devpriv->io_addr + DPR_Params(2));
-		printk("param[2]=0x%04x\n", divider & 0xffff);
+		dev_dbg(dev->hw_dev, "param[2]=0x%04x\n", divider & 0xffff);
 	} else {
 		/* not supported */
 	}
@@ -668,21 +669,21 @@
 		tscandiv = dt3k_ns_to_timer(100, &cmd->scan_begin_arg,
 					    cmd->flags & TRIG_ROUND_MASK);
 		writew((tscandiv >> 16), devpriv->io_addr + DPR_Params(3));
-		printk("param[3]=0x%04x\n", tscandiv >> 16);
+		dev_dbg(dev->hw_dev, "param[3]=0x%04x\n", tscandiv >> 16);
 		writew((tscandiv & 0xffff), devpriv->io_addr + DPR_Params(4));
-		printk("param[4]=0x%04x\n", tscandiv & 0xffff);
+		dev_dbg(dev->hw_dev, "param[4]=0x%04x\n", tscandiv & 0xffff);
 	} else {
 		/* not supported */
 	}
 
 	mode = DT3000_AD_RETRIG_INTERNAL | 0 | 0;
 	writew(mode, devpriv->io_addr + DPR_Params(5));
-	printk("param[5]=0x%04x\n", mode);
+	dev_dbg(dev->hw_dev, "param[5]=0x%04x\n", mode);
 	writew(aref == AREF_DIFF, devpriv->io_addr + DPR_Params(6));
-	printk("param[6]=0x%04x\n", aref == AREF_DIFF);
+	dev_dbg(dev->hw_dev, "param[6]=0x%04x\n", aref == AREF_DIFF);
 
 	writew(AI_FIFO_DEPTH / 2, devpriv->io_addr + DPR_Params(7));
-	printk("param[7]=0x%04x\n", AI_FIFO_DEPTH / 2);
+	dev_dbg(dev->hw_dev, "param[7]=0x%04x\n", AI_FIFO_DEPTH / 2);
 
 	writew(SUBS_AI, devpriv->io_addr + DPR_SubSys);
 	ret = dt3k_send_cmd(dev, CMD_CONFIG);
@@ -848,7 +849,7 @@
 	int bus, slot;
 	int ret = 0;
 
-	printk("dt3000:");
+	dev_dbg(dev->hw_dev, "dt3000:\n");
 	bus = it->options[0];
 	slot = it->options[1];
 
@@ -860,7 +861,7 @@
 	if (ret < 0)
 		return ret;
 	if (ret == 0) {
-		printk(" no DT board found\n");
+		dev_warn(dev->hw_dev, "no DT board found\n");
 		return -ENODEV;
 	}
 
@@ -868,7 +869,8 @@
 
 	if (request_irq(devpriv->pci_dev->irq, dt3k_interrupt, IRQF_SHARED,
 			"dt3000", dev)) {
-		printk(" unable to allocate IRQ %u\n", devpriv->pci_dev->irq);
+		dev_err(dev->hw_dev, "unable to allocate IRQ %u\n",
+			devpriv->pci_dev->irq);
 		return -EINVAL;
 	}
 	dev->irq = devpriv->pci_dev->irq;
diff --git a/drivers/staging/comedi/drivers/jr3_pci.c b/drivers/staging/comedi/drivers/jr3_pci.c
index 8d98cf4..6a79ba1 100644
--- a/drivers/staging/comedi/drivers/jr3_pci.c
+++ b/drivers/staging/comedi/drivers/jr3_pci.c
@@ -71,18 +71,12 @@
 };
 
 static DEFINE_PCI_DEVICE_TABLE(jr3_pci_pci_table) = {
-	{
-	PCI_VENDOR_ID_JR3, PCI_DEVICE_ID_JR3_1_CHANNEL,
-		    PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, {
-	PCI_VENDOR_ID_JR3, PCI_DEVICE_ID_JR3_1_CHANNEL_NEW,
-		    PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, {
-	PCI_VENDOR_ID_JR3, PCI_DEVICE_ID_JR3_2_CHANNEL,
-		    PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, {
-	PCI_VENDOR_ID_JR3, PCI_DEVICE_ID_JR3_3_CHANNEL,
-		    PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, {
-	PCI_VENDOR_ID_JR3, PCI_DEVICE_ID_JR3_4_CHANNEL,
-		    PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, {
-	0}
+	{ PCI_DEVICE(PCI_VENDOR_ID_JR3, PCI_DEVICE_ID_JR3_1_CHANNEL) },
+	{ PCI_DEVICE(PCI_VENDOR_ID_JR3, PCI_DEVICE_ID_JR3_1_CHANNEL_NEW) },
+	{ PCI_DEVICE(PCI_VENDOR_ID_JR3, PCI_DEVICE_ID_JR3_2_CHANNEL) },
+	{ PCI_DEVICE(PCI_VENDOR_ID_JR3, PCI_DEVICE_ID_JR3_3_CHANNEL) },
+	{ PCI_DEVICE(PCI_VENDOR_ID_JR3, PCI_DEVICE_ID_JR3_4_CHANNEL) },
+	{0}
 };
 
 MODULE_DEVICE_TABLE(pci, jr3_pci_pci_table);
@@ -378,14 +372,14 @@
 	int i;
 	struct jr3_pci_dev_private *devpriv = dev->private;
 
-	printk("jr3_pci_open\n");
+	dev_dbg(dev->hw_dev, "jr3_pci_open\n");
 	for (i = 0; i < devpriv->n_channels; i++) {
 		struct jr3_pci_subdev_private *p;
 
 		p = dev->subdevices[i].private;
 		if (p) {
-			printk("serial: %p %d (%d)\n", p, p->serial_no,
-			       p->channel_no);
+			dev_dbg(dev->hw_dev, "serial: %p %d (%d)\n", p,
+				p->serial_no, p->channel_no);
 		}
 	}
 	return 0;
@@ -463,8 +457,8 @@
 					break;
 				more = more
 				    && read_idm_word(data, size, &pos, &addr);
-				printk("Loading#%d %4.4x bytes at %4.4x\n", i,
-				       count, addr);
+				dev_dbg(dev->hw_dev, "Loading#%d %4.4x bytes at %4.4x\n",
+					i, count, addr);
 				while (more && count > 0) {
 					if (addr & 0x4000) {
 						/*  16 bit data, never seen in real life!! */
@@ -599,24 +593,24 @@
 					min_full_scale =
 					    get_min_full_scales(channel);
 					printk("Obtained Min. Full Scales:\n");
-					printk("%i   ", (min_full_scale).fx);
-					printk("%i   ", (min_full_scale).fy);
-					printk("%i   ", (min_full_scale).fz);
-					printk("%i   ", (min_full_scale).mx);
-					printk("%i   ", (min_full_scale).my);
-					printk("%i   ", (min_full_scale).mz);
-					printk("\n");
+					printk(KERN_DEBUG "%i ", (min_full_scale).fx);
+					printk(KERN_CONT "%i ", (min_full_scale).fy);
+					printk(KERN_CONT "%i ", (min_full_scale).fz);
+					printk(KERN_CONT "%i ", (min_full_scale).mx);
+					printk(KERN_CONT "%i ", (min_full_scale).my);
+					printk(KERN_CONT "%i ", (min_full_scale).mz);
+					printk(KERN_CONT "\n");
 
 					max_full_scale =
 					    get_max_full_scales(channel);
 					printk("Obtained Max. Full Scales:\n");
-					printk("%i   ", (max_full_scale).fx);
-					printk("%i   ", (max_full_scale).fy);
-					printk("%i   ", (max_full_scale).fz);
-					printk("%i   ", (max_full_scale).mx);
-					printk("%i   ", (max_full_scale).my);
-					printk("%i   ", (max_full_scale).mz);
-					printk("\n");
+					printk(KERN_DEBUG "%i ", (max_full_scale).fx);
+					printk(KERN_CONT "%i ", (max_full_scale).fy);
+					printk(KERN_CONT "%i ", (max_full_scale).fz);
+					printk(KERN_CONT "%i ", (max_full_scale).mx);
+					printk(KERN_CONT "%i ", (max_full_scale).my);
+					printk(KERN_CONT "%i ", (max_full_scale).mz);
+					printk(KERN_CONT "\n");
 
 					set_full_scales(channel,
 							max_full_scale);
@@ -779,14 +773,12 @@
 	int opt_bus, opt_slot, i;
 	struct jr3_pci_dev_private *devpriv;
 
-	printk("comedi%d: jr3_pci\n", dev->minor);
-
 	opt_bus = it->options[0];
 	opt_slot = it->options[1];
 
 	if (sizeof(struct jr3_channel) != 0xc00) {
-		printk("sizeof(struct jr3_channel) = %x [expected %x]\n",
-		       (unsigned)sizeof(struct jr3_channel), 0xc00);
+		dev_err(dev->hw_dev, "sizeof(struct jr3_channel) = %x [expected %x]\n",
+			(unsigned)sizeof(struct jr3_channel), 0xc00);
 		return -EINVAL;
 	}
 
@@ -840,7 +832,7 @@
 		}
 	}
 	if (!card) {
-		printk(" no jr3_pci found\n");
+		dev_err(dev->hw_dev, "no jr3_pci found\n");
 		return -EIO;
 	} else {
 		devpriv->pci_dev = card;
@@ -875,10 +867,10 @@
 
 			p = dev->subdevices[i].private;
 			p->channel = &devpriv->iobase->channel[i].data;
-			printk("p->channel %p %p (%tx)\n",
-			       p->channel, devpriv->iobase,
-			       ((char *)(p->channel) -
-				(char *)(devpriv->iobase)));
+			dev_dbg(dev->hw_dev, "p->channel %p %p (%tx)\n",
+				p->channel, devpriv->iobase,
+				((char *)(p->channel) -
+				 (char *)(devpriv->iobase)));
 			p->channel_no = i;
 			for (j = 0; j < 8; j++) {
 				int k;
@@ -916,7 +908,7 @@
 	devpriv->iobase->channel[0].reset = 0;
 
 	result = comedi_load_firmware(dev, "jr3pci.idm", jr3_download_firmware);
-	printk("Firmare load %d\n", result);
+	dev_dbg(dev->hw_dev, "Firmare load %d\n", result);
 
 	if (result < 0)
 		goto out;
@@ -934,9 +926,9 @@
  */
 	msleep_interruptible(25);
 	for (i = 0; i < 0x18; i++) {
-		printk("%c",
-		       get_u16(&devpriv->iobase->channel[0].
-			       data.copyright[i]) >> 8);
+		dev_dbg(dev->hw_dev, "%c\n",
+			get_u16(&devpriv->iobase->channel[0].
+				data.copyright[i]) >> 8);
 	}
 
 	/*  Start card timer */
@@ -963,7 +955,6 @@
 	int i;
 	struct jr3_pci_dev_private *devpriv = dev->private;
 
-	printk("comedi%d: jr3_pci: remove\n", dev->minor);
 	if (devpriv) {
 		del_timer_sync(&devpriv->timer);
 
diff --git a/drivers/staging/comedi/drivers/ke_counter.c b/drivers/staging/comedi/drivers/ke_counter.c
index 286093b..4e9e9a0 100644
--- a/drivers/staging/comedi/drivers/ke_counter.c
+++ b/drivers/staging/comedi/drivers/ke_counter.c
@@ -52,10 +52,8 @@
 static int cnt_detach(struct comedi_device *dev);
 
 static DEFINE_PCI_DEVICE_TABLE(cnt_pci_table) = {
-	{
-	PCI_VENDOR_ID_KOLTER, CNT_CARD_DEVICE_ID, PCI_ANY_ID,
-		    PCI_ANY_ID, 0, 0, 0}, {
-	0}
+	{ PCI_DEVICE(PCI_VENDOR_ID_KOLTER, CNT_CARD_DEVICE_ID) },
+	{0}
 };
 
 MODULE_DEVICE_TABLE(pci, cnt_pci_table);
diff --git a/drivers/staging/comedi/drivers/me_daq.c b/drivers/staging/comedi/drivers/me_daq.c
index cda4b22..8b812e4 100644
--- a/drivers/staging/comedi/drivers/me_daq.c
+++ b/drivers/staging/comedi/drivers/me_daq.c
@@ -188,12 +188,9 @@
 };
 
 static DEFINE_PCI_DEVICE_TABLE(me_pci_table) = {
-	{
-	PCI_VENDOR_ID_MEILHAUS, ME2600_DEVICE_ID, PCI_ANY_ID,
-		    PCI_ANY_ID, 0, 0, 0}, {
-	PCI_VENDOR_ID_MEILHAUS, ME2000_DEVICE_ID, PCI_ANY_ID,
-		    PCI_ANY_ID, 0, 0, 0}, {
-	0}
+	{ PCI_DEVICE(PCI_VENDOR_ID_MEILHAUS, ME2600_DEVICE_ID) },
+	{ PCI_DEVICE(PCI_VENDOR_ID_MEILHAUS, ME2000_DEVICE_ID) },
+	{0}
 };
 
 MODULE_DEVICE_TABLE(pci, me_pci_table);
diff --git a/drivers/staging/comedi/drivers/ni_at_a2150.c b/drivers/staging/comedi/drivers/ni_at_a2150.c
index 32e675e..c25e44c 100644
--- a/drivers/staging/comedi/drivers/ni_at_a2150.c
+++ b/drivers/staging/comedi/drivers/ni_at_a2150.c
@@ -731,9 +731,8 @@
 	outw(trigger_bits, dev->iobase + TRIGGER_REG);
 
 	/*  start acquisition for soft trigger */
-	if (cmd->start_src == TRIG_NOW) {
+	if (cmd->start_src == TRIG_NOW)
 		outw(0, dev->iobase + FIFO_START_REG);
-	}
 #ifdef A2150_DEBUG
 	ni_dump_regs(dev);
 #endif
@@ -860,11 +859,10 @@
 	case TRIG_ROUND_NEAREST:
 	default:
 		/*  if least upper bound is better approximation */
-		if (lub - *period < *period - glb) {
+		if (lub - *period < *period - glb)
 			*period = lub;
-		} else {
+		else
 			*period = glb;
-		}
 		break;
 	case TRIG_ROUND_UP:
 		*period = lub;
diff --git a/drivers/staging/comedi/drivers/ni_daq_dio24.c b/drivers/staging/comedi/drivers/ni_daq_dio24.c
index 49b824c..c0423a8 100644
--- a/drivers/staging/comedi/drivers/ni_daq_dio24.c
+++ b/drivers/staging/comedi/drivers/ni_daq_dio24.c
@@ -52,7 +52,7 @@
 #include <pcmcia/cisreg.h>
 #include <pcmcia/ds.h>
 
-static struct pcmcia_device *pcmcia_cur_dev = NULL;
+static struct pcmcia_device *pcmcia_cur_dev;
 
 #define DIO24_SIZE 4		/*  size of io region used by board */
 
@@ -133,22 +133,19 @@
 #endif
 		break;
 	default:
-		printk("bug! couldn't determine board type\n");
+		pr_err("bug! couldn't determine board type\n");
 		return -EINVAL;
 		break;
 	}
-	printk("comedi%d: ni_daq_dio24: %s, io 0x%lx", dev->minor,
-	       thisboard->name, iobase);
+	pr_debug("comedi%d: ni_daq_dio24: %s, io 0x%lx", dev->minor,
+		 thisboard->name, iobase);
 #ifdef incomplete
-	if (irq) {
-		printk(", irq %u", irq);
-	}
+	if (irq)
+		pr_debug("irq %u\n", irq);
 #endif
 
-	printk("\n");
-
 	if (iobase == 0) {
-		printk("io base address is zero!\n");
+		pr_err("io base address is zero!\n");
 		return -EINVAL;
 	}
 
@@ -173,7 +170,7 @@
 
 static int dio24_detach(struct comedi_device *dev)
 {
-	printk("comedi%d: ni_daq_dio24: remove\n", dev->minor);
+	dev_info(dev->hw_dev, "comedi%d: ni_daq_dio24: remove\n", dev->minor);
 
 	if (dev->subdevices)
 		subdev_8255_cleanup(dev, dev->subdevices + 0);
diff --git a/drivers/staging/comedi/drivers/ni_labpc_cs.c b/drivers/staging/comedi/drivers/ni_labpc_cs.c
index 832a517..ff38405 100644
--- a/drivers/staging/comedi/drivers/ni_labpc_cs.c
+++ b/drivers/staging/comedi/drivers/ni_labpc_cs.c
@@ -145,7 +145,7 @@
 		irq = link->irq;
 		break;
 	default:
-		printk("bug! couldn't determine board type\n");
+		pr_err("bug! couldn't determine board type\n");
 		return -EINVAL;
 		break;
 	}
diff --git a/drivers/staging/comedi/drivers/ni_pcimio.c b/drivers/staging/comedi/drivers/ni_pcimio.c
index 9148abd..0f0d995 100644
--- a/drivers/staging/comedi/drivers/ni_pcimio.c
+++ b/drivers/staging/comedi/drivers/ni_pcimio.c
@@ -1470,7 +1470,7 @@
 		/* FIXME: DIO_Output_Register (16 bit reg) is replaced by M_Offset_Static_Digital_Output (32 bit)
 		   and M_Offset_SCXI_Serial_Data_Out (8 bit) */
 	default:
-		printk("%s: bug! unhandled register=0x%x in switch.\n",
+		printk(KERN_WARNING "%s: bug! unhandled register=0x%x in switch.\n",
 		       __func__, reg);
 		BUG();
 		return;
@@ -1505,7 +1505,7 @@
 		offset = M_Offset_G01_Status;
 		break;
 	default:
-		printk("%s: bug! unhandled register=0x%x in switch.\n",
+		printk(KERN_WARNING "%s: bug! unhandled register=0x%x in switch.\n",
 		       __func__, reg);
 		BUG();
 		return 0;
@@ -1547,7 +1547,7 @@
 		offset = M_Offset_G1_Load_B;
 		break;
 	default:
-		printk("%s: bug! unhandled register=0x%x in switch.\n",
+		printk(KERN_WARNING "%s: bug! unhandled register=0x%x in switch.\n",
 		       __func__, reg);
 		BUG();
 		return;
@@ -1573,7 +1573,7 @@
 		offset = M_Offset_G1_Save;
 		break;
 	default:
-		printk("%s: bug! unhandled register=0x%x in switch.\n",
+		printk(KERN_WARNING "%s: bug! unhandled register=0x%x in switch.\n",
 		       __func__, reg);
 		BUG();
 		return 0;
@@ -1632,9 +1632,8 @@
 	}
 	devpriv->serial_number = be32_to_cpu(devpriv->serial_number);
 
-	for (i = 0; i < M_SERIES_EEPROM_SIZE; ++i) {
+	for (i = 0; i < M_SERIES_EEPROM_SIZE; ++i)
 		devpriv->eeprom_buffer[i] = ni_readb(Start_Cal_EEPROM + i);
-	}
 
 	writel(old_iodwbsr1_bits, devpriv->mite->mite_io_addr + MITE_IODWBSR_1);
 	writel(old_iodwbsr_bits, devpriv->mite->mite_io_addr + MITE_IODWBSR);
@@ -1665,9 +1664,9 @@
 static int pcimio_detach(struct comedi_device *dev)
 {
 	mio_common_detach(dev);
-	if (dev->irq) {
+	if (dev->irq)
 		free_irq(dev->irq, dev);
-	}
+
 	if (dev->private) {
 		mite_free_ring(devpriv->ai_mite_ring);
 		mite_free_ring(devpriv->ao_mite_ring);
@@ -1685,7 +1684,7 @@
 {
 	int ret;
 
-	printk("comedi%d: ni_pcimio:", dev->minor);
+	dev_info(dev->hw_dev, "comedi%d: ni_pcimio:\n", dev->minor);
 
 	ret = ni_alloc_private(dev);
 	if (ret < 0)
@@ -1695,7 +1694,7 @@
 	if (ret < 0)
 		return ret;
 
-	printk(" %s", boardtype.name);
+	dev_dbg(dev->hw_dev, "%s\n", boardtype.name);
 	dev->board_name = boardtype.name;
 
 	if (boardtype.reg_type & ni_reg_m_series_mask) {
@@ -1712,7 +1711,7 @@
 
 	ret = mite_setup(devpriv->mite);
 	if (ret < 0) {
-		printk(" error setting up mite\n");
+		pr_warn("error setting up mite\n");
 		return ret;
 	}
 	comedi_set_hw_dev(dev, &devpriv->mite->pcidev->dev);
@@ -1740,13 +1739,13 @@
 	dev->irq = mite_irq(devpriv->mite);
 
 	if (dev->irq == 0) {
-		printk(" unknown irq (bad)\n");
+		pr_warn("unknown irq (bad)\n");
 	} else {
-		printk(" ( irq = %u )", dev->irq);
+		pr_debug("( irq = %u )\n", dev->irq);
 		ret = request_irq(dev->irq, ni_E_interrupt, NI_E_IRQ_FLAGS,
 				  DRV_NAME, dev);
 		if (ret < 0) {
-			printk(" irq not available\n");
+			pr_warn("irq not available\n");
 			dev->irq = 0;
 		}
 	}
@@ -1787,7 +1786,7 @@
 			}
 		}
 	}
-	printk("no device found\n");
+	pr_warn("no device found\n");
 	mite_list_devices();
 	return -EIO;
 }
diff --git a/drivers/staging/comedi/drivers/pcl816.c b/drivers/staging/comedi/drivers/pcl816.c
index 0b9bee3..96cd7ec 100644
--- a/drivers/staging/comedi/drivers/pcl816.c
+++ b/drivers/staging/comedi/drivers/pcl816.c
@@ -155,8 +155,8 @@
 static int pcl816_detach(struct comedi_device *dev);
 
 #ifdef unused
-static int RTC_lock = 0;	/* RTC lock */
-static int RTC_timer_lock = 0;	/* RTC int lock */
+static int RTC_lock;	/* RTC lock */
+static int RTC_timer_lock;	/* RTC int lock */
 #endif
 
 static struct comedi_driver driver_pcl816 = {
diff --git a/drivers/staging/comedi/drivers/pcl818.c b/drivers/staging/comedi/drivers/pcl818.c
index b45a9bd..7344a53 100644
--- a/drivers/staging/comedi/drivers/pcl818.c
+++ b/drivers/staging/comedi/drivers/pcl818.c
@@ -252,8 +252,8 @@
 static int pcl818_detach(struct comedi_device *dev);
 
 #ifdef unused
-static int RTC_lock = 0;	/* RTC lock */
-static int RTC_timer_lock = 0;	/* RTC int lock */
+static int RTC_lock;	/* RTC lock */
+static int RTC_timer_lock;	/* RTC int lock */
 #endif
 
 struct pcl818_board {
@@ -463,9 +463,8 @@
 	int n;
 	int chan = CR_CHAN(insn->chanspec);
 
-	for (n = 0; n < insn->n; n++) {
+	for (n = 0; n < insn->n; n++)
 		data[n] = devpriv->ao_readback[chan];
-	}
 
 	return n;
 }
@@ -571,9 +570,9 @@
 		return IRQ_HANDLED;
 	}
 	devpriv->act_chanlist_pos++;
-	if (devpriv->act_chanlist_pos >= devpriv->act_chanlist_len) {
+	if (devpriv->act_chanlist_pos >= devpriv->act_chanlist_len)
 		devpriv->act_chanlist_pos = 0;
-	}
+
 	s->async->cur_chan++;
 	if (s->async->cur_chan >= devpriv->ai_n_chan) {
 		/*  printk("E"); */
@@ -645,9 +644,9 @@
 		comedi_buf_put(s->async, ptr[bufptr++] >> 4);	/*  get one sample */
 
 		devpriv->act_chanlist_pos++;
-		if (devpriv->act_chanlist_pos >= devpriv->act_chanlist_len) {
+		if (devpriv->act_chanlist_pos >= devpriv->act_chanlist_len)
 			devpriv->act_chanlist_pos = 0;
-		}
+
 		s->async->cur_chan++;
 		if (s->async->cur_chan >= devpriv->ai_n_chan) {
 			s->async->cur_chan = 0;
@@ -805,11 +804,10 @@
 		return IRQ_HANDLED;
 	}
 
-	if (lo & 2) {
+	if (lo & 2)
 		len = 512;
-	} else {
+	else
 		len = 0;
-	}
 
 	for (i = 0; i < len; i++) {
 		lo = inb(dev->iobase + PCL818_FI_DATALO);
@@ -827,9 +825,9 @@
 		comedi_buf_put(s->async, (lo >> 4) | (inb(dev->iobase + PCL818_FI_DATAHI) << 4));	/*  get one sample */
 
 		devpriv->act_chanlist_pos++;
-		if (devpriv->act_chanlist_pos >= devpriv->act_chanlist_len) {
+		if (devpriv->act_chanlist_pos >= devpriv->act_chanlist_len)
 			devpriv->act_chanlist_pos = 0;
-		}
+
 		s->async->cur_chan++;
 		if (s->async->cur_chan >= devpriv->ai_n_chan) {
 			s->async->cur_chan = 0;
@@ -1009,7 +1007,7 @@
 	int divisor1 = 0, divisor2 = 0;
 	unsigned int seglen;
 
-	printk("pcl818_ai_cmd_mode()\n");
+	dev_dbg(dev->hw_dev, "pcl818_ai_cmd_mode()\n");
 	if ((!dev->irq) && (!devpriv->dma_rtc)) {
 		comedi_error(dev, "IRQ not defined!");
 		return -EINVAL;
@@ -1112,7 +1110,7 @@
 		break;
 	}
 #endif
-	printk("pcl818_ai_cmd_mode() end\n");
+	dev_dbg(dev->hw_dev, "pcl818_ai_cmd_mode() end\n");
 	return 0;
 }
 
@@ -1309,11 +1307,9 @@
 */
 static int check_single_ended(unsigned int port)
 {
-	if (inb(port + PCL818_STATUS) & 0x20) {
+	if (inb(port + PCL818_STATUS) & 0x20)
 		return 1;
-	} else {
-		return 0;
-	}
+	return 0;
 }
 
 /*
@@ -1352,9 +1348,8 @@
 	if (!cmd->stop_src || tmp != cmd->stop_src)
 		err++;
 
-	if (err) {
+	if (err)
 		return 1;
-	}
 
 	/* step 2: make sure trigger sources are unique and mutually compatible */
 
@@ -1377,9 +1372,8 @@
 	if (cmd->stop_src != TRIG_NONE && cmd->stop_src != TRIG_COUNT)
 		err++;
 
-	if (err) {
+	if (err)
 		return 2;
-	}
 
 	/* step 3: make sure arguments are trivially compatible */
 
@@ -1421,9 +1415,8 @@
 		}
 	}
 
-	if (err) {
+	if (err)
 		return 3;
-	}
 
 	/* step 4: fix up any arguments */
 
@@ -1438,9 +1431,8 @@
 			err++;
 	}
 
-	if (err) {
+	if (err)
 		return 4;
-	}
 
 	/* step 5: complain about special chanlist considerations */
 
@@ -1461,7 +1453,7 @@
 	struct comedi_cmd *cmd = &s->async->cmd;
 	int retval;
 
-	printk("pcl818_ai_cmd()\n");
+	dev_dbg(dev->hw_dev, "pcl818_ai_cmd()\n");
 	devpriv->ai_n_chan = cmd->chanlist_len;
 	devpriv->ai_chanlist = cmd->chanlist;
 	devpriv->ai_flags = cmd->flags;
@@ -1470,17 +1462,16 @@
 	devpriv->ai_timer1 = 0;
 	devpriv->ai_timer2 = 0;
 
-	if (cmd->stop_src == TRIG_COUNT) {
+	if (cmd->stop_src == TRIG_COUNT)
 		devpriv->ai_scans = cmd->stop_arg;
-	} else {
+	else
 		devpriv->ai_scans = 0;
-	}
 
 	if (cmd->scan_begin_src == TRIG_FOLLOW) {	/*  mode 1, 3 */
 		if (cmd->convert_src == TRIG_TIMER) {	/*  mode 1 */
 			devpriv->ai_timer1 = cmd->convert_arg;
 			retval = pcl818_ai_cmd_mode(1, dev, s);
-			printk("pcl818_ai_cmd() end\n");
+			dev_dbg(dev->hw_dev, "pcl818_ai_cmd() end\n");
 			return retval;
 		}
 		if (cmd->convert_src == TRIG_EXT) {	/*  mode 3 */
@@ -1499,7 +1490,7 @@
 			    struct comedi_subdevice *s)
 {
 	if (devpriv->irq_blocked > 0) {
-		printk("pcl818_ai_cancel()\n");
+		dev_dbg(dev->hw_dev, "pcl818_ai_cancel()\n");
 		devpriv->irq_was_now_closed = 1;
 
 		switch (devpriv->ai_mode) {
@@ -1549,7 +1540,7 @@
 	}
 
 end:
-	printk("pcl818_ai_cancel() end\n");
+	dev_dbg(dev->hw_dev, "pcl818_ai_cancel() end\n");
 	return 0;
 }
 
@@ -1633,11 +1624,11 @@
 	save_flags(flags);
 	cli();
 	val = CMOS_READ(RTC_CONTROL);
-	if (bit) {
+	if (bit)
 		val |= RTC_PIE;
-	} else {
+	else
 		val &= ~RTC_PIE;
-	}
+
 	CMOS_WRITE(val, RTC_CONTROL);
 	CMOS_READ(RTC_INTR_FLAGS);
 	restore_flags(flags);
@@ -1754,22 +1745,23 @@
 
 	/* claim our I/O space */
 	iobase = it->options[0];
-	printk("comedi%d: pcl818:  board=%s, ioport=0x%03lx",
-	       dev->minor, this_board->name, iobase);
+	printk
+	    ("comedi%d: pcl818:  board=%s, ioport=0x%03lx",
+	     dev->minor, this_board->name, iobase);
 	devpriv->io_range = this_board->io_range;
 	if ((this_board->fifo) && (it->options[2] == -1)) {	/*  we've board with FIFO and we want to use FIFO */
 		devpriv->io_range = PCLx1xFIFO_RANGE;
 		devpriv->usefifo = 1;
 	}
 	if (!request_region(iobase, devpriv->io_range, "pcl818")) {
-		printk("I/O port conflict\n");
+		comedi_error(dev, "I/O port conflict\n");
 		return -EIO;
 	}
 
 	dev->iobase = iobase;
 
 	if (pcl818_check(iobase)) {
-		printk(", I can't detect board. FAIL!\n");
+		comedi_error(dev, "I can't detect board. FAIL!\n");
 		return -EIO;
 	}
 
@@ -1793,19 +1785,18 @@
 					     irq);
 					irq = 0;	/* Can't use IRQ */
 				} else {
-					printk(", irq=%u", irq);
+					printk(KERN_DEBUG "irq=%u", irq);
 				}
 			}
 		}
 	}
 
 	dev->irq = irq;
-	if (irq) {
-		devpriv->irq_free = 1;
-	} /* 1=we have allocated irq */
-	else {
+	if (irq)
+		devpriv->irq_free = 1;   /* 1=we have allocated irq */
+	else
 		devpriv->irq_free = 0;
-	}
+
 	devpriv->irq_blocked = 0;	/* number of subdevice which use IRQ */
 	devpriv->ai_mode = 0;	/* mode of irq */
 
@@ -1825,7 +1816,7 @@
 				 "pcl818 DMA (RTC)", dev)) {
 			devpriv->dma_rtc = 1;
 			devpriv->rtc_irq = RTC_IRQ;
-			printk(", dma_irq=%u", devpriv->rtc_irq);
+			printk(KERN_DEBUG "dma_irq=%u", devpriv->rtc_irq);
 		} else {
 			RTC_lock--;
 			if (RTC_lock == 0) {
@@ -1850,34 +1841,26 @@
 		if (dma < 1)
 			goto no_dma;	/* DMA disabled */
 		if (((1 << dma) & this_board->DMAbits) == 0) {
-			printk(", DMA is out of allowed range, FAIL!\n");
+			printk(KERN_ERR "DMA is out of allowed range, FAIL!\n");
 			return -EINVAL;	/* Bad DMA */
 		}
 		ret = request_dma(dma, "pcl818");
-		if (ret) {
-			printk(", unable to allocate DMA %u, FAIL!\n", dma);
+		if (ret)
 			return -EBUSY;	/* DMA isn't free */
-		}
 		devpriv->dma = dma;
-		printk(", dma=%u", dma);
 		pages = 2;	/* we need 16KB */
 		devpriv->dmabuf[0] = __get_dma_pages(GFP_KERNEL, pages);
-		if (!devpriv->dmabuf[0]) {
-			printk(", unable to allocate DMA buffer, FAIL!\n");
+		if (!devpriv->dmabuf[0])
 			/* maybe experiment with try_to_free_pages() will help .... */
 			return -EBUSY;	/* no buffer :-( */
-		}
 		devpriv->dmapages[0] = pages;
 		devpriv->hwdmaptr[0] = virt_to_bus((void *)devpriv->dmabuf[0]);
 		devpriv->hwdmasize[0] = (1 << pages) * PAGE_SIZE;
 		/* printk("%d %d %ld, ",devpriv->dmapages[0],devpriv->hwdmasize[0],PAGE_SIZE); */
 		if (devpriv->dma_rtc == 0) {	/*  we must do duble buff :-( */
 			devpriv->dmabuf[1] = __get_dma_pages(GFP_KERNEL, pages);
-			if (!devpriv->dmabuf[1]) {
-				printk
-				    (", unable to allocate DMA buffer, FAIL!\n");
+			if (!devpriv->dmabuf[1])
 				return -EBUSY;
-			}
 			devpriv->dmapages[1] = pages;
 			devpriv->hwdmaptr[1] =
 			    virt_to_bus((void *)devpriv->dmabuf[1]);
@@ -2017,11 +2000,10 @@
 	}
 
 	/* select 1/10MHz oscilator */
-	if ((it->options[3] == 0) || (it->options[3] == 10)) {
+	if ((it->options[3] == 0) || (it->options[3] == 10))
 		devpriv->i8253_osc_base = 100;
-	} else {
+	else
 		devpriv->i8253_osc_base = 1000;
-	}
 
 	/* max sampling speed */
 	devpriv->ns_min = this_board->ns_min;
diff --git a/drivers/staging/comedi/drivers/pcmmio.c b/drivers/staging/comedi/drivers/pcmmio.c
index 3ad04aa..eddac00 100644
--- a/drivers/staging/comedi/drivers/pcmmio.c
+++ b/drivers/staging/comedi/drivers/pcmmio.c
@@ -371,15 +371,15 @@
 	iobase = it->options[0];
 	irq[0] = it->options[1];
 
-	printk(KERN_INFO "comedi%d: %s: io: %lx ", dev->minor, driver.driver_name,
-	       iobase);
+	printk(KERN_INFO "comedi%d: %s: io: %lx attaching...\n", dev->minor,
+			driver.driver_name, iobase);
 
 	dev->iobase = iobase;
 
 	if (!iobase || !request_region(iobase,
 				       thisboard->total_iosize,
 				       driver.driver_name)) {
-		printk(KERN_ERR "I/O port conflict\n");
+		printk(KERN_ERR "comedi%d: I/O port conflict\n", dev->minor);
 		return -EIO;
 	}
 
@@ -394,7 +394,8 @@
  * convenient macro defined in comedidev.h.
  */
 	if (alloc_private(dev, sizeof(struct pcmmio_private)) < 0) {
-		printk(KERN_ERR "cannot allocate private data structure\n");
+		printk(KERN_ERR "comedi%d: cannot allocate private data structure\n",
+				dev->minor);
 		return -ENOMEM;
 	}
 
@@ -417,7 +418,8 @@
 	    kcalloc(n_subdevs, sizeof(struct pcmmio_subdev_private),
 		    GFP_KERNEL);
 	if (!devpriv->sprivs) {
-		printk(KERN_ERR "cannot allocate subdevice private data structures\n");
+		printk(KERN_ERR "comedi%d: cannot allocate subdevice private data structures\n",
+				dev->minor);
 		return -ENOMEM;
 	}
 	/*
@@ -427,7 +429,8 @@
 	 * Allocate 1 AI + 1 AO + 2 DIO subdevs (24 lines per DIO)
 	 */
 	if (alloc_subdevices(dev, n_subdevs) < 0) {
-		printk(KERN_ERR "cannot allocate subdevice data structures\n");
+		printk(KERN_ERR "comedi%d: cannot allocate subdevice data structures\n",
+				dev->minor);
 		return -ENOMEM;
 	}
 
@@ -557,14 +560,15 @@
 				 */
 
 	if (irq[0]) {
-		printk(KERN_DEBUG "irq: %u ", irq[0]);
+		printk(KERN_DEBUG "comedi%d: irq: %u\n", dev->minor, irq[0]);
 		if (thisboard->dio_num_asics == 2 && irq[1])
-			printk(KERN_DEBUG "second ASIC irq: %u ", irq[1]);
+			printk(KERN_DEBUG "comedi%d: second ASIC irq: %u\n",
+					dev->minor, irq[1]);
 	} else {
-		printk(KERN_INFO "(IRQ mode disabled) ");
+		printk(KERN_INFO "comedi%d: (IRQ mode disabled)\n", dev->minor);
 	}
 
-	printk(KERN_INFO "attached\n");
+	printk(KERN_INFO "comedi%d: attached\n", dev->minor);
 
 	return 1;
 }
@@ -663,7 +667,7 @@
 		}
 #ifdef DAMMIT_ITS_BROKEN
 		/* DEBUG */
-		printk(KERN_DEBUG "data_out_byte %02x\n", (unsigned)byte);
+		printk("data_out_byte %02x\n", (unsigned)byte);
 #endif
 		/* save the digital input lines for this byte.. */
 		s->state |= ((unsigned int)byte) << offset;
diff --git a/drivers/staging/comedi/drivers/pcmuio.c b/drivers/staging/comedi/drivers/pcmuio.c
index b2c2c89..661ba2e 100644
--- a/drivers/staging/comedi/drivers/pcmuio.c
+++ b/drivers/staging/comedi/drivers/pcmuio.c
@@ -295,15 +295,15 @@
 	irq[0] = it->options[1];
 	irq[1] = it->options[2];
 
-	printk("comedi%d: %s: io: %lx ", dev->minor, driver.driver_name,
-	       iobase);
+	dev_dbg(dev->hw_dev, "comedi%d: %s: io: %lx attached\n", dev->minor,
+		driver.driver_name, iobase);
 
 	dev->iobase = iobase;
 
 	if (!iobase || !request_region(iobase,
 				       thisboard->num_asics * ASIC_IOSIZE,
 				       driver.driver_name)) {
-		printk("I/O port conflict\n");
+		dev_err(dev->hw_dev, "I/O port conflict\n");
 		return -EIO;
 	}
 
@@ -318,7 +318,7 @@
  * convenient macro defined in comedidev.h.
  */
 	if (alloc_private(dev, sizeof(struct pcmuio_private)) < 0) {
-		printk("cannot allocate private data structure\n");
+		dev_warn(dev->hw_dev, "cannot allocate private data structure\n");
 		return -ENOMEM;
 	}
 
@@ -337,7 +337,7 @@
 	    kcalloc(n_subdevs, sizeof(struct pcmuio_subdev_private),
 		    GFP_KERNEL);
 	if (!devpriv->sprivs) {
-		printk("cannot allocate subdevice private data structures\n");
+		dev_warn(dev->hw_dev, "cannot allocate subdevice private data structures\n");
 		return -ENOMEM;
 	}
 	/*
@@ -348,7 +348,7 @@
 	 * 96-channel version of the board.
 	 */
 	if (alloc_subdevices(dev, n_subdevs) < 0) {
-		printk("cannot allocate subdevice data structures\n");
+		dev_dbg(dev->hw_dev, "cannot allocate subdevice data structures\n");
 		return -ENOMEM;
 	}
 
@@ -436,14 +436,13 @@
 				   irqs.. */
 
 	if (irq[0]) {
-		printk("irq: %u ", irq[0]);
+		dev_dbg(dev->hw_dev, "irq: %u\n", irq[0]);
 		if (irq[1] && thisboard->num_asics == 2)
-			printk("second ASIC irq: %u ", irq[1]);
+			dev_dbg(dev->hw_dev, "second ASIC irq: %u\n", irq[1]);
 	} else {
-		printk("(IRQ mode disabled) ");
+		dev_dbg(dev->hw_dev, "(IRQ mode disabled)\n");
 	}
 
-	printk("attached\n");
 
 	return 1;
 }
@@ -460,7 +459,8 @@
 {
 	int i;
 
-	printk("comedi%d: %s: remove\n", dev->minor, driver.driver_name);
+	dev_dbg(dev->hw_dev, "comedi%d: %s: remove\n", dev->minor,
+		driver.driver_name);
 	if (dev->iobase)
 		release_region(dev->iobase, ASIC_IOSIZE * thisboard->num_asics);
 
@@ -501,7 +501,8 @@
 
 #ifdef DAMMIT_ITS_BROKEN
 	/* DEBUG */
-	printk("write mask: %08x  data: %08x\n", data[0], data[1]);
+	dev_dbg(dev->hw_dev, "write mask: %08x  data: %08x\n", data[0],
+		data[1]);
 #endif
 
 	s->state = 0;
@@ -537,7 +538,7 @@
 		}
 #ifdef DAMMIT_ITS_BROKEN
 		/* DEBUG */
-		printk("data_out_byte %02x\n", (unsigned)byte);
+		dev_dbg(dev->hw_dev, "data_out_byte %02x\n", (unsigned)byte);
 #endif
 		/* save the digital input lines for this byte.. */
 		s->state |= ((unsigned int)byte) << offset;
@@ -548,7 +549,8 @@
 
 #ifdef DAMMIT_ITS_BROKEN
 	/* DEBUG */
-	printk("s->state %08x data_out %08x\n", s->state, data[1]);
+	dev_dbg(dev->hw_dev, "s->state %08x data_out %08x\n", s->state,
+		data[1]);
 #endif
 
 	return 2;
@@ -951,14 +953,13 @@
 
 	spin_lock_irqsave(&subpriv->intr.spinlock, flags);
 	s->async->inttrig = 0;
-	if (subpriv->intr.active) {
+	if (subpriv->intr.active)
 		event = pcmuio_start_intr(dev, s);
-	}
+
 	spin_unlock_irqrestore(&subpriv->intr.spinlock, flags);
 
-	if (event) {
+	if (event)
 		comedi_event(dev, s);
-	}
 
 	return 1;
 }
@@ -1000,9 +1001,8 @@
 	}
 	spin_unlock_irqrestore(&subpriv->intr.spinlock, flags);
 
-	if (event) {
+	if (event)
 		comedi_event(dev, s);
-	}
 
 	return 0;
 }
diff --git a/drivers/staging/comedi/drivers/serial2002.c b/drivers/staging/comedi/drivers/serial2002.c
index ade2202..d880c2f 100644
--- a/drivers/staging/comedi/drivers/serial2002.c
+++ b/drivers/staging/comedi/drivers/serial2002.c
@@ -824,7 +824,7 @@
 {
 	struct comedi_subdevice *s;
 
-	printk("comedi%d: serial2002: ", dev->minor);
+	dev_dbg(dev->hw_dev, "comedi%d: attached\n", dev->minor);
 	dev->board_name = thisboard->name;
 	if (alloc_private(dev, sizeof(struct serial2002_private)) < 0)
 		return -ENOMEM;
@@ -832,7 +832,8 @@
 	dev->close = serial_2002_close;
 	devpriv->port = it->options[0];
 	devpriv->speed = it->options[1];
-	printk("/dev/ttyS%d @ %d\n", devpriv->port, devpriv->speed);
+	dev_dbg(dev->hw_dev, "/dev/ttyS%d @ %d\n", devpriv->port,
+		devpriv->speed);
 
 	if (alloc_subdevices(dev, 5) < 0)
 		return -ENOMEM;
@@ -891,7 +892,7 @@
 	struct comedi_subdevice *s;
 	int i;
 
-	printk("comedi%d: serial2002: remove\n", dev->minor);
+	dev_dbg(dev->hw_dev, "comedi%d: remove\n", dev->minor);
 	for (i = 0; i < 5; i++) {
 		s = &dev->subdevices[i];
 		kfree(s->maxdata_list);
diff --git a/drivers/staging/comedi/drivers/usbduxsigma.c b/drivers/staging/comedi/drivers/usbduxsigma.c
index 6144afb..ca6bcf8 100644
--- a/drivers/staging/comedi/drivers/usbduxsigma.c
+++ b/drivers/staging/comedi/drivers/usbduxsigma.c
@@ -1524,15 +1524,17 @@
 		return -EFAULT;
 
 	down(&this_usbduxsub->sem);
+
 	if (!(this_usbduxsub->probed)) {
-		up(&this_usbduxsub->sem);
-		return -ENODEV;
+		ret = -ENODEV;
+		goto out;
 	}
 	if (trignum != 0) {
 		dev_err(&this_usbduxsub->interface->dev,
 			"comedi%d: usbdux_ao_inttrig: invalid trignum\n",
 			dev->minor);
-		return -EINVAL;
+		ret = -EINVAL;
+		goto out;
 	}
 	if (!(this_usbduxsub->ao_cmd_running)) {
 		this_usbduxsub->ao_cmd_running = 1;
@@ -1542,8 +1544,7 @@
 				"comedi%d: usbdux_ao_inttrig: submitURB: "
 				"err=%d\n", dev->minor, ret);
 			this_usbduxsub->ao_cmd_running = 0;
-			up(&this_usbduxsub->sem);
-			return ret;
+			goto out;
 		}
 		s->async->inttrig = NULL;
 	} else {
@@ -1551,8 +1552,10 @@
 			"comedi%d: ao_inttrig but acqu is already running.\n",
 			dev->minor);
 	}
+	ret = 1;
+out:
 	up(&this_usbduxsub->sem);
-	return 1;
+	return ret;
 }
 
 static int usbdux_ao_cmdtest(struct comedi_device *dev,
@@ -2689,6 +2692,7 @@
 	if (ret < 0) {
 		dev_err(&udev->interface->dev,
 			"comedi%d: no space for subdev\n", dev->minor);
+		up(&udev->sem);
 		up(&start_stop_sem);
 		return ret;
 	}
diff --git a/drivers/staging/crystalhd/bc_dts_defs.h b/drivers/staging/crystalhd/bc_dts_defs.h
index fde5b06..8cd51a7 100644
--- a/drivers/staging/crystalhd/bc_dts_defs.h
+++ b/drivers/staging/crystalhd/bc_dts_defs.h
@@ -296,43 +296,79 @@
 	vdecColourPrimariesSMPTE240M,
 	vdecColourPrimariesGenericFilm,
 };
-
+/**
+ * @vdecRESOLUTION_CUSTOM: custom
+ * @vdecRESOLUTION_480i: 480i
+ * @vdecRESOLUTION_1080i: 1080i (1920x1080, 60i)
+ * @vdecRESOLUTION_NTSC: NTSC (720x483, 60i)
+ * @vdecRESOLUTION_480p: 480p (720x480, 60p)
+ * @vdecRESOLUTION_720p: 720p (1280x720, 60p)
+ * @vdecRESOLUTION_PAL1: PAL_1 (720x576, 50i)
+ * @vdecRESOLUTION_1080i25: 1080i25 (1920x1080, 50i)
+ * @vdecRESOLUTION_720p50: 720p50 (1280x720, 50p)
+ * @vdecRESOLUTION_576p: 576p (720x576, 50p)
+ * @vdecRESOLUTION_1080i29_97: 1080i (1920x1080, 59.94i)
+ * @vdecRESOLUTION_720p59_94: 720p (1280x720, 59.94p)
+ * @vdecRESOLUTION_SD_DVD: SD DVD (720x483, 60i)
+ * @vdecRESOLUTION_480p656: 480p (720x480, 60p),
+ *	output bus width 8 bit, clock 74.25MHz
+ * @vdecRESOLUTION_1080p23_976: 1080p23_976 (1920x1080, 23.976p)
+ * @vdecRESOLUTION_720p23_976: 720p23_976 (1280x720p, 23.976p)
+ * @vdecRESOLUTION_240p29_97: 240p (1440x240, 29.97p )
+ * @vdecRESOLUTION_240p30: 240p (1440x240, 30p)
+ * @vdecRESOLUTION_288p25: 288p (1440x288p, 25p)
+ * @vdecRESOLUTION_1080p29_97: 1080p29_97 (1920x1080, 29.97p)
+ * @vdecRESOLUTION_1080p30: 1080p30 (1920x1080, 30p)
+ * @vdecRESOLUTION_1080p24: 1080p24 (1920x1080, 24p)
+ * @vdecRESOLUTION_1080p25: 1080p25 (1920x1080, 25p)
+ * @vdecRESOLUTION_720p24: 720p24 (1280x720, 25p)
+ * @vdecRESOLUTION_720p29_97: 720p29.97 (1280x720, 29.97p)
+ * @vdecRESOLUTION_480p23_976: 480p23.976 (720*480, 23.976)
+ * @vdecRESOLUTION_480p29_97: 480p29.976 (720*480, 29.97p)
+ * @vdecRESOLUTION_576p25: 576p25 (720*576, 25p)
+ * @vdecRESOLUTION_480p0: 480p (720x480, 0p)
+ * @vdecRESOLUTION_480i0: 480i (720x480, 0i)
+ * @vdecRESOLUTION_576p0: 576p (720x576, 0p)
+ * @vdecRESOLUTION_720p0: 720p (1280x720, 0p)
+ * @vdecRESOLUTION_1080p0: 1080p (1920x1080, 0p)
+ * @vdecRESOLUTION_1080i0: 1080i (1920x1080, 0i)
+ */
 enum {
-	vdecRESOLUTION_CUSTOM	= 0x00000000, /* custom */
-	vdecRESOLUTION_480i	= 0x00000001, /* 480i */
-	vdecRESOLUTION_1080i	= 0x00000002, /* 1080i (1920x1080, 60i) */
-	vdecRESOLUTION_NTSC	= 0x00000003, /* NTSC (720x483, 60i) */
-	vdecRESOLUTION_480p	= 0x00000004, /* 480p (720x480, 60p) */
-	vdecRESOLUTION_720p	= 0x00000005, /* 720p (1280x720, 60p) */
-	vdecRESOLUTION_PAL1	= 0x00000006, /* PAL_1 (720x576, 50i) */
-	vdecRESOLUTION_1080i25	= 0x00000007, /* 1080i25 (1920x1080, 50i) */
-	vdecRESOLUTION_720p50	= 0x00000008, /* 720p50 (1280x720, 50p) */
-	vdecRESOLUTION_576p	= 0x00000009, /* 576p (720x576, 50p) */
-	vdecRESOLUTION_1080i29_97 = 0x0000000A, /* 1080i (1920x1080, 59.94i) */
-	vdecRESOLUTION_720p59_94  = 0x0000000B, /* 720p (1280x720, 59.94p) */
-	vdecRESOLUTION_SD_DVD	= 0x0000000C, /* SD DVD (720x483, 60i) */
-	vdecRESOLUTION_480p656	= 0x0000000D, /* 480p (720x480, 60p), output bus width 8 bit, clock 74.25MHz */
-	vdecRESOLUTION_1080p23_976 = 0x0000000E, /* 1080p23_976 (1920x1080, 23.976p) */
-	vdecRESOLUTION_720p23_976  = 0x0000000F, /* 720p23_976 (1280x720p, 23.976p) */
-	vdecRESOLUTION_240p29_97   = 0x00000010, /* 240p (1440x240, 29.97p ) */
-	vdecRESOLUTION_240p30	= 0x00000011, /* 240p (1440x240, 30p) */
-	vdecRESOLUTION_288p25	= 0x00000012, /* 288p (1440x288p, 25p) */
-	vdecRESOLUTION_1080p29_97 = 0x00000013, /* 1080p29_97 (1920x1080, 29.97p) */
-	vdecRESOLUTION_1080p30	= 0x00000014, /* 1080p30 (1920x1080, 30p) */
-	vdecRESOLUTION_1080p24	= 0x00000015, /* 1080p24 (1920x1080, 24p) */
-	vdecRESOLUTION_1080p25	= 0x00000016, /* 1080p25 (1920x1080, 25p) */
-	vdecRESOLUTION_720p24	= 0x00000017, /* 720p24 (1280x720, 25p) */
-	vdecRESOLUTION_720p29_97  = 0x00000018, /* 720p29.97 (1280x720, 29.97p) */
-	vdecRESOLUTION_480p23_976 = 0x00000019, /* 480p23.976 (720*480, 23.976) */
-	vdecRESOLUTION_480p29_97  = 0x0000001A, /* 480p29.976 (720*480, 29.97p) */
-	vdecRESOLUTION_576p25	= 0x0000001B, /* 576p25 (720*576, 25p) */
+	vdecRESOLUTION_CUSTOM	= 0x00000000,
+	vdecRESOLUTION_480i	= 0x00000001,
+	vdecRESOLUTION_1080i	= 0x00000002,
+	vdecRESOLUTION_NTSC	= 0x00000003,
+	vdecRESOLUTION_480p	= 0x00000004,
+	vdecRESOLUTION_720p	= 0x00000005,
+	vdecRESOLUTION_PAL1	= 0x00000006,
+	vdecRESOLUTION_1080i25	= 0x00000007,
+	vdecRESOLUTION_720p50	= 0x00000008,
+	vdecRESOLUTION_576p	= 0x00000009,
+	vdecRESOLUTION_1080i29_97 = 0x0000000A,
+	vdecRESOLUTION_720p59_94  = 0x0000000B,
+	vdecRESOLUTION_SD_DVD	= 0x0000000C,
+	vdecRESOLUTION_480p656	= 0x0000000D,
+	vdecRESOLUTION_1080p23_976 = 0x0000000E,
+	vdecRESOLUTION_720p23_976  = 0x0000000F,
+	vdecRESOLUTION_240p29_97   = 0x00000010,
+	vdecRESOLUTION_240p30	= 0x00000011,
+	vdecRESOLUTION_288p25	= 0x00000012,
+	vdecRESOLUTION_1080p29_97 = 0x00000013,
+	vdecRESOLUTION_1080p30	= 0x00000014,
+	vdecRESOLUTION_1080p24	= 0x00000015,
+	vdecRESOLUTION_1080p25	= 0x00000016,
+	vdecRESOLUTION_720p24	= 0x00000017,
+	vdecRESOLUTION_720p29_97  = 0x00000018,
+	vdecRESOLUTION_480p23_976 = 0x00000019,
+	vdecRESOLUTION_480p29_97  = 0x0000001A,
+	vdecRESOLUTION_576p25	= 0x0000001B,
 	/* For Zero Frame Rate */
-	vdecRESOLUTION_480p0	= 0x0000001C, /* 480p (720x480, 0p) */
-	vdecRESOLUTION_480i0	= 0x0000001D, /* 480i (720x480, 0i) */
-	vdecRESOLUTION_576p0	= 0x0000001E, /* 576p (720x576, 0p) */
-	vdecRESOLUTION_720p0	= 0x0000001F, /* 720p (1280x720, 0p) */
-	vdecRESOLUTION_1080p0	= 0x00000020, /* 1080p (1920x1080, 0p) */
-	vdecRESOLUTION_1080i0	= 0x00000021, /* 1080i (1920x1080, 0i) */
+	vdecRESOLUTION_480p0	= 0x0000001C,
+	vdecRESOLUTION_480i0	= 0x0000001D,
+	vdecRESOLUTION_576p0	= 0x0000001E,
+	vdecRESOLUTION_720p0	= 0x0000001F,
+	vdecRESOLUTION_1080p0	= 0x00000020,
+	vdecRESOLUTION_1080i0	= 0x00000021,
 };
 
 /* Bit definitions for 'flags' field */
@@ -359,14 +395,23 @@
 	MODE422_YUY2			= 0x1,
 	MODE422_UYVY			= 0x2,
 };
-
+/**
+ * struct BC_PIC_INFO_BLOCK
+ * @timeStam;: Timestamp
+ * @picture_number: Ordinal display number
+ * @width:  pixels
+ * @height:  pixels
+ * @chroma_format:  0x420, 0x422 or 0x444
+ * @n_drop;:  number of non-reference frames
+ *	remaining to be dropped
+ */
 struct BC_PIC_INFO_BLOCK {
 	/* Common fields. */
-	uint64_t	timeStamp;	/* Timestamp */
-	uint32_t	picture_number;	/* Ordinal display number  */
-	uint32_t	width;		/* pixels	    */
-	uint32_t	height;		/* pixels	    */
-	uint32_t	chroma_format;	/* 0x420, 0x422 or 0x444 */
+	uint64_t	timeStamp;
+	uint32_t	picture_number;
+	uint32_t	width;
+	uint32_t	height;
+	uint32_t	chroma_format;
 	uint32_t	pulldown;
 	uint32_t	flags;
 	uint32_t	frame_rate;
@@ -376,7 +421,8 @@
 	uint32_t	sess_num;
 	uint32_t	ycom;
 	uint32_t	custom_aspect_ratio_width_height;
-	uint32_t	n_drop;	/* number of non-reference frames remaining to be dropped */
+	uint32_t	n_drop;	/* number of non-reference frames
+					remaining to be dropped */
 
 	/* Protocol-specific extensions. */
 	union {
@@ -390,43 +436,71 @@
 /*------------------------------------------------------*
  *    ProcOut Info					*
  *------------------------------------------------------*/
-/* Optional flags for ProcOut Interface.*/
+
+/**
+ * enum POUT_OPTIONAL_IN_FLAGS - Optional flags for ProcOut Interface.
+ * @BC_POUT_FLAGS_YV12:  Copy Data in YV12 format
+ * @BC_POUT_FLAGS_STRIDE:  Stride size is valid.
+ * @BC_POUT_FLAGS_SIZE:  Take size information from Application
+ * @BC_POUT_FLAGS_INTERLACED:  copy only half the bytes
+ * @BC_POUT_FLAGS_INTERLEAVED:  interleaved frame
+ * @:  * @BC_POUT_FLAGS_FMT_CHANGE:  Data is not VALID when this flag is set
+ * @BC_POUT_FLAGS_PIB_VALID:  PIB Information valid
+ * @BC_POUT_FLAGS_ENCRYPTED:  Data is encrypted.
+ * @BC_POUT_FLAGS_FLD_BOT:  Bottom Field data
+ */
 enum POUT_OPTIONAL_IN_FLAGS_ {
 	/* Flags from App to Device */
-	BC_POUT_FLAGS_YV12	  = 0x01,	/* Copy Data in YV12 format */
-	BC_POUT_FLAGS_STRIDE	  = 0x02,	/* Stride size is valid. */
-	BC_POUT_FLAGS_SIZE	  = 0x04,	/* Take size information from Application */
-	BC_POUT_FLAGS_INTERLACED  = 0x08,	/* copy only half the bytes */
-	BC_POUT_FLAGS_INTERLEAVED = 0x10,	/* interleaved frame */
+	BC_POUT_FLAGS_YV12	  = 0x01,
+	BC_POUT_FLAGS_STRIDE	  = 0x02,
+	BC_POUT_FLAGS_SIZE	  = 0x04,
+	BC_POUT_FLAGS_INTERLACED  = 0x08,
+	BC_POUT_FLAGS_INTERLEAVED = 0x10,
 
 	/* Flags from Device to APP */
-	BC_POUT_FLAGS_FMT_CHANGE  = 0x10000,	/* Data is not VALID when this flag is set */
-	BC_POUT_FLAGS_PIB_VALID	  = 0x20000,	/* PIB Information valid */
-	BC_POUT_FLAGS_ENCRYPTED	  = 0x40000,	/* Data is encrypted. */
-	BC_POUT_FLAGS_FLD_BOT	  = 0x80000,	/* Bottom Field data */
+	BC_POUT_FLAGS_FMT_CHANGE  = 0x10000,
+	BC_POUT_FLAGS_PIB_VALID	  = 0x20000,
+	BC_POUT_FLAGS_ENCRYPTED	  = 0x40000,
+	BC_POUT_FLAGS_FLD_BOT	  = 0x80000,
 };
 
-typedef enum BC_STATUS(*dts_pout_callback)(void  *shnd, uint32_t width, uint32_t height, uint32_t stride, void *pOut);
+typedef enum BC_STATUS(*dts_pout_callback)(void  *shnd, uint32_t width,
+			uint32_t height, uint32_t stride, void *pOut);
 
 /* Line 21 Closed Caption */
 /* User Data */
 #define MAX_UD_SIZE		1792	/* 1920 - 128 */
 
+/**
+ * struct BC_DTS_PROC_OUT
+ * @Ybuff: Caller Supplied buffer for Y data
+ * @YbuffSz: Caller Supplied Y buffer size
+ * @YBuffDoneSz: Transferred Y datasize
+ * @*UVbuff: Caller Supplied buffer for UV data
+ * @UVbuffSz: Caller Supplied UV buffer size
+ * @UVBuffDoneSz: Transferred UV data size
+ * @StrideSz: Caller supplied Stride Size
+ * @PoutFlags: Call IN Flags
+ * @discCnt: Picture discontinuity count
+ * @PicInfo: Picture Information Block Data
+ * @b422Mode: Picture output Mode
+ * @bPibEnc: PIB encrypted
+ */
 struct BC_DTS_PROC_OUT {
-	uint8_t		*Ybuff;			/* Caller Supplied buffer for Y data */
-	uint32_t	YbuffSz;		/* Caller Supplied Y buffer size */
-	uint32_t	YBuffDoneSz;		/* Transferred Y datasize */
+	uint8_t		*Ybuff;
+	uint32_t	YbuffSz;
+	uint32_t	YBuffDoneSz;
 
-	uint8_t		*UVbuff;		/* Caller Supplied buffer for UV data */
-	uint32_t	UVbuffSz;		/* Caller Supplied UV buffer size */
-	uint32_t	UVBuffDoneSz;		/* Transferred UV data size */
+	uint8_t		*UVbuff;
+	uint32_t	UVbuffSz;
+	uint32_t	UVBuffDoneSz;
 
-	uint32_t	StrideSz;		/* Caller supplied Stride Size */
-	uint32_t	PoutFlags;		/* Call IN Flags */
+	uint32_t	StrideSz;
+	uint32_t	PoutFlags;
 
-	uint32_t	discCnt;		/* Picture discontinuity count */
+	uint32_t	discCnt;
 
-	struct BC_PIC_INFO_BLOCK PicInfo;		/* Picture Information Block Data */
+	struct BC_PIC_INFO_BLOCK PicInfo;
 
 	/* Line 21 Closed Caption */
 	/* User Data */
@@ -436,39 +510,47 @@
 	void		*hnd;
 	dts_pout_callback AppCallBack;
 	uint8_t		DropFrames;
-	uint8_t		b422Mode;		/* Picture output Mode */
-	uint8_t		bPibEnc;		/* PIB encrypted */
+	uint8_t		b422Mode;
+	uint8_t		bPibEnc;
 	uint8_t		bRevertScramble;
 
 };
-
+/**
+ * struct BC_DTS_STATUS
+ * @ReadyListCount: Number of frames in ready list (reported by driver)
+ * @PowerStateChange: Number of active state power
+ *	transitions (reported by driver)
+ * @FramesDropped:  Number of frames dropped.  (reported by DIL)
+ * @FramesCaptured: Number of frames captured. (reported by DIL)
+ * @FramesRepeated: Number of frames repeated. (reported by DIL)
+ * @InputCount:	Times compressed video has been sent to the HW.
+ *	i.e. Successful DtsProcInput() calls (reported by DIL)
+ * @InputTotalSize: Amount of compressed video that has been sent to the HW.
+ *	(reported by DIL)
+ * @InputBusyCount: Times compressed video has attempted to be sent to the HW
+ *	but the input FIFO was full. (reported by DIL)
+ * @PIBMissCount: Amount of times a PIB is invalid. (reported by DIL)
+ * @cpbEmptySize: supported only for H.264, specifically changed for
+ *	Adobe. Report size of CPB buffer available. (reported by DIL)
+ * @NextTimeStamp: TimeStamp of the next picture that will be returned
+ *	by a call to ProcOutput. Added for Adobe. Reported
+ *	back from the driver
+ */
 struct BC_DTS_STATUS {
-	uint8_t		ReadyListCount;	/* Number of frames in ready list (reported by driver) */
-	uint8_t		FreeListCount;	/* Number of frame buffers free.  (reported by driver) */
-	uint8_t		PowerStateChange; /* Number of active state power transitions (reported by driver) */
+	uint8_t		ReadyListCount;
+	uint8_t		FreeListCount;
+	uint8_t		PowerStateChange;
 	uint8_t		reserved_[1];
-
-	uint32_t	FramesDropped;	/* Number of frames dropped.  (reported by DIL) */
-	uint32_t	FramesCaptured;	/* Number of frames captured. (reported by DIL) */
-	uint32_t	FramesRepeated;	/* Number of frames repeated. (reported by DIL) */
-
-	uint32_t	InputCount;	/* Times compressed video has been sent to the HW.
-					 * i.e. Successful DtsProcInput() calls (reported by DIL) */
-	uint64_t	InputTotalSize;	/* Amount of compressed video that has been sent to the HW.
-					 * (reported by DIL) */
-	uint32_t	InputBusyCount;	/* Times compressed video has attempted to be sent to the HW
-					 * but the input FIFO was full. (reported by DIL) */
-
-	uint32_t	PIBMissCount;	/* Amount of times a PIB is invalid. (reported by DIL) */
-
-	uint32_t	cpbEmptySize;	/* supported only for H.264, specifically changed for
-					 * Adobe. Report size of CPB buffer available.
-					 * Reported by DIL */
-	uint64_t	NextTimeStamp;	/* TimeStamp of the next picture that will be returned
-					 * by a call to ProcOutput. Added for Adobe. Reported
-					 * back from the driver */
+	uint32_t	FramesDropped;
+	uint32_t	FramesCaptured;
+	uint32_t	FramesRepeated;
+	uint32_t	InputCount;
+	uint64_t	InputTotalSize;
+	uint32_t	InputBusyCount;
+	uint32_t	PIBMissCount;
+	uint32_t	cpbEmptySize;
+	uint64_t	NextTimeStamp;
 	uint8_t		reserved__[16];
-
 };
 
 #define BC_SWAP32(_v)			\
diff --git a/drivers/staging/cxt1e1/comet.h b/drivers/staging/cxt1e1/comet.h
index 5cb3afd..e06da4a 100644
--- a/drivers/staging/cxt1e1/comet.h
+++ b/drivers/staging/cxt1e1/comet.h
@@ -1,7 +1,3 @@
-/*
- * $Id: comet.h,v 1.3 2005/09/28 00:10:07 rickd PMCC4_3_1B $
- */
-
 #ifndef _INC_COMET_H_
 #define _INC_COMET_H_
 
@@ -23,27 +19,9 @@
  * For further information, contact via email: support@sbei.com
  * SBE, Inc.  San Ramon, California  U.S.A.
  *-----------------------------------------------------------------------------
- * RCS info:
- * RCS revision: $Revision: 1.3 $
- * Last changed on $Date: 2005/09/28 00:10:07 $
- * Changed by $Author: rickd $
- *-----------------------------------------------------------------------------
- * $Log: comet.h,v $
- * Revision 1.3  2005/09/28 00:10:07  rickd
- * Add RCS header. Switch to structure usage.
- *
- * Revision 1.2  2005/04/28 23:43:03  rickd
- * Add RCS tracking heading.
- *
- *-----------------------------------------------------------------------------
  */
 
-#if defined(__FreeBSD__) || defined (__NetBSD__)
-#include <sys/types.h>
-#else
 #include <linux/types.h>
-#endif
-
 
 #define VINT32  volatile u_int32_t
 
diff --git a/drivers/staging/cxt1e1/comet_tables.c b/drivers/staging/cxt1e1/comet_tables.c
index db1293c..8493111 100644
--- a/drivers/staging/cxt1e1/comet_tables.c
+++ b/drivers/staging/cxt1e1/comet_tables.c
@@ -1,7 +1,3 @@
-/*
- * $Id: comet_tables.c,v 1.2 2005/10/17 23:55:27 rickd PMCC4_3_1B $
- */
-
 /*-----------------------------------------------------------------------------
  * comet_tables.c - waveform tables for the PM4351 'COMET'
  *
@@ -20,28 +16,8 @@
  * For further information, contact via email: support@sbei.com
  * SBE, Inc.  San Ramon, California  U.S.A.
  *-----------------------------------------------------------------------------
- * RCS info:
- * RCS revision: $Revision: 1.2 $
- * Last changed on $Date: 2005/10/17 23:55:27 $
- * Changed by $Author: rickd $
- *-----------------------------------------------------------------------------
- * $Log: comet_tables.c,v $
- * Revision 1.2  2005/10/17 23:55:27  rickd
- * Note that 75 Ohm transmit waveform is not supported on PMCC4.
- *
- * Revision 1.1  2005/09/28 00:10:05  rickd
- * Cosmetic alignment of tables for readability.
- *
- * Revision 1.0  2005/05/10 22:47:53  rickd
- * Initial revision
- *
- *-----------------------------------------------------------------------------
  */
 
-char SBEid_pmcc4_comet_tblc[] =
-  "@(#)comet_tables.c - $Revision: 1.2 $      (c) Copyright 2004-2005 SBE, Inc.";
-
-
 #include <linux/types.h>
 
 /*****************************************************************************
diff --git a/drivers/staging/cxt1e1/comet_tables.h b/drivers/staging/cxt1e1/comet_tables.h
index 80424a2..3e2e5ba 100644
--- a/drivers/staging/cxt1e1/comet_tables.h
+++ b/drivers/staging/cxt1e1/comet_tables.h
@@ -1,7 +1,3 @@
-/*
- * $Id: comet_tables.h,v 1.5 2006/01/02 22:37:31 rickd PMCC4_3_1B $
- */
-
 #ifndef _INC_COMET_TBLS_H_
 #define _INC_COMET_TBLS_H_
 
@@ -23,26 +19,6 @@
  * For further information, contact via email: support@sbei.com
  * SBE, Inc.  San Ramon, California  U.S.A.
  *-----------------------------------------------------------------------------
- * RCS info:
- * RCS revision: $Revision: 1.5 $
- * Last changed on $Date: 2006/01/02 22:37:31 $
- * Changed by $Author: rickd $
- *-----------------------------------------------------------------------------
- * $Log: comet_tables.h,v $
- * Revision 1.5  2006/01/02 22:37:31  rickd
- * Double indexed arrays need sizings to avoid CC errors under
- * gcc 4.0.0
- *
- * Revision 1.4  2005/10/17 23:55:28  rickd
- * The 75 Ohm transmit waveform is not supported on PMCC4.
- *
- * Revision 1.3  2005/09/28 00:10:08  rickd
- * Add GNU License info. Structures moved to -C- file.
- *
- * Revision 1.2  2005/04/28 23:43:04  rickd
- * Add RCS tracking heading.
- *
- *-----------------------------------------------------------------------------
  */
 
 
diff --git a/drivers/staging/cxt1e1/libsbew.h b/drivers/staging/cxt1e1/libsbew.h
index ae8f06d..4254c04 100644
--- a/drivers/staging/cxt1e1/libsbew.h
+++ b/drivers/staging/cxt1e1/libsbew.h
@@ -1,7 +1,3 @@
-/*
- * $Id: libsbew.h,v 2.1 2005/10/27 18:54:19 rickd PMCC4_3_1B $
- */
-
 #ifndef _INC_LIBSBEW_H_
 #define _INC_LIBSBEW_H_
 
@@ -25,32 +21,8 @@
  * For further information, contact via email: support@sbei.com
  * SBE, Inc.  San Ramon, California  U.S.A.
  *-----------------------------------------------------------------------------
- * RCS info:
- * RCS revision: $Revision: 2.1 $
- * Last changed on $Date: 2005/10/27 18:54:19 $
- * Changed by $Author: rickd $
- *-----------------------------------------------------------------------------
- * $Log: libsbew.h,v $
- * Revision 2.1  2005/10/27 18:54:19  rickd
- * Add E1PLAIN support.
- *
- * Revision 2.0  2005/09/28 00:10:08  rickd
- * Customized for PMCC4 comet-per-port design.
- *
- * Revision 1.15  2005/03/29 00:51:31  rickd
- * File imported from C1T3 port, Revision 1.15
- *-----------------------------------------------------------------------------
  */
 
-#ifndef __KERNEL__
-#include <sys/types.h>
-#endif
-
-#ifdef __cplusplus
-extern      "C"
-{
-#endif
-
 /********************************/
 /**  set driver logging level  **/
 /********************************/
@@ -574,8 +546,4 @@
     extern int  wancfg_set_tsioc (wcfg_t *, struct wanc1t3_ts_param *);
 #endif
 
-#ifdef __cplusplus
-}
-#endif
-
 #endif                          /*** _INC_LIBSBEW_H_ ***/
diff --git a/drivers/staging/cxt1e1/musycc.c b/drivers/staging/cxt1e1/musycc.c
index 5cc3423..90c0f1e 100644
--- a/drivers/staging/cxt1e1/musycc.c
+++ b/drivers/staging/cxt1e1/musycc.c
@@ -1,7 +1,3 @@
-/*
- * $Id: musycc.c,v 2.1 2007/08/15 23:32:17 rickd PMCC4_3_1B $
- */
-
 unsigned int max_intcnt = 0;
 unsigned int max_bh = 0;
 
@@ -24,53 +20,8 @@
  * For further information, contact via email: support@onestopsystems.com
  * One Stop Systems, Inc.  Escondido, California  U.S.A.
  *-----------------------------------------------------------------------------
- * RCS info:
- * RCS revision: $Revision: 2.1 $
- * Last changed on $Date: 2007/08/15 23:32:17 $
- * Changed by $Author: rickd $
- *-----------------------------------------------------------------------------
- * $Log: musycc.c,v $
- * Revision 2.1  2007/08/15 23:32:17  rickd
- * Use 'if 0' instead of GNU comment delimeter to avoid line wrap induced compiler errors.
- *
- * Revision 2.0  2007/08/15 22:13:20  rickd
- * Update to printf pointer %p usage and correct some UINT to ULONG for
- * 64bit comptibility.
- *
- * Revision 1.7  2006/04/21 00:56:40  rickd
- * workqueue files now prefixed with <sbecom> prefix.
- *
- * Revision 1.6  2005/10/27 18:54:19  rickd
- * Clean out old code.  Default to HDLC_FCS16, not TRANS.
- *
- * Revision 1.5  2005/10/17 23:55:28  rickd
- * Initial port of NCOMM support patches from original work found
- * in pmc_c4t1e1 as updated by NCOMM.  Ref: CONFIG_SBE_PMCC4_NCOMM.
- *
- * Revision 1.4  2005/10/13 20:35:25  rickd
- * Cleanup warning for unused <flags> variable.
- *
- * Revision 1.3  2005/10/13 19:19:22  rickd
- * Disable redundant driver removal cleanup code.
- *
- * Revision 1.2  2005/10/11 18:36:16  rickd
- * Clean up warning messages caused by de-implemented some <flags> associated
- * with spin_lock() removals.
- *
- * Revision 1.1  2005/10/05 00:45:28  rickd
- * Re-enable xmit on flow-controlled and full channel to fix restart hang.
- * Add some temp spin-lock debug code (rld_spin_owner).
- *
- * Revision 1.0  2005/09/28 00:10:06  rickd
- * Initial release for C4T1E1 support. Lots of transparent
- * mode updates.
- *
- *-----------------------------------------------------------------------------
  */
 
-char        SBEid_pmcc4_musyccc[] =
-"@(#)musycc.c - $Revision: 2.1 $      (c) Copyright 2004-2006 SBE, Inc.";
-
 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
 
 #include <linux/types.h>
diff --git a/drivers/staging/cxt1e1/musycc.h b/drivers/staging/cxt1e1/musycc.h
index 68f3660..cf6b54e 100644
--- a/drivers/staging/cxt1e1/musycc.h
+++ b/drivers/staging/cxt1e1/musycc.h
@@ -1,7 +1,3 @@
-/*
- * $Id: musycc.h,v 1.3 2005/09/28 00:10:08 rickd PMCC4_3_1B $
- */
-
 #ifndef _INC_MUSYCC_H_
 #define _INC_MUSYCC_H_
 
@@ -24,36 +20,13 @@
  * For further information, contact via email: support@sbei.com
  * SBE, Inc.  San Ramon, California  U.S.A.
  *-----------------------------------------------------------------------------
- * RCS info:
- * RCS revision: $Revision: 1.3 $
- * Last changed on $Date: 2005/09/28 00:10:08 $
- * Changed by $Author: rickd $
- *-----------------------------------------------------------------------------
- * $Log: musycc.h,v $
- * Revision 1.3  2005/09/28 00:10:08  rickd
- * Add GNU license info. Add PMCC4 PCI/DevIDs.  Implement new
- * musycc reg&bits namings. Use PORTMAP_0 GCD grouping.
- *
- * Revision 1.2  2005/04/28 23:43:04  rickd
- * Add RCS tracking heading.
- *
- *-----------------------------------------------------------------------------
  */
 
-#if defined (__FreeBSD__) || defined (__NetBSD__)
-#include <sys/types.h>
-#else
 #include <linux/types.h>
-#endif
 
 #define VINT8   volatile u_int8_t
 #define VINT32  volatile u_int32_t
 
-#ifdef __cplusplus
-extern      "C"
-{
-#endif
-
 #include "pmcc4_defs.h"
 
 
@@ -448,10 +421,6 @@
 /*  This must be defined on an entire channel group (Port) basis */
 #define SUERM_THRESHOLD     0x1f
 
-#ifdef __cplusplus
-}
-#endif
-
 #undef VINT32
 #undef VINT8
 
diff --git a/drivers/staging/cxt1e1/ossiRelease.c b/drivers/staging/cxt1e1/ossiRelease.c
index a560298..f17a902 100644
--- a/drivers/staging/cxt1e1/ossiRelease.c
+++ b/drivers/staging/cxt1e1/ossiRelease.c
@@ -1,7 +1,3 @@
-/*
- * $Id: ossiRelease.c,v 1.2 2008/05/08 20:14:03 rdobbs PMCC4_3_1B $
- */
-
 /*-----------------------------------------------------------------------------
  * ossiRelease.c -
  *
@@ -26,14 +22,8 @@
  * One Stop Systems, Inc.  Escondido, California  U.S.A.
  *
  *-----------------------------------------------------------------------------
- * RCS info:
- * RCS revision: $Revision: 1.2 $
- * Last changed on $Date: 2008/05/08 20:14:03 $
- * Changed by $Author: rdobbs $
- *-----------------------------------------------------------------------------
  */
 
-
 char pmcc4_OSSI_release[] = "$Release: PMCC4_3_1B,  Copyright (c) 2008 One Stop Systems$";
 
 /***  End-of-File  ***/
diff --git a/drivers/staging/cxt1e1/pmc93x6_eeprom.h b/drivers/staging/cxt1e1/pmc93x6_eeprom.h
index c3ada87..96c48cb 100644
--- a/drivers/staging/cxt1e1/pmc93x6_eeprom.h
+++ b/drivers/staging/cxt1e1/pmc93x6_eeprom.h
@@ -1,7 +1,3 @@
-/*
- * $Id: pmc93x6_eeprom.h,v 1.1 2005/09/28 00:10:08 rickd PMCC4_3_1B $
- */
-
 #ifndef _INC_PMC93X6_EEPROM_H_
 #define _INC_PMC93X6_EEPROM_H_
 
@@ -23,26 +19,9 @@
  * For further information, contact via email: support@sbei.com
  * SBE, Inc.  San Ramon, California  U.S.A.
  *-----------------------------------------------------------------------------
- * RCS info:
- *-----------------------------------------------------------------------------
- * $Log: pmc93x6_eeprom.h,v $
- * Revision 1.1  2005/09/28 00:10:08  rickd
- * pmc_verify_cksum return value is char.
- *
- * Revision 1.0  2005/05/04 17:20:51  rickd
- * Initial revision
- *
- * Revision 1.0  2005/04/22 23:48:48  rickd
- * Initial revision
- *
- *-----------------------------------------------------------------------------
  */
 
-#if defined (__FreeBSD__) || defined (__NetBSD__)
-#include <sys/types.h>
-#else
 #include <linux/types.h>
-#endif
 
 #ifdef __KERNEL__
 
diff --git a/drivers/staging/cxt1e1/pmcc4.h b/drivers/staging/cxt1e1/pmcc4.h
index e046b87..b0ed4ad 100644
--- a/drivers/staging/cxt1e1/pmcc4.h
+++ b/drivers/staging/cxt1e1/pmcc4.h
@@ -1,7 +1,3 @@
-/*
- * $Id: pmcc4.h,v 1.4 2005/11/01 19:24:48 rickd PMCC4_3_1B $
- */
-
 #ifndef _INC_PMCC4_H_
 #define _INC_PMCC4_H_
 
@@ -23,49 +19,15 @@
  * For further information, contact via email: support@sbei.com
  * SBE, Inc.  San Ramon, California  U.S.A.
  *-----------------------------------------------------------------------------
- * RCS info:
- * RCS revision: $Revision: 1.4 $
- * Last changed on $Date: 2005/11/01 19:24:48 $
- * Changed by $Author: rickd $
- *-----------------------------------------------------------------------------
- * $Log: pmcc4.h,v $
- * Revision 1.4  2005/11/01 19:24:48  rickd
- * Remove de-implement function prototypes.  Several <int> to
- * <status_t> changes for consistent usage of same.
- *
- * Revision 1.3  2005/09/28 00:10:08  rickd
- * Add GNU license info. Use config params from libsbew.h
- *
- * Revision 1.2  2005/04/28 23:43:03  rickd
- * Add RCS tracking heading.
- *
- *-----------------------------------------------------------------------------
  */
 
-
-#if defined(__FreeBSD__) || defined(__NetBSD__)
-#include <sys/types.h>
-#else
-#ifndef __KERNEL__
-#include <sys/types.h>
-#else
 #include <linux/types.h>
-#endif
-#endif
-
-
 
 typedef int status_t;
 
 #define SBE_DRVR_FAIL     0
 #define SBE_DRVR_SUCCESS  1
 
-#ifdef __cplusplus
-extern      "C"
-{
-#endif
-
-
 /********************/
 /* PMCC4 memory Map */
 /********************/
@@ -105,10 +67,6 @@
 #define sbeE1errSMF    0x02
 #define sbeE1CRC       0x01
 
-#ifdef __cplusplus
-}
-#endif
-
 #ifdef __KERNEL__
 
 /*
diff --git a/drivers/staging/cxt1e1/pmcc4_cpld.h b/drivers/staging/cxt1e1/pmcc4_cpld.h
index 6d8f033..a51209b 100644
--- a/drivers/staging/cxt1e1/pmcc4_cpld.h
+++ b/drivers/staging/cxt1e1/pmcc4_cpld.h
@@ -1,7 +1,3 @@
-/*
- * $Id: pmcc4_cpld.h,v 1.0 2005/09/28 00:10:08 rickd PMCC4_3_1B $
- */
-
 #ifndef _INC_PMCC4_CPLD_H_
 #define _INC_PMCC4_CPLD_H_
 
@@ -23,34 +19,9 @@
  * For further information, contact via email: support@sbei.com
  * SBE, Inc.  San Ramon, California  U.S.A.
  *-----------------------------------------------------------------------------
- * RCS info:
- * RCS revision: $Revision: 1.0 $
- * Last changed on $Date: 2005/09/28 00:10:08 $
- * Changed by $Author: rickd $
- *-----------------------------------------------------------------------------
- * $Log: pmcc4_cpld.h,v $
- * Revision 1.0  2005/09/28 00:10:08  rickd
- * Initial revision
- *
- *-----------------------------------------------------------------------------
  */
 
-
-#if defined(__FreeBSD__) || defined(__NetBSD__)
-#include <sys/types.h>
-#else
-#ifndef __KERNEL__
-#include <sys/types.h>
-#else
 #include <linux/types.h>
-#endif
-#endif
-
-#ifdef __cplusplus
-extern      "C"
-{
-#endif
-
 
 /********************************/
 /* iSPLD control chip registers */
@@ -117,8 +88,4 @@
 #define PMCC4_CPLD_INTR_CMT_3   0x04
 #define PMCC4_CPLD_INTR_CMT_4   0x08
 
-#ifdef __cplusplus
-}
-#endif
-
 #endif                          /* _INC_PMCC4_CPLD_H_ */
diff --git a/drivers/staging/cxt1e1/pmcc4_defs.h b/drivers/staging/cxt1e1/pmcc4_defs.h
index a39505f..83ceae4 100644
--- a/drivers/staging/cxt1e1/pmcc4_defs.h
+++ b/drivers/staging/cxt1e1/pmcc4_defs.h
@@ -1,7 +1,3 @@
-/*
- * $Id: pmcc4_defs.h,v 1.0 2005/09/28 00:10:09 rickd PMCC4_3_1B $
- */
-
 #ifndef _INC_PMCC4_DEFS_H_
 #define _INC_PMCC4_DEFS_H_
 
@@ -25,16 +21,6 @@
  * For further information, contact via email: support@sbei.com
  * SBE, Inc.  San Ramon, California  U.S.A.
  *-----------------------------------------------------------------------------
- * RCS info:
- * RCS revision: $Revision: 1.0 $
- * Last changed on $Date: 2005/09/28 00:10:09 $
- * Changed by $Author: rickd $
- *-----------------------------------------------------------------------------
- * $Log: pmcc4_defs.h,v $
- * Revision 1.0  2005/09/28 00:10:09  rickd
- * Initial revision
- *
- *-----------------------------------------------------------------------------
  */
 
 
diff --git a/drivers/staging/cxt1e1/pmcc4_drv.c b/drivers/staging/cxt1e1/pmcc4_drv.c
index e1f07fa..8a7b3a6 100644
--- a/drivers/staging/cxt1e1/pmcc4_drv.c
+++ b/drivers/staging/cxt1e1/pmcc4_drv.c
@@ -1,8 +1,3 @@
-/*
- * $Id: pmcc4_drv.c,v 3.1 2007/08/15 23:32:17 rickd PMCC4_3_1B $
- */
-
-
 /*-----------------------------------------------------------------------------
  * pmcc4_drv.c -
  *
@@ -22,74 +17,10 @@
  * For further information, contact via email: support@onestopsystems.com
  * One Stop Systems, Inc.  Escondido, California  U.S.A.
  *-----------------------------------------------------------------------------
- * RCS info:
- * RCS revision: $Revision: 3.1 $
- * Last changed on $Date: 2007/08/15 23:32:17 $
- * Changed by $Author: rickd $
- *-----------------------------------------------------------------------------
- * $Log: pmcc4_drv.c,v $
- * Revision 3.1  2007/08/15 23:32:17  rickd
- * Use 'if 0' instead of GNU comment delimeter to avoid line wrap induced compiler errors.
- *
- * Revision 3.0  2007/08/15 22:19:55  rickd
- * Correct sizeof() castings and pi->regram to support 64bit compatibility.
- *
- * Revision 2.10  2006/04/21 00:56:40  rickd
- * workqueue files now prefixed with <sbecom> prefix.
- *
- * Revision 2.9  2005/11/01 19:22:49  rickd
- * Add sanity checks against max_port for ioctl functions.
- *
- * Revision 2.8  2005/10/27 18:59:25  rickd
- * Code cleanup.  Default channel config to HDLC_FCS16.
- *
- * Revision 2.7  2005/10/18 18:16:30  rickd
- * Further NCOMM code repairs - (1) interrupt matrix usage inconsistent
- * for indexing into nciInterrupt[][], code missing double parameters.
- * (2) check input of ncomm interrupt registration cardID for correct
- * boundary values.
- *
- * Revision 2.6  2005/10/17 23:55:28  rickd
- * Initial port of NCOMM support patches from original work found
- * in pmc_c4t1e1 as updated by NCOMM.  Ref: CONFIG_SBE_PMCC4_NCOMM.
- * Corrected NCOMMs wanpmcC4T1E1_getBaseAddress() to correctly handle
- * multiple boards.
- *
- * Revision 2.5  2005/10/13 23:01:28  rickd
- * Correct panic for illegal address reference w/in get_brdinfo on
- * first_if/last_if name acquistion under Linux 2.6
- *
- * Revision 2.4  2005/10/13 21:20:19  rickd
- * Correction of c4_cleanup() wherein next should be acquired before
- * ci_t structure is free'd.
- *
- * Revision 2.3  2005/10/13 19:20:10  rickd
- * Correct driver removal cleanup code for multiple boards.
- *
- * Revision 2.2  2005/10/11 18:34:04  rickd
- * New routine added to determine number of ports (comets) on board.
- *
- * Revision 2.1  2005/10/05 00:48:13  rickd
- * Add some RX activation trace code.
- *
- * Revision 2.0  2005/09/28 00:10:06  rickd
- * Implement 2.6 workqueue for TX/RX restart.  Correction to
- * hardware register boundary checks allows expanded access of MUSYCC.
- * Implement new musycc reg&bits namings.
- *
- *-----------------------------------------------------------------------------
  */
 
-char        OSSIid_pmcc4_drvc[] =
-"@(#)pmcc4_drv.c - $Revision: 3.1 $   (c) Copyright 2002-2007 One Stop Systems, Inc.";
-
 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
 
-#if defined (__FreeBSD__) || defined (__NetBSD__)
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/errno.h>
-#else
 #include <linux/types.h>
 #include "pmcc4_sysdep.h"
 #include <linux/errno.h>
@@ -98,7 +29,6 @@
 #include <linux/timer.h>        /* include for timer */
 #include <linux/hdlc.h>
 #include <asm/io.h>
-#endif
 
 #include "sbecom_inline_linux.h"
 #include "libsbew.h"
diff --git a/drivers/staging/cxt1e1/pmcc4_ioctls.h b/drivers/staging/cxt1e1/pmcc4_ioctls.h
index 6b8d656..56a1ee3 100644
--- a/drivers/staging/cxt1e1/pmcc4_ioctls.h
+++ b/drivers/staging/cxt1e1/pmcc4_ioctls.h
@@ -1,6 +1,3 @@
-/* RCSid: $Header: /home/rickd/projects/pmcc4/include/pmcc4_ioctls.h,v 2.0 2005/09/28 00:10:09 rickd PMCC4_3_1B $
- */
-
 #ifndef _INC_PMCC4_IOCTLS_H_
 #define _INC_PMCC4_IOCTLS_H_
 
@@ -22,19 +19,6 @@
  * For further information, contact via email: support@sbei.com
  * SBE, Inc.  San Ramon, California  U.S.A.
  *-----------------------------------------------------------------------------
- * RCS info:
- * RCS revision: $Revision: 2.0 $
- * Last changed on $Date: 2005/09/28 00:10:09 $
- * Changed by $Author: rickd $
- *-----------------------------------------------------------------------------
- * $Log: pmcc4_ioctls.h,v $
- * Revision 2.0  2005/09/28 00:10:09  rickd
- * Add GNU license info. Switch Ioctls to sbe_ioc.h usage.
- *
- * Revision 1.2  2005/04/28 23:43:03  rickd
- * Add RCS tracking heading.
- *
- *-----------------------------------------------------------------------------
  */
 
 #include "sbew_ioc.h"
diff --git a/drivers/staging/cxt1e1/sbe_bid.h b/drivers/staging/cxt1e1/sbe_bid.h
index 1f49b40..abc2e55 100644
--- a/drivers/staging/cxt1e1/sbe_bid.h
+++ b/drivers/staging/cxt1e1/sbe_bid.h
@@ -1,7 +1,3 @@
-/*
- * $Id: sbe_bid.h,v 1.0 2005/09/28 00:10:09 rickd PMCC4_3_1B $
- */
-
 #ifndef _INC_SBEBID_H_
 #define _INC_SBEBID_H_
 
@@ -24,16 +20,6 @@
  * SBE, Inc.  San Ramon, California  U.S.A.
  *
  *-----------------------------------------------------------------------------
- * RCS info:
- * RCS revision: $Revision: 1.0 $
- * Last changed on $Date: 2005/09/28 00:10:09 $
- * Changed by $Author: rickd $
- *-----------------------------------------------------------------------------
- * $Log: sbe_bid.h,v $
- * Revision 1.0  2005/09/28 00:10:09  rickd
- * Initial revision
- *
- *-----------------------------------------------------------------------------
  */
 
 #define SBE_BID_REG        0x00000000   /* Board ID Register */
diff --git a/drivers/staging/cxt1e1/sbe_promformat.h b/drivers/staging/cxt1e1/sbe_promformat.h
index 746f81b..aad411d 100644
--- a/drivers/staging/cxt1e1/sbe_promformat.h
+++ b/drivers/staging/cxt1e1/sbe_promformat.h
@@ -1,7 +1,3 @@
-/*
- * $Id: sbe_promformat.h,v 2.2 2005/09/28 00:10:09 rickd PMCC4_3_1B $
- */
-
 #ifndef _INC_SBE_PROMFORMAT_H_
 #define _INC_SBE_PROMFORMAT_H_
 
@@ -24,19 +20,6 @@
  * SBE, Inc.  San Ramon, California  U.S.A.
  *
  *-----------------------------------------------------------------------------
- * RCS info:
- * RCS revision: $Revision: 2.2 $
- * Last changed on $Date: 2005/09/28 00:10:09 $
- * Changed by $Author: rickd $
- *-----------------------------------------------------------------------------
- * $Log: sbe_promformat.h,v $
- * Revision 2.2  2005/09/28 00:10:09  rickd
- * Add EEPROM sample from C4T1E1 board.
- *
- * Revision 2.1  2005/05/04 17:18:24  rickd
- * Initial CI.
- *
- *-----------------------------------------------------------------------------
  */
 
 
@@ -85,12 +68,6 @@
  *
  */
 
-#ifdef __cplusplus
-extern      "C"
-{
-#endif
-
-
 #define STRUCT_OFFSET(type, symbol)  ((long)&(((type *)0)->symbol))
 
 /*------------------------------------------------------------------------
@@ -150,8 +127,4 @@
         FLD_TYPE2   fldType2;
     }           PROMFORMAT;
 
-#ifdef __cplusplus
-}
-#endif
-
 #endif                          /*** _INC_SBE_PROMFORMAT_H_ ***/
diff --git a/drivers/staging/cxt1e1/sbecom_inline_linux.h b/drivers/staging/cxt1e1/sbecom_inline_linux.h
index 9ea2c0c..68ed445 100644
--- a/drivers/staging/cxt1e1/sbecom_inline_linux.h
+++ b/drivers/staging/cxt1e1/sbecom_inline_linux.h
@@ -1,7 +1,3 @@
-/*
- * $Id: sbecom_inline_linux.h,v 1.2 2007/08/15 22:51:35 rickd PMCC4_3_1B $
- */
-
 #ifndef _INC_SBECOM_INLNX_H_
 #define _INC_SBECOM_INLNX_H_
 
@@ -24,22 +20,6 @@
  * For further information, contact via email: support@onestopsystems.com
  * One Stop Systems, Inc.  Escondido, California  U.S.A.
  *-----------------------------------------------------------------------------
- * RCS info:
- * RCS revision: $Revision: 1.2 $
- * Last changed on $Date: 2007/08/15 22:51:35 $
- * Changed by $Author: rickd $
- *-----------------------------------------------------------------------------
- * $Log: sbecom_inline_linux.h,v $
- * Revision 1.2  2007/08/15 22:51:35  rickd
- * Remove duplicate version.h entry.
- *
- * Revision 1.1  2007/08/15 22:50:29  rickd
- * Update linux/config for 2.6.18 and later.
- *
- * Revision 1.0  2005/09/28 00:10:09  rickd
- * Initial revision
- *
- *-----------------------------------------------------------------------------
  */
 
 
diff --git a/drivers/staging/cxt1e1/sbeproc.h b/drivers/staging/cxt1e1/sbeproc.h
index 4aa53f4..e82be6a 100644
--- a/drivers/staging/cxt1e1/sbeproc.h
+++ b/drivers/staging/cxt1e1/sbeproc.h
@@ -1,7 +1,3 @@
-/*
- * $Id: sbeproc.h,v 1.2 2005/10/17 23:55:28 rickd PMCC4_3_1B $
- */
-
 #ifndef _INC_SBEPROC_H_
 #define _INC_SBEPROC_H_
 
@@ -23,22 +19,6 @@
  * For further information, contact via email: support@sbei.com
  * SBE, Inc.  San Ramon, California  U.S.A.
  *-----------------------------------------------------------------------------
- * RCS info:
- * RCS revision: $Revision: 1.2 $
- * Last changed on $Date: 2005/10/17 23:55:28 $
- * Changed by $Author: rickd $
- *-----------------------------------------------------------------------------
- * $Log: sbeproc.h,v $
- * Revision 1.2  2005/10/17 23:55:28  rickd
- * sbecom_proc_brd_init() is an declared an __init function.
- *
- * Revision 1.1  2005/09/28 00:10:09  rickd
- * Remove unneeded inclusion of c4_private.h.
- *
- * Revision 1.0  2005/05/10 22:21:46  rickd
- * Initial check-in.
- *
- *-----------------------------------------------------------------------------
  */
 
 
diff --git a/drivers/staging/cxt1e1/sbew_ioc.h b/drivers/staging/cxt1e1/sbew_ioc.h
index 14d3719..ce9b15c 100644
--- a/drivers/staging/cxt1e1/sbew_ioc.h
+++ b/drivers/staging/cxt1e1/sbew_ioc.h
@@ -1,7 +1,3 @@
-/*
- * $Id: sbew_ioc.h,v 1.0 2005/09/28 00:10:10 rickd PMCC4_3_1B $
- */
-
 #ifndef _INC_SBEWIOC_H_
 #define _INC_SBEWIOC_H_
 
@@ -24,55 +20,9 @@
  * SBE, Inc.  San Ramon, California  U.S.A.
  *
  *-----------------------------------------------------------------------------
- * RCS info:
- * RCS revision: $Revision: 1.0 $
- * Last changed on $Date: 2005/09/28 00:10:10 $
- * Changed by $Author: rickd $
- *-----------------------------------------------------------------------------
- * $Log: sbew_ioc.h,v $
- * Revision 1.0  2005/09/28 00:10:10  rickd
- * Initial revision
- *
- * Revision 1.6  2005/01/11 18:41:01  rickd
- * Add BRDADDR_GET Ioctl.
- *
- * Revision 1.5  2004/09/16 18:55:59  rickd
- * Start setting up for generic framer configuration Ioctl by switch
- * from tect3_framer_param[] to sbecom_framer_param[].
- *
- * Revision 1.4  2004/06/28 17:58:15  rickd
- * Rename IOC_TSMAP_[GS] to IOC_TSIOC_[GS] to support need for
- * multiple formats of data when setting up TimeSlots.
- *
- * Revision 1.3  2004/06/22 21:18:13  rickd
- * read_vec now() ONLY handles a single common wrt_vec array.
- *
- * Revision 1.1  2004/06/10 18:11:34  rickd
- * Add IID_GET Ioctl reference.
- *
- * Revision 1.0  2004/06/08 22:59:38  rickd
- * Initial revision
- *
- * Revision 2.0  2004/06/07 17:49:47  rickd
- * Initial library release following merge of wanc1t3/wan256 into
- * common elements for lib.
- *
- *-----------------------------------------------------------------------------
  */
 
-#ifndef __KERNEL__
-#include <sys/types.h>
-#endif
-#ifdef SunOS
-#include <sys/ioccom.h>
-#else
 #include <linux/ioctl.h>
-#endif
-
-#ifdef __cplusplus
-extern      "C"
-{
-#endif
 
 #define SBE_LOCKFILE   "/tmp/.sbewan.LCK"
 
@@ -128,9 +78,4 @@
 
 #define SBE_IOC_MAXVEC    1
 
-
-#ifdef __cplusplus
-}
-#endif
-
 #endif                          /*** _INC_SBEWIOC_H_ ***/
diff --git a/drivers/staging/et131x/et131x.c b/drivers/staging/et131x/et131x.c
index 0c1c6ca..2c4069f 100644
--- a/drivers/staging/et131x/et131x.c
+++ b/drivers/staging/et131x/et131x.c
@@ -155,7 +155,6 @@
 #define fMP_ADAPTER_FAIL_SEND_MASK	0x3ff00000
 
 /* Some offsets in PCI config space that are actually used. */
-#define ET1310_PCI_MAX_PYLD		0x4C
 #define ET1310_PCI_MAC_ADDRESS		0xA4
 #define ET1310_PCI_EEPROM_STATUS	0xB2
 #define ET1310_PCI_ACK_NACK		0xC0
@@ -178,9 +177,7 @@
 
 /* RX defines */
 #define USE_FBR0 1
-
 #define FBR_CHUNKS 32
-
 #define MAX_DESC_PER_RING_RX         1024
 
 /* number of RFDs - default and min */
@@ -195,7 +192,6 @@
 #endif
 
 #define NIC_MIN_NUM_RFD		64
-
 #define NUM_PACKETS_HANDLED	256
 
 #define ALCATEL_MULTICAST_PKT	0x01000000
@@ -303,8 +299,8 @@
 	dma_addr_t	 ring_physaddr;
 	void		*mem_virtaddrs[MAX_DESC_PER_RING_RX / FBR_CHUNKS];
 	dma_addr_t	 mem_physaddrs[MAX_DESC_PER_RING_RX / FBR_CHUNKS];
-	uint64_t	 real_physaddr;
-	uint64_t	 offset;
+	u64		 real_physaddr;
+	u64		 offset;
 	u32		 local_full;
 	u32		 num_entries;
 	u32		 buffsize;
@@ -427,7 +423,6 @@
 	int since_irq;
 };
 
-/* ADAPTER defines */
 /*
  * Do not change these values: if changed, then change also in respective
  * TXdma and Rxdma engines
@@ -576,8 +571,6 @@
 	struct net_device_stats net_stats;
 };
 
-/* EEPROM functions */
-
 static int eeprom_wait_ready(struct pci_dev *pdev, u32 *status)
 {
 	u32 reg;
@@ -795,7 +788,7 @@
 	return (status & LBCIF_STATUS_ACK_ERROR) ? -EIO : 0;
 }
 
-int et131x_init_eeprom(struct et131x_adapter *adapter)
+static int et131x_init_eeprom(struct et131x_adapter *adapter)
 {
 	struct pci_dev *pdev = adapter->pdev;
 	u8 eestatus;
@@ -868,7 +861,7 @@
  * et131x_rx_dma_enable - re-start of Rx_DMA on the ET1310.
  * @adapter: pointer to our adapter structure
  */
-void et131x_rx_dma_enable(struct et131x_adapter *adapter)
+static void et131x_rx_dma_enable(struct et131x_adapter *adapter)
 {
 	/* Setup the receive dma configuration register for normal operation */
 	u32 csr =  0x2000;	/* FBR1 enable */
@@ -906,7 +899,7 @@
  * et131x_rx_dma_disable - Stop of Rx_DMA on the ET1310
  * @adapter: pointer to our adapter structure
  */
-void et131x_rx_dma_disable(struct et131x_adapter *adapter)
+static void et131x_rx_dma_disable(struct et131x_adapter *adapter)
 {
 	u32 csr;
 	/* Setup the receive dma configuration register */
@@ -928,7 +921,7 @@
  *
  * Mainly used after a return to the D0 (full-power) state from a lower state.
  */
-void et131x_tx_dma_enable(struct et131x_adapter *adapter)
+static void et131x_tx_dma_enable(struct et131x_adapter *adapter)
 {
 	/* Setup the transmit dma configuration register for normal
 	 * operation
@@ -948,23 +941,10 @@
 }
 
 /**
- * nic_rx_pkts - Checks the hardware for available packets
- * @adapter: pointer to our adapter
- *
- * Returns rfd, a pointer to our MPRFD.
- *
- * Checks the hardware for available packets, using completion ring
- * If packets are available, it gets an RFD from the recv_list, attaches
- * the packet to it, puts the RFD in the RecvPendList, and also returns
- * the pointer to the RFD.
- */
-/* MAC functions */
-
-/**
  * et1310_config_mac_regs1 - Initialize the first part of MAC regs
  * @adapter: pointer to our adapter structure
  */
-void et1310_config_mac_regs1(struct et131x_adapter *adapter)
+static void et1310_config_mac_regs1(struct et131x_adapter *adapter)
 {
 	struct mac_regs __iomem *macregs = &adapter->regs->mac;
 	u32 station1;
@@ -1024,7 +1004,7 @@
  * et1310_config_mac_regs2 - Initialize the second part of MAC regs
  * @adapter: pointer to our adapter structure
  */
-void et1310_config_mac_regs2(struct et131x_adapter *adapter)
+static void et1310_config_mac_regs2(struct et131x_adapter *adapter)
 {
 	int32_t delay = 0;
 	struct mac_regs __iomem *mac = &adapter->regs->mac;
@@ -1105,7 +1085,7 @@
  *
  * Returns 0 if the device is not in phy coma, 1 if it is in phy coma
  */
-int et1310_in_phy_coma(struct et131x_adapter *adapter)
+static int et1310_in_phy_coma(struct et131x_adapter *adapter)
 {
 	u32 pmcsr;
 
@@ -1114,15 +1094,13 @@
 	return ET_PM_PHY_SW_COMA & pmcsr ? 1 : 0;
 }
 
-void et1310_setup_device_for_multicast(struct et131x_adapter *adapter)
+static void et1310_setup_device_for_multicast(struct et131x_adapter *adapter)
 {
 	struct rxmac_regs __iomem *rxmac = &adapter->regs->rxmac;
-	uint32_t nIndex;
-	uint32_t result;
-	uint32_t hash1 = 0;
-	uint32_t hash2 = 0;
-	uint32_t hash3 = 0;
-	uint32_t hash4 = 0;
+	u32 hash1 = 0;
+	u32 hash2 = 0;
+	u32 hash3 = 0;
+	u32 hash4 = 0;
 	u32 pm_csr;
 
 	/* If ET131X_PACKET_TYPE_MULTICAST is specified, then we provision
@@ -1131,10 +1109,13 @@
 	 * driver.
 	 */
 	if (adapter->packet_filter & ET131X_PACKET_TYPE_MULTICAST) {
+		int i;
+
 		/* Loop through our multicast array and set up the device */
-		for (nIndex = 0; nIndex < adapter->multicast_addr_count;
-		     nIndex++) {
-			result = ether_crc(6, adapter->multicast_list[nIndex]);
+		for (i = 0; i < adapter->multicast_addr_count; i++) {
+			u32 result;
+
+			result = ether_crc(6, adapter->multicast_list[i]);
 
 			result = (result & 0x3F800000) >> 23;
 
@@ -1163,7 +1144,7 @@
 	}
 }
 
-void et1310_setup_device_for_unicast(struct et131x_adapter *adapter)
+static void et1310_setup_device_for_unicast(struct et131x_adapter *adapter)
 {
 	struct rxmac_regs __iomem *rxmac = &adapter->regs->rxmac;
 	u32 uni_pf1;
@@ -1203,7 +1184,7 @@
 	}
 }
 
-void et1310_config_rxmac_regs(struct et131x_adapter *adapter)
+static void et1310_config_rxmac_regs(struct et131x_adapter *adapter)
 {
 	struct rxmac_regs __iomem *rxmac = &adapter->regs->rxmac;
 	struct phy_device *phydev = adapter->phydev;
@@ -1334,7 +1315,7 @@
 	writel(0x9, &rxmac->ctrl);
 }
 
-void et1310_config_txmac_regs(struct et131x_adapter *adapter)
+static void et1310_config_txmac_regs(struct et131x_adapter *adapter)
 {
 	struct txmac_regs __iomem *txmac = &adapter->regs->txmac;
 
@@ -1348,7 +1329,7 @@
 		writel(0x40, &txmac->cf_param);
 }
 
-void et1310_config_macstat_regs(struct et131x_adapter *adapter)
+static void et1310_config_macstat_regs(struct et131x_adapter *adapter)
 {
 	struct macstat_regs __iomem *macstat =
 		&adapter->regs->macstat;
@@ -1422,7 +1403,7 @@
  *
  * Returns 0 on success, errno on failure (as defined in errno.h)
  */
-int et131x_phy_mii_read(struct et131x_adapter *adapter, u8 addr,
+static int et131x_phy_mii_read(struct et131x_adapter *adapter, u8 addr,
 	      u8 reg, u16 *value)
 {
 	struct mac_regs __iomem *mac = &adapter->regs->mac;
@@ -1478,7 +1459,7 @@
 	return status;
 }
 
-int et131x_mii_read(struct et131x_adapter *adapter, u8 reg, u16 *value)
+static int et131x_mii_read(struct et131x_adapter *adapter, u8 reg, u16 *value)
 {
 	struct phy_device *phydev = adapter->phydev;
 
@@ -1498,7 +1479,7 @@
  *
  * Return 0 on success, errno on failure (as defined in errno.h)
  */
-int et131x_mii_write(struct et131x_adapter *adapter, u8 reg, u16 value)
+static int et131x_mii_write(struct et131x_adapter *adapter, u8 reg, u16 value)
 {
 	struct mac_regs __iomem *mac = &adapter->regs->mac;
 	struct phy_device *phydev = adapter->phydev;
@@ -1564,8 +1545,9 @@
 }
 
 /* Still used from _mac for BIT_READ */
-void et1310_phy_access_mii_bit(struct et131x_adapter *adapter, u16 action,
-			       u16 regnum, u16 bitnum, u8 *value)
+static void et1310_phy_access_mii_bit(struct et131x_adapter *adapter,
+				      u16 action, u16 regnum, u16 bitnum,
+				      u8 *value)
 {
 	u16 reg;
 	u16 mask = 0x0001 << bitnum;
@@ -1591,7 +1573,7 @@
 	}
 }
 
-void et1310_config_flow_control(struct et131x_adapter *adapter)
+static void et1310_config_flow_control(struct et131x_adapter *adapter)
 {
 	struct phy_device *phydev = adapter->phydev;
 
@@ -1632,7 +1614,7 @@
  * et1310_update_macstat_host_counters - Update the local copy of the statistics
  * @adapter: pointer to the adapter structure
  */
-void et1310_update_macstat_host_counters(struct et131x_adapter *adapter)
+static void et1310_update_macstat_host_counters(struct et131x_adapter *adapter)
 {
 	struct ce_stats *stats = &adapter->stats;
 	struct macstat_regs __iomem *macstat =
@@ -1664,7 +1646,7 @@
  * the statistics held in the adapter structure, checking the "wrap"
  * bit for each counter.
  */
-void et1310_handle_macstat_interrupt(struct et131x_adapter *adapter)
+static void et1310_handle_macstat_interrupt(struct et131x_adapter *adapter)
 {
 	u32 carry_reg1;
 	u32 carry_reg2;
@@ -1714,9 +1696,7 @@
 		adapter->stats.tx_collisions	+= COUNTER_WRAP_12_BIT;
 }
 
-/* PHY functions */
-
-int et131x_mdio_read(struct mii_bus *bus, int phy_addr, int reg)
+static int et131x_mdio_read(struct mii_bus *bus, int phy_addr, int reg)
 {
 	struct net_device *netdev = bus->priv;
 	struct et131x_adapter *adapter = netdev_priv(netdev);
@@ -1731,7 +1711,7 @@
 		return value;
 }
 
-int et131x_mdio_write(struct mii_bus *bus, int phy_addr, int reg, u16 value)
+static int et131x_mdio_write(struct mii_bus *bus, int phy_addr, int reg, u16 value)
 {
 	struct net_device *netdev = bus->priv;
 	struct et131x_adapter *adapter = netdev_priv(netdev);
@@ -1739,7 +1719,7 @@
 	return et131x_mii_write(adapter, reg, value);
 }
 
-int et131x_mdio_reset(struct mii_bus *bus)
+static int et131x_mdio_reset(struct mii_bus *bus)
 {
 	struct net_device *netdev = bus->priv;
 	struct et131x_adapter *adapter = netdev_priv(netdev);
@@ -1759,7 +1739,7 @@
  *	Can't you see that this code processed
  *	Phy power, phy power..
  */
-void et1310_phy_power_down(struct et131x_adapter *adapter, bool down)
+static void et1310_phy_power_down(struct et131x_adapter *adapter, bool down)
 {
 	u16 data;
 
@@ -1775,7 +1755,7 @@
  * @adapter: pointer to our private adapter structure
  *
  */
-void et131x_xcvr_init(struct et131x_adapter *adapter)
+static void et131x_xcvr_init(struct et131x_adapter *adapter)
 {
 	u16 imr;
 	u16 isr;
@@ -1822,7 +1802,7 @@
  *
  * Used to configure the global registers on the JAGCore
  */
-void et131x_configure_global_regs(struct et131x_adapter *adapter)
+static void et131x_configure_global_regs(struct et131x_adapter *adapter)
 {
 	struct global_regs __iomem *regs = &adapter->regs->global;
 
@@ -1863,13 +1843,11 @@
 	writel(0, &regs->watchdog_timer);
 }
 
-/* PM functions */
-
 /**
  * et131x_config_rx_dma_regs - Start of Rx_DMA init sequence
  * @adapter: pointer to our adapter structure
  */
-void et131x_config_rx_dma_regs(struct et131x_adapter *adapter)
+static void et131x_config_rx_dma_regs(struct et131x_adapter *adapter)
 {
 	struct rxdma_regs __iomem *rx_dma = &adapter->regs->rxdma;
 	struct rx_ring *rx_local = &adapter->rx_ring;
@@ -1987,7 +1965,7 @@
  * Configure the transmit engine with the ring buffers we have created
  * and prepare it for use.
  */
-void et131x_config_tx_dma_regs(struct et131x_adapter *adapter)
+static void et131x_config_tx_dma_regs(struct et131x_adapter *adapter)
 {
 	struct txdma_regs __iomem *txdma = &adapter->regs->txdma;
 
@@ -2017,7 +1995,7 @@
  *
  * Returns 0 on success, errno on failure (as defined in errno.h)
  */
-void et131x_adapter_setup(struct et131x_adapter *adapter)
+static void et131x_adapter_setup(struct et131x_adapter *adapter)
 {
 	/* Configure the JAGCore */
 	et131x_configure_global_regs(adapter);
@@ -2044,7 +2022,7 @@
  * et131x_soft_reset - Issue a soft reset to the hardware, complete for ET1310
  * @adapter: pointer to our private adapter structure
  */
-void et131x_soft_reset(struct et131x_adapter *adapter)
+static void et131x_soft_reset(struct et131x_adapter *adapter)
 {
 	/* Disable MAC Core */
 	writel(0xc00f0000, &adapter->regs->mac.cfg1);
@@ -2062,7 +2040,7 @@
  *	Enable the appropriate interrupts on the ET131x according to our
  *	configuration
  */
-void et131x_enable_interrupts(struct et131x_adapter *adapter)
+static void et131x_enable_interrupts(struct et131x_adapter *adapter)
 {
 	u32 mask;
 
@@ -2082,7 +2060,7 @@
  *
  *	Block all interrupts from the et131x device at the device itself
  */
-void et131x_disable_interrupts(struct et131x_adapter *adapter)
+static void et131x_disable_interrupts(struct et131x_adapter *adapter)
 {
 	/* Disable all global interrupts */
 	writel(INT_MASK_DISABLE, &adapter->regs->global.int_mask);
@@ -2092,7 +2070,7 @@
  * et131x_tx_dma_disable - Stop of Tx_DMA on the ET1310
  * @adapter: pointer to our adapter structure
  */
-void et131x_tx_dma_disable(struct et131x_adapter *adapter)
+static void et131x_tx_dma_disable(struct et131x_adapter *adapter)
 {
 	/* Setup the tramsmit dma configuration register */
 	writel(ET_TXDMA_CSR_HALT|ET_TXDMA_SNGL_EPKT,
@@ -2103,7 +2081,7 @@
  * et131x_enable_txrx - Enable tx/rx queues
  * @netdev: device to be enabled
  */
-void et131x_enable_txrx(struct net_device *netdev)
+static void et131x_enable_txrx(struct net_device *netdev)
 {
 	struct et131x_adapter *adapter = netdev_priv(netdev);
 
@@ -2123,7 +2101,7 @@
  * et131x_disable_txrx - Disable tx/rx queues
  * @netdev: device to be disabled
  */
-void et131x_disable_txrx(struct net_device *netdev)
+static void et131x_disable_txrx(struct net_device *netdev)
 {
 	struct et131x_adapter *adapter = netdev_priv(netdev);
 
@@ -2142,7 +2120,7 @@
  * et131x_init_send - Initialize send data structures
  * @adapter: pointer to our private adapter structure
  */
-void et131x_init_send(struct et131x_adapter *adapter)
+static void et131x_init_send(struct et131x_adapter *adapter)
 {
 	struct tcb *tcb;
 	u32 ct;
@@ -2192,7 +2170,7 @@
  *       indicating linkup status, call the MPDisablePhyComa routine to
  *             restore JAGCore and gigE PHY
  */
-void et1310_enable_phy_coma(struct et131x_adapter *adapter)
+static void et1310_enable_phy_coma(struct et131x_adapter *adapter)
 {
 	unsigned long flags;
 	u32 pmcsr;
@@ -2231,7 +2209,7 @@
  * et1310_disable_phy_coma - Disable the Phy Coma Mode
  * @adapter: pointer to our adapter structure
  */
-void et1310_disable_phy_coma(struct et131x_adapter *adapter)
+static void et1310_disable_phy_coma(struct et131x_adapter *adapter)
 {
 	u32 pmcsr;
 
@@ -2269,8 +2247,6 @@
 	et131x_enable_txrx(adapter->netdev);
 }
 
-/* RX functions */
-
 static inline u32 bump_free_buff_ring(u32 *free_buff_ring, u32 limit)
 {
 	u32 tmp_free_buff_ring = *free_buff_ring;
@@ -2296,16 +2272,14 @@
  * @offset: pointer to the offset variable
  * @mask: correct mask
  */
-void et131x_align_allocated_memory(struct et131x_adapter *adapter,
-				   uint64_t *phys_addr,
-				   uint64_t *offset, uint64_t mask)
+static void et131x_align_allocated_memory(struct et131x_adapter *adapter,
+					  u64 *phys_addr, u64 *offset,
+					  u64 mask)
 {
-	uint64_t new_addr;
+	u64 new_addr = *phys_addr & ~mask;
 
 	*offset = 0;
 
-	new_addr = *phys_addr & ~mask;
-
 	if (new_addr != *phys_addr) {
 		/* Move to next aligned block */
 		new_addr += mask + 1;
@@ -2325,7 +2299,7 @@
  * Allocates Free buffer ring 1 for sure, free buffer ring 0 if required,
  * and the Packet Status Ring.
  */
-int et131x_rx_dma_memory_alloc(struct et131x_adapter *adapter)
+static int et131x_rx_dma_memory_alloc(struct et131x_adapter *adapter)
 {
 	u32 i, j;
 	u32 bufsize;
@@ -2454,8 +2428,8 @@
 			rx_ring->fbr[1]->offset);
 #endif
 	for (i = 0; i < (rx_ring->fbr[0]->num_entries / FBR_CHUNKS); i++) {
-		u64 fbr1_offset;
 		u64 fbr1_tmp_physaddr;
+		u64 fbr1_offset;
 		u32 fbr1_align;
 
 		/* This code allocates an area of memory big enough for N
@@ -2520,8 +2494,8 @@
 #ifdef USE_FBR0
 	/* Same for FBR0 (if in use) */
 	for (i = 0; i < (rx_ring->fbr[1]->num_entries / FBR_CHUNKS); i++) {
-		u64 fbr0_offset;
 		u64 fbr0_tmp_physaddr;
+		u64 fbr0_offset;
 
 		fbr_chunksize =
 		    ((FBR_CHUNKS + 1) * rx_ring->fbr[1]->buffsize) - 1;
@@ -2629,7 +2603,7 @@
  * et131x_rx_dma_memory_free - Free all memory allocated within this module.
  * @adapter: pointer to our private adapter structure
  */
-void et131x_rx_dma_memory_free(struct et131x_adapter *adapter)
+static void et131x_rx_dma_memory_free(struct et131x_adapter *adapter)
 {
 	u32 index;
 	u32 bufsize;
@@ -2774,7 +2748,7 @@
  *
  * Returns 0 on success and errno on failure (as defined in errno.h)
  */
-int et131x_init_recv(struct et131x_adapter *adapter)
+static int et131x_init_recv(struct et131x_adapter *adapter)
 {
 	int status = -ENOMEM;
 	struct rfd *rfd = NULL;
@@ -2824,7 +2798,7 @@
  * et131x_set_rx_dma_timer - Set the heartbeat timer according to line rate.
  * @adapter: pointer to our adapter structure
  */
-void et131x_set_rx_dma_timer(struct et131x_adapter *adapter)
+static void et131x_set_rx_dma_timer(struct et131x_adapter *adapter)
 {
 	struct phy_device *phydev = adapter->phydev;
 
@@ -2918,6 +2892,17 @@
 	WARN_ON(rx_local->num_ready_recv > rx_local->num_rfd);
 }
 
+/**
+ * nic_rx_pkts - Checks the hardware for available packets
+ * @adapter: pointer to our adapter
+ *
+ * Returns rfd, a pointer to our MPRFD.
+ *
+ * Checks the hardware for available packets, using completion ring
+ * If packets are available, it gets an RFD from the recv_list, attaches
+ * the packet to it, puts the RFD in the RecvPendList, and also returns
+ * the pointer to the RFD.
+ */
 static struct rfd *nic_rx_pkts(struct et131x_adapter *adapter)
 {
 	struct rx_ring *rx_local = &adapter->rx_ring;
@@ -3139,7 +3124,7 @@
  *
  * Assumption, Rcv spinlock has been acquired.
  */
-void et131x_handle_recv_interrupt(struct et131x_adapter *adapter)
+static void et131x_handle_recv_interrupt(struct et131x_adapter *adapter)
 {
 	struct rfd *rfd = NULL;
 	u32 count = 0;
@@ -3188,8 +3173,6 @@
 		adapter->rx_ring.unfinished_receives = false;
 }
 
-/* TX functions */
-
 /**
  * et131x_tx_dma_memory_alloc
  * @adapter: pointer to our private adapter structure
@@ -3202,7 +3185,7 @@
  * memory. The device will update the "status" in memory each time it xmits a
  * packet.
  */
-int et131x_tx_dma_memory_alloc(struct et131x_adapter *adapter)
+static int et131x_tx_dma_memory_alloc(struct et131x_adapter *adapter)
 {
 	int desc_size = 0;
 	struct tx_ring *tx_ring = &adapter->tx_ring;
@@ -3256,7 +3239,7 @@
  *
  * Returns 0 on success and errno on failure (as defined in errno.h).
  */
-void et131x_tx_dma_memory_free(struct et131x_adapter *adapter)
+static void et131x_tx_dma_memory_free(struct et131x_adapter *adapter)
 {
 	int desc_size = 0;
 
@@ -3578,7 +3561,7 @@
  *
  * Return 0 in almost all cases; non-zero value in extreme hard failure only
  */
-int et131x_send_packets(struct sk_buff *skb, struct net_device *netdev)
+static int et131x_send_packets(struct sk_buff *skb, struct net_device *netdev)
 {
 	int status = 0;
 	struct et131x_adapter *adapter = netdev_priv(netdev);
@@ -3696,7 +3679,7 @@
  *
  * Assumption - Send spinlock has been acquired
  */
-void et131x_free_busy_send_packets(struct et131x_adapter *adapter)
+static void et131x_free_busy_send_packets(struct et131x_adapter *adapter)
 {
 	struct tcb *tcb;
 	unsigned long flags;
@@ -3743,7 +3726,7 @@
  *
  * Assumption - Send spinlock has been acquired
  */
-void et131x_handle_send_interrupt(struct et131x_adapter *adapter)
+static void et131x_handle_send_interrupt(struct et131x_adapter *adapter)
 {
 	unsigned long flags;
 	u32 serviced;
@@ -3798,8 +3781,6 @@
 	spin_unlock_irqrestore(&adapter->tcb_send_qlock, flags);
 }
 
-/* ETHTOOL functions */
-
 static int et131x_get_settings(struct net_device *netdev,
 			       struct ethtool_cmd *cmd)
 {
@@ -3965,18 +3946,16 @@
 	.get_link = ethtool_op_get_link,
 };
 
-void et131x_set_ethtool_ops(struct net_device *netdev)
+static void et131x_set_ethtool_ops(struct net_device *netdev)
 {
 	SET_ETHTOOL_OPS(netdev, &et131x_ethtool_ops);
 }
 
-/* PCI functions */
-
 /**
  * et131x_hwaddr_init - set up the MAC Address on the ET1310
  * @adapter: pointer to our private adapter structure
  */
-void et131x_hwaddr_init(struct et131x_adapter *adapter)
+static void et131x_hwaddr_init(struct et131x_adapter *adapter)
 {
 	/* If have our default mac from init and no mac address from
 	 * EEPROM then we need to generate the last octet and set it on the
@@ -4022,24 +4001,31 @@
 static int et131x_pci_init(struct et131x_adapter *adapter,
 						struct pci_dev *pdev)
 {
-	int i;
-	u8 max_payload;
-	u8 read_size_reg;
+	int cap = pci_pcie_cap(pdev);
+	u16 max_payload;
+	u16 ctl;
+	int i, rc;
 
-	if (et131x_init_eeprom(adapter) < 0)
-		return -EIO;
+	rc = et131x_init_eeprom(adapter);
+	if (rc < 0)
+		goto out;
 
+	if (!cap) {
+		dev_err(&pdev->dev, "Missing PCIe capabilities\n");
+		goto err_out;
+	}
+		
 	/* Let's set up the PORT LOGIC Register.  First we need to know what
 	 * the max_payload_size is
 	 */
-	if (pci_read_config_byte(pdev, ET1310_PCI_MAX_PYLD, &max_payload)) {
+	if (pci_read_config_word(pdev, cap + PCI_EXP_DEVCAP, &max_payload)) {
 		dev_err(&pdev->dev,
 		    "Could not read PCI config space for Max Payload Size\n");
-		return -EIO;
+		goto err_out;
 	}
 
 	/* Program the Ack/Nak latency and replay timers */
-	max_payload &= 0x07;	/* Only the lower 3 bits are valid */
+	max_payload &= 0x07;
 
 	if (max_payload < 2) {
 		static const u16 acknak[2] = { 0x76, 0xD0 };
@@ -4049,13 +4035,13 @@
 					       acknak[max_payload])) {
 			dev_err(&pdev->dev,
 			  "Could not write PCI config space for ACK/NAK\n");
-			return -EIO;
+			goto err_out;
 		}
 		if (pci_write_config_word(pdev, ET1310_PCI_REPLAY,
 					       replay[max_payload])) {
 			dev_err(&pdev->dev,
 			  "Could not write PCI config space for Replay Timer\n");
-			return -EIO;
+			goto err_out;
 		}
 	}
 
@@ -4065,23 +4051,22 @@
 	if (pci_write_config_byte(pdev, ET1310_PCI_L0L1LATENCY, 0x11)) {
 		dev_err(&pdev->dev,
 		  "Could not write PCI config space for Latency Timers\n");
-		return -EIO;
+		goto err_out;
 	}
 
 	/* Change the max read size to 2k */
-	if (pci_read_config_byte(pdev, 0x51, &read_size_reg)) {
+	if (pci_read_config_word(pdev, cap + PCI_EXP_DEVCTL, &ctl)) {
 		dev_err(&pdev->dev,
 			"Could not read PCI config space for Max read size\n");
-		return -EIO;
+		goto err_out;
 	}
 
-	read_size_reg &= 0x8f;
-	read_size_reg |= 0x40;
+	ctl = (ctl & ~PCI_EXP_DEVCTL_READRQ) | ( 0x04 << 12);
 
-	if (pci_write_config_byte(pdev, 0x51, read_size_reg)) {
+	if (pci_write_config_word(pdev, cap + PCI_EXP_DEVCTL, ctl)) {
 		dev_err(&pdev->dev,
 		      "Could not write PCI config space for Max read size\n");
-		return -EIO;
+		goto err_out;
 	}
 
 	/* Get MAC address from config space if an eeprom exists, otherwise
@@ -4096,11 +4081,15 @@
 		if (pci_read_config_byte(pdev, ET1310_PCI_MAC_ADDRESS + i,
 					adapter->rom_addr + i)) {
 			dev_err(&pdev->dev, "Could not read PCI config space for MAC address\n");
-			return -EIO;
+			goto err_out;
 		}
 	}
 	memcpy(adapter->addr, adapter->rom_addr, ETH_ALEN);
-	return 0;
+out:
+	return rc;
+err_out:
+	rc = -EIO;
+	goto out;
 }
 
 /**
@@ -4110,7 +4099,7 @@
  * The routine called when the error timer expires, to track the number of
  * recurring errors.
  */
-void et131x_error_timer_handler(unsigned long data)
+static void et131x_error_timer_handler(unsigned long data)
 {
 	struct et131x_adapter *adapter = (struct et131x_adapter *) data;
 	struct phy_device *phydev = adapter->phydev;
@@ -4153,7 +4142,7 @@
  *
  * Allocate all the memory blocks for send, receive and others.
  */
-int et131x_adapter_memory_alloc(struct et131x_adapter *adapter)
+static int et131x_adapter_memory_alloc(struct et131x_adapter *adapter)
 {
 	int status;
 
@@ -4188,7 +4177,7 @@
  * et131x_adapter_memory_free - Free all memory allocated for use by Tx & Rx
  * @adapter: pointer to our private adapter structure
  */
-void et131x_adapter_memory_free(struct et131x_adapter *adapter)
+static void et131x_adapter_memory_free(struct et131x_adapter *adapter)
 {
 	/* Free DMA memory */
 	et131x_tx_dma_memory_free(adapter);
@@ -4364,10 +4353,6 @@
 	adapter->pdev = pci_dev_get(pdev);
 	adapter->netdev = netdev;
 
-	/* Do the same for the netdev struct */
-	netdev->irq = pdev->irq;
-	netdev->base_addr = pci_resource_start(pdev, 0);
-
 	/* Initialize spinlocks here */
 	spin_lock_init(&adapter->lock);
 	spin_lock_init(&adapter->tcb_send_qlock);
@@ -4400,6 +4385,7 @@
 	struct et131x_adapter *adapter = netdev_priv(netdev);
 
 	unregister_netdev(netdev);
+	phy_disconnect(adapter->phydev);
 	mdiobus_unregister(adapter->mii_bus);
 	kfree(adapter->mii_bus->irq);
 	mdiobus_free(adapter->mii_bus);
@@ -4417,7 +4403,7 @@
  * et131x_up - Bring up a device for use.
  * @netdev: device to be opened
  */
-void et131x_up(struct net_device *netdev)
+static void et131x_up(struct net_device *netdev)
 {
 	struct et131x_adapter *adapter = netdev_priv(netdev);
 
@@ -4429,7 +4415,7 @@
  * et131x_down - Bring down the device
  * @netdev: device to be broght down
  */
-void et131x_down(struct net_device *netdev)
+static void et131x_down(struct net_device *netdev)
 {
 	struct et131x_adapter *adapter = netdev_priv(netdev);
 
@@ -4475,8 +4461,6 @@
 #define ET131X_PM_OPS NULL
 #endif
 
-/* ISR functions */
-
 /**
  * et131x_isr - The Interrupt Service Routine for the driver.
  * @irq: the IRQ on which the interrupt was received.
@@ -4573,7 +4557,7 @@
  * scheduled to run in a deferred context by the ISR. This is where the ISR's
  * work actually gets done.
  */
-void et131x_isr_handler(struct work_struct *work)
+static void et131x_isr_handler(struct work_struct *work)
 {
 	struct et131x_adapter *adapter =
 		container_of(work, struct et131x_adapter, task);
@@ -4774,8 +4758,6 @@
 	et131x_enable_interrupts(adapter);
 }
 
-/* NETDEV functions */
-
 /**
  * et131x_stats - Return the current device statistics.
  * @netdev: device whose stats are being queried
@@ -4829,10 +4811,12 @@
  *
  * Returns 0 on success, errno on failure (as defined in errno.h)
  */
-int et131x_open(struct net_device *netdev)
+static int et131x_open(struct net_device *netdev)
 {
-	int result = 0;
 	struct et131x_adapter *adapter = netdev_priv(netdev);
+	struct pci_dev *pdev = adapter->pdev;
+	unsigned int irq = pdev->irq;
+	int result;
 
 	/* Start the timer to track NIC errors */
 	init_timer(&adapter->error_timer);
@@ -4841,12 +4825,9 @@
 	adapter->error_timer.data = (unsigned long)adapter;
 	add_timer(&adapter->error_timer);
 
-	/* Register our IRQ */
-	result = request_irq(netdev->irq, et131x_isr, IRQF_SHARED,
-					netdev->name, netdev);
+	result = request_irq(irq, et131x_isr, IRQF_SHARED, netdev->name, netdev);
 	if (result) {
-		dev_err(&adapter->pdev->dev, "could not register IRQ %d\n",
-			netdev->irq);
+		dev_err(&pdev->dev, "could not register IRQ %d\n", irq);
 		return result;
 	}
 
@@ -4863,14 +4844,14 @@
  *
  * Returns 0 on success, errno on failure (as defined in errno.h)
  */
-int et131x_close(struct net_device *netdev)
+static int et131x_close(struct net_device *netdev)
 {
 	struct et131x_adapter *adapter = netdev_priv(netdev);
 
 	et131x_down(netdev);
 
 	adapter->flags &= ~fMP_ADAPTER_INTERRUPT_IN_USE;
-	free_irq(netdev->irq, netdev);
+	free_irq(adapter->pdev->irq, netdev);
 
 	/* Stop the error timer */
 	return del_timer_sync(&adapter->error_timer);
@@ -4905,8 +4886,8 @@
  */
 static int et131x_set_packet_filter(struct et131x_adapter *adapter)
 {
+	int filter = adapter->packet_filter;
 	int status = 0;
-	uint32_t filter = adapter->packet_filter;
 	u32 ctrl;
 	u32 pf_ctrl;
 
@@ -4968,7 +4949,7 @@
 static void et131x_multicast(struct net_device *netdev)
 {
 	struct et131x_adapter *adapter = netdev_priv(netdev);
-	uint32_t packet_filter = 0;
+	int packet_filter;
 	unsigned long flags;
 	struct netdev_hw_addr *ha;
 	int i;
@@ -5249,40 +5230,6 @@
 };
 
 /**
- * et131x_device_alloc
- *
- * Returns pointer to the allocated and initialized net_device struct for
- * this device.
- *
- * Create instances of net_device and wl_private for the new adapter and
- * register the device's entry points in the net_device structure.
- */
-struct net_device *et131x_device_alloc(void)
-{
-	struct net_device *netdev;
-
-	/* Alloc net_device and adapter structs */
-	netdev = alloc_etherdev(sizeof(struct et131x_adapter));
-
-	if (!netdev) {
-		printk(KERN_ERR "et131x: Alloc of net_device struct failed\n");
-		return NULL;
-	}
-
-	/*
-	 * Setup the function registration table (and other data) for a
-	 * net_device
-	 */
-	netdev->watchdog_timeo = ET131X_TX_TIMEOUT;
-	netdev->netdev_ops     = &et131x_netdev_ops;
-
-	/* Poll? */
-	/* netdev->poll               = &et131x_poll; */
-	/* netdev->poll_controller    = &et131x_poll_controller; */
-	return netdev;
-}
-
-/**
  * et131x_pci_setup - Perform device initialization
  * @pdev: a pointer to the device's pci_dev structure
  * @ent: this device's entry in the pci_device_id table
@@ -5297,24 +5244,26 @@
 static int __devinit et131x_pci_setup(struct pci_dev *pdev,
 			       const struct pci_device_id *ent)
 {
-	int result;
 	struct net_device *netdev;
 	struct et131x_adapter *adapter;
+	int rc;
 	int ii;
 
-	result = pci_enable_device(pdev);
-	if (result) {
+	rc = pci_enable_device(pdev);
+	if (rc < 0) {
 		dev_err(&pdev->dev, "pci_enable_device() failed\n");
-		goto err_out;
+		goto out;
 	}
 
 	/* Perform some basic PCI checks */
 	if (!(pci_resource_flags(pdev, 0) & IORESOURCE_MEM)) {
 		dev_err(&pdev->dev, "Can't find PCI device's base address\n");
+		rc = -ENODEV;
 		goto err_disable;
 	}
 
-	if (pci_request_regions(pdev, DRIVER_NAME)) {
+	rc = pci_request_regions(pdev, DRIVER_NAME);
+	if (rc < 0) {
 		dev_err(&pdev->dev, "Can't get PCI resources\n");
 		goto err_disable;
 	}
@@ -5323,46 +5272,50 @@
 
 	/* Check the DMA addressing support of this device */
 	if (!dma_set_mask(&pdev->dev, DMA_BIT_MASK(64))) {
-		result = dma_set_coherent_mask(&pdev->dev, DMA_BIT_MASK(64));
-		if (result) {
+		rc = dma_set_coherent_mask(&pdev->dev, DMA_BIT_MASK(64));
+		if (rc < 0) {
 			dev_err(&pdev->dev,
 			  "Unable to obtain 64 bit DMA for consistent allocations\n");
 			goto err_release_res;
 		}
 	} else if (!dma_set_mask(&pdev->dev, DMA_BIT_MASK(32))) {
-		result = dma_set_coherent_mask(&pdev->dev, DMA_BIT_MASK(32));
-		if (result) {
+		rc = dma_set_coherent_mask(&pdev->dev, DMA_BIT_MASK(32));
+		if (rc < 0) {
 			dev_err(&pdev->dev,
 			  "Unable to obtain 32 bit DMA for consistent allocations\n");
 			goto err_release_res;
 		}
 	} else {
 		dev_err(&pdev->dev, "No usable DMA addressing method\n");
-		result = -EIO;
+		rc = -EIO;
 		goto err_release_res;
 	}
 
 	/* Allocate netdev and private adapter structs */
-	netdev = et131x_device_alloc();
+	netdev = alloc_etherdev(sizeof(struct et131x_adapter));
 	if (!netdev) {
 		dev_err(&pdev->dev, "Couldn't alloc netdev struct\n");
-		result = -ENOMEM;
+		rc = -ENOMEM;
 		goto err_release_res;
 	}
 
+	netdev->watchdog_timeo = ET131X_TX_TIMEOUT;
+	netdev->netdev_ops     = &et131x_netdev_ops;
+
 	SET_NETDEV_DEV(netdev, &pdev->dev);
 	et131x_set_ethtool_ops(netdev);
 
 	adapter = et131x_adapter_init(netdev, pdev);
 
-	/* Initialise the PCI setup for the device */
-	et131x_pci_init(adapter, pdev);
+	rc = et131x_pci_init(adapter, pdev);
+	if (rc < 0)
+		goto err_free_dev;
 
 	/* Map the bus-relative registers to system virtual memory */
 	adapter->regs = pci_ioremap_bar(pdev, 0);
 	if (!adapter->regs) {
 		dev_err(&pdev->dev, "Cannot map device registers\n");
-		result = -ENOMEM;
+		rc = -ENOMEM;
 		goto err_free_dev;
 	}
 
@@ -5376,8 +5329,8 @@
 	et131x_disable_interrupts(adapter);
 
 	/* Allocate DMA memory */
-	result = et131x_adapter_memory_alloc(adapter);
-	if (result) {
+	rc = et131x_adapter_memory_alloc(adapter);
+	if (rc < 0) {
 		dev_err(&pdev->dev, "Could not alloc adapater memory (DMA)\n");
 		goto err_iounmap;
 	}
@@ -5395,6 +5348,8 @@
 	adapter->boot_coma = 0;
 	et1310_disable_phy_coma(adapter);
 
+	rc = -ENOMEM;
+
 	/* Setup the mii_bus struct */
 	adapter->mii_bus = mdiobus_alloc();
 	if (!adapter->mii_bus) {
@@ -5418,13 +5373,14 @@
 	for (ii = 0; ii < PHY_MAX_ADDR; ii++)
 		adapter->mii_bus->irq[ii] = PHY_POLL;
 
-	if (mdiobus_register(adapter->mii_bus)) {
+	rc = mdiobus_register(adapter->mii_bus);
+	if (rc < 0) {
 		dev_err(&pdev->dev, "failed to register MII bus\n");
-		mdiobus_free(adapter->mii_bus);
 		goto err_mdio_free_irq;
 	}
 
-	if (et131x_mii_probe(netdev)) {
+	rc = et131x_mii_probe(netdev);
+	if (rc < 0) {
 		dev_err(&pdev->dev, "failed to probe MII bus\n");
 		goto err_mdio_unregister;
 	}
@@ -5440,10 +5396,10 @@
 	 */
 
 	/* Register the net_device struct with the Linux network layer */
-	result = register_netdev(netdev);
-	if (result != 0) {
+	rc = register_netdev(netdev);
+	if (rc < 0) {
 		dev_err(&pdev->dev, "register_netdev() failed\n");
-		goto err_mdio_unregister;
+		goto err_phy_disconnect;
 	}
 
 	/* Register the net_device struct with the PCI subsystem. Save a copy
@@ -5451,10 +5407,11 @@
 	 * been initialized, just in case it needs to be quickly restored.
 	 */
 	pci_set_drvdata(pdev, netdev);
-	pci_save_state(adapter->pdev);
+out:
+	return rc;
 
-	return result;
-
+err_phy_disconnect:
+	phy_disconnect(adapter->phydev);
 err_mdio_unregister:
 	mdiobus_unregister(adapter->mii_bus);
 err_mdio_free_irq:
@@ -5472,8 +5429,7 @@
 	pci_release_regions(pdev);
 err_disable:
 	pci_disable_device(pdev);
-err_out:
-	return result;
+	goto out;
 }
 
 static DEFINE_PCI_DEVICE_TABLE(et131x_pci_table) = {
diff --git a/drivers/staging/frontier/tranzport.c b/drivers/staging/frontier/tranzport.c
index c263284..cf47a5d 100644
--- a/drivers/staging/frontier/tranzport.c
+++ b/drivers/staging/frontier/tranzport.c
@@ -199,7 +199,7 @@
 		struct usb_interface *intf = to_usb_interface(dev);	\
 		struct usb_tranzport *t = usb_get_intfdata(intf);	\
 		unsigned long temp;	\
-		if (strict_strtoul(buf, 10, &temp))	\
+		if (kstrtoul(buf, 10, &temp))	\
 			return -EINVAL;	\
 		t->value = temp;	\
 		return count;	\
diff --git a/drivers/staging/gma500/Kconfig b/drivers/staging/gma500/Kconfig
index bfe2166..c7a2b3b 100644
--- a/drivers/staging/gma500/Kconfig
+++ b/drivers/staging/gma500/Kconfig
@@ -1,6 +1,6 @@
 config DRM_PSB
 	tristate "Intel GMA5/600 KMS Framebuffer"
-	depends on DRM && PCI && X86
+	depends on DRM && PCI && X86 && BROKEN
 	select FB_CFB_COPYAREA
         select FB_CFB_FILLRECT
         select FB_CFB_IMAGEBLIT
diff --git a/drivers/staging/gma500/power.c b/drivers/staging/gma500/power.c
index 436fe97..4082570 100644
--- a/drivers/staging/gma500/power.c
+++ b/drivers/staging/gma500/power.c
@@ -266,7 +266,7 @@
 	ret = gma_resume_pci(dev->pdev);
 	if (ret == 0) {
 		/* FIXME: we want to defer this for Medfield/Oaktrail */
-		gma_resume_display(dev);
+		gma_resume_display(dev->pdev);
 		psb_irq_preinstall(dev);
 		psb_irq_postinstall(dev);
 		pm_runtime_get(&dev->pdev->dev);
diff --git a/drivers/staging/hv/Kconfig b/drivers/staging/hv/Kconfig
index 072185e..60ac479 100644
--- a/drivers/staging/hv/Kconfig
+++ b/drivers/staging/hv/Kconfig
@@ -3,15 +3,3 @@
 	depends on HYPERV && SCSI
 	help
 	 Select this option to enable the Hyper-V virtual storage driver.
-
-config HYPERV_NET
-	tristate "Microsoft Hyper-V virtual network driver"
-	depends on HYPERV && NET
-	help
-	  Select this option to enable the Hyper-V virtual network driver.
-
-config HYPERV_MOUSE
-	tristate "Microsoft Hyper-V mouse driver"
-	depends on HYPERV && HID
-	help
-	  Select this option to enable the Hyper-V mouse driver.
diff --git a/drivers/staging/hv/Makefile b/drivers/staging/hv/Makefile
index 0f55cee..af95a6b 100644
--- a/drivers/staging/hv/Makefile
+++ b/drivers/staging/hv/Makefile
@@ -1,6 +1,3 @@
 obj-$(CONFIG_HYPERV_STORAGE)	+= hv_storvsc.o
-obj-$(CONFIG_HYPERV_NET)	+= hv_netvsc.o
-obj-$(CONFIG_HYPERV_MOUSE)	+= hv_mouse.o
 
 hv_storvsc-y := storvsc_drv.o
-hv_netvsc-y := netvsc_drv.o netvsc.o rndis_filter.o
diff --git a/drivers/staging/hv/TODO b/drivers/staging/hv/TODO
index ed4d636..dea7d92 100644
--- a/drivers/staging/hv/TODO
+++ b/drivers/staging/hv/TODO
@@ -1,7 +1,5 @@
 TODO:
-	- audit the network driver
 	- audit the scsi driver
 
 Please send patches for this code to Greg Kroah-Hartman <gregkh@suse.de>,
-Hank Janssen <hjanssen@microsoft.com>, Haiyang Zhang <haiyangz@microsoft.com>,
-K. Y. Srinivasan <kys@microsoft.com>
+Haiyang Zhang <haiyangz@microsoft.com>, and K. Y. Srinivasan <kys@microsoft.com>
diff --git a/drivers/staging/hv/hv_mouse.c b/drivers/staging/hv/hv_mouse.c
deleted file mode 100644
index ccd39c7..0000000
--- a/drivers/staging/hv/hv_mouse.c
+++ /dev/null
@@ -1,599 +0,0 @@
-/*
- *  Copyright (c) 2009, Citrix Systems, Inc.
- *  Copyright (c) 2010, Microsoft Corporation.
- *  Copyright (c) 2011, Novell Inc.
- *
- *  This program is free software; you can redistribute it and/or modify it
- *  under the terms and conditions of the GNU General Public License,
- *  version 2, as published by the Free Software Foundation.
- *
- *  This program is distributed in the hope it will be useful, but WITHOUT
- *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
- *  more details.
- */
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/delay.h>
-#include <linux/device.h>
-#include <linux/workqueue.h>
-#include <linux/sched.h>
-#include <linux/wait.h>
-#include <linux/input.h>
-#include <linux/hid.h>
-#include <linux/hiddev.h>
-#include <linux/hyperv.h>
-
-
-struct hv_input_dev_info {
-	unsigned int size;
-	unsigned short vendor;
-	unsigned short product;
-	unsigned short version;
-	unsigned short reserved[11];
-};
-
-/* The maximum size of a synthetic input message. */
-#define SYNTHHID_MAX_INPUT_REPORT_SIZE 16
-
-/*
- * Current version
- *
- * History:
- * Beta, RC < 2008/1/22        1,0
- * RC > 2008/1/22              2,0
- */
-#define SYNTHHID_INPUT_VERSION_MAJOR	2
-#define SYNTHHID_INPUT_VERSION_MINOR	0
-#define SYNTHHID_INPUT_VERSION		(SYNTHHID_INPUT_VERSION_MINOR | \
-					 (SYNTHHID_INPUT_VERSION_MAJOR << 16))
-
-
-#pragma pack(push, 1)
-/*
- * Message types in the synthetic input protocol
- */
-enum synthhid_msg_type {
-	SYNTH_HID_PROTOCOL_REQUEST,
-	SYNTH_HID_PROTOCOL_RESPONSE,
-	SYNTH_HID_INITIAL_DEVICE_INFO,
-	SYNTH_HID_INITIAL_DEVICE_INFO_ACK,
-	SYNTH_HID_INPUT_REPORT,
-	SYNTH_HID_MAX
-};
-
-/*
- * Basic message structures.
- */
-struct synthhid_msg_hdr {
-	enum synthhid_msg_type type;
-	u32 size;
-};
-
-struct synthhid_msg {
-	struct synthhid_msg_hdr header;
-	char data[1]; /* Enclosed message */
-};
-
-union synthhid_version {
-	struct {
-		u16 minor_version;
-		u16 major_version;
-	};
-	u32 version;
-};
-
-/*
- * Protocol messages
- */
-struct synthhid_protocol_request {
-	struct synthhid_msg_hdr header;
-	union synthhid_version version_requested;
-};
-
-struct synthhid_protocol_response {
-	struct synthhid_msg_hdr header;
-	union synthhid_version version_requested;
-	unsigned char approved;
-};
-
-struct synthhid_device_info {
-	struct synthhid_msg_hdr header;
-	struct hv_input_dev_info hid_dev_info;
-	struct hid_descriptor hid_descriptor;
-};
-
-struct synthhid_device_info_ack {
-	struct synthhid_msg_hdr header;
-	unsigned char reserved;
-};
-
-struct synthhid_input_report {
-	struct synthhid_msg_hdr header;
-	char buffer[1];
-};
-
-#pragma pack(pop)
-
-#define INPUTVSC_SEND_RING_BUFFER_SIZE		(10*PAGE_SIZE)
-#define INPUTVSC_RECV_RING_BUFFER_SIZE		(10*PAGE_SIZE)
-
-#define NBITS(x) (((x)/BITS_PER_LONG)+1)
-
-enum pipe_prot_msg_type {
-	PIPE_MESSAGE_INVALID,
-	PIPE_MESSAGE_DATA,
-	PIPE_MESSAGE_MAXIMUM
-};
-
-
-struct pipe_prt_msg {
-	enum pipe_prot_msg_type type;
-	u32 size;
-	char data[1];
-};
-
-struct  mousevsc_prt_msg {
-	enum pipe_prot_msg_type type;
-	u32 size;
-	union {
-		struct synthhid_protocol_request request;
-		struct synthhid_protocol_response response;
-		struct synthhid_device_info_ack ack;
-	};
-};
-
-/*
- * Represents an mousevsc device
- */
-struct mousevsc_dev {
-	struct hv_device	*device;
-	unsigned char		init_complete;
-	struct mousevsc_prt_msg	protocol_req;
-	struct mousevsc_prt_msg	protocol_resp;
-	/* Synchronize the request/response if needed */
-	struct completion	wait_event;
-	int			dev_info_status;
-
-	struct hid_descriptor	*hid_desc;
-	unsigned char		*report_desc;
-	u32			report_desc_size;
-	struct hv_input_dev_info hid_dev_info;
-	int			connected;
-	struct hid_device       *hid_device;
-};
-
-
-static struct mousevsc_dev *alloc_input_device(struct hv_device *device)
-{
-	struct mousevsc_dev *input_dev;
-
-	input_dev = kzalloc(sizeof(struct mousevsc_dev), GFP_KERNEL);
-
-	if (!input_dev)
-		return NULL;
-
-	input_dev->device = device;
-	hv_set_drvdata(device, input_dev);
-	init_completion(&input_dev->wait_event);
-
-	return input_dev;
-}
-
-static void free_input_device(struct mousevsc_dev *device)
-{
-	kfree(device->hid_desc);
-	kfree(device->report_desc);
-	hv_set_drvdata(device->device, NULL);
-	kfree(device);
-}
-
-
-static void mousevsc_on_receive_device_info(struct mousevsc_dev *input_device,
-				struct synthhid_device_info *device_info)
-{
-	int ret = 0;
-	struct hid_descriptor *desc;
-	struct mousevsc_prt_msg ack;
-
-	/* Assume success for now */
-	input_device->dev_info_status = 0;
-
-	memcpy(&input_device->hid_dev_info, &device_info->hid_dev_info,
-		sizeof(struct hv_input_dev_info));
-
-	desc = &device_info->hid_descriptor;
-	WARN_ON(desc->bLength == 0);
-
-	input_device->hid_desc = kzalloc(desc->bLength, GFP_ATOMIC);
-
-	if (!input_device->hid_desc)
-		goto cleanup;
-
-	memcpy(input_device->hid_desc, desc, desc->bLength);
-
-	input_device->report_desc_size = desc->desc[0].wDescriptorLength;
-	if (input_device->report_desc_size == 0)
-		goto cleanup;
-	input_device->report_desc = kzalloc(input_device->report_desc_size,
-					  GFP_ATOMIC);
-
-	if (!input_device->report_desc)
-		goto cleanup;
-
-	memcpy(input_device->report_desc,
-	       ((unsigned char *)desc) + desc->bLength,
-	       desc->desc[0].wDescriptorLength);
-
-	/* Send the ack */
-	memset(&ack, 0, sizeof(struct mousevsc_prt_msg));
-
-	ack.type = PIPE_MESSAGE_DATA;
-	ack.size = sizeof(struct synthhid_device_info_ack);
-
-	ack.ack.header.type = SYNTH_HID_INITIAL_DEVICE_INFO_ACK;
-	ack.ack.header.size = 1;
-	ack.ack.reserved = 0;
-
-	ret = vmbus_sendpacket(input_device->device->channel,
-			&ack,
-			sizeof(struct pipe_prt_msg) - sizeof(unsigned char) +
-			sizeof(struct synthhid_device_info_ack),
-			(unsigned long)&ack,
-			VM_PKT_DATA_INBAND,
-			VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED);
-	if (ret != 0)
-		goto cleanup;
-
-	complete(&input_device->wait_event);
-
-	return;
-
-cleanup:
-	kfree(input_device->hid_desc);
-	input_device->hid_desc = NULL;
-
-	kfree(input_device->report_desc);
-	input_device->report_desc = NULL;
-
-	input_device->dev_info_status = -1;
-	complete(&input_device->wait_event);
-}
-
-static void mousevsc_on_receive(struct hv_device *device,
-				struct vmpacket_descriptor *packet)
-{
-	struct pipe_prt_msg *pipe_msg;
-	struct synthhid_msg *hid_msg;
-	struct mousevsc_dev *input_dev = hv_get_drvdata(device);
-	struct synthhid_input_report *input_report;
-
-	pipe_msg = (struct pipe_prt_msg *)((unsigned long)packet +
-						(packet->offset8 << 3));
-
-	if (pipe_msg->type != PIPE_MESSAGE_DATA)
-		return;
-
-	hid_msg = (struct synthhid_msg *)&pipe_msg->data[0];
-
-	switch (hid_msg->header.type) {
-	case SYNTH_HID_PROTOCOL_RESPONSE:
-		memcpy(&input_dev->protocol_resp, pipe_msg,
-		       pipe_msg->size + sizeof(struct pipe_prt_msg) -
-		       sizeof(unsigned char));
-		complete(&input_dev->wait_event);
-		break;
-
-	case SYNTH_HID_INITIAL_DEVICE_INFO:
-		WARN_ON(pipe_msg->size < sizeof(struct hv_input_dev_info));
-
-		/*
-		 * Parse out the device info into device attr,
-		 * hid desc and report desc
-		 */
-		mousevsc_on_receive_device_info(input_dev,
-			(struct synthhid_device_info *)&pipe_msg->data[0]);
-		break;
-	case SYNTH_HID_INPUT_REPORT:
-		input_report =
-			(struct synthhid_input_report *)&pipe_msg->data[0];
-		if (!input_dev->init_complete)
-			break;
-		hid_input_report(input_dev->hid_device,
-				HID_INPUT_REPORT, input_report->buffer,
-				input_report->header.size, 1);
-		break;
-	default:
-		pr_err("unsupported hid msg type - type %d len %d",
-		       hid_msg->header.type, hid_msg->header.size);
-		break;
-	}
-
-}
-
-static void mousevsc_on_channel_callback(void *context)
-{
-	const int packetSize = 0x100;
-	int ret = 0;
-	struct hv_device *device = (struct hv_device *)context;
-
-	u32 bytes_recvd;
-	u64 req_id;
-	unsigned char packet[0x100];
-	struct vmpacket_descriptor *desc;
-	unsigned char	*buffer = packet;
-	int	bufferlen = packetSize;
-
-
-	do {
-		ret = vmbus_recvpacket_raw(device->channel, buffer,
-					bufferlen, &bytes_recvd, &req_id);
-
-		if (ret == 0) {
-			if (bytes_recvd > 0) {
-				desc = (struct vmpacket_descriptor *)buffer;
-
-				switch (desc->type) {
-				case VM_PKT_COMP:
-					break;
-
-				case VM_PKT_DATA_INBAND:
-					mousevsc_on_receive(
-						device, desc);
-					break;
-
-				default:
-					pr_err("unhandled packet type %d, tid %llx len %d\n",
-						   desc->type,
-						   req_id,
-						   bytes_recvd);
-					break;
-				}
-
-				/* reset */
-				if (bufferlen > packetSize) {
-					kfree(buffer);
-
-					buffer = packet;
-					bufferlen = packetSize;
-				}
-			} else {
-				if (bufferlen > packetSize) {
-					kfree(buffer);
-
-					buffer = packet;
-					bufferlen = packetSize;
-				}
-				break;
-			}
-		} else if (ret == -ENOBUFS) {
-			/* Handle large packet */
-			bufferlen = bytes_recvd;
-			buffer = kzalloc(bytes_recvd, GFP_ATOMIC);
-
-			if (buffer == NULL) {
-				buffer = packet;
-				bufferlen = packetSize;
-				break;
-			}
-		}
-	} while (1);
-
-	return;
-}
-
-static int mousevsc_connect_to_vsp(struct hv_device *device)
-{
-	int ret = 0;
-	int t;
-	struct mousevsc_dev *input_dev = hv_get_drvdata(device);
-	struct mousevsc_prt_msg *request;
-	struct mousevsc_prt_msg *response;
-
-
-	request = &input_dev->protocol_req;
-
-	memset(request, 0, sizeof(struct mousevsc_prt_msg));
-
-	request->type = PIPE_MESSAGE_DATA;
-	request->size = sizeof(struct synthhid_protocol_request);
-
-	request->request.header.type = SYNTH_HID_PROTOCOL_REQUEST;
-	request->request.header.size = sizeof(unsigned int);
-	request->request.version_requested.version = SYNTHHID_INPUT_VERSION;
-
-
-	ret = vmbus_sendpacket(device->channel, request,
-				sizeof(struct pipe_prt_msg) -
-				sizeof(unsigned char) +
-				sizeof(struct synthhid_protocol_request),
-				(unsigned long)request,
-				VM_PKT_DATA_INBAND,
-				VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED);
-	if (ret != 0)
-		goto cleanup;
-
-	t = wait_for_completion_timeout(&input_dev->wait_event, 5*HZ);
-	if (t == 0) {
-		ret = -ETIMEDOUT;
-		goto cleanup;
-	}
-
-	response = &input_dev->protocol_resp;
-
-	if (!response->response.approved) {
-		pr_err("synthhid protocol request failed (version %d)",
-		       SYNTHHID_INPUT_VERSION);
-		ret = -ENODEV;
-		goto cleanup;
-	}
-
-	t = wait_for_completion_timeout(&input_dev->wait_event, 5*HZ);
-	if (t == 0) {
-		ret = -ETIMEDOUT;
-		goto cleanup;
-	}
-
-	/*
-	 * We should have gotten the device attr, hid desc and report
-	 * desc at this point
-	 */
-	if (input_dev->dev_info_status)
-		ret = -ENOMEM;
-
-cleanup:
-
-	return ret;
-}
-
-static int mousevsc_hid_open(struct hid_device *hid)
-{
-	return 0;
-}
-
-static void mousevsc_hid_close(struct hid_device *hid)
-{
-}
-
-static struct hid_ll_driver mousevsc_ll_driver = {
-	.open = mousevsc_hid_open,
-	.close = mousevsc_hid_close,
-};
-
-static struct hid_driver mousevsc_hid_driver;
-
-static void reportdesc_callback(struct hv_device *dev, void *packet, u32 len)
-{
-	struct hid_device *hid_dev;
-	struct mousevsc_dev *input_device = hv_get_drvdata(dev);
-
-	hid_dev = hid_allocate_device();
-	if (IS_ERR(hid_dev))
-		return;
-
-	hid_dev->ll_driver = &mousevsc_ll_driver;
-	hid_dev->driver = &mousevsc_hid_driver;
-
-	if (hid_parse_report(hid_dev, packet, len))
-		return;
-
-	hid_dev->bus = BUS_VIRTUAL;
-	hid_dev->vendor = input_device->hid_dev_info.vendor;
-	hid_dev->product = input_device->hid_dev_info.product;
-	hid_dev->version = input_device->hid_dev_info.version;
-
-	sprintf(hid_dev->name, "%s", "Microsoft Vmbus HID-compliant Mouse");
-
-	if (!hidinput_connect(hid_dev, 0)) {
-		hid_dev->claimed |= HID_CLAIMED_INPUT;
-
-		input_device->connected = 1;
-
-	}
-
-	input_device->hid_device = hid_dev;
-}
-
-static int mousevsc_on_device_add(struct hv_device *device)
-{
-	int ret = 0;
-	struct mousevsc_dev *input_dev;
-
-	input_dev = alloc_input_device(device);
-
-	if (!input_dev)
-		return -ENOMEM;
-
-	input_dev->init_complete = false;
-
-	ret = vmbus_open(device->channel,
-		INPUTVSC_SEND_RING_BUFFER_SIZE,
-		INPUTVSC_RECV_RING_BUFFER_SIZE,
-		NULL,
-		0,
-		mousevsc_on_channel_callback,
-		device
-		);
-
-	if (ret != 0) {
-		free_input_device(input_dev);
-		return ret;
-	}
-
-
-	ret = mousevsc_connect_to_vsp(device);
-
-	if (ret != 0) {
-		vmbus_close(device->channel);
-		free_input_device(input_dev);
-		return ret;
-	}
-
-
-	/* workaround SA-167 */
-	if (input_dev->report_desc[14] == 0x25)
-		input_dev->report_desc[14] = 0x29;
-
-	reportdesc_callback(device, input_dev->report_desc,
-			    input_dev->report_desc_size);
-
-	input_dev->init_complete = true;
-
-	return ret;
-}
-
-static int mousevsc_probe(struct hv_device *dev,
-			const struct hv_vmbus_device_id *dev_id)
-{
-
-	return mousevsc_on_device_add(dev);
-
-}
-
-static int mousevsc_remove(struct hv_device *dev)
-{
-	struct mousevsc_dev *input_dev = hv_get_drvdata(dev);
-
-	vmbus_close(dev->channel);
-
-	if (input_dev->connected) {
-		hidinput_disconnect(input_dev->hid_device);
-		input_dev->connected = 0;
-		hid_destroy_device(input_dev->hid_device);
-	}
-
-	free_input_device(input_dev);
-
-	return 0;
-}
-
-static const struct hv_vmbus_device_id id_table[] = {
-	/* Mouse guid */
-	{ VMBUS_DEVICE(0x9E, 0xB6, 0xA8, 0xCF, 0x4A, 0x5B, 0xc0, 0x4c,
-		       0xB9, 0x8B, 0x8B, 0xA1, 0xA1, 0xF3, 0xF9, 0x5A) },
-	{ },
-};
-
-MODULE_DEVICE_TABLE(vmbus, id_table);
-
-static struct  hv_driver mousevsc_drv = {
-	.name = "mousevsc",
-	.id_table = id_table,
-	.probe = mousevsc_probe,
-	.remove = mousevsc_remove,
-};
-
-static int __init mousevsc_init(void)
-{
-	return vmbus_driver_register(&mousevsc_drv);
-}
-
-static void __exit mousevsc_exit(void)
-{
-	vmbus_driver_unregister(&mousevsc_drv);
-}
-
-MODULE_LICENSE("GPL");
-MODULE_VERSION(HV_DRV_VERSION);
-module_init(mousevsc_init);
-module_exit(mousevsc_exit);
diff --git a/drivers/staging/hv/storvsc_drv.c b/drivers/staging/hv/storvsc_drv.c
index ae8c33e..eb853f7 100644
--- a/drivers/staging/hv/storvsc_drv.c
+++ b/drivers/staging/hv/storvsc_drv.c
@@ -32,6 +32,7 @@
 #include <linux/module.h>
 #include <linux/device.h>
 #include <linux/hyperv.h>
+#include <linux/mempool.h>
 #include <scsi/scsi.h>
 #include <scsi/scsi_cmnd.h>
 #include <scsi/scsi_host.h>
@@ -42,6 +43,7 @@
 #include <scsi/scsi_dbg.h>
 
 
+#define STORVSC_MIN_BUF_NR				64
 #define STORVSC_RING_BUFFER_SIZE			(20*PAGE_SIZE)
 static int storvsc_ringbuffer_size = STORVSC_RING_BUFFER_SIZE;
 
@@ -78,7 +80,7 @@
 /* V1 Beta                    0.1 */
 /* V1 RC < 2008/1/31          1.0 */
 /* V1 RC > 2008/1/31          2.0 */
-#define VMSTOR_PROTOCOL_VERSION_CURRENT VMSTOR_PROTOCOL_VERSION(2, 0)
+#define VMSTOR_PROTOCOL_VERSION_CURRENT VMSTOR_PROTOCOL_VERSION(4, 2)
 
 
 
@@ -104,7 +106,8 @@
 	VSTOR_OPERATION_END_INITIALIZATION	= 8,
 	VSTOR_OPERATION_QUERY_PROTOCOL_VERSION	= 9,
 	VSTOR_OPERATION_QUERY_PROPERTIES	= 10,
-	VSTOR_OPERATION_MAXIMUM			= 10
+	VSTOR_OPERATION_ENUMERATE_BUS		= 11,
+	VSTOR_OPERATION_MAXIMUM			= 11
 };
 
 /*
@@ -234,8 +237,6 @@
 #define STORVSC_MAX_CHANNELS				1
 #define STORVSC_MAX_CMD_LEN				16
 
-struct hv_storvsc_request;
-
 /* Matches Windows-end */
 enum storvsc_request_type {
 	WRITE_TYPE,
@@ -284,9 +285,13 @@
 	struct hv_storvsc_request reset_request;
 };
 
+struct stor_mem_pools {
+	struct kmem_cache *request_pool;
+	mempool_t *request_mempool;
+};
+
 struct hv_host_device {
 	struct hv_device *dev;
-	struct kmem_cache *request_pool;
 	unsigned int port;
 	unsigned char path;
 	unsigned char target;
@@ -302,6 +307,51 @@
 	struct hv_storvsc_request request;
 };
 
+struct storvsc_scan_work {
+	struct work_struct work;
+	struct Scsi_Host *host;
+	uint lun;
+};
+
+static void storvsc_bus_scan(struct work_struct *work)
+{
+	struct storvsc_scan_work *wrk;
+	int id, order_id;
+
+	wrk = container_of(work, struct storvsc_scan_work, work);
+	for (id = 0; id < wrk->host->max_id; ++id) {
+		if (wrk->host->reverse_ordering)
+			order_id = wrk->host->max_id - id - 1;
+		else
+			order_id = id;
+
+		scsi_scan_target(&wrk->host->shost_gendev, 0,
+				order_id, SCAN_WILD_CARD, 1);
+	}
+	kfree(wrk);
+}
+
+static void storvsc_remove_lun(struct work_struct *work)
+{
+	struct storvsc_scan_work *wrk;
+	struct scsi_device *sdev;
+
+	wrk = container_of(work, struct storvsc_scan_work, work);
+	if (!scsi_host_get(wrk->host))
+		goto done;
+
+	sdev = scsi_device_lookup(wrk->host, 0, 0, wrk->lun);
+
+	if (sdev) {
+		scsi_remove_device(sdev);
+		scsi_device_put(sdev);
+	}
+	scsi_host_put(wrk->host);
+
+done:
+	kfree(wrk);
+}
+
 static inline struct storvsc_device *get_out_stor_device(
 					struct hv_device *device)
 {
@@ -549,11 +599,25 @@
 			     struct vstor_packet *vstor_packet,
 			     struct hv_storvsc_request *request)
 {
+	struct storvsc_scan_work *work;
+	struct storvsc_device *stor_device;
+
 	switch (vstor_packet->operation) {
 	case VSTOR_OPERATION_COMPLETE_IO:
 		storvsc_on_io_completion(device, vstor_packet, request);
 		break;
+
 	case VSTOR_OPERATION_REMOVE_DEVICE:
+	case VSTOR_OPERATION_ENUMERATE_BUS:
+		stor_device = get_in_stor_device(device);
+		work = kmalloc(sizeof(struct storvsc_scan_work), GFP_ATOMIC);
+		if (!work)
+			return;
+
+		INIT_WORK(&work->work, storvsc_bus_scan);
+		work->host = stor_device->host;
+		schedule_work(&work->work);
+		break;
 
 	default:
 		break;
@@ -729,19 +793,48 @@
 
 static int storvsc_device_alloc(struct scsi_device *sdevice)
 {
-	/*
-	 * This enables luns to be located sparsely. Otherwise, we may not
-	 * discovered them.
-	 */
-	sdevice->sdev_bflags |= BLIST_SPARSELUN | BLIST_LARGELUN;
+	struct stor_mem_pools *memp;
+	int number = STORVSC_MIN_BUF_NR;
+
+	memp = kzalloc(sizeof(struct stor_mem_pools), GFP_KERNEL);
+	if (!memp)
+		return -ENOMEM;
+
+	memp->request_pool =
+		kmem_cache_create(dev_name(&sdevice->sdev_dev),
+				sizeof(struct storvsc_cmd_request), 0,
+				SLAB_HWCACHE_ALIGN, NULL);
+
+	if (!memp->request_pool)
+		goto err0;
+
+	memp->request_mempool = mempool_create(number, mempool_alloc_slab,
+						mempool_free_slab,
+						memp->request_pool);
+
+	if (!memp->request_mempool)
+		goto err1;
+
+	sdevice->hostdata = memp;
+
 	return 0;
+
+err1:
+	kmem_cache_destroy(memp->request_pool);
+
+err0:
+	kfree(memp);
+	return -ENOMEM;
 }
 
-static int storvsc_merge_bvec(struct request_queue *q,
-			      struct bvec_merge_data *bmd, struct bio_vec *bvec)
+static void storvsc_device_destroy(struct scsi_device *sdevice)
 {
-	/* checking done by caller. */
-	return bvec->bv_len;
+	struct stor_mem_pools *memp = sdevice->hostdata;
+
+	mempool_destroy(memp->request_mempool);
+	kmem_cache_destroy(memp->request_pool);
+	kfree(memp);
+	sdevice->hostdata = NULL;
 }
 
 static int storvsc_device_configure(struct scsi_device *sdevice)
@@ -751,8 +844,6 @@
 
 	blk_queue_max_segment_size(sdevice->request_queue, PAGE_SIZE);
 
-	blk_queue_merge_bvec(sdevice->request_queue, storvsc_merge_bvec);
-
 	blk_queue_bounce_limit(sdevice->request_queue, BLK_BOUNCE_ANY);
 
 	return 0;
@@ -802,12 +893,14 @@
 
 static struct scatterlist *create_bounce_buffer(struct scatterlist *sgl,
 						unsigned int sg_count,
-						unsigned int len)
+						unsigned int len,
+						int write)
 {
 	int i;
 	int num_pages;
 	struct scatterlist *bounce_sgl;
 	struct page *page_buf;
+	unsigned int buf_len = ((write == WRITE_TYPE) ? 0 : PAGE_SIZE);
 
 	num_pages = ALIGN(len, PAGE_SIZE) >> PAGE_SHIFT;
 
@@ -819,7 +912,7 @@
 		page_buf = alloc_page(GFP_ATOMIC);
 		if (!page_buf)
 			goto cleanup;
-		sg_set_page(&bounce_sgl[i], page_buf, 0, 0);
+		sg_set_page(&bounce_sgl[i], page_buf, buf_len, 0);
 	}
 
 	return bounce_sgl;
@@ -833,7 +926,8 @@
 /* Assume the original sgl has enough room */
 static unsigned int copy_from_bounce_buffer(struct scatterlist *orig_sgl,
 					    struct scatterlist *bounce_sgl,
-					    unsigned int orig_sgl_count)
+					    unsigned int orig_sgl_count,
+					    unsigned int bounce_sgl_count)
 {
 	int i;
 	int j = 0;
@@ -874,6 +968,24 @@
 				kunmap_atomic((void *)bounce_addr, KM_IRQ0);
 				j++;
 
+				/*
+				 * It is possible that the number of elements
+				 * in the bounce buffer may not be equal to
+				 * the number of elements in the original
+				 * scatter list. Handle this correctly.
+				 */
+
+				if (j == bounce_sgl_count) {
+					/*
+					 * We are done; cleanup and return.
+					 */
+					kunmap_atomic((void *)(dest_addr -
+							orig_sgl[i].offset),
+							KM_IRQ0);
+					local_irq_restore(flags);
+					return total_copied;
+				}
+
 				/* if we need to use another bounce buffer */
 				if (destlen || i != orig_sgl_count - 1)
 					bounce_addr =
@@ -965,18 +1077,13 @@
 {
 	struct storvsc_device *stor_device = hv_get_drvdata(dev);
 	struct Scsi_Host *host = stor_device->host;
-	struct hv_host_device *host_dev =
-			(struct hv_host_device *)host->hostdata;
 
 	scsi_remove_host(host);
 
 	scsi_host_put(host);
 
 	storvsc_dev_remove(dev);
-	if (host_dev->request_pool) {
-		kmem_cache_destroy(host_dev->request_pool);
-		host_dev->request_pool = NULL;
-	}
+
 	return 0;
 }
 
@@ -1014,7 +1121,7 @@
 
 	stor_device = get_out_stor_device(device);
 	if (!stor_device)
-		return -ENODEV;
+		return FAILED;
 
 	request = &stor_device->reset_request;
 	vstor_packet = &request->vstor_packet;
@@ -1031,13 +1138,11 @@
 			       VM_PKT_DATA_INBAND,
 			       VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED);
 	if (ret != 0)
-		goto cleanup;
+		return FAILED;
 
 	t = wait_for_completion_timeout(&request->wait_event, 5*HZ);
-	if (t == 0) {
-		ret = -ETIMEDOUT;
-		goto cleanup;
-	}
+	if (t == 0)
+		return TIMEOUT_ERROR;
 
 
 	/*
@@ -1045,8 +1150,7 @@
 	 * should have been flushed out and return to us
 	 */
 
-cleanup:
-	return ret;
+	return SUCCESS;
 }
 
 
@@ -1055,16 +1159,10 @@
  */
 static int storvsc_host_reset_handler(struct scsi_cmnd *scmnd)
 {
-	int ret;
-	struct hv_host_device *host_dev =
-		(struct hv_host_device *)scmnd->device->host->hostdata;
+	struct hv_host_device *host_dev = shost_priv(scmnd->device->host);
 	struct hv_device *dev = host_dev->dev;
 
-	ret = storvsc_host_reset(dev);
-	if (ret != 0)
-		return ret;
-
-	return ret;
+	return storvsc_host_reset(dev);
 }
 
 
@@ -1076,21 +1174,22 @@
 	struct storvsc_cmd_request *cmd_request =
 		(struct storvsc_cmd_request *)request->context;
 	struct scsi_cmnd *scmnd = cmd_request->cmd;
-	struct hv_host_device *host_dev =
-		(struct hv_host_device *)scmnd->device->host->hostdata;
+	struct hv_host_device *host_dev = shost_priv(scmnd->device->host);
 	void (*scsi_done_fn)(struct scsi_cmnd *);
 	struct scsi_sense_hdr sense_hdr;
 	struct vmscsi_request *vm_srb;
+	struct storvsc_scan_work *wrk;
+	struct stor_mem_pools *memp = scmnd->device->hostdata;
 
 	vm_srb = &request->vstor_packet.vm_srb;
 	if (cmd_request->bounce_sgl_count) {
-		if (vm_srb->data_in == READ_TYPE) {
+		if (vm_srb->data_in == READ_TYPE)
 			copy_from_bounce_buffer(scsi_sglist(scmnd),
 					cmd_request->bounce_sgl,
-					scsi_sg_count(scmnd));
-			destroy_bounce_buffer(cmd_request->bounce_sgl,
+					scsi_sg_count(scmnd),
 					cmd_request->bounce_sgl_count);
-		}
+		destroy_bounce_buffer(cmd_request->bounce_sgl,
+					cmd_request->bounce_sgl_count);
 	}
 
 	/*
@@ -1103,6 +1202,29 @@
 	else
 		scmnd->result = vm_srb->scsi_status;
 
+	/*
+	 * If the LUN is invalid; remove the device.
+	 */
+	if (vm_srb->srb_status == 0x20) {
+		struct storvsc_device *stor_dev;
+		struct hv_device *dev = host_dev->dev;
+		struct Scsi_Host *host;
+
+		stor_dev = get_in_stor_device(dev);
+		host = stor_dev->host;
+
+		wrk = kmalloc(sizeof(struct storvsc_scan_work),
+				GFP_ATOMIC);
+		if (!wrk) {
+			scmnd->result = DID_TARGET_FAILURE << 16;
+		} else {
+			wrk->host = host;
+			wrk->lun = vm_srb->lun;
+			INIT_WORK(&wrk->work, storvsc_remove_lun);
+			schedule_work(&wrk->work);
+		}
+	}
+
 	if (scmnd->result) {
 		if (scsi_normalize_sense(scmnd->sense_buffer,
 				SCSI_SENSE_BUFFERSIZE, &sense_hdr))
@@ -1120,7 +1242,7 @@
 
 	scsi_done_fn(scmnd);
 
-	kmem_cache_free(host_dev->request_pool, cmd_request);
+	mempool_free(cmd_request, memp->request_mempool);
 }
 
 static bool storvsc_check_scsi_cmd(struct scsi_cmnd *scmnd)
@@ -1131,7 +1253,7 @@
 	switch (scsi_op) {
 	/* smartd sends this command, which will offline the device */
 	case SET_WINDOW:
-		scmnd->result = DID_ERROR << 16;
+		scmnd->result = ILLEGAL_REQUEST << 16;
 		allowed = false;
 		break;
 	default:
@@ -1143,12 +1265,10 @@
 /*
  * storvsc_queuecommand - Initiate command processing
  */
-static int storvsc_queuecommand_lck(struct scsi_cmnd *scmnd,
-				void (*done)(struct scsi_cmnd *))
+static int storvsc_queuecommand(struct Scsi_Host *host, struct scsi_cmnd *scmnd)
 {
 	int ret;
-	struct hv_host_device *host_dev =
-		(struct hv_host_device *)scmnd->device->host->hostdata;
+	struct hv_host_device *host_dev = shost_priv(host);
 	struct hv_device *dev = host_dev->dev;
 	struct hv_storvsc_request *request;
 	struct storvsc_cmd_request *cmd_request;
@@ -1157,9 +1277,10 @@
 	struct scatterlist *sgl;
 	unsigned int sg_count = 0;
 	struct vmscsi_request *vm_srb;
+	struct stor_mem_pools *memp = scmnd->device->hostdata;
 
 	if (storvsc_check_scsi_cmd(scmnd) == false) {
-		done(scmnd);
+		scmnd->scsi_done(scmnd);
 		return 0;
 	}
 
@@ -1172,16 +1293,14 @@
 		goto retry_request;
 	}
 
-	scmnd->scsi_done = done;
-
 	request_size = sizeof(struct storvsc_cmd_request);
 
-	cmd_request = kmem_cache_zalloc(host_dev->request_pool,
+	cmd_request = mempool_alloc(memp->request_mempool,
 				       GFP_ATOMIC);
-	if (!cmd_request) {
-		scmnd->scsi_done = NULL;
+	if (!cmd_request)
 		return SCSI_MLQUEUE_DEVICE_BUSY;
-	}
+
+	memset(cmd_request, 0, sizeof(struct storvsc_cmd_request));
 
 	/* Setup the cmd request */
 	cmd_request->bounce_sgl_count = 0;
@@ -1231,12 +1350,12 @@
 		if (do_bounce_buffer(sgl, scsi_sg_count(scmnd)) != -1) {
 			cmd_request->bounce_sgl =
 				create_bounce_buffer(sgl, scsi_sg_count(scmnd),
-						     scsi_bufflen(scmnd));
+						     scsi_bufflen(scmnd),
+						     vm_srb->data_in);
 			if (!cmd_request->bounce_sgl) {
-				scmnd->scsi_done = NULL;
 				scmnd->host_scribble = NULL;
-				kmem_cache_free(host_dev->request_pool,
-						cmd_request);
+				mempool_free(cmd_request,
+						memp->request_mempool);
 
 				return SCSI_MLQUEUE_HOST_BUSY;
 			}
@@ -1278,9 +1397,8 @@
 			destroy_bounce_buffer(cmd_request->bounce_sgl,
 					cmd_request->bounce_sgl_count);
 
-		kmem_cache_free(host_dev->request_pool, cmd_request);
+		mempool_free(cmd_request, memp->request_mempool);
 
-		scmnd->scsi_done = NULL;
 		scmnd->host_scribble = NULL;
 
 		ret = SCSI_MLQUEUE_DEVICE_BUSY;
@@ -1289,9 +1407,6 @@
 	return ret;
 }
 
-static DEF_SCSI_QCMD(storvsc_queuecommand)
-
-
 /* Scsi driver */
 static struct scsi_host_template scsi_driver = {
 	.module	=		THIS_MODULE,
@@ -1300,6 +1415,7 @@
 	.queuecommand =		storvsc_queuecommand,
 	.eh_host_reset_handler =	storvsc_host_reset_handler,
 	.slave_alloc =		storvsc_device_alloc,
+	.slave_destroy =	storvsc_device_destroy,
 	.slave_configure =	storvsc_device_configure,
 	.cmd_per_lun =		1,
 	/* 64 max_queue * 1 target */
@@ -1308,14 +1424,7 @@
 	/* no use setting to 0 since ll_blk_rw reset it to 1 */
 	/* currently 32 */
 	.sg_tablesize =		MAX_MULTIPAGE_BUFFER_COUNT,
-	/*
-	 * ENABLE_CLUSTERING allows mutiple physically contig bio_vecs to merge
-	 * into 1 sg element. If set, we must limit the max_segment_size to
-	 * PAGE_SIZE, otherwise we may get 1 sg element that represents
-	 * multiple
-	 */
-	/* physically contig pfns (ie sg[x].length > PAGE_SIZE). */
-	.use_clustering =	ENABLE_CLUSTERING,
+	.use_clustering =	DISABLE_CLUSTERING,
 	/* Make sure we dont get a sg segment crosses a page boundary */
 	.dma_boundary =		PAGE_SIZE-1,
 };
@@ -1360,27 +1469,17 @@
 	if (!host)
 		return -ENOMEM;
 
-	host_dev = (struct hv_host_device *)host->hostdata;
+	host_dev = shost_priv(host);
 	memset(host_dev, 0, sizeof(struct hv_host_device));
 
 	host_dev->port = host->host_no;
 	host_dev->dev = device;
 
-	host_dev->request_pool =
-				kmem_cache_create(dev_name(&device->device),
-					sizeof(struct storvsc_cmd_request), 0,
-					SLAB_HWCACHE_ALIGN, NULL);
-
-	if (!host_dev->request_pool) {
-		scsi_host_put(host);
-		return -ENOMEM;
-	}
 
 	stor_device = kzalloc(sizeof(struct storvsc_device), GFP_KERNEL);
 	if (!stor_device) {
-		kmem_cache_destroy(host_dev->request_pool);
-		scsi_host_put(host);
-		return -ENOMEM;
+		ret = -ENOMEM;
+		goto err_out0;
 	}
 
 	stor_device->destroy = false;
@@ -1391,12 +1490,8 @@
 
 	stor_device->port_number = host->host_no;
 	ret = storvsc_connect_to_vsp(device, storvsc_ringbuffer_size);
-	if (ret) {
-		kmem_cache_destroy(host_dev->request_pool);
-		scsi_host_put(host);
-		kfree(stor_device);
-		return ret;
-	}
+	if (ret)
+		goto err_out1;
 
 	if (dev_is_ide)
 		storvsc_get_ide_info(device, &target, &path);
@@ -1416,7 +1511,7 @@
 	/* Register the HBA and start the scsi bus scan */
 	ret = scsi_add_host(host, &device->device);
 	if (ret != 0)
-		goto err_out;
+		goto err_out2;
 
 	if (!dev_is_ide) {
 		scsi_scan_host(host);
@@ -1425,21 +1520,32 @@
 	ret = scsi_add_device(host, 0, target, 0);
 	if (ret) {
 		scsi_remove_host(host);
-		goto err_out;
+		goto err_out2;
 	}
 	return 0;
 
-err_out:
+err_out2:
+	/*
+	 * Once we have connected with the host, we would need to
+	 * to invoke storvsc_dev_remove() to rollback this state and
+	 * this call also frees up the stor_device; hence the jump around
+	 * err_out1 label.
+	 */
 	storvsc_dev_remove(device);
-	kmem_cache_destroy(host_dev->request_pool);
+	goto err_out0;
+
+err_out1:
+	kfree(stor_device);
+
+err_out0:
 	scsi_host_put(host);
-	return -ENODEV;
+	return ret;
 }
 
 /* The one and only one */
 
 static struct hv_driver storvsc_drv = {
-	.name = "storvsc",
+	.name = KBUILD_MODNAME,
 	.id_table = id_table,
 	.probe = storvsc_probe,
 	.remove = storvsc_remove,
diff --git a/drivers/staging/iio/Documentation/generic_buffer.c b/drivers/staging/iio/Documentation/generic_buffer.c
index d580953..69a05b9 100644
--- a/drivers/staging/iio/Documentation/generic_buffer.c
+++ b/drivers/staging/iio/Documentation/generic_buffer.c
@@ -28,6 +28,7 @@
 #include <linux/types.h>
 #include <string.h>
 #include <poll.h>
+#include <endian.h>
 #include "iio_utils.h"
 
 /**
@@ -56,6 +57,13 @@
 
 void print2byte(int input, struct iio_channel_info *info)
 {
+	/* First swap if incorrect endian */
+
+	if (info->be)
+		input = be16toh((uint_16t)input);
+	else
+		input = le16toh((uint_16t)input);
+
 	/* shift before conversion to avoid sign extension
 	   of left aligned data */
 	input = input >> info->shift;
diff --git a/drivers/staging/iio/Documentation/iio_utils.h b/drivers/staging/iio/Documentation/iio_utils.h
index 75938b2..6f3a392 100644
--- a/drivers/staging/iio/Documentation/iio_utils.h
+++ b/drivers/staging/iio/Documentation/iio_utils.h
@@ -13,6 +13,7 @@
 #include <ctype.h>
 #include <stdio.h>
 #include <stdint.h>
+#include <dirent.h>
 
 #define IIO_MAX_NAME_LENGTH 30
 
@@ -73,6 +74,7 @@
 	unsigned bits_used;
 	unsigned shift;
 	uint64_t mask;
+	unsigned be;
 	unsigned is_signed;
 	unsigned enabled;
 	unsigned location;
@@ -83,6 +85,7 @@
  * @is_signed: output whether channel is signed
  * @bytes: output how many bytes the channel storage occupies
  * @mask: output a bit mask for the raw data
+ * @be: big endian
  * @device_dir: the iio device directory
  * @name: the channel name
  * @generic_name: the channel type name
@@ -92,6 +95,7 @@
 			     unsigned *bits_used,
 			     unsigned *shift,
 			     uint64_t *mask,
+			     unsigned *be,
 			     const char *device_dir,
 			     const char *name,
 			     const char *generic_name)
@@ -100,7 +104,7 @@
 	int ret;
 	DIR *dp;
 	char *scan_el_dir, *builtname, *builtname_generic, *filename = 0;
-	char signchar;
+	char signchar, endianchar;
 	unsigned padint;
 	const struct dirent *ent;
 
@@ -144,9 +148,18 @@
 				ret = -errno;
 				goto error_free_filename;
 			}
-			fscanf(sysfsfp,
-			       "%c%u/%u>>%u", &signchar, bits_used,
-			       &padint, shift);
+
+			ret = fscanf(sysfsfp,
+				     "%ce:%c%u/%u>>%u",
+				     &endianchar,
+				     &signchar,
+				     bits_used,
+				     &padint, shift);
+			if (ret < 0) {
+				printf("failed to pass scan type description\n");
+				return ret;
+			}
+			*be = (endianchar == 'b');
 			*bytes = padint / 8;
 			if (*bits_used == 64)
 				*mask = ~0;
@@ -156,6 +169,10 @@
 				*is_signed = 1;
 			else
 				*is_signed = 0;
+			fclose(sysfsfp);
+			free(filename);
+
+			filename = 0;
 		}
 error_free_filename:
 	if (filename)
@@ -386,6 +403,7 @@
 						&current->bits_used,
 						&current->shift,
 						&current->mask,
+						&current->be,
 						device_dir,
 						current->name,
 						current->generic_name);
diff --git a/drivers/staging/iio/Documentation/ring.txt b/drivers/staging/iio/Documentation/ring.txt
index 7e99ef2..e338077 100644
--- a/drivers/staging/iio/Documentation/ring.txt
+++ b/drivers/staging/iio/Documentation/ring.txt
@@ -23,10 +23,6 @@
 as much buffer functionality as possible. Note almost all of these
 are optional.
 
-mark_in_use, unmark_in_use
-  Basically indicate that not changes should be made to the buffer state that
-  will effect the form of the data being captures (e.g. scan elements or length)
-
 store_to
   If possible, push data to the buffer.
 
@@ -39,8 +35,6 @@
   The primary buffer reading function. Note that it may well not return
   as much data as requested.
 
-mark_param_changed
-  Used to indicate that something has changed. Used in conjunction with
 request_update
   If parameters have changed that require reinitialization or configuration of
   the buffer this will trigger it.
@@ -51,7 +45,3 @@
 get_length / set_length
   Get/set the number of complete scans that may be held by the buffer.
 
-is_enabled
-  Query if ring buffer is in use
-enable
-  Start the ring buffer.
diff --git a/drivers/staging/iio/Documentation/sysfs-bus-iio b/drivers/staging/iio/Documentation/sysfs-bus-iio
index 0d6823d..46a995d 100644
--- a/drivers/staging/iio/Documentation/sysfs-bus-iio
+++ b/drivers/staging/iio/Documentation/sysfs-bus-iio
@@ -276,6 +276,16 @@
 		If a discrete set of scale values are available, they
 		are listed in this attribute.
 
+What:		/sys/.../in_accel_filter_low_pass_3db_frequency
+What:		/sys/.../in_magn_filter_low_pass_3db_frequency
+What:		/sys/.../in_anglvel_filter_low_pass_3db_frequency
+KernelVersion:	3.2
+Contact:	linux-iio@vger.kernel.org
+Description:
+		If a known or controllable low pass filter is applied
+		to the underlying data channel, then this parameter
+		gives the 3dB frequency of the filter in Hz.
+
 What:		/sys/bus/iio/devices/iio:deviceX/out_voltageY_raw
 KernelVersion:	2.6.37
 Contact:	linux-iio@vger.kernel.org
diff --git a/drivers/staging/iio/Kconfig b/drivers/staging/iio/Kconfig
index 4ec9118..90162aa 100644
--- a/drivers/staging/iio/Kconfig
+++ b/drivers/staging/iio/Kconfig
@@ -76,7 +76,6 @@
 
 config IIO_SIMPLE_DUMMY
        tristate "An example driver with no hardware requirements"
-       select IIO_SIMPLE_DUMMY_EVGEN if IIO_SIMPLE_DUMMY_EVENTS
        help
 	 Driver intended mainly as documentation for how to write
 	 a driver. May also be useful for testing userspace code
diff --git a/drivers/staging/iio/accel/adis16201_core.c b/drivers/staging/iio/accel/adis16201_core.c
index 97f747e..d439e45 100644
--- a/drivers/staging/iio/accel/adis16201_core.c
+++ b/drivers/staging/iio/accel/adis16201_core.c
@@ -17,7 +17,7 @@
 
 #include "../iio.h"
 #include "../sysfs.h"
-#include "../buffer_generic.h"
+#include "../buffer.h"
 
 #include "adis16201.h"
 
@@ -322,8 +322,7 @@
 		*val = val16;
 		mutex_unlock(&indio_dev->mlock);
 		return IIO_VAL_INT;
-	case (1 << IIO_CHAN_INFO_SCALE_SEPARATE):
-	case (1 << IIO_CHAN_INFO_SCALE_SHARED):
+	case IIO_CHAN_INFO_SCALE:
 		switch (chan->type) {
 		case IIO_VOLTAGE:
 			*val = 0;
@@ -348,10 +347,10 @@
 			return -EINVAL;
 		}
 		break;
-	case (1 << IIO_CHAN_INFO_OFFSET_SEPARATE):
+	case IIO_CHAN_INFO_OFFSET:
 		*val = 25;
 		return IIO_VAL_INT;
-	case (1 << IIO_CHAN_INFO_CALIBBIAS_SEPARATE):
+	case IIO_CHAN_INFO_CALIBBIAS:
 		switch (chan->type) {
 		case IIO_ACCEL:
 			bits = 12;
@@ -388,7 +387,7 @@
 	s16 val16;
 	u8 addr;
 	switch (mask) {
-	case (1 << IIO_CHAN_INFO_CALIBBIAS_SEPARATE):
+	case IIO_CHAN_INFO_CALIBBIAS:
 		switch (chan->type) {
 		case IIO_ACCEL:
 			bits = 12;
@@ -408,36 +407,36 @@
 
 static struct iio_chan_spec adis16201_channels[] = {
 	IIO_CHAN(IIO_VOLTAGE, 0, 1, 0, "supply", 0, 0,
-		 (1 << IIO_CHAN_INFO_SCALE_SEPARATE),
+		 IIO_CHAN_INFO_SCALE_SEPARATE_BIT,
 		 in_supply, ADIS16201_SCAN_SUPPLY,
 		 IIO_ST('u', 12, 16, 0), 0),
 	IIO_CHAN(IIO_TEMP, 0, 1, 0, NULL, 0, 0,
-		 (1 << IIO_CHAN_INFO_SCALE_SEPARATE) |
-		 (1 << IIO_CHAN_INFO_OFFSET_SEPARATE),
+		 IIO_CHAN_INFO_SCALE_SEPARATE_BIT |
+		 IIO_CHAN_INFO_OFFSET_SEPARATE_BIT,
 		 temp, ADIS16201_SCAN_TEMP,
 		 IIO_ST('u', 12, 16, 0), 0),
 	IIO_CHAN(IIO_ACCEL, 1, 0, 0, NULL, 0, IIO_MOD_X,
-		 (1 << IIO_CHAN_INFO_SCALE_SHARED) |
-		 (1 << IIO_CHAN_INFO_CALIBBIAS_SEPARATE),
+		 IIO_CHAN_INFO_SCALE_SHARED_BIT |
+		 IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT,
 		 accel_x, ADIS16201_SCAN_ACC_X,
 		 IIO_ST('s', 14, 16, 0), 0),
 	IIO_CHAN(IIO_ACCEL, 1, 0, 0, NULL, 0, IIO_MOD_Y,
-		 (1 << IIO_CHAN_INFO_SCALE_SHARED) |
-		 (1 << IIO_CHAN_INFO_CALIBBIAS_SEPARATE),
+		 IIO_CHAN_INFO_SCALE_SHARED_BIT |
+		 IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT,
 		 accel_y, ADIS16201_SCAN_ACC_Y,
 		 IIO_ST('s', 14, 16, 0), 0),
 	IIO_CHAN(IIO_VOLTAGE, 0, 1, 0, NULL, 1, 0,
-		 (1 << IIO_CHAN_INFO_SCALE_SEPARATE),
+		 IIO_CHAN_INFO_SCALE_SEPARATE_BIT,
 		 in_aux, ADIS16201_SCAN_AUX_ADC,
 		 IIO_ST('u', 12, 16, 0), 0),
 	IIO_CHAN(IIO_INCLI, 1, 0, 0, NULL, 0, IIO_MOD_X,
-		 (1 << IIO_CHAN_INFO_SCALE_SHARED) |
-		 (1 << IIO_CHAN_INFO_CALIBBIAS_SEPARATE),
+		 IIO_CHAN_INFO_SCALE_SHARED_BIT |
+		 IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT,
 		 incli_x, ADIS16201_SCAN_INCLI_X,
 		 IIO_ST('s', 14, 16, 0), 0),
 	IIO_CHAN(IIO_INCLI, 1, 0, 0, NULL, 0, IIO_MOD_Y,
-		 (1 << IIO_CHAN_INFO_SCALE_SHARED) |
-		 (1 << IIO_CHAN_INFO_CALIBBIAS_SEPARATE),
+		 IIO_CHAN_INFO_SCALE_SHARED_BIT |
+		 IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT,
 		 incli_y, ADIS16201_SCAN_INCLI_Y,
 		 IIO_ST('s', 14, 16, 0), 0),
 	IIO_CHAN_SOFT_TIMESTAMP(7)
@@ -554,3 +553,4 @@
 MODULE_AUTHOR("Barry Song <21cnbao@gmail.com>");
 MODULE_DESCRIPTION("Analog Devices ADIS16201 Programmable Digital Vibration Sensor driver");
 MODULE_LICENSE("GPL v2");
+MODULE_ALIAS("spi:adis16201");
diff --git a/drivers/staging/iio/accel/adis16201_ring.c b/drivers/staging/iio/accel/adis16201_ring.c
index 0016ed3..26c610f 100644
--- a/drivers/staging/iio/accel/adis16201_ring.c
+++ b/drivers/staging/iio/accel/adis16201_ring.c
@@ -74,11 +74,11 @@
 		return -ENOMEM;
 	}
 
-	if (ring->scan_count)
-		if (adis16201_read_ring_data(indio_dev, st->rx) >= 0)
-			for (; i < ring->scan_count; i++)
-				data[i] = be16_to_cpup(
-					(__be16 *)&(st->rx[i*2]));
+	if (!bitmap_empty(indio_dev->active_scan_mask, indio_dev->masklength)
+	    && adis16201_read_ring_data(indio_dev, st->rx) >= 0)
+		for (; i < bitmap_weight(indio_dev->active_scan_mask,
+					 indio_dev->masklength); i++)
+			data[i] = be16_to_cpup((__be16 *)&(st->rx[i*2]));
 
 	/* Guaranteed to be aligned with 8 byte boundary */
 	if (ring->scan_timestamp)
@@ -116,11 +116,9 @@
 	}
 	indio_dev->buffer = ring;
 	/* Effectively select the ring buffer implementation */
-	ring->bpe = 2;
 	ring->scan_timestamp = true;
 	ring->access = &ring_sw_access_funcs;
-	ring->setup_ops = &adis16201_ring_setup_ops;
-	ring->owner = THIS_MODULE;
+	indio_dev->setup_ops = &adis16201_ring_setup_ops;
 
 	indio_dev->pollfunc = iio_alloc_pollfunc(&iio_pollfunc_store_time,
 						 &adis16201_trigger_handler,
diff --git a/drivers/staging/iio/accel/adis16203_core.c b/drivers/staging/iio/accel/adis16203_core.c
index a6d6d27..1a5140f 100644
--- a/drivers/staging/iio/accel/adis16203_core.c
+++ b/drivers/staging/iio/accel/adis16203_core.c
@@ -17,7 +17,7 @@
 
 #include "../iio.h"
 #include "../sysfs.h"
-#include "../buffer_generic.h"
+#include "../buffer.h"
 
 #include "adis16203.h"
 
@@ -329,8 +329,7 @@
 		*val = val16;
 		mutex_unlock(&indio_dev->mlock);
 		return IIO_VAL_INT;
-	case (1 << IIO_CHAN_INFO_SCALE_SEPARATE):
-	case (1 << IIO_CHAN_INFO_SCALE_SHARED):
+	case IIO_CHAN_INFO_SCALE:
 		switch (chan->type) {
 		case IIO_VOLTAGE:
 			*val = 0;
@@ -350,10 +349,10 @@
 		default:
 			return -EINVAL;
 		}
-	case (1 << IIO_CHAN_INFO_OFFSET_SEPARATE):
+	case IIO_CHAN_INFO_OFFSET:
 		*val = 25;
 		return IIO_VAL_INT;
-	case (1 << IIO_CHAN_INFO_CALIBBIAS_SEPARATE):
+	case IIO_CHAN_INFO_CALIBBIAS:
 		bits = 14;
 		mutex_lock(&indio_dev->mlock);
 		addr = adis16203_addresses[chan->address][1];
@@ -374,26 +373,26 @@
 
 static struct iio_chan_spec adis16203_channels[] = {
 	IIO_CHAN(IIO_VOLTAGE, 0, 1, 0, "supply", 0, 0,
-		 (1 << IIO_CHAN_INFO_SCALE_SEPARATE),
+		 IIO_CHAN_INFO_SCALE_SEPARATE_BIT,
 		 in_supply, ADIS16203_SCAN_SUPPLY,
 		 IIO_ST('u', 12, 16, 0), 0),
 	IIO_CHAN(IIO_VOLTAGE, 0, 1, 0, NULL, 1, 0,
-		 (1 << IIO_CHAN_INFO_SCALE_SEPARATE),
+		 IIO_CHAN_INFO_SCALE_SEPARATE_BIT,
 		 in_aux, ADIS16203_SCAN_AUX_ADC,
 		 IIO_ST('u', 12, 16, 0), 0),
 	IIO_CHAN(IIO_INCLI, 1, 0, 0, NULL, 0, IIO_MOD_X,
-		 (1 << IIO_CHAN_INFO_SCALE_SHARED) |
-		 (1 << IIO_CHAN_INFO_CALIBBIAS_SEPARATE),
+		 IIO_CHAN_INFO_SCALE_SHARED_BIT |
+		 IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT,
 		 incli_x, ADIS16203_SCAN_INCLI_X,
 		 IIO_ST('s', 14, 16, 0), 0),
 	/* Fixme: Not what it appears to be - see data sheet */
 	IIO_CHAN(IIO_INCLI, 1, 0, 0, NULL, 0, IIO_MOD_Y,
-		 (1 << IIO_CHAN_INFO_SCALE_SHARED),
+		 IIO_CHAN_INFO_SCALE_SHARED_BIT,
 		 incli_y, ADIS16203_SCAN_INCLI_Y,
 		 IIO_ST('s', 14, 16, 0), 0),
 	IIO_CHAN(IIO_TEMP, 0, 1, 0, NULL, 0, 0,
-		 (1 << IIO_CHAN_INFO_SCALE_SEPARATE) |
-		 (1 << IIO_CHAN_INFO_OFFSET_SEPARATE),
+		 IIO_CHAN_INFO_SCALE_SEPARATE_BIT |
+		 IIO_CHAN_INFO_OFFSET_SEPARATE_BIT,
 		 temp, ADIS16203_SCAN_TEMP,
 		 IIO_ST('u', 12, 16, 0), 0),
 	IIO_CHAN_SOFT_TIMESTAMP(5),
@@ -509,3 +508,4 @@
 MODULE_AUTHOR("Barry Song <21cnbao@gmail.com>");
 MODULE_DESCRIPTION("Analog Devices ADIS16203 Programmable Digital Vibration Sensor driver");
 MODULE_LICENSE("GPL v2");
+MODULE_ALIAS("spi:adis16203");
diff --git a/drivers/staging/iio/accel/adis16203_ring.c b/drivers/staging/iio/accel/adis16203_ring.c
index 1fdfe6f..064640d 100644
--- a/drivers/staging/iio/accel/adis16203_ring.c
+++ b/drivers/staging/iio/accel/adis16203_ring.c
@@ -74,11 +74,11 @@
 		return -ENOMEM;
 	}
 
-	if (ring->scan_count)
-		if (adis16203_read_ring_data(&indio_dev->dev, st->rx) >= 0)
-			for (; i < ring->scan_count; i++)
-				data[i] = be16_to_cpup(
-					(__be16 *)&(st->rx[i*2]));
+	if (!bitmap_empty(indio_dev->active_scan_mask, indio_dev->masklength) &&
+	    adis16203_read_ring_data(&indio_dev->dev, st->rx) >= 0)
+		for (; i < bitmap_weight(indio_dev->active_scan_mask,
+					 indio_dev->masklength); i++)
+			data[i] = be16_to_cpup((__be16 *)&(st->rx[i*2]));
 
 	/* Guaranteed to be aligned with 8 byte boundary */
 	if (ring->scan_timestamp)
@@ -118,11 +118,9 @@
 	}
 	indio_dev->buffer = ring;
 	/* Effectively select the ring buffer implementation */
-	ring->bpe = 2;
 	ring->scan_timestamp = true;
 	ring->access = &ring_sw_access_funcs;
-	ring->setup_ops = &adis16203_ring_setup_ops;
-	ring->owner = THIS_MODULE;
+	indio_dev->setup_ops = &adis16203_ring_setup_ops;
 
 	indio_dev->pollfunc = iio_alloc_pollfunc(&iio_pollfunc_store_time,
 						 &adis16203_trigger_handler,
diff --git a/drivers/staging/iio/accel/adis16204_core.c b/drivers/staging/iio/accel/adis16204_core.c
index 7ac5b4c..fa89364 100644
--- a/drivers/staging/iio/accel/adis16204_core.c
+++ b/drivers/staging/iio/accel/adis16204_core.c
@@ -20,7 +20,7 @@
 
 #include "../iio.h"
 #include "../sysfs.h"
-#include "../buffer_generic.h"
+#include "../buffer.h"
 
 #include "adis16204.h"
 
@@ -366,7 +366,7 @@
 		*val = val16;
 		mutex_unlock(&indio_dev->mlock);
 		return IIO_VAL_INT;
-	case (1 << IIO_CHAN_INFO_SCALE_SEPARATE):
+	case IIO_CHAN_INFO_SCALE:
 		switch (chan->type) {
 		case IIO_VOLTAGE:
 			*val = 0;
@@ -390,12 +390,12 @@
 			return -EINVAL;
 		}
 		break;
-	case (1 << IIO_CHAN_INFO_OFFSET_SEPARATE):
+	case IIO_CHAN_INFO_OFFSET:
 		*val = 25;
 		return IIO_VAL_INT;
-	case (1 << IIO_CHAN_INFO_CALIBBIAS_SEPARATE):
-	case (1 << IIO_CHAN_INFO_PEAK_SEPARATE):
-		if (mask == (1 << IIO_CHAN_INFO_CALIBBIAS_SEPARATE)) {
+	case IIO_CHAN_INFO_CALIBBIAS:
+	case IIO_CHAN_INFO_PEAK:
+		if (mask == IIO_CHAN_INFO_CALIBBIAS) {
 			bits = 12;
 			addrind = 1;
 		} else { /* PEAK_SEPARATE */
@@ -428,7 +428,7 @@
 	s16 val16;
 	u8 addr;
 	switch (mask) {
-	case (1 << IIO_CHAN_INFO_CALIBBIAS_SEPARATE):
+	case IIO_CHAN_INFO_CALIBBIAS:
 		switch (chan->type) {
 		case IIO_ACCEL:
 			bits = 12;
@@ -445,28 +445,28 @@
 
 static struct iio_chan_spec adis16204_channels[] = {
 	IIO_CHAN(IIO_VOLTAGE, 0, 0, 0, "supply", 0, 0,
-		 (1 << IIO_CHAN_INFO_SCALE_SEPARATE),
+		 IIO_CHAN_INFO_SCALE_SEPARATE_BIT,
 		 in_supply, ADIS16204_SCAN_SUPPLY,
 		 IIO_ST('u', 12, 16, 0), 0),
 	IIO_CHAN(IIO_VOLTAGE, 0, 1, 0, NULL, 1, 0,
-		 (1 << IIO_CHAN_INFO_SCALE_SEPARATE),
+		 IIO_CHAN_INFO_SCALE_SEPARATE_BIT,
 		 in_aux, ADIS16204_SCAN_AUX_ADC,
 		 IIO_ST('u', 12, 16, 0), 0),
 	IIO_CHAN(IIO_TEMP, 0, 1, 0, NULL, 0, 0,
-		 (1 << IIO_CHAN_INFO_SCALE_SEPARATE) |
-		 (1 << IIO_CHAN_INFO_OFFSET_SEPARATE),
+		 IIO_CHAN_INFO_SCALE_SEPARATE_BIT |
+		 IIO_CHAN_INFO_OFFSET_SEPARATE_BIT,
 		 temp, ADIS16204_SCAN_TEMP,
 		 IIO_ST('u', 12, 16, 0), 0),
 	IIO_CHAN(IIO_ACCEL, 1, 0, 0, NULL, 0, IIO_MOD_X,
-		 (1 << IIO_CHAN_INFO_SCALE_SEPARATE) |
-		 (1 << IIO_CHAN_INFO_CALIBBIAS_SEPARATE) |
-		 (1 << IIO_CHAN_INFO_PEAK_SEPARATE),
+		 IIO_CHAN_INFO_SCALE_SEPARATE_BIT |
+		 IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT |
+		 IIO_CHAN_INFO_PEAK_SEPARATE_BIT,
 		 accel_x, ADIS16204_SCAN_ACC_X,
 		 IIO_ST('s', 14, 16, 0), 0),
 	IIO_CHAN(IIO_ACCEL, 1, 0, 0, NULL, 0, IIO_MOD_Y,
-		 (1 << IIO_CHAN_INFO_SCALE_SEPARATE) |
-		 (1 << IIO_CHAN_INFO_CALIBBIAS_SEPARATE) |
-		 (1 << IIO_CHAN_INFO_PEAK_SEPARATE),
+		 IIO_CHAN_INFO_SCALE_SEPARATE_BIT |
+		 IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT |
+		 IIO_CHAN_INFO_PEAK_SEPARATE_BIT,
 		 accel_y, ADIS16204_SCAN_ACC_Y,
 		 IIO_ST('s', 14, 16, 0), 0),
 	IIO_CHAN_SOFT_TIMESTAMP(5),
@@ -582,3 +582,4 @@
 MODULE_AUTHOR("Barry Song <21cnbao@gmail.com>");
 MODULE_DESCRIPTION("ADIS16204 High-g Digital Impact Sensor and Recorder");
 MODULE_LICENSE("GPL v2");
+MODULE_ALIAS("spi:adis16204");
diff --git a/drivers/staging/iio/accel/adis16204_ring.c b/drivers/staging/iio/accel/adis16204_ring.c
index 6fd3d8f..4081179 100644
--- a/drivers/staging/iio/accel/adis16204_ring.c
+++ b/drivers/staging/iio/accel/adis16204_ring.c
@@ -71,11 +71,11 @@
 		return -ENOMEM;
 	}
 
-	if (ring->scan_count)
-		if (adis16204_read_ring_data(&indio_dev->dev, st->rx) >= 0)
-			for (; i < ring->scan_count; i++)
-				data[i] = be16_to_cpup(
-					(__be16 *)&(st->rx[i*2]));
+	if (!bitmap_empty(indio_dev->active_scan_mask, indio_dev->masklength) &&
+	    adis16204_read_ring_data(&indio_dev->dev, st->rx) >= 0)
+		for (; i < bitmap_weight(indio_dev->active_scan_mask,
+					 indio_dev->masklength); i++)
+			data[i] = be16_to_cpup((__be16 *)&(st->rx[i*2]));
 
 	/* Guaranteed to be aligned with 8 byte boundary */
 	if (ring->scan_timestamp)
@@ -114,10 +114,8 @@
 	indio_dev->buffer = ring;
 	/* Effectively select the ring buffer implementation */
 	ring->access = &ring_sw_access_funcs;
-	ring->bpe = 2;
 	ring->scan_timestamp = true;
-	ring->setup_ops = &adis16204_ring_setup_ops;
-	ring->owner = THIS_MODULE;
+	indio_dev->setup_ops = &adis16204_ring_setup_ops;
 
 	indio_dev->pollfunc = iio_alloc_pollfunc(&iio_pollfunc_store_time,
 						 &adis16204_trigger_handler,
diff --git a/drivers/staging/iio/accel/adis16209_core.c b/drivers/staging/iio/accel/adis16209_core.c
index c03afbf..a98715f 100644
--- a/drivers/staging/iio/accel/adis16209_core.c
+++ b/drivers/staging/iio/accel/adis16209_core.c
@@ -18,7 +18,7 @@
 
 #include "../iio.h"
 #include "../sysfs.h"
-#include "../buffer_generic.h"
+#include "../buffer.h"
 
 #include "adis16209.h"
 
@@ -304,7 +304,7 @@
 	s16 val16;
 	u8 addr;
 	switch (mask) {
-	case (1 << IIO_CHAN_INFO_CALIBBIAS_SEPARATE):
+	case IIO_CHAN_INFO_CALIBBIAS:
 		switch (chan->type) {
 		case IIO_ACCEL:
 		case IIO_INCLI:
@@ -355,8 +355,7 @@
 		*val = val16;
 		mutex_unlock(&indio_dev->mlock);
 		return IIO_VAL_INT;
-	case (1 << IIO_CHAN_INFO_SCALE_SEPARATE):
-	case (1 << IIO_CHAN_INFO_SCALE_SHARED):
+	case IIO_CHAN_INFO_SCALE:
 		switch (chan->type) {
 		case IIO_VOLTAGE:
 			*val = 0;
@@ -381,10 +380,10 @@
 			return -EINVAL;
 		}
 		break;
-	case (1 << IIO_CHAN_INFO_OFFSET_SEPARATE):
+	case IIO_CHAN_INFO_OFFSET:
 		*val = 25;
 		return IIO_VAL_INT;
-	case (1 << IIO_CHAN_INFO_CALIBBIAS_SEPARATE):
+	case IIO_CHAN_INFO_CALIBBIAS:
 		switch (chan->type) {
 		case IIO_ACCEL:
 			bits = 14;
@@ -410,34 +409,34 @@
 
 static struct iio_chan_spec adis16209_channels[] = {
 	IIO_CHAN(IIO_VOLTAGE, 0, 1, 0, NULL, 0, 0,
-		 (1 << IIO_CHAN_INFO_SCALE_SEPARATE),
+		 IIO_CHAN_INFO_SCALE_SEPARATE_BIT,
 		 in_supply, ADIS16209_SCAN_SUPPLY,
 		 IIO_ST('u', 14, 16, 0), 0),
 	IIO_CHAN(IIO_TEMP, 0, 1, 0, NULL, 0, 0,
-		 (1 << IIO_CHAN_INFO_SCALE_SEPARATE) |
-		 (1 << IIO_CHAN_INFO_OFFSET_SEPARATE),
+		 IIO_CHAN_INFO_SCALE_SEPARATE_BIT |
+		 IIO_CHAN_INFO_OFFSET_SEPARATE_BIT,
 		 temp, ADIS16209_SCAN_TEMP,
 		 IIO_ST('u', 12, 16, 0), 0),
 	IIO_CHAN(IIO_ACCEL, 1, 0, 0, NULL, 0, IIO_MOD_X,
-		 (1 << IIO_CHAN_INFO_SCALE_SHARED) |
-		 (1 << IIO_CHAN_INFO_CALIBBIAS_SEPARATE),
+		 IIO_CHAN_INFO_SCALE_SHARED_BIT |
+		 IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT,
 		 accel_x, ADIS16209_SCAN_ACC_X,
 		 IIO_ST('s', 14, 16, 0), 0),
 	IIO_CHAN(IIO_ACCEL, 1, 0, 0, NULL, 0, IIO_MOD_Y,
-		 (1 << IIO_CHAN_INFO_SCALE_SHARED) |
-		 (1 << IIO_CHAN_INFO_CALIBBIAS_SEPARATE),
+		 IIO_CHAN_INFO_SCALE_SHARED_BIT |
+		 IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT,
 		 accel_y, ADIS16209_SCAN_ACC_Y,
 		 IIO_ST('s', 14, 16, 0), 0),
 	IIO_CHAN(IIO_VOLTAGE, 0, 1, 0, NULL, 1, 0,
-		 (1 << IIO_CHAN_INFO_SCALE_SEPARATE),
+		 IIO_CHAN_INFO_SCALE_SEPARATE_BIT,
 		 in_aux, ADIS16209_SCAN_AUX_ADC,
 		 IIO_ST('u', 12, 16, 0), 0),
 	IIO_CHAN(IIO_INCLI, 1, 0, 0, NULL, 0, IIO_MOD_X,
-		 (1 << IIO_CHAN_INFO_SCALE_SHARED),
+		 IIO_CHAN_INFO_SCALE_SHARED_BIT,
 		 incli_x, ADIS16209_SCAN_INCLI_X,
 		 IIO_ST('s', 14, 16, 0), 0),
 	IIO_CHAN(IIO_INCLI, 1, 0, 0, NULL, 0, IIO_MOD_Y,
-		 (1 << IIO_CHAN_INFO_SCALE_SHARED),
+		 IIO_CHAN_INFO_SCALE_SHARED_BIT,
 		 incli_y, ADIS16209_SCAN_INCLI_Y,
 		 IIO_ST('s', 14, 16, 0), 0),
 	IIO_CHAN(IIO_ROT, 0, 1, 0, NULL, 0, IIO_MOD_X,
@@ -558,3 +557,4 @@
 MODULE_AUTHOR("Barry Song <21cnbao@gmail.com>");
 MODULE_DESCRIPTION("Analog Devices ADIS16209 Digital Vibration Sensor driver");
 MODULE_LICENSE("GPL v2");
+MODULE_ALIAS("spi:adis16209");
diff --git a/drivers/staging/iio/accel/adis16209_ring.c b/drivers/staging/iio/accel/adis16209_ring.c
index d17e39d..2a6fd334 100644
--- a/drivers/staging/iio/accel/adis16209_ring.c
+++ b/drivers/staging/iio/accel/adis16209_ring.c
@@ -72,9 +72,10 @@
 		return -ENOMEM;
 	}
 
-	if (ring->scan_count &&
+	if (!bitmap_empty(indio_dev->active_scan_mask, indio_dev->masklength) &&
 	    adis16209_read_ring_data(&indio_dev->dev, st->rx) >= 0)
-		for (; i < ring->scan_count; i++)
+		for (; i < bitmap_weight(indio_dev->active_scan_mask,
+					 indio_dev->masklength); i++)
 			data[i] = be16_to_cpup((__be16 *)&(st->rx[i*2]));
 
 	/* Guaranteed to be aligned with 8 byte boundary */
@@ -114,10 +115,8 @@
 	indio_dev->buffer = ring;
 	/* Effectively select the ring buffer implementation */
 	ring->access = &ring_sw_access_funcs;
-	ring->bpe = 2;
 	ring->scan_timestamp = true;
-	ring->setup_ops = &adis16209_ring_setup_ops;
-	ring->owner = THIS_MODULE;
+	indio_dev->setup_ops = &adis16209_ring_setup_ops;
 
 	indio_dev->pollfunc = iio_alloc_pollfunc(&iio_pollfunc_store_time,
 						 &adis16209_trigger_handler,
diff --git a/drivers/staging/iio/accel/adis16220_core.c b/drivers/staging/iio/accel/adis16220_core.c
index 73298e7..51a852d 100644
--- a/drivers/staging/iio/accel/adis16220_core.c
+++ b/drivers/staging/iio/accel/adis16220_core.c
@@ -167,9 +167,9 @@
 	struct iio_dev *indio_dev = dev_get_drvdata(dev);
 	struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
 	int ret;
-	long val;
+	u16 val;
 
-	ret = strict_strtol(buf, 10, &val);
+	ret = kstrtou16(buf, 10, &val);
 	if (ret)
 		goto error_ret;
 	ret = adis16220_spi_write_reg_16(indio_dev, this_attr->address, val);
@@ -510,17 +510,17 @@
 	case 0:
 		addrind = 0;
 		break;
-	case (1 << IIO_CHAN_INFO_OFFSET_SEPARATE):
+	case IIO_CHAN_INFO_OFFSET:
 		if (chan->type == IIO_TEMP) {
 			*val = 25;
 			return IIO_VAL_INT;
 		}
 		addrind = 1;
 		break;
-	case (1 << IIO_CHAN_INFO_PEAK_SEPARATE):
+	case IIO_CHAN_INFO_PEAK:
 		addrind = 2;
 		break;
-	case (1 << IIO_CHAN_INFO_SCALE_SEPARATE):
+	case IIO_CHAN_INFO_SCALE:
 		*val = 0;
 		switch (chan->type) {
 		case IIO_TEMP:
@@ -575,27 +575,27 @@
 		.indexed = 1,
 		.channel = 0,
 		.extend_name = "supply",
-		.info_mask = (1 << IIO_CHAN_INFO_SCALE_SEPARATE),
+		.info_mask = IIO_CHAN_INFO_SCALE_SEPARATE_BIT,
 		.address = in_supply,
 	}, {
 		.type = IIO_ACCEL,
-		.info_mask = (1 << IIO_CHAN_INFO_OFFSET_SEPARATE) |
-			     (1 << IIO_CHAN_INFO_SCALE_SEPARATE) |
-			     (1 << IIO_CHAN_INFO_PEAK_SEPARATE),
+		.info_mask = IIO_CHAN_INFO_OFFSET_SEPARATE_BIT |
+			     IIO_CHAN_INFO_SCALE_SEPARATE_BIT |
+			     IIO_CHAN_INFO_PEAK_SEPARATE_BIT,
 		.address = accel,
 	}, {
 		.type = IIO_TEMP,
 		.indexed = 1,
 		.channel = 0,
-		.info_mask = (1 << IIO_CHAN_INFO_OFFSET_SEPARATE) |
-			     (1 << IIO_CHAN_INFO_SCALE_SEPARATE),
+		.info_mask = IIO_CHAN_INFO_OFFSET_SEPARATE_BIT |
+			     IIO_CHAN_INFO_SCALE_SEPARATE_BIT,
 		.address = temp,
 	}, {
 		.type = IIO_VOLTAGE,
 		.indexed = 1,
 		.channel = 1,
-		.info_mask = (1 << IIO_CHAN_INFO_OFFSET_SEPARATE) |
-			     (1 << IIO_CHAN_INFO_SCALE_SEPARATE),
+		.info_mask = IIO_CHAN_INFO_OFFSET_SEPARATE_BIT |
+			     IIO_CHAN_INFO_SCALE_SEPARATE_BIT,
 		.address = in_1,
 	}, {
 		.type = IIO_VOLTAGE,
@@ -713,3 +713,4 @@
 MODULE_AUTHOR("Barry Song <21cnbao@gmail.com>");
 MODULE_DESCRIPTION("Analog Devices ADIS16220 Digital Vibration Sensor");
 MODULE_LICENSE("GPL v2");
+MODULE_ALIAS("spi:adis16220");
diff --git a/drivers/staging/iio/accel/adis16240_core.c b/drivers/staging/iio/accel/adis16240_core.c
index 88881b9..17f77fe 100644
--- a/drivers/staging/iio/accel/adis16240_core.c
+++ b/drivers/staging/iio/accel/adis16240_core.c
@@ -21,7 +21,7 @@
 
 #include "../iio.h"
 #include "../sysfs.h"
-#include "../buffer_generic.h"
+#include "../buffer.h"
 
 #include "adis16240.h"
 
@@ -389,8 +389,7 @@
 		*val = val16;
 		mutex_unlock(&indio_dev->mlock);
 		return IIO_VAL_INT;
-	case (1 << IIO_CHAN_INFO_SCALE_SEPARATE):
-	case (1 << IIO_CHAN_INFO_SCALE_SHARED):
+	case IIO_CHAN_INFO_SCALE:
 		switch (chan->type) {
 		case IIO_VOLTAGE:
 			*val = 0;
@@ -411,14 +410,14 @@
 			return -EINVAL;
 		}
 		break;
-	case (1 << IIO_CHAN_INFO_PEAK_SCALE_SHARED):
+	case IIO_CHAN_INFO_PEAK_SCALE:
 		*val = 6;
 		*val2 = 629295;
 		return IIO_VAL_INT_PLUS_MICRO;
-	case (1 << IIO_CHAN_INFO_OFFSET_SEPARATE):
+	case IIO_CHAN_INFO_OFFSET:
 		*val = 25;
 		return IIO_VAL_INT;
-	case (1 << IIO_CHAN_INFO_CALIBBIAS_SEPARATE):
+	case IIO_CHAN_INFO_CALIBBIAS:
 		bits = 10;
 		mutex_lock(&indio_dev->mlock);
 		addr = adis16240_addresses[chan->address][1];
@@ -432,7 +431,7 @@
 		*val = val16;
 		mutex_unlock(&indio_dev->mlock);
 		return IIO_VAL_INT;
-	case (1 << IIO_CHAN_INFO_PEAK_SEPARATE):
+	case IIO_CHAN_INFO_PEAK:
 		bits = 10;
 		mutex_lock(&indio_dev->mlock);
 		addr = adis16240_addresses[chan->address][2];
@@ -460,7 +459,7 @@
 	s16 val16;
 	u8 addr;
 	switch (mask) {
-	case (1 << IIO_CHAN_INFO_CALIBBIAS_SEPARATE):
+	case IIO_CHAN_INFO_CALIBBIAS:
 		val16 = val & ((1 << bits) - 1);
 		addr = adis16240_addresses[chan->address][1];
 		return adis16240_spi_write_reg_16(indio_dev, addr, val16);
@@ -470,7 +469,7 @@
 
 static struct iio_chan_spec adis16240_channels[] = {
 	IIO_CHAN(IIO_VOLTAGE, 0, 1, 0, "supply", 0, 0,
-		 (1 << IIO_CHAN_INFO_SCALE_SEPARATE),
+		 IIO_CHAN_INFO_SCALE_SEPARATE_BIT,
 		 in_supply, ADIS16240_SCAN_SUPPLY,
 		 IIO_ST('u', 10, 16, 0), 0),
 	IIO_CHAN(IIO_VOLTAGE, 0, 1, 0, NULL, 1, 0,
@@ -478,22 +477,22 @@
 		 in_aux, ADIS16240_SCAN_AUX_ADC,
 		 IIO_ST('u', 10, 16, 0), 0),
 	IIO_CHAN(IIO_ACCEL, 1, 0, 0, NULL, 0, IIO_MOD_X,
-		 (1 << IIO_CHAN_INFO_SCALE_SHARED) |
-		 (1 << IIO_CHAN_INFO_CALIBBIAS_SEPARATE),
+		 IIO_CHAN_INFO_SCALE_SHARED_BIT |
+		 IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT,
 		 accel_x, ADIS16240_SCAN_ACC_X,
 		 IIO_ST('s', 10, 16, 0), 0),
 	IIO_CHAN(IIO_ACCEL, 1, 0, 0, NULL, 0, IIO_MOD_Y,
-		 (1 << IIO_CHAN_INFO_SCALE_SHARED) |
-		 (1 << IIO_CHAN_INFO_CALIBBIAS_SEPARATE),
+		 IIO_CHAN_INFO_SCALE_SHARED_BIT |
+		 IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT,
 		 accel_y, ADIS16240_SCAN_ACC_Y,
 		 IIO_ST('s', 10, 16, 0), 0),
 	IIO_CHAN(IIO_ACCEL, 1, 0, 0, NULL, 0, IIO_MOD_Z,
-		 (1 << IIO_CHAN_INFO_SCALE_SHARED) |
-		 (1 << IIO_CHAN_INFO_CALIBBIAS_SEPARATE),
+		 IIO_CHAN_INFO_SCALE_SHARED_BIT |
+		 IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT,
 		 accel_z, ADIS16240_SCAN_ACC_Z,
 		 IIO_ST('s', 10, 16, 0), 0),
 	IIO_CHAN(IIO_TEMP, 0, 1, 0, NULL, 0, 0,
-		 (1 << IIO_CHAN_INFO_SCALE_SEPARATE),
+		 IIO_CHAN_INFO_SCALE_SEPARATE_BIT,
 		 temp, ADIS16240_SCAN_TEMP,
 		 IIO_ST('u', 10, 16, 0), 0),
 	IIO_CHAN_SOFT_TIMESTAMP(6)
@@ -611,3 +610,4 @@
 MODULE_AUTHOR("Barry Song <21cnbao@gmail.com>");
 MODULE_DESCRIPTION("Analog Devices Programmable Impact Sensor and Recorder");
 MODULE_LICENSE("GPL v2");
+MODULE_ALIAS("spi:adis16240");
diff --git a/drivers/staging/iio/accel/adis16240_ring.c b/drivers/staging/iio/accel/adis16240_ring.c
index b907ca3..e23622d 100644
--- a/drivers/staging/iio/accel/adis16240_ring.c
+++ b/drivers/staging/iio/accel/adis16240_ring.c
@@ -69,9 +69,10 @@
 		return -ENOMEM;
 	}
 
-	if (ring->scan_count &&
+	if (!bitmap_empty(indio_dev->active_scan_mask, indio_dev->masklength) &&
 	    adis16240_read_ring_data(&indio_dev->dev, st->rx) >= 0)
-		for (; i < ring->scan_count; i++)
+		for (; i < bitmap_weight(indio_dev->active_scan_mask,
+					 indio_dev->masklength); i++)
 			data[i] = be16_to_cpup((__be16 *)&(st->rx[i*2]));
 
 	/* Guaranteed to be aligned with 8 byte boundary */
@@ -111,10 +112,8 @@
 	indio_dev->buffer = ring;
 	/* Effectively select the ring buffer implementation */
 	ring->access = &ring_sw_access_funcs;
-	ring->bpe = 2;
 	ring->scan_timestamp = true;
-	ring->setup_ops = &adis16240_ring_setup_ops;
-	ring->owner = THIS_MODULE;
+	indio_dev->setup_ops = &adis16240_ring_setup_ops;
 
 	indio_dev->pollfunc = iio_alloc_pollfunc(&iio_pollfunc_store_time,
 						 &adis16240_trigger_handler,
diff --git a/drivers/staging/iio/accel/kxsd9.c b/drivers/staging/iio/accel/kxsd9.c
index cfce21c..d13d721 100644
--- a/drivers/staging/iio/accel/kxsd9.c
+++ b/drivers/staging/iio/accel/kxsd9.c
@@ -140,7 +140,7 @@
 {
 	int ret = -EINVAL;
 
-	if (mask == (1 << IIO_CHAN_INFO_SCALE_SHARED)) {
+	if (mask == IIO_CHAN_INFO_SCALE) {
 		/* Check no integer component */
 		if (val)
 			return -EINVAL;
@@ -164,7 +164,7 @@
 			goto error_ret;
 		*val = ret;
 		break;
-	case (1 << IIO_CHAN_INFO_SCALE_SHARED):
+	case IIO_CHAN_INFO_SCALE:
 		ret = spi_w8r8(st->us, KXSD9_READ(KXSD9_REG_CTRL_C));
 		if (ret)
 			goto error_ret;
@@ -181,7 +181,7 @@
 		.type = IIO_ACCEL,					\
 		.modified = 1,						\
 		.channel2 = IIO_MOD_##axis,				\
-		.info_mask = 1 << IIO_CHAN_INFO_SCALE_SHARED,		\
+		.info_mask = IIO_CHAN_INFO_SCALE_SHARED_BIT,		\
 		.address = KXSD9_REG_##axis,				\
 	}
 
@@ -268,8 +268,10 @@
 }
 
 static const struct spi_device_id kxsd9_id[] = {
-	{"kxsd9", 0}
+	{"kxsd9", 0},
+	{ },
 };
+MODULE_DEVICE_TABLE(spi, kxsd9_id);
 
 static struct spi_driver kxsd9_driver = {
 	.driver = {
diff --git a/drivers/staging/iio/accel/lis3l02dq.h b/drivers/staging/iio/accel/lis3l02dq.h
index 7237a9a..2db383f 100644
--- a/drivers/staging/iio/accel/lis3l02dq.h
+++ b/drivers/staging/iio/accel/lis3l02dq.h
@@ -181,11 +181,6 @@
 void lis3l02dq_remove_trigger(struct iio_dev *indio_dev);
 int lis3l02dq_probe_trigger(struct iio_dev *indio_dev);
 
-ssize_t lis3l02dq_read_accel_from_buffer(struct iio_buffer *buffer,
-				       int index,
-				       int *val);
-
-
 int lis3l02dq_configure_buffer(struct iio_dev *indio_dev);
 void lis3l02dq_unconfigure_buffer(struct iio_dev *indio_dev);
 
@@ -212,13 +207,6 @@
 {
 	return 0;
 }
-static inline ssize_t
-lis3l02dq_read_accel_from_buffer(struct iio_buffer *buffer,
-				 int index,
-				 int *val)
-{
-	return 0;
-}
 
 static int lis3l02dq_configure_buffer(struct iio_dev *indio_dev)
 {
diff --git a/drivers/staging/iio/accel/lis3l02dq_core.c b/drivers/staging/iio/accel/lis3l02dq_core.c
index 6877521..376da51 100644
--- a/drivers/staging/iio/accel/lis3l02dq_core.c
+++ b/drivers/staging/iio/accel/lis3l02dq_core.c
@@ -25,7 +25,8 @@
 
 #include "../iio.h"
 #include "../sysfs.h"
-#include "../buffer_generic.h"
+#include "../events.h"
+#include "../buffer.h"
 
 #include "lis3l02dq.h"
 
@@ -226,14 +227,14 @@
 	u8 uval;
 	s8 sval;
 	switch (mask) {
-	case (1 << IIO_CHAN_INFO_CALIBBIAS_SEPARATE):
+	case IIO_CHAN_INFO_CALIBBIAS:
 		if (val > 255 || val < -256)
 			return -EINVAL;
 		sval = val;
 		reg = lis3l02dq_axis_map[LIS3L02DQ_BIAS][chan->address];
 		ret = lis3l02dq_spi_write_reg_8(indio_dev, reg, sval);
 		break;
-	case (1 << IIO_CHAN_INFO_CALIBSCALE_SEPARATE):
+	case IIO_CHAN_INFO_CALIBSCALE:
 		if (val & ~0xFF)
 			return -EINVAL;
 		uval = val;
@@ -259,23 +260,20 @@
 	case 0:
 		/* Take the iio_dev status lock */
 		mutex_lock(&indio_dev->mlock);
-		if (indio_dev->currentmode == INDIO_BUFFER_TRIGGERED)
-			ret = lis3l02dq_read_accel_from_buffer(indio_dev->
-							       buffer,
-							       chan->scan_index,
-							       val);
-		else {
+		if (indio_dev->currentmode == INDIO_BUFFER_TRIGGERED) {
+			ret = -EBUSY;
+		} else {
 			reg = lis3l02dq_axis_map
 				[LIS3L02DQ_ACCEL][chan->address];
 			ret = lis3l02dq_read_reg_s16(indio_dev, reg, val);
 		}
 		mutex_unlock(&indio_dev->mlock);
 		return IIO_VAL_INT;
-	case (1 << IIO_CHAN_INFO_SCALE_SHARED):
+	case IIO_CHAN_INFO_SCALE:
 		*val = 0;
 		*val2 = 9580;
 		return IIO_VAL_INT_PLUS_MICRO;
-	case (1 << IIO_CHAN_INFO_CALIBSCALE_SEPARATE):
+	case IIO_CHAN_INFO_CALIBSCALE:
 		reg = lis3l02dq_axis_map[LIS3L02DQ_GAIN][chan->address];
 		ret = lis3l02dq_spi_read_reg_8(indio_dev, reg, &utemp);
 		if (ret)
@@ -284,7 +282,7 @@
 		*val = utemp;
 		return IIO_VAL_INT;
 
-	case (1 << IIO_CHAN_INFO_CALIBBIAS_SEPARATE):
+	case IIO_CHAN_INFO_CALIBBIAS:
 		reg = lis3l02dq_axis_map[LIS3L02DQ_BIAS][chan->address];
 		ret = lis3l02dq_spi_read_reg_8(indio_dev, reg, (u8 *)&stemp);
 		/* to match with what previous code does */
@@ -331,11 +329,11 @@
 					 size_t len)
 {
 	struct iio_dev *indio_dev = dev_get_drvdata(dev);
-	long val;
+	unsigned long val;
 	int ret;
 	u8 t;
 
-	ret = strict_strtol(buf, 10, &val);
+	ret = kstrtoul(buf, 10, &val);
 	if (ret)
 		return ret;
 
@@ -515,9 +513,9 @@
 }
 
 #define LIS3L02DQ_INFO_MASK				\
-	((1 << IIO_CHAN_INFO_SCALE_SHARED) |		\
-	 (1 << IIO_CHAN_INFO_CALIBSCALE_SEPARATE) |	\
-	 (1 << IIO_CHAN_INFO_CALIBBIAS_SEPARATE))
+	(IIO_CHAN_INFO_SCALE_SHARED_BIT |		\
+	 IIO_CHAN_INFO_CALIBSCALE_SEPARATE_BIT |	\
+	 IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT)
 
 #define LIS3L02DQ_EVENT_MASK					\
 	(IIO_EV_BIT(IIO_EV_TYPE_THRESH, IIO_EV_DIR_RISING) |	\
@@ -534,7 +532,7 @@
 };
 
 
-static ssize_t lis3l02dq_read_event_config(struct iio_dev *indio_dev,
+static int lis3l02dq_read_event_config(struct iio_dev *indio_dev,
 					   u64 event_code)
 {
 
@@ -809,3 +807,4 @@
 MODULE_AUTHOR("Jonathan Cameron <jic23@cam.ac.uk>");
 MODULE_DESCRIPTION("ST LIS3L02DQ Accelerometer SPI driver");
 MODULE_LICENSE("GPL v2");
+MODULE_ALIAS("spi:lis3l02dq");
diff --git a/drivers/staging/iio/accel/lis3l02dq_ring.c b/drivers/staging/iio/accel/lis3l02dq_ring.c
index 89527af..98c5c92 100644
--- a/drivers/staging/iio/accel/lis3l02dq_ring.c
+++ b/drivers/staging/iio/accel/lis3l02dq_ring.c
@@ -38,38 +38,6 @@
 		return IRQ_WAKE_THREAD;
 }
 
-/**
- * lis3l02dq_read_accel_from_buffer() individual acceleration read from buffer
- **/
-ssize_t lis3l02dq_read_accel_from_buffer(struct iio_buffer *buffer,
-					 int index,
-					 int *val)
-{
-	int ret;
-	s16 *data;
-
-	if (!iio_scan_mask_query(buffer, index))
-		return -EINVAL;
-
-	if (!buffer->access->read_last)
-		return -EBUSY;
-
-	data = kmalloc(buffer->access->get_bytes_per_datum(buffer),
-		       GFP_KERNEL);
-	if (data == NULL)
-		return -ENOMEM;
-
-	ret = buffer->access->read_last(buffer, (u8 *)data);
-	if (ret)
-		goto error_free_data;
-	*val = data[bitmap_weight(buffer->scan_mask, index)];
-error_free_data:
-
-	kfree(data);
-
-	return ret;
-}
-
 static const u8 read_all_tx_array[] = {
 	LIS3L02DQ_READ_REG(LIS3L02DQ_REG_OUT_X_L_ADDR), 0,
 	LIS3L02DQ_READ_REG(LIS3L02DQ_REG_OUT_X_H_ADDR), 0,
@@ -87,21 +55,21 @@
  **/
 static int lis3l02dq_read_all(struct iio_dev *indio_dev, u8 *rx_array)
 {
-	struct iio_buffer *buffer = indio_dev->buffer;
 	struct lis3l02dq_state *st = iio_priv(indio_dev);
 	struct spi_transfer *xfers;
 	struct spi_message msg;
 	int ret, i, j = 0;
 
-	xfers = kzalloc((buffer->scan_count) * 2
-			* sizeof(*xfers), GFP_KERNEL);
+	xfers = kcalloc(bitmap_weight(indio_dev->active_scan_mask,
+				      indio_dev->masklength) * 2,
+			sizeof(*xfers), GFP_KERNEL);
 	if (!xfers)
 		return -ENOMEM;
 
 	mutex_lock(&st->buf_lock);
 
 	for (i = 0; i < ARRAY_SIZE(read_all_tx_array)/4; i++)
-		if (test_bit(i, buffer->scan_mask)) {
+		if (test_bit(i, indio_dev->active_scan_mask)) {
 			/* lower byte */
 			xfers[j].tx_buf = st->tx + 2*j;
 			st->tx[2*j] = read_all_tx_array[i*4];
@@ -129,7 +97,8 @@
 	 * values in alternate bytes
 	 */
 	spi_message_init(&msg);
-	for (j = 0; j < buffer->scan_count * 2; j++)
+	for (j = 0; j < bitmap_weight(indio_dev->active_scan_mask,
+				      indio_dev->masklength) * 2; j++)
 		spi_message_add_tail(&xfers[j], &msg);
 
 	ret = spi_sync(st->us, &msg);
@@ -145,14 +114,16 @@
 	int ret, i;
 	u8 *rx_array ;
 	s16 *data = (s16 *)buf;
+	int scan_count = bitmap_weight(indio_dev->active_scan_mask,
+				       indio_dev->masklength);
 
-	rx_array = kzalloc(4 * (indio_dev->buffer->scan_count), GFP_KERNEL);
+	rx_array = kzalloc(4 * scan_count, GFP_KERNEL);
 	if (rx_array == NULL)
 		return -ENOMEM;
 	ret = lis3l02dq_read_all(indio_dev, rx_array);
 	if (ret < 0)
 		return ret;
-	for (i = 0; i < indio_dev->buffer->scan_count; i++)
+	for (i = 0; i < scan_count; i++)
 		data[i] = combine_8_to_16(rx_array[i*4+1],
 					rx_array[i*4+3]);
 	kfree(rx_array);
@@ -175,7 +146,7 @@
 		return -ENOMEM;
 	}
 
-	if (buffer->scan_count)
+	if (!bitmap_empty(indio_dev->active_scan_mask, indio_dev->masklength))
 		len = lis3l02dq_get_buffer_element(indio_dev, data);
 
 	  /* Guaranteed to be aligned with 8 byte boundary */
@@ -363,17 +334,17 @@
 	if (ret)
 		goto error_ret;
 
-	if (iio_scan_mask_query(indio_dev->buffer, 0)) {
+	if (test_bit(0, indio_dev->active_scan_mask)) {
 		t |= LIS3L02DQ_REG_CTRL_1_AXES_X_ENABLE;
 		oneenabled = true;
 	} else
 		t &= ~LIS3L02DQ_REG_CTRL_1_AXES_X_ENABLE;
-	if (iio_scan_mask_query(indio_dev->buffer, 1)) {
+	if (test_bit(1, indio_dev->active_scan_mask)) {
 		t |= LIS3L02DQ_REG_CTRL_1_AXES_Y_ENABLE;
 		oneenabled = true;
 	} else
 		t &= ~LIS3L02DQ_REG_CTRL_1_AXES_Y_ENABLE;
-	if (iio_scan_mask_query(indio_dev->buffer, 2)) {
+	if (test_bit(2, indio_dev->active_scan_mask)) {
 		t |= LIS3L02DQ_REG_CTRL_1_AXES_Z_ENABLE;
 		oneenabled = true;
 	} else
@@ -437,11 +408,9 @@
 	indio_dev->buffer = buffer;
 	/* Effectively select the buffer implementation */
 	indio_dev->buffer->access = &lis3l02dq_access_funcs;
-	buffer->bpe = 2;
 
 	buffer->scan_timestamp = true;
-	buffer->setup_ops = &lis3l02dq_buffer_setup_ops;
-	buffer->owner = THIS_MODULE;
+	indio_dev->setup_ops = &lis3l02dq_buffer_setup_ops;
 
 	/* Functions are NULL as we set handler below */
 	indio_dev->pollfunc = iio_alloc_pollfunc(&iio_pollfunc_store_time,
diff --git a/drivers/staging/iio/accel/sca3000_core.c b/drivers/staging/iio/accel/sca3000_core.c
index 6c35907..49764fb 100644
--- a/drivers/staging/iio/accel/sca3000_core.c
+++ b/drivers/staging/iio/accel/sca3000_core.c
@@ -20,7 +20,8 @@
 #include <linux/module.h>
 #include "../iio.h"
 #include "../sysfs.h"
-#include "../buffer_generic.h"
+#include "../events.h"
+#include "../buffer.h"
 
 #include "sca3000.h"
 
@@ -381,13 +382,17 @@
 	struct iio_dev *indio_dev = dev_get_drvdata(dev);
 	struct sca3000_state *st = iio_priv(indio_dev);
 	int ret;
-	int mask = 0x03;
-	long val;
+	u8 mask = 0x03;
+	u8 val;
 
 	mutex_lock(&st->lock);
-	ret = strict_strtol(buf, 10, &val);
+	ret = kstrtou8(buf, 10, &val);
 	if (ret)
 		goto error_ret;
+	if (val > 3) {
+		ret = -EINVAL;
+		goto error_ret;
+	}
 	ret = sca3000_read_data_short(st, SCA3000_REG_ADDR_MODE, 1);
 	if (ret)
 		goto error_ret;
@@ -424,7 +429,7 @@
 static IIO_DEVICE_ATTR(revision, S_IRUGO, sca3000_show_rev, NULL, 0);
 
 #define SCA3000_INFO_MASK			\
-	(1 << IIO_CHAN_INFO_SCALE_SHARED)
+	IIO_CHAN_INFO_SCALE_SHARED_BIT
 #define SCA3000_EVENT_MASK					\
 	(IIO_EV_BIT(IIO_EV_TYPE_MAG, IIO_EV_DIR_RISING))
 
@@ -474,7 +479,7 @@
 			(sizeof(*val)*8 - 13);
 		mutex_unlock(&st->lock);
 		return IIO_VAL_INT;
-	case (1 << IIO_CHAN_INFO_SCALE_SHARED):
+	case IIO_CHAN_INFO_SCALE:
 		*val = 0;
 		if (chan->type == IIO_ACCEL)
 			*val2 = st->info->scale;
@@ -1161,9 +1166,9 @@
 	if (ret < 0)
 		goto error_unregister_dev;
 	if (indio_dev->buffer) {
-		iio_scan_mask_set(indio_dev->buffer, 0);
-		iio_scan_mask_set(indio_dev->buffer, 1);
-		iio_scan_mask_set(indio_dev->buffer, 2);
+		iio_scan_mask_set(indio_dev, indio_dev->buffer, 0);
+		iio_scan_mask_set(indio_dev, indio_dev->buffer, 1);
+		iio_scan_mask_set(indio_dev, indio_dev->buffer, 2);
 	}
 
 	if (spi->irq) {
@@ -1240,6 +1245,7 @@
 	{"sca3000_e05", e05},
 	{}
 };
+MODULE_DEVICE_TABLE(spi, sca3000_id);
 
 static struct spi_driver sca3000_driver = {
 	.driver = {
diff --git a/drivers/staging/iio/accel/sca3000_ring.c b/drivers/staging/iio/accel/sca3000_ring.c
index 4a9a01d..6b824a1 100644
--- a/drivers/staging/iio/accel/sca3000_ring.c
+++ b/drivers/staging/iio/accel/sca3000_ring.c
@@ -20,7 +20,7 @@
 
 #include "../iio.h"
 #include "../sysfs.h"
-#include "../buffer_generic.h"
+#include "../buffer.h"
 #include "../ring_hw.h"
 #include "sca3000.h"
 
@@ -146,7 +146,6 @@
 }
 
 static IIO_BUFFER_ENABLE_ATTR;
-static IIO_BUFFER_BYTES_PER_DATUM_ATTR;
 static IIO_BUFFER_LENGTH_ATTR;
 
 /**
@@ -158,8 +157,7 @@
 {
 	struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
 	int ret, val;
-	struct iio_buffer *ring = dev_get_drvdata(dev);
-	struct iio_dev *indio_dev = ring->indio_dev;
+	struct iio_dev *indio_dev = dev_get_drvdata(dev);
 	struct sca3000_state *st = iio_priv(indio_dev);
 
 	mutex_lock(&st->lock);
@@ -180,8 +178,7 @@
 				      const char *buf,
 				      size_t len)
 {
-	struct iio_buffer *ring = dev_get_drvdata(dev);
-	struct iio_dev *indio_dev = ring->indio_dev;
+	struct iio_dev *indio_dev = dev_get_drvdata(dev);
 	struct sca3000_state *st = iio_priv(indio_dev);
 	struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
 	long val;
@@ -222,8 +219,7 @@
 					 struct device_attribute *attr,
 					 char *buf)
 {
-	struct iio_buffer *ring = dev_get_drvdata(dev);
-	struct iio_dev *indio_dev = ring->indio_dev;
+	struct iio_dev *indio_dev = dev_get_drvdata(dev);
 	struct sca3000_state *st = iio_priv(indio_dev);
 
 	return sprintf(buf, "0.%06d\n", 4*st->info->scale);
@@ -243,7 +239,6 @@
  */
 static struct attribute *sca3000_ring_attributes[] = {
 	&dev_attr_length.attr,
-	&dev_attr_bytes_per_datum.attr,
 	&dev_attr_enable.attr,
 	&iio_dev_attr_50_percent.dev_attr.attr,
 	&iio_dev_attr_75_percent.dev_attr.attr,
@@ -269,7 +264,7 @@
 	buf = &ring->buf;
 	buf->stufftoread = 0;
 	buf->attrs = &sca3000_ring_attr;
-	iio_buffer_init(buf, indio_dev);
+	iio_buffer_init(buf);
 
 	return buf;
 }
@@ -350,7 +345,7 @@
 
 void sca3000_register_ring_funcs(struct iio_dev *indio_dev)
 {
-	indio_dev->buffer->setup_ops = &sca3000_ring_setup_ops;
+	indio_dev->setup_ops = &sca3000_ring_setup_ops;
 }
 
 /**
diff --git a/drivers/staging/iio/adc/ad7192.c b/drivers/staging/iio/adc/ad7192.c
index 797e65c..45f4504 100644
--- a/drivers/staging/iio/adc/ad7192.c
+++ b/drivers/staging/iio/adc/ad7192.c
@@ -19,7 +19,7 @@
 
 #include "../iio.h"
 #include "../sysfs.h"
-#include "../buffer_generic.h"
+#include "../buffer.h"
 #include "../ring_sw.h"
 #include "../trigger.h"
 #include "../trigger_consumer.h"
@@ -453,25 +453,6 @@
 	return ret;
 }
 
-static int ad7192_scan_from_ring(struct ad7192_state *st, unsigned ch, int *val)
-{
-	struct iio_buffer *ring = iio_priv_to_dev(st)->buffer;
-	int ret;
-	s64 dat64[2];
-	u32 *dat32 = (u32 *)dat64;
-
-	if (!(test_bit(ch, ring->scan_mask)))
-		return  -EBUSY;
-
-	ret = ring->access->read_last(ring, (u8 *) &dat64);
-	if (ret)
-		return ret;
-
-	*val = *dat32;
-
-	return 0;
-}
-
 static int ad7192_ring_preenable(struct iio_dev *indio_dev)
 {
 	struct ad7192_state *st = iio_priv(indio_dev);
@@ -479,12 +460,14 @@
 	size_t d_size;
 	unsigned channel;
 
-	if (!ring->scan_count)
+	if (bitmap_empty(indio_dev->active_scan_mask, indio_dev->masklength))
 		return -EINVAL;
 
-	channel = find_first_bit(ring->scan_mask, indio_dev->masklength);
+	channel = find_first_bit(indio_dev->active_scan_mask,
+				 indio_dev->masklength);
 
-	d_size = ring->scan_count *
+	d_size = bitmap_weight(indio_dev->active_scan_mask,
+			       indio_dev->masklength) *
 		 indio_dev->channels[0].scan_type.storagebits / 8;
 
 	if (ring->scan_timestamp) {
@@ -544,7 +527,7 @@
 	s64 dat64[2];
 	s32 *dat32 = (s32 *)dat64;
 
-	if (ring->scan_count)
+	if (!bitmap_empty(indio_dev->active_scan_mask, indio_dev->masklength))
 		__ad7192_read_reg(st, 1, 1, AD7192_REG_DATA,
 				  dat32,
 				  indio_dev->channels[0].scan_type.realbits/8);
@@ -592,7 +575,7 @@
 	}
 
 	/* Ring buffer functions - here trigger setup related */
-	indio_dev->buffer->setup_ops = &ad7192_ring_setup_ops;
+	indio_dev->setup_ops = &ad7192_ring_setup_ops;
 
 	/* Flag that polled ring buffering is possible */
 	indio_dev->modes |= INDIO_BUFFER_TRIGGERED;
@@ -626,6 +609,10 @@
 	return IRQ_HANDLED;
 }
 
+static struct iio_trigger_ops ad7192_trigger_ops = {
+	.owner = THIS_MODULE,
+};
+
 static int ad7192_probe_trigger(struct iio_dev *indio_dev)
 {
 	struct ad7192_state *st = iio_priv(indio_dev);
@@ -638,7 +625,7 @@
 		ret = -ENOMEM;
 		goto error_ret;
 	}
-
+	st->trig->ops = &ad7192_trigger_ops;
 	ret = request_irq(st->spi->irq,
 			  ad7192_data_rdy_trig_poll,
 			  IRQF_TRIGGER_LOW,
@@ -650,7 +637,6 @@
 	disable_irq_nosync(st->spi->irq);
 	st->irq_dis = true;
 	st->trig->dev.parent = &st->spi->dev;
-	st->trig->owner = THIS_MODULE;
 	st->trig->private_data = indio_dev;
 
 	ret = iio_trigger_register(st->trig);
@@ -795,7 +781,7 @@
 		return -EBUSY;
 	}
 
-	switch (this_attr->address) {
+	switch ((u32) this_attr->address) {
 	case AD7192_REG_GPOCON:
 		if (val)
 			st->gpocon |= AD7192_GPOCON_BPDSW;
@@ -873,8 +859,7 @@
 	case 0:
 		mutex_lock(&indio_dev->mlock);
 		if (iio_buffer_enabled(indio_dev))
-			ret = ad7192_scan_from_ring(st,
-					chan->scan_index, &smpl);
+			ret = -EBUSY;
 		else
 			ret = ad7192_read(st, chan->address,
 					chan->scan_type.realbits / 8, &smpl);
@@ -901,18 +886,20 @@
 		}
 		return IIO_VAL_INT;
 
-	case (1 << IIO_CHAN_INFO_SCALE_SHARED):
-		mutex_lock(&indio_dev->mlock);
-		*val = st->scale_avail[AD7192_CONF_GAIN(st->conf)][0];
-		*val2 = st->scale_avail[AD7192_CONF_GAIN(st->conf)][1];
-		mutex_unlock(&indio_dev->mlock);
-
-		return IIO_VAL_INT_PLUS_NANO;
-
-	case (1 << IIO_CHAN_INFO_SCALE_SEPARATE):
-		*val =  1000;
-
-		return IIO_VAL_INT;
+	case IIO_CHAN_INFO_SCALE:
+		switch (chan->type) {
+		case IIO_VOLTAGE:
+			mutex_lock(&indio_dev->mlock);
+			*val = st->scale_avail[AD7192_CONF_GAIN(st->conf)][0];
+			*val2 = st->scale_avail[AD7192_CONF_GAIN(st->conf)][1];
+			mutex_unlock(&indio_dev->mlock);
+			return IIO_VAL_INT_PLUS_NANO;
+		case IIO_TEMP:
+			*val =  1000;
+			return IIO_VAL_INT;
+		default:
+			return -EINVAL;
+		}
 	}
 
 	return -EINVAL;
@@ -935,7 +922,7 @@
 	}
 
 	switch (mask) {
-	case (1 << IIO_CHAN_INFO_SCALE_SHARED):
+	case IIO_CHAN_INFO_SCALE:
 		ret = -EINVAL;
 		for (i = 0; i < ARRAY_SIZE(st->scale_avail); i++)
 			if (val2 == st->scale_avail[i][1]) {
@@ -992,7 +979,7 @@
 	  .extend_name = _name,						\
 	  .channel = _chan,						\
 	  .channel2 = _chan2,						\
-	  .info_mask = (1 << IIO_CHAN_INFO_SCALE_SHARED),		\
+	  .info_mask = IIO_CHAN_INFO_SCALE_SHARED_BIT,		\
 	  .address = _address,						\
 	  .scan_index = _si,						\
 	  .scan_type =  IIO_ST('s', 24, 32, 0)}
@@ -1001,7 +988,7 @@
 	{ .type = IIO_VOLTAGE,						\
 	  .indexed = 1,							\
 	  .channel = _chan,						\
-	  .info_mask = (1 << IIO_CHAN_INFO_SCALE_SHARED),		\
+	  .info_mask = IIO_CHAN_INFO_SCALE_SHARED_BIT,		\
 	  .address = _address,						\
 	  .scan_index = _si,						\
 	  .scan_type =  IIO_ST('s', 24, 32, 0)}
@@ -1010,7 +997,7 @@
 	{ .type = IIO_TEMP,						\
 	  .indexed = 1,							\
 	  .channel = _chan,						\
-	  .info_mask = (1 << IIO_CHAN_INFO_SCALE_SEPARATE),		\
+	  .info_mask = IIO_CHAN_INFO_SCALE_SEPARATE_BIT,		\
 	  .address = _address,						\
 	  .scan_index = _si,						\
 	  .scan_type =  IIO_ST('s', 24, 32, 0)}
@@ -1151,6 +1138,7 @@
 	{"ad7195", ID_AD7195},
 	{}
 };
+MODULE_DEVICE_TABLE(spi, ad7192_id);
 
 static struct spi_driver ad7192_driver = {
 	.driver = {
diff --git a/drivers/staging/iio/adc/ad7280a.c b/drivers/staging/iio/adc/ad7280a.c
index dbaeae8..7dbd681 100644
--- a/drivers/staging/iio/adc/ad7280a.c
+++ b/drivers/staging/iio/adc/ad7280a.c
@@ -18,6 +18,7 @@
 
 #include "../iio.h"
 #include "../sysfs.h"
+#include "../events.h"
 
 #include "ad7280a.h"
 
@@ -455,10 +456,10 @@
 	struct iio_dev *indio_dev = dev_get_drvdata(dev);
 	struct ad7280_state *st = iio_priv(indio_dev);
 	struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
-	long val;
+	unsigned long val;
 	int ret;
 
-	ret = strict_strtoul(buf, 10, &val);
+	ret = kstrtoul(buf, 10, &val);
 	if (ret)
 		return ret;
 
@@ -487,8 +488,8 @@
 {
 	int dev, ch, cnt;
 
-	st->channels = kzalloc(sizeof(*st->channels) *
-				((st->slave_num + 1) * 12 + 2), GFP_KERNEL);
+	st->channels = kcalloc((st->slave_num + 1) * 12 + 2,
+			       sizeof(*st->channels), GFP_KERNEL);
 	if (st->channels == NULL)
 		return -ENOMEM;
 
@@ -507,7 +508,7 @@
 			}
 			st->channels[cnt].indexed = 1;
 			st->channels[cnt].info_mask =
-				(1 << IIO_CHAN_INFO_SCALE_SHARED);
+				IIO_CHAN_INFO_SCALE_SHARED_BIT;
 			st->channels[cnt].address =
 				AD7280A_DEVADDR(dev) << 8 | ch;
 			st->channels[cnt].scan_index = cnt;
@@ -523,7 +524,7 @@
 	st->channels[cnt].channel2 = dev * 6;
 	st->channels[cnt].address = AD7280A_ALL_CELLS;
 	st->channels[cnt].indexed = 1;
-	st->channels[cnt].info_mask = (1 << IIO_CHAN_INFO_SCALE_SHARED);
+	st->channels[cnt].info_mask = IIO_CHAN_INFO_SCALE_SHARED_BIT;
 	st->channels[cnt].scan_index = cnt;
 	st->channels[cnt].scan_type.sign = 'u';
 	st->channels[cnt].scan_type.realbits = 32;
@@ -600,7 +601,7 @@
 	struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
 	unsigned val;
 
-	switch (this_attr->address) {
+	switch ((u32) this_attr->address) {
 	case AD7280A_CELL_OVERVOLTAGE:
 		val = 1000 + (st->cell_threshhigh * 1568) / 100;
 		break;
@@ -636,7 +637,7 @@
 	if (ret)
 		return ret;
 
-	switch (this_attr->address) {
+	switch ((u32) this_attr->address) {
 	case AD7280A_CELL_OVERVOLTAGE:
 	case AD7280A_CELL_UNDERVOLTAGE:
 		val = ((val - 1000) * 100) / 1568; /* LSB 15.68mV */
@@ -652,7 +653,7 @@
 	val = clamp(val, 0L, 0xFFL);
 
 	mutex_lock(&indio_dev->mlock);
-	switch (this_attr->address) {
+	switch ((u32) this_attr->address) {
 	case AD7280A_CELL_OVERVOLTAGE:
 		st->cell_threshhigh = val;
 		break;
@@ -682,13 +683,13 @@
 	unsigned *channels;
 	int i, ret;
 
-	channels = kzalloc(sizeof(*channels) * st->scan_cnt, GFP_KERNEL);
+	channels = kcalloc(st->scan_cnt, sizeof(*channels), GFP_KERNEL);
 	if (channels == NULL)
 		return IRQ_HANDLED;
 
 	ret = ad7280_read_all_channels(st, st->scan_cnt, channels);
 	if (ret < 0)
-		return IRQ_HANDLED;
+		goto out;
 
 	for (i = 0; i < st->scan_cnt; i++) {
 		if (((channels[i] >> 23) & 0xF) <= AD7280A_CELL_VOLTAGE_6) {
@@ -731,6 +732,7 @@
 		}
 	}
 
+out:
 	kfree(channels);
 
 	return IRQ_HANDLED;
@@ -801,7 +803,7 @@
 		*val = ret;
 
 		return IIO_VAL_INT;
-	case (1 << IIO_CHAN_INFO_SCALE_SHARED):
+	case IIO_CHAN_INFO_SCALE:
 		if ((chan->address & 0xFF) <= AD7280A_CELL_VOLTAGE_6)
 			scale_uv = (4000 * 1000) >> AD7280A_BITS;
 		else
@@ -968,11 +970,11 @@
 	{"ad7280a", 0},
 	{}
 };
+MODULE_DEVICE_TABLE(spi, ad7280_id);
 
 static struct spi_driver ad7280_driver = {
 	.driver = {
 		.name	= "ad7280",
-		.bus	= &spi_bus_type,
 		.owner	= THIS_MODULE,
 	},
 	.probe		= ad7280_probe,
diff --git a/drivers/staging/iio/adc/ad7291.c b/drivers/staging/iio/adc/ad7291.c
index aa44a52..0a13616 100644
--- a/drivers/staging/iio/adc/ad7291.c
+++ b/drivers/staging/iio/adc/ad7291.c
@@ -19,6 +19,7 @@
 
 #include "../iio.h"
 #include "../sysfs.h"
+#include "../events.h"
 
 /*
  * Simplified handling
@@ -500,7 +501,7 @@
 		default:
 			return -EINVAL;
 		}
-	case (1 << IIO_CHAN_INFO_AVERAGE_RAW_SEPARATE):
+	case IIO_CHAN_INFO_AVERAGE_RAW:
 		ret = i2c_smbus_read_word_data(chip->client,
 					       AD7291_T_AVERAGE);
 			if (ret < 0)
@@ -509,18 +510,24 @@
 				AD7291_VALUE_MASK) << 4) >> 4;
 			*val = signval;
 			return IIO_VAL_INT;
-	case (1 << IIO_CHAN_INFO_SCALE_SHARED):
-		scale_uv = (chip->int_vref_mv * 1000) >> AD7291_BITS;
-		*val =  scale_uv / 1000;
-		*val2 = (scale_uv % 1000) * 1000;
-		return IIO_VAL_INT_PLUS_MICRO;
-	case (1 << IIO_CHAN_INFO_SCALE_SEPARATE):
-		/*
-		* One LSB of the ADC corresponds to 0.25 deg C.
-		* The temperature reading is in 12-bit twos complement format
-		*/
-		*val = 250;
-		return IIO_VAL_INT;
+	case IIO_CHAN_INFO_SCALE:
+		switch (chan->type) {
+		case IIO_VOLTAGE:
+			scale_uv = (chip->int_vref_mv * 1000) >> AD7291_BITS;
+			*val =  scale_uv / 1000;
+			*val2 = (scale_uv % 1000) * 1000;
+			return IIO_VAL_INT_PLUS_MICRO;
+		case IIO_TEMP:
+			/*
+			 * One LSB of the ADC corresponds to 0.25 deg C.
+			 * The temperature reading is in 12-bit twos
+			 * complement format
+			 */
+			*val = 250;
+			return IIO_VAL_INT;
+		default:
+			return -EINVAL;
+		}
 	default:
 		return -EINVAL;
 	}
@@ -529,7 +536,7 @@
 #define AD7291_VOLTAGE_CHAN(_chan)					\
 {									\
 	.type = IIO_VOLTAGE,						\
-	.info_mask = (1 << IIO_CHAN_INFO_SCALE_SHARED),			\
+	.info_mask = IIO_CHAN_INFO_SCALE_SHARED_BIT,			\
 	.indexed = 1,							\
 	.channel = _chan,						\
 	.event_mask = IIO_EV_BIT(IIO_EV_TYPE_THRESH, IIO_EV_DIR_RISING)|\
@@ -547,8 +554,8 @@
 	AD7291_VOLTAGE_CHAN(7),
 	{
 		.type = IIO_TEMP,
-		.info_mask = (1 << IIO_CHAN_INFO_AVERAGE_RAW_SEPARATE) |
-				(1 << IIO_CHAN_INFO_SCALE_SEPARATE),
+		.info_mask = IIO_CHAN_INFO_AVERAGE_RAW_SEPARATE_BIT |
+				IIO_CHAN_INFO_SCALE_SEPARATE_BIT,
 		.indexed = 1,
 		.channel = 0,
 		.event_mask =
diff --git a/drivers/staging/iio/adc/ad7298.h b/drivers/staging/iio/adc/ad7298.h
index 9ddf5cf..a0e5dea 100644
--- a/drivers/staging/iio/adc/ad7298.h
+++ b/drivers/staging/iio/adc/ad7298.h
@@ -54,14 +54,9 @@
 };
 
 #ifdef CONFIG_IIO_BUFFER
-int ad7298_scan_from_ring(struct iio_dev *indio_dev, long ch);
 int ad7298_register_ring_funcs_and_init(struct iio_dev *indio_dev);
 void ad7298_ring_cleanup(struct iio_dev *indio_dev);
 #else /* CONFIG_IIO_BUFFER */
-static inline int ad7298_scan_from_ring(struct iio_dev *indio_dev, long ch)
-{
-	return 0;
-}
 
 static inline int
 ad7298_register_ring_funcs_and_init(struct iio_dev *indio_dev)
diff --git a/drivers/staging/iio/adc/ad7298_core.c b/drivers/staging/iio/adc/ad7298_core.c
index a799bd19..8dd6aa9 100644
--- a/drivers/staging/iio/adc/ad7298_core.c
+++ b/drivers/staging/iio/adc/ad7298_core.c
@@ -18,37 +18,37 @@
 
 #include "../iio.h"
 #include "../sysfs.h"
-#include "../buffer_generic.h"
+#include "../buffer.h"
 
 #include "ad7298.h"
 
 static struct iio_chan_spec ad7298_channels[] = {
 	IIO_CHAN(IIO_TEMP, 0, 1, 0, NULL, 0, 0,
-		 (1 << IIO_CHAN_INFO_SCALE_SEPARATE),
+		 IIO_CHAN_INFO_SCALE_SEPARATE_BIT,
 		 9, AD7298_CH_TEMP, IIO_ST('s', 32, 32, 0), 0),
 	IIO_CHAN(IIO_VOLTAGE, 0, 1, 0, NULL, 0, 0,
-		 (1 << IIO_CHAN_INFO_SCALE_SHARED),
+		 IIO_CHAN_INFO_SCALE_SHARED_BIT,
 		 0, 0, IIO_ST('u', 12, 16, 0), 0),
 	IIO_CHAN(IIO_VOLTAGE, 0, 1, 0, NULL, 1, 0,
-		 (1 << IIO_CHAN_INFO_SCALE_SHARED),
+		 IIO_CHAN_INFO_SCALE_SHARED_BIT,
 		 1, 1, IIO_ST('u', 12, 16, 0), 0),
 	IIO_CHAN(IIO_VOLTAGE, 0, 1, 0, NULL, 2, 0,
-		 (1 << IIO_CHAN_INFO_SCALE_SHARED),
+		 IIO_CHAN_INFO_SCALE_SHARED_BIT,
 		 2, 2, IIO_ST('u', 12, 16, 0), 0),
 	IIO_CHAN(IIO_VOLTAGE, 0, 1, 0, NULL, 3, 0,
-		 (1 << IIO_CHAN_INFO_SCALE_SHARED),
+		 IIO_CHAN_INFO_SCALE_SHARED_BIT,
 		 3, 3, IIO_ST('u', 12, 16, 0), 0),
 	IIO_CHAN(IIO_VOLTAGE, 0, 1, 0, NULL, 4, 0,
-		 (1 << IIO_CHAN_INFO_SCALE_SHARED),
+		 IIO_CHAN_INFO_SCALE_SHARED_BIT,
 		 4, 4, IIO_ST('u', 12, 16, 0), 0),
 	IIO_CHAN(IIO_VOLTAGE, 0, 1, 0, NULL, 5, 0,
-		 (1 << IIO_CHAN_INFO_SCALE_SHARED),
+		 IIO_CHAN_INFO_SCALE_SHARED_BIT,
 		 5, 5, IIO_ST('u', 12, 16, 0), 0),
 	IIO_CHAN(IIO_VOLTAGE, 0, 1, 0, NULL, 6, 0,
-		 (1 << IIO_CHAN_INFO_SCALE_SHARED),
+		 IIO_CHAN_INFO_SCALE_SHARED_BIT,
 		 6, 6, IIO_ST('u', 12, 16, 0), 0),
 	IIO_CHAN(IIO_VOLTAGE, 0, 1, 0, NULL, 7, 0,
-		 (1 << IIO_CHAN_INFO_SCALE_SHARED),
+		 IIO_CHAN_INFO_SCALE_SHARED_BIT,
 		 7, 7, IIO_ST('u', 12, 16, 0), 0),
 	IIO_CHAN_SOFT_TIMESTAMP(8),
 };
@@ -69,27 +69,28 @@
 static int ad7298_scan_temp(struct ad7298_state *st, int *val)
 {
 	int tmp, ret;
+	__be16 buf;
 
-	tmp = cpu_to_be16(AD7298_WRITE | AD7298_TSENSE |
+	buf = cpu_to_be16(AD7298_WRITE | AD7298_TSENSE |
 			  AD7298_TAVG | st->ext_ref);
 
-	ret = spi_write(st->spi, (u8 *)&tmp, 2);
+	ret = spi_write(st->spi, (u8 *)&buf, 2);
 	if (ret)
 		return ret;
 
-	tmp = 0;
+	buf = cpu_to_be16(0);
 
-	ret = spi_write(st->spi, (u8 *)&tmp, 2);
+	ret = spi_write(st->spi, (u8 *)&buf, 2);
 	if (ret)
 		return ret;
 
 	usleep_range(101, 1000); /* sleep > 100us */
 
-	ret = spi_read(st->spi, (u8 *)&tmp, 2);
+	ret = spi_read(st->spi, (u8 *)&buf, 2);
 	if (ret)
 		return ret;
 
-	tmp = be16_to_cpu(tmp) & RES_MASK(AD7298_BITS);
+	tmp = be16_to_cpu(buf) & RES_MASK(AD7298_BITS);
 
 	/*
 	 * One LSB of the ADC corresponds to 0.25 deg C.
@@ -122,12 +123,8 @@
 	switch (m) {
 	case 0:
 		mutex_lock(&indio_dev->mlock);
-		if (iio_buffer_enabled(indio_dev)) {
-			if (chan->address == AD7298_CH_TEMP)
-				ret = -ENODEV;
-			else
-				ret = ad7298_scan_from_ring(indio_dev,
-							    chan->address);
+		if (indio_dev->currentmode == INDIO_BUFFER_TRIGGERED) {
+			ret = -EBUSY;
 		} else {
 			if (chan->address == AD7298_CH_TEMP)
 				ret = ad7298_scan_temp(st, val);
@@ -143,15 +140,20 @@
 			*val = ret & RES_MASK(AD7298_BITS);
 
 		return IIO_VAL_INT;
-	case (1 << IIO_CHAN_INFO_SCALE_SHARED):
-		scale_uv = (st->int_vref_mv * 1000) >> AD7298_BITS;
-		*val =  scale_uv / 1000;
-		*val2 = (scale_uv % 1000) * 1000;
-		return IIO_VAL_INT_PLUS_MICRO;
-	case (1 << IIO_CHAN_INFO_SCALE_SEPARATE):
-		*val =  1;
-		*val2 = 0;
-		return IIO_VAL_INT_PLUS_MICRO;
+	case IIO_CHAN_INFO_SCALE:
+		switch (chan->type) {
+		case IIO_VOLTAGE:
+			scale_uv = (st->int_vref_mv * 1000) >> AD7298_BITS;
+			*val =  scale_uv / 1000;
+			*val2 = (scale_uv % 1000) * 1000;
+			return IIO_VAL_INT_PLUS_MICRO;
+		case IIO_TEMP:
+			*val =  1;
+			*val2 = 0;
+			return IIO_VAL_INT_PLUS_MICRO;
+		default:
+			return -EINVAL;
+		}
 	}
 	return -EINVAL;
 }
@@ -265,11 +267,11 @@
 	{"ad7298", 0},
 	{}
 };
+MODULE_DEVICE_TABLE(spi, ad7298_id);
 
 static struct spi_driver ad7298_driver = {
 	.driver = {
 		.name	= "ad7298",
-		.bus	= &spi_bus_type,
 		.owner	= THIS_MODULE,
 	},
 	.probe		= ad7298_probe,
@@ -281,4 +283,3 @@
 MODULE_AUTHOR("Michael Hennerich <hennerich@blackfin.uclinux.org>");
 MODULE_DESCRIPTION("Analog Devices AD7298 ADC");
 MODULE_LICENSE("GPL v2");
-MODULE_ALIAS("spi:ad7298");
diff --git a/drivers/staging/iio/adc/ad7298_ring.c b/drivers/staging/iio/adc/ad7298_ring.c
index 47630d5..d1a12dd 100644
--- a/drivers/staging/iio/adc/ad7298_ring.c
+++ b/drivers/staging/iio/adc/ad7298_ring.c
@@ -12,41 +12,12 @@
 #include <linux/spi/spi.h>
 
 #include "../iio.h"
-#include "../buffer_generic.h"
+#include "../buffer.h"
 #include "../ring_sw.h"
 #include "../trigger_consumer.h"
 
 #include "ad7298.h"
 
-int ad7298_scan_from_ring(struct iio_dev *indio_dev, long ch)
-{
-	struct iio_buffer *ring = indio_dev->buffer;
-	int ret;
-	u16 *ring_data;
-
-	if (!(test_bit(ch, ring->scan_mask))) {
-		ret = -EBUSY;
-		goto error_ret;
-	}
-
-	ring_data = kmalloc(ring->access->get_bytes_per_datum(ring),
-			    GFP_KERNEL);
-	if (ring_data == NULL) {
-		ret = -ENOMEM;
-		goto error_ret;
-	}
-	ret = ring->access->read_last(ring, (u8 *) ring_data);
-	if (ret)
-		goto error_free_ring_data;
-
-	ret = be16_to_cpu(ring_data[ch]);
-
-error_free_ring_data:
-	kfree(ring_data);
-error_ret:
-	return ret;
-}
-
 /**
  * ad7298_ring_preenable() setup the parameters of the ring before enabling
  *
@@ -61,8 +32,9 @@
 	size_t d_size;
 	int i, m;
 	unsigned short command;
-
-	d_size = ring->scan_count * (AD7298_STORAGE_BITS / 8);
+	int scan_count = bitmap_weight(indio_dev->active_scan_mask,
+				       indio_dev->masklength);
+	d_size = scan_count * (AD7298_STORAGE_BITS / 8);
 
 	if (ring->scan_timestamp) {
 		d_size += sizeof(s64);
@@ -79,7 +51,7 @@
 	command = AD7298_WRITE | st->ext_ref;
 
 	for (i = 0, m = AD7298_CH(0); i < AD7298_MAX_CHAN; i++, m >>= 1)
-		if (test_bit(i, ring->scan_mask))
+		if (test_bit(i, indio_dev->active_scan_mask))
 			command |= m;
 
 	st->tx_buf[0] = cpu_to_be16(command);
@@ -96,7 +68,7 @@
 	spi_message_add_tail(&st->ring_xfer[0], &st->ring_msg);
 	spi_message_add_tail(&st->ring_xfer[1], &st->ring_msg);
 
-	for (i = 0; i < ring->scan_count; i++) {
+	for (i = 0; i < scan_count; i++) {
 		st->ring_xfer[i + 2].rx_buf = &st->rx_buf[i];
 		st->ring_xfer[i + 2].len = 2;
 		st->ring_xfer[i + 2].cs_change = 1;
@@ -134,7 +106,8 @@
 			&time_ns, sizeof(time_ns));
 	}
 
-	for (i = 0; i < ring->scan_count; i++)
+	for (i = 0; i < bitmap_weight(indio_dev->active_scan_mask,
+						 indio_dev->masklength); i++)
 		buf[i] = be16_to_cpu(st->rx_buf[i]);
 
 	indio_dev->buffer->access->store_to(ring, (u8 *)buf, time_ns);
@@ -174,7 +147,7 @@
 	}
 
 	/* Ring buffer functions - here trigger setup related */
-	indio_dev->buffer->setup_ops = &ad7298_ring_setup_ops;
+	indio_dev->setup_ops = &ad7298_ring_setup_ops;
 	indio_dev->buffer->scan_timestamp = true;
 
 	/* Flag that polled ring buffering is possible */
diff --git a/drivers/staging/iio/adc/ad7476.h b/drivers/staging/iio/adc/ad7476.h
index 6014292..27f696c 100644
--- a/drivers/staging/iio/adc/ad7476.h
+++ b/drivers/staging/iio/adc/ad7476.h
@@ -50,14 +50,9 @@
 };
 
 #ifdef CONFIG_IIO_BUFFER
-int ad7476_scan_from_ring(struct iio_dev *indio_dev);
 int ad7476_register_ring_funcs_and_init(struct iio_dev *indio_dev);
 void ad7476_ring_cleanup(struct iio_dev *indio_dev);
 #else /* CONFIG_IIO_BUFFER */
-static inline int ad7476_scan_from_ring(struct iio_dev *indio_dev)
-{
-	return 0;
-}
 
 static inline int
 ad7476_register_ring_funcs_and_init(struct iio_dev *indio_dev)
diff --git a/drivers/staging/iio/adc/ad7476_core.c b/drivers/staging/iio/adc/ad7476_core.c
index 0b58520..0c064d1 100644
--- a/drivers/staging/iio/adc/ad7476_core.c
+++ b/drivers/staging/iio/adc/ad7476_core.c
@@ -17,7 +17,7 @@
 
 #include "../iio.h"
 #include "../sysfs.h"
-#include "../buffer_generic.h"
+#include "../buffer.h"
 
 #include "ad7476.h"
 
@@ -46,7 +46,7 @@
 	case 0:
 		mutex_lock(&indio_dev->mlock);
 		if (iio_buffer_enabled(indio_dev))
-			ret = ad7476_scan_from_ring(indio_dev);
+			ret = -EBUSY;
 		else
 			ret = ad7476_scan_direct(st);
 		mutex_unlock(&indio_dev->mlock);
@@ -56,7 +56,7 @@
 		*val = (ret >> st->chip_info->channel[0].scan_type.shift) &
 			RES_MASK(st->chip_info->channel[0].scan_type.realbits);
 		return IIO_VAL_INT;
-	case (1 << IIO_CHAN_INFO_SCALE_SHARED):
+	case IIO_CHAN_INFO_SCALE:
 		scale_uv = (st->int_vref_mv * 1000)
 			>> st->chip_info->channel[0].scan_type.realbits;
 		*val =  scale_uv/1000;
@@ -69,49 +69,49 @@
 static const struct ad7476_chip_info ad7476_chip_info_tbl[] = {
 	[ID_AD7466] = {
 		.channel[0] = IIO_CHAN(IIO_VOLTAGE, 0, 1, 0, NULL, 0, 0,
-				       (1 << IIO_CHAN_INFO_SCALE_SHARED),
+				       IIO_CHAN_INFO_SCALE_SHARED_BIT,
 				       0, 0, IIO_ST('u', 12, 16, 0), 0),
 		.channel[1] = IIO_CHAN_SOFT_TIMESTAMP(1),
 	},
 	[ID_AD7467] = {
 		.channel[0] = IIO_CHAN(IIO_VOLTAGE, 0, 1, 0, NULL, 0, 0,
-				       (1 << IIO_CHAN_INFO_SCALE_SHARED),
+				       IIO_CHAN_INFO_SCALE_SHARED_BIT,
 				       0, 0, IIO_ST('u', 10, 16, 2), 0),
 		.channel[1] = IIO_CHAN_SOFT_TIMESTAMP(1),
 	},
 	[ID_AD7468] = {
 		.channel[0] = IIO_CHAN(IIO_VOLTAGE, 0, 1 , 0, NULL, 0, 0,
-				       (1 << IIO_CHAN_INFO_SCALE_SHARED),
+				       IIO_CHAN_INFO_SCALE_SHARED_BIT,
 				       0, 0, IIO_ST('u', 8, 16, 4), 0),
 		.channel[1] = IIO_CHAN_SOFT_TIMESTAMP(1),
 	},
 	[ID_AD7475] = {
 		.channel[0] = IIO_CHAN(IIO_VOLTAGE, 0, 1, 0, NULL, 0, 0,
-				       (1 << IIO_CHAN_INFO_SCALE_SHARED),
+				       IIO_CHAN_INFO_SCALE_SHARED_BIT,
 				       0, 0, IIO_ST('u', 12, 16, 0), 0),
 		.channel[1] = IIO_CHAN_SOFT_TIMESTAMP(1),
 	},
 	[ID_AD7476] = {
 		.channel[0] = IIO_CHAN(IIO_VOLTAGE, 0, 1, 0, NULL, 0, 0,
-				       (1 << IIO_CHAN_INFO_SCALE_SHARED),
+				       IIO_CHAN_INFO_SCALE_SHARED_BIT,
 				       0, 0, IIO_ST('u', 12, 16, 0), 0),
 		.channel[1] = IIO_CHAN_SOFT_TIMESTAMP(1),
 	},
 	[ID_AD7477] = {
 		.channel[0] = IIO_CHAN(IIO_VOLTAGE, 0, 1, 0, NULL, 0, 0,
-				       (1 << IIO_CHAN_INFO_SCALE_SHARED),
+				       IIO_CHAN_INFO_SCALE_SHARED_BIT,
 				       0, 0, IIO_ST('u', 10, 16, 2), 0),
 		.channel[1] = IIO_CHAN_SOFT_TIMESTAMP(1),
 	},
 	[ID_AD7478] = {
 		.channel[0] = IIO_CHAN(IIO_VOLTAGE, 0, 1, 0, NULL, 0, 0,
-				       (1 << IIO_CHAN_INFO_SCALE_SHARED),
+				       IIO_CHAN_INFO_SCALE_SHARED_BIT,
 				       0, 0, IIO_ST('u', 8, 16, 4), 0),
 		.channel[1] = IIO_CHAN_SOFT_TIMESTAMP(1),
 	},
 	[ID_AD7495] = {
 		.channel[0] = IIO_CHAN(IIO_VOLTAGE, 0, 1, 0, NULL, 0, 0,
-				       (1 << IIO_CHAN_INFO_SCALE_SHARED),
+				       IIO_CHAN_INFO_SCALE_SHARED_BIT,
 				       0, 0, IIO_ST('u', 12, 16, 0), 0),
 		.channel[1] = IIO_CHAN_SOFT_TIMESTAMP(1),
 		.int_vref_mv = 2500,
@@ -237,11 +237,11 @@
 	{"ad7495", ID_AD7495},
 	{}
 };
+MODULE_DEVICE_TABLE(spi, ad7476_id);
 
 static struct spi_driver ad7476_driver = {
 	.driver = {
 		.name	= "ad7476",
-		.bus	= &spi_bus_type,
 		.owner	= THIS_MODULE,
 	},
 	.probe		= ad7476_probe,
@@ -253,4 +253,3 @@
 MODULE_AUTHOR("Michael Hennerich <hennerich@blackfin.uclinux.org>");
 MODULE_DESCRIPTION("Analog Devices AD7475/6/7/8(A) AD7466/7/8 ADC");
 MODULE_LICENSE("GPL v2");
-MODULE_ALIAS("spi:ad7476");
diff --git a/drivers/staging/iio/adc/ad7476_ring.c b/drivers/staging/iio/adc/ad7476_ring.c
index e82c1a4..4e298b2 100644
--- a/drivers/staging/iio/adc/ad7476_ring.c
+++ b/drivers/staging/iio/adc/ad7476_ring.c
@@ -14,36 +14,12 @@
 #include <linux/spi/spi.h>
 
 #include "../iio.h"
-#include "../buffer_generic.h"
+#include "../buffer.h"
 #include "../ring_sw.h"
 #include "../trigger_consumer.h"
 
 #include "ad7476.h"
 
-int ad7476_scan_from_ring(struct iio_dev *indio_dev)
-{
-	struct iio_buffer *ring = indio_dev->buffer;
-	int ret;
-	u8 *ring_data;
-
-	ring_data = kmalloc(ring->access->get_bytes_per_datum(ring),
-			    GFP_KERNEL);
-	if (ring_data == NULL) {
-		ret = -ENOMEM;
-		goto error_ret;
-	}
-	ret = ring->access->read_last(ring, ring_data);
-	if (ret)
-		goto error_free_ring_data;
-
-	ret = (ring_data[0] << 8) | ring_data[1];
-
-error_free_ring_data:
-	kfree(ring_data);
-error_ret:
-	return ret;
-}
-
 /**
  * ad7476_ring_preenable() setup the parameters of the ring before enabling
  *
@@ -56,7 +32,8 @@
 	struct ad7476_state *st = iio_priv(indio_dev);
 	struct iio_buffer *ring = indio_dev->buffer;
 
-	st->d_size = ring->scan_count *
+	st->d_size = bitmap_weight(indio_dev->active_scan_mask,
+				   indio_dev->masklength) *
 		st->chip_info->channel[0].scan_type.storagebits / 8;
 
 	if (ring->scan_timestamp) {
@@ -137,7 +114,7 @@
 	}
 
 	/* Ring buffer functions - here trigger setup related */
-	indio_dev->buffer->setup_ops = &ad7476_ring_setup_ops;
+	indio_dev->setup_ops = &ad7476_ring_setup_ops;
 	indio_dev->buffer->scan_timestamp = true;
 
 	/* Flag that polled ring buffering is possible */
diff --git a/drivers/staging/iio/adc/ad7606.h b/drivers/staging/iio/adc/ad7606.h
index 35018c3..10f5989 100644
--- a/drivers/staging/iio/adc/ad7606.h
+++ b/drivers/staging/iio/adc/ad7606.h
@@ -99,7 +99,6 @@
 	ID_AD7606_4
 };
 
-int ad7606_scan_from_ring(struct iio_dev *indio_dev, unsigned ch);
 int ad7606_register_ring_funcs_and_init(struct iio_dev *indio_dev);
 void ad7606_ring_cleanup(struct iio_dev *indio_dev);
 #endif /* IIO_ADC_AD7606_H_ */
diff --git a/drivers/staging/iio/adc/ad7606_core.c b/drivers/staging/iio/adc/ad7606_core.c
index e3ecd3d..ddb7ef9 100644
--- a/drivers/staging/iio/adc/ad7606_core.c
+++ b/drivers/staging/iio/adc/ad7606_core.c
@@ -20,7 +20,7 @@
 
 #include "../iio.h"
 #include "../sysfs.h"
-#include "../buffer_generic.h"
+#include "../buffer.h"
 
 #include "ad7606.h"
 
@@ -91,7 +91,7 @@
 	case 0:
 		mutex_lock(&indio_dev->mlock);
 		if (iio_buffer_enabled(indio_dev))
-			ret = ad7606_scan_from_ring(indio_dev, chan->address);
+			ret = -EBUSY;
 		else
 			ret = ad7606_scan_direct(indio_dev, chan->address);
 		mutex_unlock(&indio_dev->mlock);
@@ -100,7 +100,7 @@
 			return ret;
 		*val = (short) ret;
 		return IIO_VAL_INT;
-	case (1 << IIO_CHAN_INFO_SCALE_SHARED):
+	case IIO_CHAN_INFO_SCALE:
 		scale_uv = (st->range * 1000 * 2)
 			>> st->chip_info->channels[0].scan_type.realbits;
 		*val =  scale_uv / 1000;
diff --git a/drivers/staging/iio/adc/ad7606_par.c b/drivers/staging/iio/adc/ad7606_par.c
index 688632e..cff9756 100644
--- a/drivers/staging/iio/adc/ad7606_par.c
+++ b/drivers/staging/iio/adc/ad7606_par.c
@@ -189,4 +189,3 @@
 MODULE_AUTHOR("Michael Hennerich <hennerich@blackfin.uclinux.org>");
 MODULE_DESCRIPTION("Analog Devices AD7606 ADC");
 MODULE_LICENSE("GPL v2");
-MODULE_ALIAS("platform:ad7606_par");
diff --git a/drivers/staging/iio/adc/ad7606_ring.c b/drivers/staging/iio/adc/ad7606_ring.c
index 20927fd..e8f94a1 100644
--- a/drivers/staging/iio/adc/ad7606_ring.c
+++ b/drivers/staging/iio/adc/ad7606_ring.c
@@ -12,36 +12,12 @@
 #include <linux/slab.h>
 
 #include "../iio.h"
-#include "../buffer_generic.h"
+#include "../buffer.h"
 #include "../ring_sw.h"
 #include "../trigger_consumer.h"
 
 #include "ad7606.h"
 
-int ad7606_scan_from_ring(struct iio_dev *indio_dev, unsigned ch)
-{
-	struct iio_buffer *ring = indio_dev->buffer;
-	int ret;
-	u16 *ring_data;
-
-	ring_data = kmalloc(ring->access->get_bytes_per_datum(ring),
-			    GFP_KERNEL);
-	if (ring_data == NULL) {
-		ret = -ENOMEM;
-		goto error_ret;
-	}
-	ret = ring->access->read_last(ring, (u8 *) ring_data);
-	if (ret)
-		goto error_free_ring_data;
-
-	ret = ring_data[ch];
-
-error_free_ring_data:
-	kfree(ring_data);
-error_ret:
-	return ret;
-}
-
 /**
  * ad7606_trigger_handler_th() th/bh of trigger launched polling to ring buffer
  *
@@ -136,8 +112,6 @@
 
 	/* Effectively select the ring buffer implementation */
 	indio_dev->buffer->access = &ring_sw_access_funcs;
-	indio_dev->buffer->bpe =
-		st->chip_info->channels[0].scan_type.storagebits / 8;
 	indio_dev->pollfunc = iio_alloc_pollfunc(&ad7606_trigger_handler_th_bh,
 						 &ad7606_trigger_handler_th_bh,
 						 0,
@@ -152,7 +126,7 @@
 
 	/* Ring buffer functions - here trigger setup related */
 
-	indio_dev->buffer->setup_ops = &ad7606_ring_setup_ops;
+	indio_dev->setup_ops = &ad7606_ring_setup_ops;
 	indio_dev->buffer->scan_timestamp = true ;
 
 	INIT_WORK(&st->poll_work, &ad7606_poll_bh_to_ring);
diff --git a/drivers/staging/iio/adc/ad7606_spi.c b/drivers/staging/iio/adc/ad7606_spi.c
index b984bd2..237f1c4 100644
--- a/drivers/staging/iio/adc/ad7606_spi.c
+++ b/drivers/staging/iio/adc/ad7606_spi.c
@@ -97,11 +97,11 @@
 	{"ad7606-4", ID_AD7606_4},
 	{}
 };
+MODULE_DEVICE_TABLE(spi, ad7606_id);
 
 static struct spi_driver ad7606_driver = {
 	.driver = {
 		.name = "ad7606",
-		.bus = &spi_bus_type,
 		.owner = THIS_MODULE,
 		.pm    = AD7606_SPI_PM_OPS,
 	},
@@ -114,4 +114,3 @@
 MODULE_AUTHOR("Michael Hennerich <hennerich@blackfin.uclinux.org>");
 MODULE_DESCRIPTION("Analog Devices AD7606 ADC");
 MODULE_LICENSE("GPL v2");
-MODULE_ALIAS("spi:ad7606_spi");
diff --git a/drivers/staging/iio/adc/ad7780.c b/drivers/staging/iio/adc/ad7780.c
index ec90261..a13e58c 100644
--- a/drivers/staging/iio/adc/ad7780.c
+++ b/drivers/staging/iio/adc/ad7780.c
@@ -114,7 +114,7 @@
 			*val *= 128;
 
 		return IIO_VAL_INT;
-	case (1 << IIO_CHAN_INFO_SCALE_SHARED):
+	case IIO_CHAN_INFO_SCALE:
 		scale_uv = (st->int_vref_mv * 100000)
 			>> (channel.scan_type.realbits - 1);
 		*val =  scale_uv / 100000;
@@ -127,12 +127,12 @@
 static const struct ad7780_chip_info ad7780_chip_info_tbl[] = {
 	[ID_AD7780] = {
 		.channel = IIO_CHAN(IIO_VOLTAGE, 0, 1, 0, NULL, 0, 0,
-				    (1 << IIO_CHAN_INFO_SCALE_SHARED),
+				    IIO_CHAN_INFO_SCALE_SHARED_BIT,
 				    0, 0, IIO_ST('s', 24, 32, 8), 0),
 	},
 	[ID_AD7781] = {
 		.channel = IIO_CHAN(IIO_VOLTAGE, 0, 1, 0, NULL, 0, 0,
-				    (1 << IIO_CHAN_INFO_SCALE_SHARED),
+				    IIO_CHAN_INFO_SCALE_SHARED_BIT,
 				    0, 0, IIO_ST('s', 20, 32, 12), 0),
 	},
 };
@@ -272,11 +272,11 @@
 	{"ad7781", ID_AD7781},
 	{}
 };
+MODULE_DEVICE_TABLE(spi, ad7780_id);
 
 static struct spi_driver ad7780_driver = {
 	.driver = {
 		.name	= "ad7780",
-		.bus	= &spi_bus_type,
 		.owner	= THIS_MODULE,
 	},
 	.probe		= ad7780_probe,
diff --git a/drivers/staging/iio/adc/ad7793.c b/drivers/staging/iio/adc/ad7793.c
index 1c5588e..6a058b1 100644
--- a/drivers/staging/iio/adc/ad7793.c
+++ b/drivers/staging/iio/adc/ad7793.c
@@ -20,7 +20,7 @@
 
 #include "../iio.h"
 #include "../sysfs.h"
-#include "../buffer_generic.h"
+#include "../buffer.h"
 #include "../ring_sw.h"
 #include "../trigger.h"
 #include "../trigger_consumer.h"
@@ -316,25 +316,6 @@
 	return ret;
 }
 
-static int ad7793_scan_from_ring(struct ad7793_state *st, unsigned ch, int *val)
-{
-	struct iio_buffer *ring = iio_priv_to_dev(st)->buffer;
-	int ret;
-	s64 dat64[2];
-	u32 *dat32 = (u32 *)dat64;
-
-	if (!(test_bit(ch, ring->scan_mask)))
-		return  -EBUSY;
-
-	ret = ring->access->read_last(ring, (u8 *) &dat64);
-	if (ret)
-		return ret;
-
-	*val = *dat32;
-
-	return 0;
-}
-
 static int ad7793_ring_preenable(struct iio_dev *indio_dev)
 {
 	struct ad7793_state *st = iio_priv(indio_dev);
@@ -342,14 +323,15 @@
 	size_t d_size;
 	unsigned channel;
 
-	if (!ring->scan_count)
+	if (bitmap_empty(indio_dev->active_scan_mask, indio_dev->masklength))
 		return -EINVAL;
 
-	channel = find_first_bit(ring->scan_mask,
+	channel = find_first_bit(indio_dev->active_scan_mask,
 				 indio_dev->masklength);
 
-	d_size = ring->scan_count *
-		 indio_dev->channels[0].scan_type.storagebits / 8;
+	d_size = bitmap_weight(indio_dev->active_scan_mask,
+			       indio_dev->masklength) *
+		indio_dev->channels[0].scan_type.storagebits / 8;
 
 	if (ring->scan_timestamp) {
 		d_size += sizeof(s64);
@@ -411,7 +393,7 @@
 	s64 dat64[2];
 	s32 *dat32 = (s32 *)dat64;
 
-	if (ring->scan_count)
+	if (!bitmap_empty(indio_dev->active_scan_mask, indio_dev->masklength))
 		__ad7793_read_reg(st, 1, 1, AD7793_REG_DATA,
 				  dat32,
 				  indio_dev->channels[0].scan_type.realbits/8);
@@ -459,7 +441,7 @@
 	}
 
 	/* Ring buffer functions - here trigger setup related */
-	indio_dev->buffer->setup_ops = &ad7793_ring_setup_ops;
+	indio_dev->setup_ops = &ad7793_ring_setup_ops;
 
 	/* Flag that polled ring buffering is possible */
 	indio_dev->modes |= INDIO_BUFFER_TRIGGERED;
@@ -493,6 +475,10 @@
 	return IRQ_HANDLED;
 }
 
+static struct iio_trigger_ops ad7793_trigger_ops = {
+	.owner = THIS_MODULE,
+};
+
 static int ad7793_probe_trigger(struct iio_dev *indio_dev)
 {
 	struct ad7793_state *st = iio_priv(indio_dev);
@@ -505,6 +491,7 @@
 		ret = -ENOMEM;
 		goto error_ret;
 	}
+	st->trig->ops = &ad7793_trigger_ops;
 
 	ret = request_irq(st->spi->irq,
 			  ad7793_data_rdy_trig_poll,
@@ -517,7 +504,6 @@
 	disable_irq_nosync(st->spi->irq);
 	st->irq_dis = true;
 	st->trig->dev.parent = &st->spi->dev;
-	st->trig->owner = THIS_MODULE;
 	st->trig->private_data = indio_dev;
 
 	ret = iio_trigger_register(st->trig);
@@ -649,8 +635,7 @@
 	case 0:
 		mutex_lock(&indio_dev->mlock);
 		if (iio_buffer_enabled(indio_dev))
-			ret = ad7793_scan_from_ring(st,
-					chan->scan_index, &smpl);
+			ret = -EBUSY;
 		else
 			ret = ad7793_read(st, chan->address,
 					chan->scan_type.realbits / 8, &smpl);
@@ -667,19 +652,21 @@
 
 		return IIO_VAL_INT;
 
-	case (1 << IIO_CHAN_INFO_SCALE_SHARED):
-		*val = st->scale_avail[(st->conf >> 8) & 0x7][0];
-		*val2 = st->scale_avail[(st->conf >> 8) & 0x7][1];
-
-		return IIO_VAL_INT_PLUS_NANO;
-
-	case (1 << IIO_CHAN_INFO_SCALE_SEPARATE):
+	case IIO_CHAN_INFO_SCALE:
 		switch (chan->type) {
 		case IIO_VOLTAGE:
-			/* 1170mV / 2^23 * 6 */
-			scale_uv = (1170ULL * 100000000ULL * 6ULL)
-				>> (chan->scan_type.realbits -
-				(unipolar ? 0 : 1));
+			if (chan->differential) {
+				*val = st->
+					scale_avail[(st->conf >> 8) & 0x7][0];
+				*val2 = st->
+					scale_avail[(st->conf >> 8) & 0x7][1];
+				return IIO_VAL_INT_PLUS_NANO;
+			} else {
+				/* 1170mV / 2^23 * 6 */
+				scale_uv = (1170ULL * 100000000ULL * 6ULL)
+					>> (chan->scan_type.realbits -
+					    (unipolar ? 0 : 1));
+			}
 			break;
 		case IIO_TEMP:
 			/* Always uses unity gain and internal ref */
@@ -716,7 +703,7 @@
 	}
 
 	switch (mask) {
-	case (1 << IIO_CHAN_INFO_SCALE_SHARED):
+	case IIO_CHAN_INFO_SCALE:
 		ret = -EINVAL;
 		for (i = 0; i < ARRAY_SIZE(st->scale_avail); i++)
 			if (val2 == st->scale_avail[i][1]) {
@@ -775,7 +762,7 @@
 			.channel = 0,
 			.channel2 = 0,
 			.address = AD7793_CH_AIN1P_AIN1M,
-			.info_mask = (1 << IIO_CHAN_INFO_SCALE_SHARED),
+			.info_mask = IIO_CHAN_INFO_SCALE_SHARED_BIT,
 			.scan_index = 0,
 			.scan_type = IIO_ST('s', 24, 32, 0)
 		},
@@ -786,7 +773,7 @@
 			.channel = 1,
 			.channel2 = 1,
 			.address = AD7793_CH_AIN2P_AIN2M,
-			.info_mask = (1 << IIO_CHAN_INFO_SCALE_SHARED),
+			.info_mask = IIO_CHAN_INFO_SCALE_SHARED_BIT,
 			.scan_index = 1,
 			.scan_type = IIO_ST('s', 24, 32, 0)
 		},
@@ -797,7 +784,7 @@
 			.channel = 2,
 			.channel2 = 2,
 			.address = AD7793_CH_AIN3P_AIN3M,
-			.info_mask = (1 << IIO_CHAN_INFO_SCALE_SHARED),
+			.info_mask = IIO_CHAN_INFO_SCALE_SHARED_BIT,
 			.scan_index = 2,
 			.scan_type = IIO_ST('s', 24, 32, 0)
 		},
@@ -809,7 +796,7 @@
 			.channel = 2,
 			.channel2 = 2,
 			.address = AD7793_CH_AIN1M_AIN1M,
-			.info_mask = (1 << IIO_CHAN_INFO_SCALE_SHARED),
+			.info_mask = IIO_CHAN_INFO_SCALE_SHARED_BIT,
 			.scan_index = 2,
 			.scan_type = IIO_ST('s', 24, 32, 0)
 		},
@@ -818,7 +805,7 @@
 			.indexed = 1,
 			.channel = 0,
 			.address = AD7793_CH_TEMP,
-			.info_mask = (1 << IIO_CHAN_INFO_SCALE_SEPARATE),
+			.info_mask = IIO_CHAN_INFO_SCALE_SEPARATE_BIT,
 			.scan_index = 4,
 			.scan_type = IIO_ST('s', 24, 32, 0),
 		},
@@ -828,7 +815,7 @@
 			.indexed = 1,
 			.channel = 4,
 			.address = AD7793_CH_AVDD_MONITOR,
-			.info_mask = (1 << IIO_CHAN_INFO_SCALE_SEPARATE),
+			.info_mask = IIO_CHAN_INFO_SCALE_SEPARATE_BIT,
 			.scan_index = 5,
 			.scan_type = IIO_ST('s', 24, 32, 0),
 		},
@@ -842,7 +829,7 @@
 			.channel = 0,
 			.channel2 = 0,
 			.address = AD7793_CH_AIN1P_AIN1M,
-			.info_mask = (1 << IIO_CHAN_INFO_SCALE_SHARED),
+			.info_mask = IIO_CHAN_INFO_SCALE_SHARED_BIT,
 			.scan_index = 0,
 			.scan_type = IIO_ST('s', 16, 32, 0)
 		},
@@ -853,7 +840,7 @@
 			.channel = 1,
 			.channel2 = 1,
 			.address = AD7793_CH_AIN2P_AIN2M,
-			.info_mask = (1 << IIO_CHAN_INFO_SCALE_SHARED),
+			.info_mask = IIO_CHAN_INFO_SCALE_SHARED_BIT,
 			.scan_index = 1,
 			.scan_type = IIO_ST('s', 16, 32, 0)
 		},
@@ -864,7 +851,7 @@
 			.channel = 2,
 			.channel2 = 2,
 			.address = AD7793_CH_AIN3P_AIN3M,
-			.info_mask = (1 << IIO_CHAN_INFO_SCALE_SHARED),
+			.info_mask = IIO_CHAN_INFO_SCALE_SHARED_BIT,
 			.scan_index = 2,
 			.scan_type = IIO_ST('s', 16, 32, 0)
 		},
@@ -876,7 +863,7 @@
 			.channel = 2,
 			.channel2 = 2,
 			.address = AD7793_CH_AIN1M_AIN1M,
-			.info_mask = (1 << IIO_CHAN_INFO_SCALE_SHARED),
+			.info_mask = IIO_CHAN_INFO_SCALE_SHARED_BIT,
 			.scan_index = 2,
 			.scan_type = IIO_ST('s', 16, 32, 0)
 		},
@@ -885,7 +872,7 @@
 			.indexed = 1,
 			.channel = 0,
 			.address = AD7793_CH_TEMP,
-			.info_mask = (1 << IIO_CHAN_INFO_SCALE_SEPARATE),
+			.info_mask = IIO_CHAN_INFO_SCALE_SEPARATE_BIT,
 			.scan_index = 4,
 			.scan_type = IIO_ST('s', 16, 32, 0),
 		},
@@ -895,7 +882,7 @@
 			.indexed = 1,
 			.channel = 4,
 			.address = AD7793_CH_AVDD_MONITOR,
-			.info_mask = (1 << IIO_CHAN_INFO_SCALE_SEPARATE),
+			.info_mask = IIO_CHAN_INFO_SCALE_SEPARATE_BIT,
 			.scan_index = 5,
 			.scan_type = IIO_ST('s', 16, 32, 0),
 		},
@@ -1034,11 +1021,11 @@
 	{"ad7793", ID_AD7793},
 	{}
 };
+MODULE_DEVICE_TABLE(spi, ad7793_id);
 
 static struct spi_driver ad7793_driver = {
 	.driver = {
 		.name	= "ad7793",
-		.bus	= &spi_bus_type,
 		.owner	= THIS_MODULE,
 	},
 	.probe		= ad7793_probe,
diff --git a/drivers/staging/iio/adc/ad7816.c b/drivers/staging/iio/adc/ad7816.c
index acbf936..52b720e 100644
--- a/drivers/staging/iio/adc/ad7816.c
+++ b/drivers/staging/iio/adc/ad7816.c
@@ -18,6 +18,7 @@
 
 #include "../iio.h"
 #include "../sysfs.h"
+#include "../events.h"
 
 /*
  * AD7816 config masks
@@ -459,7 +460,6 @@
 static struct spi_driver ad7816_driver = {
 	.driver = {
 		.name = "ad7816",
-		.bus = &spi_bus_type,
 		.owner = THIS_MODULE,
 	},
 	.probe = ad7816_probe,
diff --git a/drivers/staging/iio/adc/ad7887.h b/drivers/staging/iio/adc/ad7887.h
index 3452d18..bc53b65 100644
--- a/drivers/staging/iio/adc/ad7887.h
+++ b/drivers/staging/iio/adc/ad7887.h
@@ -83,14 +83,9 @@
 };
 
 #ifdef CONFIG_IIO_BUFFER
-int ad7887_scan_from_ring(struct ad7887_state *st, int channum);
 int ad7887_register_ring_funcs_and_init(struct iio_dev *indio_dev);
 void ad7887_ring_cleanup(struct iio_dev *indio_dev);
 #else /* CONFIG_IIO_BUFFER */
-static inline int ad7887_scan_from_ring(struct ad7887_state *st, int channum)
-{
-	return 0;
-}
 
 static inline int
 ad7887_register_ring_funcs_and_init(struct iio_dev *indio_dev)
diff --git a/drivers/staging/iio/adc/ad7887_core.c b/drivers/staging/iio/adc/ad7887_core.c
index 91b8fb0..e9bbc3e 100644
--- a/drivers/staging/iio/adc/ad7887_core.c
+++ b/drivers/staging/iio/adc/ad7887_core.c
@@ -17,7 +17,7 @@
 
 #include "../iio.h"
 #include "../sysfs.h"
-#include "../buffer_generic.h"
+#include "../buffer.h"
 
 
 #include "ad7887.h"
@@ -45,7 +45,7 @@
 	case 0:
 		mutex_lock(&indio_dev->mlock);
 		if (iio_buffer_enabled(indio_dev))
-			ret = ad7887_scan_from_ring(st, 1 << chan->address);
+			ret = -EBUSY;
 		else
 			ret = ad7887_scan_direct(st, chan->address);
 		mutex_unlock(&indio_dev->mlock);
@@ -55,7 +55,7 @@
 		*val = (ret >> st->chip_info->channel[0].scan_type.shift) &
 			RES_MASK(st->chip_info->channel[0].scan_type.realbits);
 		return IIO_VAL_INT;
-	case (1 << IIO_CHAN_INFO_SCALE_SHARED):
+	case IIO_CHAN_INFO_SCALE:
 		scale_uv = (st->int_vref_mv * 1000)
 			>> st->chip_info->channel[0].scan_type.realbits;
 		*val =  scale_uv/1000;
@@ -75,7 +75,7 @@
 			.type = IIO_VOLTAGE,
 			.indexed = 1,
 			.channel = 1,
-			.info_mask = (1 << IIO_CHAN_INFO_SCALE_SHARED),
+			.info_mask = IIO_CHAN_INFO_SCALE_SHARED_BIT,
 			.address = 1,
 			.scan_index = 1,
 			.scan_type = IIO_ST('u', 12, 16, 0),
@@ -84,7 +84,7 @@
 			.type = IIO_VOLTAGE,
 			.indexed = 1,
 			.channel = 0,
-			.info_mask = (1 << IIO_CHAN_INFO_SCALE_SHARED),
+			.info_mask = IIO_CHAN_INFO_SCALE_SHARED_BIT,
 			.address = 0,
 			.scan_index = 0,
 			.scan_type = IIO_ST('u', 12, 16, 0),
@@ -246,11 +246,11 @@
 	{"ad7887", ID_AD7887},
 	{}
 };
+MODULE_DEVICE_TABLE(spi, ad7887_id);
 
 static struct spi_driver ad7887_driver = {
 	.driver = {
 		.name	= "ad7887",
-		.bus	= &spi_bus_type,
 		.owner	= THIS_MODULE,
 	},
 	.probe		= ad7887_probe,
@@ -262,4 +262,3 @@
 MODULE_AUTHOR("Michael Hennerich <hennerich@blackfin.uclinux.org>");
 MODULE_DESCRIPTION("Analog Devices AD7887 ADC");
 MODULE_LICENSE("GPL v2");
-MODULE_ALIAS("spi:ad7887");
diff --git a/drivers/staging/iio/adc/ad7887_ring.c b/drivers/staging/iio/adc/ad7887_ring.c
index cb74cad..85076cd 100644
--- a/drivers/staging/iio/adc/ad7887_ring.c
+++ b/drivers/staging/iio/adc/ad7887_ring.c
@@ -13,46 +13,12 @@
 #include <linux/spi/spi.h>
 
 #include "../iio.h"
-#include "../buffer_generic.h"
+#include "../buffer.h"
 #include "../ring_sw.h"
 #include "../trigger_consumer.h"
 
 #include "ad7887.h"
 
-int ad7887_scan_from_ring(struct ad7887_state *st, int channum)
-{
-	struct iio_buffer *ring = iio_priv_to_dev(st)->buffer;
-	int count = 0, ret;
-	u16 *ring_data;
-
-	if (!(test_bit(channum, ring->scan_mask))) {
-		ret = -EBUSY;
-		goto error_ret;
-	}
-
-	ring_data = kmalloc(ring->access->get_bytes_per_datum(ring),
-			    GFP_KERNEL);
-	if (ring_data == NULL) {
-		ret = -ENOMEM;
-		goto error_ret;
-	}
-	ret = ring->access->read_last(ring, (u8 *) ring_data);
-	if (ret)
-		goto error_free_ring_data;
-
-	/* for single channel scan the result is stored with zero offset */
-	if ((test_bit(1, ring->scan_mask) || test_bit(0, ring->scan_mask)) &&
-	    (channum == 1))
-		count = 1;
-
-	ret = be16_to_cpu(ring_data[count]);
-
-error_free_ring_data:
-	kfree(ring_data);
-error_ret:
-	return ret;
-}
-
 /**
  * ad7887_ring_preenable() setup the parameters of the ring before enabling
  *
@@ -65,7 +31,8 @@
 	struct ad7887_state *st = iio_priv(indio_dev);
 	struct iio_buffer *ring = indio_dev->buffer;
 
-	st->d_size = ring->scan_count *
+	st->d_size = bitmap_weight(indio_dev->active_scan_mask,
+				   indio_dev->masklength) *
 		st->chip_info->channel[0].scan_type.storagebits / 8;
 
 	if (ring->scan_timestamp) {
@@ -80,7 +47,7 @@
 			set_bytes_per_datum(indio_dev->buffer, st->d_size);
 
 	/* We know this is a single long so can 'cheat' */
-	switch (*ring->scan_mask) {
+	switch (*indio_dev->active_scan_mask) {
 	case (1 << 0):
 		st->ring_msg = &st->msg[AD7887_CH0];
 		break;
@@ -121,7 +88,8 @@
 	__u8 *buf;
 	int b_sent;
 
-	unsigned int bytes = ring->scan_count *
+	unsigned int bytes = bitmap_weight(indio_dev->active_scan_mask,
+					   indio_dev->masklength) *
 		st->chip_info->channel[0].scan_type.storagebits / 8;
 
 	buf = kzalloc(st->d_size, GFP_KERNEL);
@@ -176,7 +144,7 @@
 		goto error_deallocate_sw_rb;
 	}
 	/* Ring buffer functions - here trigger setup related */
-	indio_dev->buffer->setup_ops = &ad7887_ring_setup_ops;
+	indio_dev->setup_ops = &ad7887_ring_setup_ops;
 
 	/* Flag that polled ring buffering is possible */
 	indio_dev->modes |= INDIO_BUFFER_TRIGGERED;
diff --git a/drivers/staging/iio/adc/ad799x.h b/drivers/staging/iio/adc/ad799x.h
index eda01d5..356f690 100644
--- a/drivers/staging/iio/adc/ad799x.h
+++ b/drivers/staging/iio/adc/ad799x.h
@@ -124,15 +124,9 @@
 int ad7997_8_set_scan_mode(struct ad799x_state *st, unsigned mask);
 
 #ifdef CONFIG_AD799X_RING_BUFFER
-int ad799x_single_channel_from_ring(struct iio_dev *indio_dev, int channum);
 int ad799x_register_ring_funcs_and_init(struct iio_dev *indio_dev);
 void ad799x_ring_cleanup(struct iio_dev *indio_dev);
 #else /* CONFIG_AD799X_RING_BUFFER */
-int ad799x_single_channel_from_ring(struct iio_dev *indio_dev, int channum)
-{
-	return -EINVAL;
-}
-
 
 static inline int
 ad799x_register_ring_funcs_and_init(struct iio_dev *indio_dev)
diff --git a/drivers/staging/iio/adc/ad799x_core.c b/drivers/staging/iio/adc/ad799x_core.c
index c0d2f88..d5b581d 100644
--- a/drivers/staging/iio/adc/ad799x_core.c
+++ b/drivers/staging/iio/adc/ad799x_core.c
@@ -35,7 +35,8 @@
 
 #include "../iio.h"
 #include "../sysfs.h"
-#include "../buffer_generic.h"
+#include "../events.h"
+#include "../buffer.h"
 
 #include "ad799x.h"
 
@@ -150,8 +151,7 @@
 	case 0:
 		mutex_lock(&indio_dev->mlock);
 		if (iio_buffer_enabled(indio_dev))
-			ret = ad799x_single_channel_from_ring(indio_dev,
-							      chan->scan_index);
+			ret = -EBUSY;
 		else
 			ret = ad799x_scan_direct(st, chan->scan_index);
 		mutex_unlock(&indio_dev->mlock);
@@ -161,7 +161,7 @@
 		*val = (ret >> chan->scan_type.shift) &
 			RES_MASK(chan->scan_type.realbits);
 		return IIO_VAL_INT;
-	case (1 << IIO_CHAN_INFO_SCALE_SHARED):
+	case IIO_CHAN_INFO_SCALE:
 		scale_uv = (st->int_vref_mv * 1000) >> chan->scan_type.realbits;
 		*val =  scale_uv / 1000;
 		*val2 = (scale_uv % 1000) * 1000;
@@ -934,4 +934,3 @@
 MODULE_AUTHOR("Michael Hennerich <hennerich@blackfin.uclinux.org>");
 MODULE_DESCRIPTION("Analog Devices AD799x ADC");
 MODULE_LICENSE("GPL v2");
-MODULE_ALIAS("i2c:ad799x");
diff --git a/drivers/staging/iio/adc/ad799x_ring.c b/drivers/staging/iio/adc/ad799x_ring.c
index e3f4698..5dded9e 100644
--- a/drivers/staging/iio/adc/ad799x_ring.c
+++ b/drivers/staging/iio/adc/ad799x_ring.c
@@ -17,42 +17,12 @@
 #include <linux/bitops.h>
 
 #include "../iio.h"
-#include "../buffer_generic.h"
+#include "../buffer.h"
 #include "../ring_sw.h"
 #include "../trigger_consumer.h"
 
 #include "ad799x.h"
 
-int ad799x_single_channel_from_ring(struct iio_dev *indio_dev, int channum)
-{
-	struct iio_buffer *ring = indio_dev->buffer;
-	int count = 0, ret;
-	u16 *ring_data;
-
-	if (!(test_bit(channum, ring->scan_mask))) {
-		ret = -EBUSY;
-		goto error_ret;
-	}
-
-	ring_data = kmalloc(ring->access->get_bytes_per_datum(ring),
-			    GFP_KERNEL);
-	if (ring_data == NULL) {
-		ret = -ENOMEM;
-		goto error_ret;
-	}
-	ret = ring->access->read_last(ring, (u8 *) ring_data);
-	if (ret)
-		goto error_free_ring_data;
-	/* Need a count of channels prior to this one */
-	count = bitmap_weight(ring->scan_mask, channum);
-	ret = be16_to_cpu(ring_data[count]);
-
-error_free_ring_data:
-	kfree(ring_data);
-error_ret:
-	return ret;
-}
-
 /**
  * ad799x_ring_preenable() setup the parameters of the ring before enabling
  *
@@ -71,9 +41,10 @@
 	 */
 
 	if (st->id == ad7997 || st->id == ad7998)
-		ad7997_8_set_scan_mode(st, *ring->scan_mask);
+		ad7997_8_set_scan_mode(st, *indio_dev->active_scan_mask);
 
-	st->d_size = ring->scan_count * 2;
+	st->d_size = bitmap_weight(indio_dev->active_scan_mask,
+				   indio_dev->masklength) * 2;
 
 	if (ring->scan_timestamp) {
 		st->d_size += sizeof(s64);
@@ -115,12 +86,13 @@
 	case ad7991:
 	case ad7995:
 	case ad7999:
-		cmd = st->config | (*ring->scan_mask << AD799X_CHANNEL_SHIFT);
+		cmd = st->config |
+			(*indio_dev->active_scan_mask << AD799X_CHANNEL_SHIFT);
 		break;
 	case ad7992:
 	case ad7993:
 	case ad7994:
-		cmd = (*ring->scan_mask << AD799X_CHANNEL_SHIFT) |
+		cmd = (*indio_dev->active_scan_mask << AD799X_CHANNEL_SHIFT) |
 			AD7998_CONV_RES_REG;
 		break;
 	case ad7997:
@@ -132,7 +104,8 @@
 	}
 
 	b_sent = i2c_smbus_read_i2c_block_data(st->client,
-			cmd, ring->scan_count * 2, rxbuf);
+			cmd, bitmap_weight(indio_dev->active_scan_mask,
+					   indio_dev->masklength) * 2, rxbuf);
 	if (b_sent < 0)
 		goto done;
 
@@ -183,7 +156,7 @@
 	}
 
 	/* Ring buffer functions - here trigger setup related */
-	indio_dev->buffer->setup_ops = &ad799x_buf_setup_ops;
+	indio_dev->setup_ops = &ad799x_buf_setup_ops;
 	indio_dev->buffer->scan_timestamp = true;
 
 	/* Flag that polled ring buffering is possible */
diff --git a/drivers/staging/iio/adc/adt7310.c b/drivers/staging/iio/adc/adt7310.c
index bc307f3..eec2f32 100644
--- a/drivers/staging/iio/adc/adt7310.c
+++ b/drivers/staging/iio/adc/adt7310.c
@@ -17,7 +17,7 @@
 
 #include "../iio.h"
 #include "../sysfs.h"
-
+#include "../events.h"
 /*
  * ADT7310 registers definition
  */
@@ -877,7 +877,6 @@
 static struct spi_driver adt7310_driver = {
 	.driver = {
 		.name = "adt7310",
-		.bus = &spi_bus_type,
 		.owner = THIS_MODULE,
 	},
 	.probe = adt7310_probe,
diff --git a/drivers/staging/iio/adc/adt7410.c b/drivers/staging/iio/adc/adt7410.c
index 3481cf6..c62248c 100644
--- a/drivers/staging/iio/adc/adt7410.c
+++ b/drivers/staging/iio/adc/adt7410.c
@@ -17,6 +17,7 @@
 
 #include "../iio.h"
 #include "../sysfs.h"
+#include "../events.h"
 
 /*
  * ADT7410 registers definition
diff --git a/drivers/staging/iio/adc/max1363.h b/drivers/staging/iio/adc/max1363.h
index cbcb08a..2cd0112 100644
--- a/drivers/staging/iio/adc/max1363.h
+++ b/drivers/staging/iio/adc/max1363.h
@@ -146,22 +146,22 @@
 };
 
 const struct max1363_mode
-*max1363_match_mode(unsigned long *mask, const struct max1363_chip_info *ci);
+*max1363_match_mode(const unsigned long *mask,
+		    const struct max1363_chip_info *ci);
 
 int max1363_set_scan_mode(struct max1363_state *st);
 
 #ifdef CONFIG_MAX1363_RING_BUFFER
-
-int max1363_single_channel_from_ring(const long *mask,
-				     struct max1363_state *st);
+int max1363_update_scan_mode(struct iio_dev *indio_dev,
+			     const unsigned long *scan_mask);
 int max1363_register_ring_funcs_and_init(struct iio_dev *indio_dev);
 void max1363_ring_cleanup(struct iio_dev *indio_dev);
 
 #else /* CONFIG_MAX1363_RING_BUFFER */
-
-int max1363_single_channel_from_ring(long mask, struct max1363_state *st)
+int max1363_update_scan_mode(struct iio_dev *indio_dev,
+			     const long *scan_mask)
 {
-	return -EINVAL;
+	return 0;
 }
 
 static inline int
diff --git a/drivers/staging/iio/adc/max1363_core.c b/drivers/staging/iio/adc/max1363_core.c
index 3f28f1a..b92cb4a 100644
--- a/drivers/staging/iio/adc/max1363_core.c
+++ b/drivers/staging/iio/adc/max1363_core.c
@@ -34,7 +34,8 @@
 
 #include "../iio.h"
 #include "../sysfs.h"
-#include "../buffer_generic.h"
+#include "../events.h"
+#include "../buffer.h"
 
 #include "max1363.h"
 
@@ -147,7 +148,8 @@
 };
 
 const struct max1363_mode
-*max1363_match_mode(unsigned long *mask, const struct max1363_chip_info *ci)
+*max1363_match_mode(const unsigned long *mask,
+const struct max1363_chip_info *ci)
 {
 	int i;
 	if (mask)
@@ -189,7 +191,6 @@
 	int ret = 0;
 	s32 data;
 	char rxbuf[2];
-	const unsigned long *mask;
 	struct max1363_state *st = iio_priv(indio_dev);
 	struct i2c_client *client = st->client;
 
@@ -198,46 +199,38 @@
 	 * If monitor mode is enabled, the method for reading a single
 	 * channel will have to be rather different and has not yet
 	 * been implemented.
+	 *
+	 * Also, cannot read directly if buffered capture enabled.
 	 */
-	if (st->monitor_on) {
+	if (st->monitor_on || iio_buffer_enabled(indio_dev)) {
 		ret = -EBUSY;
 		goto error_ret;
 	}
 
-	/* If ring buffer capture is occurring, query the buffer */
-	if (iio_buffer_enabled(indio_dev)) {
-		mask = max1363_mode_table[chan->address].modemask;
-		data = max1363_single_channel_from_ring(mask, st);
+	/* Check to see if current scan mode is correct */
+	if (st->current_mode != &max1363_mode_table[chan->address]) {
+		/* Update scan mode if needed */
+		st->current_mode = &max1363_mode_table[chan->address];
+		ret = max1363_set_scan_mode(st);
+		if (ret < 0)
+			goto error_ret;
+	}
+	if (st->chip_info->bits != 8) {
+		/* Get reading */
+		data = i2c_master_recv(client, rxbuf, 2);
 		if (data < 0) {
 			ret = data;
 			goto error_ret;
 		}
+		data = (s32)(rxbuf[1]) | ((s32)(rxbuf[0] & 0x0F)) << 8;
 	} else {
-		/* Check to see if current scan mode is correct */
-		if (st->current_mode != &max1363_mode_table[chan->address]) {
-			/* Update scan mode if needed */
-			st->current_mode = &max1363_mode_table[chan->address];
-			ret = max1363_set_scan_mode(st);
-			if (ret < 0)
-				goto error_ret;
+		/* Get reading */
+		data = i2c_master_recv(client, rxbuf, 1);
+		if (data < 0) {
+			ret = data;
+			goto error_ret;
 		}
-		if (st->chip_info->bits != 8) {
-			/* Get reading */
-			data = i2c_master_recv(client, rxbuf, 2);
-			if (data < 0) {
-				ret = data;
-				goto error_ret;
-			}
-			data = (s32)(rxbuf[1]) | ((s32)(rxbuf[0] & 0x0F)) << 8;
-		} else {
-			/* Get reading */
-			data = i2c_master_recv(client, rxbuf, 1);
-			if (data < 0) {
-				ret = data;
-				goto error_ret;
-			}
-			data = rxbuf[0];
-		}
+		data = rxbuf[0];
 	}
 	*val = data;
 error_ret:
@@ -260,7 +253,7 @@
 		if (ret < 0)
 			return ret;
 		return IIO_VAL_INT;
-	case (1 << IIO_CHAN_INFO_SCALE_SHARED):
+	case IIO_CHAN_INFO_SCALE:
 		if ((1 << (st->chip_info->bits + 1)) >
 		    st->chip_info->int_vref_mv) {
 			*val = 0;
@@ -288,7 +281,7 @@
 #define MAX1363_EV_M						\
 	(IIO_EV_BIT(IIO_EV_TYPE_THRESH, IIO_EV_DIR_RISING)	\
 	 | IIO_EV_BIT(IIO_EV_TYPE_THRESH, IIO_EV_DIR_FALLING))
-#define MAX1363_INFO_MASK (1 << IIO_CHAN_INFO_SCALE_SHARED)
+#define MAX1363_INFO_MASK IIO_CHAN_INFO_SCALE_SHARED_BIT
 #define MAX1363_CHAN_U(num, addr, si, bits, evmask)			\
 	{								\
 		.type = IIO_VOLTAGE,					\
@@ -296,7 +289,13 @@
 		.channel = num,						\
 		.address = addr,					\
 		.info_mask = MAX1363_INFO_MASK,				\
-		.scan_type = IIO_ST('u', bits, (bits > 8) ? 16 : 8, 0), \
+		.datasheet_name = "AIN"#num,				\
+		.scan_type = {						\
+			.sign = 'u',					\
+			.realbits = bits,				\
+			.storagebits = (bits > 8) ? 16 : 8,		\
+			.endianness = IIO_BE,				\
+		},							\
 		.scan_index = si,					\
 		.event_mask = evmask,					\
 	}
@@ -311,7 +310,13 @@
 		.channel2 = num2,					\
 		.address = addr,					\
 		.info_mask = MAX1363_INFO_MASK,				\
-		.scan_type = IIO_ST('u', bits, (bits > 8) ? 16 : 8, 0), \
+		.datasheet_name = "AIN"#num"-AIN"#num2,			\
+		.scan_type = {						\
+			.sign = 's',					\
+			.realbits = bits,				\
+			.storagebits = (bits > 8) ? 16 : 8,		\
+			.endianness = IIO_BE,				\
+		},							\
 		.scan_index = si,					\
 		.event_mask = evmask,					\
 	}
@@ -833,6 +838,7 @@
 	.read_event_config = &max1363_read_event_config,
 	.write_event_config = &max1363_write_event_config,
 	.read_raw = &max1363_read_raw,
+	.update_scan_mode = &max1363_update_scan_mode,
 	.driver_module = THIS_MODULE,
 	.event_attrs = &max1363_event_attribute_group,
 };
diff --git a/drivers/staging/iio/adc/max1363_ring.c b/drivers/staging/iio/adc/max1363_ring.c
index df6893e..f730b3f 100644
--- a/drivers/staging/iio/adc/max1363_ring.c
+++ b/drivers/staging/iio/adc/max1363_ring.c
@@ -15,88 +15,25 @@
 #include <linux/bitops.h>
 
 #include "../iio.h"
-#include "../buffer_generic.h"
+#include "../buffer.h"
 #include "../ring_sw.h"
 #include "../trigger_consumer.h"
 
 #include "max1363.h"
 
-int max1363_single_channel_from_ring(const long *mask, struct max1363_state *st)
-{
-	struct iio_buffer *ring = iio_priv_to_dev(st)->buffer;
-	int count = 0, ret, index;
-	u8 *ring_data;
-	index = find_first_bit(mask, MAX1363_MAX_CHANNELS);
-
-	if (!(test_bit(index, st->current_mode->modemask))) {
-		ret = -EBUSY;
-		goto error_ret;
-	}
-
-	ring_data = kmalloc(ring->access->get_bytes_per_datum(ring),
-			    GFP_KERNEL);
-	if (ring_data == NULL) {
-		ret = -ENOMEM;
-		goto error_ret;
-	}
-	ret = ring->access->read_last(ring, ring_data);
-	if (ret)
-		goto error_free_ring_data;
-	/* Need a count of channels prior to this one */
-
-	count = bitmap_weight(mask, index - 1);
-	if (st->chip_info->bits != 8)
-		ret = ((int)(ring_data[count*2 + 0] & 0x0F) << 8)
-			+ (int)(ring_data[count*2 + 1]);
-	else
-		ret = ring_data[count];
-
-error_free_ring_data:
-	kfree(ring_data);
-error_ret:
-	return ret;
-}
-
-
-/**
- * max1363_ring_preenable() - setup the parameters of the ring before enabling
- *
- * The complex nature of the setting of the nuber of bytes per datum is due
- * to this driver currently ensuring that the timestamp is stored at an 8
- * byte boundary.
- **/
-static int max1363_ring_preenable(struct iio_dev *indio_dev)
+int max1363_update_scan_mode(struct iio_dev *indio_dev,
+			     const unsigned long *scan_mask)
 {
 	struct max1363_state *st = iio_priv(indio_dev);
-	struct iio_buffer *ring = indio_dev->buffer;
-	size_t d_size = 0;
-	unsigned long numvals;
 
 	/*
 	 * Need to figure out the current mode based upon the requested
 	 * scan mask in iio_dev
 	 */
-	st->current_mode = max1363_match_mode(ring->scan_mask,
-					st->chip_info);
+	st->current_mode = max1363_match_mode(scan_mask, st->chip_info);
 	if (!st->current_mode)
 		return -EINVAL;
-
 	max1363_set_scan_mode(st);
-
-	numvals = bitmap_weight(st->current_mode->modemask,
-				indio_dev->masklength);
-	if (ring->access->set_bytes_per_datum) {
-		if (ring->scan_timestamp)
-			d_size += sizeof(s64);
-		if (st->chip_info->bits != 8)
-			d_size += numvals*2;
-		else
-			d_size += numvals;
-		if (ring->scan_timestamp && (d_size % 8))
-			d_size += 8 - (d_size % 8);
-		ring->access->set_bytes_per_datum(ring, d_size);
-	}
-
 	return 0;
 }
 
@@ -114,12 +51,14 @@
 
 	/* Ensure the timestamp is 8 byte aligned */
 	if (st->chip_info->bits != 8)
-		d_size = numvals*2 + sizeof(s64);
+		d_size = numvals*2;
 	else
-		d_size = numvals + sizeof(s64);
-	if (d_size % sizeof(s64))
-		d_size += sizeof(s64) - (d_size % sizeof(s64));
-
+		d_size = numvals;
+	if (indio_dev->buffer->scan_timestamp) {
+		d_size += sizeof(s64);
+		if (d_size % sizeof(s64))
+			d_size += sizeof(s64) - (d_size % sizeof(s64));
+	}
 	/* Monitor mode prevents reading. Whilst not currently implemented
 	 * might as well have this test in here in the meantime as it does
 	 * no harm.
@@ -139,9 +78,10 @@
 
 	time_ns = iio_get_time_ns();
 
-	memcpy(rxbuf + d_size - sizeof(s64), &time_ns, sizeof(time_ns));
+	if (indio_dev->buffer->scan_timestamp)
+		memcpy(rxbuf + d_size - sizeof(s64), &time_ns, sizeof(time_ns));
+	iio_push_to_buffer(indio_dev->buffer, rxbuf, time_ns);
 
-	indio_dev->buffer->access->store_to(indio_dev->buffer, rxbuf, time_ns);
 done:
 	iio_trigger_notify_done(indio_dev->trig);
 	kfree(rxbuf);
@@ -151,7 +91,7 @@
 
 static const struct iio_buffer_setup_ops max1363_ring_setup_ops = {
 	.postenable = &iio_triggered_buffer_postenable,
-	.preenable = &max1363_ring_preenable,
+	.preenable = &iio_sw_buffer_preenable,
 	.predisable = &iio_triggered_buffer_predisable,
 };
 
@@ -179,7 +119,7 @@
 	/* Effectively select the ring buffer implementation */
 	indio_dev->buffer->access = &ring_sw_access_funcs;
 	/* Ring buffer functions - here trigger setup related */
-	indio_dev->buffer->setup_ops = &max1363_ring_setup_ops;
+	indio_dev->setup_ops = &max1363_ring_setup_ops;
 
 	/* Flag that polled ring buffering is possible */
 	indio_dev->modes |= INDIO_BUFFER_TRIGGERED;
diff --git a/drivers/staging/iio/addac/adt7316-spi.c b/drivers/staging/iio/addac/adt7316-spi.c
index 1e93c7b..1ea3cd0 100644
--- a/drivers/staging/iio/addac/adt7316-spi.c
+++ b/drivers/staging/iio/addac/adt7316-spi.c
@@ -151,7 +151,6 @@
 static struct spi_driver adt7316_driver = {
 	.driver = {
 		.name = "adt7316",
-		.bus = &spi_bus_type,
 		.owner = THIS_MODULE,
 	},
 	.probe = adt7316_spi_probe,
diff --git a/drivers/staging/iio/addac/adt7316.c b/drivers/staging/iio/addac/adt7316.c
index 8df2470..13c3929 100644
--- a/drivers/staging/iio/addac/adt7316.c
+++ b/drivers/staging/iio/addac/adt7316.c
@@ -20,6 +20,7 @@
 #include <linux/module.h>
 
 #include "../iio.h"
+#include "../events.h"
 #include "../sysfs.h"
 #include "adt7316.h"
 
diff --git a/drivers/staging/iio/buffer_generic.h b/drivers/staging/iio/buffer.h
similarity index 67%
rename from drivers/staging/iio/buffer_generic.h
rename to drivers/staging/iio/buffer.h
index 9e8f010..6fb6e64 100644
--- a/drivers/staging/iio/buffer_generic.h
+++ b/drivers/staging/iio/buffer.h
@@ -11,7 +11,6 @@
 #define _IIO_BUFFER_GENERIC_H_
 #include <linux/sysfs.h>
 #include "iio.h"
-#include "chrdev.h"
 
 #ifdef CONFIG_IIO_BUFFER
 
@@ -19,22 +18,14 @@
 
 /**
  * struct iio_buffer_access_funcs - access functions for buffers.
- * @mark_in_use:	reference counting, typically to prevent module removal
- * @unmark_in_use:	reduce reference count when no longer using buffer
  * @store_to:		actually store stuff to the buffer
- * @read_last:		get the last element stored
- * @read_first_n:	try to get a specified number of elements (must exist)
- * @mark_param_change:	notify buffer that some relevant parameter has changed
- *			Often this means the underlying storage may need to
- *			change.
+ * @read_first_n:	try to get a specified number of bytes (must exist)
  * @request_update:	if a parameter change has been marked, update underlying
  *			storage.
  * @get_bytes_per_datum:get current bytes per datum
  * @set_bytes_per_datum:set number of bytes per datum
  * @get_length:		get number of datums in buffer
  * @set_length:		set number of datums in buffer
- * @is_enabled:		query if buffer is currently being used
- * @enable:		enable the buffer
  *
  * The purpose of this structure is to make the buffer element
  * modular as event for a given driver, different usecases may require
@@ -45,85 +36,60 @@
  * any of them not existing.
  **/
 struct iio_buffer_access_funcs {
-	void (*mark_in_use)(struct iio_buffer *buffer);
-	void (*unmark_in_use)(struct iio_buffer *buffer);
-
 	int (*store_to)(struct iio_buffer *buffer, u8 *data, s64 timestamp);
-	int (*read_last)(struct iio_buffer *buffer, u8 *data);
 	int (*read_first_n)(struct iio_buffer *buffer,
 			    size_t n,
 			    char __user *buf);
 
-	int (*mark_param_change)(struct iio_buffer *buffer);
 	int (*request_update)(struct iio_buffer *buffer);
 
 	int (*get_bytes_per_datum)(struct iio_buffer *buffer);
 	int (*set_bytes_per_datum)(struct iio_buffer *buffer, size_t bpd);
 	int (*get_length)(struct iio_buffer *buffer);
 	int (*set_length)(struct iio_buffer *buffer, int length);
-
-	int (*is_enabled)(struct iio_buffer *buffer);
-	int (*enable)(struct iio_buffer *buffer);
-};
-
-/**
- * struct iio_buffer_setup_ops - buffer setup related callbacks
- * @preenable:		[DRIVER] function to run prior to marking buffer enabled
- * @postenable:		[DRIVER] function to run after marking buffer enabled
- * @predisable:		[DRIVER] function to run prior to marking buffer
- *			disabled
- * @postdisable:	[DRIVER] function to run after marking buffer disabled
- */
-struct iio_buffer_setup_ops {
-	int				(*preenable)(struct iio_dev *);
-	int				(*postenable)(struct iio_dev *);
-	int				(*predisable)(struct iio_dev *);
-	int				(*postdisable)(struct iio_dev *);
 };
 
 /**
  * struct iio_buffer - general buffer structure
- * @indio_dev:		industrial I/O device structure
- * @owner:		module that owns the buffer (for ref counting)
  * @length:		[DEVICE] number of datums in buffer
  * @bytes_per_datum:	[DEVICE] size of individual datum including timestamp
- * @bpe:		[DEVICE] size of individual channel value
  * @scan_el_attrs:	[DRIVER] control of scan elements if that scan mode
  *			control method is used
- * @scan_count:	[INTERN] the number of elements in the current scan mode
  * @scan_mask:		[INTERN] bitmask used in masking scan mode elements
+ * @scan_index_timestamp:[INTERN] cache of the index to the timestamp
  * @scan_timestamp:	[INTERN] does the scan mode include a timestamp
  * @access:		[DRIVER] buffer access functions associated with the
  *			implementation.
- * @flags:		[INTERN] file ops related flags including busy flag.
+ * @scan_el_dev_attr_list:[INTERN] list of scan element related attributes.
+ * @scan_el_group:	[DRIVER] attribute group for those attributes not
+ *			created from the iio_chan_info array.
+ * @pollq:		[INTERN] wait queue to allow for polling on the buffer.
+ * @stufftoread:	[INTERN] flag to indicate new data.
+ * @demux_list:		[INTERN] list of operations required to demux the scan.
+ * @demux_bounce:	[INTERN] buffer for doing gather from incoming scan.
  **/
 struct iio_buffer {
-	struct iio_dev				*indio_dev;
-	struct module				*owner;
 	int					length;
 	int					bytes_per_datum;
-	int					bpe;
 	struct attribute_group			*scan_el_attrs;
-	int					scan_count;
 	long					*scan_mask;
 	bool					scan_timestamp;
+	unsigned				scan_index_timestamp;
 	const struct iio_buffer_access_funcs	*access;
-	const struct iio_buffer_setup_ops		*setup_ops;
 	struct list_head			scan_el_dev_attr_list;
 	struct attribute_group			scan_el_group;
 	wait_queue_head_t			pollq;
 	bool					stufftoread;
-	unsigned long				flags;
 	const struct attribute_group *attrs;
+	struct list_head			demux_list;
+	unsigned char				*demux_bounce;
 };
 
 /**
  * iio_buffer_init() - Initialize the buffer structure
  * @buffer: buffer to be initialized
- * @indio_dev: the iio device the buffer is assocated with
  **/
-void iio_buffer_init(struct iio_buffer *buffer,
-			  struct iio_dev *indio_dev);
+void iio_buffer_init(struct iio_buffer *buffer);
 
 void iio_buffer_deinit(struct iio_buffer *buffer);
 
@@ -140,17 +106,27 @@
 	buffer->length = length;
 }
 
-int iio_scan_mask_query(struct iio_buffer *buffer, int bit);
+int iio_scan_mask_query(struct iio_dev *indio_dev,
+			struct iio_buffer *buffer, int bit);
 
 /**
  * iio_scan_mask_set() - set particular bit in the scan mask
  * @buffer: the buffer whose scan mask we are interested in
  * @bit: the bit to be set.
  **/
-int iio_scan_mask_set(struct iio_buffer *buffer, int bit);
+int iio_scan_mask_set(struct iio_dev *indio_dev,
+		      struct iio_buffer *buffer, int bit);
 
-#define to_iio_buffer(d)				\
-	container_of(d, struct iio_buffer, dev)
+/**
+ * iio_push_to_buffer() - push to a registered buffer.
+ * @buffer:		IIO buffer structure for device
+ * @scan:		Full scan.
+ * @timestamp:
+ */
+int iio_push_to_buffer(struct iio_buffer *buffer, unsigned char *data,
+		       s64 timestamp);
+
+int iio_update_demux(struct iio_dev *indio_dev);
 
 /**
  * iio_buffer_register() - register the buffer with IIO core
@@ -180,12 +156,6 @@
 			      const char *buf,
 			      size_t len);
 /**
- * iio_buffer_read_bytes_per_datum() - attr for number of bytes in whole datum
- **/
-ssize_t iio_buffer_read_bytes_per_datum(struct device *dev,
-					struct device_attribute *attr,
-					char *buf);
-/**
  * iio_buffer_store_enable() - attr to turn the buffer on
  **/
 ssize_t iio_buffer_store_enable(struct device *dev,
@@ -201,9 +171,6 @@
 #define IIO_BUFFER_LENGTH_ATTR DEVICE_ATTR(length, S_IRUGO | S_IWUSR,	\
 					   iio_buffer_read_length,	\
 					   iio_buffer_write_length)
-#define IIO_BUFFER_BYTES_PER_DATUM_ATTR					\
-	DEVICE_ATTR(bytes_per_datum, S_IRUGO | S_IWUSR,			\
-		    iio_buffer_read_bytes_per_datum, NULL)
 
 #define IIO_BUFFER_ENABLE_ATTR DEVICE_ATTR(enable, S_IRUGO | S_IWUSR,	\
 					   iio_buffer_show_enable,	\
diff --git a/drivers/staging/iio/cdc/ad7150.c b/drivers/staging/iio/cdc/ad7150.c
index 4718187..b73007d 100644
--- a/drivers/staging/iio/cdc/ad7150.c
+++ b/drivers/staging/iio/cdc/ad7150.c
@@ -15,7 +15,7 @@
 
 #include "../iio.h"
 #include "../sysfs.h"
-
+#include "../events.h"
 /*
  * AD7150 registers definition
  */
@@ -111,7 +111,7 @@
 			return ret;
 		*val = swab16(ret);
 		return IIO_VAL_INT;
-	case (1 << IIO_CHAN_INFO_AVERAGE_RAW_SEPARATE):
+	case IIO_CHAN_INFO_AVERAGE_RAW:
 		ret = i2c_smbus_read_word_data(chip->client,
 					ad7150_addresses[chan->channel][1]);
 		if (ret < 0)
@@ -429,7 +429,7 @@
 		.type = IIO_CAPACITANCE,
 		.indexed = 1,
 		.channel = 0,
-		.info_mask = (1 << IIO_CHAN_INFO_AVERAGE_RAW_SEPARATE),
+		.info_mask = IIO_CHAN_INFO_AVERAGE_RAW_SEPARATE_BIT,
 		.event_mask =
 		IIO_EV_BIT(IIO_EV_TYPE_THRESH, IIO_EV_DIR_RISING) |
 		IIO_EV_BIT(IIO_EV_TYPE_THRESH, IIO_EV_DIR_FALLING) |
@@ -441,7 +441,7 @@
 		.type = IIO_CAPACITANCE,
 		.indexed = 1,
 		.channel = 1,
-		.info_mask = (1 << IIO_CHAN_INFO_AVERAGE_RAW_SEPARATE),
+		.info_mask = IIO_CHAN_INFO_AVERAGE_RAW_SEPARATE_BIT,
 		.event_mask =
 		IIO_EV_BIT(IIO_EV_TYPE_THRESH, IIO_EV_DIR_RISING) |
 		IIO_EV_BIT(IIO_EV_TYPE_THRESH, IIO_EV_DIR_FALLING) |
diff --git a/drivers/staging/iio/cdc/ad7152.c b/drivers/staging/iio/cdc/ad7152.c
index 152d3be..fdb83c3 100644
--- a/drivers/staging/iio/cdc/ad7152.c
+++ b/drivers/staging/iio/cdc/ad7152.c
@@ -259,7 +259,7 @@
 	mutex_lock(&indio_dev->mlock);
 
 	switch (mask) {
-	case (1 << IIO_CHAN_INFO_CALIBSCALE_SEPARATE):
+	case IIO_CHAN_INFO_CALIBSCALE:
 		if (val != 1) {
 			ret = -EINVAL;
 			goto out;
@@ -276,7 +276,7 @@
 		ret = 0;
 		break;
 
-	case (1 << IIO_CHAN_INFO_CALIBBIAS_SEPARATE):
+	case IIO_CHAN_INFO_CALIBBIAS:
 		if ((val < 0) | (val > 0xFFFF)) {
 			ret = -EINVAL;
 			goto out;
@@ -289,7 +289,7 @@
 
 		ret = 0;
 		break;
-	case (1 << IIO_CHAN_INFO_SCALE_SEPARATE):
+	case IIO_CHAN_INFO_SCALE:
 		if (val != 0) {
 			ret = -EINVAL;
 			goto out;
@@ -372,7 +372,7 @@
 
 		ret = IIO_VAL_INT;
 		break;
-	case (1 << IIO_CHAN_INFO_CALIBSCALE_SEPARATE):
+	case IIO_CHAN_INFO_CALIBSCALE:
 
 		ret = i2c_smbus_read_word_data(chip->client,
 				ad7152_addresses[chan->channel][AD7152_GAIN]);
@@ -384,7 +384,7 @@
 
 		ret = IIO_VAL_INT_PLUS_MICRO;
 		break;
-	case (1 << IIO_CHAN_INFO_CALIBBIAS_SEPARATE):
+	case IIO_CHAN_INFO_CALIBBIAS:
 		ret = i2c_smbus_read_word_data(chip->client,
 				ad7152_addresses[chan->channel][AD7152_OFFS]);
 		if (ret < 0)
@@ -393,7 +393,7 @@
 
 		ret = IIO_VAL_INT;
 		break;
-	case (1 << IIO_CHAN_INFO_SCALE_SEPARATE):
+	case IIO_CHAN_INFO_SCALE:
 		ret = i2c_smbus_read_byte_data(chip->client,
 				ad7152_addresses[chan->channel][AD7152_SETUP]);
 		if (ret < 0)
@@ -416,7 +416,7 @@
 			       long mask)
 {
 	switch (mask) {
-	case (1 << IIO_CHAN_INFO_SCALE_SEPARATE):
+	case IIO_CHAN_INFO_SCALE:
 		return IIO_VAL_INT_PLUS_NANO;
 	default:
 		return IIO_VAL_INT_PLUS_MICRO;
@@ -436,34 +436,34 @@
 		.type = IIO_CAPACITANCE,
 		.indexed = 1,
 		.channel = 0,
-		.info_mask = (1 << IIO_CHAN_INFO_CALIBSCALE_SEPARATE) |
-		(1 << IIO_CHAN_INFO_CALIBBIAS_SEPARATE) |
-		(1 << IIO_CHAN_INFO_SCALE_SEPARATE),
+		.info_mask = IIO_CHAN_INFO_CALIBSCALE_SEPARATE_BIT |
+		IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT |
+		IIO_CHAN_INFO_SCALE_SEPARATE_BIT,
 	}, {
 		.type = IIO_CAPACITANCE,
 		.differential = 1,
 		.indexed = 1,
 		.channel = 0,
 		.channel2 = 2,
-		.info_mask = (1 << IIO_CHAN_INFO_CALIBSCALE_SEPARATE) |
-		(1 << IIO_CHAN_INFO_CALIBBIAS_SEPARATE) |
-		(1 << IIO_CHAN_INFO_SCALE_SEPARATE),
+		.info_mask = IIO_CHAN_INFO_CALIBSCALE_SEPARATE_BIT |
+		IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT |
+		IIO_CHAN_INFO_SCALE_SEPARATE_BIT,
 	}, {
 		.type = IIO_CAPACITANCE,
 		.indexed = 1,
 		.channel = 1,
-		.info_mask = (1 << IIO_CHAN_INFO_CALIBSCALE_SEPARATE) |
-		(1 << IIO_CHAN_INFO_CALIBBIAS_SEPARATE) |
-		(1 << IIO_CHAN_INFO_SCALE_SEPARATE),
+		.info_mask = IIO_CHAN_INFO_CALIBSCALE_SEPARATE_BIT |
+		IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT |
+		IIO_CHAN_INFO_SCALE_SEPARATE_BIT,
 	}, {
 		.type = IIO_CAPACITANCE,
 		.differential = 1,
 		.indexed = 1,
 		.channel = 1,
 		.channel2 = 3,
-		.info_mask = (1 << IIO_CHAN_INFO_CALIBSCALE_SEPARATE) |
-		(1 << IIO_CHAN_INFO_CALIBBIAS_SEPARATE) |
-		(1 << IIO_CHAN_INFO_SCALE_SEPARATE),
+		.info_mask = IIO_CHAN_INFO_CALIBSCALE_SEPARATE_BIT |
+		IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT |
+		IIO_CHAN_INFO_SCALE_SEPARATE_BIT,
 	}
 };
 /*
diff --git a/drivers/staging/iio/cdc/ad7746.c b/drivers/staging/iio/cdc/ad7746.c
index 9df5908..40b8512 100644
--- a/drivers/staging/iio/cdc/ad7746.c
+++ b/drivers/staging/iio/cdc/ad7746.c
@@ -123,7 +123,7 @@
 		.type = IIO_VOLTAGE,
 		.indexed = 1,
 		.channel = 0,
-		.info_mask = (1 << IIO_CHAN_INFO_SCALE_SHARED),
+		.info_mask = IIO_CHAN_INFO_SCALE_SHARED_BIT,
 		.address = AD7746_REG_VT_DATA_HIGH << 8 |
 			AD7746_VTSETUP_VTMD_EXT_VIN,
 	},
@@ -132,7 +132,7 @@
 		.indexed = 1,
 		.channel = 1,
 		.extend_name = "supply",
-		.info_mask = (1 << IIO_CHAN_INFO_SCALE_SHARED),
+		.info_mask = IIO_CHAN_INFO_SCALE_SHARED_BIT,
 		.address = AD7746_REG_VT_DATA_HIGH << 8 |
 			AD7746_VTSETUP_VTMD_VDD_MON,
 	},
@@ -156,10 +156,10 @@
 		.type = IIO_CAPACITANCE,
 		.indexed = 1,
 		.channel = 0,
-		.info_mask = (1 << IIO_CHAN_INFO_CALIBSCALE_SEPARATE) |
-		(1 << IIO_CHAN_INFO_CALIBBIAS_SHARED) |
-		(1 << IIO_CHAN_INFO_OFFSET_SEPARATE) |
-		(1 << IIO_CHAN_INFO_SCALE_SHARED),
+		.info_mask = IIO_CHAN_INFO_CALIBSCALE_SEPARATE_BIT |
+		IIO_CHAN_INFO_CALIBBIAS_SHARED_BIT |
+		IIO_CHAN_INFO_OFFSET_SEPARATE_BIT |
+		IIO_CHAN_INFO_SCALE_SHARED_BIT,
 		.address = AD7746_REG_CAP_DATA_HIGH << 8,
 	},
 	[CIN1_DIFF] = {
@@ -168,10 +168,10 @@
 		.indexed = 1,
 		.channel = 0,
 		.channel2 = 2,
-		.info_mask = (1 << IIO_CHAN_INFO_CALIBSCALE_SEPARATE) |
-		(1 << IIO_CHAN_INFO_CALIBBIAS_SHARED) |
-		(1 << IIO_CHAN_INFO_OFFSET_SEPARATE) |
-		(1 << IIO_CHAN_INFO_SCALE_SHARED),
+		.info_mask = IIO_CHAN_INFO_CALIBSCALE_SEPARATE_BIT |
+		IIO_CHAN_INFO_CALIBBIAS_SHARED_BIT |
+		IIO_CHAN_INFO_OFFSET_SEPARATE_BIT |
+		IIO_CHAN_INFO_SCALE_SHARED_BIT,
 		.address = AD7746_REG_CAP_DATA_HIGH << 8 |
 			AD7746_CAPSETUP_CAPDIFF
 	},
@@ -179,10 +179,10 @@
 		.type = IIO_CAPACITANCE,
 		.indexed = 1,
 		.channel = 1,
-		.info_mask = (1 << IIO_CHAN_INFO_CALIBSCALE_SEPARATE) |
-		(1 << IIO_CHAN_INFO_CALIBBIAS_SHARED) |
-		(1 << IIO_CHAN_INFO_OFFSET_SEPARATE) |
-		(1 << IIO_CHAN_INFO_SCALE_SHARED),
+		.info_mask = IIO_CHAN_INFO_CALIBSCALE_SEPARATE_BIT |
+		IIO_CHAN_INFO_CALIBBIAS_SHARED_BIT |
+		IIO_CHAN_INFO_OFFSET_SEPARATE_BIT |
+		IIO_CHAN_INFO_SCALE_SHARED_BIT,
 		.address = AD7746_REG_CAP_DATA_HIGH << 8 |
 			AD7746_CAPSETUP_CIN2,
 	},
@@ -192,10 +192,10 @@
 		.indexed = 1,
 		.channel = 1,
 		.channel2 = 3,
-		.info_mask = (1 << IIO_CHAN_INFO_CALIBSCALE_SEPARATE) |
-		(1 << IIO_CHAN_INFO_CALIBBIAS_SHARED) |
-		(1 << IIO_CHAN_INFO_OFFSET_SEPARATE) |
-		(1 << IIO_CHAN_INFO_SCALE_SHARED),
+		.info_mask = IIO_CHAN_INFO_CALIBSCALE_SEPARATE_BIT |
+		IIO_CHAN_INFO_CALIBBIAS_SHARED_BIT |
+		IIO_CHAN_INFO_OFFSET_SEPARATE_BIT |
+		IIO_CHAN_INFO_SCALE_SHARED_BIT,
 		.address = AD7746_REG_CAP_DATA_HIGH << 8 |
 			AD7746_CAPSETUP_CAPDIFF | AD7746_CAPSETUP_CIN2,
 	}
@@ -477,7 +477,7 @@
 	mutex_lock(&indio_dev->mlock);
 
 	switch (mask) {
-	case (1 << IIO_CHAN_INFO_CALIBSCALE_SEPARATE):
+	case IIO_CHAN_INFO_CALIBSCALE:
 		if (val != 1) {
 			ret = -EINVAL;
 			goto out;
@@ -503,7 +503,7 @@
 
 		ret = 0;
 		break;
-	case (1 << IIO_CHAN_INFO_CALIBBIAS_SHARED):
+	case IIO_CHAN_INFO_CALIBBIAS:
 		if ((val < 0) | (val > 0xFFFF)) {
 			ret = -EINVAL;
 			goto out;
@@ -515,7 +515,7 @@
 
 		ret = 0;
 		break;
-	case (1 << IIO_CHAN_INFO_OFFSET_SEPARATE):
+	case IIO_CHAN_INFO_OFFSET:
 		if ((val < 0) | (val > 43008000)) { /* 21pF */
 			ret = -EINVAL;
 			goto out;
@@ -612,7 +612,7 @@
 
 		ret = IIO_VAL_INT;
 		break;
-	case (1 << IIO_CHAN_INFO_CALIBSCALE_SEPARATE):
+	case IIO_CHAN_INFO_CALIBSCALE:
 		switch (chan->type) {
 		case IIO_CAPACITANCE:
 			reg = AD7746_REG_CAP_GAINH;
@@ -634,7 +634,7 @@
 
 		ret = IIO_VAL_INT_PLUS_MICRO;
 		break;
-	case (1 << IIO_CHAN_INFO_CALIBBIAS_SHARED):
+	case IIO_CHAN_INFO_CALIBBIAS:
 		ret = i2c_smbus_read_word_data(chip->client,
 					       AD7746_REG_CAP_OFFH);
 		if (ret < 0)
@@ -643,13 +643,13 @@
 
 		ret = IIO_VAL_INT;
 		break;
-	case (1 << IIO_CHAN_INFO_OFFSET_SEPARATE):
+	case IIO_CHAN_INFO_OFFSET:
 		*val = AD7746_CAPDAC_DACP(chip->capdac[chan->channel]
 			[chan->differential]) * 338646;
 
 		ret = IIO_VAL_INT;
 		break;
-	case (1 << IIO_CHAN_INFO_SCALE_SHARED):
+	case IIO_CHAN_INFO_SCALE:
 		switch (chan->type) {
 		case IIO_CAPACITANCE:
 			/* 8.192pf / 2^24 */
diff --git a/drivers/staging/iio/chrdev.h b/drivers/staging/iio/chrdev.h
deleted file mode 100644
index d8e736f..0000000
--- a/drivers/staging/iio/chrdev.h
+++ /dev/null
@@ -1,25 +0,0 @@
-/* The industrial I/O core - character device related
- *
- * Copyright (c) 2008 Jonathan Cameron
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 as published by
- * the Free Software Foundation.
- */
-
-#ifndef _IIO_CHRDEV_H_
-#define _IIO_CHRDEV_H_
-
-/**
- * struct iio_event_data - The actual event being pushed to userspace
- * @id:		event identifier
- * @timestamp:	best estimate of time of event occurrence (often from
- *		the interrupt handler)
- */
-struct iio_event_data {
-	u64	id;
-	s64	timestamp;
-};
-
-#define IIO_GET_EVENT_FD_IOCTL _IOR('i', 0x90, int)
-#endif
diff --git a/drivers/staging/iio/dac/Kconfig b/drivers/staging/iio/dac/Kconfig
index fac8549..13e2797 100644
--- a/drivers/staging/iio/dac/Kconfig
+++ b/drivers/staging/iio/dac/Kconfig
@@ -24,6 +24,29 @@
 	  To compile this driver as module choose M here: the module will be called
 	  ad5360.
 
+config AD5380
+	tristate "Analog Devices AD5380/81/82/83/84/90/91/92 DAC driver"
+	depends on (SPI_MASTER || I2C)
+	select REGMAP_I2C if I2C
+	select REGMAP_SPI if SPI_MASTER
+	help
+	  Say yes here to build support for Analog Devices AD5380, AD5381,
+	  AD5382, AD5383, AD5384, AD5390, AD5391, AD5392 multi-channel
+	  Digital to Analog Converters (DAC).
+
+	  To compile this driver as module choose M here: the module will be called
+	  ad5380.
+
+config AD5421
+	tristate "Analog Devices AD5421 DAC driver"
+	depends on SPI
+	help
+	  Say yes here to build support for Analog Devices AD5421 loop-powered
+	  digital-to-analog convertors (DAC).
+
+	  To compile this driver as module choose M here: the module will be called
+	  ad5421.
+
 config AD5624R_SPI
 	tristate "Analog Devices AD5624/44/64R DAC spi driver"
 	depends on SPI
@@ -37,7 +60,7 @@
 	help
 	  Say yes here to build support for Analog Devices AD5444, AD5446,
 	  AD5512A, AD5542A, AD5543, AD5553, AD5601, AD5611, AD5620, AD5621,
-	  AD5640, AD5660 DACs.
+	  AD5640, AD5660, AD5662 DACs.
 
 	  To compile this driver as a module, choose M here: the
 	  module will be called ad5446.
@@ -52,12 +75,22 @@
 	  To compile this driver as a module, choose M here: the
 	  module will be called ad5504.
 
+config AD5764
+	tristate "Analog Devices AD5764/64R/44/44R DAC driver"
+	depends on SPI_MASTER
+	help
+	  Say yes here to build support for Analog Devices AD5764, AD5764R, AD5744,
+	  AD5744R Digital to Analog Converter.
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called ad5764.
+
 config AD5791
-	tristate "Analog Devices AD5760/AD5780/AD5781/AD5791 DAC SPI driver"
+	tristate "Analog Devices AD5760/AD5780/AD5781/AD5790/AD5791 DAC SPI driver"
 	depends on SPI
 	help
 	  Say yes here to build support for Analog Devices AD5760, AD5780,
-	  AD5781, AD5791 High Resolution Voltage Output Digital to
+	  AD5781, AD5790, AD5791 High Resolution Voltage Output Digital to
 	  Analog Converter.
 
 	  To compile this driver as a module, choose M here: the
diff --git a/drivers/staging/iio/dac/Makefile b/drivers/staging/iio/dac/Makefile
index 07b6f5e..8ab1d26 100644
--- a/drivers/staging/iio/dac/Makefile
+++ b/drivers/staging/iio/dac/Makefile
@@ -3,10 +3,13 @@
 #
 
 obj-$(CONFIG_AD5360) += ad5360.o
+obj-$(CONFIG_AD5380) += ad5380.o
+obj-$(CONFIG_AD5421) += ad5421.o
 obj-$(CONFIG_AD5624R_SPI) += ad5624r_spi.o
 obj-$(CONFIG_AD5064) += ad5064.o
 obj-$(CONFIG_AD5504) += ad5504.o
 obj-$(CONFIG_AD5446) += ad5446.o
+obj-$(CONFIG_AD5764) += ad5764.o
 obj-$(CONFIG_AD5791) += ad5791.o
 obj-$(CONFIG_AD5686) += ad5686.o
 obj-$(CONFIG_MAX517) += max517.o
diff --git a/drivers/staging/iio/dac/ad5064.c b/drivers/staging/iio/dac/ad5064.c
index 39cfe6c..049a855 100644
--- a/drivers/staging/iio/dac/ad5064.c
+++ b/drivers/staging/iio/dac/ad5064.c
@@ -91,7 +91,7 @@
 	.indexed = 1,						\
 	.output = 1,						\
 	.channel = (chan),					\
-	.info_mask = (1 << IIO_CHAN_INFO_SCALE_SEPARATE),	\
+	.info_mask = IIO_CHAN_INFO_SCALE_SEPARATE_BIT,	\
 	.address = AD5064_ADDR_DAC(chan),			\
 	.scan_type = IIO_ST('u', (bits), 16, 20 - (bits))	\
 }
@@ -280,14 +280,14 @@
 			   long m)
 {
 	struct ad5064_state *st = iio_priv(indio_dev);
-	unsigned long scale_uv;
 	unsigned int vref;
+	int scale_uv;
 
 	switch (m) {
 	case 0:
 		*val = st->dac_cache[chan->channel];
 		return IIO_VAL_INT;
-	case (1 << IIO_CHAN_INFO_SCALE_SEPARATE):
+	case IIO_CHAN_INFO_SCALE:
 		vref = st->chip_info->shared_vref ? 0 : chan->channel;
 		scale_uv = regulator_get_voltage(st->vref_reg[vref].consumer);
 		if (scale_uv < 0)
diff --git a/drivers/staging/iio/dac/ad5360.c b/drivers/staging/iio/dac/ad5360.c
index bc0459e..710b256 100644
--- a/drivers/staging/iio/dac/ad5360.c
+++ b/drivers/staging/iio/dac/ad5360.c
@@ -103,10 +103,10 @@
 	.type = IIO_VOLTAGE,					\
 	.indexed = 1,						\
 	.output = 1,						\
-	.info_mask = (1 << IIO_CHAN_INFO_SCALE_SEPARATE) |	\
-		(1 << IIO_CHAN_INFO_OFFSET_SEPARATE) |		\
-		(1 << IIO_CHAN_INFO_CALIBSCALE_SEPARATE) |	\
-		(1 << IIO_CHAN_INFO_CALIBBIAS_SEPARATE),	\
+	.info_mask = IIO_CHAN_INFO_SCALE_SEPARATE_BIT |	\
+		IIO_CHAN_INFO_OFFSET_SEPARATE_BIT |		\
+		IIO_CHAN_INFO_CALIBSCALE_SEPARATE_BIT |	\
+		IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT,	\
 	.scan_type = IIO_ST('u', (bits), 16, 16 - (bits))	\
 }
 
@@ -326,21 +326,21 @@
 		return ad5360_write(indio_dev, AD5360_CMD_WRITE_DATA,
 				 chan->address, val, chan->scan_type.shift);
 
-	case (1 << IIO_CHAN_INFO_CALIBBIAS_SEPARATE):
+	case IIO_CHAN_INFO_CALIBBIAS:
 		if (val >= max_val || val < 0)
 			return -EINVAL;
 
 		return ad5360_write(indio_dev, AD5360_CMD_WRITE_OFFSET,
 				 chan->address, val, chan->scan_type.shift);
 
-	case (1 << IIO_CHAN_INFO_CALIBSCALE_SEPARATE):
+	case IIO_CHAN_INFO_CALIBSCALE:
 		if (val >= max_val || val < 0)
 			return -EINVAL;
 
 		return ad5360_write(indio_dev, AD5360_CMD_WRITE_GAIN,
 				 chan->address, val, chan->scan_type.shift);
 
-	case (1 << IIO_CHAN_INFO_OFFSET_SEPARATE):
+	case IIO_CHAN_INFO_OFFSET:
 		if (val <= -max_val || val > 0)
 			return -EINVAL;
 
@@ -371,8 +371,8 @@
 			   long m)
 {
 	struct ad5360_state *st = iio_priv(indio_dev);
-	unsigned long scale_uv;
 	unsigned int ofs_index;
+	int scale_uv;
 	int ret;
 
 	switch (m) {
@@ -383,7 +383,7 @@
 			return ret;
 		*val = ret >> chan->scan_type.shift;
 		return IIO_VAL_INT;
-	case (1 << IIO_CHAN_INFO_SCALE_SEPARATE):
+	case IIO_CHAN_INFO_SCALE:
 		/* vout = 4 * vref * dac_code */
 		scale_uv = ad5360_get_channel_vref(st, chan->channel) * 4 * 100;
 		if (scale_uv < 0)
@@ -393,21 +393,21 @@
 		*val =  scale_uv / 100000;
 		*val2 = (scale_uv % 100000) * 10;
 		return IIO_VAL_INT_PLUS_MICRO;
-	case (1 << IIO_CHAN_INFO_CALIBBIAS_SEPARATE):
+	case IIO_CHAN_INFO_CALIBBIAS:
 		ret = ad5360_read(indio_dev, AD5360_READBACK_OFFSET,
 			chan->address);
 		if (ret < 0)
 			return ret;
 		*val = ret;
 		return IIO_VAL_INT;
-	case (1 << IIO_CHAN_INFO_CALIBSCALE_SEPARATE):
+	case IIO_CHAN_INFO_CALIBSCALE:
 		ret = ad5360_read(indio_dev, AD5360_READBACK_GAIN,
 			chan->address);
 		if (ret < 0)
 			return ret;
 		*val = ret;
 		return IIO_VAL_INT;
-	case (1 << IIO_CHAN_INFO_OFFSET_SEPARATE):
+	case IIO_CHAN_INFO_OFFSET:
 		ofs_index = ad5360_get_channel_vref_index(st, chan->channel);
 		ret = ad5360_read(indio_dev, AD5360_READBACK_SF,
 			AD5360_REG_SF_OFS(ofs_index));
diff --git a/drivers/staging/iio/dac/ad5380.c b/drivers/staging/iio/dac/ad5380.c
new file mode 100644
index 0000000..eff97ae0
--- /dev/null
+++ b/drivers/staging/iio/dac/ad5380.c
@@ -0,0 +1,676 @@
+/*
+ * Analog devices AD5380, AD5381, AD5382, AD5383, AD5390, AD5391, AD5392
+ * multi-channel Digital to Analog Converters driver
+ *
+ * Copyright 2011 Analog Devices Inc.
+ *
+ * Licensed under the GPL-2.
+ */
+
+#include <linux/device.h>
+#include <linux/err.h>
+#include <linux/i2c.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/spi/spi.h>
+#include <linux/slab.h>
+#include <linux/sysfs.h>
+#include <linux/regmap.h>
+#include <linux/regulator/consumer.h>
+
+#include "../iio.h"
+#include "../sysfs.h"
+#include "dac.h"
+
+
+#define AD5380_REG_DATA(x)	(((x) << 2) | 3)
+#define AD5380_REG_OFFSET(x)	(((x) << 2) | 2)
+#define AD5380_REG_GAIN(x)	(((x) << 2) | 1)
+#define AD5380_REG_SF_PWR_DOWN	(8 << 2)
+#define AD5380_REG_SF_PWR_UP	(9 << 2)
+#define AD5380_REG_SF_CTRL	(12 << 2)
+
+#define AD5380_CTRL_PWR_DOWN_MODE_OFFSET	13
+#define AD5380_CTRL_INT_VREF_2V5		BIT(12)
+#define AD5380_CTRL_INT_VREF_EN			BIT(10)
+
+/**
+ * struct ad5380_chip_info - chip specific information
+ * @channel_template:	channel specification template
+ * @num_channels:	number of channels
+ * @int_vref:		internal vref in uV
+*/
+
+struct ad5380_chip_info {
+	struct iio_chan_spec	channel_template;
+	unsigned int		num_channels;
+	unsigned int		int_vref;
+};
+
+/**
+ * struct ad5380_state - driver instance specific data
+ * @regmap:		regmap instance used by the device
+ * @chip_info:		chip model specific constants, available modes etc
+ * @vref_reg:		vref supply regulator
+ * @vref:		actual reference voltage used in uA
+ * @pwr_down:		whether the chip is currently in power down mode
+ */
+
+struct ad5380_state {
+	struct regmap			*regmap;
+	const struct ad5380_chip_info	*chip_info;
+	struct regulator		*vref_reg;
+	int				vref;
+	bool				pwr_down;
+};
+
+enum ad5380_type {
+	ID_AD5380_3,
+	ID_AD5380_5,
+	ID_AD5381_3,
+	ID_AD5381_5,
+	ID_AD5382_3,
+	ID_AD5382_5,
+	ID_AD5383_3,
+	ID_AD5383_5,
+	ID_AD5390_3,
+	ID_AD5390_5,
+	ID_AD5391_3,
+	ID_AD5391_5,
+	ID_AD5392_3,
+	ID_AD5392_5,
+};
+
+#define AD5380_CHANNEL(_bits) {					\
+	.type = IIO_VOLTAGE,					\
+	.indexed = 1,						\
+	.output = 1,						\
+	.info_mask = IIO_CHAN_INFO_SCALE_SHARED_BIT |		\
+		IIO_CHAN_INFO_CALIBSCALE_SEPARATE_BIT |		\
+		IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT,		\
+	.scan_type = IIO_ST('u', (_bits), 16, 14 - (_bits))	\
+}
+
+static const struct ad5380_chip_info ad5380_chip_info_tbl[] = {
+	[ID_AD5380_3] = {
+		.channel_template = AD5380_CHANNEL(14),
+		.num_channels = 40,
+		.int_vref = 1250000,
+	},
+	[ID_AD5380_5] = {
+		.channel_template = AD5380_CHANNEL(14),
+		.num_channels = 40,
+		.int_vref = 2500000,
+	},
+	[ID_AD5381_3] = {
+		.channel_template = AD5380_CHANNEL(12),
+		.num_channels = 16,
+		.int_vref = 1250000,
+	},
+	[ID_AD5381_5] = {
+		.channel_template = AD5380_CHANNEL(12),
+		.num_channels = 16,
+		.int_vref = 2500000,
+	},
+	[ID_AD5382_3] = {
+		.channel_template = AD5380_CHANNEL(14),
+		.num_channels = 32,
+		.int_vref = 1250000,
+	},
+	[ID_AD5382_5] = {
+		.channel_template = AD5380_CHANNEL(14),
+		.num_channels = 32,
+		.int_vref = 2500000,
+	},
+	[ID_AD5383_3] = {
+		.channel_template = AD5380_CHANNEL(12),
+		.num_channels = 32,
+		.int_vref = 1250000,
+	},
+	[ID_AD5383_5] = {
+		.channel_template = AD5380_CHANNEL(12),
+		.num_channels = 32,
+		.int_vref = 2500000,
+	},
+	[ID_AD5390_3] = {
+		.channel_template = AD5380_CHANNEL(14),
+		.num_channels = 16,
+		.int_vref = 1250000,
+	},
+	[ID_AD5390_5] = {
+		.channel_template = AD5380_CHANNEL(14),
+		.num_channels = 16,
+		.int_vref = 2500000,
+	},
+	[ID_AD5391_3] = {
+		.channel_template = AD5380_CHANNEL(12),
+		.num_channels = 16,
+		.int_vref = 1250000,
+	},
+	[ID_AD5391_5] = {
+		.channel_template = AD5380_CHANNEL(12),
+		.num_channels = 16,
+		.int_vref = 2500000,
+	},
+	[ID_AD5392_3] = {
+		.channel_template = AD5380_CHANNEL(14),
+		.num_channels = 8,
+		.int_vref = 1250000,
+	},
+	[ID_AD5392_5] = {
+		.channel_template = AD5380_CHANNEL(14),
+		.num_channels = 8,
+		.int_vref = 2500000,
+	},
+};
+
+static ssize_t ad5380_read_dac_powerdown(struct device *dev,
+	struct device_attribute *attr, char *buf)
+{
+	struct iio_dev *indio_dev = dev_get_drvdata(dev);
+	struct ad5380_state *st = iio_priv(indio_dev);
+
+	return sprintf(buf, "%d\n", st->pwr_down);
+}
+
+static ssize_t ad5380_write_dac_powerdown(struct device *dev,
+	struct device_attribute *attr, const char *buf, size_t len)
+{
+	struct iio_dev *indio_dev = dev_get_drvdata(dev);
+	struct ad5380_state *st = iio_priv(indio_dev);
+	bool pwr_down;
+	int ret;
+
+	ret = strtobool(buf, &pwr_down);
+	if (ret)
+		return ret;
+
+	mutex_lock(&indio_dev->mlock);
+
+	if (pwr_down)
+		ret = regmap_write(st->regmap, AD5380_REG_SF_PWR_DOWN, 0);
+	else
+		ret = regmap_write(st->regmap, AD5380_REG_SF_PWR_UP, 0);
+
+	st->pwr_down = pwr_down;
+
+	mutex_unlock(&indio_dev->mlock);
+
+	return ret ? ret : len;
+}
+
+static IIO_DEVICE_ATTR(out_voltage_powerdown,
+			S_IRUGO | S_IWUSR,
+			ad5380_read_dac_powerdown,
+			ad5380_write_dac_powerdown, 0);
+
+static const char ad5380_powerdown_modes[][15] = {
+	[0]	= "100kohm_to_gnd",
+	[1]	= "three_state",
+};
+
+static ssize_t ad5380_read_powerdown_mode(struct device *dev,
+	struct device_attribute *attr, char *buf)
+{
+	struct iio_dev *indio_dev = dev_get_drvdata(dev);
+	struct ad5380_state *st = iio_priv(indio_dev);
+	unsigned int mode;
+	int ret;
+
+	ret = regmap_read(st->regmap, AD5380_REG_SF_CTRL, &mode);
+	if (ret)
+		return ret;
+
+	mode = (mode >> AD5380_CTRL_PWR_DOWN_MODE_OFFSET) & 1;
+
+	return sprintf(buf, "%s\n", ad5380_powerdown_modes[mode]);
+}
+
+static ssize_t ad5380_write_powerdown_mode(struct device *dev,
+	struct device_attribute *attr, const char *buf, size_t len)
+{
+	struct iio_dev *indio_dev = dev_get_drvdata(dev);
+	struct ad5380_state *st = iio_priv(indio_dev);
+	unsigned int i;
+	int ret;
+
+	for (i = 0; i < ARRAY_SIZE(ad5380_powerdown_modes); ++i) {
+		if (sysfs_streq(buf, ad5380_powerdown_modes[i]))
+			break;
+	}
+
+	if (i == ARRAY_SIZE(ad5380_powerdown_modes))
+		return -EINVAL;
+
+	ret = regmap_update_bits(st->regmap, AD5380_REG_SF_CTRL,
+		1 << AD5380_CTRL_PWR_DOWN_MODE_OFFSET,
+		i << AD5380_CTRL_PWR_DOWN_MODE_OFFSET);
+
+	return ret ? ret : len;
+}
+
+static IIO_DEVICE_ATTR(out_voltage_powerdown_mode,
+			S_IRUGO | S_IWUSR,
+			ad5380_read_powerdown_mode,
+			ad5380_write_powerdown_mode, 0);
+
+static IIO_CONST_ATTR(out_voltage_powerdown_mode_available,
+			"100kohm_to_gnd three_state");
+
+static struct attribute *ad5380_attributes[] = {
+	&iio_dev_attr_out_voltage_powerdown.dev_attr.attr,
+	&iio_dev_attr_out_voltage_powerdown_mode.dev_attr.attr,
+	&iio_const_attr_out_voltage_powerdown_mode_available.dev_attr.attr,
+	NULL,
+};
+
+static const struct attribute_group ad5380_attribute_group = {
+	.attrs = ad5380_attributes,
+};
+
+static unsigned int ad5380_info_to_reg(struct iio_chan_spec const *chan,
+	long info)
+{
+	switch (info) {
+	case 0:
+		return AD5380_REG_DATA(chan->address);
+	case IIO_CHAN_INFO_CALIBBIAS:
+		return AD5380_REG_OFFSET(chan->address);
+	case IIO_CHAN_INFO_CALIBSCALE:
+		return AD5380_REG_GAIN(chan->address);
+	default:
+		break;
+	}
+
+	return 0;
+}
+
+static int ad5380_write_raw(struct iio_dev *indio_dev,
+	struct iio_chan_spec const *chan, int val, int val2, long info)
+{
+	const unsigned int max_val = (1 << chan->scan_type.realbits);
+	struct ad5380_state *st = iio_priv(indio_dev);
+
+	switch (info) {
+	case 0:
+	case IIO_CHAN_INFO_CALIBSCALE:
+		if (val >= max_val || val < 0)
+			return -EINVAL;
+
+		return regmap_write(st->regmap,
+			ad5380_info_to_reg(chan, info),
+			val << chan->scan_type.shift);
+	case IIO_CHAN_INFO_CALIBBIAS:
+		val += (1 << chan->scan_type.realbits) / 2;
+		if (val >= max_val || val < 0)
+			return -EINVAL;
+
+		return regmap_write(st->regmap,
+			AD5380_REG_OFFSET(chan->address),
+			val << chan->scan_type.shift);
+	default:
+		break;
+	}
+	return -EINVAL;
+}
+
+static int ad5380_read_raw(struct iio_dev *indio_dev,
+	struct iio_chan_spec const *chan, int *val, int *val2, long info)
+{
+	struct ad5380_state *st = iio_priv(indio_dev);
+	unsigned long scale_uv;
+	int ret;
+
+	switch (info) {
+	case 0:
+	case IIO_CHAN_INFO_CALIBSCALE:
+		ret = regmap_read(st->regmap, ad5380_info_to_reg(chan, info),
+					val);
+		if (ret)
+			return ret;
+		*val >>= chan->scan_type.shift;
+		return IIO_VAL_INT;
+	case IIO_CHAN_INFO_CALIBBIAS:
+		ret = regmap_read(st->regmap, AD5380_REG_OFFSET(chan->address),
+					val);
+		if (ret)
+			return ret;
+		*val >>= chan->scan_type.shift;
+		val -= (1 << chan->scan_type.realbits) / 2;
+		return IIO_VAL_INT;
+	case IIO_CHAN_INFO_SCALE:
+		scale_uv = ((2 * st->vref) >> chan->scan_type.realbits) * 100;
+		*val =  scale_uv / 100000;
+		*val2 = (scale_uv % 100000) * 10;
+		return IIO_VAL_INT_PLUS_MICRO;
+	default:
+		break;
+	}
+
+	return -EINVAL;
+}
+
+static const struct iio_info ad5380_info = {
+	.read_raw = ad5380_read_raw,
+	.write_raw = ad5380_write_raw,
+	.attrs = &ad5380_attribute_group,
+	.driver_module = THIS_MODULE,
+};
+
+static int __devinit ad5380_alloc_channels(struct iio_dev *indio_dev)
+{
+	struct ad5380_state *st = iio_priv(indio_dev);
+	struct iio_chan_spec *channels;
+	unsigned int i;
+
+	channels = kcalloc(sizeof(struct iio_chan_spec),
+			st->chip_info->num_channels, GFP_KERNEL);
+
+	if (!channels)
+		return -ENOMEM;
+
+	for (i = 0; i < st->chip_info->num_channels; ++i) {
+		channels[i] = st->chip_info->channel_template;
+		channels[i].channel = i;
+		channels[i].address = i;
+	}
+
+	indio_dev->channels = channels;
+
+	return 0;
+}
+
+static int __devinit ad5380_probe(struct device *dev, struct regmap *regmap,
+	enum ad5380_type type, const char *name)
+{
+	struct iio_dev *indio_dev;
+	struct ad5380_state *st;
+	unsigned int ctrl = 0;
+	int ret;
+
+	indio_dev = iio_allocate_device(sizeof(*st));
+	if (indio_dev == NULL) {
+		dev_err(dev, "Failed to allocate iio device\n");
+		ret = -ENOMEM;
+		goto error_regmap_exit;
+	}
+
+	st = iio_priv(indio_dev);
+	dev_set_drvdata(dev, indio_dev);
+
+	st->chip_info = &ad5380_chip_info_tbl[type];
+	st->regmap = regmap;
+
+	indio_dev->dev.parent = dev;
+	indio_dev->name = name;
+	indio_dev->info = &ad5380_info;
+	indio_dev->modes = INDIO_DIRECT_MODE;
+	indio_dev->num_channels = st->chip_info->num_channels;
+
+	ret = ad5380_alloc_channels(indio_dev);
+	if (ret) {
+		dev_err(dev, "Failed to allocate channel spec: %d\n", ret);
+		goto error_free;
+	}
+
+	if (st->chip_info->int_vref == 2500000)
+		ctrl |= AD5380_CTRL_INT_VREF_2V5;
+
+	st->vref_reg = regulator_get(dev, "vref");
+	if (!IS_ERR(st->vref_reg)) {
+		ret = regulator_enable(st->vref_reg);
+		if (ret) {
+			dev_err(dev, "Failed to enable vref regulators: %d\n",
+				ret);
+			goto error_free_reg;
+		}
+
+		st->vref = regulator_get_voltage(st->vref_reg);
+	} else {
+		st->vref = st->chip_info->int_vref;
+		ctrl |= AD5380_CTRL_INT_VREF_EN;
+	}
+
+	ret = regmap_write(st->regmap, AD5380_REG_SF_CTRL, ctrl);
+	if (ret) {
+		dev_err(dev, "Failed to write to device: %d\n", ret);
+		goto error_disable_reg;
+	}
+
+	ret = iio_device_register(indio_dev);
+	if (ret) {
+		dev_err(dev, "Failed to register iio device: %d\n", ret);
+		goto error_disable_reg;
+	}
+
+	return 0;
+
+error_disable_reg:
+	if (!IS_ERR(st->vref_reg))
+		regulator_disable(st->vref_reg);
+error_free_reg:
+	if (!IS_ERR(st->vref_reg))
+		regulator_put(st->vref_reg);
+
+	kfree(indio_dev->channels);
+error_free:
+	iio_free_device(indio_dev);
+error_regmap_exit:
+	regmap_exit(regmap);
+
+	return ret;
+}
+
+static int __devexit ad5380_remove(struct device *dev)
+{
+	struct iio_dev *indio_dev = dev_get_drvdata(dev);
+	struct ad5380_state *st = iio_priv(indio_dev);
+
+	iio_device_unregister(indio_dev);
+
+	kfree(indio_dev->channels);
+
+	if (!IS_ERR(st->vref_reg)) {
+		regulator_disable(st->vref_reg);
+		regulator_put(st->vref_reg);
+	}
+
+	regmap_exit(st->regmap);
+	iio_free_device(indio_dev);
+
+	return 0;
+}
+
+static bool ad5380_reg_false(struct device *dev, unsigned int reg)
+{
+	return false;
+}
+
+static const struct regmap_config ad5380_regmap_config = {
+	.reg_bits = 10,
+	.val_bits = 14,
+
+	.max_register = AD5380_REG_DATA(40),
+	.cache_type = REGCACHE_RBTREE,
+
+	.volatile_reg = ad5380_reg_false,
+	.readable_reg = ad5380_reg_false,
+};
+
+#if IS_ENABLED(CONFIG_SPI_MASTER)
+
+static int __devinit ad5380_spi_probe(struct spi_device *spi)
+{
+	const struct spi_device_id *id = spi_get_device_id(spi);
+	struct regmap *regmap;
+
+	regmap = regmap_init_spi(spi, &ad5380_regmap_config);
+
+	if (IS_ERR(regmap))
+		return PTR_ERR(regmap);
+
+	return ad5380_probe(&spi->dev, regmap, id->driver_data, id->name);
+}
+
+static int __devexit ad5380_spi_remove(struct spi_device *spi)
+{
+	return ad5380_remove(&spi->dev);
+}
+
+static const struct spi_device_id ad5380_spi_ids[] = {
+	{ "ad5380-3", ID_AD5380_3 },
+	{ "ad5380-5", ID_AD5380_5 },
+	{ "ad5381-3", ID_AD5381_3 },
+	{ "ad5381-5", ID_AD5381_5 },
+	{ "ad5382-3", ID_AD5382_3 },
+	{ "ad5382-5", ID_AD5382_5 },
+	{ "ad5383-3", ID_AD5383_3 },
+	{ "ad5383-5", ID_AD5383_5 },
+	{ "ad5384-3", ID_AD5380_3 },
+	{ "ad5384-5", ID_AD5380_5 },
+	{ "ad5390-3", ID_AD5390_3 },
+	{ "ad5390-5", ID_AD5390_5 },
+	{ "ad5391-3", ID_AD5391_3 },
+	{ "ad5391-5", ID_AD5391_5 },
+	{ "ad5392-3", ID_AD5392_3 },
+	{ "ad5392-5", ID_AD5392_5 },
+	{ }
+};
+MODULE_DEVICE_TABLE(spi, ad5380_spi_ids);
+
+static struct spi_driver ad5380_spi_driver = {
+	.driver = {
+		   .name = "ad5380",
+		   .owner = THIS_MODULE,
+	},
+	.probe = ad5380_spi_probe,
+	.remove = __devexit_p(ad5380_spi_remove),
+	.id_table = ad5380_spi_ids,
+};
+
+static inline int ad5380_spi_register_driver(void)
+{
+	return spi_register_driver(&ad5380_spi_driver);
+}
+
+static inline void ad5380_spi_unregister_driver(void)
+{
+	spi_unregister_driver(&ad5380_spi_driver);
+}
+
+#else
+
+static inline int ad5380_spi_register_driver(void)
+{
+	return 0;
+}
+
+static inline void ad5380_spi_unregister_driver(void)
+{
+}
+
+#endif
+
+#if IS_ENABLED(CONFIG_I2C)
+
+static int __devinit ad5380_i2c_probe(struct i2c_client *i2c,
+	const struct i2c_device_id *id)
+{
+	struct regmap *regmap;
+
+	regmap = regmap_init_i2c(i2c, &ad5380_regmap_config);
+
+	if (IS_ERR(regmap))
+		return PTR_ERR(regmap);
+
+	return ad5380_probe(&i2c->dev, regmap, id->driver_data, id->name);
+}
+
+static int __devexit ad5380_i2c_remove(struct i2c_client *i2c)
+{
+	return ad5380_remove(&i2c->dev);
+}
+
+static const struct i2c_device_id ad5380_i2c_ids[] = {
+	{ "ad5380-3", ID_AD5380_3 },
+	{ "ad5380-5", ID_AD5380_5 },
+	{ "ad5381-3", ID_AD5381_3 },
+	{ "ad5381-5", ID_AD5381_5 },
+	{ "ad5382-3", ID_AD5382_3 },
+	{ "ad5382-5", ID_AD5382_5 },
+	{ "ad5383-3", ID_AD5383_3 },
+	{ "ad5383-5", ID_AD5383_5 },
+	{ "ad5384-3", ID_AD5380_3 },
+	{ "ad5384-5", ID_AD5380_5 },
+	{ "ad5390-3", ID_AD5390_3 },
+	{ "ad5390-5", ID_AD5390_5 },
+	{ "ad5391-3", ID_AD5391_3 },
+	{ "ad5391-5", ID_AD5391_5 },
+	{ "ad5392-3", ID_AD5392_3 },
+	{ "ad5392-5", ID_AD5392_5 },
+	{ }
+};
+MODULE_DEVICE_TABLE(i2c, ad5380_i2c_ids);
+
+static struct i2c_driver ad5380_i2c_driver = {
+	.driver = {
+		   .name = "ad5380",
+		   .owner = THIS_MODULE,
+	},
+	.probe = ad5380_i2c_probe,
+	.remove = __devexit_p(ad5380_i2c_remove),
+	.id_table = ad5380_i2c_ids,
+};
+
+static inline int ad5380_i2c_register_driver(void)
+{
+	return i2c_add_driver(&ad5380_i2c_driver);
+}
+
+static inline void ad5380_i2c_unregister_driver(void)
+{
+	i2c_del_driver(&ad5380_i2c_driver);
+}
+
+#else
+
+static inline int ad5380_i2c_register_driver(void)
+{
+	return 0;
+}
+
+static inline void ad5380_i2c_unregister_driver(void)
+{
+}
+
+#endif
+
+static int __init ad5380_spi_init(void)
+{
+	int ret;
+
+	ret = ad5380_spi_register_driver();
+	if (ret)
+		return ret;
+
+	ret = ad5380_i2c_register_driver();
+	if (ret) {
+		ad5380_spi_unregister_driver();
+		return ret;
+	}
+
+	return 0;
+}
+module_init(ad5380_spi_init);
+
+static void __exit ad5380_spi_exit(void)
+{
+	ad5380_i2c_unregister_driver();
+	ad5380_spi_unregister_driver();
+
+}
+module_exit(ad5380_spi_exit);
+
+MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>");
+MODULE_DESCRIPTION("Analog Devices AD5380/81/82/83/84/90/91/92 DAC");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/staging/iio/dac/ad5421.c b/drivers/staging/iio/dac/ad5421.c
new file mode 100644
index 0000000..71ee868
--- /dev/null
+++ b/drivers/staging/iio/dac/ad5421.c
@@ -0,0 +1,555 @@
+/*
+ * AD5421 Digital to analog converters  driver
+ *
+ * Copyright 2011 Analog Devices Inc.
+ *
+ * Licensed under the GPL-2.
+ */
+
+#include <linux/device.h>
+#include <linux/delay.h>
+#include <linux/err.h>
+#include <linux/module.h>
+#include <linux/interrupt.h>
+#include <linux/kernel.h>
+#include <linux/spi/spi.h>
+#include <linux/slab.h>
+#include <linux/sysfs.h>
+
+#include "../iio.h"
+#include "../sysfs.h"
+#include "../events.h"
+#include "dac.h"
+#include "ad5421.h"
+
+
+#define AD5421_REG_DAC_DATA		0x1
+#define AD5421_REG_CTRL			0x2
+#define AD5421_REG_OFFSET		0x3
+#define AD5421_REG_GAIN			0x4
+/* load dac and fault shared the same register number. Writing to it will cause
+ * a dac load command, reading from it will return the fault status register */
+#define AD5421_REG_LOAD_DAC		0x5
+#define AD5421_REG_FAULT		0x5
+#define AD5421_REG_FORCE_ALARM_CURRENT	0x6
+#define AD5421_REG_RESET		0x7
+#define AD5421_REG_START_CONVERSION	0x8
+#define AD5421_REG_NOOP			0x9
+
+#define AD5421_CTRL_WATCHDOG_DISABLE	BIT(12)
+#define AD5421_CTRL_AUTO_FAULT_READBACK	BIT(11)
+#define AD5421_CTRL_MIN_CURRENT		BIT(9)
+#define AD5421_CTRL_ADC_SOURCE_TEMP	BIT(8)
+#define AD5421_CTRL_ADC_ENABLE		BIT(7)
+#define AD5421_CTRL_PWR_DOWN_INT_VREF	BIT(6)
+
+#define AD5421_FAULT_SPI			BIT(15)
+#define AD5421_FAULT_PEC			BIT(14)
+#define AD5421_FAULT_OVER_CURRENT		BIT(13)
+#define AD5421_FAULT_UNDER_CURRENT		BIT(12)
+#define AD5421_FAULT_TEMP_OVER_140		BIT(11)
+#define AD5421_FAULT_TEMP_OVER_100		BIT(10)
+#define AD5421_FAULT_UNDER_VOLTAGE_6V		BIT(9)
+#define AD5421_FAULT_UNDER_VOLTAGE_12V		BIT(8)
+
+/* These bits will cause the fault pin to go high */
+#define AD5421_FAULT_TRIGGER_IRQ \
+	(AD5421_FAULT_SPI | AD5421_FAULT_PEC | AD5421_FAULT_OVER_CURRENT | \
+	AD5421_FAULT_UNDER_CURRENT | AD5421_FAULT_TEMP_OVER_140)
+
+/**
+ * struct ad5421_state - driver instance specific data
+ * @spi:		spi_device
+ * @ctrl:		control register cache
+ * @current_range:	current range which the device is configured for
+ * @data:		spi transfer buffers
+ * @fault_mask:		software masking of events
+ */
+struct ad5421_state {
+	struct spi_device		*spi;
+	unsigned int			ctrl;
+	enum ad5421_current_range	current_range;
+	unsigned int			fault_mask;
+
+	/*
+	 * DMA (thus cache coherency maintenance) requires the
+	 * transfer buffers to live in their own cache lines.
+	 */
+	union {
+		u32 d32;
+		u8 d8[4];
+	} data[2] ____cacheline_aligned;
+};
+
+static const struct iio_chan_spec ad5421_channels[] = {
+	{
+		.type = IIO_CURRENT,
+		.indexed = 1,
+		.output = 1,
+		.channel = 0,
+		.info_mask = IIO_CHAN_INFO_SCALE_SHARED_BIT |
+			IIO_CHAN_INFO_OFFSET_SHARED_BIT |
+			IIO_CHAN_INFO_CALIBSCALE_SEPARATE_BIT |
+			IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT,
+		.scan_type = IIO_ST('u', 16, 16, 0),
+		.event_mask = IIO_EV_BIT(IIO_EV_TYPE_THRESH, IIO_EV_DIR_RISING) |
+			IIO_EV_BIT(IIO_EV_TYPE_THRESH, IIO_EV_DIR_FALLING),
+	},
+	{
+		.type = IIO_TEMP,
+		.channel = -1,
+		.event_mask = IIO_EV_BIT(IIO_EV_TYPE_THRESH, IIO_EV_DIR_RISING),
+	},
+};
+
+static int ad5421_write_unlocked(struct iio_dev *indio_dev,
+	unsigned int reg, unsigned int val)
+{
+	struct ad5421_state *st = iio_priv(indio_dev);
+
+	st->data[0].d32 = cpu_to_be32((reg << 16) | val);
+
+	return spi_write(st->spi, &st->data[0].d8[1], 3);
+}
+
+static int ad5421_write(struct iio_dev *indio_dev, unsigned int reg,
+	unsigned int val)
+{
+	int ret;
+
+	mutex_lock(&indio_dev->mlock);
+	ret = ad5421_write_unlocked(indio_dev, reg, val);
+	mutex_unlock(&indio_dev->mlock);
+
+	return ret;
+}
+
+static int ad5421_read(struct iio_dev *indio_dev, unsigned int reg)
+{
+	struct ad5421_state *st = iio_priv(indio_dev);
+	struct spi_message m;
+	int ret;
+	struct spi_transfer t[] = {
+		{
+			.tx_buf = &st->data[0].d8[1],
+			.len = 3,
+			.cs_change = 1,
+		}, {
+			.rx_buf = &st->data[1].d8[1],
+			.len = 3,
+		},
+	};
+
+	spi_message_init(&m);
+	spi_message_add_tail(&t[0], &m);
+	spi_message_add_tail(&t[1], &m);
+
+	mutex_lock(&indio_dev->mlock);
+
+	st->data[0].d32 = cpu_to_be32((1 << 23) | (reg << 16));
+
+	ret = spi_sync(st->spi, &m);
+	if (ret >= 0)
+		ret = be32_to_cpu(st->data[1].d32) & 0xffff;
+
+	mutex_unlock(&indio_dev->mlock);
+
+	return ret;
+}
+
+static int ad5421_update_ctrl(struct iio_dev *indio_dev, unsigned int set,
+	unsigned int clr)
+{
+	struct ad5421_state *st = iio_priv(indio_dev);
+	unsigned int ret;
+
+	mutex_lock(&indio_dev->mlock);
+
+	st->ctrl &= ~clr;
+	st->ctrl |= set;
+
+	ret = ad5421_write_unlocked(indio_dev, AD5421_REG_CTRL, st->ctrl);
+
+	mutex_unlock(&indio_dev->mlock);
+
+	return ret;
+}
+
+static irqreturn_t ad5421_fault_handler(int irq, void *data)
+{
+	struct iio_dev *indio_dev = data;
+	struct ad5421_state *st = iio_priv(indio_dev);
+	unsigned int fault;
+	unsigned int old_fault = 0;
+	unsigned int events;
+
+	fault = ad5421_read(indio_dev, AD5421_REG_FAULT);
+	if (!fault)
+		return IRQ_NONE;
+
+	/* If we had a fault, this might mean that the DAC has lost its state
+	 * and has been reset. Make sure that the control register actually
+	 * contains what we expect it to contain. Otherwise the watchdog might
+	 * be enabled and we get watchdog timeout faults, which will render the
+	 * DAC unusable. */
+	ad5421_update_ctrl(indio_dev, 0, 0);
+
+
+	/* The fault pin stays high as long as a fault condition is present and
+	 * it is not possible to mask fault conditions. For certain fault
+	 * conditions for example like over-temperature it takes some time
+	 * until the fault condition disappears. If we would exit the interrupt
+	 * handler immediately after handling the event it would be entered
+	 * again instantly. Thus we fall back to polling in case we detect that
+	 * a interrupt condition is still present.
+	 */
+	do {
+		/* 0xffff is a invalid value for the register and will only be
+		 * read if there has been a communication error */
+		if (fault == 0xffff)
+			fault = 0;
+
+		/* we are only interested in new events */
+		events = (old_fault ^ fault) & fault;
+		events &= st->fault_mask;
+
+		if (events & AD5421_FAULT_OVER_CURRENT) {
+			iio_push_event(indio_dev,
+				IIO_UNMOD_EVENT_CODE(IIO_CURRENT,
+					0,
+					IIO_EV_TYPE_THRESH,
+					IIO_EV_DIR_RISING),
+			iio_get_time_ns());
+		}
+
+		if (events & AD5421_FAULT_UNDER_CURRENT) {
+			iio_push_event(indio_dev,
+				IIO_UNMOD_EVENT_CODE(IIO_CURRENT,
+					0,
+					IIO_EV_TYPE_THRESH,
+					IIO_EV_DIR_FALLING),
+				iio_get_time_ns());
+		}
+
+		if (events & AD5421_FAULT_TEMP_OVER_140) {
+			iio_push_event(indio_dev,
+				IIO_UNMOD_EVENT_CODE(IIO_TEMP,
+					0,
+					IIO_EV_TYPE_MAG,
+					IIO_EV_DIR_RISING),
+				iio_get_time_ns());
+		}
+
+		old_fault = fault;
+		fault = ad5421_read(indio_dev, AD5421_REG_FAULT);
+
+		/* still active? go to sleep for some time */
+		if (fault & AD5421_FAULT_TRIGGER_IRQ)
+			msleep(1000);
+
+	} while (fault & AD5421_FAULT_TRIGGER_IRQ);
+
+
+	return IRQ_HANDLED;
+}
+
+static void ad5421_get_current_min_max(struct ad5421_state *st,
+	unsigned int *min, unsigned int *max)
+{
+	/* The current range is configured using external pins, which are
+	 * usually hard-wired and not run-time switchable. */
+	switch (st->current_range) {
+	case AD5421_CURRENT_RANGE_4mA_20mA:
+		*min = 4000;
+		*max = 20000;
+		break;
+	case AD5421_CURRENT_RANGE_3mA8_21mA:
+		*min = 3800;
+		*max = 21000;
+		break;
+	case AD5421_CURRENT_RANGE_3mA2_24mA:
+		*min = 3200;
+		*max = 24000;
+		break;
+	default:
+		*min = 0;
+		*max = 1;
+		break;
+	}
+}
+
+static inline unsigned int ad5421_get_offset(struct ad5421_state *st)
+{
+	unsigned int min, max;
+
+	ad5421_get_current_min_max(st, &min, &max);
+	return (min * (1 << 16)) / (max - min);
+}
+
+static inline unsigned int ad5421_get_scale(struct ad5421_state *st)
+{
+	unsigned int min, max;
+
+	ad5421_get_current_min_max(st, &min, &max);
+	return ((max - min) * 1000) / (1 << 16);
+}
+
+static int ad5421_read_raw(struct iio_dev *indio_dev,
+	struct iio_chan_spec const *chan, int *val, int *val2, long m)
+{
+	struct ad5421_state *st = iio_priv(indio_dev);
+	int ret;
+
+	if (chan->type != IIO_CURRENT)
+		return -EINVAL;
+
+	switch (m) {
+	case 0:
+		ret = ad5421_read(indio_dev, AD5421_REG_DAC_DATA);
+		if (ret < 0)
+			return ret;
+		*val = ret;
+		return IIO_VAL_INT;
+	case IIO_CHAN_INFO_SCALE:
+		*val = 0;
+		*val2 = ad5421_get_scale(st);
+		return IIO_VAL_INT_PLUS_MICRO;
+	case IIO_CHAN_INFO_OFFSET:
+		*val = ad5421_get_offset(st);
+		return IIO_VAL_INT;
+	case IIO_CHAN_INFO_CALIBBIAS:
+		ret = ad5421_read(indio_dev, AD5421_REG_OFFSET);
+		if (ret < 0)
+			return ret;
+		*val = ret - 32768;
+		return IIO_VAL_INT;
+	case IIO_CHAN_INFO_CALIBSCALE:
+		ret = ad5421_read(indio_dev, AD5421_REG_GAIN);
+		if (ret < 0)
+			return ret;
+		*val = ret;
+		return IIO_VAL_INT;
+	}
+
+	return -EINVAL;
+}
+
+static int ad5421_write_raw(struct iio_dev *indio_dev,
+	struct iio_chan_spec const *chan, int val, int val2, long mask)
+{
+	const unsigned int max_val = 1 << 16;
+
+	switch (mask) {
+	case 0:
+		if (val >= max_val || val < 0)
+			return -EINVAL;
+
+		return ad5421_write(indio_dev, AD5421_REG_DAC_DATA, val);
+	case IIO_CHAN_INFO_CALIBBIAS:
+		val += 32768;
+		if (val >= max_val || val < 0)
+			return -EINVAL;
+
+		return ad5421_write(indio_dev, AD5421_REG_OFFSET, val);
+	case IIO_CHAN_INFO_CALIBSCALE:
+		if (val >= max_val || val < 0)
+			return -EINVAL;
+
+		return ad5421_write(indio_dev, AD5421_REG_GAIN, val);
+	default:
+		break;
+	}
+
+	return -EINVAL;
+}
+
+static int ad5421_write_event_config(struct iio_dev *indio_dev,
+	u64 event_code, int state)
+{
+	struct ad5421_state *st = iio_priv(indio_dev);
+	unsigned int mask;
+
+	switch (IIO_EVENT_CODE_EXTRACT_CHAN_TYPE(event_code)) {
+	case IIO_CURRENT:
+		if (IIO_EVENT_CODE_EXTRACT_DIR(event_code) ==
+			IIO_EV_DIR_RISING)
+			mask = AD5421_FAULT_OVER_CURRENT;
+		else
+			mask = AD5421_FAULT_UNDER_CURRENT;
+		break;
+	case IIO_TEMP:
+		mask = AD5421_FAULT_TEMP_OVER_140;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	mutex_lock(&indio_dev->mlock);
+	if (state)
+		st->fault_mask |= mask;
+	else
+		st->fault_mask &= ~mask;
+	mutex_unlock(&indio_dev->mlock);
+
+	return 0;
+}
+
+static int ad5421_read_event_config(struct iio_dev *indio_dev,
+	u64 event_code)
+{
+	struct ad5421_state *st = iio_priv(indio_dev);
+	unsigned int mask;
+
+	switch (IIO_EVENT_CODE_EXTRACT_CHAN_TYPE(event_code)) {
+	case IIO_CURRENT:
+		if (IIO_EVENT_CODE_EXTRACT_DIR(event_code) ==
+			IIO_EV_DIR_RISING)
+			mask = AD5421_FAULT_OVER_CURRENT;
+		else
+			mask = AD5421_FAULT_UNDER_CURRENT;
+		break;
+	case IIO_TEMP:
+		mask = AD5421_FAULT_TEMP_OVER_140;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	return (bool)(st->fault_mask & mask);
+}
+
+static int ad5421_read_event_value(struct iio_dev *indio_dev, u64 event_code,
+	int *val)
+{
+	int ret;
+
+	switch (IIO_EVENT_CODE_EXTRACT_CHAN_TYPE(event_code)) {
+	case IIO_CURRENT:
+		ret = ad5421_read(indio_dev, AD5421_REG_DAC_DATA);
+		if (ret < 0)
+			return ret;
+		*val = ret;
+		break;
+	case IIO_TEMP:
+		*val = 140000;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static const struct iio_info ad5421_info = {
+	.read_raw =		ad5421_read_raw,
+	.write_raw =		ad5421_write_raw,
+	.read_event_config =	ad5421_read_event_config,
+	.write_event_config =	ad5421_write_event_config,
+	.read_event_value =	ad5421_read_event_value,
+	.driver_module =	THIS_MODULE,
+};
+
+static int __devinit ad5421_probe(struct spi_device *spi)
+{
+	struct ad5421_platform_data *pdata = dev_get_platdata(&spi->dev);
+	struct iio_dev *indio_dev;
+	struct ad5421_state *st;
+	int ret;
+
+	indio_dev = iio_allocate_device(sizeof(*st));
+	if (indio_dev == NULL) {
+		dev_err(&spi->dev, "Failed to allocate iio device\n");
+		return  -ENOMEM;
+	}
+
+	st = iio_priv(indio_dev);
+	spi_set_drvdata(spi, indio_dev);
+
+	st->spi = spi;
+
+	indio_dev->dev.parent = &spi->dev;
+	indio_dev->name = "ad5421";
+	indio_dev->info = &ad5421_info;
+	indio_dev->modes = INDIO_DIRECT_MODE;
+	indio_dev->channels = ad5421_channels;
+	indio_dev->num_channels = ARRAY_SIZE(ad5421_channels);
+
+	st->ctrl = AD5421_CTRL_WATCHDOG_DISABLE |
+			AD5421_CTRL_AUTO_FAULT_READBACK;
+
+	if (pdata) {
+		st->current_range = pdata->current_range;
+		if (pdata->external_vref)
+			st->ctrl |= AD5421_CTRL_PWR_DOWN_INT_VREF;
+	} else {
+		st->current_range = AD5421_CURRENT_RANGE_4mA_20mA;
+	}
+
+	/* write initial ctrl register value */
+	ad5421_update_ctrl(indio_dev, 0, 0);
+
+	if (spi->irq) {
+		ret = request_threaded_irq(spi->irq,
+					   NULL,
+					   ad5421_fault_handler,
+					   IRQF_TRIGGER_HIGH | IRQF_ONESHOT,
+					   "ad5421 fault",
+					   indio_dev);
+		if (ret)
+			goto error_free;
+	}
+
+	ret = iio_device_register(indio_dev);
+	if (ret) {
+		dev_err(&spi->dev, "Failed to register iio device: %d\n", ret);
+		goto error_free_irq;
+	}
+
+	return 0;
+
+error_free_irq:
+	if (spi->irq)
+		free_irq(spi->irq, indio_dev);
+error_free:
+	iio_free_device(indio_dev);
+
+	return ret;
+}
+
+static int __devexit ad5421_remove(struct spi_device *spi)
+{
+	struct iio_dev *indio_dev = spi_get_drvdata(spi);
+
+	iio_device_unregister(indio_dev);
+	if (spi->irq)
+		free_irq(spi->irq, indio_dev);
+	iio_free_device(indio_dev);
+
+	return 0;
+}
+
+static struct spi_driver ad5421_driver = {
+	.driver = {
+		   .name = "ad5421",
+		   .owner = THIS_MODULE,
+	},
+	.probe = ad5421_probe,
+	.remove = __devexit_p(ad5421_remove),
+};
+
+static __init int ad5421_init(void)
+{
+	return spi_register_driver(&ad5421_driver);
+}
+module_init(ad5421_init);
+
+static __exit void ad5421_exit(void)
+{
+	spi_unregister_driver(&ad5421_driver);
+}
+module_exit(ad5421_exit);
+
+MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>");
+MODULE_DESCRIPTION("Analog Devices AD5421 DAC");
+MODULE_LICENSE("GPL v2");
+MODULE_ALIAS("spi:ad5421");
diff --git a/drivers/staging/iio/dac/ad5421.h b/drivers/staging/iio/dac/ad5421.h
new file mode 100644
index 0000000..cd2bb84
--- /dev/null
+++ b/drivers/staging/iio/dac/ad5421.h
@@ -0,0 +1,32 @@
+#ifndef __IIO_DAC_AD5421_H__
+#define __IIO_DAC_AD5421_H__
+
+/*
+ * TODO: This file needs to go into include/linux/iio
+ */
+
+/**
+ * enum ad5421_current_range - Current range the AD5421 is configured for.
+ * @AD5421_CURRENT_RANGE_4mA_20mA: 4 mA to 20 mA (RANGE1,0 pins = 00)
+ * @AD5421_CURRENT_RANGE_3mA8_21mA: 3.8 mA to 21 mA (RANGE1,0 pins = x1)
+ * @AD5421_CURRENT_RANGE_3mA2_24mA: 3.2 mA to 24 mA (RANGE1,0 pins = 10)
+ */
+
+enum ad5421_current_range {
+	AD5421_CURRENT_RANGE_4mA_20mA,
+	AD5421_CURRENT_RANGE_3mA8_21mA,
+	AD5421_CURRENT_RANGE_3mA2_24mA,
+};
+
+/**
+ * struct ad5421_platform_data - AD5421 DAC driver platform data
+ * @external_vref: whether an external reference voltage is used or not
+ * @current_range: Current range the AD5421 is configured for
+ */
+
+struct ad5421_platform_data {
+	bool external_vref;
+	enum ad5421_current_range current_range;
+};
+
+#endif
diff --git a/drivers/staging/iio/dac/ad5446.c b/drivers/staging/iio/dac/ad5446.c
index ec701e9..693e748 100644
--- a/drivers/staging/iio/dac/ad5446.c
+++ b/drivers/staging/iio/dac/ad5446.c
@@ -26,19 +26,17 @@
 
 static void ad5446_store_sample(struct ad5446_state *st, unsigned val)
 {
-	st->data.d16 = cpu_to_be16(AD5446_LOAD |
-					(val << st->chip_info->left_shift));
+	st->data.d16 = cpu_to_be16(AD5446_LOAD | val);
 }
 
 static void ad5542_store_sample(struct ad5446_state *st, unsigned val)
 {
-	st->data.d16 = cpu_to_be16(val << st->chip_info->left_shift);
+	st->data.d16 = cpu_to_be16(val);
 }
 
 static void ad5620_store_sample(struct ad5446_state *st, unsigned val)
 {
-	st->data.d16 = cpu_to_be16(AD5620_LOAD |
-					(val << st->chip_info->left_shift));
+	st->data.d16 = cpu_to_be16(AD5620_LOAD | val);
 }
 
 static void ad5660_store_sample(struct ad5446_state *st, unsigned val)
@@ -63,50 +61,6 @@
 	st->data.d24[2] = val & 0xFF;
 }
 
-static ssize_t ad5446_write(struct device *dev,
-		struct device_attribute *attr,
-		const char *buf,
-		size_t len)
-{
-	struct iio_dev *indio_dev = dev_get_drvdata(dev);
-	struct ad5446_state *st = iio_priv(indio_dev);
-	int ret;
-	long val;
-
-	ret = strict_strtol(buf, 10, &val);
-	if (ret)
-		goto error_ret;
-
-	if (val > RES_MASK(st->chip_info->bits)) {
-		ret = -EINVAL;
-		goto error_ret;
-	}
-
-	mutex_lock(&indio_dev->mlock);
-	st->cached_val = val;
-	st->chip_info->store_sample(st, val);
-	ret = spi_sync(st->spi, &st->msg);
-	mutex_unlock(&indio_dev->mlock);
-
-error_ret:
-	return ret ? ret : len;
-}
-
-static IIO_DEV_ATTR_OUT_RAW(0, ad5446_write, 0);
-
-static ssize_t ad5446_show_scale(struct device *dev,
-				struct device_attribute *attr,
-				char *buf)
-{
-	struct iio_dev *indio_dev = dev_get_drvdata(dev);
-	struct ad5446_state *st = iio_priv(indio_dev);
-	/* Corresponds to Vref / 2^(bits) */
-	unsigned int scale_uv = (st->vref_mv * 1000) >> st->chip_info->bits;
-
-	return sprintf(buf, "%d.%03d\n", scale_uv / 1000, scale_uv % 1000);
-}
-static IIO_DEVICE_ATTR(out_voltage_scale, S_IRUGO, ad5446_show_scale, NULL, 0);
-
 static ssize_t ad5446_write_powerdown_mode(struct device *dev,
 				       struct device_attribute *attr,
 				       const char *buf, size_t len)
@@ -189,8 +143,6 @@
 			ad5446_write_dac_powerdown, 0);
 
 static struct attribute *ad5446_attributes[] = {
-	&iio_dev_attr_out_voltage0_raw.dev_attr.attr,
-	&iio_dev_attr_out_voltage_scale.dev_attr.attr,
 	&iio_dev_attr_out_voltage0_powerdown.dev_attr.attr,
 	&iio_dev_attr_out_voltage_powerdown_mode.dev_attr.attr,
 	&iio_const_attr_out_voltage_powerdown_mode_available.dev_attr.attr,
@@ -223,121 +175,148 @@
 	.is_visible = ad5446_attr_is_visible,
 };
 
+#define AD5446_CHANNEL(bits, storage, shift) { \
+	.type = IIO_VOLTAGE, \
+	.indexed = 1, \
+	.output = 1, \
+	.channel = 0, \
+	.info_mask = IIO_CHAN_INFO_SCALE_SHARED_BIT, \
+	.scan_type = IIO_ST('u', (bits), (storage), (shift)) \
+}
+
 static const struct ad5446_chip_info ad5446_chip_info_tbl[] = {
 	[ID_AD5444] = {
-		.bits = 12,
-		.storagebits = 16,
-		.left_shift = 2,
+		.channel = AD5446_CHANNEL(12, 16, 2),
 		.store_sample = ad5446_store_sample,
 	},
 	[ID_AD5446] = {
-		.bits = 14,
-		.storagebits = 16,
-		.left_shift = 0,
+		.channel = AD5446_CHANNEL(14, 16, 0),
 		.store_sample = ad5446_store_sample,
 	},
 	[ID_AD5541A] = {
-		.bits = 16,
-		.storagebits = 16,
-		.left_shift = 0,
+		.channel = AD5446_CHANNEL(16, 16, 0),
 		.store_sample = ad5542_store_sample,
 	},
 	[ID_AD5542A] = {
-		.bits = 16,
-		.storagebits = 16,
-		.left_shift = 0,
+		.channel = AD5446_CHANNEL(16, 16, 0),
 		.store_sample = ad5542_store_sample,
 	},
 	[ID_AD5543] = {
-		.bits = 16,
-		.storagebits = 16,
-		.left_shift = 0,
+		.channel = AD5446_CHANNEL(16, 16, 0),
 		.store_sample = ad5542_store_sample,
 	},
 	[ID_AD5512A] = {
-		.bits = 12,
-		.storagebits = 16,
-		.left_shift = 4,
+		.channel = AD5446_CHANNEL(12, 16, 4),
 		.store_sample = ad5542_store_sample,
 	},
 	[ID_AD5553] = {
-		.bits = 14,
-		.storagebits = 16,
-		.left_shift = 0,
+		.channel = AD5446_CHANNEL(14, 16, 0),
 		.store_sample = ad5542_store_sample,
 	},
 	[ID_AD5601] = {
-		.bits = 8,
-		.storagebits = 16,
-		.left_shift = 6,
+		.channel = AD5446_CHANNEL(8, 16, 6),
 		.store_sample = ad5542_store_sample,
 		.store_pwr_down = ad5620_store_pwr_down,
 	},
 	[ID_AD5611] = {
-		.bits = 10,
-		.storagebits = 16,
-		.left_shift = 4,
+		.channel = AD5446_CHANNEL(10, 16, 4),
 		.store_sample = ad5542_store_sample,
 		.store_pwr_down = ad5620_store_pwr_down,
 	},
 	[ID_AD5621] = {
-		.bits = 12,
-		.storagebits = 16,
-		.left_shift = 2,
+		.channel = AD5446_CHANNEL(12, 16, 2),
 		.store_sample = ad5542_store_sample,
 		.store_pwr_down = ad5620_store_pwr_down,
 	},
 	[ID_AD5620_2500] = {
-		.bits = 12,
-		.storagebits = 16,
-		.left_shift = 2,
+		.channel = AD5446_CHANNEL(12, 16, 2),
 		.int_vref_mv = 2500,
 		.store_sample = ad5620_store_sample,
 		.store_pwr_down = ad5620_store_pwr_down,
 	},
 	[ID_AD5620_1250] = {
-		.bits = 12,
-		.storagebits = 16,
-		.left_shift = 2,
+		.channel = AD5446_CHANNEL(12, 16, 2),
 		.int_vref_mv = 1250,
 		.store_sample = ad5620_store_sample,
 		.store_pwr_down = ad5620_store_pwr_down,
 	},
 	[ID_AD5640_2500] = {
-		.bits = 14,
-		.storagebits = 16,
-		.left_shift = 0,
+		.channel = AD5446_CHANNEL(14, 16, 0),
 		.int_vref_mv = 2500,
 		.store_sample = ad5620_store_sample,
 		.store_pwr_down = ad5620_store_pwr_down,
 	},
 	[ID_AD5640_1250] = {
-		.bits = 14,
-		.storagebits = 16,
-		.left_shift = 0,
+		.channel = AD5446_CHANNEL(14, 16, 0),
 		.int_vref_mv = 1250,
 		.store_sample = ad5620_store_sample,
 		.store_pwr_down = ad5620_store_pwr_down,
 	},
 	[ID_AD5660_2500] = {
-		.bits = 16,
-		.storagebits = 24,
-		.left_shift = 0,
+		.channel = AD5446_CHANNEL(16, 16, 0),
 		.int_vref_mv = 2500,
 		.store_sample = ad5660_store_sample,
 		.store_pwr_down = ad5660_store_pwr_down,
 	},
 	[ID_AD5660_1250] = {
-		.bits = 16,
-		.storagebits = 24,
-		.left_shift = 0,
+		.channel = AD5446_CHANNEL(16, 16, 0),
 		.int_vref_mv = 1250,
 		.store_sample = ad5660_store_sample,
 		.store_pwr_down = ad5660_store_pwr_down,
 	},
 };
 
+static int ad5446_read_raw(struct iio_dev *indio_dev,
+			   struct iio_chan_spec const *chan,
+			   int *val,
+			   int *val2,
+			   long m)
+{
+	struct ad5446_state *st = iio_priv(indio_dev);
+	unsigned long scale_uv;
+
+	switch (m) {
+	case IIO_CHAN_INFO_SCALE:
+		scale_uv = (st->vref_mv * 1000) >> chan->scan_type.realbits;
+		*val =  scale_uv / 1000;
+		*val2 = (scale_uv % 1000) * 1000;
+		return IIO_VAL_INT_PLUS_MICRO;
+
+	}
+	return -EINVAL;
+}
+
+static int ad5446_write_raw(struct iio_dev *indio_dev,
+			       struct iio_chan_spec const *chan,
+			       int val,
+			       int val2,
+			       long mask)
+{
+	struct ad5446_state *st = iio_priv(indio_dev);
+	int ret;
+
+	switch (mask) {
+	case 0:
+		if (val >= (1 << chan->scan_type.realbits) || val < 0)
+			return -EINVAL;
+
+		val <<= chan->scan_type.shift;
+		mutex_lock(&indio_dev->mlock);
+		st->cached_val = val;
+		st->chip_info->store_sample(st, val);
+		ret = spi_sync(st->spi, &st->msg);
+		mutex_unlock(&indio_dev->mlock);
+		break;
+	default:
+		ret = -EINVAL;
+	}
+
+	return ret;
+}
+
 static const struct iio_info ad5446_info = {
+	.read_raw = ad5446_read_raw,
+	.write_raw = ad5446_write_raw,
 	.attrs = &ad5446_attribute_group,
 	.driver_module = THIS_MODULE,
 };
@@ -376,11 +355,13 @@
 	indio_dev->name = spi_get_device_id(spi)->name;
 	indio_dev->info = &ad5446_info;
 	indio_dev->modes = INDIO_DIRECT_MODE;
+	indio_dev->channels = &st->chip_info->channel;
+	indio_dev->num_channels = 1;
 
 	/* Setup default message */
 
 	st->xfer.tx_buf = &st->data;
-	st->xfer.len = st->chip_info->storagebits / 8;
+	st->xfer.len = st->chip_info->channel.scan_type.storagebits / 8;
 
 	spi_message_init(&st->msg);
 	spi_message_add_tail(&st->xfer, &st->msg);
@@ -454,11 +435,11 @@
 	{"ad5660-1250", ID_AD5660_1250},
 	{}
 };
+MODULE_DEVICE_TABLE(spi, ad5446_id);
 
 static struct spi_driver ad5446_driver = {
 	.driver = {
 		.name	= "ad5446",
-		.bus	= &spi_bus_type,
 		.owner	= THIS_MODULE,
 	},
 	.probe		= ad5446_probe,
@@ -470,4 +451,3 @@
 MODULE_AUTHOR("Michael Hennerich <hennerich@blackfin.uclinux.org>");
 MODULE_DESCRIPTION("Analog Devices AD5444/AD5446 DAC");
 MODULE_LICENSE("GPL v2");
-MODULE_ALIAS("spi:ad5446");
diff --git a/drivers/staging/iio/dac/ad5446.h b/drivers/staging/iio/dac/ad5446.h
index 7118d65..4ea3476 100644
--- a/drivers/staging/iio/dac/ad5446.h
+++ b/drivers/staging/iio/dac/ad5446.h
@@ -25,8 +25,6 @@
 #define AD5660_PWRDWN_100k	(0x2 << 16) /* Power-down: 100kOhm to GND */
 #define AD5660_PWRDWN_TRISTATE	(0x3 << 16) /* Power-down: Three-state */
 
-#define RES_MASK(bits)	((1 << (bits)) - 1)
-
 #define MODE_PWRDWN_1k		0x1
 #define MODE_PWRDWN_100k	0x2
 #define MODE_PWRDWN_TRISTATE	0x3
@@ -62,18 +60,14 @@
 
 /**
  * struct ad5446_chip_info - chip specific information
- * @bits:		accuracy of the DAC in bits
- * @storagebits:	number of bits written to the DAC
- * @left_shift:		number of bits the datum must be shifted
+ * @channel:		channel spec for the DAC
  * @int_vref_mv:	AD5620/40/60: the internal reference voltage
  * @store_sample:	chip specific helper function to store the datum
  * @store_sample:	chip specific helper function to store the powerpown cmd
  */
 
 struct ad5446_chip_info {
-	u8			bits;
-	u8			storagebits;
-	u8			left_shift;
+	struct iio_chan_spec	channel;
 	u16			int_vref_mv;
 	void (*store_sample)	(struct ad5446_state *st, unsigned val);
 	void (*store_pwr_down)	(struct ad5446_state *st, unsigned mode);
diff --git a/drivers/staging/iio/dac/ad5504.c b/drivers/staging/iio/dac/ad5504.c
index 57539ce..bc17205 100644
--- a/drivers/staging/iio/dac/ad5504.c
+++ b/drivers/staging/iio/dac/ad5504.c
@@ -18,9 +18,27 @@
 
 #include "../iio.h"
 #include "../sysfs.h"
+#include "../events.h"
 #include "dac.h"
 #include "ad5504.h"
 
+#define AD5504_CHANNEL(_chan) { \
+	.type = IIO_VOLTAGE, \
+	.indexed = 1, \
+	.output = 1, \
+	.channel = (_chan), \
+	.info_mask = IIO_CHAN_INFO_SCALE_SHARED_BIT, \
+	.address = AD5504_ADDR_DAC(_chan), \
+	.scan_type = IIO_ST('u', 12, 16, 0), \
+}
+
+static const struct iio_chan_spec ad5504_channels[] = {
+	AD5504_CHANNEL(0),
+	AD5504_CHANNEL(1),
+	AD5504_CHANNEL(2),
+	AD5504_CHANNEL(3),
+};
+
 static int ad5504_spi_write(struct spi_device *spi, u8 addr, u16 val)
 {
 	u16 tmp = cpu_to_be16(AD5504_CMD_WRITE |
@@ -30,13 +48,14 @@
 	return spi_write(spi, (u8 *)&tmp, 2);
 }
 
-static int ad5504_spi_read(struct spi_device *spi, u8 addr, u16 *val)
+static int ad5504_spi_read(struct spi_device *spi, u8 addr)
 {
 	u16 tmp = cpu_to_be16(AD5504_CMD_READ | AD5504_ADDR(addr));
+	u16 val;
 	int ret;
 	struct spi_transfer	t = {
 			.tx_buf		= &tmp,
-			.rx_buf		= val,
+			.rx_buf		= &val,
 			.len		= 2,
 		};
 	struct spi_message	m;
@@ -45,44 +64,61 @@
 	spi_message_add_tail(&t, &m);
 	ret = spi_sync(spi, &m);
 
-	*val = be16_to_cpu(*val) & AD5504_RES_MASK;
-
-	return ret;
-}
-
-static ssize_t ad5504_write_dac(struct device *dev,
-				 struct device_attribute *attr,
-				 const char *buf, size_t len)
-{
-	struct iio_dev *indio_dev = dev_get_drvdata(dev);
-	struct ad5504_state *st = iio_priv(indio_dev);
-	struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
-	long readin;
-	int ret;
-
-	ret = strict_strtol(buf, 10, &readin);
-	if (ret)
+	if (ret < 0)
 		return ret;
 
-	ret = ad5504_spi_write(st->spi, this_attr->address, readin);
-	return ret ? ret : len;
+	return be16_to_cpu(val) & AD5504_RES_MASK;
 }
 
-static ssize_t ad5504_read_dac(struct device *dev,
-					   struct device_attribute *attr,
-					   char *buf)
+static int ad5504_read_raw(struct iio_dev *indio_dev,
+			   struct iio_chan_spec const *chan,
+			   int *val,
+			   int *val2,
+			   long m)
 {
-	struct iio_dev *indio_dev = dev_get_drvdata(dev);
 	struct ad5504_state *st = iio_priv(indio_dev);
-	struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
+	unsigned long scale_uv;
 	int ret;
-	u16 val;
 
-	ret = ad5504_spi_read(st->spi, this_attr->address, &val);
-	if (ret)
-		return ret;
+	switch (m) {
+	case 0:
+		ret = ad5504_spi_read(st->spi, chan->address);
+		if (ret < 0)
+			return ret;
 
-	return sprintf(buf, "%d\n", val);
+		*val = ret;
+
+		return IIO_VAL_INT;
+	case IIO_CHAN_INFO_SCALE:
+		scale_uv = (st->vref_mv * 1000) >> chan->scan_type.realbits;
+		*val =  scale_uv / 1000;
+		*val2 = (scale_uv % 1000) * 1000;
+		return IIO_VAL_INT_PLUS_MICRO;
+
+	}
+	return -EINVAL;
+}
+
+static int ad5504_write_raw(struct iio_dev *indio_dev,
+			       struct iio_chan_spec const *chan,
+			       int val,
+			       int val2,
+			       long mask)
+{
+	struct ad5504_state *st = iio_priv(indio_dev);
+	int ret;
+
+	switch (mask) {
+	case 0:
+		if (val >= (1 << chan->scan_type.realbits) || val < 0)
+			return -EINVAL;
+
+		return ad5504_spi_write(st->spi, chan->address, val);
+	default:
+		ret = -EINVAL;
+	}
+
+	return -EINVAL;
 }
 
 static ssize_t ad5504_read_powerdown_mode(struct device *dev,
@@ -157,32 +193,6 @@
 	return ret ? ret : len;
 }
 
-static ssize_t ad5504_show_scale(struct device *dev,
-				struct device_attribute *attr,
-				char *buf)
-{
-	struct iio_dev *indio_dev = dev_get_drvdata(dev);
-	struct ad5504_state *st = iio_priv(indio_dev);
-	/* Corresponds to Vref / 2^(bits) */
-	unsigned int scale_uv = (st->vref_mv * 1000) >> AD5505_BITS;
-
-	return sprintf(buf, "%d.%03d\n", scale_uv / 1000, scale_uv % 1000);
-}
-static IIO_DEVICE_ATTR(out_voltage_scale, S_IRUGO, ad5504_show_scale, NULL, 0);
-
-#define IIO_DEV_ATTR_OUT_RW_RAW(_num, _show, _store, _addr)		\
-	IIO_DEVICE_ATTR(out_voltage##_num##_raw,			\
-			S_IRUGO | S_IWUSR, _show, _store, _addr)
-
-static IIO_DEV_ATTR_OUT_RW_RAW(0, ad5504_read_dac,
-	ad5504_write_dac, AD5504_ADDR_DAC0);
-static IIO_DEV_ATTR_OUT_RW_RAW(1, ad5504_read_dac,
-	ad5504_write_dac, AD5504_ADDR_DAC1);
-static IIO_DEV_ATTR_OUT_RW_RAW(2, ad5504_read_dac,
-	ad5504_write_dac, AD5504_ADDR_DAC2);
-static IIO_DEV_ATTR_OUT_RW_RAW(3, ad5504_read_dac,
-	ad5504_write_dac, AD5504_ADDR_DAC3);
-
 static IIO_DEVICE_ATTR(out_voltage_powerdown_mode, S_IRUGO |
 			S_IWUSR, ad5504_read_powerdown_mode,
 			ad5504_write_powerdown_mode, 0);
@@ -203,17 +213,12 @@
 				   ad5504_write_dac_powerdown, 3);
 
 static struct attribute *ad5504_attributes[] = {
-	&iio_dev_attr_out_voltage0_raw.dev_attr.attr,
-	&iio_dev_attr_out_voltage1_raw.dev_attr.attr,
-	&iio_dev_attr_out_voltage2_raw.dev_attr.attr,
-	&iio_dev_attr_out_voltage3_raw.dev_attr.attr,
 	&iio_dev_attr_out_voltage0_powerdown.dev_attr.attr,
 	&iio_dev_attr_out_voltage1_powerdown.dev_attr.attr,
 	&iio_dev_attr_out_voltage2_powerdown.dev_attr.attr,
 	&iio_dev_attr_out_voltage3_powerdown.dev_attr.attr,
 	&iio_dev_attr_out_voltage_powerdown_mode.dev_attr.attr,
 	&iio_const_attr_out_voltage_powerdown_mode_available.dev_attr.attr,
-	&iio_dev_attr_out_voltage_scale.dev_attr.attr,
 	NULL,
 };
 
@@ -222,11 +227,9 @@
 };
 
 static struct attribute *ad5501_attributes[] = {
-	&iio_dev_attr_out_voltage0_raw.dev_attr.attr,
 	&iio_dev_attr_out_voltage0_powerdown.dev_attr.attr,
 	&iio_dev_attr_out_voltage_powerdown_mode.dev_attr.attr,
 	&iio_const_attr_out_voltage_powerdown_mode_available.dev_attr.attr,
-	&iio_dev_attr_out_voltage_scale.dev_attr.attr,
 	NULL,
 };
 
@@ -261,12 +264,16 @@
 }
 
 static const struct iio_info ad5504_info = {
+	.write_raw = ad5504_write_raw,
+	.read_raw = ad5504_read_raw,
 	.attrs = &ad5504_attribute_group,
 	.event_attrs = &ad5504_ev_attribute_group,
 	.driver_module = THIS_MODULE,
 };
 
 static const struct iio_info ad5501_info = {
+	.write_raw = ad5504_write_raw,
+	.read_raw = ad5504_read_raw,
 	.attrs = &ad5501_attribute_group,
 	.event_attrs = &ad5504_ev_attribute_group,
 	.driver_module = THIS_MODULE,
@@ -307,10 +314,14 @@
 	st->spi = spi;
 	indio_dev->dev.parent = &spi->dev;
 	indio_dev->name = spi_get_device_id(st->spi)->name;
-	if (spi_get_device_id(st->spi)->driver_data == ID_AD5501)
+	if (spi_get_device_id(st->spi)->driver_data == ID_AD5501) {
 		indio_dev->info = &ad5501_info;
-	else
+		indio_dev->num_channels = 1;
+	} else {
 		indio_dev->info = &ad5504_info;
+		indio_dev->num_channels = 4;
+	}
+	indio_dev->channels = ad5504_channels;
 	indio_dev->modes = INDIO_DIRECT_MODE;
 
 	if (spi->irq) {
@@ -367,6 +378,7 @@
 	{"ad5501", ID_AD5501},
 	{}
 };
+MODULE_DEVICE_TABLE(spi, ad5504_id);
 
 static struct spi_driver ad5504_driver = {
 	.driver = {
diff --git a/drivers/staging/iio/dac/ad5504.h b/drivers/staging/iio/dac/ad5504.h
index 85beb1d..afe0952 100644
--- a/drivers/staging/iio/dac/ad5504.h
+++ b/drivers/staging/iio/dac/ad5504.h
@@ -18,10 +18,7 @@
 
 /* Registers */
 #define AD5504_ADDR_NOOP		0
-#define AD5504_ADDR_DAC0		1
-#define AD5504_ADDR_DAC1		2
-#define AD5504_ADDR_DAC2		3
-#define AD5504_ADDR_DAC3		4
+#define AD5504_ADDR_DAC(x)		((x) + 1)
 #define AD5504_ADDR_ALL_DAC		5
 #define AD5504_ADDR_CTRL		7
 
diff --git a/drivers/staging/iio/dac/ad5624r.h b/drivers/staging/iio/dac/ad5624r.h
index b71c6a0..5dca302 100644
--- a/drivers/staging/iio/dac/ad5624r.h
+++ b/drivers/staging/iio/dac/ad5624r.h
@@ -32,12 +32,12 @@
 
 /**
  * struct ad5624r_chip_info - chip specific information
- * @bits:		accuracy of the DAC in bits
+ * @channels:		channel spec for the DAC
  * @int_vref_mv:	AD5620/40/60: the internal reference voltage
  */
 
 struct ad5624r_chip_info {
-	u8				bits;
+	const struct iio_chan_spec	*channels;
 	u16				int_vref_mv;
 };
 
diff --git a/drivers/staging/iio/dac/ad5624r_spi.c b/drivers/staging/iio/dac/ad5624r_spi.c
index 6e05f0d..10c7484 100644
--- a/drivers/staging/iio/dac/ad5624r_spi.c
+++ b/drivers/staging/iio/dac/ad5624r_spi.c
@@ -21,29 +21,51 @@
 #include "dac.h"
 #include "ad5624r.h"
 
+#define AD5624R_CHANNEL(_chan, _bits) { \
+	.type = IIO_VOLTAGE, \
+	.indexed = 1, \
+	.output = 1, \
+	.channel = (_chan), \
+	.info_mask = IIO_CHAN_INFO_SCALE_SHARED_BIT, \
+	.address = (_chan), \
+	.scan_type = IIO_ST('u', (_bits), 16, 16 - (_bits)), \
+}
+
+#define DECLARE_AD5624R_CHANNELS(_name, _bits) \
+	const struct iio_chan_spec _name##_channels[] = { \
+		AD5624R_CHANNEL(0, _bits), \
+		AD5624R_CHANNEL(1, _bits), \
+		AD5624R_CHANNEL(2, _bits), \
+		AD5624R_CHANNEL(3, _bits), \
+}
+
+static DECLARE_AD5624R_CHANNELS(ad5624r, 12);
+static DECLARE_AD5624R_CHANNELS(ad5644r, 14);
+static DECLARE_AD5624R_CHANNELS(ad5664r, 16);
+
 static const struct ad5624r_chip_info ad5624r_chip_info_tbl[] = {
 	[ID_AD5624R3] = {
-		.bits = 12,
-		.int_vref_mv = 1250,
-	},
-	[ID_AD5644R3] = {
-		.bits = 14,
-		.int_vref_mv = 1250,
-	},
-	[ID_AD5664R3] = {
-		.bits = 16,
+		.channels = ad5624r_channels,
 		.int_vref_mv = 1250,
 	},
 	[ID_AD5624R5] = {
-		.bits = 12,
+		.channels = ad5624r_channels,
 		.int_vref_mv = 2500,
 	},
+	[ID_AD5644R3] = {
+		.channels = ad5644r_channels,
+		.int_vref_mv = 1250,
+	},
 	[ID_AD5644R5] = {
-		.bits = 14,
+		.channels = ad5644r_channels,
 		.int_vref_mv = 2500,
 	},
+	[ID_AD5664R3] = {
+		.channels = ad5664r_channels,
+		.int_vref_mv = 1250,
+	},
 	[ID_AD5664R5] = {
-		.bits = 16,
+		.channels = ad5664r_channels,
 		.int_vref_mv = 2500,
 	},
 };
@@ -70,24 +92,49 @@
 	return spi_write(spi, msg, 3);
 }
 
-static ssize_t ad5624r_write_dac(struct device *dev,
-				 struct device_attribute *attr,
-				 const char *buf, size_t len)
+static int ad5624r_read_raw(struct iio_dev *indio_dev,
+			   struct iio_chan_spec const *chan,
+			   int *val,
+			   int *val2,
+			   long m)
 {
-	long readin;
-	int ret;
-	struct iio_dev *indio_dev = dev_get_drvdata(dev);
 	struct ad5624r_state *st = iio_priv(indio_dev);
-	struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
+	unsigned long scale_uv;
 
-	ret = strict_strtol(buf, 10, &readin);
-	if (ret)
-		return ret;
+	switch (m) {
+	case IIO_CHAN_INFO_SCALE:
+		scale_uv = (st->vref_mv * 1000) >> chan->scan_type.realbits;
+		*val =  scale_uv / 1000;
+		*val2 = (scale_uv % 1000) * 1000;
+		return IIO_VAL_INT_PLUS_MICRO;
 
-	ret = ad5624r_spi_write(st->us, AD5624R_CMD_WRITE_INPUT_N_UPDATE_N,
-				this_attr->address, readin,
-				st->chip_info->bits);
-	return ret ? ret : len;
+	}
+	return -EINVAL;
+}
+
+static int ad5624r_write_raw(struct iio_dev *indio_dev,
+			       struct iio_chan_spec const *chan,
+			       int val,
+			       int val2,
+			       long mask)
+{
+	struct ad5624r_state *st = iio_priv(indio_dev);
+	int ret;
+
+	switch (mask) {
+	case 0:
+		if (val >= (1 << chan->scan_type.realbits) || val < 0)
+			return -EINVAL;
+
+		return ad5624r_spi_write(st->us,
+				AD5624R_CMD_WRITE_INPUT_N_UPDATE_N,
+				chan->address, val,
+				chan->scan_type.shift);
+	default:
+		ret = -EINVAL;
+	}
+
+	return -EINVAL;
 }
 
 static ssize_t ad5624r_read_powerdown_mode(struct device *dev,
@@ -161,24 +208,6 @@
 	return ret ? ret : len;
 }
 
-static ssize_t ad5624r_show_scale(struct device *dev,
-				struct device_attribute *attr,
-				char *buf)
-{
-	struct iio_dev *indio_dev = dev_get_drvdata(dev);
-	struct ad5624r_state *st = iio_priv(indio_dev);
-	/* Corresponds to Vref / 2^(bits) */
-	unsigned int scale_uv = (st->vref_mv * 1000) >> st->chip_info->bits;
-
-	return sprintf(buf, "%d.%03d\n", scale_uv / 1000, scale_uv % 1000);
-}
-static IIO_DEVICE_ATTR(out_voltage_scale, S_IRUGO, ad5624r_show_scale, NULL, 0);
-
-static IIO_DEV_ATTR_OUT_RAW(0, ad5624r_write_dac, AD5624R_ADDR_DAC0);
-static IIO_DEV_ATTR_OUT_RAW(1, ad5624r_write_dac, AD5624R_ADDR_DAC1);
-static IIO_DEV_ATTR_OUT_RAW(2, ad5624r_write_dac, AD5624R_ADDR_DAC2);
-static IIO_DEV_ATTR_OUT_RAW(3, ad5624r_write_dac, AD5624R_ADDR_DAC3);
-
 static IIO_DEVICE_ATTR(out_voltage_powerdown_mode, S_IRUGO |
 			S_IWUSR, ad5624r_read_powerdown_mode,
 			ad5624r_write_powerdown_mode, 0);
@@ -200,17 +229,12 @@
 				   ad5624r_write_dac_powerdown, 3);
 
 static struct attribute *ad5624r_attributes[] = {
-	&iio_dev_attr_out_voltage0_raw.dev_attr.attr,
-	&iio_dev_attr_out_voltage1_raw.dev_attr.attr,
-	&iio_dev_attr_out_voltage2_raw.dev_attr.attr,
-	&iio_dev_attr_out_voltage3_raw.dev_attr.attr,
 	&iio_dev_attr_out_voltage0_powerdown.dev_attr.attr,
 	&iio_dev_attr_out_voltage1_powerdown.dev_attr.attr,
 	&iio_dev_attr_out_voltage2_powerdown.dev_attr.attr,
 	&iio_dev_attr_out_voltage3_powerdown.dev_attr.attr,
 	&iio_dev_attr_out_voltage_powerdown_mode.dev_attr.attr,
 	&iio_const_attr_out_voltage_powerdown_mode_available.dev_attr.attr,
-	&iio_dev_attr_out_voltage_scale.dev_attr.attr,
 	NULL,
 };
 
@@ -219,6 +243,8 @@
 };
 
 static const struct iio_info ad5624r_info = {
+	.write_raw = ad5624r_write_raw,
+	.read_raw = ad5624r_read_raw,
 	.attrs = &ad5624r_attribute_group,
 	.driver_module = THIS_MODULE,
 };
@@ -259,6 +285,8 @@
 	indio_dev->name = spi_get_device_id(spi)->name;
 	indio_dev->info = &ad5624r_info;
 	indio_dev->modes = INDIO_DIRECT_MODE;
+	indio_dev->channels = st->chip_info->channels;
+	indio_dev->num_channels = AD5624R_DAC_CHANNELS;
 
 	ret = ad5624r_spi_write(spi, AD5624R_CMD_INTERNAL_REFER_SETUP, 0,
 				!!voltage_uv, 16);
@@ -307,6 +335,7 @@
 	{"ad5664r5", ID_AD5664R5},
 	{}
 };
+MODULE_DEVICE_TABLE(spi, ad5624r_id);
 
 static struct spi_driver ad5624r_driver = {
 	.driver = {
diff --git a/drivers/staging/iio/dac/ad5686.c b/drivers/staging/iio/dac/ad5686.c
index e72db2f..ce2d619 100644
--- a/drivers/staging/iio/dac/ad5686.c
+++ b/drivers/staging/iio/dac/ad5686.c
@@ -99,7 +99,7 @@
 		.indexed = 1,					\
 		.output = 1,					\
 		.channel = chan,				\
-		.info_mask = (1 << IIO_CHAN_INFO_SCALE_SHARED),	\
+		.info_mask = IIO_CHAN_INFO_SCALE_SHARED_BIT,	\
 		.address = AD5686_ADDR_DAC(chan),			\
 		.scan_type = IIO_ST('u', bits, 16, shift)	\
 }
@@ -306,7 +306,7 @@
 		*val = ret;
 		return IIO_VAL_INT;
 		break;
-	case (1 << IIO_CHAN_INFO_SCALE_SHARED):
+	case IIO_CHAN_INFO_SCALE:
 		scale_uv = (st->vref_mv * 100000)
 			>> (chan->scan_type.realbits);
 		*val =  scale_uv / 100000;
@@ -437,6 +437,7 @@
 	{"ad5686", ID_AD5686},
 	{}
 };
+MODULE_DEVICE_TABLE(spi, ad5686_id);
 
 static struct spi_driver ad5686_driver = {
 	.driver = {
diff --git a/drivers/staging/iio/dac/ad5764.c b/drivers/staging/iio/dac/ad5764.c
new file mode 100644
index 0000000..ff91480
--- /dev/null
+++ b/drivers/staging/iio/dac/ad5764.c
@@ -0,0 +1,393 @@
+/*
+ * Analog devices AD5764, AD5764R, AD5744, AD5744R quad-channel
+ * Digital to Analog Converters driver
+ *
+ * Copyright 2011 Analog Devices Inc.
+ *
+ * Licensed under the GPL-2.
+ */
+
+#include <linux/device.h>
+#include <linux/err.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/spi/spi.h>
+#include <linux/slab.h>
+#include <linux/sysfs.h>
+#include <linux/regulator/consumer.h>
+
+#include "../iio.h"
+#include "../sysfs.h"
+#include "dac.h"
+
+#define AD5764_REG_SF_NOP			0x0
+#define AD5764_REG_SF_CONFIG			0x1
+#define AD5764_REG_SF_CLEAR			0x4
+#define AD5764_REG_SF_LOAD			0x5
+#define AD5764_REG_DATA(x)			((2 << 3) | (x))
+#define AD5764_REG_COARSE_GAIN(x)		((3 << 3) | (x))
+#define AD5764_REG_FINE_GAIN(x)			((4 << 3) | (x))
+#define AD5764_REG_OFFSET(x)			((5 << 3) | (x))
+
+#define AD5764_NUM_CHANNELS 4
+
+/**
+ * struct ad5764_chip_info - chip specific information
+ * @int_vref:	Value of the internal reference voltage in uV - 0 if external
+ *		reference voltage is used
+ * @channel	channel specification
+*/
+
+struct ad5764_chip_info {
+	unsigned long int_vref;
+	const struct iio_chan_spec *channels;
+};
+
+/**
+ * struct ad5764_state - driver instance specific data
+ * @spi:		spi_device
+ * @chip_info:		chip info
+ * @vref_reg:		vref supply regulators
+ * @data:		spi transfer buffers
+ */
+
+struct ad5764_state {
+	struct spi_device		*spi;
+	const struct ad5764_chip_info	*chip_info;
+	struct regulator_bulk_data	vref_reg[2];
+
+	/*
+	 * DMA (thus cache coherency maintenance) requires the
+	 * transfer buffers to live in their own cache lines.
+	 */
+	union {
+		__be32 d32;
+		u8 d8[4];
+	} data[2] ____cacheline_aligned;
+};
+
+enum ad5764_type {
+	ID_AD5744,
+	ID_AD5744R,
+	ID_AD5764,
+	ID_AD5764R,
+};
+
+#define AD5764_CHANNEL(_chan, _bits) {				\
+	.type = IIO_VOLTAGE,					\
+	.indexed = 1,						\
+	.output = 1,						\
+	.channel = (_chan),					\
+	.address = (_chan),					\
+	.info_mask = IIO_CHAN_INFO_OFFSET_SHARED_BIT |		\
+		IIO_CHAN_INFO_SCALE_SEPARATE_BIT |		\
+		IIO_CHAN_INFO_CALIBSCALE_SEPARATE_BIT |		\
+		IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT,		\
+	.scan_type = IIO_ST('u', (_bits), 16, 16 - (_bits))	\
+}
+
+#define DECLARE_AD5764_CHANNELS(_name, _bits) \
+const struct iio_chan_spec _name##_channels[] = { \
+	AD5764_CHANNEL(0, (_bits)), \
+	AD5764_CHANNEL(1, (_bits)), \
+	AD5764_CHANNEL(2, (_bits)), \
+	AD5764_CHANNEL(3, (_bits)), \
+};
+
+static DECLARE_AD5764_CHANNELS(ad5764, 16);
+static DECLARE_AD5764_CHANNELS(ad5744, 14);
+
+static const struct ad5764_chip_info ad5764_chip_infos[] = {
+	[ID_AD5744] = {
+		.int_vref = 0,
+		.channels = ad5744_channels,
+	},
+	[ID_AD5744R] = {
+		.int_vref = 5000000,
+		.channels = ad5744_channels,
+	},
+	[ID_AD5764] = {
+		.int_vref = 0,
+		.channels = ad5764_channels,
+	},
+	[ID_AD5764R] = {
+		.int_vref = 5000000,
+		.channels = ad5764_channels,
+	},
+};
+
+static int ad5764_write(struct iio_dev *indio_dev, unsigned int reg,
+	unsigned int val)
+{
+	struct ad5764_state *st = iio_priv(indio_dev);
+	int ret;
+
+	mutex_lock(&indio_dev->mlock);
+	st->data[0].d32 = cpu_to_be32((reg << 16) | val);
+
+	ret = spi_write(st->spi, &st->data[0].d8[1], 3);
+	mutex_unlock(&indio_dev->mlock);
+
+	return ret;
+}
+
+static int ad5764_read(struct iio_dev *indio_dev, unsigned int reg,
+	unsigned int *val)
+{
+	struct ad5764_state *st = iio_priv(indio_dev);
+	struct spi_message m;
+	int ret;
+	struct spi_transfer t[] = {
+		{
+			.tx_buf = &st->data[0].d8[1],
+			.len = 3,
+			.cs_change = 1,
+		}, {
+			.rx_buf = &st->data[1].d8[1],
+			.len = 3,
+		},
+	};
+
+	spi_message_init(&m);
+	spi_message_add_tail(&t[0], &m);
+	spi_message_add_tail(&t[1], &m);
+
+	mutex_lock(&indio_dev->mlock);
+
+	st->data[0].d32 = cpu_to_be32((1 << 23) | (reg << 16));
+
+	ret = spi_sync(st->spi, &m);
+	if (ret >= 0)
+		*val = be32_to_cpu(st->data[1].d32) & 0xffff;
+
+	mutex_unlock(&indio_dev->mlock);
+
+	return ret;
+}
+
+static int ad5764_chan_info_to_reg(struct iio_chan_spec const *chan, long info)
+{
+	switch (info) {
+	case 0:
+		return AD5764_REG_DATA(chan->address);
+	case IIO_CHAN_INFO_CALIBBIAS:
+		return AD5764_REG_OFFSET(chan->address);
+	case IIO_CHAN_INFO_CALIBSCALE:
+		return AD5764_REG_FINE_GAIN(chan->address);
+	default:
+		break;
+	}
+
+	return 0;
+}
+
+static int ad5764_write_raw(struct iio_dev *indio_dev,
+	struct iio_chan_spec const *chan, int val, int val2, long info)
+{
+	const int max_val = (1 << chan->scan_type.realbits);
+	unsigned int reg;
+
+	switch (info) {
+	case 0:
+		if (val >= max_val || val < 0)
+			return -EINVAL;
+		val <<= chan->scan_type.shift;
+		break;
+	case IIO_CHAN_INFO_CALIBBIAS:
+		if (val >= 128 || val < -128)
+			return -EINVAL;
+		break;
+	case IIO_CHAN_INFO_CALIBSCALE:
+		if (val >= 32 || val < -32)
+			return -EINVAL;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	reg = ad5764_chan_info_to_reg(chan, info);
+	return ad5764_write(indio_dev, reg, (u16)val);
+}
+
+static int ad5764_get_channel_vref(struct ad5764_state *st,
+	unsigned int channel)
+{
+	if (st->chip_info->int_vref)
+		return st->chip_info->int_vref;
+	else
+		return regulator_get_voltage(st->vref_reg[channel / 2].consumer);
+}
+
+static int ad5764_read_raw(struct iio_dev *indio_dev,
+	struct iio_chan_spec const *chan, int *val, int *val2, long info)
+{
+	struct ad5764_state *st = iio_priv(indio_dev);
+	unsigned long scale_uv;
+	unsigned int reg;
+	int vref;
+	int ret;
+
+	switch (info) {
+	case 0:
+		reg = AD5764_REG_DATA(chan->address);
+		ret = ad5764_read(indio_dev, reg, val);
+		if (ret < 0)
+			return ret;
+		*val >>= chan->scan_type.shift;
+		return IIO_VAL_INT;
+	case IIO_CHAN_INFO_CALIBBIAS:
+		reg = AD5764_REG_OFFSET(chan->address);
+		ret = ad5764_read(indio_dev, reg, val);
+		if (ret < 0)
+			return ret;
+		*val = sign_extend32(*val, 7);
+		return IIO_VAL_INT;
+	case IIO_CHAN_INFO_CALIBSCALE:
+		reg = AD5764_REG_FINE_GAIN(chan->address);
+		ret = ad5764_read(indio_dev, reg, val);
+		if (ret < 0)
+			return ret;
+		*val = sign_extend32(*val, 5);
+		return IIO_VAL_INT;
+	case IIO_CHAN_INFO_SCALE:
+		/* vout = 4 * vref + ((dac_code / 65535) - 0.5) */
+		vref = ad5764_get_channel_vref(st, chan->channel);
+		if (vref < 0)
+			return vref;
+
+		scale_uv = (vref * 4 * 100) >> chan->scan_type.realbits;
+		*val = scale_uv / 100000;
+		*val2 = (scale_uv % 100000) * 10;
+		return IIO_VAL_INT_PLUS_MICRO;
+	case IIO_CHAN_INFO_OFFSET:
+		*val = -(1 << chan->scan_type.realbits) / 2;
+		return IIO_VAL_INT;
+	}
+
+	return -EINVAL;
+}
+
+static const struct iio_info ad5764_info = {
+	.read_raw = ad5764_read_raw,
+	.write_raw = ad5764_write_raw,
+	.driver_module = THIS_MODULE,
+};
+
+static int __devinit ad5764_probe(struct spi_device *spi)
+{
+	enum ad5764_type type = spi_get_device_id(spi)->driver_data;
+	struct iio_dev *indio_dev;
+	struct ad5764_state *st;
+	int ret;
+
+	indio_dev = iio_allocate_device(sizeof(*st));
+	if (indio_dev == NULL) {
+		dev_err(&spi->dev, "Failed to allocate iio device\n");
+		return -ENOMEM;
+	}
+
+	st = iio_priv(indio_dev);
+	spi_set_drvdata(spi, indio_dev);
+
+	st->spi = spi;
+	st->chip_info = &ad5764_chip_infos[type];
+
+	indio_dev->dev.parent = &spi->dev;
+	indio_dev->name = spi_get_device_id(spi)->name;
+	indio_dev->info = &ad5764_info;
+	indio_dev->modes = INDIO_DIRECT_MODE;
+	indio_dev->num_channels = AD5764_NUM_CHANNELS;
+	indio_dev->channels = st->chip_info->channels;
+
+	if (st->chip_info->int_vref == 0) {
+		st->vref_reg[0].supply = "vrefAB";
+		st->vref_reg[1].supply = "vrefCD";
+
+		ret = regulator_bulk_get(&st->spi->dev,
+			ARRAY_SIZE(st->vref_reg), st->vref_reg);
+		if (ret) {
+			dev_err(&spi->dev, "Failed to request vref regulators: %d\n",
+				ret);
+			goto error_free;
+		}
+
+		ret = regulator_bulk_enable(ARRAY_SIZE(st->vref_reg),
+			st->vref_reg);
+		if (ret) {
+			dev_err(&spi->dev, "Failed to enable vref regulators: %d\n",
+				ret);
+			goto error_free_reg;
+		}
+	}
+
+	ret = iio_device_register(indio_dev);
+	if (ret) {
+		dev_err(&spi->dev, "Failed to register iio device: %d\n", ret);
+		goto error_disable_reg;
+	}
+
+	return 0;
+
+error_disable_reg:
+	if (st->chip_info->int_vref == 0)
+		regulator_bulk_disable(ARRAY_SIZE(st->vref_reg), st->vref_reg);
+error_free_reg:
+	if (st->chip_info->int_vref == 0)
+		regulator_bulk_free(ARRAY_SIZE(st->vref_reg), st->vref_reg);
+error_free:
+	iio_free_device(indio_dev);
+
+	return ret;
+}
+
+static int __devexit ad5764_remove(struct spi_device *spi)
+{
+	struct iio_dev *indio_dev = spi_get_drvdata(spi);
+	struct ad5764_state *st = iio_priv(indio_dev);
+
+	iio_device_unregister(indio_dev);
+
+	if (st->chip_info->int_vref == 0) {
+		regulator_bulk_disable(ARRAY_SIZE(st->vref_reg), st->vref_reg);
+		regulator_bulk_free(ARRAY_SIZE(st->vref_reg), st->vref_reg);
+	}
+
+	iio_free_device(indio_dev);
+
+	return 0;
+}
+
+static const struct spi_device_id ad5764_ids[] = {
+	{ "ad5744", ID_AD5744 },
+	{ "ad5744r", ID_AD5744R },
+	{ "ad5764", ID_AD5764 },
+	{ "ad5764r", ID_AD5764R },
+	{ }
+};
+MODULE_DEVICE_TABLE(spi, ad5764_ids);
+
+static struct spi_driver ad5764_driver = {
+	.driver = {
+		.name = "ad5764",
+		.owner = THIS_MODULE,
+	},
+	.probe = ad5764_probe,
+	.remove = __devexit_p(ad5764_remove),
+	.id_table = ad5764_ids,
+};
+
+static int __init ad5764_spi_init(void)
+{
+	return spi_register_driver(&ad5764_driver);
+}
+module_init(ad5764_spi_init);
+
+static void __exit ad5764_spi_exit(void)
+{
+	spi_unregister_driver(&ad5764_driver);
+}
+module_exit(ad5764_spi_exit);
+
+MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>");
+MODULE_DESCRIPTION("Analog Devices AD5744/AD5744R/AD5764/AD5764R DAC");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/staging/iio/dac/ad5791.c b/drivers/staging/iio/dac/ad5791.c
index 4a80fd8..ac45636 100644
--- a/drivers/staging/iio/dac/ad5791.c
+++ b/drivers/staging/iio/dac/ad5791.c
@@ -1,5 +1,6 @@
 /*
- * AD5760, AD5780, AD5781, AD5791 Voltage Output Digital to Analog Converter
+ * AD5760, AD5780, AD5781, AD5790, AD5791 Voltage Output Digital to Analog
+ * Converter
  *
  * Copyright 2011 Analog Devices Inc.
  *
@@ -77,8 +78,8 @@
 	.indexed = 1,					\
 	.address = AD5791_ADDR_DAC0,			\
 	.channel = 0,					\
-	.info_mask = (1 << IIO_CHAN_INFO_SCALE_SHARED) | \
-		(1 << IIO_CHAN_INFO_OFFSET_SHARED),	\
+	.info_mask = IIO_CHAN_INFO_SCALE_SHARED_BIT | \
+		IIO_CHAN_INFO_OFFSET_SHARED_BIT,	\
 	.scan_type = IIO_ST('u', bits, 24, shift)	\
 }
 
@@ -237,11 +238,11 @@
 		*val &= AD5791_DAC_MASK;
 		*val >>= chan->scan_type.shift;
 		return IIO_VAL_INT;
-	case (1 << IIO_CHAN_INFO_SCALE_SHARED):
+	case IIO_CHAN_INFO_SCALE:
 		*val = 0;
 		*val2 = (((u64)st->vref_mv) * 1000000ULL) >> chan->scan_type.realbits;
 		return IIO_VAL_INT_PLUS_MICRO;
-	case (1 << IIO_CHAN_INFO_OFFSET_SHARED):
+	case IIO_CHAN_INFO_OFFSET:
 		val64 = (((u64)st->vref_neg_mv) << chan->scan_type.realbits);
 		do_div(val64, st->vref_mv);
 		*val = -val64;
@@ -397,9 +398,11 @@
 	{"ad5760", ID_AD5760},
 	{"ad5780", ID_AD5780},
 	{"ad5781", ID_AD5781},
+	{"ad5790", ID_AD5791},
 	{"ad5791", ID_AD5791},
 	{}
 };
+MODULE_DEVICE_TABLE(spi, ad5791_id);
 
 static struct spi_driver ad5791_driver = {
 	.driver = {
@@ -413,5 +416,5 @@
 module_spi_driver(ad5791_driver);
 
 MODULE_AUTHOR("Michael Hennerich <hennerich@blackfin.uclinux.org>");
-MODULE_DESCRIPTION("Analog Devices AD5760/AD5780/AD5781/AD5791 DAC");
+MODULE_DESCRIPTION("Analog Devices AD5760/AD5780/AD5781/AD5790/AD5791 DAC");
 MODULE_LICENSE("GPL v2");
diff --git a/drivers/staging/iio/dds/ad5930.c b/drivers/staging/iio/dds/ad5930.c
index 4a360d0..9c32d1b 100644
--- a/drivers/staging/iio/dds/ad5930.c
+++ b/drivers/staging/iio/dds/ad5930.c
@@ -148,3 +148,4 @@
 MODULE_AUTHOR("Cliff Cai");
 MODULE_DESCRIPTION("Analog Devices ad5930 driver");
 MODULE_LICENSE("GPL v2");
+MODULE_ALIAS("spi:" DRV_NAME);
diff --git a/drivers/staging/iio/dds/ad9832.c b/drivers/staging/iio/dds/ad9832.c
index cc32fd6..2ccf25d 100644
--- a/drivers/staging/iio/dds/ad9832.c
+++ b/drivers/staging/iio/dds/ad9832.c
@@ -88,7 +88,7 @@
 		goto error_ret;
 
 	mutex_lock(&indio_dev->mlock);
-	switch (this_attr->address) {
+	switch ((u32) this_attr->address) {
 	case AD9832_FREQ0HM:
 	case AD9832_FREQ1HM:
 		ret = ad9832_write_frequency(st, this_attr->address, val);
@@ -344,11 +344,11 @@
 	{"ad9835", 0},
 	{}
 };
+MODULE_DEVICE_TABLE(spi, ad9832_id);
 
 static struct spi_driver ad9832_driver = {
 	.driver = {
 		.name	= "ad9832",
-		.bus	= &spi_bus_type,
 		.owner	= THIS_MODULE,
 	},
 	.probe		= ad9832_probe,
@@ -360,4 +360,3 @@
 MODULE_AUTHOR("Michael Hennerich <hennerich@blackfin.uclinux.org>");
 MODULE_DESCRIPTION("Analog Devices AD9832/AD9835 DDS");
 MODULE_LICENSE("GPL v2");
-MODULE_ALIAS("spi:ad9832");
diff --git a/drivers/staging/iio/dds/ad9834.c b/drivers/staging/iio/dds/ad9834.c
index 51fda6f..5e67104 100644
--- a/drivers/staging/iio/dds/ad9834.c
+++ b/drivers/staging/iio/dds/ad9834.c
@@ -77,7 +77,7 @@
 		goto error_ret;
 
 	mutex_lock(&indio_dev->mlock);
-	switch (this_attr->address) {
+	switch ((u32) this_attr->address) {
 	case AD9834_REG_FREQ0:
 	case AD9834_REG_FREQ1:
 		ret = ad9834_write_frequency(st, this_attr->address, val);
@@ -153,7 +153,7 @@
 
 	mutex_lock(&indio_dev->mlock);
 
-	switch (this_attr->address) {
+	switch ((u32) this_attr->address) {
 	case 0:
 		if (sysfs_streq(buf, "sine")) {
 			st->control &= ~AD9834_MODE;
@@ -435,11 +435,11 @@
 	{"ad9838", ID_AD9838},
 	{}
 };
+MODULE_DEVICE_TABLE(spi, ad9834_id);
 
 static struct spi_driver ad9834_driver = {
 	.driver = {
 		.name	= "ad9834",
-		.bus	= &spi_bus_type,
 		.owner	= THIS_MODULE,
 	},
 	.probe		= ad9834_probe,
@@ -451,4 +451,3 @@
 MODULE_AUTHOR("Michael Hennerich <hennerich@blackfin.uclinux.org>");
 MODULE_DESCRIPTION("Analog Devices AD9833/AD9834/AD9837/AD9838 DDS");
 MODULE_LICENSE("GPL v2");
-MODULE_ALIAS("spi:ad9834");
diff --git a/drivers/staging/iio/dds/ad9850.c b/drivers/staging/iio/dds/ad9850.c
index f9c96af..f4f731b 100644
--- a/drivers/staging/iio/dds/ad9850.c
+++ b/drivers/staging/iio/dds/ad9850.c
@@ -134,3 +134,4 @@
 MODULE_AUTHOR("Cliff Cai");
 MODULE_DESCRIPTION("Analog Devices ad9850 driver");
 MODULE_LICENSE("GPL v2");
+MODULE_ALIAS("spi:" DRV_NAME);
diff --git a/drivers/staging/iio/dds/ad9852.c b/drivers/staging/iio/dds/ad9852.c
index 9fc73fd..554266c 100644
--- a/drivers/staging/iio/dds/ad9852.c
+++ b/drivers/staging/iio/dds/ad9852.c
@@ -285,3 +285,4 @@
 MODULE_AUTHOR("Cliff Cai");
 MODULE_DESCRIPTION("Analog Devices ad9852 driver");
 MODULE_LICENSE("GPL v2");
+MODULE_ALIAS("spi:" DRV_NAME);
diff --git a/drivers/staging/iio/dds/ad9910.c b/drivers/staging/iio/dds/ad9910.c
index 57046b0..3985766 100644
--- a/drivers/staging/iio/dds/ad9910.c
+++ b/drivers/staging/iio/dds/ad9910.c
@@ -418,3 +418,4 @@
 MODULE_AUTHOR("Cliff Cai");
 MODULE_DESCRIPTION("Analog Devices ad9910 driver");
 MODULE_LICENSE("GPL v2");
+MODULE_ALIAS("spi:" DRV_NAME);
diff --git a/drivers/staging/iio/dds/ad9951.c b/drivers/staging/iio/dds/ad9951.c
index d29130e..4d15004 100644
--- a/drivers/staging/iio/dds/ad9951.c
+++ b/drivers/staging/iio/dds/ad9951.c
@@ -229,3 +229,4 @@
 MODULE_AUTHOR("Cliff Cai");
 MODULE_DESCRIPTION("Analog Devices ad9951 driver");
 MODULE_LICENSE("GPL v2");
+MODULE_ALIAS("spi:" DRV_NAME);
diff --git a/drivers/staging/iio/events.h b/drivers/staging/iio/events.h
new file mode 100644
index 0000000..bfb6340
--- /dev/null
+++ b/drivers/staging/iio/events.h
@@ -0,0 +1,103 @@
+/* The industrial I/O - event passing to userspace
+ *
+ * Copyright (c) 2008-2011 Jonathan Cameron
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ */
+#ifndef _IIO_EVENTS_H_
+#define _IIO_EVENTS_H_
+
+#include <linux/ioctl.h>
+#include <linux/types.h>
+#include "types.h"
+
+/**
+ * struct iio_event_data - The actual event being pushed to userspace
+ * @id:		event identifier
+ * @timestamp:	best estimate of time of event occurrence (often from
+ *		the interrupt handler)
+ */
+struct iio_event_data {
+	__u64	id;
+	__s64	timestamp;
+};
+
+#define IIO_GET_EVENT_FD_IOCTL _IOR('i', 0x90, int)
+
+enum iio_event_type {
+	IIO_EV_TYPE_THRESH,
+	IIO_EV_TYPE_MAG,
+	IIO_EV_TYPE_ROC,
+	IIO_EV_TYPE_THRESH_ADAPTIVE,
+	IIO_EV_TYPE_MAG_ADAPTIVE,
+};
+
+enum iio_event_direction {
+	IIO_EV_DIR_EITHER,
+	IIO_EV_DIR_RISING,
+	IIO_EV_DIR_FALLING,
+};
+
+/**
+ * IIO_EVENT_CODE() - create event identifier
+ * @chan_type:	Type of the channel. Should be one of enum iio_chan_type.
+ * @diff:	Whether the event is for an differential channel or not.
+ * @modifier:	Modifier for the channel. Should be one of enum iio_modifier.
+ * @direction:	Direction of the event. One of enum iio_event_direction.
+ * @type:	Type of the event. Should be one enum iio_event_type.
+ * @chan:	Channel number for non-differential channels.
+ * @chan1:	First channel number for differential channels.
+ * @chan2:	Second channel number for differential channels.
+ */
+
+#define IIO_EVENT_CODE(chan_type, diff, modifier, direction,		\
+		       type, chan, chan1, chan2)			\
+	(((u64)type << 56) | ((u64)diff << 55) |			\
+	 ((u64)direction << 48) | ((u64)modifier << 40) |		\
+	 ((u64)chan_type << 32) | (((u16)chan2) << 16) | ((u16)chan1) | \
+	 ((u16)chan))
+
+
+#define IIO_EV_DIR_MAX 4
+#define IIO_EV_BIT(type, direction)			\
+	(1 << (type*IIO_EV_DIR_MAX + direction))
+
+/**
+ * IIO_MOD_EVENT_CODE() - create event identifier for modified channels
+ * @chan_type:	Type of the channel. Should be one of enum iio_chan_type.
+ * @number:	Channel number.
+ * @modifier:	Modifier for the channel. Should be one of enum iio_modifier.
+ * @type:	Type of the event. Should be one enum iio_event_type.
+ * @direction:	Direction of the event. One of enum iio_event_direction.
+ */
+
+#define IIO_MOD_EVENT_CODE(chan_type, number, modifier,		\
+			   type, direction)				\
+	IIO_EVENT_CODE(chan_type, 0, modifier, direction, type, number, 0, 0)
+
+/**
+ * IIO_UNMOD_EVENT_CODE() - create event identifier for unmodified channels
+ * @chan_type:	Type of the channel. Should be one of enum iio_chan_type.
+ * @number:	Channel number.
+ * @type:	Type of the event. Should be one enum iio_event_type.
+ * @direction:	Direction of the event. One of enum iio_event_direction.
+ */
+
+#define IIO_UNMOD_EVENT_CODE(chan_type, number, type, direction)	\
+	IIO_EVENT_CODE(chan_type, 0, 0, direction, type, number, 0, 0)
+
+#define IIO_EVENT_CODE_EXTRACT_TYPE(mask) ((mask >> 56) & 0xFF)
+
+#define IIO_EVENT_CODE_EXTRACT_DIR(mask) ((mask >> 48) & 0xCF)
+
+#define IIO_EVENT_CODE_EXTRACT_CHAN_TYPE(mask) ((mask >> 32) & 0xFF)
+
+/* Event code number extraction depends on which type of event we have.
+ * Perhaps review this function in the future*/
+#define IIO_EVENT_CODE_EXTRACT_NUM(mask) ((__s16)(mask & 0xFFFF))
+
+#define IIO_EVENT_CODE_EXTRACT_MODIFIER(mask) ((mask >> 40) & 0xFF)
+
+#endif
diff --git a/drivers/staging/iio/gyro/Kconfig b/drivers/staging/iio/gyro/Kconfig
index 22aea5b..ea295b2 100644
--- a/drivers/staging/iio/gyro/Kconfig
+++ b/drivers/staging/iio/gyro/Kconfig
@@ -37,11 +37,11 @@
 	  will be called adis16260.
 
 config ADXRS450
-	tristate "Analog Devices ADXRS450 Digital Output Gyroscope SPI driver"
+	tristate "Analog Devices ADXRS450/3 Digital Output Gyroscope SPI driver"
 	depends on SPI
 	help
-	  Say yes here to build support for Analog Devices ADXRS450 programmable
-	  digital output gyroscope.
+	  Say yes here to build support for Analog Devices ADXRS450 and ADXRS453
+	  programmable digital output gyroscope.
 
 	  This driver can also be built as a module.  If so, the module
 	  will be called adxrs450.
diff --git a/drivers/staging/iio/gyro/adis16060_core.c b/drivers/staging/iio/gyro/adis16060_core.c
index ff1b5a8..c0ca709 100644
--- a/drivers/staging/iio/gyro/adis16060_core.c
+++ b/drivers/staging/iio/gyro/adis16060_core.c
@@ -98,11 +98,11 @@
 		mutex_unlock(&indio_dev->mlock);
 		*val = tval;
 		return IIO_VAL_INT;
-	case (1 << IIO_CHAN_INFO_OFFSET_SEPARATE):
+	case IIO_CHAN_INFO_OFFSET:
 		*val = -7;
 		*val2 = 461117;
 		return IIO_VAL_INT_PLUS_MICRO;
-	case (1 << IIO_CHAN_INFO_SCALE_SEPARATE):
+	case IIO_CHAN_INFO_SCALE:
 		*val = 0;
 		*val2 = 34000;
 		return IIO_VAL_INT_PLUS_MICRO;
@@ -136,8 +136,8 @@
 		.type = IIO_TEMP,
 		.indexed = 1,
 		.channel = 0,
-		.info_mask = (1 << IIO_CHAN_INFO_OFFSET_SEPARATE) |
-		(1 << IIO_CHAN_INFO_SCALE_SEPARATE),
+		.info_mask = IIO_CHAN_INFO_OFFSET_SEPARATE_BIT |
+		IIO_CHAN_INFO_SCALE_SEPARATE_BIT,
 		.address = ADIS16060_TEMP_OUT,
 	}
 };
diff --git a/drivers/staging/iio/gyro/adis16080_core.c b/drivers/staging/iio/gyro/adis16080_core.c
index 9405f2d..1815490 100644
--- a/drivers/staging/iio/gyro/adis16080_core.c
+++ b/drivers/staging/iio/gyro/adis16080_core.c
@@ -194,3 +194,4 @@
 MODULE_AUTHOR("Barry Song <21cnbao@gmail.com>");
 MODULE_DESCRIPTION("Analog Devices ADIS16080/100 Yaw Rate Gyroscope Driver");
 MODULE_LICENSE("GPL v2");
+MODULE_ALIAS("spi:adis16080");
diff --git a/drivers/staging/iio/gyro/adis16130_core.c b/drivers/staging/iio/gyro/adis16130_core.c
index c9aaca9..947eb86 100644
--- a/drivers/staging/iio/gyro/adis16130_core.c
+++ b/drivers/staging/iio/gyro/adis16130_core.c
@@ -173,3 +173,4 @@
 MODULE_AUTHOR("Barry Song <21cnbao@gmail.com>");
 MODULE_DESCRIPTION("Analog Devices ADIS16130 High Precision Angular Rate");
 MODULE_LICENSE("GPL v2");
+MODULE_ALIAS("spi:adis16130");
diff --git a/drivers/staging/iio/gyro/adis16260_core.c b/drivers/staging/iio/gyro/adis16260_core.c
index 886dddf..8f6af47 100644
--- a/drivers/staging/iio/gyro/adis16260_core.c
+++ b/drivers/staging/iio/gyro/adis16260_core.c
@@ -20,7 +20,7 @@
 
 #include "../iio.h"
 #include "../sysfs.h"
-#include "../buffer_generic.h"
+#include "../buffer.h"
 
 #include "adis16260.h"
 
@@ -390,9 +390,9 @@
 #define ADIS16260_GYRO_CHANNEL_SET(axis, mod)				\
 	struct iio_chan_spec adis16260_channels_##axis[] = {		\
 		IIO_CHAN(IIO_ANGL_VEL, 1, 0, 0, NULL, 0, mod,		\
-			 (1 << IIO_CHAN_INFO_CALIBBIAS_SEPARATE) |	\
-			 (1 << IIO_CHAN_INFO_CALIBSCALE_SEPARATE) |	\
-			 (1 << IIO_CHAN_INFO_SCALE_SEPARATE),		\
+			 IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT |	\
+			 IIO_CHAN_INFO_CALIBSCALE_SEPARATE_BIT |	\
+			 IIO_CHAN_INFO_SCALE_SEPARATE_BIT,		\
 			 gyro, ADIS16260_SCAN_GYRO,			\
 			 IIO_ST('s', 14, 16, 0), 0),			\
 		IIO_CHAN(IIO_ANGL, 1, 0, 0, NULL, 0, mod,		\
@@ -400,16 +400,16 @@
 			 angle, ADIS16260_SCAN_ANGL,			\
 			 IIO_ST('u', 14, 16, 0), 0),			\
 		IIO_CHAN(IIO_TEMP, 0, 1, 0, NULL, 0, 0,			\
-			 (1 << IIO_CHAN_INFO_OFFSET_SEPARATE) |		\
-			 (1 << IIO_CHAN_INFO_SCALE_SEPARATE),		\
+			 IIO_CHAN_INFO_OFFSET_SEPARATE_BIT |		\
+			 IIO_CHAN_INFO_SCALE_SEPARATE_BIT,		\
 			 temp, ADIS16260_SCAN_TEMP,			\
 			 IIO_ST('u', 12, 16, 0), 0),			\
 		IIO_CHAN(IIO_VOLTAGE, 0, 1, 0, "supply", 0, 0,		\
-			 (1 << IIO_CHAN_INFO_SCALE_SEPARATE),		\
+			 IIO_CHAN_INFO_SCALE_SEPARATE_BIT,		\
 			 in_supply, ADIS16260_SCAN_SUPPLY,		\
 			 IIO_ST('u', 12, 16, 0), 0),			\
 		IIO_CHAN(IIO_VOLTAGE, 0, 1, 0, NULL, 1, 0,		\
-			 (1 << IIO_CHAN_INFO_SCALE_SEPARATE),		\
+			 IIO_CHAN_INFO_SCALE_SEPARATE_BIT,		\
 			 in_aux, ADIS16260_SCAN_AUX_ADC,		\
 			 IIO_ST('u', 12, 16, 0), 0),			\
 		IIO_CHAN_SOFT_TIMESTAMP(5)				\
@@ -464,8 +464,7 @@
 		*val = val16;
 		mutex_unlock(&indio_dev->mlock);
 		return IIO_VAL_INT;
-	case (1 << IIO_CHAN_INFO_SCALE_SEPARATE):
-	case (1 << IIO_CHAN_INFO_SCALE_SHARED):
+	case IIO_CHAN_INFO_SCALE:
 		switch (chan->type) {
 		case IIO_ANGL_VEL:
 			*val = 0;
@@ -489,10 +488,10 @@
 			return -EINVAL;
 		}
 		break;
-	case (1 << IIO_CHAN_INFO_OFFSET_SEPARATE):
+	case IIO_CHAN_INFO_OFFSET:
 		*val = 25;
 		return IIO_VAL_INT;
-	case (1 << IIO_CHAN_INFO_CALIBBIAS_SEPARATE):
+	case IIO_CHAN_INFO_CALIBBIAS:
 		switch (chan->type) {
 		case IIO_ANGL_VEL:
 			bits = 12;
@@ -512,7 +511,7 @@
 		*val = val16;
 		mutex_unlock(&indio_dev->mlock);
 		return IIO_VAL_INT;
-	case (1 << IIO_CHAN_INFO_CALIBSCALE_SEPARATE):
+	case IIO_CHAN_INFO_CALIBSCALE:
 		switch (chan->type) {
 		case IIO_ANGL_VEL:
 			bits = 12;
@@ -544,11 +543,11 @@
 	s16 val16;
 	u8 addr;
 	switch (mask) {
-	case (1 << IIO_CHAN_INFO_CALIBBIAS_SEPARATE):
+	case IIO_CHAN_INFO_CALIBBIAS:
 		val16 = val & ((1 << bits) - 1);
 		addr = adis16260_addresses[chan->address][1];
 		return adis16260_spi_write_reg_16(indio_dev, addr, val16);
-	case (1 << IIO_CHAN_INFO_CALIBSCALE_SEPARATE):
+	case IIO_CHAN_INFO_CALIBSCALE:
 		val16 = val & ((1 << bits) - 1);
 		addr = adis16260_addresses[chan->address][2];
 		return adis16260_spi_write_reg_16(indio_dev, addr, val16);
@@ -633,11 +632,16 @@
 	}
 	if (indio_dev->buffer) {
 		/* Set default scan mode */
-		iio_scan_mask_set(indio_dev->buffer, ADIS16260_SCAN_SUPPLY);
-		iio_scan_mask_set(indio_dev->buffer, ADIS16260_SCAN_GYRO);
-		iio_scan_mask_set(indio_dev->buffer, ADIS16260_SCAN_AUX_ADC);
-		iio_scan_mask_set(indio_dev->buffer, ADIS16260_SCAN_TEMP);
-		iio_scan_mask_set(indio_dev->buffer, ADIS16260_SCAN_ANGL);
+		iio_scan_mask_set(indio_dev, indio_dev->buffer,
+				  ADIS16260_SCAN_SUPPLY);
+		iio_scan_mask_set(indio_dev, indio_dev->buffer,
+				  ADIS16260_SCAN_GYRO);
+		iio_scan_mask_set(indio_dev, indio_dev->buffer,
+				  ADIS16260_SCAN_AUX_ADC);
+		iio_scan_mask_set(indio_dev, indio_dev->buffer,
+				  ADIS16260_SCAN_TEMP);
+		iio_scan_mask_set(indio_dev, indio_dev->buffer,
+				  ADIS16260_SCAN_ANGL);
 	}
 	if (spi->irq) {
 		ret = adis16260_probe_trigger(indio_dev);
@@ -701,6 +705,7 @@
 	{"adis16251", 1},
 	{}
 };
+MODULE_DEVICE_TABLE(spi, adis16260_id);
 
 static struct spi_driver adis16260_driver = {
 	.driver = {
diff --git a/drivers/staging/iio/gyro/adis16260_ring.c b/drivers/staging/iio/gyro/adis16260_ring.c
index 52a9e78..699a615 100644
--- a/drivers/staging/iio/gyro/adis16260_ring.c
+++ b/drivers/staging/iio/gyro/adis16260_ring.c
@@ -74,9 +74,10 @@
 		return -ENOMEM;
 	}
 
-	if (ring->scan_count &&
+	if (!bitmap_empty(indio_dev->active_scan_mask, indio_dev->masklength) &&
 	    adis16260_read_ring_data(&indio_dev->dev, st->rx) >= 0)
-		for (; i < ring->scan_count; i++)
+		for (; i < bitmap_weight(indio_dev->active_scan_mask,
+					 indio_dev->masklength); i++)
 			data[i] = be16_to_cpup((__be16 *)&(st->rx[i*2]));
 
 	/* Guaranteed to be aligned with 8 byte boundary */
@@ -116,10 +117,8 @@
 	indio_dev->buffer = ring;
 	/* Effectively select the ring buffer implementation */
 	ring->access = &ring_sw_access_funcs;
-	ring->bpe = 2;
 	ring->scan_timestamp = true;
-	ring->setup_ops = &adis16260_ring_setup_ops;
-	ring->owner = THIS_MODULE;
+	indio_dev->setup_ops = &adis16260_ring_setup_ops;
 
 	indio_dev->pollfunc = iio_alloc_pollfunc(&iio_pollfunc_store_time,
 						 &adis16260_trigger_handler,
diff --git a/drivers/staging/iio/gyro/adxrs450.h b/drivers/staging/iio/gyro/adxrs450.h
index b6b6828..af0c870 100644
--- a/drivers/staging/iio/gyro/adxrs450.h
+++ b/drivers/staging/iio/gyro/adxrs450.h
@@ -39,6 +39,11 @@
 
 #define ADXRS450_GET_ST(a)	((a >> 26) & 0x3)
 
+enum {
+	ID_ADXRS450,
+	ID_ADXRS453,
+};
+
 /**
  * struct adxrs450_state - device instance specific data
  * @us:			actual spi_device
diff --git a/drivers/staging/iio/gyro/adxrs450_core.c b/drivers/staging/iio/gyro/adxrs450_core.c
index 70fd468..15e2496 100644
--- a/drivers/staging/iio/gyro/adxrs450_core.c
+++ b/drivers/staging/iio/gyro/adxrs450_core.c
@@ -1,5 +1,5 @@
 /*
- * ADXRS450 Digital Output Gyroscope Driver
+ * ADXRS450/ADXRS453 Digital Output Gyroscope Driver
  *
  * Copyright 2011 Analog Devices Inc.
  *
@@ -243,7 +243,7 @@
 {
 	int ret;
 	switch (mask) {
-	case (1 << IIO_CHAN_INFO_CALIBBIAS_SEPARATE):
+	case IIO_CHAN_INFO_CALIBBIAS:
 		ret = adxrs450_spi_write_reg_16(indio_dev,
 						ADXRS450_DNC1,
 						val & 0x3FF);
@@ -263,7 +263,7 @@
 {
 	int ret;
 	s16 t;
-	u16 ut;
+
 	switch (mask) {
 	case 0:
 		switch (chan->type) {
@@ -276,10 +276,10 @@
 			break;
 		case IIO_TEMP:
 			ret = adxrs450_spi_read_reg_16(indio_dev,
-						       ADXRS450_TEMP1, &ut);
+						       ADXRS450_TEMP1, &t);
 			if (ret)
 				break;
-			*val = ut;
+			*val = (t >> 6) + 225;
 			ret = IIO_VAL_INT;
 			break;
 		default:
@@ -287,13 +287,34 @@
 			break;
 		}
 		break;
-	case (1 << IIO_CHAN_INFO_QUADRATURE_CORRECTION_RAW_SEPARATE):
+	case IIO_CHAN_INFO_SCALE:
+		switch (chan->type) {
+		case IIO_ANGL_VEL:
+			*val = 0;
+			*val2 = 218166;
+			return IIO_VAL_INT_PLUS_NANO;
+		case IIO_TEMP:
+			*val = 200;
+			*val2 = 0;
+			return IIO_VAL_INT;
+		default:
+			return -EINVAL;
+		}
+		break;
+	case IIO_CHAN_INFO_QUADRATURE_CORRECTION_RAW:
 		ret = adxrs450_spi_read_reg_16(indio_dev, ADXRS450_QUAD1, &t);
 		if (ret)
 			break;
 		*val = t;
 		ret = IIO_VAL_INT;
 		break;
+	case IIO_CHAN_INFO_CALIBBIAS:
+		ret = adxrs450_spi_read_reg_16(indio_dev, ADXRS450_DNC1, &t);
+		if (ret)
+			break;
+		*val = t;
+		ret = IIO_VAL_INT;
+		break;
 	default:
 		ret = -EINVAL;
 		break;
@@ -302,18 +323,36 @@
 	return ret;
 }
 
-static const struct iio_chan_spec adxrs450_channels[] = {
-	{
-		.type = IIO_ANGL_VEL,
-		.modified = 1,
-		.channel2 = IIO_MOD_Z,
-		.info_mask = (1 << IIO_CHAN_INFO_CALIBBIAS_SEPARATE) |
-		(1 << IIO_CHAN_INFO_QUADRATURE_CORRECTION_RAW_SEPARATE)
-	}, {
-		.type = IIO_TEMP,
-		.indexed = 1,
-		.channel = 0,
-	}
+static const struct iio_chan_spec adxrs450_channels[2][2] = {
+	[ID_ADXRS450] = {
+		{
+			.type = IIO_ANGL_VEL,
+			.modified = 1,
+			.channel2 = IIO_MOD_Z,
+			.info_mask = IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT |
+			IIO_CHAN_INFO_QUADRATURE_CORRECTION_RAW_SEPARATE_BIT |
+			IIO_CHAN_INFO_SCALE_SEPARATE_BIT,
+		}, {
+			.type = IIO_TEMP,
+			.indexed = 1,
+			.channel = 0,
+			.info_mask = IIO_CHAN_INFO_SCALE_SEPARATE_BIT,
+		}
+	},
+	[ID_ADXRS453] = {
+		{
+			.type = IIO_ANGL_VEL,
+			.modified = 1,
+			.channel2 = IIO_MOD_Z,
+			.info_mask = IIO_CHAN_INFO_SCALE_SEPARATE_BIT |
+			IIO_CHAN_INFO_QUADRATURE_CORRECTION_RAW_SEPARATE_BIT,
+		}, {
+			.type = IIO_TEMP,
+			.indexed = 1,
+			.channel = 0,
+			.info_mask = IIO_CHAN_INFO_SCALE_SEPARATE_BIT,
+		}
+	},
 };
 
 static const struct iio_info adxrs450_info = {
@@ -343,7 +382,8 @@
 	indio_dev->dev.parent = &spi->dev;
 	indio_dev->info = &adxrs450_info;
 	indio_dev->modes = INDIO_DIRECT_MODE;
-	indio_dev->channels = adxrs450_channels;
+	indio_dev->channels =
+		adxrs450_channels[spi_get_device_id(spi)->driver_data];
 	indio_dev->num_channels = ARRAY_SIZE(adxrs450_channels);
 	indio_dev->name = spi->dev.driver->name;
 
@@ -373,6 +413,13 @@
 	return 0;
 }
 
+static const struct spi_device_id adxrs450_id[] = {
+	{"adxrs450", ID_ADXRS450},
+	{"adxrs453", ID_ADXRS453},
+	{}
+};
+MODULE_DEVICE_TABLE(spi, adxrs450_id);
+
 static struct spi_driver adxrs450_driver = {
 	.driver = {
 		.name = "adxrs450",
@@ -380,9 +427,10 @@
 	},
 	.probe = adxrs450_probe,
 	.remove = __devexit_p(adxrs450_remove),
+	.id_table	= adxrs450_id,
 };
 module_spi_driver(adxrs450_driver);
 
 MODULE_AUTHOR("Cliff Cai <cliff.cai@xxxxxxxxxx>");
-MODULE_DESCRIPTION("Analog Devices ADXRS450 Gyroscope SPI driver");
+MODULE_DESCRIPTION("Analog Devices ADXRS450/ADXRS453 Gyroscope SPI driver");
 MODULE_LICENSE("GPL v2");
diff --git a/drivers/staging/iio/iio.h b/drivers/staging/iio/iio.h
index f3d88cd..be6ced3 100644
--- a/drivers/staging/iio/iio.h
+++ b/drivers/staging/iio/iio.h
@@ -7,13 +7,12 @@
  * under the terms of the GNU General Public License version 2 as published by
  * the Free Software Foundation.
  */
-
 #ifndef _INDUSTRIAL_IO_H_
 #define _INDUSTRIAL_IO_H_
 
 #include <linux/device.h>
 #include <linux/cdev.h>
-
+#include "types.h"
 /* IIO TODO LIST */
 /*
  * Provide means of adjusting timer accuracy.
@@ -25,62 +24,64 @@
 	IIO_PROCESSED,
 };
 
-enum iio_chan_type {
-	/* real channel types */
-	IIO_VOLTAGE,
-	IIO_CURRENT,
-	IIO_POWER,
-	IIO_ACCEL,
-	IIO_ANGL_VEL,
-	IIO_MAGN,
-	IIO_LIGHT,
-	IIO_INTENSITY,
-	IIO_PROXIMITY,
-	IIO_TEMP,
-	IIO_INCLI,
-	IIO_ROT,
-	IIO_ANGL,
-	IIO_TIMESTAMP,
-	IIO_CAPACITANCE,
-};
-
-enum iio_modifier {
-	IIO_NO_MOD,
-	IIO_MOD_X,
-	IIO_MOD_Y,
-	IIO_MOD_Z,
-	IIO_MOD_X_AND_Y,
-	IIO_MOD_X_ANX_Z,
-	IIO_MOD_Y_AND_Z,
-	IIO_MOD_X_AND_Y_AND_Z,
-	IIO_MOD_X_OR_Y,
-	IIO_MOD_X_OR_Z,
-	IIO_MOD_Y_OR_Z,
-	IIO_MOD_X_OR_Y_OR_Z,
-	IIO_MOD_LIGHT_BOTH,
-	IIO_MOD_LIGHT_IR,
-};
-
 /* Could add the raw attributes as well - allowing buffer only devices */
 enum iio_chan_info_enum {
-	IIO_CHAN_INFO_SCALE_SHARED,
-	IIO_CHAN_INFO_SCALE_SEPARATE,
-	IIO_CHAN_INFO_OFFSET_SHARED,
-	IIO_CHAN_INFO_OFFSET_SEPARATE,
-	IIO_CHAN_INFO_CALIBSCALE_SHARED,
-	IIO_CHAN_INFO_CALIBSCALE_SEPARATE,
-	IIO_CHAN_INFO_CALIBBIAS_SHARED,
-	IIO_CHAN_INFO_CALIBBIAS_SEPARATE,
-	IIO_CHAN_INFO_PEAK_SHARED,
-	IIO_CHAN_INFO_PEAK_SEPARATE,
-	IIO_CHAN_INFO_PEAK_SCALE_SHARED,
-	IIO_CHAN_INFO_PEAK_SCALE_SEPARATE,
-	IIO_CHAN_INFO_QUADRATURE_CORRECTION_RAW_SHARED,
-	IIO_CHAN_INFO_QUADRATURE_CORRECTION_RAW_SEPARATE,
-	IIO_CHAN_INFO_AVERAGE_RAW_SHARED,
-	IIO_CHAN_INFO_AVERAGE_RAW_SEPARATE,
+	/* 0 is reserverd for raw attributes */
+	IIO_CHAN_INFO_SCALE = 1,
+	IIO_CHAN_INFO_OFFSET,
+	IIO_CHAN_INFO_CALIBSCALE,
+	IIO_CHAN_INFO_CALIBBIAS,
+	IIO_CHAN_INFO_PEAK,
+	IIO_CHAN_INFO_PEAK_SCALE,
+	IIO_CHAN_INFO_QUADRATURE_CORRECTION_RAW,
+	IIO_CHAN_INFO_AVERAGE_RAW,
+	IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY,
 };
 
+#define IIO_CHAN_INFO_SHARED_BIT(type) BIT(type*2)
+#define IIO_CHAN_INFO_SEPARATE_BIT(type) BIT(type*2 + 1)
+
+#define IIO_CHAN_INFO_SCALE_SEPARATE_BIT		\
+	IIO_CHAN_INFO_SEPARATE_BIT(IIO_CHAN_INFO_SCALE)
+#define IIO_CHAN_INFO_SCALE_SHARED_BIT			\
+	IIO_CHAN_INFO_SHARED_BIT(IIO_CHAN_INFO_SCALE)
+#define IIO_CHAN_INFO_OFFSET_SEPARATE_BIT			\
+	IIO_CHAN_INFO_SEPARATE_BIT(IIO_CHAN_INFO_OFFSET)
+#define IIO_CHAN_INFO_OFFSET_SHARED_BIT			\
+	IIO_CHAN_INFO_SHARED_BIT(IIO_CHAN_INFO_OFFSET)
+#define IIO_CHAN_INFO_CALIBSCALE_SEPARATE_BIT			\
+	IIO_CHAN_INFO_SEPARATE_BIT(IIO_CHAN_INFO_CALIBSCALE)
+#define IIO_CHAN_INFO_CALIBSCALE_SHARED_BIT			\
+	IIO_CHAN_INFO_SHARED_BIT(IIO_CHAN_INFO_CALIBSCALE)
+#define IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT			\
+	IIO_CHAN_INFO_SEPARATE_BIT(IIO_CHAN_INFO_CALIBBIAS)
+#define IIO_CHAN_INFO_CALIBBIAS_SHARED_BIT			\
+	IIO_CHAN_INFO_SHARED_BIT(IIO_CHAN_INFO_CALIBBIAS)
+#define IIO_CHAN_INFO_PEAK_SEPARATE_BIT			\
+	IIO_CHAN_INFO_SEPARATE_BIT(IIO_CHAN_INFO_PEAK)
+#define IIO_CHAN_INFO_PEAK_SHARED_BIT			\
+	IIO_CHAN_INFO_SHARED_BIT(IIO_CHAN_INFO_PEAK)
+#define IIO_CHAN_INFO_PEAKSCALE_SEPARATE_BIT			\
+	IIO_CHAN_INFO_SEPARATE_BIT(IIO_CHAN_INFO_PEAKSCALE)
+#define IIO_CHAN_INFO_PEAKSCALE_SHARED_BIT			\
+	IIO_CHAN_INFO_SHARED_BIT(IIO_CHAN_INFO_PEAKSCALE)
+#define IIO_CHAN_INFO_QUADRATURE_CORRECTION_RAW_SEPARATE_BIT	\
+	IIO_CHAN_INFO_SEPARATE_BIT(				\
+		IIO_CHAN_INFO_QUADRATURE_CORRECTION_RAW)
+#define IIO_CHAN_INFO_QUADRATURE_CORRECTION_RAW_SHARED_BIT	\
+	IIO_CHAN_INFO_SHARED_BIT(				\
+		IIO_CHAN_INFO_QUADRATURE_CORRECTION_RAW)
+#define IIO_CHAN_INFO_AVERAGE_RAW_SEPARATE_BIT			\
+	IIO_CHAN_INFO_SEPARATE_BIT(IIO_CHAN_INFO_AVERAGE_RAW)
+#define IIO_CHAN_INFO_AVERAGE_RAW_SHARED_BIT			\
+	IIO_CHAN_INFO_SHARED_BIT(IIO_CHAN_INFO_AVERAGE_RAW)
+#define IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY_SHARED_BIT \
+	IIO_CHAN_INFO_SHARED_BIT(			       \
+		IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY)
+#define IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY_SEPARATE_BIT \
+	IIO_CHAN_INFO_SEPARATE_BIT(			       \
+		IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY)
+
 enum iio_endian {
 	IIO_CPU,
 	IIO_BE,
@@ -109,6 +110,10 @@
  * @extend_name:	Allows labeling of channel attributes with an
  *			informative name. Note this has no effect codes etc,
  *			unlike modifiers.
+ * @datasheet_name:	A name used in in kernel mapping of channels. It should
+ *			corrspond to the first name that the channel is referred
+ *			to by in the datasheet (e.g. IND), or the nearest
+ *			possible compound name (e.g. IND-INC).
  * @processed_val:	Flag to specify the data access attribute should be
  *			*_input rather than *_raw.
  * @modified:		Does a modifier apply to this channel. What these are
@@ -137,6 +142,7 @@
 	long			info_mask;
 	long			event_mask;
 	char			*extend_name;
+	const char		*datasheet_name;
 	unsigned		processed_val:1;
 	unsigned		modified:1;
 	unsigned		indexed:1;
@@ -261,7 +267,23 @@
 				 int val);
 	int (*validate_trigger)(struct iio_dev *indio_dev,
 				struct iio_trigger *trig);
+	int (*update_scan_mode)(struct iio_dev *indio_dev,
+				const unsigned long *scan_mask);
+};
 
+/**
+ * struct iio_buffer_setup_ops - buffer setup related callbacks
+ * @preenable:		[DRIVER] function to run prior to marking buffer enabled
+ * @postenable:		[DRIVER] function to run after marking buffer enabled
+ * @predisable:		[DRIVER] function to run prior to marking buffer
+ *			disabled
+ * @postdisable:	[DRIVER] function to run after marking buffer disabled
+ */
+struct iio_buffer_setup_ops {
+	int				(*preenable)(struct iio_dev *);
+	int				(*postenable)(struct iio_dev *);
+	int				(*predisable)(struct iio_dev *);
+	int				(*postdisable)(struct iio_dev *);
 };
 
 /**
@@ -278,6 +300,7 @@
  * @available_scan_masks: [DRIVER] optional array of allowed bitmasks
  * @masklength:		[INTERN] the length of the mask established from
  *			channels
+ * @active_scan_mask:	[INTERN] union of all scan masks requested by buffers
  * @trig:		[INTERN] current device trigger (buffer modes)
  * @pollfunc:		[DRIVER] function run on trigger being received
  * @channels:		[DRIVER] channel specification structure table
@@ -290,6 +313,7 @@
  * @chrdev:		[INTERN] associated character device
  * @groups:		[INTERN] attribute groups
  * @groupcounter:	[INTERN] index of next attribute group
+ * @flags:		[INTERN] file ops related flags including busy flag.
  **/
 struct iio_dev {
 	int				id;
@@ -305,6 +329,7 @@
 
 	unsigned long			*available_scan_masks;
 	unsigned			masklength;
+	unsigned long			*active_scan_mask;
 	struct iio_trigger		*trig;
 	struct iio_poll_func		*pollfunc;
 
@@ -315,13 +340,24 @@
 	struct attribute_group		chan_attr_group;
 	const char			*name;
 	const struct iio_info		*info;
+	const struct iio_buffer_setup_ops	*setup_ops;
 	struct cdev			chrdev;
 #define IIO_MAX_GROUPS 6
 	const struct attribute_group	*groups[IIO_MAX_GROUPS + 1];
 	int				groupcounter;
+
+	unsigned long			flags;
 };
 
 /**
+ * iio_find_channel_from_si() - get channel from its scan index
+ * @indio_dev:		device
+ * @si:			scan index to match
+ */
+const struct iio_chan_spec
+*iio_find_channel_from_si(struct iio_dev *indio_dev, int si);
+
+/**
  * iio_device_register() - register a device with the IIO subsystem
  * @indio_dev:		Device structure filled by the device driver
  **/
diff --git a/drivers/staging/iio/iio_core.h b/drivers/staging/iio/iio_core.h
index 36159e0..107cfb1 100644
--- a/drivers/staging/iio/iio_core.h
+++ b/drivers/staging/iio/iio_core.h
@@ -33,9 +33,6 @@
 #ifdef CONFIG_IIO_BUFFER
 struct poll_table_struct;
 
-int iio_chrdev_buffer_open(struct iio_dev *indio_dev);
-void iio_chrdev_buffer_release(struct iio_dev *indio_dev);
-
 unsigned int iio_buffer_poll(struct file *filp,
 			     struct poll_table_struct *wait);
 ssize_t iio_buffer_read_first_n_outer(struct file *filp, char __user *buf,
@@ -47,14 +44,6 @@
 
 #else
 
-static inline int iio_chrdev_buffer_open(struct iio_dev *indio_dev)
-{
-	return -EINVAL;
-}
-
-static inline void iio_chrdev_buffer_release(struct iio_dev *indio_dev)
-{}
-
 #define iio_buffer_poll_addr NULL
 #define iio_buffer_read_first_n_outer_addr NULL
 
diff --git a/drivers/staging/iio/iio_core_trigger.h b/drivers/staging/iio/iio_core_trigger.h
index 523c288..6f7c56f 100644
--- a/drivers/staging/iio/iio_core_trigger.h
+++ b/drivers/staging/iio/iio_core_trigger.h
@@ -13,8 +13,7 @@
  * iio_device_register_trigger_consumer() - set up an iio_dev to use triggers
  * @indio_dev: iio_dev associated with the device that will consume the trigger
  **/
-
-int iio_device_register_trigger_consumer(struct iio_dev *indio_dev);
+void iio_device_register_trigger_consumer(struct iio_dev *indio_dev);
 
 /**
  * iio_device_unregister_trigger_consumer() - reverse the registration process
diff --git a/drivers/staging/iio/iio_dummy_evgen.c b/drivers/staging/iio/iio_dummy_evgen.c
index da657d1..cdbf289 100644
--- a/drivers/staging/iio/iio_dummy_evgen.c
+++ b/drivers/staging/iio/iio_dummy_evgen.c
@@ -102,6 +102,10 @@
 int iio_dummy_evgen_get_irq(void)
 {
 	int i, ret = 0;
+
+	if (iio_evgen == NULL)
+		return -ENODEV;
+
 	mutex_lock(&iio_evgen->lock);
 	for (i = 0; i < IIO_EVENTGEN_NO; i++)
 		if (iio_evgen->inuse[i] == false) {
diff --git a/drivers/staging/iio/iio_simple_dummy.c b/drivers/staging/iio/iio_simple_dummy.c
index af0c992..e3a9457 100644
--- a/drivers/staging/iio/iio_simple_dummy.c
+++ b/drivers/staging/iio/iio_simple_dummy.c
@@ -21,7 +21,8 @@
 
 #include "iio.h"
 #include "sysfs.h"
-#include "buffer_generic.h"
+#include "events.h"
+#include "buffer.h"
 #include "iio_simple_dummy.h"
 
 /*
@@ -76,13 +77,13 @@
 		 * Offset for userspace to apply prior to scale
 		 * when converting to standard units (microvolts)
 		 */
-		(1 << IIO_CHAN_INFO_OFFSET_SEPARATE) |
+		IIO_CHAN_INFO_OFFSET_SEPARATE_BIT |
 		/*
 		 * in_voltage0_scale
 		 * Multipler for userspace to apply post offset
 		 * when converting to standard units (microvolts)
 		 */
-		(1 << IIO_CHAN_INFO_SCALE_SEPARATE),
+		IIO_CHAN_INFO_SCALE_SEPARATE_BIT,
 		/* The ordering of elements in the buffer via an enum */
 		.scan_index = voltage0,
 		.scan_type = { /* Description of storage in buffer */
@@ -117,7 +118,7 @@
 		 * Shared version of scale - shared by differential
 		 * input channels of type IIO_VOLTAGE.
 		 */
-		(1 << IIO_CHAN_INFO_SCALE_SHARED),
+		IIO_CHAN_INFO_SCALE_SHARED_BIT,
 		.scan_index = diffvoltage1m2,
 		.scan_type = { /* Description of storage in buffer */
 			.sign = 's', /* signed */
@@ -134,7 +135,7 @@
 		.channel = 3,
 		.channel2 = 4,
 		.info_mask =
-		(1 << IIO_CHAN_INFO_SCALE_SHARED),
+		IIO_CHAN_INFO_SCALE_SHARED_BIT,
 		.scan_index = diffvoltage3m4,
 		.scan_type = {
 			.sign = 's',
@@ -159,7 +160,7 @@
 		 * seeing the readings. Typically part of hardware
 		 * calibration.
 		 */
-		(1 << IIO_CHAN_INFO_CALIBBIAS_SEPARATE),
+		IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT,
 		.scan_index = accelx,
 		.scan_type = { /* Description of storage in buffer */
 			.sign = 's', /* signed */
@@ -228,29 +229,32 @@
 			break;
 		}
 		break;
-	case (1 << IIO_CHAN_INFO_OFFSET_SEPARATE):
+	case IIO_CHAN_INFO_OFFSET:
 		/* only single ended adc -> 7 */
 		*val = 7;
 		ret = IIO_VAL_INT;
 		break;
-	case (1 << IIO_CHAN_INFO_SCALE_SEPARATE):
-		/* only single ended adc -> 0.001333 */
-		*val = 0;
-		*val2 = 1333;
-		ret = IIO_VAL_INT_PLUS_MICRO;
+	case IIO_CHAN_INFO_SCALE:
+		switch (chan->differential) {
+		case 0:
+			/* only single ended adc -> 0.001333 */
+			*val = 0;
+			*val2 = 1333;
+			ret = IIO_VAL_INT_PLUS_MICRO;
+			break;
+		case 1:
+			/* all differential adc channels -> 0.000001344 */
+			*val = 0;
+			*val2 = 1344;
+			ret = IIO_VAL_INT_PLUS_NANO;
+		}
 		break;
-	case (1 << IIO_CHAN_INFO_SCALE_SHARED):
-		/* all differential adc channels -> 0.000001344 */
-		*val = 0;
-		*val2 = 1344;
-		ret = IIO_VAL_INT_PLUS_NANO;
-		break;
-	case (1 << IIO_CHAN_INFO_CALIBBIAS_SEPARATE):
+	case IIO_CHAN_INFO_CALIBBIAS:
 		/* only the acceleration axis - read from cache */
 		*val = st->accel_calibbias;
 		ret = IIO_VAL_INT;
 		break;
-	case (1 << IIO_CHAN_INFO_CALIBSCALE_SEPARATE):
+	case IIO_CHAN_INFO_CALIBSCALE:
 		*val = st->accel_calibscale->val;
 		*val2 = st->accel_calibscale->val2;
 		ret = IIO_VAL_INT_PLUS_MICRO;
@@ -295,7 +299,7 @@
 		st->dac_val = val;
 		mutex_unlock(&st->lock);
 		return 0;
-	case (1 << IIO_CHAN_INFO_CALIBBIAS_SEPARATE):
+	case IIO_CHAN_INFO_CALIBBIAS:
 		mutex_lock(&st->lock);
 		/* Compare against table - hard matching here */
 		for (i = 0; i < ARRAY_SIZE(dummy_scales); i++)
@@ -514,7 +518,8 @@
 		return -EINVAL;
 	}
 	/* Fake a bus */
-	iio_dummy_devs = kzalloc(sizeof(*iio_dummy_devs)*instances, GFP_KERNEL);
+	iio_dummy_devs = kcalloc(instances, sizeof(*iio_dummy_devs),
+				 GFP_KERNEL);
 	/* Here we have no actual device so call probe */
 	for (i = 0; i < instances; i++) {
 		ret = iio_dummy_probe(i);
diff --git a/drivers/staging/iio/iio_simple_dummy_buffer.c b/drivers/staging/iio/iio_simple_dummy_buffer.c
index edad0e7..d6a1c0e 100644
--- a/drivers/staging/iio/iio_simple_dummy_buffer.c
+++ b/drivers/staging/iio/iio_simple_dummy_buffer.c
@@ -57,7 +57,7 @@
 	if (data == NULL)
 		return -ENOMEM;
 
-	if (buffer->scan_count) {
+	if (!bitmap_empty(indio_dev->active_scan_mask, indio_dev->masklength)) {
 		/*
 		 * Three common options here:
 		 * hardware scans: certain combinations of channels make
@@ -75,7 +75,10 @@
 		 * in the constant table fakedata.
 		 */
 		int i, j;
-		for (i = 0, j = 0; i < buffer->scan_count; i++) {
+		for (i = 0, j = 0;
+		     i < bitmap_weight(indio_dev->active_scan_mask,
+				       indio_dev->masklength);
+		     i++) {
 			j = find_next_bit(buffer->scan_mask,
 					  indio_dev->masklength, j + 1);
 			/* random access read form the 'device' */
@@ -142,8 +145,6 @@
 	/* Tell the core how to access the buffer */
 	buffer->access = &kfifo_access_funcs;
 
-	/* Number of bytes per element */
-	buffer->bpe = 2;
 	/* Enable timestamps by default */
 	buffer->scan_timestamp = true;
 
@@ -151,8 +152,7 @@
 	 * Tell the core what device type specific functions should
 	 * be run on either side of buffer capture enable / disable.
 	 */
-	buffer->setup_ops = &iio_simple_dummy_buffer_setup_ops;
-	buffer->owner = THIS_MODULE;
+	indio_dev->setup_ops = &iio_simple_dummy_buffer_setup_ops;
 
 	/*
 	 * Configure a polling function.
diff --git a/drivers/staging/iio/iio_simple_dummy_events.c b/drivers/staging/iio/iio_simple_dummy_events.c
index 9f00cff..449c7a5 100644
--- a/drivers/staging/iio/iio_simple_dummy_events.c
+++ b/drivers/staging/iio/iio_simple_dummy_events.c
@@ -14,6 +14,7 @@
 
 #include "iio.h"
 #include "sysfs.h"
+#include "events.h"
 #include "iio_simple_dummy.h"
 
 /* Evgen 'fakes' interrupt events for this example */
diff --git a/drivers/staging/iio/impedance-analyzer/ad5933.c b/drivers/staging/iio/impedance-analyzer/ad5933.c
index 454d131..9a2ca55 100644
--- a/drivers/staging/iio/impedance-analyzer/ad5933.c
+++ b/drivers/staging/iio/impedance-analyzer/ad5933.c
@@ -21,7 +21,7 @@
 
 #include "../iio.h"
 #include "../sysfs.h"
-#include "../buffer_generic.h"
+#include "../buffer.h"
 #include "../ring_sw.h"
 
 #include "ad5933.h"
@@ -113,10 +113,10 @@
 		 0, AD5933_REG_TEMP_DATA, IIO_ST('s', 14, 16, 0), 0),
 	/* Ring Channels */
 	IIO_CHAN(IIO_VOLTAGE, 0, 1, 0, "real_raw", 0, 0,
-		 (1 << IIO_CHAN_INFO_SCALE_SEPARATE),
+		 IIO_CHAN_INFO_SCALE_SEPARATE_BIT,
 		 AD5933_REG_REAL_DATA, 0, IIO_ST('s', 16, 16, 0), 0),
 	IIO_CHAN(IIO_VOLTAGE, 0, 1, 0, "imag_raw", 0, 0,
-		 (1 << IIO_CHAN_INFO_SCALE_SEPARATE),
+		 IIO_CHAN_INFO_SCALE_SEPARATE_BIT,
 		 AD5933_REG_IMAG_DATA, 1, IIO_ST('s', 16, 16, 0), 0),
 };
 
@@ -329,7 +329,7 @@
 	int ret = 0, len = 0;
 
 	mutex_lock(&indio_dev->mlock);
-	switch (this_attr->address) {
+	switch ((u32) this_attr->address) {
 	case AD5933_OUT_RANGE:
 		len = sprintf(buf, "%d\n",
 			      st->range_avail[(st->ctrl_hb >> 1) & 0x3]);
@@ -380,7 +380,7 @@
 	}
 
 	mutex_lock(&indio_dev->mlock);
-	switch (this_attr->address) {
+	switch ((u32) this_attr->address) {
 	case AD5933_OUT_RANGE:
 		for (i = 0; i < 4; i++)
 			if (val == st->range_avail[i]) {
@@ -537,14 +537,14 @@
 static int ad5933_ring_preenable(struct iio_dev *indio_dev)
 {
 	struct ad5933_state *st = iio_priv(indio_dev);
-	struct iio_buffer *ring = indio_dev->buffer;
 	size_t d_size;
 	int ret;
 
-	if (!ring->scan_count)
+	if (bitmap_empty(indio_dev->active_scan_mask, indio_dev->masklength))
 		return -EINVAL;
 
-	d_size = ring->scan_count *
+	d_size = bitmap_weight(indio_dev->active_scan_mask,
+			       indio_dev->masklength) *
 		 ad5933_channels[1].scan_type.storagebits / 8;
 
 	if (indio_dev->buffer->access->set_bytes_per_datum)
@@ -611,7 +611,7 @@
 	indio_dev->buffer->access = &ring_sw_access_funcs;
 
 	/* Ring buffer functions - here trigger setup related */
-	indio_dev->buffer->setup_ops = &ad5933_ring_setup_ops;
+	indio_dev->setup_ops = &ad5933_ring_setup_ops;
 
 	indio_dev->modes |= INDIO_BUFFER_HARDWARE;
 
@@ -640,12 +640,14 @@
 	ad5933_i2c_read(st->client, AD5933_REG_STATUS, 1, &status);
 
 	if (status & AD5933_STAT_DATA_VALID) {
+		int scan_count = bitmap_weight(indio_dev->active_scan_mask,
+					       indio_dev->masklength);
 		ad5933_i2c_read(st->client,
-				test_bit(1, ring->scan_mask) ?
+				test_bit(1, indio_dev->active_scan_mask) ?
 				AD5933_REG_REAL_DATA : AD5933_REG_IMAG_DATA,
-				ring->scan_count * 2, (u8 *)buf);
+				scan_count * 2, (u8 *)buf);
 
-		if (ring->scan_count == 2) {
+		if (scan_count == 2) {
 			buf[0] = be16_to_cpu(buf[0]);
 			buf[1] = be16_to_cpu(buf[1]);
 		} else {
@@ -734,8 +736,8 @@
 		goto error_unreg_ring;
 
 	/* enable both REAL and IMAG channels by default */
-	iio_scan_mask_set(indio_dev->buffer, 0);
-	iio_scan_mask_set(indio_dev->buffer, 1);
+	iio_scan_mask_set(indio_dev, indio_dev->buffer, 0);
+	iio_scan_mask_set(indio_dev, indio_dev->buffer, 1);
 
 	ret = ad5933_setup(st);
 	if (ret)
diff --git a/drivers/staging/iio/imu/adis16400.h b/drivers/staging/iio/imu/adis16400.h
index f3546ee..83d133e 100644
--- a/drivers/staging/iio/imu/adis16400.h
+++ b/drivers/staging/iio/imu/adis16400.h
@@ -148,12 +148,14 @@
  * @tx:			transmit buffer
  * @rx:			receive buffer
  * @buf_lock:		mutex to protect tx and rx
+ * @filt_int:		integer part of requested filter frequency
  **/
 struct adis16400_state {
 	struct spi_device		*us;
 	struct iio_trigger		*trig;
 	struct mutex			buf_lock;
 	struct adis16400_chip_info	*variant;
+	int				filt_int;
 
 	u8	tx[ADIS16400_MAX_TX] ____cacheline_aligned;
 	u8	rx[ADIS16400_MAX_RX] ____cacheline_aligned;
diff --git a/drivers/staging/iio/imu/adis16400_core.c b/drivers/staging/iio/imu/adis16400_core.c
index efc0f65..e73ad78 100644
--- a/drivers/staging/iio/imu/adis16400_core.c
+++ b/drivers/staging/iio/imu/adis16400_core.c
@@ -28,7 +28,7 @@
 
 #include "../iio.h"
 #include "../sysfs.h"
-#include "../buffer_generic.h"
+#include "../buffer.h"
 #include "adis16400.h"
 
 enum adis16400_chip_variant {
@@ -161,25 +161,65 @@
 	return ret;
 }
 
+static int adis16400_get_freq(struct iio_dev *indio_dev)
+{
+	u16 t;
+	int sps, ret;
+
+	ret = adis16400_spi_read_reg_16(indio_dev, ADIS16400_SMPL_PRD, &t);
+	if (ret < 0)
+		return ret;
+	sps =  (t & ADIS16400_SMPL_PRD_TIME_BASE) ? 53 : 1638;
+	sps /= (t & ADIS16400_SMPL_PRD_DIV_MASK) + 1;
+
+	return sps;
+}
+
 static ssize_t adis16400_read_frequency(struct device *dev,
 		struct device_attribute *attr,
 		char *buf)
 {
 	struct iio_dev *indio_dev = dev_get_drvdata(dev);
 	int ret, len = 0;
-	u16 t;
-	int sps;
-	ret = adis16400_spi_read_reg_16(indio_dev,
-			ADIS16400_SMPL_PRD,
-			&t);
-	if (ret)
+	ret = adis16400_get_freq(indio_dev);
+	if (ret < 0)
 		return ret;
-	sps =  (t & ADIS16400_SMPL_PRD_TIME_BASE) ? 53 : 1638;
-	sps /= (t & ADIS16400_SMPL_PRD_DIV_MASK) + 1;
-	len = sprintf(buf, "%d SPS\n", sps);
+	len = sprintf(buf, "%d SPS\n", ret);
 	return len;
 }
 
+static const unsigned adis16400_3db_divisors[] = {
+	[0] = 2, /* Special case */
+	[1] = 5,
+	[2] = 10,
+	[3] = 50,
+	[4] = 200,
+};
+
+static int adis16400_set_filter(struct iio_dev *indio_dev, int sps, int val)
+{
+	int i, ret;
+	u16 val16;
+	for (i = ARRAY_SIZE(adis16400_3db_divisors) - 1; i >= 0; i--)
+		if (sps/adis16400_3db_divisors[i] > val)
+			break;
+	if (i == -1)
+		ret = -EINVAL;
+	else {
+		ret = adis16400_spi_read_reg_16(indio_dev,
+						ADIS16400_SENS_AVG,
+						&val16);
+		if (ret < 0)
+			goto error_ret;
+
+		ret = adis16400_spi_write_reg_16(indio_dev,
+						 ADIS16400_SENS_AVG,
+						 (val16 & ~0x03) | i);
+	}
+error_ret:
+	return ret;
+}
+
 static ssize_t adis16400_write_frequency(struct device *dev,
 		struct device_attribute *attr,
 		const char *buf,
@@ -210,6 +250,7 @@
 			ADIS16400_SMPL_PRD,
 			t);
 
+	/* Also update the filter */
 	mutex_unlock(&indio_dev->mlock);
 
 	return ret ? ret : len;
@@ -455,22 +496,39 @@
 	[incli_y] = { ADIS16300_ROLL_OUT }
 };
 
+
 static int adis16400_write_raw(struct iio_dev *indio_dev,
 			       struct iio_chan_spec const *chan,
 			       int val,
 			       int val2,
 			       long mask)
 {
-	int ret;
+	struct adis16400_state *st = iio_priv(indio_dev);
+	int ret, sps;
 
 	switch (mask) {
-	case (1 << IIO_CHAN_INFO_CALIBBIAS_SEPARATE):
+	case IIO_CHAN_INFO_CALIBBIAS:
 		mutex_lock(&indio_dev->mlock);
 		ret = adis16400_spi_write_reg_16(indio_dev,
 				adis16400_addresses[chan->address][1],
 				val);
 		mutex_unlock(&indio_dev->mlock);
 		return ret;
+	case IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY:
+		/* Need to cache values so we can update if the frequency
+		   changes */
+		mutex_lock(&indio_dev->mlock);
+		st->filt_int = val;
+		/* Work out update to current value */
+		sps = adis16400_get_freq(indio_dev);
+		if (sps < 0) {
+			mutex_unlock(&indio_dev->mlock);
+			return sps;
+		}
+
+		ret = adis16400_set_filter(indio_dev, sps, val);
+		mutex_unlock(&indio_dev->mlock);
+		return ret;
 	default:
 		return -EINVAL;
 	}
@@ -504,8 +562,7 @@
 		*val = val16;
 		mutex_unlock(&indio_dev->mlock);
 		return IIO_VAL_INT;
-	case (1 << IIO_CHAN_INFO_SCALE_SHARED):
-	case (1 << IIO_CHAN_INFO_SCALE_SEPARATE):
+	case IIO_CHAN_INFO_SCALE:
 		switch (chan->type) {
 		case IIO_ANGL_VEL:
 			*val = 0;
@@ -533,7 +590,7 @@
 		default:
 			return -EINVAL;
 		}
-	case (1 << IIO_CHAN_INFO_CALIBBIAS_SEPARATE):
+	case IIO_CHAN_INFO_CALIBBIAS:
 		mutex_lock(&indio_dev->mlock);
 		ret = adis16400_spi_read_reg_16(indio_dev,
 				adis16400_addresses[chan->address][1],
@@ -544,11 +601,29 @@
 		val16 = ((val16 & 0xFFF) << 4) >> 4;
 		*val = val16;
 		return IIO_VAL_INT;
-	case (1 << IIO_CHAN_INFO_OFFSET_SEPARATE):
+	case IIO_CHAN_INFO_OFFSET:
 		/* currently only temperature */
 		*val = 198;
 		*val2 = 160000;
 		return IIO_VAL_INT_PLUS_MICRO;
+	case IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY:
+		mutex_lock(&indio_dev->mlock);
+		/* Need both the number of taps and the sampling frequency */
+		ret = adis16400_spi_read_reg_16(indio_dev,
+						ADIS16400_SENS_AVG,
+						&val16);
+		if (ret < 0) {
+			mutex_unlock(&indio_dev->mlock);
+			return ret;
+		}
+		ret = adis16400_get_freq(indio_dev);
+		if (ret > 0)
+			*val = ret/adis16400_3db_divisors[val16 & 0x03];
+		*val2 = 0;
+		mutex_unlock(&indio_dev->mlock);
+		if (ret < 0)
+			return ret;
+		return IIO_VAL_INT_PLUS_MICRO;
 	default:
 		return -EINVAL;
 	}
@@ -560,7 +635,7 @@
 		.indexed = 1,
 		.channel = 0,
 		.extend_name = "supply",
-		.info_mask = (1 << IIO_CHAN_INFO_SCALE_SEPARATE),
+		.info_mask = IIO_CHAN_INFO_SCALE_SEPARATE_BIT,
 		.address = in_supply,
 		.scan_index = ADIS16400_SCAN_SUPPLY,
 		.scan_type = IIO_ST('u', 14, 16, 0)
@@ -568,8 +643,9 @@
 		.type = IIO_ANGL_VEL,
 		.modified = 1,
 		.channel2 = IIO_MOD_X,
-		.info_mask = (1 << IIO_CHAN_INFO_CALIBBIAS_SEPARATE) |
-		(1 << IIO_CHAN_INFO_SCALE_SHARED),
+		.info_mask = IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT |
+		IIO_CHAN_INFO_SCALE_SHARED_BIT |
+		IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY_SHARED_BIT,
 		.address = gyro_x,
 		.scan_index = ADIS16400_SCAN_GYRO_X,
 		.scan_type = IIO_ST('s', 14, 16, 0)
@@ -577,8 +653,9 @@
 		.type = IIO_ANGL_VEL,
 		.modified = 1,
 		.channel2 = IIO_MOD_Y,
-		.info_mask = (1 << IIO_CHAN_INFO_CALIBBIAS_SEPARATE) |
-		(1 << IIO_CHAN_INFO_SCALE_SHARED),
+		.info_mask = IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT |
+		IIO_CHAN_INFO_SCALE_SHARED_BIT |
+		IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY_SHARED_BIT,
 		.address = gyro_y,
 		.scan_index = ADIS16400_SCAN_GYRO_Y,
 		.scan_type = IIO_ST('s', 14, 16, 0),
@@ -586,8 +663,9 @@
 		.type = IIO_ANGL_VEL,
 		.modified = 1,
 		.channel2 = IIO_MOD_Z,
-		.info_mask = (1 << IIO_CHAN_INFO_CALIBBIAS_SEPARATE) |
-		(1 << IIO_CHAN_INFO_SCALE_SHARED),
+		.info_mask = IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT |
+		IIO_CHAN_INFO_SCALE_SHARED_BIT |
+		IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY_SHARED_BIT,
 		.address = gyro_z,
 		.scan_index = ADIS16400_SCAN_GYRO_Z,
 		.scan_type = IIO_ST('s', 14, 16, 0),
@@ -595,8 +673,9 @@
 		.type = IIO_ACCEL,
 		.modified = 1,
 		.channel2 = IIO_MOD_X,
-		.info_mask = (1 << IIO_CHAN_INFO_CALIBBIAS_SEPARATE) |
-		(1 << IIO_CHAN_INFO_SCALE_SHARED),
+		.info_mask = IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT |
+		IIO_CHAN_INFO_SCALE_SHARED_BIT |
+		IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY_SHARED_BIT,
 		.address = accel_x,
 		.scan_index = ADIS16400_SCAN_ACC_X,
 		.scan_type = IIO_ST('s', 14, 16, 0),
@@ -604,8 +683,9 @@
 		.type = IIO_ACCEL,
 		.modified = 1,
 		.channel2 = IIO_MOD_Y,
-		.info_mask = (1 << IIO_CHAN_INFO_CALIBBIAS_SEPARATE) |
-		(1 << IIO_CHAN_INFO_SCALE_SHARED),
+		.info_mask = IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT |
+		IIO_CHAN_INFO_SCALE_SHARED_BIT |
+		IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY_SHARED_BIT,
 		.address = accel_y,
 		.scan_index = ADIS16400_SCAN_ACC_Y,
 		.scan_type = IIO_ST('s', 14, 16, 0),
@@ -613,8 +693,9 @@
 		.type = IIO_ACCEL,
 		.modified = 1,
 		.channel2 = IIO_MOD_Z,
-		.info_mask = (1 << IIO_CHAN_INFO_CALIBBIAS_SEPARATE) |
-		(1 << IIO_CHAN_INFO_SCALE_SHARED),
+		.info_mask = IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT |
+		IIO_CHAN_INFO_SCALE_SHARED_BIT |
+		IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY_SHARED_BIT,
 		.address = accel_z,
 		.scan_index = ADIS16400_SCAN_ACC_Z,
 		.scan_type = IIO_ST('s', 14, 16, 0),
@@ -622,7 +703,8 @@
 		.type = IIO_MAGN,
 		.modified = 1,
 		.channel2 = IIO_MOD_X,
-		.info_mask = (1 << IIO_CHAN_INFO_SCALE_SHARED),
+		.info_mask = IIO_CHAN_INFO_SCALE_SHARED_BIT |
+		IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY_SHARED_BIT,
 		.address = magn_x,
 		.scan_index = ADIS16400_SCAN_MAGN_X,
 		.scan_type = IIO_ST('s', 14, 16, 0),
@@ -630,7 +712,8 @@
 		.type = IIO_MAGN,
 		.modified = 1,
 		.channel2 = IIO_MOD_Y,
-		.info_mask = (1 << IIO_CHAN_INFO_SCALE_SHARED),
+		.info_mask = IIO_CHAN_INFO_SCALE_SHARED_BIT |
+		IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY_SHARED_BIT,
 		.address = magn_y,
 		.scan_index = ADIS16400_SCAN_MAGN_Y,
 		.scan_type = IIO_ST('s', 14, 16, 0),
@@ -638,7 +721,8 @@
 		.type = IIO_MAGN,
 		.modified = 1,
 		.channel2 = IIO_MOD_Z,
-		.info_mask = (1 << IIO_CHAN_INFO_SCALE_SHARED),
+		.info_mask = IIO_CHAN_INFO_SCALE_SHARED_BIT |
+		IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY_SHARED_BIT,
 		.address = magn_z,
 		.scan_index = ADIS16400_SCAN_MAGN_Z,
 		.scan_type = IIO_ST('s', 14, 16, 0),
@@ -646,8 +730,8 @@
 		.type = IIO_TEMP,
 		.indexed = 1,
 		.channel = 0,
-		.info_mask = (1 << IIO_CHAN_INFO_OFFSET_SEPARATE) |
-		(1 << IIO_CHAN_INFO_SCALE_SEPARATE),
+		.info_mask = IIO_CHAN_INFO_OFFSET_SEPARATE_BIT |
+		IIO_CHAN_INFO_SCALE_SEPARATE_BIT,
 		.address = temp,
 		.scan_index = ADIS16400_SCAN_TEMP,
 		.scan_type = IIO_ST('s', 12, 16, 0),
@@ -655,7 +739,7 @@
 		.type = IIO_VOLTAGE,
 		.indexed = 1,
 		.channel = 1,
-		.info_mask = (1 << IIO_CHAN_INFO_SCALE_SEPARATE),
+		.info_mask = IIO_CHAN_INFO_SCALE_SEPARATE_BIT,
 		.address = in1,
 		.scan_index = ADIS16400_SCAN_ADC_0,
 		.scan_type = IIO_ST('s', 12, 16, 0),
@@ -669,7 +753,7 @@
 		.indexed = 1,
 		.channel = 0,
 		.extend_name = "supply",
-		.info_mask = (1 << IIO_CHAN_INFO_SCALE_SEPARATE),
+		.info_mask = IIO_CHAN_INFO_SCALE_SEPARATE_BIT,
 		.address = in_supply,
 		.scan_index = ADIS16400_SCAN_SUPPLY,
 		.scan_type = IIO_ST('u', 12, 16, 0)
@@ -677,8 +761,9 @@
 		.type = IIO_ANGL_VEL,
 		.modified = 1,
 		.channel2 = IIO_MOD_X,
-		.info_mask = (1 << IIO_CHAN_INFO_CALIBBIAS_SEPARATE) |
-		(1 << IIO_CHAN_INFO_SCALE_SHARED),
+		.info_mask = IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT |
+		IIO_CHAN_INFO_SCALE_SHARED_BIT |
+		IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY_SHARED_BIT,
 		.address = gyro_x,
 		.scan_index = ADIS16400_SCAN_GYRO_X,
 		.scan_type = IIO_ST('s', 14, 16, 0)
@@ -686,8 +771,9 @@
 		.type = IIO_ANGL_VEL,
 		.modified = 1,
 		.channel2 = IIO_MOD_Y,
-		.info_mask = (1 << IIO_CHAN_INFO_CALIBBIAS_SEPARATE) |
-		(1 << IIO_CHAN_INFO_SCALE_SHARED),
+		.info_mask = IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT |
+		IIO_CHAN_INFO_SCALE_SHARED_BIT |
+		IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY_SHARED_BIT,
 		.address = gyro_y,
 		.scan_index = ADIS16400_SCAN_GYRO_Y,
 		.scan_type = IIO_ST('s', 14, 16, 0),
@@ -695,8 +781,9 @@
 		.type = IIO_ANGL_VEL,
 		.modified = 1,
 		.channel2 = IIO_MOD_Z,
-		.info_mask = (1 << IIO_CHAN_INFO_CALIBBIAS_SEPARATE) |
-		(1 << IIO_CHAN_INFO_SCALE_SHARED),
+		.info_mask = IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT |
+		IIO_CHAN_INFO_SCALE_SHARED_BIT |
+		IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY_SHARED_BIT,
 		.address = gyro_z,
 		.scan_index = ADIS16400_SCAN_GYRO_Z,
 		.scan_type = IIO_ST('s', 14, 16, 0),
@@ -704,8 +791,9 @@
 	.type = IIO_ACCEL,
 		.modified = 1,
 		.channel2 = IIO_MOD_X,
-		.info_mask = (1 << IIO_CHAN_INFO_CALIBBIAS_SEPARATE) |
-		(1 << IIO_CHAN_INFO_SCALE_SHARED),
+		.info_mask = IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT |
+		IIO_CHAN_INFO_SCALE_SHARED_BIT |
+		IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY_SHARED_BIT,
 		.address = accel_x,
 		.scan_index = ADIS16400_SCAN_ACC_X,
 		.scan_type = IIO_ST('s', 14, 16, 0),
@@ -713,8 +801,9 @@
 		.type = IIO_ACCEL,
 		.modified = 1,
 		.channel2 = IIO_MOD_Y,
-		.info_mask = (1 << IIO_CHAN_INFO_CALIBBIAS_SEPARATE) |
-		(1 << IIO_CHAN_INFO_SCALE_SHARED),
+		.info_mask = IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT |
+		IIO_CHAN_INFO_SCALE_SHARED_BIT |
+		IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY_SHARED_BIT,
 		.address = accel_y,
 		.scan_index = ADIS16400_SCAN_ACC_Y,
 		.scan_type = IIO_ST('s', 14, 16, 0),
@@ -722,8 +811,9 @@
 		.type = IIO_ACCEL,
 		.modified = 1,
 		.channel2 = IIO_MOD_Z,
-		.info_mask = (1 << IIO_CHAN_INFO_CALIBBIAS_SEPARATE) |
-		(1 << IIO_CHAN_INFO_SCALE_SHARED),
+		.info_mask = IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT |
+		IIO_CHAN_INFO_SCALE_SHARED_BIT |
+		IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY_SHARED_BIT,
 		.address = accel_z,
 		.scan_index = ADIS16400_SCAN_ACC_Z,
 		.scan_type = IIO_ST('s', 14, 16, 0),
@@ -732,8 +822,9 @@
 		.indexed = 1,
 		.channel = 0,
 		.extend_name = "x",
-		.info_mask = (1 << IIO_CHAN_INFO_OFFSET_SEPARATE) |
-		(1 << IIO_CHAN_INFO_SCALE_SEPARATE),
+		.info_mask = IIO_CHAN_INFO_OFFSET_SEPARATE_BIT |
+		IIO_CHAN_INFO_SCALE_SEPARATE_BIT |
+		IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY_SHARED_BIT,
 		.address = temp0,
 		.scan_index = ADIS16350_SCAN_TEMP_X,
 		.scan_type = IIO_ST('s', 12, 16, 0),
@@ -742,8 +833,9 @@
 		.indexed = 1,
 		.channel = 1,
 		.extend_name = "y",
-		.info_mask = (1 << IIO_CHAN_INFO_OFFSET_SEPARATE) |
-		(1 << IIO_CHAN_INFO_SCALE_SEPARATE),
+		.info_mask = IIO_CHAN_INFO_OFFSET_SEPARATE_BIT |
+		IIO_CHAN_INFO_SCALE_SEPARATE_BIT |
+		IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY_SHARED_BIT,
 		.address = temp1,
 		.scan_index = ADIS16350_SCAN_TEMP_Y,
 		.scan_type = IIO_ST('s', 12, 16, 0),
@@ -752,8 +844,8 @@
 		.indexed = 1,
 		.channel = 2,
 		.extend_name = "z",
-		.info_mask = (1 << IIO_CHAN_INFO_OFFSET_SEPARATE) |
-		(1 << IIO_CHAN_INFO_SCALE_SEPARATE),
+		.info_mask = IIO_CHAN_INFO_OFFSET_SEPARATE_BIT |
+		IIO_CHAN_INFO_SCALE_SEPARATE_BIT,
 		.address = temp2,
 		.scan_index = ADIS16350_SCAN_TEMP_Z,
 		.scan_type = IIO_ST('s', 12, 16, 0),
@@ -761,7 +853,7 @@
 		.type = IIO_VOLTAGE,
 		.indexed = 1,
 		.channel = 1,
-		.info_mask = (1 << IIO_CHAN_INFO_SCALE_SEPARATE),
+		.info_mask = IIO_CHAN_INFO_SCALE_SEPARATE_BIT,
 		.address = in1,
 		.scan_index = ADIS16350_SCAN_ADC_0,
 		.scan_type = IIO_ST('s', 12, 16, 0),
@@ -775,7 +867,7 @@
 		.indexed = 1,
 		.channel = 0,
 		.extend_name = "supply",
-		.info_mask = (1 << IIO_CHAN_INFO_SCALE_SEPARATE),
+		.info_mask = IIO_CHAN_INFO_SCALE_SEPARATE_BIT,
 		.address = in_supply,
 		.scan_index = ADIS16400_SCAN_SUPPLY,
 		.scan_type = IIO_ST('u', 12, 16, 0)
@@ -783,8 +875,9 @@
 		.type = IIO_ANGL_VEL,
 		.modified = 1,
 		.channel2 = IIO_MOD_X,
-		.info_mask = (1 << IIO_CHAN_INFO_CALIBBIAS_SEPARATE) |
-		(1 << IIO_CHAN_INFO_SCALE_SHARED),
+		.info_mask = IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT |
+		IIO_CHAN_INFO_SCALE_SHARED_BIT |
+		IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY_SHARED_BIT,
 		.address = gyro_x,
 		.scan_index = ADIS16400_SCAN_GYRO_X,
 		.scan_type = IIO_ST('s', 14, 16, 0),
@@ -792,8 +885,9 @@
 		.type = IIO_ACCEL,
 		.modified = 1,
 		.channel2 = IIO_MOD_X,
-		.info_mask = (1 << IIO_CHAN_INFO_CALIBBIAS_SEPARATE) |
-		(1 << IIO_CHAN_INFO_SCALE_SHARED),
+		.info_mask = IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT |
+		IIO_CHAN_INFO_SCALE_SHARED_BIT |
+		IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY_SHARED_BIT,
 		.address = accel_x,
 		.scan_index = ADIS16400_SCAN_ACC_X,
 		.scan_type = IIO_ST('s', 14, 16, 0),
@@ -801,8 +895,9 @@
 		.type = IIO_ACCEL,
 		.modified = 1,
 		.channel2 = IIO_MOD_Y,
-		.info_mask = (1 << IIO_CHAN_INFO_CALIBBIAS_SEPARATE) |
-		(1 << IIO_CHAN_INFO_SCALE_SHARED),
+		.info_mask = IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT |
+		IIO_CHAN_INFO_SCALE_SHARED_BIT |
+		IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY_SHARED_BIT,
 		.address = accel_y,
 		.scan_index = ADIS16400_SCAN_ACC_Y,
 		.scan_type = IIO_ST('s', 14, 16, 0),
@@ -810,8 +905,9 @@
 		.type = IIO_ACCEL,
 		.modified = 1,
 		.channel2 = IIO_MOD_Z,
-		.info_mask = (1 << IIO_CHAN_INFO_CALIBBIAS_SEPARATE) |
-		(1 << IIO_CHAN_INFO_SCALE_SHARED),
+		.info_mask = IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT |
+		IIO_CHAN_INFO_SCALE_SHARED_BIT |
+		IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY_SHARED_BIT,
 		.address = accel_z,
 		.scan_index = ADIS16400_SCAN_ACC_Z,
 		.scan_type = IIO_ST('s', 14, 16, 0),
@@ -819,8 +915,8 @@
 		.type = IIO_TEMP,
 		.indexed = 1,
 		.channel = 0,
-		.info_mask = (1 << IIO_CHAN_INFO_OFFSET_SEPARATE) |
-		(1 << IIO_CHAN_INFO_SCALE_SEPARATE),
+		.info_mask = IIO_CHAN_INFO_OFFSET_SEPARATE_BIT |
+		IIO_CHAN_INFO_SCALE_SEPARATE_BIT,
 		.address = temp,
 		.scan_index = ADIS16400_SCAN_TEMP,
 		.scan_type = IIO_ST('s', 12, 16, 0),
@@ -828,7 +924,7 @@
 		.type = IIO_VOLTAGE,
 		.indexed = 1,
 		.channel = 1,
-		.info_mask = (1 << IIO_CHAN_INFO_SCALE_SEPARATE),
+		.info_mask = IIO_CHAN_INFO_SCALE_SEPARATE_BIT,
 		.address = in1,
 		.scan_index = ADIS16350_SCAN_ADC_0,
 		.scan_type = IIO_ST('s', 12, 16, 0),
@@ -836,7 +932,7 @@
 		.type = IIO_INCLI,
 		.modified = 1,
 		.channel2 = IIO_MOD_X,
-		.info_mask = (1 << IIO_CHAN_INFO_SCALE_SHARED),
+		.info_mask = IIO_CHAN_INFO_SCALE_SHARED_BIT,
 		.address = incli_x,
 		.scan_index = ADIS16300_SCAN_INCLI_X,
 		.scan_type = IIO_ST('s', 13, 16, 0),
@@ -844,7 +940,7 @@
 		.type = IIO_INCLI,
 		.modified = 1,
 		.channel2 = IIO_MOD_Y,
-		.info_mask = (1 << IIO_CHAN_INFO_SCALE_SHARED),
+		.info_mask = IIO_CHAN_INFO_SCALE_SHARED_BIT,
 		.address = incli_y,
 		.scan_index = ADIS16300_SCAN_INCLI_Y,
 		.scan_type = IIO_ST('s', 13, 16, 0),
@@ -857,8 +953,9 @@
 		.type = IIO_ANGL_VEL,
 		.modified = 1,
 		.channel2 = IIO_MOD_X,
-		.info_mask = (1 << IIO_CHAN_INFO_CALIBBIAS_SEPARATE) |
-		(1 << IIO_CHAN_INFO_SCALE_SHARED),
+		.info_mask = IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT |
+		IIO_CHAN_INFO_SCALE_SHARED_BIT |
+		IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY_SHARED_BIT,
 		.address = gyro_x,
 		.scan_index = ADIS16400_SCAN_GYRO_X,
 		.scan_type = IIO_ST('s', 14, 16, 0),
@@ -866,8 +963,9 @@
 		.type = IIO_ANGL_VEL,
 		.modified = 1,
 		.channel2 = IIO_MOD_Y,
-		.info_mask = (1 << IIO_CHAN_INFO_CALIBBIAS_SEPARATE) |
-		(1 << IIO_CHAN_INFO_SCALE_SHARED),
+		.info_mask = IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT |
+		IIO_CHAN_INFO_SCALE_SHARED_BIT |
+		IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY_SHARED_BIT,
 		.address = gyro_y,
 		.scan_index = ADIS16400_SCAN_GYRO_Y,
 		.scan_type = IIO_ST('s', 14, 16, 0),
@@ -875,8 +973,9 @@
 		.type = IIO_ANGL_VEL,
 		.modified = 1,
 		.channel2 = IIO_MOD_Z,
-		.info_mask = (1 << IIO_CHAN_INFO_CALIBBIAS_SEPARATE) |
-		(1 << IIO_CHAN_INFO_SCALE_SHARED),
+		.info_mask = IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT |
+		IIO_CHAN_INFO_SCALE_SHARED_BIT |
+		IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY_SHARED_BIT,
 		.address = gyro_z,
 		.scan_index = ADIS16400_SCAN_GYRO_Z,
 		.scan_type = IIO_ST('s', 14, 16, 0),
@@ -884,8 +983,9 @@
 		.type = IIO_ACCEL,
 		.modified = 1,
 		.channel2 = IIO_MOD_X,
-		.info_mask = (1 << IIO_CHAN_INFO_CALIBBIAS_SEPARATE) |
-		(1 << IIO_CHAN_INFO_SCALE_SHARED),
+		.info_mask = IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT |
+		IIO_CHAN_INFO_SCALE_SHARED_BIT |
+		IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY_SHARED_BIT,
 		.address = accel_x,
 		.scan_index = ADIS16400_SCAN_ACC_X,
 		.scan_type = IIO_ST('s', 14, 16, 0),
@@ -893,8 +993,9 @@
 		.type = IIO_ACCEL,
 		.modified = 1,
 		.channel2 = IIO_MOD_Y,
-		.info_mask = (1 << IIO_CHAN_INFO_CALIBBIAS_SEPARATE) |
-		(1 << IIO_CHAN_INFO_SCALE_SHARED),
+		.info_mask = IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT |
+		IIO_CHAN_INFO_SCALE_SHARED_BIT |
+		IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY_SHARED_BIT,
 		.address = accel_y,
 		.scan_index = ADIS16400_SCAN_ACC_Y,
 		.scan_type = IIO_ST('s', 14, 16, 0),
@@ -902,8 +1003,9 @@
 		.type = IIO_ACCEL,
 		.modified = 1,
 		.channel2 = IIO_MOD_Z,
-		.info_mask = (1 << IIO_CHAN_INFO_CALIBBIAS_SEPARATE) |
-		(1 << IIO_CHAN_INFO_SCALE_SHARED),
+		.info_mask = IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT |
+		IIO_CHAN_INFO_SCALE_SHARED_BIT |
+		IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY_SHARED_BIT,
 		.address = accel_z,
 		.scan_index = ADIS16400_SCAN_ACC_Z,
 		.scan_type = IIO_ST('s', 14, 16, 0),
@@ -911,8 +1013,8 @@
 		.type = IIO_TEMP,
 		.indexed = 1,
 		.channel = 0,
-		.info_mask = (1 << IIO_CHAN_INFO_CALIBBIAS_SEPARATE) |
-		(1 << IIO_CHAN_INFO_SCALE_SHARED),
+		.info_mask = IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT |
+		IIO_CHAN_INFO_SCALE_SHARED_BIT,
 		.address = accel_z,
 		.scan_index = ADIS16400_SCAN_ACC_Z,
 		.scan_type = IIO_ST('s', 14, 16, 0),
@@ -1118,6 +1220,7 @@
 	{"adis16405", ADIS16400},
 	{}
 };
+MODULE_DEVICE_TABLE(spi, adis16400_id);
 
 static struct spi_driver adis16400_driver = {
 	.driver = {
diff --git a/drivers/staging/iio/imu/adis16400_ring.c b/drivers/staging/iio/imu/adis16400_ring.c
index fd886bf..ac22de5 100644
--- a/drivers/staging/iio/imu/adis16400_ring.c
+++ b/drivers/staging/iio/imu/adis16400_ring.c
@@ -79,14 +79,16 @@
 	struct spi_message msg;
 	int i, j = 0, ret;
 	struct spi_transfer *xfers;
+	int scan_count = bitmap_weight(indio_dev->active_scan_mask,
+				       indio_dev->masklength);
 
-	xfers = kzalloc(sizeof(*xfers)*indio_dev->buffer->scan_count + 1,
+	xfers = kzalloc(sizeof(*xfers)*(scan_count + 1),
 			GFP_KERNEL);
 	if (xfers == NULL)
 		return -ENOMEM;
 
 	for (i = 0; i < ARRAY_SIZE(read_all_tx_array); i++)
-		if (test_bit(i, indio_dev->buffer->scan_mask)) {
+		if (test_bit(i, indio_dev->active_scan_mask)) {
 			xfers[j].tx_buf = &read_all_tx_array[i];
 			xfers[j].bits_per_word = 16;
 			xfers[j].len = 2;
@@ -97,7 +99,7 @@
 	xfers[j].len = 2;
 
 	spi_message_init(&msg);
-	for (j = 0; j < indio_dev->buffer->scan_count + 1; j++)
+	for (j = 0; j < scan_count + 1; j++)
 		spi_message_add_tail(&xfers[j], &msg);
 
 	ret = spi_sync(st->us, &msg);
@@ -119,26 +121,27 @@
 	s16 *data;
 	size_t datasize = ring->access->get_bytes_per_datum(ring);
 	/* Asumption that long is enough for maximum channels */
-	unsigned long mask = *ring->scan_mask;
-
+	unsigned long mask = *indio_dev->active_scan_mask;
+	int scan_count = bitmap_weight(indio_dev->active_scan_mask,
+				       indio_dev->masklength);
 	data = kmalloc(datasize , GFP_KERNEL);
 	if (data == NULL) {
 		dev_err(&st->us->dev, "memory alloc failed in ring bh");
 		return -ENOMEM;
 	}
 
-	if (ring->scan_count) {
+	if (scan_count) {
 		if (st->variant->flags & ADIS16400_NO_BURST) {
 			ret = adis16350_spi_read_all(&indio_dev->dev, st->rx);
 			if (ret < 0)
 				goto err;
-			for (; i < ring->scan_count; i++)
+			for (; i < scan_count; i++)
 				data[i]	= *(s16 *)(st->rx + i*2);
 		} else {
 			ret = adis16400_spi_read_burst(&indio_dev->dev, st->rx);
 			if (ret < 0)
 				goto err;
-			for (; i < indio_dev->buffer->scan_count; i++) {
+			for (; i < scan_count; i++) {
 				j = __ffs(mask);
 				mask &= ~(1 << j);
 				data[i] = be16_to_cpup(
@@ -186,10 +189,8 @@
 	indio_dev->buffer = ring;
 	/* Effectively select the ring buffer implementation */
 	ring->access = &ring_sw_access_funcs;
-	ring->bpe = 2;
 	ring->scan_timestamp = true;
-	ring->setup_ops = &adis16400_ring_setup_ops;
-	ring->owner = THIS_MODULE;
+	indio_dev->setup_ops = &adis16400_ring_setup_ops;
 
 	indio_dev->pollfunc = iio_alloc_pollfunc(&iio_pollfunc_store_time,
 						 &adis16400_trigger_handler,
diff --git a/drivers/staging/iio/industrialio-buffer.c b/drivers/staging/iio/industrialio-buffer.c
index 9df0ce8..d7b1e9e 100644
--- a/drivers/staging/iio/industrialio-buffer.c
+++ b/drivers/staging/iio/industrialio-buffer.c
@@ -24,7 +24,7 @@
 #include "iio.h"
 #include "iio_core.h"
 #include "sysfs.h"
-#include "buffer_generic.h"
+#include "buffer.h"
 
 static const char * const iio_endian_prefix[] = {
 	[IIO_BE] = "be",
@@ -43,7 +43,7 @@
 	struct iio_dev *indio_dev = filp->private_data;
 	struct iio_buffer *rb = indio_dev->buffer;
 
-	if (!rb->access->read_first_n)
+	if (!rb || !rb->access->read_first_n)
 		return -EINVAL;
 	return rb->access->read_first_n(rb, n, buf);
 }
@@ -64,28 +64,9 @@
 	return 0;
 }
 
-int iio_chrdev_buffer_open(struct iio_dev *indio_dev)
+void iio_buffer_init(struct iio_buffer *buffer)
 {
-	struct iio_buffer *rb = indio_dev->buffer;
-	if (!rb)
-		return -EINVAL;
-	if (rb->access->mark_in_use)
-		rb->access->mark_in_use(rb);
-	return 0;
-}
-
-void iio_chrdev_buffer_release(struct iio_dev *indio_dev)
-{
-	struct iio_buffer *rb = indio_dev->buffer;
-
-	clear_bit(IIO_BUSY_BIT_POS, &rb->flags);
-	if (rb->access->unmark_in_use)
-		rb->access->unmark_in_use(rb);
-}
-
-void iio_buffer_init(struct iio_buffer *buffer, struct iio_dev *indio_dev)
-{
-	buffer->indio_dev = indio_dev;
+	INIT_LIST_HEAD(&buffer->demux_list);
 	init_waitqueue_head(&buffer->pollq);
 }
 EXPORT_SYMBOL(iio_buffer_init);
@@ -126,17 +107,15 @@
 	int ret;
 	struct iio_dev *indio_dev = dev_get_drvdata(dev);
 
-	ret = iio_scan_mask_query(indio_dev->buffer,
-				  to_iio_dev_attr(attr)->address);
-	if (ret < 0)
-		return ret;
+	ret = test_bit(to_iio_dev_attr(attr)->address,
+		       indio_dev->buffer->scan_mask);
+
 	return sprintf(buf, "%d\n", ret);
 }
 
 static int iio_scan_mask_clear(struct iio_buffer *buffer, int bit)
 {
 	clear_bit(bit, buffer->scan_mask);
-	buffer->scan_count--;
 	return 0;
 }
 
@@ -153,11 +132,11 @@
 
 	state = !(buf[0] == '0');
 	mutex_lock(&indio_dev->mlock);
-	if (indio_dev->currentmode == INDIO_BUFFER_TRIGGERED) {
+	if (iio_buffer_enabled(indio_dev)) {
 		ret = -EBUSY;
 		goto error_ret;
 	}
-	ret = iio_scan_mask_query(buffer, this_attr->address);
+	ret = iio_scan_mask_query(indio_dev, buffer, this_attr->address);
 	if (ret < 0)
 		goto error_ret;
 	if (!state && ret) {
@@ -165,7 +144,7 @@
 		if (ret)
 			goto error_ret;
 	} else if (state && !ret) {
-		ret = iio_scan_mask_set(buffer, this_attr->address);
+		ret = iio_scan_mask_set(indio_dev, buffer, this_attr->address);
 		if (ret)
 			goto error_ret;
 	}
@@ -173,7 +152,7 @@
 error_ret:
 	mutex_unlock(&indio_dev->mlock);
 
-	return ret ? ret : len;
+	return ret < 0 ? ret : len;
 
 }
 
@@ -196,7 +175,7 @@
 
 	state = !(buf[0] == '0');
 	mutex_lock(&indio_dev->mlock);
-	if (indio_dev->currentmode == INDIO_BUFFER_TRIGGERED) {
+	if (iio_buffer_enabled(indio_dev)) {
 		ret = -EBUSY;
 		goto error_ret;
 	}
@@ -311,12 +290,14 @@
 			if (ret < 0)
 				goto error_cleanup_dynamic;
 			attrcount += ret;
+			if (channels[i].type == IIO_TIMESTAMP)
+				buffer->scan_index_timestamp =
+					channels[i].scan_index;
 		}
 		if (indio_dev->masklength && buffer->scan_mask == NULL) {
-			buffer->scan_mask
-				= kzalloc(sizeof(*buffer->scan_mask)*
-					  BITS_TO_LONGS(indio_dev->masklength),
-					  GFP_KERNEL);
+			buffer->scan_mask = kcalloc(BITS_TO_LONGS(indio_dev->masklength),
+						    sizeof(*buffer->scan_mask),
+						    GFP_KERNEL);
 			if (buffer->scan_mask == NULL) {
 				ret = -ENOMEM;
 				goto error_cleanup_dynamic;
@@ -326,10 +307,9 @@
 
 	buffer->scan_el_group.name = iio_scan_elements_group_name;
 
-	buffer->scan_el_group.attrs
-		= kzalloc(sizeof(buffer->scan_el_group.attrs[0])*
-			  (attrcount + 1),
-			  GFP_KERNEL);
+	buffer->scan_el_group.attrs = kcalloc(attrcount + 1,
+					      sizeof(buffer->scan_el_group.attrs[0]),
+					      GFP_KERNEL);
 	if (buffer->scan_el_group.attrs == NULL) {
 		ret = -ENOMEM;
 		goto error_free_scan_mask;
@@ -395,31 +375,20 @@
 		if (val == buffer->access->get_length(buffer))
 			return len;
 
-	if (buffer->access->set_length) {
-		buffer->access->set_length(buffer, val);
-		if (buffer->access->mark_param_change)
-			buffer->access->mark_param_change(buffer);
+	mutex_lock(&indio_dev->mlock);
+	if (iio_buffer_enabled(indio_dev)) {
+		ret = -EBUSY;
+	} else {
+		if (buffer->access->set_length)
+			buffer->access->set_length(buffer, val);
+		ret = 0;
 	}
+	mutex_unlock(&indio_dev->mlock);
 
-	return len;
+	return ret ? ret : len;
 }
 EXPORT_SYMBOL(iio_buffer_write_length);
 
-ssize_t iio_buffer_read_bytes_per_datum(struct device *dev,
-					struct device_attribute *attr,
-					char *buf)
-{
-	struct iio_dev *indio_dev = dev_get_drvdata(dev);
-	struct iio_buffer *buffer = indio_dev->buffer;
-
-	if (buffer->access->get_bytes_per_datum)
-		return sprintf(buf, "%d\n",
-			       buffer->access->get_bytes_per_datum(buffer));
-
-	return 0;
-}
-EXPORT_SYMBOL(iio_buffer_read_bytes_per_datum);
-
 ssize_t iio_buffer_store_enable(struct device *dev,
 				struct device_attribute *attr,
 				const char *buf,
@@ -434,14 +403,14 @@
 	mutex_lock(&indio_dev->mlock);
 	previous_mode = indio_dev->currentmode;
 	requested_state = !(buf[0] == '0');
-	current_state = !!(previous_mode & INDIO_ALL_BUFFER_MODES);
+	current_state = iio_buffer_enabled(indio_dev);
 	if (current_state == requested_state) {
 		printk(KERN_INFO "iio-buffer, current state requested again\n");
 		goto done;
 	}
 	if (requested_state) {
-		if (buffer->setup_ops->preenable) {
-			ret = buffer->setup_ops->preenable(indio_dev);
+		if (indio_dev->setup_ops->preenable) {
+			ret = indio_dev->setup_ops->preenable(indio_dev);
 			if (ret) {
 				printk(KERN_ERR
 				       "Buffer not started:"
@@ -458,16 +427,12 @@
 				goto error_ret;
 			}
 		}
-		if (buffer->access->mark_in_use)
-			buffer->access->mark_in_use(buffer);
 		/* Definitely possible for devices to support both of these.*/
 		if (indio_dev->modes & INDIO_BUFFER_TRIGGERED) {
 			if (!indio_dev->trig) {
 				printk(KERN_INFO
 				       "Buffer not started: no trigger\n");
 				ret = -EINVAL;
-				if (buffer->access->unmark_in_use)
-					buffer->access->unmark_in_use(buffer);
 				goto error_ret;
 			}
 			indio_dev->currentmode = INDIO_BUFFER_TRIGGERED;
@@ -478,32 +443,28 @@
 			goto error_ret;
 		}
 
-		if (buffer->setup_ops->postenable) {
-			ret = buffer->setup_ops->postenable(indio_dev);
+		if (indio_dev->setup_ops->postenable) {
+			ret = indio_dev->setup_ops->postenable(indio_dev);
 			if (ret) {
 				printk(KERN_INFO
 				       "Buffer not started:"
 				       "postenable failed\n");
-				if (buffer->access->unmark_in_use)
-					buffer->access->unmark_in_use(buffer);
 				indio_dev->currentmode = previous_mode;
-				if (buffer->setup_ops->postdisable)
-					buffer->setup_ops->
+				if (indio_dev->setup_ops->postdisable)
+					indio_dev->setup_ops->
 						postdisable(indio_dev);
 				goto error_ret;
 			}
 		}
 	} else {
-		if (buffer->setup_ops->predisable) {
-			ret = buffer->setup_ops->predisable(indio_dev);
+		if (indio_dev->setup_ops->predisable) {
+			ret = indio_dev->setup_ops->predisable(indio_dev);
 			if (ret)
 				goto error_ret;
 		}
-		if (buffer->access->unmark_in_use)
-			buffer->access->unmark_in_use(buffer);
 		indio_dev->currentmode = INDIO_DIRECT_MODE;
-		if (buffer->setup_ops->postdisable) {
-			ret = buffer->setup_ops->postdisable(indio_dev);
+		if (indio_dev->setup_ops->postdisable) {
+			ret = indio_dev->setup_ops->postdisable(indio_dev);
 			if (ret)
 				goto error_ret;
 		}
@@ -523,37 +484,10 @@
 			       char *buf)
 {
 	struct iio_dev *indio_dev = dev_get_drvdata(dev);
-	return sprintf(buf, "%d\n", !!(indio_dev->currentmode
-				       & INDIO_ALL_BUFFER_MODES));
+	return sprintf(buf, "%d\n", iio_buffer_enabled(indio_dev));
 }
 EXPORT_SYMBOL(iio_buffer_show_enable);
 
-int iio_sw_buffer_preenable(struct iio_dev *indio_dev)
-{
-	struct iio_buffer *buffer = indio_dev->buffer;
-	size_t size;
-	dev_dbg(&indio_dev->dev, "%s\n", __func__);
-	/* Check if there are any scan elements enabled, if not fail*/
-	if (!(buffer->scan_count || buffer->scan_timestamp))
-		return -EINVAL;
-	if (buffer->scan_timestamp)
-		if (buffer->scan_count)
-			/* Timestamp (aligned to s64) and data */
-			size = (((buffer->scan_count * buffer->bpe)
-					+ sizeof(s64) - 1)
-				& ~(sizeof(s64) - 1))
-				+ sizeof(s64);
-		else /* Timestamp only  */
-			size = sizeof(s64);
-	else /* Data only */
-		size = buffer->scan_count * buffer->bpe;
-	buffer->access->set_bytes_per_datum(buffer, size);
-
-	return 0;
-}
-EXPORT_SYMBOL(iio_sw_buffer_preenable);
-
-
 /* note NULL used as error indicator as it doesn't make sense. */
 static unsigned long *iio_scan_mask_match(unsigned long *av_masks,
 					  unsigned int masklength,
@@ -569,14 +503,57 @@
 	return NULL;
 }
 
+int iio_sw_buffer_preenable(struct iio_dev *indio_dev)
+{
+	struct iio_buffer *buffer = indio_dev->buffer;
+	const struct iio_chan_spec *ch;
+	unsigned bytes = 0;
+	int length, i;
+	dev_dbg(&indio_dev->dev, "%s\n", __func__);
+
+	/* How much space will the demuxed element take? */
+	for_each_set_bit(i, buffer->scan_mask,
+			 indio_dev->masklength) {
+		ch = iio_find_channel_from_si(indio_dev, i);
+		length = ch->scan_type.storagebits/8;
+		bytes = ALIGN(bytes, length);
+		bytes += length;
+	}
+	if (buffer->scan_timestamp) {
+		ch = iio_find_channel_from_si(indio_dev,
+					      buffer->scan_index_timestamp);
+		length = ch->scan_type.storagebits/8;
+		bytes = ALIGN(bytes, length);
+		bytes += length;
+	}
+	buffer->access->set_bytes_per_datum(buffer, bytes);
+
+	/* What scan mask do we actually have ?*/
+	if (indio_dev->available_scan_masks)
+		indio_dev->active_scan_mask =
+			iio_scan_mask_match(indio_dev->available_scan_masks,
+					    indio_dev->masklength,
+					    buffer->scan_mask);
+	else
+		indio_dev->active_scan_mask = buffer->scan_mask;
+	iio_update_demux(indio_dev);
+
+	if (indio_dev->info->update_scan_mode)
+		return indio_dev->info
+			->update_scan_mode(indio_dev,
+					   indio_dev->active_scan_mask);
+	return 0;
+}
+EXPORT_SYMBOL(iio_sw_buffer_preenable);
+
 /**
  * iio_scan_mask_set() - set particular bit in the scan mask
  * @buffer: the buffer whose scan mask we are interested in
  * @bit: the bit to be set.
  **/
-int iio_scan_mask_set(struct iio_buffer *buffer, int bit)
+int iio_scan_mask_set(struct iio_dev *indio_dev,
+		      struct iio_buffer *buffer, int bit)
 {
-	struct iio_dev *indio_dev = buffer->indio_dev;
 	unsigned long *mask;
 	unsigned long *trialmask;
 
@@ -604,7 +581,6 @@
 		}
 	}
 	bitmap_copy(buffer->scan_mask, trialmask, indio_dev->masklength);
-	buffer->scan_count++;
 
 	kfree(trialmask);
 
@@ -612,25 +588,147 @@
 };
 EXPORT_SYMBOL_GPL(iio_scan_mask_set);
 
-int iio_scan_mask_query(struct iio_buffer *buffer, int bit)
+int iio_scan_mask_query(struct iio_dev *indio_dev,
+			struct iio_buffer *buffer, int bit)
 {
-	struct iio_dev *indio_dev = buffer->indio_dev;
-	long *mask;
-
 	if (bit > indio_dev->masklength)
 		return -EINVAL;
 
 	if (!buffer->scan_mask)
 		return 0;
-	if (indio_dev->available_scan_masks)
-		mask = iio_scan_mask_match(indio_dev->available_scan_masks,
-					   indio_dev->masklength,
-					   buffer->scan_mask);
-	else
-		mask = buffer->scan_mask;
-	if (!mask)
-		return 0;
 
-	return test_bit(bit, mask);
+	return test_bit(bit, buffer->scan_mask);
 };
 EXPORT_SYMBOL_GPL(iio_scan_mask_query);
+
+/**
+ * struct iio_demux_table() - table describing demux memcpy ops
+ * @from:	index to copy from
+ * @to:	index to copy to
+ * @length:	how many bytes to copy
+ * @l:		list head used for management
+ */
+struct iio_demux_table {
+	unsigned from;
+	unsigned to;
+	unsigned length;
+	struct list_head l;
+};
+
+static unsigned char *iio_demux(struct iio_buffer *buffer,
+				 unsigned char *datain)
+{
+	struct iio_demux_table *t;
+
+	if (list_empty(&buffer->demux_list))
+		return datain;
+	list_for_each_entry(t, &buffer->demux_list, l)
+		memcpy(buffer->demux_bounce + t->to,
+		       datain + t->from, t->length);
+
+	return buffer->demux_bounce;
+}
+
+int iio_push_to_buffer(struct iio_buffer *buffer, unsigned char *data,
+		       s64 timestamp)
+{
+	unsigned char *dataout = iio_demux(buffer, data);
+
+	return buffer->access->store_to(buffer, dataout, timestamp);
+}
+EXPORT_SYMBOL_GPL(iio_push_to_buffer);
+
+int iio_update_demux(struct iio_dev *indio_dev)
+{
+	const struct iio_chan_spec *ch;
+	struct iio_buffer *buffer = indio_dev->buffer;
+	int ret, in_ind = -1, out_ind, length;
+	unsigned in_loc = 0, out_loc = 0;
+	struct iio_demux_table *p, *q;
+
+	/* Clear out any old demux */
+	list_for_each_entry_safe(p, q, &buffer->demux_list, l) {
+		list_del(&p->l);
+		kfree(p);
+	}
+	kfree(buffer->demux_bounce);
+	buffer->demux_bounce = NULL;
+
+	/* First work out which scan mode we will actually have */
+	if (bitmap_equal(indio_dev->active_scan_mask,
+			 buffer->scan_mask,
+			 indio_dev->masklength))
+		return 0;
+
+	/* Now we have the two masks, work from least sig and build up sizes */
+	for_each_set_bit(out_ind,
+			 indio_dev->active_scan_mask,
+			 indio_dev->masklength) {
+		in_ind = find_next_bit(indio_dev->active_scan_mask,
+				       indio_dev->masklength,
+				       in_ind + 1);
+		while (in_ind != out_ind) {
+			in_ind = find_next_bit(indio_dev->active_scan_mask,
+					       indio_dev->masklength,
+					       in_ind + 1);
+			ch = iio_find_channel_from_si(indio_dev, in_ind);
+			length = ch->scan_type.storagebits/8;
+			/* Make sure we are aligned */
+			in_loc += length;
+			if (in_loc % length)
+				in_loc += length - in_loc % length;
+		}
+		p = kmalloc(sizeof(*p), GFP_KERNEL);
+		if (p == NULL) {
+			ret = -ENOMEM;
+			goto error_clear_mux_table;
+		}
+		ch = iio_find_channel_from_si(indio_dev, in_ind);
+		length = ch->scan_type.storagebits/8;
+		if (out_loc % length)
+			out_loc += length - out_loc % length;
+		if (in_loc % length)
+			in_loc += length - in_loc % length;
+		p->from = in_loc;
+		p->to = out_loc;
+		p->length = length;
+		list_add_tail(&p->l, &buffer->demux_list);
+		out_loc += length;
+		in_loc += length;
+	}
+	/* Relies on scan_timestamp being last */
+	if (buffer->scan_timestamp) {
+		p = kmalloc(sizeof(*p), GFP_KERNEL);
+		if (p == NULL) {
+			ret = -ENOMEM;
+			goto error_clear_mux_table;
+		}
+		ch = iio_find_channel_from_si(indio_dev,
+			buffer->scan_index_timestamp);
+		length = ch->scan_type.storagebits/8;
+		if (out_loc % length)
+			out_loc += length - out_loc % length;
+		if (in_loc % length)
+			in_loc += length - in_loc % length;
+		p->from = in_loc;
+		p->to = out_loc;
+		p->length = length;
+		list_add_tail(&p->l, &buffer->demux_list);
+		out_loc += length;
+		in_loc += length;
+	}
+	buffer->demux_bounce = kzalloc(out_loc, GFP_KERNEL);
+	if (buffer->demux_bounce == NULL) {
+		ret = -ENOMEM;
+		goto error_clear_mux_table;
+	}
+	return 0;
+
+error_clear_mux_table:
+	list_for_each_entry_safe(p, q, &buffer->demux_list, l) {
+		list_del(&p->l);
+		kfree(p);
+	}
+	return ret;
+}
+EXPORT_SYMBOL_GPL(iio_update_demux);
diff --git a/drivers/staging/iio/industrialio-core.c b/drivers/staging/iio/industrialio-core.c
index aec9311..19f897f 100644
--- a/drivers/staging/iio/industrialio-core.c
+++ b/drivers/staging/iio/industrialio-core.c
@@ -25,8 +25,8 @@
 #include "iio.h"
 #include "iio_core.h"
 #include "iio_core_trigger.h"
-#include "chrdev.h"
 #include "sysfs.h"
+#include "events.h"
 
 /* IDA to assign each registered device a unique id*/
 static DEFINE_IDA(iio_ida);
@@ -77,17 +77,29 @@
 
 /* relies on pairs of these shared then separate */
 static const char * const iio_chan_info_postfix[] = {
-	[IIO_CHAN_INFO_SCALE_SHARED/2] = "scale",
-	[IIO_CHAN_INFO_OFFSET_SHARED/2] = "offset",
-	[IIO_CHAN_INFO_CALIBSCALE_SHARED/2] = "calibscale",
-	[IIO_CHAN_INFO_CALIBBIAS_SHARED/2] = "calibbias",
-	[IIO_CHAN_INFO_PEAK_SHARED/2] = "peak_raw",
-	[IIO_CHAN_INFO_PEAK_SCALE_SHARED/2] = "peak_scale",
-	[IIO_CHAN_INFO_QUADRATURE_CORRECTION_RAW_SHARED/2]
-	= "quadrature_correction_raw",
-	[IIO_CHAN_INFO_AVERAGE_RAW_SHARED/2] = "mean_raw",
+	[IIO_CHAN_INFO_SCALE] = "scale",
+	[IIO_CHAN_INFO_OFFSET] = "offset",
+	[IIO_CHAN_INFO_CALIBSCALE] = "calibscale",
+	[IIO_CHAN_INFO_CALIBBIAS] = "calibbias",
+	[IIO_CHAN_INFO_PEAK] = "peak_raw",
+	[IIO_CHAN_INFO_PEAK_SCALE] = "peak_scale",
+	[IIO_CHAN_INFO_QUADRATURE_CORRECTION_RAW] = "quadrature_correction_raw",
+	[IIO_CHAN_INFO_AVERAGE_RAW] = "mean_raw",
+	[IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY]
+	= "filter_low_pass_3db_frequency",
 };
 
+const struct iio_chan_spec
+*iio_find_channel_from_si(struct iio_dev *indio_dev, int si)
+{
+	int i;
+
+	for (i = 0; i < indio_dev->num_channels; i++)
+		if (indio_dev->channels[i].scan_index == si)
+			return &indio_dev->channels[i];
+	return NULL;
+}
+
 /**
  * struct iio_detected_event_list - list element for events that have occurred
  * @list:		linked list header
@@ -169,8 +181,11 @@
 {
 	struct iio_event_interface *ev_int = filep->private_data;
 	struct iio_detected_event_list *el;
+	size_t len = sizeof(el->ev);
 	int ret;
-	size_t len;
+
+	if (count < len)
+		return -EINVAL;
 
 	mutex_lock(&ev_int->event_list_lock);
 	if (list_empty(&ev_int->det_events)) {
@@ -192,7 +207,6 @@
 	el = list_first_entry(&ev_int->det_events,
 			      struct iio_detected_event_list,
 			      list);
-	len = sizeof el->ev;
 	if (copy_to_user(buf, &(el->ev), len)) {
 		ret = -EFAULT;
 		goto error_mutex_unlock;
@@ -415,7 +429,7 @@
 	sysfs_attr_init(&dev_attr->attr);
 
 	/* Build up postfix of <extend_name>_<modifier>_postfix */
-	if (chan->modified) {
+	if (chan->modified && !generic) {
 		if (chan->extend_name)
 			full_postfix = kasprintf(GFP_KERNEL, "%s_%s_%s",
 						 iio_modifier_names[chan
@@ -600,7 +614,7 @@
 					     chan,
 					     &iio_read_channel_info,
 					     &iio_write_channel_info,
-					     (1 << i),
+					     i/2,
 					     !(i%2),
 					     &indio_dev->dev,
 					     &indio_dev->channel_attr_list);
@@ -665,10 +679,9 @@
 	if (indio_dev->name)
 		attrcount++;
 
-	indio_dev->chan_attr_group.attrs
-		= kzalloc(sizeof(indio_dev->chan_attr_group.attrs[0])*
-			  (attrcount + 1),
-			  GFP_KERNEL);
+	indio_dev->chan_attr_group.attrs = kcalloc(attrcount + 1,
+						   sizeof(indio_dev->chan_attr_group.attrs[0]),
+						   GFP_KERNEL);
 	if (indio_dev->chan_attr_group.attrs == NULL) {
 		ret = -ENOMEM;
 		goto error_clear_attrs;
@@ -788,6 +801,9 @@
 	unsigned long val;
 	int ret;
 
+	if (!indio_dev->info->write_event_value)
+		return -EINVAL;
+
 	ret = strict_strtoul(buf, 10, &val);
 	if (ret)
 		return ret;
@@ -958,10 +974,9 @@
 	}
 
 	indio_dev->event_interface->group.name = iio_event_group_name;
-	indio_dev->event_interface->group.attrs =
-		kzalloc(sizeof(indio_dev->event_interface->group.attrs[0])
-			*(attrcount + 1),
-			GFP_KERNEL);
+	indio_dev->event_interface->group.attrs = kcalloc(attrcount + 1,
+							  sizeof(indio_dev->event_interface->group.attrs[0]),
+							  GFP_KERNEL);
 	if (indio_dev->event_interface->group.attrs == NULL) {
 		ret = -ENOMEM;
 		goto error_free_setup_event_lines;
@@ -1068,9 +1083,13 @@
 {
 	struct iio_dev *indio_dev = container_of(inode->i_cdev,
 						struct iio_dev, chrdev);
+
+	if (test_and_set_bit(IIO_BUSY_BIT_POS, &indio_dev->flags))
+		return -EBUSY;
+
 	filp->private_data = indio_dev;
 
-	return iio_chrdev_buffer_open(indio_dev);
+	return 0;
 }
 
 /**
@@ -1078,8 +1097,9 @@
  **/
 static int iio_chrdev_release(struct inode *inode, struct file *filp)
 {
-	iio_chrdev_buffer_release(container_of(inode->i_cdev,
-					     struct iio_dev, chrdev));
+	struct iio_dev *indio_dev = container_of(inode->i_cdev,
+						struct iio_dev, chrdev);
+	clear_bit(IIO_BUSY_BIT_POS, &indio_dev->flags);
 	return 0;
 }
 
diff --git a/drivers/staging/iio/industrialio-trigger.c b/drivers/staging/iio/industrialio-trigger.c
index 68a4d4e..47ecadd 100644
--- a/drivers/staging/iio/industrialio-trigger.c
+++ b/drivers/staging/iio/industrialio-trigger.c
@@ -159,13 +159,12 @@
 void iio_trigger_poll_chained(struct iio_trigger *trig, s64 time)
 {
 	int i;
-	if (!trig->use_count) {
+	if (!trig->use_count)
 		for (i = 0; i < CONFIG_IIO_CONSUMERS_PER_TRIGGER; i++)
 			if (trig->subirqs[i].enabled) {
 				trig->use_count++;
 				handle_nested_irq(trig->subirq_base + i);
 			}
-	}
 }
 EXPORT_SYMBOL(iio_trigger_poll_chained);
 
@@ -173,10 +172,9 @@
 {
 	trig->use_count--;
 	if (trig->use_count == 0 && trig->ops && trig->ops->try_reenable)
-		if (trig->ops->try_reenable(trig)) {
+		if (trig->ops->try_reenable(trig))
 			/* Missed and interrupt so launch new poll now */
 			iio_trigger_poll(trig, 0);
-		}
 }
 EXPORT_SYMBOL(iio_trigger_notify_done);
 
@@ -222,8 +220,16 @@
 	ret = request_threaded_irq(pf->irq, pf->h, pf->thread,
 				   pf->type, pf->name,
 				   pf);
-	if (trig->ops && trig->ops->set_trigger_state && notinuse)
+	if (ret < 0) {
+		module_put(pf->indio_dev->info->driver_module);
+		return ret;
+	}
+
+	if (trig->ops && trig->ops->set_trigger_state && notinuse) {
 		ret = trig->ops->set_trigger_state(trig, true);
+		if (ret < 0)
+			module_put(pf->indio_dev->info->driver_module);
+	}
 
 	return ret;
 }
@@ -336,6 +342,8 @@
 	mutex_unlock(&indio_dev->mlock);
 
 	trig = iio_trigger_find_by_name(buf, len);
+	if (oldtrig == trig)
+		return len;
 
 	if (trig && indio_dev->info->validate_trigger) {
 		ret = indio_dev->info->validate_trigger(indio_dev, trig);
@@ -473,12 +481,10 @@
 }
 EXPORT_SYMBOL(iio_free_trigger);
 
-int iio_device_register_trigger_consumer(struct iio_dev *indio_dev)
+void iio_device_register_trigger_consumer(struct iio_dev *indio_dev)
 {
 	indio_dev->groups[indio_dev->groupcounter++] =
 		&iio_trigger_consumer_attr_group;
-
-	return 0;
 }
 
 void iio_device_unregister_trigger_consumer(struct iio_dev *indio_dev)
@@ -490,18 +496,14 @@
 
 int iio_triggered_buffer_postenable(struct iio_dev *indio_dev)
 {
-	return indio_dev->trig
-		? iio_trigger_attach_poll_func(indio_dev->trig,
-					       indio_dev->pollfunc)
-		: 0;
+	return iio_trigger_attach_poll_func(indio_dev->trig,
+					    indio_dev->pollfunc);
 }
 EXPORT_SYMBOL(iio_triggered_buffer_postenable);
 
 int iio_triggered_buffer_predisable(struct iio_dev *indio_dev)
 {
-	return indio_dev->trig
-		? iio_trigger_dettach_poll_func(indio_dev->trig,
-						indio_dev->pollfunc)
-		: 0;
+	return iio_trigger_dettach_poll_func(indio_dev->trig,
+					     indio_dev->pollfunc);
 }
 EXPORT_SYMBOL(iio_triggered_buffer_predisable);
diff --git a/drivers/staging/iio/kfifo_buf.c b/drivers/staging/iio/kfifo_buf.c
index e8c234b..e1e9c06 100644
--- a/drivers/staging/iio/kfifo_buf.c
+++ b/drivers/staging/iio/kfifo_buf.c
@@ -11,9 +11,7 @@
 struct iio_kfifo {
 	struct iio_buffer buffer;
 	struct kfifo kf;
-	int use_count;
 	int update_needed;
-	struct mutex use_lock;
 };
 
 #define iio_to_kfifo(r) container_of(r, struct iio_kfifo, buffer)
@@ -33,54 +31,25 @@
 	int ret = 0;
 	struct iio_kfifo *buf = iio_to_kfifo(r);
 
-	mutex_lock(&buf->use_lock);
 	if (!buf->update_needed)
 		goto error_ret;
-	if (buf->use_count) {
-		ret = -EAGAIN;
-		goto error_ret;
-	}
 	kfifo_free(&buf->kf);
 	ret = __iio_allocate_kfifo(buf, buf->buffer.bytes_per_datum,
 				   buf->buffer.length);
 error_ret:
-	mutex_unlock(&buf->use_lock);
 	return ret;
 }
 
-static void iio_mark_kfifo_in_use(struct iio_buffer *r)
-{
-	struct iio_kfifo *buf = iio_to_kfifo(r);
-	mutex_lock(&buf->use_lock);
-	buf->use_count++;
-	mutex_unlock(&buf->use_lock);
-}
-
-static void iio_unmark_kfifo_in_use(struct iio_buffer *r)
-{
-	struct iio_kfifo *buf = iio_to_kfifo(r);
-	mutex_lock(&buf->use_lock);
-	buf->use_count--;
-	mutex_unlock(&buf->use_lock);
-}
-
 static int iio_get_length_kfifo(struct iio_buffer *r)
 {
 	return r->length;
 }
 
-static inline void __iio_init_kfifo(struct iio_kfifo *kf)
-{
-	mutex_init(&kf->use_lock);
-}
-
 static IIO_BUFFER_ENABLE_ATTR;
-static IIO_BUFFER_BYTES_PER_DATUM_ATTR;
 static IIO_BUFFER_LENGTH_ATTR;
 
 static struct attribute *iio_kfifo_attributes[] = {
 	&dev_attr_length.attr,
-	&dev_attr_bytes_per_datum.attr,
 	&dev_attr_enable.attr,
 	NULL,
 };
@@ -98,9 +67,8 @@
 	if (!kf)
 		return NULL;
 	kf->update_needed = true;
-	iio_buffer_init(&kf->buffer, indio_dev);
+	iio_buffer_init(&kf->buffer);
 	kf->buffer.attrs = &iio_kfifo_attribute_group;
-	__iio_init_kfifo(kf);
 
 	return &kf->buffer;
 }
@@ -111,16 +79,6 @@
 	return r->bytes_per_datum;
 }
 
-static int iio_set_bytes_per_datum_kfifo(struct iio_buffer *r, size_t bpd)
-{
-	if (r->bytes_per_datum != bpd) {
-		r->bytes_per_datum = bpd;
-		if (r->access->mark_param_change)
-			r->access->mark_param_change(r);
-	}
-	return 0;
-}
-
 static int iio_mark_update_needed_kfifo(struct iio_buffer *r)
 {
 	struct iio_kfifo *kf = iio_to_kfifo(r);
@@ -128,12 +86,20 @@
 	return 0;
 }
 
+static int iio_set_bytes_per_datum_kfifo(struct iio_buffer *r, size_t bpd)
+{
+	if (r->bytes_per_datum != bpd) {
+		r->bytes_per_datum = bpd;
+		iio_mark_update_needed_kfifo(r);
+	}
+	return 0;
+}
+
 static int iio_set_length_kfifo(struct iio_buffer *r, int length)
 {
 	if (r->length != length) {
 		r->length = length;
-		if (r->access->mark_param_change)
-			r->access->mark_param_change(r);
+		iio_mark_update_needed_kfifo(r);
 	}
 	return 0;
 }
@@ -150,16 +116,9 @@
 {
 	int ret;
 	struct iio_kfifo *kf = iio_to_kfifo(r);
-	u8 *datal = kmalloc(r->bytes_per_datum, GFP_KERNEL);
-	memcpy(datal, data, r->bytes_per_datum - sizeof(timestamp));
-	memcpy(datal + r->bytes_per_datum - sizeof(timestamp),
-		&timestamp, sizeof(timestamp));
 	ret = kfifo_in(&kf->kf, data, r->bytes_per_datum);
-	if (ret != r->bytes_per_datum) {
-		kfree(datal);
+	if (ret != r->bytes_per_datum)
 		return -EBUSY;
-	}
-	kfree(datal);
 	return 0;
 }
 
@@ -169,17 +128,18 @@
 	int ret, copied;
 	struct iio_kfifo *kf = iio_to_kfifo(r);
 
-	ret = kfifo_to_user(&kf->kf, buf, r->bytes_per_datum*n, &copied);
+	if (n < r->bytes_per_datum)
+		return -EINVAL;
+
+	n = rounddown(n, r->bytes_per_datum);
+	ret = kfifo_to_user(&kf->kf, buf, n, &copied);
 
 	return copied;
 }
 
 const struct iio_buffer_access_funcs kfifo_access_funcs = {
-	.mark_in_use = &iio_mark_kfifo_in_use,
-	.unmark_in_use = &iio_unmark_kfifo_in_use,
 	.store_to = &iio_store_to_kfifo,
 	.read_first_n = &iio_read_first_n_kfifo,
-	.mark_param_change = &iio_mark_update_needed_kfifo,
 	.request_update = &iio_request_update_kfifo,
 	.get_bytes_per_datum = &iio_get_bytes_per_datum_kfifo,
 	.set_bytes_per_datum = &iio_set_bytes_per_datum_kfifo,
diff --git a/drivers/staging/iio/kfifo_buf.h b/drivers/staging/iio/kfifo_buf.h
index a15598b..cc2bd9a 100644
--- a/drivers/staging/iio/kfifo_buf.h
+++ b/drivers/staging/iio/kfifo_buf.h
@@ -1,7 +1,7 @@
 
 #include <linux/kfifo.h>
 #include "iio.h"
-#include "buffer_generic.h"
+#include "buffer.h"
 
 extern const struct iio_buffer_access_funcs kfifo_access_funcs;
 
diff --git a/drivers/staging/iio/light/isl29018.c b/drivers/staging/iio/light/isl29018.c
index 4763836..849d6a5 100644
--- a/drivers/staging/iio/light/isl29018.c
+++ b/drivers/staging/iio/light/isl29018.c
@@ -362,8 +362,7 @@
 	int ret = -EINVAL;
 
 	mutex_lock(&chip->lock);
-	if (mask == (1 << IIO_CHAN_INFO_CALIBSCALE_SEPARATE) &&
-	    chan->type == IIO_LIGHT) {
+	if (mask == IIO_CHAN_INFO_CALIBSCALE && chan->type == IIO_LIGHT) {
 		chip->lux_scale = val;
 		ret = 0;
 	}
@@ -402,7 +401,7 @@
 		if (!ret)
 			ret = IIO_VAL_INT;
 		break;
-	case (1 << IIO_CHAN_INFO_CALIBSCALE_SEPARATE):
+	case IIO_CHAN_INFO_CALIBSCALE:
 		if (chan->type == IIO_LIGHT) {
 			*val = chip->lux_scale;
 			ret = IIO_VAL_INT;
@@ -421,7 +420,7 @@
 		.indexed = 1,
 		.channel = 0,
 		.processed_val = IIO_PROCESSED,
-		.info_mask = (1 << IIO_CHAN_INFO_CALIBSCALE_SEPARATE),
+		.info_mask = IIO_CHAN_INFO_CALIBSCALE_SEPARATE_BIT,
 	}, {
 		.type = IIO_INTENSITY,
 		.modified = 1,
diff --git a/drivers/staging/iio/light/tsl2563.c b/drivers/staging/iio/light/tsl2563.c
index 1942db1..ffca85e 100644
--- a/drivers/staging/iio/light/tsl2563.c
+++ b/drivers/staging/iio/light/tsl2563.c
@@ -37,6 +37,7 @@
 
 #include "../iio.h"
 #include "../sysfs.h"
+#include "../events.h"
 #include "tsl2563.h"
 
 /* Use this many bits for fraction part. */
@@ -226,6 +227,8 @@
 	if (ret < 0)
 		return ret;
 
+	*id = ret;
+
 	return 0;
 }
 
@@ -510,7 +513,7 @@
 		}
 		break;
 
-	case (1 << IIO_CHAN_INFO_CALIBSCALE_SEPARATE):
+	case IIO_CHAN_INFO_CALIBSCALE:
 		if (chan->channel == 0)
 			*val = calib_to_sysfs(chip->calib0);
 		else
@@ -536,7 +539,7 @@
 		.type = IIO_INTENSITY,
 		.modified = 1,
 		.channel2 = IIO_MOD_LIGHT_BOTH,
-		.info_mask = (1 << IIO_CHAN_INFO_CALIBSCALE_SEPARATE),
+		.info_mask = IIO_CHAN_INFO_CALIBSCALE_SEPARATE_BIT,
 		.event_mask = (IIO_EV_BIT(IIO_EV_TYPE_THRESH,
 					  IIO_EV_DIR_RISING) |
 			       IIO_EV_BIT(IIO_EV_TYPE_THRESH,
@@ -544,8 +547,8 @@
 	}, {
 		.type = IIO_INTENSITY,
 		.modified = 1,
-		.channel2 = IIO_MOD_LIGHT_BOTH,
-		.info_mask = (1 << IIO_CHAN_INFO_CALIBSCALE_SEPARATE),
+		.channel2 = IIO_MOD_LIGHT_IR,
+		.info_mask = IIO_CHAN_INFO_CALIBSCALE_SEPARATE_BIT,
 	}
 };
 
diff --git a/drivers/staging/iio/light/tsl2583.c b/drivers/staging/iio/light/tsl2583.c
index 3836f73..5b6455a 100644
--- a/drivers/staging/iio/light/tsl2583.c
+++ b/drivers/staging/iio/light/tsl2583.c
@@ -194,6 +194,7 @@
 {
 	u16 ch0, ch1; /* separated ch0/ch1 data from device */
 	u32 lux; /* raw lux calculated from device data */
+	u64 lux64;
 	u32 ratio;
 	u8 buf[5];
 	struct taos_lux *p;
@@ -297,9 +298,19 @@
 		lux = (lux + (chip->als_time_scale >> 1)) /
 			chip->als_time_scale;
 
-	/* adjust for active gain scale */
-	lux >>= 13; /* tables have factor of 8192 builtin for accuracy */
-	lux = (lux * chip->taos_settings.als_gain_trim + 500) / 1000;
+	/* Adjust for active gain scale.
+	 * The taos_device_lux tables above have a factor of 8192 built in,
+	 * so we need to shift right.
+	 * User-specified gain provides a multiplier.
+	 * Apply user-specified gain before shifting right to retain precision.
+	 * Use 64 bits to avoid overflow on multiplication.
+	 * Then go back to 32 bits before division to avoid using div_u64().
+	 */
+	lux64 = lux;
+	lux64 = lux64 * chip->taos_settings.als_gain_trim;
+	lux64 >>= 13;
+	lux = lux64;
+	lux = (lux + 500) / 1000;
 	if (lux > TSL258X_LUX_CALC_OVER_FLOW) { /* check for overflow */
 return_max:
 		lux = TSL258X_LUX_CALC_OVER_FLOW;
diff --git a/drivers/staging/iio/magnetometer/ak8975.c b/drivers/staging/iio/magnetometer/ak8975.c
index db31d6d..3158f12 100644
--- a/drivers/staging/iio/magnetometer/ak8975.c
+++ b/drivers/staging/iio/magnetometer/ak8975.c
@@ -431,7 +431,7 @@
 	switch (mask) {
 	case 0:
 		return ak8975_read_axis(indio_dev, chan->address, val);
-	case (1 << IIO_CHAN_INFO_SCALE_SEPARATE):
+	case IIO_CHAN_INFO_SCALE:
 		*val = data->raw_to_gauss[chan->address];
 		return IIO_VAL_INT;
 	}
@@ -443,7 +443,7 @@
 		.type = IIO_MAGN,					\
 		.modified = 1,						\
 		.channel2 = IIO_MOD_##axis,				\
-		.info_mask = (1 << IIO_CHAN_INFO_SCALE_SEPARATE),	\
+		.info_mask = IIO_CHAN_INFO_SCALE_SEPARATE_BIT,	\
 		.address = index,					\
 	}
 
diff --git a/drivers/staging/iio/magnetometer/hmc5843.c b/drivers/staging/iio/magnetometer/hmc5843.c
index 7bb1bc6..f2e85a9 100644
--- a/drivers/staging/iio/magnetometer/hmc5843.c
+++ b/drivers/staging/iio/magnetometer/hmc5843.c
@@ -463,7 +463,7 @@
 		return hmc5843_read_measurement(indio_dev,
 						chan->address,
 						val);
-	case (1 << IIO_CHAN_INFO_SCALE_SHARED):
+	case IIO_CHAN_INFO_SCALE:
 		*val = 0;
 		*val2 = hmc5843_regval_to_nanoscale[data->range];
 		return IIO_VAL_INT_PLUS_NANO;
@@ -476,7 +476,7 @@
 		.type = IIO_MAGN,					\
 		.modified = 1,						\
 		.channel2 = IIO_MOD_##axis,				\
-		.info_mask = (1 << IIO_CHAN_INFO_SCALE_SHARED),		\
+		.info_mask = IIO_CHAN_INFO_SCALE_SHARED_BIT,		\
 		.address = add						\
 	}
 
@@ -605,6 +605,7 @@
 	{ "hmc5843", 0 },
 	{ }
 };
+MODULE_DEVICE_TABLE(i2c, hmc5843_id);
 
 static struct i2c_driver hmc5843_driver = {
 	.driver = {
diff --git a/drivers/staging/iio/meter/ade7753.c b/drivers/staging/iio/meter/ade7753.c
index 4c7b0cb..57baac6 100644
--- a/drivers/staging/iio/meter/ade7753.c
+++ b/drivers/staging/iio/meter/ade7753.c
@@ -582,3 +582,4 @@
 MODULE_AUTHOR("Barry Song <21cnbao@gmail.com>");
 MODULE_DESCRIPTION("Analog Devices ADE7753/6 Single-Phase Multifunction Meter");
 MODULE_LICENSE("GPL v2");
+MODULE_ALIAS("spi:ade7753");
diff --git a/drivers/staging/iio/meter/ade7754.c b/drivers/staging/iio/meter/ade7754.c
index 15c98cd..8d81c92 100644
--- a/drivers/staging/iio/meter/ade7754.c
+++ b/drivers/staging/iio/meter/ade7754.c
@@ -605,3 +605,4 @@
 MODULE_AUTHOR("Barry Song <21cnbao@gmail.com>");
 MODULE_DESCRIPTION("Analog Devices ADE7754 Polyphase Multifunction Energy Metering IC Driver");
 MODULE_LICENSE("GPL v2");
+MODULE_ALIAS("spi:ad7754");
diff --git a/drivers/staging/iio/meter/ade7758_core.c b/drivers/staging/iio/meter/ade7758_core.c
index 39338bc..dcb2029 100644
--- a/drivers/staging/iio/meter/ade7758_core.c
+++ b/drivers/staging/iio/meter/ade7758_core.c
@@ -20,7 +20,7 @@
 
 #include "../iio.h"
 #include "../sysfs.h"
-#include "../buffer_generic.h"
+#include "../buffer.h"
 #include "meter.h"
 #include "ade7758.h"
 
@@ -663,63 +663,63 @@
 
 static struct iio_chan_spec ade7758_channels[] = {
 	IIO_CHAN(IIO_VOLTAGE, 0, 1, 0, "raw", 0, 0,
-		(1 << IIO_CHAN_INFO_SCALE_SHARED),
+		IIO_CHAN_INFO_SCALE_SHARED_BIT,
 		AD7758_WT(AD7758_PHASE_A, AD7758_VOLTAGE),
 		0, IIO_ST('s', 24, 32, 0), 0),
 	IIO_CHAN(IIO_CURRENT, 0, 1, 0, "raw", 0, 0,
-		(1 << IIO_CHAN_INFO_SCALE_SHARED),
+		IIO_CHAN_INFO_SCALE_SHARED_BIT,
 		AD7758_WT(AD7758_PHASE_A, AD7758_CURRENT),
 		1, IIO_ST('s', 24, 32, 0), 0),
 	IIO_CHAN(IIO_POWER, 0, 1, 0, "apparent_raw", 0, 0,
-		(1 << IIO_CHAN_INFO_SCALE_SHARED),
+		IIO_CHAN_INFO_SCALE_SHARED_BIT,
 		AD7758_WT(AD7758_PHASE_A, AD7758_APP_PWR),
 		2, IIO_ST('s', 24, 32, 0), 0),
 	IIO_CHAN(IIO_POWER, 0, 1, 0, "active_raw", 0, 0,
-		(1 << IIO_CHAN_INFO_SCALE_SHARED),
+		IIO_CHAN_INFO_SCALE_SHARED_BIT,
 		AD7758_WT(AD7758_PHASE_A, AD7758_ACT_PWR),
 		3, IIO_ST('s', 24, 32, 0), 0),
 	IIO_CHAN(IIO_POWER, 0, 1, 0, "reactive_raw", 0, 0,
-		(1 << IIO_CHAN_INFO_SCALE_SHARED),
+		IIO_CHAN_INFO_SCALE_SHARED_BIT,
 		AD7758_WT(AD7758_PHASE_A, AD7758_REACT_PWR),
 		4, IIO_ST('s', 24, 32, 0), 0),
 	IIO_CHAN(IIO_VOLTAGE, 0, 1, 0, "raw", 1, 0,
-		(1 << IIO_CHAN_INFO_SCALE_SHARED),
+		IIO_CHAN_INFO_SCALE_SHARED_BIT,
 		AD7758_WT(AD7758_PHASE_B, AD7758_VOLTAGE),
 		5, IIO_ST('s', 24, 32, 0), 0),
 	IIO_CHAN(IIO_CURRENT, 0, 1, 0, "raw", 1, 0,
-		(1 << IIO_CHAN_INFO_SCALE_SHARED),
+		IIO_CHAN_INFO_SCALE_SHARED_BIT,
 		AD7758_WT(AD7758_PHASE_B, AD7758_CURRENT),
 		6, IIO_ST('s', 24, 32, 0), 0),
 	IIO_CHAN(IIO_POWER, 0, 1, 0, "apparent_raw", 1, 0,
-		(1 << IIO_CHAN_INFO_SCALE_SHARED),
+		IIO_CHAN_INFO_SCALE_SHARED_BIT,
 		AD7758_WT(AD7758_PHASE_B, AD7758_APP_PWR),
 		7, IIO_ST('s', 24, 32, 0), 0),
 	IIO_CHAN(IIO_POWER, 0, 1, 0, "active_raw", 1, 0,
-		(1 << IIO_CHAN_INFO_SCALE_SHARED),
+		IIO_CHAN_INFO_SCALE_SHARED_BIT,
 		AD7758_WT(AD7758_PHASE_B, AD7758_ACT_PWR),
 		8, IIO_ST('s', 24, 32, 0), 0),
 	IIO_CHAN(IIO_POWER, 0, 1, 0, "reactive_raw", 1, 0,
-		(1 << IIO_CHAN_INFO_SCALE_SHARED),
+		IIO_CHAN_INFO_SCALE_SHARED_BIT,
 		AD7758_WT(AD7758_PHASE_B, AD7758_REACT_PWR),
 		9, IIO_ST('s', 24, 32, 0), 0),
 	IIO_CHAN(IIO_VOLTAGE, 0, 1, 0, "raw", 2, 0,
-		(1 << IIO_CHAN_INFO_SCALE_SHARED),
+		IIO_CHAN_INFO_SCALE_SHARED_BIT,
 		AD7758_WT(AD7758_PHASE_C, AD7758_VOLTAGE),
 		10, IIO_ST('s', 24, 32, 0), 0),
 	IIO_CHAN(IIO_CURRENT, 0, 1, 0, "raw", 2, 0,
-		(1 << IIO_CHAN_INFO_SCALE_SHARED),
+		IIO_CHAN_INFO_SCALE_SHARED_BIT,
 		AD7758_WT(AD7758_PHASE_C, AD7758_CURRENT),
 		11, IIO_ST('s', 24, 32, 0), 0),
 	IIO_CHAN(IIO_POWER, 0, 1, 0, "apparent_raw", 2, 0,
-		(1 << IIO_CHAN_INFO_SCALE_SHARED),
+		IIO_CHAN_INFO_SCALE_SHARED_BIT,
 		AD7758_WT(AD7758_PHASE_C, AD7758_APP_PWR),
 		12, IIO_ST('s', 24, 32, 0), 0),
 	IIO_CHAN(IIO_POWER, 0, 1, 0, "active_raw", 2, 0,
-		(1 << IIO_CHAN_INFO_SCALE_SHARED),
+		IIO_CHAN_INFO_SCALE_SHARED_BIT,
 		AD7758_WT(AD7758_PHASE_C, AD7758_ACT_PWR),
 		13, IIO_ST('s', 24, 32, 0), 0),
 	IIO_CHAN(IIO_POWER, 0, 1, 0, "reactive_raw", 2, 0,
-		(1 << IIO_CHAN_INFO_SCALE_SHARED),
+		IIO_CHAN_INFO_SCALE_SHARED_BIT,
 		AD7758_WT(AD7758_PHASE_C, AD7758_REACT_PWR),
 		14, IIO_ST('s', 24, 32, 0), 0),
 	IIO_CHAN_SOFT_TIMESTAMP(15),
@@ -746,12 +746,12 @@
 	spi_set_drvdata(spi, indio_dev);
 
 	/* Allocate the comms buffers */
-	st->rx = kzalloc(sizeof(*st->rx)*ADE7758_MAX_RX, GFP_KERNEL);
+	st->rx = kcalloc(ADE7758_MAX_RX, sizeof(*st->rx), GFP_KERNEL);
 	if (st->rx == NULL) {
 		ret = -ENOMEM;
 		goto error_free_dev;
 	}
-	st->tx = kzalloc(sizeof(*st->tx)*ADE7758_MAX_TX, GFP_KERNEL);
+	st->tx = kcalloc(ADE7758_MAX_TX, sizeof(*st->tx), GFP_KERNEL);
 	if (st->tx == NULL) {
 		ret = -ENOMEM;
 		goto error_free_rx;
@@ -843,6 +843,7 @@
 	{"ade7758", 0},
 	{}
 };
+MODULE_DEVICE_TABLE(spi, ade7758_id);
 
 static struct spi_driver ade7758_driver = {
 	.driver = {
diff --git a/drivers/staging/iio/meter/ade7758_ring.c b/drivers/staging/iio/meter/ade7758_ring.c
index 00fa2ac..f29f2b2 100644
--- a/drivers/staging/iio/meter/ade7758_ring.c
+++ b/drivers/staging/iio/meter/ade7758_ring.c
@@ -67,7 +67,7 @@
 	s64 dat64[2];
 	u32 *dat32 = (u32 *)dat64;
 
-	if (ring->scan_count)
+	if (!bitmap_empty(indio_dev->active_scan_mask, indio_dev->masklength))
 		if (ade7758_spi_read_burst(&indio_dev->dev) >= 0)
 			*dat32 = get_unaligned_be32(&st->rx_buf[5]) & 0xFFFFFF;
 
@@ -96,10 +96,11 @@
 	size_t d_size;
 	unsigned channel;
 
-	if (!ring->scan_count)
+	if (!bitmap_empty(indio_dev->active_scan_mask, indio_dev->masklength))
 		return -EINVAL;
 
-	channel = find_first_bit(ring->scan_mask, indio_dev->masklength);
+	channel = find_first_bit(indio_dev->active_scan_mask,
+				 indio_dev->masklength);
 
 	d_size = st->ade7758_ring_channels[channel].scan_type.storagebits / 8;
 
@@ -145,8 +146,7 @@
 
 	/* Effectively select the ring buffer implementation */
 	indio_dev->buffer->access = &ring_sw_access_funcs;
-	indio_dev->buffer->setup_ops = &ade7758_ring_setup_ops;
-	indio_dev->buffer->owner = THIS_MODULE;
+	indio_dev->setup_ops = &ade7758_ring_setup_ops;
 
 	indio_dev->pollfunc = iio_alloc_pollfunc(&iio_pollfunc_store_time,
 						 &ade7758_trigger_handler,
diff --git a/drivers/staging/iio/meter/ade7759.c b/drivers/staging/iio/meter/ade7759.c
index cfa2a5e..0beab47 100644
--- a/drivers/staging/iio/meter/ade7759.c
+++ b/drivers/staging/iio/meter/ade7759.c
@@ -526,3 +526,4 @@
 MODULE_AUTHOR("Barry Song <21cnbao@gmail.com>");
 MODULE_DESCRIPTION("Analog Devices ADE7759 Active Energy Metering IC Driver");
 MODULE_LICENSE("GPL v2");
+MODULE_ALIAS("spi:ad7759");
diff --git a/drivers/staging/iio/meter/ade7854-spi.c b/drivers/staging/iio/meter/ade7854-spi.c
index c485a79..8112186 100644
--- a/drivers/staging/iio/meter/ade7854-spi.c
+++ b/drivers/staging/iio/meter/ade7854-spi.c
@@ -343,6 +343,7 @@
 	{ "ade7878", 0 },
 	{ }
 };
+MODULE_DEVICE_TABLE(spi, ade7854_id);
 
 static struct spi_driver ade7854_driver = {
 	.driver = {
diff --git a/drivers/staging/iio/resolver/ad2s1200.c b/drivers/staging/iio/resolver/ad2s1200.c
index 1c6a02b..d8ce854 100644
--- a/drivers/staging/iio/resolver/ad2s1200.c
+++ b/drivers/staging/iio/resolver/ad2s1200.c
@@ -160,6 +160,7 @@
 	{ "ad2s1205" },
 	{}
 };
+MODULE_DEVICE_TABLE(spi, ad2s1200_id);
 
 static struct spi_driver ad2s1200_driver = {
 	.driver = {
diff --git a/drivers/staging/iio/resolver/ad2s1210.c b/drivers/staging/iio/resolver/ad2s1210.c
index ff1b331..c439fcf 100644
--- a/drivers/staging/iio/resolver/ad2s1210.c
+++ b/drivers/staging/iio/resolver/ad2s1210.c
@@ -749,6 +749,7 @@
 	{ "ad2s1210" },
 	{}
 };
+MODULE_DEVICE_TABLE(spi, ad2s1210_id);
 
 static struct spi_driver ad2s1210_driver = {
 	.driver = {
diff --git a/drivers/staging/iio/resolver/ad2s90.c b/drivers/staging/iio/resolver/ad2s90.c
index 6d07943..2a86f58 100644
--- a/drivers/staging/iio/resolver/ad2s90.c
+++ b/drivers/staging/iio/resolver/ad2s90.c
@@ -109,6 +109,7 @@
 	{ "ad2s90" },
 	{}
 };
+MODULE_DEVICE_TABLE(spi, ad2s90_id);
 
 static struct spi_driver ad2s90_driver = {
 	.driver = {
diff --git a/drivers/staging/iio/ring_sw.c b/drivers/staging/iio/ring_sw.c
index 66a34ad..3e24ec4 100644
--- a/drivers/staging/iio/ring_sw.c
+++ b/drivers/staging/iio/ring_sw.c
@@ -23,11 +23,8 @@
  * @data:		the ring buffer memory
  * @read_p:		read pointer (oldest available)
  * @write_p:		write pointer
- * @last_written_p:	read pointer (newest available)
  * @half_p:		half buffer length behind write_p (event generation)
- * @use_count:		reference count to prevent resizing when in use
  * @update_needed:	flag to indicated change in size requested
- * @use_lock:		lock to prevent change in size when in use
  *
  * Note that the first element of all ring buffers must be a
  * struct iio_buffer.
@@ -37,12 +34,9 @@
 	unsigned char		*data;
 	unsigned char		*read_p;
 	unsigned char		*write_p;
-	unsigned char		*last_written_p;
 	/* used to act as a point at which to signal an event */
 	unsigned char		*half_p;
-	int			use_count;
 	int			update_needed;
-	spinlock_t		use_lock;
 };
 
 #define iio_to_sw_ring(r) container_of(r, struct iio_sw_ring_buffer, buf)
@@ -56,38 +50,15 @@
 	ring->data = kmalloc(length*ring->buf.bytes_per_datum, GFP_ATOMIC);
 	ring->read_p = NULL;
 	ring->write_p = NULL;
-	ring->last_written_p = NULL;
 	ring->half_p = NULL;
 	return ring->data ? 0 : -ENOMEM;
 }
 
-static inline void __iio_init_sw_ring_buffer(struct iio_sw_ring_buffer *ring)
-{
-	spin_lock_init(&ring->use_lock);
-}
-
 static inline void __iio_free_sw_ring_buffer(struct iio_sw_ring_buffer *ring)
 {
 	kfree(ring->data);
 }
 
-static void iio_mark_sw_rb_in_use(struct iio_buffer *r)
-{
-	struct iio_sw_ring_buffer *ring = iio_to_sw_ring(r);
-	spin_lock(&ring->use_lock);
-	ring->use_count++;
-	spin_unlock(&ring->use_lock);
-}
-
-static void iio_unmark_sw_rb_in_use(struct iio_buffer *r)
-{
-	struct iio_sw_ring_buffer *ring = iio_to_sw_ring(r);
-	spin_lock(&ring->use_lock);
-	ring->use_count--;
-	spin_unlock(&ring->use_lock);
-}
-
-
 /* Ring buffer related functionality */
 /* Store to ring is typically called in the bh of a data ready interrupt handler
  * in the device driver */
@@ -115,7 +86,6 @@
 	 * Always valid as either points to latest or second latest value.
 	 * Before this runs it is null and read attempts fail with -EAGAIN.
 	 */
-	ring->last_written_p = ring->write_p;
 	barrier();
 	/* temp_ptr used to ensure we never have an invalid pointer
 	 * it may be slightly lagging, but never invalid
@@ -174,6 +144,7 @@
 	u8 *initial_read_p, *initial_write_p, *current_read_p, *end_read_p;
 	u8 *data;
 	int ret, max_copied, bytes_to_rip, dead_offset;
+	size_t data_available, buffer_size;
 
 	/* A userspace program has probably made an error if it tries to
 	 *  read something that is not a whole number of bpds.
@@ -186,9 +157,11 @@
 		       n, ring->buf.bytes_per_datum);
 		goto error_ret;
 	}
+
+	buffer_size = ring->buf.bytes_per_datum*ring->buf.length;
+
 	/* Limit size to whole of ring buffer */
-	bytes_to_rip = min((size_t)(ring->buf.bytes_per_datum*ring->buf.length),
-			   n);
+	bytes_to_rip = min_t(size_t, buffer_size, n);
 
 	data = kmalloc(bytes_to_rip, GFP_KERNEL);
 	if (data == NULL) {
@@ -217,38 +190,24 @@
 		goto error_free_data_cpy;
 	}
 
-	if (initial_write_p >= initial_read_p + bytes_to_rip) {
-		/* write_p is greater than necessary, all is easy */
-		max_copied = bytes_to_rip;
+	if (initial_write_p >= initial_read_p)
+		data_available = initial_write_p - initial_read_p;
+	else
+		data_available = buffer_size - (initial_read_p - initial_write_p);
+
+	if (data_available < bytes_to_rip)
+		bytes_to_rip = data_available;
+
+	if (initial_read_p + bytes_to_rip >= ring->data + buffer_size) {
+		max_copied = ring->data + buffer_size - initial_read_p;
 		memcpy(data, initial_read_p, max_copied);
-		end_read_p = initial_read_p + max_copied;
-	} else if (initial_write_p > initial_read_p) {
-		/*not enough data to cpy */
-		max_copied = initial_write_p - initial_read_p;
-		memcpy(data, initial_read_p, max_copied);
-		end_read_p = initial_write_p;
+		memcpy(data + max_copied, ring->data, bytes_to_rip - max_copied);
+		end_read_p = ring->data + bytes_to_rip - max_copied;
 	} else {
-		/* going through 'end' of ring buffer */
-		max_copied = ring->data
-			+ ring->buf.length*ring->buf.bytes_per_datum - initial_read_p;
-		memcpy(data, initial_read_p, max_copied);
-		/* possible we are done if we align precisely with end */
-		if (max_copied == bytes_to_rip)
-			end_read_p = ring->data;
-		else if (initial_write_p
-			 > ring->data + bytes_to_rip - max_copied) {
-			/* enough data to finish */
-			memcpy(data + max_copied, ring->data,
-			       bytes_to_rip - max_copied);
-			max_copied = bytes_to_rip;
-			end_read_p = ring->data + (bytes_to_rip - max_copied);
-		} else {  /* not enough data */
-			memcpy(data + max_copied, ring->data,
-			       initial_write_p - ring->data);
-			max_copied += initial_write_p - ring->data;
-			end_read_p = initial_write_p;
-		}
+		memcpy(data, initial_read_p, bytes_to_rip);
+		end_read_p = initial_read_p + bytes_to_rip;
 	}
+
 	/* Now to verify which section was cleanly copied - i.e. how far
 	 * read pointer has been pushed */
 	current_read_p = ring->read_p;
@@ -256,15 +215,14 @@
 	if (initial_read_p <= current_read_p)
 		dead_offset = current_read_p - initial_read_p;
 	else
-		dead_offset = ring->buf.length*ring->buf.bytes_per_datum
-			- (initial_read_p - current_read_p);
+		dead_offset = buffer_size - (initial_read_p - current_read_p);
 
 	/* possible issue if the initial write has been lapped or indeed
 	 * the point we were reading to has been passed */
 	/* No valid data read.
 	 * In this case the read pointer is already correct having been
 	 * pushed further than we would look. */
-	if (max_copied - dead_offset < 0) {
+	if (bytes_to_rip - dead_offset < 0) {
 		ret = 0;
 		goto error_free_data_cpy;
 	}
@@ -280,7 +238,7 @@
 	while (ring->read_p != end_read_p)
 		ring->read_p = end_read_p;
 
-	ret = max_copied - dead_offset;
+	ret = bytes_to_rip - dead_offset;
 
 	if (copy_to_user(buf, data + dead_offset, ret))  {
 		ret =  -EFAULT;
@@ -305,52 +263,18 @@
 	return iio_store_to_sw_ring(ring, data, timestamp);
 }
 
-static int iio_read_last_from_sw_ring(struct iio_sw_ring_buffer *ring,
-				      unsigned char *data)
-{
-	unsigned char *last_written_p_copy;
-
-	iio_mark_sw_rb_in_use(&ring->buf);
-again:
-	barrier();
-	last_written_p_copy = ring->last_written_p;
-	barrier(); /*unnessecary? */
-	/* Check there is anything here */
-	if (last_written_p_copy == NULL)
-		return -EAGAIN;
-	memcpy(data, last_written_p_copy, ring->buf.bytes_per_datum);
-
-	if (unlikely(ring->last_written_p != last_written_p_copy))
-		goto again;
-
-	iio_unmark_sw_rb_in_use(&ring->buf);
-	return 0;
-}
-
-static int iio_read_last_from_sw_rb(struct iio_buffer *r,
-			     unsigned char *data)
-{
-	return iio_read_last_from_sw_ring(iio_to_sw_ring(r), data);
-}
-
 static int iio_request_update_sw_rb(struct iio_buffer *r)
 {
 	int ret = 0;
 	struct iio_sw_ring_buffer *ring = iio_to_sw_ring(r);
 
 	r->stufftoread = false;
-	spin_lock(&ring->use_lock);
 	if (!ring->update_needed)
 		goto error_ret;
-	if (ring->use_count) {
-		ret = -EAGAIN;
-		goto error_ret;
-	}
 	__iio_free_sw_ring_buffer(ring);
 	ret = __iio_allocate_sw_ring_buffer(ring, ring->buf.bytes_per_datum,
 					    ring->buf.length);
 error_ret:
-	spin_unlock(&ring->use_lock);
 	return ret;
 }
 
@@ -360,12 +284,18 @@
 	return ring->buf.bytes_per_datum;
 }
 
+static int iio_mark_update_needed_sw_rb(struct iio_buffer *r)
+{
+	struct iio_sw_ring_buffer *ring = iio_to_sw_ring(r);
+	ring->update_needed = true;
+	return 0;
+}
+
 static int iio_set_bytes_per_datum_sw_rb(struct iio_buffer *r, size_t bpd)
 {
 	if (r->bytes_per_datum != bpd) {
 		r->bytes_per_datum = bpd;
-		if (r->access->mark_param_change)
-			r->access->mark_param_change(r);
+		iio_mark_update_needed_sw_rb(r);
 	}
 	return 0;
 }
@@ -379,27 +309,17 @@
 {
 	if (r->length != length) {
 		r->length = length;
-		if (r->access->mark_param_change)
-			r->access->mark_param_change(r);
+		iio_mark_update_needed_sw_rb(r);
 	}
 	return 0;
 }
 
-static int iio_mark_update_needed_sw_rb(struct iio_buffer *r)
-{
-	struct iio_sw_ring_buffer *ring = iio_to_sw_ring(r);
-	ring->update_needed = true;
-	return 0;
-}
-
 static IIO_BUFFER_ENABLE_ATTR;
-static IIO_BUFFER_BYTES_PER_DATUM_ATTR;
 static IIO_BUFFER_LENGTH_ATTR;
 
 /* Standard set of ring buffer attributes */
 static struct attribute *iio_ring_attributes[] = {
 	&dev_attr_length.attr,
-	&dev_attr_bytes_per_datum.attr,
 	&dev_attr_enable.attr,
 	NULL,
 };
@@ -419,8 +339,7 @@
 		return NULL;
 	ring->update_needed = true;
 	buf = &ring->buf;
-	iio_buffer_init(buf, indio_dev);
-	__iio_init_sw_ring_buffer(ring);
+	iio_buffer_init(buf);
 	buf->attrs = &iio_ring_attribute_group;
 
 	return buf;
@@ -434,12 +353,8 @@
 EXPORT_SYMBOL(iio_sw_rb_free);
 
 const struct iio_buffer_access_funcs ring_sw_access_funcs = {
-	.mark_in_use = &iio_mark_sw_rb_in_use,
-	.unmark_in_use = &iio_unmark_sw_rb_in_use,
 	.store_to = &iio_store_to_sw_rb,
-	.read_last = &iio_read_last_from_sw_rb,
 	.read_first_n = &iio_read_first_n_sw_rb,
-	.mark_param_change = &iio_mark_update_needed_sw_rb,
 	.request_update = &iio_request_update_sw_rb,
 	.get_bytes_per_datum = &iio_get_bytes_per_datum_sw_rb,
 	.set_bytes_per_datum = &iio_set_bytes_per_datum_sw_rb,
diff --git a/drivers/staging/iio/ring_sw.h b/drivers/staging/iio/ring_sw.h
index a3e1578..e6a6e2c 100644
--- a/drivers/staging/iio/ring_sw.h
+++ b/drivers/staging/iio/ring_sw.h
@@ -23,7 +23,7 @@
 
 #ifndef _IIO_RING_SW_H_
 #define _IIO_RING_SW_H_
-#include "buffer_generic.h"
+#include "buffer.h"
 
 /**
  * ring_sw_access_funcs - access functions for a software ring buffer
diff --git a/drivers/staging/iio/sysfs.h b/drivers/staging/iio/sysfs.h
index 868952b..bfedb73 100644
--- a/drivers/staging/iio/sysfs.h
+++ b/drivers/staging/iio/sysfs.h
@@ -114,47 +114,4 @@
 #define IIO_CONST_ATTR_TEMP_SCALE(_string)		\
 	IIO_CONST_ATTR(in_temp_scale, _string)
 
-enum iio_event_type {
-	IIO_EV_TYPE_THRESH,
-	IIO_EV_TYPE_MAG,
-	IIO_EV_TYPE_ROC,
-	IIO_EV_TYPE_THRESH_ADAPTIVE,
-	IIO_EV_TYPE_MAG_ADAPTIVE,
-};
-
-enum iio_event_direction {
-	IIO_EV_DIR_EITHER,
-	IIO_EV_DIR_RISING,
-	IIO_EV_DIR_FALLING,
-};
-
-#define IIO_EVENT_CODE(chan_type, diff, modifier, direction,		\
-		       type, chan, chan1, chan2)			\
-	(((u64)type << 56) | ((u64)diff << 55) |			\
-	 ((u64)direction << 48) | ((u64)modifier << 40) |		\
-	 ((u64)chan_type << 32) | (chan2 << 16) | chan1 | chan)
-
-#define IIO_EV_DIR_MAX 4
-#define IIO_EV_BIT(type, direction)			\
-	(1 << (type*IIO_EV_DIR_MAX + direction))
-
-#define IIO_MOD_EVENT_CODE(channelclass, number, modifier,		\
-			   type, direction)				\
-	IIO_EVENT_CODE(channelclass, 0, modifier, direction, type, number, 0, 0)
-
-#define IIO_UNMOD_EVENT_CODE(channelclass, number, type, direction)	\
-	IIO_EVENT_CODE(channelclass, 0, 0, direction, type, number, 0, 0)
-
-#define IIO_EVENT_CODE_EXTRACT_TYPE(mask) ((mask >> 56) & 0xFF)
-
-#define IIO_EVENT_CODE_EXTRACT_DIR(mask) ((mask >> 48) & 0xCF)
-
-#define IIO_EVENT_CODE_EXTRACT_CHAN_TYPE(mask) ((mask >> 32) & 0xFF)
-
-/* Event code number extraction depends on which type of event we have.
- * Perhaps review this function in the future*/
-#define IIO_EVENT_CODE_EXTRACT_NUM(mask) (mask & 0xFFFF)
-
-#define IIO_EVENT_CODE_EXTRACT_MODIFIER(mask) ((mask >> 40) & 0xFF)
-
 #endif /* _INDUSTRIAL_IO_SYSFS_H_ */
diff --git a/drivers/staging/iio/trigger.h b/drivers/staging/iio/trigger.h
index 5cc42a6..1cfca23 100644
--- a/drivers/staging/iio/trigger.h
+++ b/drivers/staging/iio/trigger.h
@@ -46,7 +46,6 @@
  * @private_data:	[DRIVER] device specific data
  * @list:		[INTERN] used in maintenance of global trigger list
  * @alloc_list:		[DRIVER] used for driver specific trigger list
- * @owner:		[DRIVER] used to monitor usage count of the trigger.
  * @use_count:		use count for the trigger
  * @subirq_chip:	[INTERN] associate 'virtual' irq chip.
  * @subirq_base:	[INTERN] base number for irqs provided by trigger.
@@ -63,7 +62,6 @@
 	void				*private_data;
 	struct list_head		list;
 	struct list_head		alloc_list;
-	struct module			*owner;
 	int use_count;
 
 	struct irq_chip			subirq_chip;
diff --git a/drivers/staging/iio/trigger/iio-trig-periodic-rtc.c b/drivers/staging/iio/trigger/iio-trig-periodic-rtc.c
index d35d085..bd7416b 100644
--- a/drivers/staging/iio/trigger/iio-trig-periodic-rtc.c
+++ b/drivers/staging/iio/trigger/iio-trig-periodic-rtc.c
@@ -125,7 +125,6 @@
 			goto error_put_trigger_and_remove_from_list;
 		}
 		trig->private_data = trig_info;
-		trig->owner = THIS_MODULE;
 		trig->ops = &iio_prtc_trigger_ops;
 		/* RTC access */
 		trig_info->rtc
diff --git a/drivers/staging/iio/types.h b/drivers/staging/iio/types.h
new file mode 100644
index 0000000..b7d2647
--- /dev/null
+++ b/drivers/staging/iio/types.h
@@ -0,0 +1,49 @@
+/* industrial I/O data types needed both in and out of kernel
+ *
+ * Copyright (c) 2008 Jonathan Cameron
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ */
+
+#ifndef _IIO_TYPES_H_
+#define _IIO_TYPES_H_
+
+enum iio_chan_type {
+	/* real channel types */
+	IIO_VOLTAGE,
+	IIO_CURRENT,
+	IIO_POWER,
+	IIO_ACCEL,
+	IIO_ANGL_VEL,
+	IIO_MAGN,
+	IIO_LIGHT,
+	IIO_INTENSITY,
+	IIO_PROXIMITY,
+	IIO_TEMP,
+	IIO_INCLI,
+	IIO_ROT,
+	IIO_ANGL,
+	IIO_TIMESTAMP,
+	IIO_CAPACITANCE,
+};
+
+enum iio_modifier {
+	IIO_NO_MOD,
+	IIO_MOD_X,
+	IIO_MOD_Y,
+	IIO_MOD_Z,
+	IIO_MOD_X_AND_Y,
+	IIO_MOD_X_AND_Z,
+	IIO_MOD_Y_AND_Z,
+	IIO_MOD_X_AND_Y_AND_Z,
+	IIO_MOD_X_OR_Y,
+	IIO_MOD_X_OR_Z,
+	IIO_MOD_Y_OR_Z,
+	IIO_MOD_X_OR_Y_OR_Z,
+	IIO_MOD_LIGHT_BOTH,
+	IIO_MOD_LIGHT_IR,
+};
+
+#endif /* _IIO_TYPES_H_ */
diff --git a/drivers/staging/intel_sst/Kconfig b/drivers/staging/intel_sst/Kconfig
deleted file mode 100644
index 8239107..0000000
--- a/drivers/staging/intel_sst/Kconfig
+++ /dev/null
@@ -1,19 +0,0 @@
-config SND_INTEL_SST
-	tristate "Intel SST (LPE) Driver"
-	depends on X86 && INTEL_SCU_IPC
-	default n
-	help
-	  Say Y here to include support for the Intel(R) MID SST DSP driver
-	  On other PC platforms if you are unsure answer 'N'
-
-config SND_INTELMID
-	tristate "Intel MID sound card driver"
-	depends on SOUND && SND
-	select SND_PCM
-	select SND_SEQUENCER
-	select SND_JACK
-	depends on SND_INTEL_SST
-	default n
-	help
-	  Say Y here to include support for the Intel(R) MID sound card driver
-	  On other PC platforms if you are unsure answer 'N'
diff --git a/drivers/staging/intel_sst/Makefile b/drivers/staging/intel_sst/Makefile
deleted file mode 100644
index 9eb7c15..0000000
--- a/drivers/staging/intel_sst/Makefile
+++ /dev/null
@@ -1,7 +0,0 @@
-#
-# Makefile for Intel MID Audio drivers
-#
-snd-intel-sst-y := intel_sst.o intel_sst_ipc.o intel_sst_stream.o intel_sst_drv_interface.o intel_sst_dsp.o intel_sst_pvt.o intel_sst_stream_encoded.o intel_sst_app_interface.o
-snd-intelmid-y := intelmid.o intelmid_msic_control.o intelmid_ctrl.o intelmid_pvt.o intelmid_v0_control.o intelmid_v1_control.o intelmid_v2_control.o
-obj-$(CONFIG_SND_INTEL_SST) += snd-intel-sst.o
-obj-$(CONFIG_SND_INTELMID) += snd-intelmid.o
diff --git a/drivers/staging/intel_sst/TODO b/drivers/staging/intel_sst/TODO
deleted file mode 100644
index c733d70..0000000
--- a/drivers/staging/intel_sst/TODO
+++ /dev/null
@@ -1,13 +0,0 @@
-TODO
-----
-
-Get the memrar driver cleaned up and upstream (dependency blocking SST)
-Replace long/short press with two virtual buttons
-Review the printks and kill off any left over ST_ERR: messages
-Review the misc device ioctls for 32/64bit safety and sanity
-Review the misc device ioctls for size safety depending on config and decide
-	if space/unused areas should be left
-What the sound folks turn up on full review
-Using the ALSA frameworks properly
-
-
diff --git a/drivers/staging/intel_sst/intel_sst.c b/drivers/staging/intel_sst/intel_sst.c
deleted file mode 100644
index ff9aaec..0000000
--- a/drivers/staging/intel_sst/intel_sst.c
+++ /dev/null
@@ -1,649 +0,0 @@
-/*
- *  intel_sst.c - Intel SST Driver for audio engine
- *
- *  Copyright (C) 2008-10	Intel Corp
- *  Authors:	Vinod Koul <vinod.koul@intel.com>
- *		Harsha Priya <priya.harsha@intel.com>
- *		Dharageswari R <dharageswari.r@intel.com>
- *		KP Jeeja <jeeja.kp@intel.com>
- *  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; version 2 of the License.
- *
- *  This program is distributed in the hope that it will be useful, but
- *  WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *  General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License along
- *  with this program; if not, write to the Free Software Foundation, Inc.,
- *  59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
- *
- * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- *
- *  This driver exposes the audio engine functionalities to the ALSA
- *	 and middleware.
- *
- *  This file contains all init functions
- */
-
-#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
-
-#include <linux/pci.h>
-#include <linux/fs.h>
-#include <linux/interrupt.h>
-#include <linux/firmware.h>
-#include <linux/miscdevice.h>
-#include <linux/pm_runtime.h>
-#include <linux/module.h>
-#include <asm/mrst.h>
-#include "intel_sst.h"
-#include "intel_sst_ioctl.h"
-#include "intel_sst_fw_ipc.h"
-#include "intel_sst_common.h"
-
-
-MODULE_AUTHOR("Vinod Koul <vinod.koul@intel.com>");
-MODULE_AUTHOR("Harsha Priya <priya.harsha@intel.com>");
-MODULE_AUTHOR("Dharageswari R <dharageswari.r@intel.com>");
-MODULE_AUTHOR("KP Jeeja <jeeja.kp@intel.com>");
-MODULE_DESCRIPTION("Intel (R) SST(R) Audio Engine Driver");
-MODULE_LICENSE("GPL v2");
-MODULE_VERSION(SST_DRIVER_VERSION);
-
-struct intel_sst_drv *sst_drv_ctx;
-static struct mutex drv_ctx_lock;
-struct class *sst_class;
-
-/* fops Routines */
-static const struct file_operations intel_sst_fops = {
-	.owner = THIS_MODULE,
-	.open = intel_sst_open,
-	.release = intel_sst_release,
-	.read = intel_sst_read,
-	.write = intel_sst_write,
-	.unlocked_ioctl = intel_sst_ioctl,
-	.mmap = intel_sst_mmap,
-	.aio_read = intel_sst_aio_read,
-	.aio_write = intel_sst_aio_write,
-};
-static const struct file_operations intel_sst_fops_cntrl = {
-	.owner = THIS_MODULE,
-	.open = intel_sst_open_cntrl,
-	.release = intel_sst_release_cntrl,
-	.unlocked_ioctl = intel_sst_ioctl,
-};
-
-static struct miscdevice lpe_dev = {
-	.minor = MISC_DYNAMIC_MINOR,/* dynamic allocation */
-	.name = "intel_sst",/* /dev/intel_sst */
-	.fops = &intel_sst_fops
-};
-
-
-static struct miscdevice lpe_ctrl = {
-	.minor = MISC_DYNAMIC_MINOR,/* dynamic allocation */
-	.name = "intel_sst_ctrl",/* /dev/intel_sst_ctrl */
-	.fops = &intel_sst_fops_cntrl
-};
-
-/**
-* intel_sst_interrupt - Interrupt service routine for SST
-*
-* @irq:	irq number of interrupt
-* @context: pointer to device structre
-*
-* This function is called by OS when SST device raises
-* an interrupt. This will be result of write in IPC register
-* Source can be busy or done interrupt
-*/
-static irqreturn_t intel_sst_interrupt(int irq, void *context)
-{
-	union interrupt_reg isr;
-	union ipc_header header;
-	union interrupt_reg imr;
-	struct intel_sst_drv *drv = (struct intel_sst_drv *) context;
-	unsigned int size = 0, str_id;
-	struct stream_info *stream ;
-
-	/* Do not handle interrupt in suspended state */
-	if (drv->sst_state == SST_SUSPENDED)
-		return IRQ_NONE;
-	/* Interrupt arrived, check src */
-	isr.full = sst_shim_read(drv->shim, SST_ISRX);
-
-	if (isr.part.busy_interrupt) {
-		header.full = sst_shim_read(drv->shim, SST_IPCD);
-		if (header.part.msg_id == IPC_SST_PERIOD_ELAPSED) {
-			sst_clear_interrupt();
-			str_id = header.part.str_id;
-			stream = &sst_drv_ctx->streams[str_id];
-			if (stream->period_elapsed)
-				stream->period_elapsed(stream->pcm_substream);
-			return IRQ_HANDLED;
-		}
-		if (header.part.large)
-			size = header.part.data;
-		if (header.part.msg_id & REPLY_MSG) {
-			sst_drv_ctx->ipc_process_msg.header = header;
-			memcpy_fromio(sst_drv_ctx->ipc_process_msg.mailbox,
-				drv->mailbox + SST_MAILBOX_RCV, size);
-			queue_work(sst_drv_ctx->process_msg_wq,
-					&sst_drv_ctx->ipc_process_msg.wq);
-		} else {
-			sst_drv_ctx->ipc_process_reply.header = header;
-			memcpy_fromio(sst_drv_ctx->ipc_process_reply.mailbox,
-				drv->mailbox + SST_MAILBOX_RCV, size);
-			queue_work(sst_drv_ctx->process_reply_wq,
-					&sst_drv_ctx->ipc_process_reply.wq);
-		}
-		/* mask busy inetrrupt */
-		imr.full = sst_shim_read(drv->shim, SST_IMRX);
-		imr.part.busy_interrupt = 1;
-		sst_shim_write(sst_drv_ctx->shim, SST_IMRX, imr.full);
-		return IRQ_HANDLED;
-	} else if (isr.part.done_interrupt) {
-		/* Clear done bit */
-		header.full = sst_shim_read(drv->shim, SST_IPCX);
-		header.part.done = 0;
-		sst_shim_write(sst_drv_ctx->shim, SST_IPCX, header.full);
-		/* write 1 to clear status register */;
-		isr.part.done_interrupt = 1;
-		/* dummy register for shim workaround */
-		sst_shim_write(sst_drv_ctx->shim, SST_ISRX, isr.full);
-		queue_work(sst_drv_ctx->post_msg_wq,
-			&sst_drv_ctx->ipc_post_msg.wq);
-		return IRQ_HANDLED;
-	} else
-		return IRQ_NONE;
-
-}
-
-
-/*
-* intel_sst_probe - PCI probe function
-*
-* @pci:	PCI device structure
-* @pci_id: PCI device ID structure
-*
-* This function is called by OS when a device is found
-* This enables the device, interrupt etc
-*/
-static int __devinit intel_sst_probe(struct pci_dev *pci,
-			const struct pci_device_id *pci_id)
-{
-	int i, ret = 0;
-
-	pr_debug("Probe for DID %x\n", pci->device);
-	mutex_lock(&drv_ctx_lock);
-	if (sst_drv_ctx) {
-		pr_err("Only one sst handle is supported\n");
-		mutex_unlock(&drv_ctx_lock);
-		return -EBUSY;
-	}
-
-	sst_drv_ctx = kzalloc(sizeof(*sst_drv_ctx), GFP_KERNEL);
-	if (!sst_drv_ctx) {
-		pr_err("malloc fail\n");
-		mutex_unlock(&drv_ctx_lock);
-		return -ENOMEM;
-	}
-	mutex_unlock(&drv_ctx_lock);
-
-	sst_drv_ctx->pci_id = pci->device;
-
-	mutex_init(&sst_drv_ctx->stream_lock);
-	mutex_init(&sst_drv_ctx->sst_lock);
-	sst_drv_ctx->pmic_state = SND_MAD_UN_INIT;
-
-	sst_drv_ctx->stream_cnt = 0;
-	sst_drv_ctx->encoded_cnt = 0;
-	sst_drv_ctx->am_cnt = 0;
-	sst_drv_ctx->pb_streams = 0;
-	sst_drv_ctx->cp_streams = 0;
-	sst_drv_ctx->unique_id = 0;
-	sst_drv_ctx->pmic_port_instance = SST_DEFAULT_PMIC_PORT;
-
-	INIT_LIST_HEAD(&sst_drv_ctx->ipc_dispatch_list);
-	INIT_WORK(&sst_drv_ctx->ipc_post_msg.wq, sst_post_message);
-	INIT_WORK(&sst_drv_ctx->ipc_process_msg.wq, sst_process_message);
-	INIT_WORK(&sst_drv_ctx->ipc_process_reply.wq, sst_process_reply);
-	INIT_WORK(&sst_drv_ctx->mad_ops.wq, sst_process_mad_ops);
-	init_waitqueue_head(&sst_drv_ctx->wait_queue);
-
-	sst_drv_ctx->mad_wq = create_workqueue("sst_mad_wq");
-	if (!sst_drv_ctx->mad_wq)
-		goto do_free_drv_ctx;
-	sst_drv_ctx->post_msg_wq = create_workqueue("sst_post_msg_wq");
-	if (!sst_drv_ctx->post_msg_wq)
-		goto free_mad_wq;
-	sst_drv_ctx->process_msg_wq = create_workqueue("sst_process_msg_wqq");
-	if (!sst_drv_ctx->process_msg_wq)
-		goto free_post_msg_wq;
-	sst_drv_ctx->process_reply_wq = create_workqueue("sst_proces_reply_wq");
-	if (!sst_drv_ctx->process_reply_wq)
-		goto free_process_msg_wq;
-
-	for (i = 0; i < MAX_ACTIVE_STREAM; i++) {
-		sst_drv_ctx->alloc_block[i].sst_id = BLOCK_UNINIT;
-		sst_drv_ctx->alloc_block[i].ops_block.condition = false;
-	}
-	spin_lock_init(&sst_drv_ctx->list_spin_lock);
-
-	sst_drv_ctx->max_streams = pci_id->driver_data;
-	pr_debug("Got drv data max stream %d\n",
-				sst_drv_ctx->max_streams);
-	for (i = 1; i <= sst_drv_ctx->max_streams; i++) {
-		struct stream_info *stream = &sst_drv_ctx->streams[i];
-		INIT_LIST_HEAD(&stream->bufs);
-		mutex_init(&stream->lock);
-		spin_lock_init(&stream->pcm_lock);
-	}
-	if (sst_drv_ctx->pci_id == SST_MRST_PCI_ID) {
-		sst_drv_ctx->mmap_mem = NULL;
-		sst_drv_ctx->mmap_len = SST_MMAP_PAGES * PAGE_SIZE;
-		while (sst_drv_ctx->mmap_len > 0) {
-			sst_drv_ctx->mmap_mem =
-				kzalloc(sst_drv_ctx->mmap_len, GFP_KERNEL);
-			if (sst_drv_ctx->mmap_mem) {
-				pr_debug("Got memory %p size 0x%x\n",
-					sst_drv_ctx->mmap_mem,
-					sst_drv_ctx->mmap_len);
-				break;
-			}
-			if (sst_drv_ctx->mmap_len < (SST_MMAP_STEP*PAGE_SIZE)) {
-				pr_err("mem alloc fail...abort!!\n");
-				ret = -ENOMEM;
-				goto free_process_reply_wq;
-			}
-			sst_drv_ctx->mmap_len -= (SST_MMAP_STEP * PAGE_SIZE);
-			pr_debug("mem alloc failed...trying %d\n",
-						sst_drv_ctx->mmap_len);
-		}
-	}
-
-	/* Init the device */
-	ret = pci_enable_device(pci);
-	if (ret) {
-		pr_err("device can't be enabled\n");
-		goto do_free_mem;
-	}
-	sst_drv_ctx->pci = pci_dev_get(pci);
-	ret = pci_request_regions(pci, SST_DRV_NAME);
-	if (ret)
-		goto do_disable_device;
-	/* map registers */
-	/* SST Shim */
-	sst_drv_ctx->shim_phy_add = pci_resource_start(pci, 1);
-	sst_drv_ctx->shim = pci_ioremap_bar(pci, 1);
-	if (!sst_drv_ctx->shim)
-		goto do_release_regions;
-	pr_debug("SST Shim Ptr %p\n", sst_drv_ctx->shim);
-
-	/* Shared SRAM */
-	sst_drv_ctx->mailbox = pci_ioremap_bar(pci, 2);
-	if (!sst_drv_ctx->mailbox)
-		goto do_unmap_shim;
-	pr_debug("SRAM Ptr %p\n", sst_drv_ctx->mailbox);
-
-	/* IRAM */
-	sst_drv_ctx->iram = pci_ioremap_bar(pci, 3);
-	if (!sst_drv_ctx->iram)
-		goto do_unmap_sram;
-	pr_debug("IRAM Ptr %p\n", sst_drv_ctx->iram);
-
-	/* DRAM */
-	sst_drv_ctx->dram = pci_ioremap_bar(pci, 4);
-	if (!sst_drv_ctx->dram)
-		goto do_unmap_iram;
-	pr_debug("DRAM Ptr %p\n", sst_drv_ctx->dram);
-
-	mutex_lock(&sst_drv_ctx->sst_lock);
-	sst_drv_ctx->sst_state = SST_UN_INIT;
-	mutex_unlock(&sst_drv_ctx->sst_lock);
-	/* Register the ISR */
-	ret = request_irq(pci->irq, intel_sst_interrupt,
-		IRQF_SHARED, SST_DRV_NAME, sst_drv_ctx);
-	if (ret)
-		goto do_unmap_dram;
-	pr_debug("Registered IRQ 0x%x\n", pci->irq);
-
-	/*Register LPE Control as misc driver*/
-	ret = misc_register(&lpe_ctrl);
-	if (ret) {
-		pr_err("couldn't register control device\n");
-		goto do_free_irq;
-	}
-
-	if (sst_drv_ctx->pci_id == SST_MRST_PCI_ID) {
-		ret = misc_register(&lpe_dev);
-		if (ret) {
-			pr_err("couldn't register LPE device\n");
-			goto do_free_misc;
-		}
-	} else if (sst_drv_ctx->pci_id == SST_MFLD_PCI_ID) {
-		u32 csr;
-
-		/*allocate mem for fw context save during suspend*/
-		sst_drv_ctx->fw_cntx = kzalloc(FW_CONTEXT_MEM, GFP_KERNEL);
-		if (!sst_drv_ctx->fw_cntx) {
-			ret = -ENOMEM;
-			goto do_free_misc;
-		}
-		/*setting zero as that is valid mem to restore*/
-		sst_drv_ctx->fw_cntx_size = 0;
-
-		/*set lpe start clock and ram size*/
-		csr = sst_shim_read(sst_drv_ctx->shim, SST_CSR);
-		csr |= 0x30060; /*remove the clock ratio after fw fix*/
-		sst_shim_write(sst_drv_ctx->shim, SST_CSR, csr);
-	}
-	sst_drv_ctx->lpe_stalled = 0;
-	pci_set_drvdata(pci, sst_drv_ctx);
-	pm_runtime_allow(&pci->dev);
-	pm_runtime_put_noidle(&pci->dev);
-	pr_debug("...successfully done!!!\n");
-	return ret;
-
-do_free_misc:
-	misc_deregister(&lpe_ctrl);
-do_free_irq:
-	free_irq(pci->irq, sst_drv_ctx);
-do_unmap_dram:
-	iounmap(sst_drv_ctx->dram);
-do_unmap_iram:
-	iounmap(sst_drv_ctx->iram);
-do_unmap_sram:
-	iounmap(sst_drv_ctx->mailbox);
-do_unmap_shim:
-	iounmap(sst_drv_ctx->shim);
-do_release_regions:
-	pci_release_regions(pci);
-do_disable_device:
-	pci_disable_device(pci);
-do_free_mem:
-	kfree(sst_drv_ctx->mmap_mem);
-free_process_reply_wq:
-	destroy_workqueue(sst_drv_ctx->process_reply_wq);
-free_process_msg_wq:
-	destroy_workqueue(sst_drv_ctx->process_msg_wq);
-free_post_msg_wq:
-	destroy_workqueue(sst_drv_ctx->post_msg_wq);
-free_mad_wq:
-	destroy_workqueue(sst_drv_ctx->mad_wq);
-do_free_drv_ctx:
-	kfree(sst_drv_ctx);
-	sst_drv_ctx = NULL;
-	pr_err("Probe failed with %d\n", ret);
-	return ret;
-}
-
-/**
-* intel_sst_remove - PCI remove function
-*
-* @pci:	PCI device structure
-*
-* This function is called by OS when a device is unloaded
-* This frees the interrupt etc
-*/
-static void __devexit intel_sst_remove(struct pci_dev *pci)
-{
-	pm_runtime_get_noresume(&pci->dev);
-	pm_runtime_forbid(&pci->dev);
-	pci_dev_put(sst_drv_ctx->pci);
-	mutex_lock(&sst_drv_ctx->sst_lock);
-	sst_drv_ctx->sst_state = SST_UN_INIT;
-	mutex_unlock(&sst_drv_ctx->sst_lock);
-	misc_deregister(&lpe_ctrl);
-	free_irq(pci->irq, sst_drv_ctx);
-	iounmap(sst_drv_ctx->dram);
-	iounmap(sst_drv_ctx->iram);
-	iounmap(sst_drv_ctx->mailbox);
-	iounmap(sst_drv_ctx->shim);
-	sst_drv_ctx->pmic_state = SND_MAD_UN_INIT;
-	if (sst_drv_ctx->pci_id == SST_MRST_PCI_ID) {
-		misc_deregister(&lpe_dev);
-		kfree(sst_drv_ctx->mmap_mem);
-	} else
-		kfree(sst_drv_ctx->fw_cntx);
-	flush_scheduled_work();
-	destroy_workqueue(sst_drv_ctx->process_reply_wq);
-	destroy_workqueue(sst_drv_ctx->process_msg_wq);
-	destroy_workqueue(sst_drv_ctx->post_msg_wq);
-	destroy_workqueue(sst_drv_ctx->mad_wq);
-	kfree(pci_get_drvdata(pci));
-	sst_drv_ctx = NULL;
-	pci_release_regions(pci);
-	pci_disable_device(pci);
-	pci_set_drvdata(pci, NULL);
-}
-
-void sst_save_dsp_context(void)
-{
-	struct snd_sst_ctxt_params fw_context;
-	unsigned int pvt_id, i;
-	struct ipc_post *msg = NULL;
-
-	/*check cpu type*/
-	if (sst_drv_ctx->pci_id != SST_MFLD_PCI_ID)
-		return;
-		/*not supported for rest*/
-	if (sst_drv_ctx->sst_state != SST_FW_RUNNING) {
-		pr_debug("fw not running no context save ...\n");
-		return;
-	}
-
-	/*send msg to fw*/
-	if (sst_create_large_msg(&msg))
-		return;
-	pvt_id = sst_assign_pvt_id(sst_drv_ctx);
-	i = sst_get_block_stream(sst_drv_ctx);
-	sst_drv_ctx->alloc_block[i].sst_id = pvt_id;
-	sst_fill_header(&msg->header, IPC_IA_GET_FW_CTXT, 1, pvt_id);
-	msg->header.part.data = sizeof(fw_context) + sizeof(u32);
-	fw_context.address = virt_to_phys((void *)sst_drv_ctx->fw_cntx);
-	fw_context.size = FW_CONTEXT_MEM;
-	memcpy(msg->mailbox_data, &msg->header, sizeof(u32));
-	memcpy(msg->mailbox_data + sizeof(u32),
-				&fw_context, sizeof(fw_context));
-	spin_lock(&sst_drv_ctx->list_spin_lock);
-	list_add_tail(&msg->node, &sst_drv_ctx->ipc_dispatch_list);
-	spin_unlock(&sst_drv_ctx->list_spin_lock);
-	sst_post_message(&sst_drv_ctx->ipc_post_msg_wq);
-	/*wait for reply*/
-	if (sst_wait_timeout(sst_drv_ctx, &sst_drv_ctx->alloc_block[i]))
-		pr_debug("err fw context save timeout  ...\n");
-	sst_drv_ctx->alloc_block[i].sst_id = BLOCK_UNINIT;
-	pr_debug("fw context saved  ...\n");
-	return;
-}
-
-/* Power Management */
-/*
-* intel_sst_suspend - PCI suspend function
-*
-* @pci: PCI device structure
-* @state: PM message
-*
-* This function is called by OS when a power event occurs
-*/
-int intel_sst_suspend(struct pci_dev *pci, pm_message_t state)
-{
-	union config_status_reg csr;
-
-	pr_debug("intel_sst_suspend called\n");
-
-	if (sst_drv_ctx->stream_cnt) {
-		pr_err("active streams,not able to suspend\n");
-		return -EBUSY;
-	}
-	/*save fw context*/
-	sst_save_dsp_context();
-	/*Assert RESET on LPE Processor*/
-	csr.full = sst_shim_read(sst_drv_ctx->shim, SST_CSR);
-	csr.full = csr.full | 0x2;
-	/* Move the SST state to Suspended */
-	mutex_lock(&sst_drv_ctx->sst_lock);
-	sst_drv_ctx->sst_state = SST_SUSPENDED;
-	sst_shim_write(sst_drv_ctx->shim, SST_CSR, csr.full);
-	mutex_unlock(&sst_drv_ctx->sst_lock);
-	pci_set_drvdata(pci, sst_drv_ctx);
-	pci_save_state(pci);
-	pci_disable_device(pci);
-	pci_set_power_state(pci, PCI_D3hot);
-	return 0;
-}
-
-/**
-* intel_sst_resume - PCI resume function
-*
-* @pci:	PCI device structure
-*
-* This function is called by OS when a power event occurs
-*/
-int intel_sst_resume(struct pci_dev *pci)
-{
-	int ret = 0;
-
-	pr_debug("intel_sst_resume called\n");
-	if (sst_drv_ctx->sst_state != SST_SUSPENDED) {
-		pr_err("SST is not in suspended state\n");
-		return 0;
-	}
-	sst_drv_ctx = pci_get_drvdata(pci);
-	pci_set_power_state(pci, PCI_D0);
-	pci_restore_state(pci);
-	ret = pci_enable_device(pci);
-	if (ret)
-		pr_err("device can't be enabled\n");
-
-	mutex_lock(&sst_drv_ctx->sst_lock);
-	sst_drv_ctx->sst_state = SST_UN_INIT;
-	mutex_unlock(&sst_drv_ctx->sst_lock);
-	return 0;
-}
-
-/* The runtime_suspend/resume is pretty much similar to the legacy
- * suspend/resume with the noted exception below:
- * The PCI core takes care of taking the system through D3hot and
- * restoring it back to D0 and so there is no need to duplicate
- * that here.
- */
-static int intel_sst_runtime_suspend(struct device *dev)
-{
-	union config_status_reg csr;
-
-	pr_debug("intel_sst_runtime_suspend called\n");
-	if (sst_drv_ctx->stream_cnt) {
-		pr_err("active streams,not able to suspend\n");
-		return -EBUSY;
-	}
-	/*save fw context*/
-	sst_save_dsp_context();
-	/*Assert RESET on LPE Processor*/
-	csr.full = sst_shim_read(sst_drv_ctx->shim, SST_CSR);
-	csr.full = csr.full | 0x2;
-	/* Move the SST state to Suspended */
-	mutex_lock(&sst_drv_ctx->sst_lock);
-	sst_drv_ctx->sst_state = SST_SUSPENDED;
-
-	/* Only needed by Medfield */
-	if (sst_drv_ctx->pci_id != SST_MRST_PCI_ID)
-		sst_shim_write(sst_drv_ctx->shim, SST_CSR, csr.full);
-	mutex_unlock(&sst_drv_ctx->sst_lock);
-	return 0;
-}
-
-static int intel_sst_runtime_resume(struct device *dev)
-{
-
-	pr_debug("intel_sst_runtime_resume called\n");
-	if (sst_drv_ctx->sst_state != SST_SUSPENDED) {
-		pr_err("SST is not in suspended state\n");
-		return 0;
-	}
-
-	mutex_lock(&sst_drv_ctx->sst_lock);
-	sst_drv_ctx->sst_state = SST_UN_INIT;
-	mutex_unlock(&sst_drv_ctx->sst_lock);
-	return 0;
-}
-
-static int intel_sst_runtime_idle(struct device *dev)
-{
-	pr_debug("runtime_idle called\n");
-	if (sst_drv_ctx->stream_cnt == 0 && sst_drv_ctx->am_cnt == 0)
-		pm_schedule_suspend(dev, SST_SUSPEND_DELAY);
-	return -EBUSY;
-}
-
-static const struct dev_pm_ops intel_sst_pm = {
-	.runtime_suspend = intel_sst_runtime_suspend,
-	.runtime_resume = intel_sst_runtime_resume,
-	.runtime_idle = intel_sst_runtime_idle,
-};
-
-/* PCI Routines */
-static struct pci_device_id intel_sst_ids[] = {
-	{ PCI_VDEVICE(INTEL, SST_MRST_PCI_ID), 3},
-	{ PCI_VDEVICE(INTEL, SST_MFLD_PCI_ID), 6},
-	{ 0, }
-};
-MODULE_DEVICE_TABLE(pci, intel_sst_ids);
-
-static struct pci_driver driver = {
-	.name = SST_DRV_NAME,
-	.id_table = intel_sst_ids,
-	.probe = intel_sst_probe,
-	.remove = __devexit_p(intel_sst_remove),
-#ifdef CONFIG_PM
-	.suspend = intel_sst_suspend,
-	.resume = intel_sst_resume,
-	.driver = {
-		.pm = &intel_sst_pm,
-	},
-#endif
-};
-
-/**
-* intel_sst_init - Module init function
-*
-* Registers with PCI
-* Registers with /dev
-* Init all data strutures
-*/
-static int __init intel_sst_init(void)
-{
-	/* Init all variables, data structure etc....*/
-	int ret = 0;
-	pr_debug("INFO: ******** SST DRIVER loading.. Ver: %s\n",
-				       SST_DRIVER_VERSION);
-
-	mutex_init(&drv_ctx_lock);
-	/* Register with PCI */
-	ret = pci_register_driver(&driver);
-	if (ret)
-		pr_err("PCI register failed\n");
-	return ret;
-}
-
-/**
-* intel_sst_exit - Module exit function
-*
-* Unregisters with PCI
-* Unregisters with /dev
-* Frees all data strutures
-*/
-static void __exit intel_sst_exit(void)
-{
-	pci_unregister_driver(&driver);
-
-	pr_debug("driver unloaded\n");
-	sst_drv_ctx = NULL;
-	return;
-}
-
-module_init(intel_sst_init);
-module_exit(intel_sst_exit);
diff --git a/drivers/staging/intel_sst/intel_sst.h b/drivers/staging/intel_sst/intel_sst.h
deleted file mode 100644
index 4ad2829..0000000
--- a/drivers/staging/intel_sst/intel_sst.h
+++ /dev/null
@@ -1,162 +0,0 @@
-#ifndef __INTEL_SST_H__
-#define __INTEL_SST_H__
-/*
- *  intel_sst.h - Intel SST Driver for audio engine
- *
- *  Copyright (C) 2008-10 Intel Corporation
- *  Authors:	Vinod Koul <vinod.koul@intel.com>
- *		Harsha Priya <priya.harsha@intel.com>
- *		Dharageswari R <dharageswari.r@intel.com>
- *		KP Jeeja <jeeja.kp@intel.com>
- *  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; version 2 of the License.
- *
- *  This program is distributed in the hope that it will be useful, but
- *  WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *  General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License along
- *  with this program; if not, write to the Free Software Foundation, Inc.,
- *  59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
- *
- * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- *
- *  This driver exposes the audio engine functionalities to the ALSA
- *	and middleware.
- *  This file is shared between the SST and MAD drivers
- */
-#include "intel_sst_ioctl.h"
-#include <sound/jack.h>
-
-#define SST_CARD_NAMES "intel_mid_card"
-
-#define MFLD_MAX_HW_CH 4
-/* control list Pmic & Lpe */
-/* Input controls */
-enum port_status {
-	ACTIVATE = 1,
-	DEACTIVATE,
-};
-
-/* Card states */
-enum sst_card_states {
-	SND_CARD_UN_INIT = 0,
-	SND_CARD_INIT_DONE,
-};
-
-enum sst_controls {
-	SST_SND_ALLOC =			0x1000,
-	SST_SND_PAUSE =			0x1001,
-	SST_SND_RESUME =		0x1002,
-	SST_SND_DROP =			0x1003,
-	SST_SND_FREE =			0x1004,
-	SST_SND_BUFFER_POINTER =	0x1005,
-	SST_SND_STREAM_INIT =		0x1006,
-	SST_SND_START	 =		0x1007,
-	SST_SND_STREAM_PROCESS =	0x1008,
-	SST_MAX_CONTROLS =		0x1008,
-	SST_CONTROL_BASE =		0x1000,
-	SST_ENABLE_RX_TIME_SLOT =	0x1009,
-};
-
-enum SND_CARDS {
-	SND_FS = 0,
-	SND_MX,
-	SND_NC,
-	SND_MSIC
-};
-
-struct pcm_stream_info {
-	int str_id;
-	void *mad_substream;
-	void (*period_elapsed) (void *mad_substream);
-	unsigned long long buffer_ptr;
-	int sfreq;
-};
-
-struct snd_pmic_ops {
-	int card_status;
-	int master_mute;
-	int num_channel;
-	int input_dev_id;
-	int mute_status;
-	struct mutex lock;
-	int pb_on, pbhs_on;
-	int cap_on;
-	int output_dev_id;
-	int lineout_dev_id, line_out_names_cnt;
-	int prev_lineout_dev_id;
-	bool jack_interrupt_status;
-	int (*set_input_dev) (u8 value);
-	int (*set_output_dev) (u8 value);
-	int (*set_lineout_dev) (u8 value);
-	int (*set_mute) (int dev_id, u8 value);
-	int (*get_mute) (int dev_id, u8 *value);
-
-	int (*set_vol) (int dev_id, int value);
-	int (*get_vol) (int dev_id, int *value);
-
-	int (*init_card) (void);
-	int (*set_pcm_audio_params)
-		(int sfreq, int word_size , int num_channel);
-	int (*set_pcm_voice_params) (void);
-	int (*set_voice_port) (int status);
-	int (*set_audio_port) (int status);
-
-	int (*power_up_pmic_pb) (unsigned int port);
-	int (*power_up_pmic_cp) (unsigned int port);
-	int (*power_down_pmic_pb) (unsigned int device);
-	int (*power_down_pmic_cp) (unsigned int device);
-	int (*power_down_pmic) (void);
-	void (*pmic_irq_cb) (void *cb_data, u8 value);
-	void (*pmic_irq_enable)(void *data);
-	int (*pmic_jack_enable) (void);
-	int (*pmic_get_mic_bias)(void *intelmaddata);
-	int (*pmic_set_headset_state)(int state);
-
-	unsigned int hw_dmic_map[MFLD_MAX_HW_CH];
-	unsigned int available_dmics;
-	int (*set_hw_dmic_route) (u8 index);
-
-	int gpio_amp;
-};
-
-extern void sst_mad_send_jack_report(struct snd_jack *jack,
-				     int buttonpressevent,
-				     int status);
-
-
-int intemad_set_headset_state(int state);
-int intelmad_get_mic_bias(void);
-
-struct intel_sst_pcm_control {
-	int (*open) (struct snd_sst_params *str_param);
-	int (*device_control) (int cmd, void *arg);
-	int (*close) (unsigned int str_id);
-};
-struct intel_sst_card_ops {
-	char *module_name;
-	unsigned int  vendor_id;
-	struct intel_sst_pcm_control *pcm_control;
-	struct snd_pmic_ops *scard_ops;
-};
-
-/* modified for generic access */
-struct sc_reg_access {
-	u16 reg_addr;
-	u8 value;
-	u8 mask;
-};
-enum sc_reg_access_type {
-	PMIC_READ = 0,
-	PMIC_WRITE,
-	PMIC_READ_MODIFY,
-};
-
-int register_sst_card(struct intel_sst_card_ops *card);
-void unregister_sst_card(struct intel_sst_card_ops *card);
-#endif /* __INTEL_SST_H__ */
diff --git a/drivers/staging/intel_sst/intel_sst_app_interface.c b/drivers/staging/intel_sst/intel_sst_app_interface.c
deleted file mode 100644
index 93b41a2..0000000
--- a/drivers/staging/intel_sst/intel_sst_app_interface.c
+++ /dev/null
@@ -1,1460 +0,0 @@
-/*
- *  intel_sst_interface.c - Intel SST Driver for audio engine
- *
- *  Copyright (C) 2008-10 Intel Corp
- *  Authors:	Vinod Koul <vinod.koul@intel.com>
- *  Harsha Priya <priya.harsha@intel.com>
- *  Dharageswari R <dharageswari.r@intel.com>
- *  Jeeja KP <jeeja.kp@intel.com>
- * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; version 2 of the License.
- *
- *  This program is distributed in the hope that it will be useful, but
- *  WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *  General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License along
- *  with this program; if not, write to the Free Software Foundation, Inc.,
- *  59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
- *
- * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- *  This driver exposes the audio engine functionalities to the ALSA
- *	and middleware.
- *  Upper layer interfaces (MAD driver, MMF) to SST driver
- */
-
-#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
-
-#include <linux/pci.h>
-#include <linux/fs.h>
-#include <linux/uio.h>
-#include <linux/aio.h>
-#include <linux/uaccess.h>
-#include <linux/firmware.h>
-#include <linux/pm_runtime.h>
-#include <linux/ioctl.h>
-#ifdef CONFIG_MRST_RAR_HANDLER
-#include <linux/rar_register.h>
-#include "../../../drivers/staging/memrar/memrar.h"
-#endif
-#include "intel_sst.h"
-#include "intel_sst_ioctl.h"
-#include "intel_sst_fw_ipc.h"
-#include "intel_sst_common.h"
-
-#define AM_MODULE 1
-#define STREAM_MODULE 0
-
-
-/**
-* intel_sst_check_device - checks SST device
-*
-* This utility function checks the state of SST device and downlaods FW if
-* not done, or resumes the device if suspended
-*/
-
-static int intel_sst_check_device(void)
-{
-	int retval = 0;
-	if (sst_drv_ctx->pmic_state != SND_MAD_INIT_DONE) {
-		pr_warn("Sound card not available\n");
-		return -EIO;
-	}
-	if (sst_drv_ctx->sst_state == SST_SUSPENDED) {
-		pr_debug("Resuming from Suspended state\n");
-		retval = intel_sst_resume(sst_drv_ctx->pci);
-		if (retval) {
-			pr_debug("Resume Failed= %#x,abort\n", retval);
-			return retval;
-		}
-	}
-
-	if (sst_drv_ctx->sst_state == SST_UN_INIT) {
-		/* FW is not downloaded */
-		retval = sst_download_fw();
-		if (retval)
-			return -ENODEV;
-		if (sst_drv_ctx->pci_id == SST_MRST_PCI_ID) {
-			retval = sst_drv_ctx->rx_time_slot_status;
-			if (retval != RX_TIMESLOT_UNINIT
-					&& sst_drv_ctx->pmic_vendor != SND_NC)
-				sst_enable_rx_timeslot(retval);
-		}
-	}
-	return 0;
-}
-
-/**
- * intel_sst_open - opens a handle to driver
- *
- * @i_node:	inode structure
- * @file_ptr:pointer to file
- *
- * This function is called by OS when a user space component
- * tries to get a driver handle. Only one handle at a time
- * will be allowed
- */
-int intel_sst_open(struct inode *i_node, struct file *file_ptr)
-{
-	unsigned int retval;
-
-	mutex_lock(&sst_drv_ctx->stream_lock);
-	pm_runtime_get_sync(&sst_drv_ctx->pci->dev);
-	retval = intel_sst_check_device();
-	if (retval) {
-		pm_runtime_put(&sst_drv_ctx->pci->dev);
-		mutex_unlock(&sst_drv_ctx->stream_lock);
-		return retval;
-	}
-
-	if (sst_drv_ctx->encoded_cnt < MAX_ENC_STREAM) {
-		struct ioctl_pvt_data *data =
-			kzalloc(sizeof(struct ioctl_pvt_data), GFP_KERNEL);
-		if (!data) {
-			pm_runtime_put(&sst_drv_ctx->pci->dev);
-			mutex_unlock(&sst_drv_ctx->stream_lock);
-			return -ENOMEM;
-		}
-
-		sst_drv_ctx->encoded_cnt++;
-		mutex_unlock(&sst_drv_ctx->stream_lock);
-		data->pvt_id = sst_assign_pvt_id(sst_drv_ctx);
-		data->str_id = 0;
-		file_ptr->private_data = (void *)data;
-		pr_debug("pvt_id handle = %d!\n", data->pvt_id);
-	} else {
-		retval = -EUSERS;
-		pm_runtime_put(&sst_drv_ctx->pci->dev);
-		mutex_unlock(&sst_drv_ctx->stream_lock);
-	}
-	return retval;
-}
-
-/**
- * intel_sst_open_cntrl - opens a handle to driver
- *
- * @i_node:	inode structure
- * @file_ptr:pointer to file
- *
- * This function is called by OS when a user space component
- * tries to get a driver handle to /dev/intel_sst_control.
- * Only one handle at a time will be allowed
- * This is for control operations only
- */
-int intel_sst_open_cntrl(struct inode *i_node, struct file *file_ptr)
-{
-	unsigned int retval;
-
-	/* audio manager open */
-	mutex_lock(&sst_drv_ctx->stream_lock);
-	pm_runtime_get_sync(&sst_drv_ctx->pci->dev);
-	retval = intel_sst_check_device();
-	if (retval) {
-		pm_runtime_put(&sst_drv_ctx->pci->dev);
-		mutex_unlock(&sst_drv_ctx->stream_lock);
-		return retval;
-	}
-
-	if (sst_drv_ctx->am_cnt < MAX_AM_HANDLES) {
-		sst_drv_ctx->am_cnt++;
-		pr_debug("AM handle opened...\n");
-		file_ptr->private_data = NULL;
-	} else {
-		retval = -EACCES;
-		pm_runtime_put(&sst_drv_ctx->pci->dev);
-	}
-
-	mutex_unlock(&sst_drv_ctx->stream_lock);
-	return retval;
-}
-
-/**
- * intel_sst_release - releases a handle to driver
- *
- * @i_node:	inode structure
- * @file_ptr:	pointer to file
- *
- * This function is called by OS when a user space component
- * tries to release a driver handle.
- */
-int intel_sst_release(struct inode *i_node, struct file *file_ptr)
-{
-	struct ioctl_pvt_data *data = file_ptr->private_data;
-
-	pr_debug("Release called, closing app handle\n");
-	mutex_lock(&sst_drv_ctx->stream_lock);
-	sst_drv_ctx->encoded_cnt--;
-	sst_drv_ctx->stream_cnt--;
-	pm_runtime_put(&sst_drv_ctx->pci->dev);
-	mutex_unlock(&sst_drv_ctx->stream_lock);
-	free_stream_context(data->str_id);
-	kfree(data);
-	return 0;
-}
-
-int intel_sst_release_cntrl(struct inode *i_node, struct file *file_ptr)
-{
-	/* audio manager close */
-	mutex_lock(&sst_drv_ctx->stream_lock);
-	sst_drv_ctx->am_cnt--;
-	pm_runtime_put(&sst_drv_ctx->pci->dev);
-	mutex_unlock(&sst_drv_ctx->stream_lock);
-	pr_debug("AM handle closed\n");
-	return 0;
-}
-
-/**
-* intel_sst_mmap - mmaps a kernel buffer to user space for copying data
-*
-* @vma:		vm area structure instance
-* @file_ptr:	pointer to file
-*
-* This function is called by OS when a user space component
-* tries to get mmap memory from driver
-*/
-int intel_sst_mmap(struct file *file_ptr, struct vm_area_struct *vma)
-{
-	int retval, length;
-	struct ioctl_pvt_data *data =
-		(struct ioctl_pvt_data *)file_ptr->private_data;
-	int str_id = data->str_id;
-	void *mem_area;
-
-	retval = sst_validate_strid(str_id);
-	if (retval)
-		return -EINVAL;
-
-	length = vma->vm_end - vma->vm_start;
-	pr_debug("called for stream %d length 0x%x\n", str_id, length);
-
-	if (length > sst_drv_ctx->mmap_len)
-		return -ENOMEM;
-	if (!sst_drv_ctx->mmap_mem)
-		return -EIO;
-
-	/* round it up to the page boundary  */
-	/*mem_area = (void *)((((unsigned long)sst_drv_ctx->mmap_mem)
-				+ PAGE_SIZE - 1) & PAGE_MASK);*/
-	mem_area = (void *) PAGE_ALIGN((unsigned int) sst_drv_ctx->mmap_mem);
-
-	/* map the whole physically contiguous area in one piece  */
-	retval = remap_pfn_range(vma,
-			vma->vm_start,
-			virt_to_phys((void *)mem_area) >> PAGE_SHIFT,
-			length,
-			vma->vm_page_prot);
-	if (retval)
-		sst_drv_ctx->streams[str_id].mmapped = false;
-	else
-		sst_drv_ctx->streams[str_id].mmapped = true;
-
-	pr_debug("mmap ret 0x%x\n", retval);
-	return retval;
-}
-
-/* sets mmap data buffers to play/capture*/
-static int intel_sst_mmap_play_capture(u32 str_id,
-		struct snd_sst_mmap_buffs *mmap_buf)
-{
-	struct sst_stream_bufs *bufs;
-	int retval, i;
-	struct stream_info *stream;
-	struct snd_sst_mmap_buff_entry *buf_entry;
-	struct snd_sst_mmap_buff_entry *tmp_buf;
-
-	pr_debug("called for str_id %d\n", str_id);
-	retval = sst_validate_strid(str_id);
-	if (retval)
-		return -EINVAL;
-
-	stream = &sst_drv_ctx->streams[str_id];
-	if (stream->mmapped != true)
-		return -EIO;
-
-	if (stream->status == STREAM_UN_INIT ||
-		stream->status == STREAM_DECODE) {
-		return -EBADRQC;
-	}
-	stream->curr_bytes = 0;
-	stream->cumm_bytes = 0;
-
-	tmp_buf = kcalloc(mmap_buf->entries, sizeof(*tmp_buf), GFP_KERNEL);
-	if (!tmp_buf)
-		return -ENOMEM;
-	if (copy_from_user(tmp_buf, (void __user *)mmap_buf->buff,
-			mmap_buf->entries * sizeof(*tmp_buf))) {
-		retval = -EFAULT;
-		goto out_free;
-	}
-
-	pr_debug("new buffers count %d status %d\n",
-			mmap_buf->entries, stream->status);
-	buf_entry = tmp_buf;
-	for (i = 0; i < mmap_buf->entries; i++) {
-		bufs = kzalloc(sizeof(*bufs), GFP_KERNEL);
-		if (!bufs) {
-			retval = -ENOMEM;
-			goto out_free;
-		}
-		bufs->size = buf_entry->size;
-		bufs->offset = buf_entry->offset;
-		bufs->addr = sst_drv_ctx->mmap_mem;
-		bufs->in_use = false;
-		buf_entry++;
-		/* locking here */
-		mutex_lock(&stream->lock);
-		list_add_tail(&bufs->node, &stream->bufs);
-		mutex_unlock(&stream->lock);
-	}
-
-	mutex_lock(&stream->lock);
-	stream->data_blk.condition = false;
-	stream->data_blk.ret_code = 0;
-	if (stream->status == STREAM_INIT &&
-			stream->prev != STREAM_UN_INIT &&
-			stream->need_draining != true) {
-		stream->prev = stream->status;
-		stream->status = STREAM_RUNNING;
-		if (stream->ops == STREAM_OPS_PLAYBACK) {
-			if (sst_play_frame(str_id) < 0) {
-				pr_warn("play frames fail\n");
-				mutex_unlock(&stream->lock);
-				retval = -EIO;
-				goto out_free;
-			}
-		} else if (stream->ops == STREAM_OPS_CAPTURE) {
-			if (sst_capture_frame(str_id) < 0) {
-				pr_warn("capture frame fail\n");
-				mutex_unlock(&stream->lock);
-				retval = -EIO;
-				goto out_free;
-			}
-		}
-	}
-	mutex_unlock(&stream->lock);
-	/* Block the call for reply */
-	if (!list_empty(&stream->bufs)) {
-		stream->data_blk.on = true;
-		retval = sst_wait_interruptible(sst_drv_ctx,
-					&stream->data_blk);
-	}
-
-	if (retval >= 0)
-		retval = stream->cumm_bytes;
-	pr_debug("end of play/rec ioctl bytes = %d!!\n", retval);
-
-out_free:
-	kfree(tmp_buf);
-	return retval;
-}
-
-/*sets user data buffers to play/capture*/
-static int intel_sst_play_capture(struct stream_info *stream, int str_id)
-{
-	int retval;
-
-	stream->data_blk.ret_code = 0;
-	stream->data_blk.on = true;
-	stream->data_blk.condition = false;
-
-	mutex_lock(&stream->lock);
-	if (stream->status == STREAM_INIT && stream->prev != STREAM_UN_INIT) {
-		/* stream is started */
-		stream->prev = stream->status;
-		stream->status = STREAM_RUNNING;
-	}
-
-	if (stream->status == STREAM_INIT && stream->prev == STREAM_UN_INIT) {
-		/* stream is not started yet */
-		pr_debug("Stream isn't in started state %d, prev %d\n",
-			stream->status, stream->prev);
-	} else if ((stream->status == STREAM_RUNNING ||
-			stream->status == STREAM_PAUSED) &&
-			stream->need_draining != true) {
-		/* stream is started */
-		if (stream->ops == STREAM_OPS_PLAYBACK ||
-				stream->ops == STREAM_OPS_PLAYBACK_DRM) {
-			if (sst_play_frame(str_id) < 0) {
-				pr_warn("play frames failed\n");
-				mutex_unlock(&stream->lock);
-				return -EIO;
-			}
-		} else if (stream->ops == STREAM_OPS_CAPTURE) {
-			if (sst_capture_frame(str_id) < 0) {
-				pr_warn("capture frames failed\n");
-				mutex_unlock(&stream->lock);
-				return -EIO;
-			}
-		}
-	} else {
-		mutex_unlock(&stream->lock);
-		return -EIO;
-	}
-	mutex_unlock(&stream->lock);
-	/* Block the call for reply */
-
-	retval = sst_wait_interruptible(sst_drv_ctx, &stream->data_blk);
-	if (retval) {
-		stream->status = STREAM_INIT;
-		pr_debug("wait returned error...\n");
-	}
-	return retval;
-}
-
-/* fills kernel list with buffer addresses for SST DSP driver to process*/
-static int snd_sst_fill_kernel_list(struct stream_info *stream,
-			const struct iovec *iovec, unsigned long nr_segs,
-			struct list_head *copy_to_list)
-{
-	struct sst_stream_bufs *stream_bufs;
-	unsigned long index, mmap_len;
-	unsigned char __user *bufp;
-	unsigned long size, copied_size;
-	int retval = 0, add_to_list = 0;
-	static int sent_offset;
-	static unsigned long sent_index;
-
-#ifdef CONFIG_MRST_RAR_HANDLER
-	if (stream->ops == STREAM_OPS_PLAYBACK_DRM) {
-		for (index = stream->sg_index; index < nr_segs; index++) {
-			__u32 rar_handle;
-			struct sst_stream_bufs *stream_bufs =
-				kzalloc(sizeof(*stream_bufs), GFP_KERNEL);
-
-			stream->sg_index = index;
-			if (!stream_bufs)
-				return -ENOMEM;
-			if (copy_from_user((void *) &rar_handle,
-					iovec[index].iov_base,
-					sizeof(__u32))) {
-				kfree(stream_bufs);
-				return -EFAULT;
-			}
-			stream_bufs->addr = (char *)rar_handle;
-			stream_bufs->in_use = false;
-			stream_bufs->size = iovec[0].iov_len;
-			/* locking here */
-			mutex_lock(&stream->lock);
-			list_add_tail(&stream_bufs->node, &stream->bufs);
-			mutex_unlock(&stream->lock);
-		}
-		stream->sg_index = index;
-		return retval;
-	}
-#endif
-	stream_bufs = kzalloc(sizeof(*stream_bufs), GFP_KERNEL);
-	if (!stream_bufs)
-		return -ENOMEM;
-	stream_bufs->addr = sst_drv_ctx->mmap_mem;
-	mmap_len = sst_drv_ctx->mmap_len;
-	stream_bufs->addr = sst_drv_ctx->mmap_mem;
-	bufp = stream->cur_ptr;
-
-	copied_size = 0;
-
-	if (!stream->sg_index)
-		sent_index = sent_offset = 0;
-
-	for (index = stream->sg_index; index < nr_segs; index++) {
-		stream->sg_index = index;
-		if (!stream->cur_ptr)
-			bufp = iovec[index].iov_base;
-
-		size = ((unsigned long)iovec[index].iov_base
-			+ iovec[index].iov_len) - (unsigned long) bufp;
-
-		if ((copied_size + size) > mmap_len)
-			size = mmap_len - copied_size;
-
-
-		if (stream->ops == STREAM_OPS_PLAYBACK) {
-			if (copy_from_user((void *)
-					(stream_bufs->addr + copied_size),
-					bufp, size)) {
-				/* Clean up the list and return error code */
-				retval = -EFAULT;
-				break;
-			}
-		} else if (stream->ops == STREAM_OPS_CAPTURE) {
-			struct snd_sst_user_cap_list *entry =
-				kzalloc(sizeof(*entry), GFP_KERNEL);
-
-			if (!entry) {
-				kfree(stream_bufs);
-				return -ENOMEM;
-			}
-			entry->iov_index = index;
-			entry->iov_offset = (unsigned long) bufp -
-					(unsigned long)iovec[index].iov_base;
-			entry->offset = copied_size;
-			entry->size = size;
-			list_add_tail(&entry->node, copy_to_list);
-		}
-
-		stream->cur_ptr = bufp + size;
-
-		if (((unsigned long)iovec[index].iov_base
-				+ iovec[index].iov_len) <
-				((unsigned long)iovec[index].iov_base)) {
-			pr_debug("Buffer overflows\n");
-			kfree(stream_bufs);
-			return -EINVAL;
-		}
-
-		if (((unsigned long)iovec[index].iov_base
-					+ iovec[index].iov_len) ==
-					(unsigned long)stream->cur_ptr) {
-			stream->cur_ptr = NULL;
-			stream->sg_index++;
-		}
-
-		copied_size += size;
-		pr_debug("copied_size - %lx\n", copied_size);
-		if ((copied_size >= mmap_len) ||
-				(stream->sg_index == nr_segs)) {
-			add_to_list = 1;
-		}
-
-		if (add_to_list) {
-			stream_bufs->in_use = false;
-			stream_bufs->size = copied_size;
-			/* locking here */
-			mutex_lock(&stream->lock);
-			list_add_tail(&stream_bufs->node, &stream->bufs);
-			mutex_unlock(&stream->lock);
-			break;
-		}
-	}
-	return retval;
-}
-
-/* This function copies the captured data returned from SST DSP engine
- * to the user buffers*/
-static int snd_sst_copy_userbuf_capture(struct stream_info *stream,
-			const struct iovec *iovec,
-			struct list_head *copy_to_list)
-{
-	struct snd_sst_user_cap_list *entry, *_entry;
-	struct sst_stream_bufs *kbufs = NULL, *_kbufs;
-	int retval = 0;
-
-	/* copy sent buffers */
-	pr_debug("capture stream copying to user now...\n");
-	list_for_each_entry_safe(kbufs, _kbufs, &stream->bufs, node) {
-		if (kbufs->in_use == true) {
-			/* copy to user */
-			list_for_each_entry_safe(entry, _entry,
-						copy_to_list, node) {
-				if (copy_to_user(iovec[entry->iov_index].iov_base + entry->iov_offset,
-					     kbufs->addr + entry->offset,
-					     entry->size)) {
-					/* Clean up the list and return error */
-					retval = -EFAULT;
-					break;
-				}
-				list_del(&entry->node);
-				kfree(entry);
-			}
-		}
-	}
-	pr_debug("end of cap copy\n");
-	return retval;
-}
-
-/*
- * snd_sst_userbufs_play_cap - constructs the list from user buffers
- *
- * @iovec:pointer to iovec structure
- * @nr_segs:number entries in the iovec structure
- * @str_id:stream id
- * @stream:pointer to stream_info structure
- *
- * This function will traverse the user list and copy the data to the kernel
- * space buffers.
- */
-static int snd_sst_userbufs_play_cap(const struct iovec *iovec,
-			unsigned long nr_segs, unsigned int str_id,
-			struct stream_info *stream)
-{
-	int retval;
-	LIST_HEAD(copy_to_list);
-
-
-	retval = snd_sst_fill_kernel_list(stream, iovec, nr_segs,
-		       &copy_to_list);
-
-	retval = intel_sst_play_capture(stream, str_id);
-	if (retval < 0)
-		return retval;
-
-	if (stream->ops == STREAM_OPS_CAPTURE) {
-		retval = snd_sst_copy_userbuf_capture(stream, iovec,
-				&copy_to_list);
-	}
-	return retval;
-}
-
-/* This function is common function across read/write
-  for user buffers called from system calls*/
-static int intel_sst_read_write(unsigned int str_id, char __user *buf,
-					size_t count)
-{
-	int retval;
-	struct stream_info *stream;
-	struct iovec iovec;
-	unsigned long nr_segs;
-
-	retval = sst_validate_strid(str_id);
-	if (retval)
-		return -EINVAL;
-	stream = &sst_drv_ctx->streams[str_id];
-	if (stream->mmapped == true) {
-		pr_warn("user write and stream is mapped\n");
-		return -EIO;
-	}
-	if (!count)
-		return -EINVAL;
-	stream->curr_bytes = 0;
-	stream->cumm_bytes = 0;
-	/* copy user buf details */
-	pr_debug("new buffers %p, copy size %d, status %d\n" ,
-			buf, (int) count, (int) stream->status);
-
-	stream->buf_type = SST_BUF_USER_STATIC;
-	iovec.iov_base = buf;
-	iovec.iov_len  = count;
-	nr_segs = 1;
-
-	do {
-		retval = snd_sst_userbufs_play_cap(
-				&iovec, nr_segs, str_id, stream);
-		if (retval < 0)
-			break;
-
-	} while (stream->sg_index < nr_segs);
-
-	stream->sg_index = 0;
-	stream->cur_ptr = NULL;
-	if (retval >= 0)
-		retval = stream->cumm_bytes;
-	pr_debug("end of play/rec bytes = %d!!\n", retval);
-	return retval;
-}
-
-/***
- * intel_sst_write - This function is called when user tries to play out data
- *
- * @file_ptr:pointer to file
- * @buf:user buffer to be played out
- * @count:size of tthe buffer
- * @offset:offset to start from
- *
- * writes the encoded data into DSP
- */
-int intel_sst_write(struct file *file_ptr, const char __user *buf,
-			size_t count, loff_t *offset)
-{
-	struct ioctl_pvt_data *data = file_ptr->private_data;
-	int str_id = data->str_id;
-	struct stream_info *stream = &sst_drv_ctx->streams[str_id];
-
-	pr_debug("called for %d\n", str_id);
-	if (stream->status == STREAM_UN_INIT ||
-		stream->status == STREAM_DECODE) {
-		return -EBADRQC;
-	}
-	return intel_sst_read_write(str_id, (char __user *)buf, count);
-}
-
-/*
- * intel_sst_aio_write - write buffers
- *
- * @kiocb:pointer to a structure containing file pointer
- * @iov:list of user buffer to be played out
- * @nr_segs:number of entries
- * @offset:offset to start from
- *
- * This function is called when user tries to play out multiple data buffers
- */
-ssize_t intel_sst_aio_write(struct kiocb *kiocb, const struct iovec *iov,
-			unsigned long nr_segs, loff_t  offset)
-{
-	int retval;
-	struct ioctl_pvt_data *data = kiocb->ki_filp->private_data;
-	int str_id = data->str_id;
-	struct stream_info *stream;
-
-	pr_debug("entry - %ld\n", nr_segs);
-
-	if (is_sync_kiocb(kiocb) == false)
-		return -EINVAL;
-
-	pr_debug("called for str_id %d\n", str_id);
-	retval = sst_validate_strid(str_id);
-	if (retval)
-		return -EINVAL;
-	stream = &sst_drv_ctx->streams[str_id];
-	if (stream->mmapped == true)
-		return -EIO;
-	if (stream->status == STREAM_UN_INIT ||
-		stream->status == STREAM_DECODE) {
-		return -EBADRQC;
-	}
-	stream->curr_bytes = 0;
-	stream->cumm_bytes = 0;
-	pr_debug("new segs %ld, offset %d, status %d\n" ,
-			nr_segs, (int) offset, (int) stream->status);
-	stream->buf_type = SST_BUF_USER_STATIC;
-	do {
-		retval = snd_sst_userbufs_play_cap(iov, nr_segs,
-						str_id, stream);
-		if (retval < 0)
-			break;
-
-	} while (stream->sg_index < nr_segs);
-
-	stream->sg_index = 0;
-	stream->cur_ptr = NULL;
-	if (retval >= 0)
-		retval = stream->cumm_bytes;
-	pr_debug("end of play/rec bytes = %d!!\n", retval);
-	return retval;
-}
-
-/*
- * intel_sst_read - read the encoded data
- *
- * @file_ptr: pointer to file
- * @buf: user buffer to be filled with captured data
- * @count: size of tthe buffer
- * @offset: offset to start from
- *
- * This function is called when user tries to capture data
- */
-int intel_sst_read(struct file *file_ptr, char __user *buf,
-			size_t count, loff_t *offset)
-{
-	struct ioctl_pvt_data *data = file_ptr->private_data;
-	int str_id = data->str_id;
-	struct stream_info *stream = &sst_drv_ctx->streams[str_id];
-
-	pr_debug("called for %d\n", str_id);
-	if (stream->status == STREAM_UN_INIT ||
-			stream->status == STREAM_DECODE)
-		return -EBADRQC;
-	return intel_sst_read_write(str_id, buf, count);
-}
-
-/*
- * intel_sst_aio_read - aio read
- *
- * @kiocb: pointer to a structure containing file pointer
- * @iov: list of user buffer to be filled with captured
- * @nr_segs: number of entries
- * @offset: offset to start from
- *
- * This function is called when user tries to capture out multiple data buffers
- */
-ssize_t intel_sst_aio_read(struct kiocb *kiocb, const struct iovec *iov,
-			 unsigned long nr_segs, loff_t offset)
-{
-	int retval;
-	struct ioctl_pvt_data *data = kiocb->ki_filp->private_data;
-	int str_id = data->str_id;
-	struct stream_info *stream;
-
-	pr_debug("entry - %ld\n", nr_segs);
-
-	if (is_sync_kiocb(kiocb) == false) {
-		pr_debug("aio_read from user space is not allowed\n");
-		return -EINVAL;
-	}
-
-	pr_debug("called for str_id %d\n", str_id);
-	retval = sst_validate_strid(str_id);
-	if (retval)
-		return -EINVAL;
-	stream = &sst_drv_ctx->streams[str_id];
-	if (stream->mmapped == true)
-		return -EIO;
-	if (stream->status == STREAM_UN_INIT ||
-			stream->status == STREAM_DECODE)
-		return -EBADRQC;
-	stream->curr_bytes = 0;
-	stream->cumm_bytes = 0;
-
-	pr_debug("new segs %ld, offset %d, status %d\n" ,
-			nr_segs, (int) offset, (int) stream->status);
-	stream->buf_type = SST_BUF_USER_STATIC;
-	do {
-		retval = snd_sst_userbufs_play_cap(iov, nr_segs,
-						str_id, stream);
-		if (retval < 0)
-			break;
-
-	} while (stream->sg_index < nr_segs);
-
-	stream->sg_index = 0;
-	stream->cur_ptr = NULL;
-	if (retval >= 0)
-		retval = stream->cumm_bytes;
-	pr_debug("end of play/rec bytes = %d!!\n", retval);
-	return retval;
-}
-
-/* sst_print_stream_params - prints the stream parameters (debug fn)*/
-static void sst_print_stream_params(struct snd_sst_get_stream_params *get_prm)
-{
-	pr_debug("codec params:result = %d\n",
-				get_prm->codec_params.result);
-	pr_debug("codec params:stream = %d\n",
-				get_prm->codec_params.stream_id);
-	pr_debug("codec params:codec = %d\n",
-				get_prm->codec_params.codec);
-	pr_debug("codec params:ops = %d\n",
-				get_prm->codec_params.ops);
-	pr_debug("codec params:stream_type = %d\n",
-				get_prm->codec_params.stream_type);
-	pr_debug("pcmparams:sfreq = %d\n",
-				get_prm->pcm_params.sfreq);
-	pr_debug("pcmparams:num_chan = %d\n",
-				get_prm->pcm_params.num_chan);
-	pr_debug("pcmparams:pcm_wd_sz = %d\n",
-				get_prm->pcm_params.pcm_wd_sz);
-	return;
-}
-
-/**
- * sst_create_algo_ipc - create ipc msg for algorithm parameters
- *
- * @algo_params: Algorithm parameters
- * @msg: post msg pointer
- *
- * This function is called to create ipc msg
- */
-int sst_create_algo_ipc(struct snd_ppp_params *algo_params,
-					struct ipc_post **msg)
-{
-	if (sst_create_large_msg(msg))
-		return -ENOMEM;
-	sst_fill_header(&(*msg)->header,
-			IPC_IA_ALG_PARAMS, 1, algo_params->str_id);
-	(*msg)->header.part.data = sizeof(u32) +
-			sizeof(*algo_params) + algo_params->size;
-	memcpy((*msg)->mailbox_data, &(*msg)->header, sizeof(u32));
-	memcpy((*msg)->mailbox_data + sizeof(u32),
-				algo_params, sizeof(*algo_params));
-	return 0;
-}
-
-/**
- * sst_send_algo_ipc - send ipc msg for algorithm parameters
- *
- * @msg: post msg pointer
- *
- * This function is called to send ipc msg
- */
-int sst_send_algo_ipc(struct ipc_post **msg)
-{
-	sst_drv_ctx->ppp_params_blk.condition = false;
-	sst_drv_ctx->ppp_params_blk.ret_code = 0;
-	sst_drv_ctx->ppp_params_blk.on = true;
-	sst_drv_ctx->ppp_params_blk.data = NULL;
-	spin_lock(&sst_drv_ctx->list_spin_lock);
-	list_add_tail(&(*msg)->node, &sst_drv_ctx->ipc_dispatch_list);
-	spin_unlock(&sst_drv_ctx->list_spin_lock);
-	sst_post_message(&sst_drv_ctx->ipc_post_msg_wq);
-	return sst_wait_interruptible_timeout(sst_drv_ctx,
-			&sst_drv_ctx->ppp_params_blk, SST_BLOCK_TIMEOUT);
-}
-
-/**
- * intel_sst_ioctl_dsp - receives the device ioctl's
- *
- * @cmd:Ioctl cmd
- * @arg:data
- *
- * This function is called when a user space component
- * sends a DSP Ioctl to SST driver
- */
-long intel_sst_ioctl_dsp(unsigned int cmd, unsigned long arg)
-{
-	int retval = 0;
-	struct snd_ppp_params algo_params;
-	struct snd_ppp_params *algo_params_copied;
-	struct ipc_post *msg;
-
-	switch (_IOC_NR(cmd)) {
-	case _IOC_NR(SNDRV_SST_SET_ALGO):
-		if (copy_from_user(&algo_params, (void __user *)arg,
-							sizeof(algo_params)))
-			return -EFAULT;
-		if (algo_params.size > SST_MAILBOX_SIZE)
-			return -EMSGSIZE;
-
-		pr_debug("Algo ID %d Str id %d Enable %d Size %d\n",
-			algo_params.algo_id, algo_params.str_id,
-			algo_params.enable, algo_params.size);
-		retval = sst_create_algo_ipc(&algo_params, &msg);
-		if (retval)
-			break;
-		algo_params.reserved = 0;
-		if (copy_from_user(msg->mailbox_data + sizeof(algo_params),
-				algo_params.params, algo_params.size))
-			return -EFAULT;
-
-		retval = sst_send_algo_ipc(&msg);
-		if (retval) {
-			pr_debug("Error in sst_set_algo = %d\n", retval);
-			retval = -EIO;
-		}
-		break;
-
-	case _IOC_NR(SNDRV_SST_GET_ALGO):
-		if (copy_from_user(&algo_params, (void __user *)arg,
-							sizeof(algo_params)))
-			return -EFAULT;
-		pr_debug("Algo ID %d Str id %d Enable %d Size %d\n",
-			algo_params.algo_id, algo_params.str_id,
-			algo_params.enable, algo_params.size);
-		retval = sst_create_algo_ipc(&algo_params, &msg);
-		if (retval)
-			break;
-		algo_params.reserved = 1;
-		retval = sst_send_algo_ipc(&msg);
-		if (retval) {
-			pr_debug("Error in sst_get_algo = %d\n", retval);
-			retval = -EIO;
-			break;
-		}
-		algo_params_copied = (struct snd_ppp_params *)
-					sst_drv_ctx->ppp_params_blk.data;
-		if (algo_params_copied->size > algo_params.size) {
-			pr_debug("mem insufficient to copy\n");
-			retval = -EMSGSIZE;
-			goto free_mem;
-		} else {
-			char __user *tmp;
-
-			if (copy_to_user(algo_params.params,
-					algo_params_copied->params,
-					algo_params_copied->size)) {
-				retval = -EFAULT;
-				goto free_mem;
-			}
-			tmp = (char __user *)arg + offsetof(
-					struct snd_ppp_params, size);
-			if (copy_to_user(tmp, &algo_params_copied->size,
-						 sizeof(__u32))) {
-				retval = -EFAULT;
-				goto free_mem;
-			}
-
-		}
-free_mem:
-		kfree(algo_params_copied->params);
-		kfree(algo_params_copied);
-		break;
-	}
-	return retval;
-}
-
-
-int sst_ioctl_tuning_params(unsigned long arg)
-{
-	struct snd_sst_tuning_params params;
-	struct ipc_post *msg;
-
-	if (copy_from_user(&params, (void __user *)arg, sizeof(params)))
-		return -EFAULT;
-	if (params.size > SST_MAILBOX_SIZE)
-		return -ENOMEM;
-	pr_debug("Parameter %d, Stream %d, Size %d\n", params.type,
-			params.str_id, params.size);
-	if (sst_create_large_msg(&msg))
-		return -ENOMEM;
-
-	sst_fill_header(&msg->header, IPC_IA_TUNING_PARAMS, 1, params.str_id);
-	msg->header.part.data = sizeof(u32) + sizeof(params) + params.size;
-	memcpy(msg->mailbox_data, &msg->header.full, sizeof(u32));
-	memcpy(msg->mailbox_data + sizeof(u32), &params, sizeof(params));
-	if (copy_from_user(msg->mailbox_data + sizeof(params),
-			(void __user *)(unsigned long)params.addr,
-			params.size)) {
-		kfree(msg->mailbox_data);
-		kfree(msg);
-		return -EFAULT;
-	}
-	return sst_send_algo_ipc(&msg);
-}
-/**
- * intel_sst_ioctl - receives the device ioctl's
- * @file_ptr:pointer to file
- * @cmd:Ioctl cmd
- * @arg:data
- *
- * This function is called by OS when a user space component
- * sends an Ioctl to SST driver
- */
-long intel_sst_ioctl(struct file *file_ptr, unsigned int cmd, unsigned long arg)
-{
-	int retval = 0;
-	struct ioctl_pvt_data *data = NULL;
-	int str_id = 0, minor = 0;
-
-	data = file_ptr->private_data;
-	if (data) {
-		minor = 0;
-		str_id = data->str_id;
-	} else
-		minor = 1;
-
-	if (sst_drv_ctx->sst_state != SST_FW_RUNNING)
-		return -EBUSY;
-
-	switch (_IOC_NR(cmd)) {
-	case _IOC_NR(SNDRV_SST_STREAM_PAUSE):
-		pr_debug("IOCTL_PAUSE received for %d!\n", str_id);
-		if (minor != STREAM_MODULE) {
-			retval = -EBADRQC;
-			break;
-		}
-		retval = sst_pause_stream(str_id);
-		break;
-
-	case _IOC_NR(SNDRV_SST_STREAM_RESUME):
-		pr_debug("SNDRV_SST_IOCTL_RESUME received!\n");
-		if (minor != STREAM_MODULE) {
-			retval = -EBADRQC;
-			break;
-		}
-		retval = sst_resume_stream(str_id);
-		break;
-
-	case _IOC_NR(SNDRV_SST_STREAM_SET_PARAMS): {
-		struct snd_sst_params str_param;
-
-		pr_debug("IOCTL_SET_PARAMS received!\n");
-		if (minor != STREAM_MODULE) {
-			retval = -EBADRQC;
-			break;
-		}
-
-		if (copy_from_user(&str_param, (void __user *)arg,
-				sizeof(str_param))) {
-			retval = -EFAULT;
-			break;
-		}
-
-		if (!str_id) {
-
-			retval = sst_get_stream(&str_param);
-			if (retval > 0) {
-				struct stream_info *str_info;
-				char __user *dest;
-
-				sst_drv_ctx->stream_cnt++;
-				data->str_id = retval;
-				str_info = &sst_drv_ctx->streams[retval];
-				str_info->src = SST_DRV;
-				dest = (char __user *)arg + offsetof(struct snd_sst_params, stream_id);
-				retval = copy_to_user(dest, &retval, sizeof(__u32));
-				if (retval)
-					retval = -EFAULT;
-			} else {
-				if (retval == -SST_ERR_INVALID_PARAMS)
-					retval = -EINVAL;
-			}
-		} else {
-			pr_debug("SET_STREAM_PARAMS received!\n");
-			/* allocated set params only */
-			retval = sst_set_stream_param(str_id, &str_param);
-			/* Block the call for reply */
-			if (!retval) {
-				int sfreq = 0, word_size = 0, num_channel = 0;
-				sfreq =	str_param.sparams.uc.pcm_params.sfreq;
-				word_size = str_param.sparams.uc.pcm_params.pcm_wd_sz;
-				num_channel = str_param.sparams.uc.pcm_params.num_chan;
-				if (str_param.ops == STREAM_OPS_CAPTURE) {
-					sst_drv_ctx->scard_ops->\
-					set_pcm_audio_params(sfreq,
-						word_size, num_channel);
-				}
-			}
-		}
-		break;
-	}
-	case _IOC_NR(SNDRV_SST_SET_VOL): {
-		struct snd_sst_vol set_vol;
-
-		if (copy_from_user(&set_vol, (void __user *)arg,
-				sizeof(set_vol))) {
-			pr_debug("copy failed\n");
-			retval = -EFAULT;
-			break;
-		}
-		pr_debug("SET_VOLUME received for %d!\n",
-				set_vol.stream_id);
-		if (minor == STREAM_MODULE && set_vol.stream_id == 0) {
-			pr_debug("invalid operation!\n");
-			retval = -EPERM;
-			break;
-		}
-		retval = sst_set_vol(&set_vol);
-		break;
-	}
-	case _IOC_NR(SNDRV_SST_GET_VOL): {
-		struct snd_sst_vol get_vol;
-
-		if (copy_from_user(&get_vol, (void __user *)arg,
-				sizeof(get_vol))) {
-			retval = -EFAULT;
-			break;
-		}
-		pr_debug("IOCTL_GET_VOLUME received for stream = %d!\n",
-				get_vol.stream_id);
-		if (minor == STREAM_MODULE && get_vol.stream_id == 0) {
-			pr_debug("invalid operation!\n");
-			retval = -EPERM;
-			break;
-		}
-		retval = sst_get_vol(&get_vol);
-		if (retval) {
-			retval = -EIO;
-			break;
-		}
-		pr_debug("id:%d\n, vol:%d, ramp_dur:%d, ramp_type:%d\n",
-				get_vol.stream_id, get_vol.volume,
-				get_vol.ramp_duration, get_vol.ramp_type);
-		if (copy_to_user((struct snd_sst_vol __user *)arg,
-				&get_vol, sizeof(get_vol))) {
-			retval = -EFAULT;
-			break;
-		}
-		/*sst_print_get_vol_info(str_id, &get_vol);*/
-		break;
-	}
-
-	case _IOC_NR(SNDRV_SST_MUTE): {
-		struct snd_sst_mute set_mute;
-
-		if (copy_from_user(&set_mute, (void __user *)arg,
-				sizeof(set_mute))) {
-			retval = -EFAULT;
-			break;
-		}
-		pr_debug("SNDRV_SST_SET_VOLUME received for %d!\n",
-			set_mute.stream_id);
-		if (minor == STREAM_MODULE && set_mute.stream_id == 0) {
-			retval = -EPERM;
-			break;
-		}
-		retval = sst_set_mute(&set_mute);
-		break;
-	}
-	case _IOC_NR(SNDRV_SST_STREAM_GET_PARAMS): {
-		struct snd_sst_get_stream_params get_params;
-
-		pr_debug("IOCTL_GET_PARAMS received!\n");
-		if (minor != 0) {
-			retval = -EBADRQC;
-			break;
-		}
-
-		retval = sst_get_stream_params(str_id, &get_params);
-		if (retval) {
-			retval = -EIO;
-			break;
-		}
-		if (copy_to_user((struct snd_sst_get_stream_params __user *)arg,
-					&get_params, sizeof(get_params))) {
-			retval = -EFAULT;
-			break;
-		}
-		sst_print_stream_params(&get_params);
-		break;
-	}
-
-	case _IOC_NR(SNDRV_SST_MMAP_PLAY):
-	case _IOC_NR(SNDRV_SST_MMAP_CAPTURE): {
-		struct snd_sst_mmap_buffs mmap_buf;
-
-		pr_debug("SNDRV_SST_MMAP_PLAY/CAPTURE received!\n");
-		if (minor != STREAM_MODULE) {
-			retval = -EBADRQC;
-			break;
-		}
-		if (copy_from_user(&mmap_buf, (void __user *)arg,
-				sizeof(mmap_buf))) {
-			retval = -EFAULT;
-			break;
-		}
-		retval = intel_sst_mmap_play_capture(str_id, &mmap_buf);
-		break;
-	}
-	case _IOC_NR(SNDRV_SST_STREAM_DROP):
-		pr_debug("SNDRV_SST_IOCTL_DROP received!\n");
-		if (minor != STREAM_MODULE) {
-			retval = -EINVAL;
-			break;
-		}
-		retval = sst_drop_stream(str_id);
-		break;
-
-	case _IOC_NR(SNDRV_SST_STREAM_GET_TSTAMP): {
-		struct snd_sst_tstamp tstamp = {0};
-		unsigned long long time, freq, mod;
-
-		pr_debug("SNDRV_SST_STREAM_GET_TSTAMP received!\n");
-		if (minor != STREAM_MODULE) {
-			retval = -EBADRQC;
-			break;
-		}
-		memcpy_fromio(&tstamp,
-			sst_drv_ctx->mailbox + SST_TIME_STAMP + str_id * sizeof(tstamp),
-			sizeof(tstamp));
-		time = tstamp.samples_rendered;
-		freq = (unsigned long long) tstamp.sampling_frequency;
-		time = time * 1000; /* converting it to ms */
-		mod = do_div(time, freq);
-		if (copy_to_user((void __user *)arg, &time,
-				sizeof(unsigned long long)))
-			retval = -EFAULT;
-		break;
-	}
-
-	case _IOC_NR(SNDRV_SST_STREAM_START):{
-		struct stream_info *stream;
-
-		pr_debug("SNDRV_SST_STREAM_START received!\n");
-		if (minor != STREAM_MODULE) {
-			retval = -EINVAL;
-			break;
-		}
-		retval = sst_validate_strid(str_id);
-		if (retval)
-			break;
-		stream = &sst_drv_ctx->streams[str_id];
-		mutex_lock(&stream->lock);
-		if (stream->status == STREAM_INIT &&
-			stream->need_draining != true) {
-			stream->prev = stream->status;
-			stream->status = STREAM_RUNNING;
-			if (stream->ops == STREAM_OPS_PLAYBACK ||
-				stream->ops == STREAM_OPS_PLAYBACK_DRM) {
-				retval = sst_play_frame(str_id);
-			} else if (stream->ops == STREAM_OPS_CAPTURE)
-				retval = sst_capture_frame(str_id);
-			else {
-				retval = -EINVAL;
-				mutex_unlock(&stream->lock);
-				break;
-			}
-			if (retval < 0) {
-				stream->status = STREAM_INIT;
-				mutex_unlock(&stream->lock);
-				break;
-			}
-		} else {
-			retval = -EINVAL;
-		}
-		mutex_unlock(&stream->lock);
-		break;
-	}
-
-	case _IOC_NR(SNDRV_SST_SET_TARGET_DEVICE): {
-		struct snd_sst_target_device target_device;
-
-		pr_debug("SET_TARGET_DEVICE received!\n");
-		if (copy_from_user(&target_device, (void __user *)arg,
-				sizeof(target_device))) {
-			retval = -EFAULT;
-			break;
-		}
-		if (minor != AM_MODULE) {
-			retval = -EBADRQC;
-			break;
-		}
-		retval = sst_target_device_select(&target_device);
-		break;
-	}
-
-	case _IOC_NR(SNDRV_SST_DRIVER_INFO): {
-		struct snd_sst_driver_info info;
-
-		pr_debug("SNDRV_SST_DRIVER_INFO received\n");
-		info.version = SST_VERSION_NUM;
-		/* hard coding, shud get sumhow later */
-		info.active_pcm_streams = sst_drv_ctx->stream_cnt -
-						sst_drv_ctx->encoded_cnt;
-		info.active_enc_streams = sst_drv_ctx->encoded_cnt;
-		info.max_pcm_streams = MAX_ACTIVE_STREAM - MAX_ENC_STREAM;
-		info.max_enc_streams = MAX_ENC_STREAM;
-		info.buf_per_stream = sst_drv_ctx->mmap_len;
-		if (copy_to_user((void __user *)arg, &info,
-				sizeof(info)))
-			retval = -EFAULT;
-		break;
-	}
-
-	case _IOC_NR(SNDRV_SST_STREAM_DECODE): {
-		struct snd_sst_dbufs param;
-		struct snd_sst_dbufs dbufs_local;
-		struct snd_sst_buffs ibufs, obufs;
-		struct snd_sst_buff_entry *ibuf_tmp, *obuf_tmp;
-		char __user *dest;
-
-		pr_debug("SNDRV_SST_STREAM_DECODE received\n");
-		if (minor != STREAM_MODULE) {
-			retval = -EBADRQC;
-			break;
-		}
-		if (copy_from_user(&param, (void __user *)arg,
-				sizeof(param))) {
-			retval = -EFAULT;
-			break;
-		}
-
-		dbufs_local.input_bytes_consumed = param.input_bytes_consumed;
-		dbufs_local.output_bytes_produced =
-					param.output_bytes_produced;
-
-		if (copy_from_user(&ibufs, (void __user *)param.ibufs, sizeof(ibufs))) {
-			retval = -EFAULT;
-			break;
-		}
-		if (copy_from_user(&obufs, (void __user *)param.obufs, sizeof(obufs))) {
-			retval = -EFAULT;
-			break;
-		}
-
-		ibuf_tmp = kcalloc(ibufs.entries, sizeof(*ibuf_tmp), GFP_KERNEL);
-		obuf_tmp = kcalloc(obufs.entries, sizeof(*obuf_tmp), GFP_KERNEL);
-		if (!ibuf_tmp || !obuf_tmp) {
-			retval = -ENOMEM;
-			goto free_iobufs;
-		}
-
-		if (copy_from_user(ibuf_tmp, (void __user *)ibufs.buff_entry,
-				ibufs.entries * sizeof(*ibuf_tmp))) {
-			retval = -EFAULT;
-			goto free_iobufs;
-		}
-		ibufs.buff_entry = ibuf_tmp;
-		dbufs_local.ibufs = &ibufs;
-
-		if (copy_from_user(obuf_tmp, (void __user *)obufs.buff_entry,
-				obufs.entries * sizeof(*obuf_tmp))) {
-			retval = -EFAULT;
-			goto free_iobufs;
-		}
-		obufs.buff_entry = obuf_tmp;
-		dbufs_local.obufs = &obufs;
-
-		retval = sst_decode(str_id, &dbufs_local);
-		if (retval) {
-			retval = -EAGAIN;
-			goto free_iobufs;
-		}
-
-		dest = (char __user *)arg + offsetof(struct snd_sst_dbufs, input_bytes_consumed);
-		if (copy_to_user(dest,
-				&dbufs_local.input_bytes_consumed,
-				sizeof(unsigned long long))) {
-			retval = -EFAULT;
-			goto free_iobufs;
-		}
-
-		dest = (char __user *)arg + offsetof(struct snd_sst_dbufs, input_bytes_consumed);
-		if (copy_to_user(dest,
-				&dbufs_local.output_bytes_produced,
-				sizeof(unsigned long long))) {
-			retval = -EFAULT;
-			goto free_iobufs;
-		}
-free_iobufs:
-		kfree(ibuf_tmp);
-		kfree(obuf_tmp);
-		break;
-	}
-
-	case _IOC_NR(SNDRV_SST_STREAM_DRAIN):
-		pr_debug("SNDRV_SST_STREAM_DRAIN received\n");
-		if (minor != STREAM_MODULE) {
-			retval = -EINVAL;
-			break;
-		}
-		retval = sst_drain_stream(str_id);
-		break;
-
-	case _IOC_NR(SNDRV_SST_STREAM_BYTES_DECODED): {
-		unsigned long long __user *bytes = (unsigned long long __user *)arg;
-		struct snd_sst_tstamp tstamp = {0};
-
-		pr_debug("STREAM_BYTES_DECODED received!\n");
-		if (minor != STREAM_MODULE) {
-			retval = -EINVAL;
-			break;
-		}
-		memcpy_fromio(&tstamp,
-			sst_drv_ctx->mailbox + SST_TIME_STAMP + str_id * sizeof(tstamp),
-			sizeof(tstamp));
-		if (copy_to_user(bytes, &tstamp.bytes_processed,
-				sizeof(*bytes)))
-			retval = -EFAULT;
-		break;
-	}
-	case _IOC_NR(SNDRV_SST_FW_INFO): {
-		struct snd_sst_fw_info *fw_info;
-
-		pr_debug("SNDRV_SST_FW_INFO received\n");
-
-		fw_info = kzalloc(sizeof(*fw_info), GFP_ATOMIC);
-		if (!fw_info) {
-			retval = -ENOMEM;
-			break;
-		}
-		retval = sst_get_fw_info(fw_info);
-		if (retval) {
-			retval = -EIO;
-			kfree(fw_info);
-			break;
-		}
-		if (copy_to_user((struct snd_sst_dbufs __user *)arg,
-				fw_info, sizeof(*fw_info))) {
-			kfree(fw_info);
-			retval = -EFAULT;
-			break;
-		}
-		/*sst_print_fw_info(fw_info);*/
-		kfree(fw_info);
-		break;
-	}
-	case _IOC_NR(SNDRV_SST_GET_ALGO):
-	case _IOC_NR(SNDRV_SST_SET_ALGO):
-		if (minor != AM_MODULE) {
-			retval = -EBADRQC;
-			break;
-		}
-		retval = intel_sst_ioctl_dsp(cmd, arg);
-		break;
-
-	case _IOC_NR(SNDRV_SST_TUNING_PARAMS):
-		if (minor != AM_MODULE) {
-			retval = -EBADRQC;
-			break;
-		}
-		retval = sst_ioctl_tuning_params(arg);
-		break;
-
-	default:
-		retval = -EINVAL;
-	}
-	pr_debug("intel_sst_ioctl:complete ret code = %d\n", retval);
-	return retval;
-}
-
diff --git a/drivers/staging/intel_sst/intel_sst_common.h b/drivers/staging/intel_sst/intel_sst_common.h
deleted file mode 100644
index 870981b..0000000
--- a/drivers/staging/intel_sst/intel_sst_common.h
+++ /dev/null
@@ -1,623 +0,0 @@
-#ifndef __INTEL_SST_COMMON_H__
-#define __INTEL_SST_COMMON_H__
-/*
- *  intel_sst_common.h - Intel SST Driver for audio engine
- *
- *  Copyright (C) 2008-10 Intel Corporation
- *  Authors:	Vinod Koul <vinod.koul@intel.com>
- *		Harsha Priya <priya.harsha@intel.com>
- *		Dharageswari R <dharageswari.r@intel.com>
- *		KP Jeeja <jeeja.kp@intel.com>
- *  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; version 2 of the License.
- *
- *  This program is distributed in the hope that it will be useful, but
- *  WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *  General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License along
- *  with this program; if not, write to the Free Software Foundation, Inc.,
- *  59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
- *
- * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- *
- *  Common private declarations for SST
- */
-
-#define SST_DRIVER_VERSION "1.2.17"
-#define SST_VERSION_NUM 0x1217
-
-/* driver names */
-#define SST_DRV_NAME "intel_sst_driver"
-#define SST_MRST_PCI_ID 0x080A
-#define SST_MFLD_PCI_ID 0x082F
-#define PCI_ID_LENGTH 4
-#define SST_SUSPEND_DELAY 2000
-#define FW_CONTEXT_MEM (64*1024)
-
-enum sst_states {
-	SST_FW_LOADED = 1,
-	SST_FW_RUNNING,
-	SST_UN_INIT,
-	SST_ERROR,
-	SST_SUSPENDED
-};
-
-#define MAX_ACTIVE_STREAM	3
-#define MAX_ENC_STREAM		1
-#define MAX_AM_HANDLES		1
-#define ALLOC_TIMEOUT		5000
-/* SST numbers */
-#define SST_BLOCK_TIMEOUT	5000
-#define TARGET_DEV_BLOCK_TIMEOUT	5000
-
-#define BLOCK_UNINIT		-1
-#define RX_TIMESLOT_UNINIT	-1
-
-/* SST register map */
-#define SST_CSR			0x00
-#define SST_PISR		0x08
-#define SST_PIMR		0x10
-#define SST_ISRX		0x18
-#define SST_IMRX		0x28
-#define SST_IPCX		0x38 /* IPC IA-SST */
-#define SST_IPCD		0x40 /* IPC SST-IA */
-#define SST_ISRD		0x20 /* dummy register for shim workaround */
-#define SST_SHIM_SIZE		0X44
-
-#define SPI_MODE_ENABLE_BASE_ADDR 0xffae4000
-#define FW_SIGNATURE_SIZE	4
-
-/* PMIC and SST hardware states */
-enum sst_mad_states {
-	SND_MAD_UN_INIT = 0,
-	SND_MAD_INIT_DONE,
-};
-
-/* stream states */
-enum sst_stream_states {
-	STREAM_UN_INIT	= 0,	/* Freed/Not used stream */
-	STREAM_RUNNING	= 1,	/* Running */
-	STREAM_PAUSED	= 2,	/* Paused stream */
-	STREAM_DECODE	= 3,	/* stream is in decoding only state */
-	STREAM_INIT	= 4,	/* stream init, waiting for data */
-};
-
-
-enum sst_ram_type {
-	SST_IRAM	= 1,
-	SST_DRAM	= 2,
-};
-/* SST shim registers to structure mapping  */
-union config_status_reg {
-	struct {
-		u32 mfld_strb:1;
-		u32 sst_reset:1;
-		u32 hw_rsvd:3;
-		u32 sst_clk:2;
-		u32 bypass:3;
-		u32 run_stall:1;
-		u32 rsvd1:2;
-		u32 strb_cntr_rst:1;
-		u32 rsvd:18;
-	} part;
-	u32 full;
-};
-
-union interrupt_reg {
-	struct {
-		u32 done_interrupt:1;
-		u32 busy_interrupt:1;
-		u32 rsvd:30;
-	} part;
-	u32 full;
-};
-
-union sst_pisr_reg {
-	struct {
-		u32 pssp0:1;
-		u32 pssp1:1;
-		u32 rsvd0:3;
-		u32 dmac:1;
-		u32 rsvd1:26;
-	} part;
-	u32 full;
-};
-
-union sst_pimr_reg {
-	struct {
-		u32 ssp0:1;
-		u32 ssp1:1;
-		u32 rsvd0:3;
-		u32 dmac:1;
-		u32 rsvd1:10;
-		u32 ssp0_sc:1;
-		u32 ssp1_sc:1;
-		u32 rsvd2:3;
-		u32 dmac_sc:1;
-		u32 rsvd3:10;
-	} part;
-	u32 full;
-};
-
-
-struct sst_stream_bufs {
-	struct list_head	node;
-	u32			size;
-	const char		*addr;
-	u32			data_copied;
-	bool			in_use;
-	u32			offset;
-};
-
-struct snd_sst_user_cap_list {
-	unsigned int iov_index; /* index of iov */
-	unsigned long iov_offset; /* offset in iov */
-	unsigned long offset; /* offset in kmem */
-	unsigned long size; /* size copied */
-	struct list_head node;
-};
-/*
-This structure is used to block a user/fw data call to another
-fw/user call
-*/
-struct sst_block {
-	bool	condition; /* condition for blocking check */
-	int	ret_code; /* ret code when block is released */
-	void	*data; /* data to be appsed for block if any */
-	bool	on;
-};
-
-enum snd_sst_buf_type {
-	SST_BUF_USER_STATIC = 1,
-	SST_BUF_USER_DYNAMIC,
-	SST_BUF_MMAP_STATIC,
-	SST_BUF_MMAP_DYNAMIC,
-};
-
-enum snd_src {
-	SST_DRV = 1,
-	MAD_DRV = 2
-};
-
-/**
- * struct stream_info - structure that holds the stream information
- *
- * @status : stream current state
- * @prev : stream prev state
- * @codec : stream codec
- * @sst_id : stream id
- * @ops : stream operation pb/cp/drm...
- * @bufs: stream buffer list
- * @lock : stream mutex for protecting state
- * @pcm_lock : spinlock for pcm path only
- * @mmapped : is stream mmapped
- * @sg_index : current stream user buffer index
- * @cur_ptr : stream user buffer pointer
- * @buf_entry : current user buffer
- * @data_blk : stream block for data operations
- * @ctrl_blk : stream block for ctrl operations
- * @buf_type : stream user buffer type
- * @pcm_substream : PCM substream
- * @period_elapsed : PCM period elapsed callback
- * @sfreq : stream sampling freq
- * @decode_ibuf : Decoded i/p buffers pointer
- * @decode_obuf : Decoded o/p buffers pointer
- * @decode_isize : Decoded i/p buffers size
- * @decode_osize : Decoded o/p buffers size
- * @decode_ibuf_type : Decoded i/p buffer type
- * @decode_obuf_type : Decoded o/p buffer type
- * @idecode_alloc : Decode alloc index
- * @need_draining : stream set for drain
- * @str_type : stream type
- * @curr_bytes : current bytes decoded
- * @cumm_bytes : cummulative bytes decoded
- * @str_type : stream type
- * @src : stream source
- * @device : output device type (medfield only)
- * @pcm_slot : pcm slot value
- */
-struct stream_info {
-	unsigned int		status;
-	unsigned int		prev;
-	u8			codec;
-	unsigned int		sst_id;
-	unsigned int		ops;
-	struct list_head	bufs;
-	struct mutex		lock; /* mutex */
-	spinlock_t          pcm_lock;
-	bool			mmapped;
-	unsigned int		sg_index; /*  current buf Index  */
-	unsigned char __user 	*cur_ptr; /*  Current static bufs  */
-	struct snd_sst_buf_entry __user *buf_entry;
-	struct sst_block	data_blk; /* stream ops block */
-	struct sst_block	ctrl_blk; /* stream control cmd block */
-	enum snd_sst_buf_type   buf_type;
-	void			*pcm_substream;
-	void (*period_elapsed) (void *pcm_substream);
-	unsigned int		sfreq;
-	void			*decode_ibuf, *decode_obuf;
-	unsigned int		decode_isize, decode_osize;
-	u8 decode_ibuf_type, decode_obuf_type;
-	unsigned int		idecode_alloc;
-	unsigned int		need_draining;
-	unsigned int		str_type;
-	u32			curr_bytes;
-	u32			cumm_bytes;
-	u32			src;
-	enum snd_sst_audio_device_type device;
-	u8			pcm_slot;
-};
-
-/*
- * struct stream_alloc_bloc - this structure is used for blocking the user's
- * alloc calls to fw's response to alloc calls
- *
- * @sst_id : session id of blocked stream
- * @ops_block : ops block struture
- */
-struct stream_alloc_block {
-	int			sst_id; /* session id of blocked stream */
-	struct sst_block	ops_block; /* ops block struture */
-};
-
-#define SST_FW_SIGN "$SST"
-#define SST_FW_LIB_SIGN "$LIB"
-
-/*
- * struct fw_header - FW file headers
- *
- * @signature : FW signature
- * @modules : # of modules
- * @file_format : version of header format
- * @reserved : reserved fields
- */
-struct fw_header {
-	unsigned char signature[FW_SIGNATURE_SIZE]; /* FW signature */
-	u32 file_size; /* size of fw minus this header */
-	u32 modules; /*  # of modules */
-	u32 file_format; /* version of header format */
-	u32 reserved[4];
-};
-
-struct fw_module_header {
-	unsigned char signature[FW_SIGNATURE_SIZE]; /* module signature */
-	u32 mod_size; /* size of module */
-	u32 blocks; /* # of blocks */
-	u32 type; /* codec type, pp lib */
-	u32 entry_point;
-};
-
-struct dma_block_info {
-	enum sst_ram_type	type;	/* IRAM/DRAM */
-	u32			size;	/* Bytes */
-	u32			ram_offset; /* Offset in I/DRAM */
-	u32			rsvd;	/* Reserved field */
-};
-
-struct ioctl_pvt_data {
-	int			str_id;
-	int			pvt_id;
-};
-
-struct sst_ipc_msg_wq {
-	union ipc_header	header;
-	char mailbox[SST_MAILBOX_SIZE];
-	struct work_struct	wq;
-};
-
-struct mad_ops_wq {
-	int stream_id;
-	enum sst_controls control_op;
-	struct work_struct	wq;
-
-};
-
-#define SST_MMAP_PAGES	(640*1024 / PAGE_SIZE)
-#define SST_MMAP_STEP	(40*1024 / PAGE_SIZE)
-
-/***
- * struct intel_sst_drv - driver ops
- *
- * @pmic_state : pmic state
- * @pmic_vendor : pmic vendor detected
- * @sst_state : current sst device state
- * @pci_id : PCI device id loaded
- * @shim : SST shim pointer
- * @mailbox : SST mailbox pointer
- * @iram : SST IRAM pointer
- * @dram : SST DRAM pointer
- * @shim_phy_add : SST shim phy addr
- * @ipc_dispatch_list : ipc messages dispatched
- * @ipc_post_msg_wq : wq to post IPC messages context
- * @ipc_process_msg : wq to process msgs from FW context
- * @ipc_process_reply : wq to process reply from FW context
- * @ipc_post_msg : wq to post reply from FW context
- * @mad_ops : MAD driver operations registered
- * @mad_wq : MAD driver wq
- * @post_msg_wq : wq to post IPC messages
- * @process_msg_wq : wq to process msgs from FW
- * @process_reply_wq : wq to process reply from FW
- * @streams : sst stream contexts
- * @alloc_block : block structure for alloc
- * @tgt_dev_blk : block structure for target device
- * @fw_info_blk : block structure for fw info block
- * @vol_info_blk : block structure for vol info block
- * @mute_info_blk : block structure for mute info block
- * @hs_info_blk : block structure for hs info block
- * @list_lock : sst driver list lock (deprecated)
- * @list_spin_lock : sst driver spin lock block
- * @scard_ops : sst card ops
- * @pci : sst pci device struture
- * @active_streams : sst active streams
- * @sst_lock : sst device lock
- * @stream_lock : sst stream lock
- * @unique_id : sst unique id
- * @stream_cnt : total sst active stream count
- * @pb_streams : total active pb streams
- * @cp_streams : total active cp streams
- * @lpe_stalled : lpe stall status
- * @pmic_port_instance : active pmic port instance
- * @rx_time_slot_status : active rx slot
- * @lpaudio_start : lpaudio status
- * @audio_start : audio status
- * @devt_d : pointer to /dev/lpe node
- * @devt_c : pointer to /dev/lpe_ctrl node
- * @max_streams : max streams allowed
- */
-struct intel_sst_drv {
-	bool			pmic_state;
-	int			pmic_vendor;
-	int			sst_state;
-	unsigned int		pci_id;
-	void __iomem		*shim;
-	void __iomem		*mailbox;
-	void __iomem		*iram;
-	void __iomem		*dram;
-	unsigned int		shim_phy_add;
-	struct list_head	ipc_dispatch_list;
-	struct work_struct	ipc_post_msg_wq;
-	struct sst_ipc_msg_wq	ipc_process_msg;
-	struct sst_ipc_msg_wq	ipc_process_reply;
-	struct sst_ipc_msg_wq	ipc_post_msg;
-	struct mad_ops_wq	mad_ops;
-	wait_queue_head_t	wait_queue;
-	struct workqueue_struct *mad_wq;
-	struct workqueue_struct *post_msg_wq;
-	struct workqueue_struct *process_msg_wq;
-	struct workqueue_struct *process_reply_wq;
-
-	struct stream_info	streams[MAX_NUM_STREAMS];
-	struct stream_alloc_block alloc_block[MAX_ACTIVE_STREAM];
-	struct sst_block	tgt_dev_blk, fw_info_blk, ppp_params_blk,
-				vol_info_blk, mute_info_blk, hs_info_blk;
-	struct mutex		list_lock;/* mutex for IPC list locking */
-	spinlock_t	list_spin_lock; /* mutex for IPC list locking */
-	struct snd_pmic_ops	*scard_ops;
-	struct pci_dev		*pci;
-	int active_streams[MAX_NUM_STREAMS];
-	void			*mmap_mem;
-	struct mutex            sst_lock;
-	struct mutex		stream_lock;
-	unsigned int		mmap_len;
-	unsigned int		unique_id;
-	unsigned int		stream_cnt;	/* total streams */
-	unsigned int		encoded_cnt;	/* enocded streams only */
-	unsigned int		am_cnt;
-	unsigned int		pb_streams;	/* pb streams active */
-	unsigned int		cp_streams;	/* cp streams active */
-	unsigned int		lpe_stalled; /* LPE is stalled or not */
-	unsigned int		pmic_port_instance; /*pmic port instance*/
-	int			rx_time_slot_status;
-	unsigned int		lpaudio_start;
-		/* 1 - LPA stream(MP3 pb) in progress*/
-	unsigned int		audio_start;
-	dev_t			devt_d, devt_c;
-	unsigned int		max_streams;
-	unsigned int		*fw_cntx;
-	unsigned int		fw_cntx_size;
-
-	unsigned int		fw_downloaded;
-};
-
-extern struct intel_sst_drv *sst_drv_ctx;
-
-#define CHIP_REV_REG 0xff108000
-#define CHIP_REV_ADDR 0x78
-
-/* misc definitions */
-#define FW_DWNL_ID 0xFF
-#define LOOP1 0x11111111
-#define LOOP2 0x22222222
-#define LOOP3 0x33333333
-#define LOOP4 0x44444444
-
-#define SST_DEFAULT_PMIC_PORT 1 /*audio port*/
-/* NOTE: status will have +ve for good cases and -ve for error ones */
-#define MAX_STREAM_FIELD 255
-
-int sst_alloc_stream(char *params, unsigned int stream_ops, u8 codec,
-						unsigned int session_id);
-int sst_alloc_stream_response(unsigned int str_id,
-				struct snd_sst_alloc_response *response);
-int sst_stalled(void);
-int sst_pause_stream(int id);
-int sst_resume_stream(int id);
-int sst_enable_rx_timeslot(int status);
-int sst_drop_stream(int id);
-int sst_free_stream(int id);
-int sst_start_stream(int streamID);
-int sst_play_frame(int streamID);
-int sst_pcm_play_frame(int str_id, struct sst_stream_bufs *sst_buf);
-int sst_capture_frame(int streamID);
-int sst_set_stream_param(int streamID, struct snd_sst_params *str_param);
-int sst_target_device_select(struct snd_sst_target_device *target_device);
-int sst_decode(int str_id, struct snd_sst_dbufs *dbufs);
-int sst_get_decoded_bytes(int str_id, unsigned long long *bytes);
-int sst_get_fw_info(struct snd_sst_fw_info *info);
-int sst_get_stream_params(int str_id,
-		struct snd_sst_get_stream_params *get_params);
-int sst_get_stream(struct snd_sst_params *str_param);
-int sst_get_stream_allocated(struct snd_sst_params *str_param,
-				struct snd_sst_lib_download **lib_dnld);
-int sst_drain_stream(int str_id);
-int sst_get_vol(struct snd_sst_vol *set_vol);
-int sst_set_vol(struct snd_sst_vol *set_vol);
-int sst_set_mute(struct snd_sst_mute *set_mute);
-
-
-void sst_post_message(struct work_struct *work);
-void sst_process_message(struct work_struct *work);
-void sst_process_reply(struct work_struct *work);
-void sst_process_mad_ops(struct work_struct *work);
-void sst_process_mad_jack_detection(struct work_struct *work);
-
-long intel_sst_ioctl(struct file *file_ptr, unsigned int cmd,
-			unsigned long arg);
-int intel_sst_open(struct inode *i_node, struct file *file_ptr);
-int intel_sst_open_cntrl(struct inode *i_node, struct file *file_ptr);
-int intel_sst_release(struct inode *i_node, struct file *file_ptr);
-int intel_sst_release_cntrl(struct inode *i_node, struct file *file_ptr);
-int intel_sst_read(struct file *file_ptr, char __user *buf,
-			size_t count, loff_t *ppos);
-int intel_sst_write(struct file *file_ptr, const char __user *buf,
-			size_t count, loff_t *ppos);
-int intel_sst_mmap(struct file *fp, struct vm_area_struct *vma);
-ssize_t intel_sst_aio_write(struct kiocb *kiocb, const struct iovec *iov,
-			unsigned long nr_segs, loff_t  offset);
-ssize_t intel_sst_aio_read(struct kiocb *kiocb, const struct iovec *iov,
-			unsigned long nr_segs, loff_t offset);
-
-int sst_load_fw(const struct firmware *fw, void *context);
-int sst_load_library(struct snd_sst_lib_download *lib, u8 ops);
-int sst_spi_mode_enable(void);
-int sst_get_block_stream(struct intel_sst_drv *sst_drv_ctx);
-
-int sst_wait_interruptible(struct intel_sst_drv *sst_drv_ctx,
-				struct sst_block *block);
-int sst_wait_interruptible_timeout(struct intel_sst_drv *sst_drv_ctx,
-		struct sst_block *block, int timeout);
-int sst_wait_timeout(struct intel_sst_drv *sst_drv_ctx,
-		struct stream_alloc_block *block);
-int sst_create_large_msg(struct ipc_post **arg);
-int sst_create_short_msg(struct ipc_post **arg);
-void sst_wake_up_alloc_block(struct intel_sst_drv *sst_drv_ctx,
-		u8 sst_id, int status, void *data);
-void sst_clear_interrupt(void);
-int intel_sst_resume(struct pci_dev *pci);
-int sst_download_fw(void);
-void free_stream_context(unsigned int str_id);
-void sst_clean_stream(struct stream_info *stream);
-
-/*
- * sst_fill_header - inline to fill sst header
- *
- * @header : ipc header
- * @msg : IPC message to be sent
- * @large : is ipc large msg
- * @str_id : stream id
- *
- * this function is an inline function that sets the headers before
- * sending a message
- */
-static inline void sst_fill_header(union ipc_header *header,
-				int msg, int large, int str_id)
-{
-	header->part.msg_id = msg;
-	header->part.str_id = str_id;
-	header->part.large = large;
-	header->part.done = 0;
-	header->part.busy = 1;
-	header->part.data = 0;
-}
-
-/*
- * sst_assign_pvt_id - assign a pvt id for stream
- *
- * @sst_drv_ctx : driver context
- *
- * this inline function assigns a private id for calls that dont have stream
- * context yet, should be called with lock held
- */
-static inline unsigned int sst_assign_pvt_id(struct intel_sst_drv *sst_drv_ctx)
-{
-	sst_drv_ctx->unique_id++;
-	if (sst_drv_ctx->unique_id >= MAX_NUM_STREAMS)
-		sst_drv_ctx->unique_id = 1;
-	return sst_drv_ctx->unique_id;
-}
-
-/*
- * sst_init_stream - this function initialzes stream context
- *
- * @stream : stream struture
- * @codec : codec for stream
- * @sst_id : stream id
- * @ops : stream operation
- * @slot : stream pcm slot
- * @device : device type
- *
- * this inline function initialzes stream context for allocated stream
- */
-static inline void sst_init_stream(struct stream_info *stream,
-		int codec, int sst_id, int ops, u8 slot,
-		enum snd_sst_audio_device_type device)
-{
-	stream->status = STREAM_INIT;
-	stream->prev = STREAM_UN_INIT;
-	stream->codec = codec;
-	stream->sst_id = sst_id;
-	stream->str_type = 0;
-	stream->ops = ops;
-	stream->data_blk.on = false;
-	stream->data_blk.condition = false;
-	stream->data_blk.ret_code = 0;
-	stream->data_blk.data = NULL;
-	stream->ctrl_blk.on = false;
-	stream->ctrl_blk.condition = false;
-	stream->ctrl_blk.ret_code = 0;
-	stream->ctrl_blk.data = NULL;
-	stream->need_draining = false;
-	stream->decode_ibuf = NULL;
-	stream->decode_isize = 0;
-	stream->mmapped = false;
-	stream->pcm_slot = slot;
-	stream->device = device;
-}
-
-
-/*
- * sst_validate_strid - this function validates the stream id
- *
- * @str_id : stream id to be validated
- *
- * returns 0 if valid stream
- */
-static inline int sst_validate_strid(int str_id)
-{
-	if (str_id <= 0 || str_id > sst_drv_ctx->max_streams) {
-		pr_err("SST ERR: invalid stream id : %d MAX_STREAMS:%d\n",
-					str_id, sst_drv_ctx->max_streams);
-		return -EINVAL;
-	} else
-		return 0;
-}
-
-static inline int sst_shim_write(void __iomem *addr, int offset, int value)
-{
-
-	if (sst_drv_ctx->pci_id == SST_MRST_PCI_ID)
-		writel(value, addr + SST_ISRD);	/*dummy*/
-	writel(value, addr + offset);
-	return 0;
-}
-
-static inline int sst_shim_read(void __iomem *addr, int offset)
-{
-	return readl(addr + offset);
-}
-#endif /* __INTEL_SST_COMMON_H__ */
diff --git a/drivers/staging/intel_sst/intel_sst_drv_interface.c b/drivers/staging/intel_sst/intel_sst_drv_interface.c
deleted file mode 100644
index 22bd29c..0000000
--- a/drivers/staging/intel_sst/intel_sst_drv_interface.c
+++ /dev/null
@@ -1,564 +0,0 @@
-/*
- *  intel_sst_interface.c - Intel SST Driver for audio engine
- *
- *  Copyright (C) 2008-10 Intel Corp
- *  Authors:	Vinod Koul <vinod.koul@intel.com>
- *		Harsha Priya <priya.harsha@intel.com>
- *		Dharageswari R <dharageswari.r@intel.com)
- * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; version 2 of the License.
- *
- *  This program is distributed in the hope that it will be useful, but
- *  WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *  General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License along
- *  with this program; if not, write to the Free Software Foundation, Inc.,
- *  59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
- *
- * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- *  This driver exposes the audio engine functionalities to the ALSA
- *	and middleware.
- *  Upper layer interfaces (MAD driver, MMF) to SST driver
- */
-
-#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
-
-#include <linux/delay.h>
-#include <linux/pci.h>
-#include <linux/fs.h>
-#include <linux/firmware.h>
-#include <linux/pm_runtime.h>
-#include <linux/export.h>
-#include "intel_sst.h"
-#include "intel_sst_ioctl.h"
-#include "intel_sst_fw_ipc.h"
-#include "intel_sst_common.h"
-
-
-/*
- * sst_download_fw - download the audio firmware to DSP
- *
- * This function is called when the FW needs to be downloaded to SST DSP engine
- */
-int sst_download_fw(void)
-{
-	int retval;
-	const struct firmware *fw_sst;
-	char name[20];
-
-	if (sst_drv_ctx->sst_state != SST_UN_INIT)
-		return -EPERM;
-
-	/* Reload firmware is not needed for MRST */
-	if ( (sst_drv_ctx->pci_id == SST_MRST_PCI_ID) && sst_drv_ctx->fw_downloaded) {
-		pr_debug("FW already downloaded, skip for MRST platform\n");
-		sst_drv_ctx->sst_state = SST_FW_RUNNING;
-		return 0;
-	}
-
-	snprintf(name, sizeof(name), "%s%04x%s", "fw_sst_",
-					sst_drv_ctx->pci_id, ".bin");
-
-	pr_debug("Downloading %s FW now...\n", name);
-	retval = request_firmware(&fw_sst, name, &sst_drv_ctx->pci->dev);
-	if (retval) {
-		pr_err("request fw failed %d\n", retval);
-		return retval;
-	}
-	sst_drv_ctx->alloc_block[0].sst_id = FW_DWNL_ID;
-	sst_drv_ctx->alloc_block[0].ops_block.condition = false;
-	retval = sst_load_fw(fw_sst, NULL);
-	if (retval)
-		goto end_restore;
-
-	retval = sst_wait_timeout(sst_drv_ctx, &sst_drv_ctx->alloc_block[0]);
-	if (retval)
-		pr_err("fw download failed %d\n" , retval);
-	else
-		sst_drv_ctx->fw_downloaded = 1;
-
-end_restore:
-	release_firmware(fw_sst);
-	sst_drv_ctx->alloc_block[0].sst_id = BLOCK_UNINIT;
-	return retval;
-}
-
-
-/*
- * sst_stalled - this function checks if the lpe is in stalled state
- */
-int sst_stalled(void)
-{
-	int retry = 1000;
-	int retval = -1;
-
-	while (retry) {
-		if (!sst_drv_ctx->lpe_stalled)
-			return 0;
-		/*wait for time and re-check*/
-		msleep(1);
-
-		retry--;
-	}
-	pr_debug("in Stalled State\n");
-	return retval;
-}
-
-void free_stream_context(unsigned int str_id)
-{
-	struct stream_info *stream;
-
-	if (!sst_validate_strid(str_id)) {
-		/* str_id is valid, so stream is alloacted */
-		stream = &sst_drv_ctx->streams[str_id];
-		if (sst_free_stream(str_id))
-			sst_clean_stream(&sst_drv_ctx->streams[str_id]);
-		if (stream->ops == STREAM_OPS_PLAYBACK ||
-				stream->ops == STREAM_OPS_PLAYBACK_DRM) {
-			sst_drv_ctx->pb_streams--;
-			if (sst_drv_ctx->pci_id == SST_MFLD_PCI_ID)
-				sst_drv_ctx->scard_ops->power_down_pmic_pb(
-						stream->device);
-			else {
-				if (sst_drv_ctx->pb_streams == 0)
-					sst_drv_ctx->scard_ops->
-					power_down_pmic_pb(stream->device);
-			}
-		} else if (stream->ops == STREAM_OPS_CAPTURE) {
-			sst_drv_ctx->cp_streams--;
-			if (sst_drv_ctx->cp_streams == 0)
-				sst_drv_ctx->scard_ops->power_down_pmic_cp(
-						stream->device);
-		}
-		if (sst_drv_ctx->pb_streams == 0
-				&& sst_drv_ctx->cp_streams == 0)
-			sst_drv_ctx->scard_ops->power_down_pmic();
-	}
-}
-
-/*
- * sst_get_stream_allocated - this function gets a stream allocated with
- * the given params
- *
- * @str_param : stream params
- * @lib_dnld : pointer to pointer of lib downlaod struct
- *
- * This creates new stream id for a stream, in case lib is to be downloaded to
- * DSP, it downloads that
- */
-int sst_get_stream_allocated(struct snd_sst_params *str_param,
-		struct snd_sst_lib_download **lib_dnld)
-{
-	int retval, str_id;
-	struct stream_info *str_info;
-
-	retval = sst_alloc_stream((char *) &str_param->sparams, str_param->ops,
-				str_param->codec, str_param->device_type);
-	if (retval < 0) {
-		pr_err("sst_alloc_stream failed %d\n", retval);
-		return retval;
-	}
-	pr_debug("Stream allocated %d\n", retval);
-	str_id = retval;
-	str_info = &sst_drv_ctx->streams[str_id];
-	/* Block the call for reply */
-	retval = sst_wait_interruptible_timeout(sst_drv_ctx,
-			&str_info->ctrl_blk, SST_BLOCK_TIMEOUT);
-	if ((retval != 0) || (str_info->ctrl_blk.ret_code != 0)) {
-		pr_debug("FW alloc failed retval %d, ret_code %d\n",
-				retval, str_info->ctrl_blk.ret_code);
-		str_id = -str_info->ctrl_blk.ret_code; /*return error*/
-		*lib_dnld = str_info->ctrl_blk.data;
-		sst_clean_stream(str_info);
-	} else
-		pr_debug("FW Stream allocated success\n");
-	return str_id; /*will ret either error (in above if) or correct str id*/
-}
-
-/*
- * sst_get_sfreq - this function returns the frequency of the stream
- *
- * @str_param : stream params
- */
-static int sst_get_sfreq(struct snd_sst_params *str_param)
-{
-	switch (str_param->codec) {
-	case SST_CODEC_TYPE_PCM:
-		return 48000; /*str_param->sparams.uc.pcm_params.sfreq;*/
-	case SST_CODEC_TYPE_MP3:
-		return str_param->sparams.uc.mp3_params.sfreq;
-	case SST_CODEC_TYPE_AAC:
-		return str_param->sparams.uc.aac_params.sfreq;
-	case SST_CODEC_TYPE_WMA9:
-		return str_param->sparams.uc.wma_params.sfreq;
-	default:
-		return 0;
-	}
-}
-
-/*
- * sst_get_stream - this function prepares for stream allocation
- *
- * @str_param : stream param
- */
-int sst_get_stream(struct snd_sst_params *str_param)
-{
-	int i, retval;
-	struct stream_info *str_info;
-	struct snd_sst_lib_download *lib_dnld;
-
-	/* stream is not allocated, we are allocating */
-	retval = sst_get_stream_allocated(str_param, &lib_dnld);
-	if (retval == -(SST_LIB_ERR_LIB_DNLD_REQUIRED)) {
-		/* codec download is required */
-		struct snd_sst_alloc_response *response;
-
-		pr_debug("Codec is required.... trying that\n");
-		if (lib_dnld == NULL) {
-			pr_err("lib download null!!! abort\n");
-			return -EIO;
-		}
-		i = sst_get_block_stream(sst_drv_ctx);
-		response = sst_drv_ctx->alloc_block[i].ops_block.data;
-		pr_debug("alloc block allocated = %d\n", i);
-		if (i < 0) {
-			kfree(lib_dnld);
-			return -ENOMEM;
-		}
-		retval = sst_load_library(lib_dnld, str_param->ops);
-		kfree(lib_dnld);
-
-		sst_drv_ctx->alloc_block[i].sst_id = BLOCK_UNINIT;
-		if (!retval) {
-			pr_debug("codec was downloaded successfully\n");
-
-			retval = sst_get_stream_allocated(str_param, &lib_dnld);
-			if (retval <= 0)
-				goto err;
-
-			pr_debug("Alloc done stream id %d\n", retval);
-		} else {
-			pr_debug("codec download failed\n");
-			retval = -EIO;
-			goto err;
-		}
-	} else if  (retval <= 0)
-		goto err;
-	/*else
-		set_port_params(str_param, str_param->ops);*/
-
-	/* store sampling freq */
-	str_info = &sst_drv_ctx->streams[retval];
-	str_info->sfreq = sst_get_sfreq(str_param);
-
-	/* power on the analog, if reqd */
-	if (str_param->ops == STREAM_OPS_PLAYBACK ||
-			str_param->ops == STREAM_OPS_PLAYBACK_DRM) {
-		if (sst_drv_ctx->pci_id == SST_MRST_PCI_ID)
-			sst_drv_ctx->scard_ops->power_up_pmic_pb(
-					sst_drv_ctx->pmic_port_instance);
-		else
-			sst_drv_ctx->scard_ops->power_up_pmic_pb(
-							str_info->device);
-		/*Only if the playback is MP3 - Send a message*/
-		sst_drv_ctx->pb_streams++;
-	} else if (str_param->ops == STREAM_OPS_CAPTURE) {
-
-		sst_drv_ctx->scard_ops->power_up_pmic_cp(
-				sst_drv_ctx->pmic_port_instance);
-		/*Send a messageif not sent already*/
-		sst_drv_ctx->cp_streams++;
-	}
-
-err:
-	return retval;
-}
-
-void sst_process_mad_ops(struct work_struct *work)
-{
-
-	struct mad_ops_wq *mad_ops =
-			container_of(work, struct mad_ops_wq, wq);
-	int retval = 0;
-
-	switch (mad_ops->control_op) {
-	case SST_SND_PAUSE:
-		retval = sst_pause_stream(mad_ops->stream_id);
-		break;
-	case SST_SND_RESUME:
-		retval = sst_resume_stream(mad_ops->stream_id);
-		break;
-	case SST_SND_DROP:
-		retval = sst_drop_stream(mad_ops->stream_id);
-		break;
-	case SST_SND_START:
-			pr_debug("SST Debug: start stream\n");
-		retval = sst_start_stream(mad_ops->stream_id);
-		break;
-	case SST_SND_STREAM_PROCESS:
-		pr_debug("play/capt frames...\n");
-		break;
-	default:
-		pr_err(" wrong control_ops reported\n");
-	}
-	return;
-}
-
-void send_intial_rx_timeslot(void)
-{
-	if (sst_drv_ctx->pci_id == SST_MRST_PCI_ID &&
-			sst_drv_ctx->rx_time_slot_status != RX_TIMESLOT_UNINIT
-			&& sst_drv_ctx->pmic_vendor != SND_NC)
-		sst_enable_rx_timeslot(sst_drv_ctx->rx_time_slot_status);
-}
-
-/*
- * sst_open_pcm_stream - Open PCM interface
- *
- * @str_param: parameters of pcm stream
- *
- * This function is called by MID sound card driver to open
- * a new pcm interface
- */
-int sst_open_pcm_stream(struct snd_sst_params *str_param)
-{
-	struct stream_info *str_info;
-	int retval;
-
-	pm_runtime_get_sync(&sst_drv_ctx->pci->dev);
-
-	if (sst_drv_ctx->sst_state == SST_SUSPENDED) {
-		/* LPE is suspended, resume it before proceeding*/
-		pr_debug("Resuming from Suspended state\n");
-		retval = intel_sst_resume(sst_drv_ctx->pci);
-		if (retval) {
-			pr_err("Resume Failed = %#x, abort\n", retval);
-			pm_runtime_put(&sst_drv_ctx->pci->dev);
-			return retval;
-		}
-	}
-	if (sst_drv_ctx->sst_state == SST_UN_INIT) {
-		/* FW is not downloaded */
-		pr_debug("DSP Downloading FW now...\n");
-		retval = sst_download_fw();
-		if (retval) {
-			pr_err("FW download fail %x, abort\n", retval);
-			pm_runtime_put(&sst_drv_ctx->pci->dev);
-			return retval;
-		}
-		send_intial_rx_timeslot();
-	}
-
-	if (!str_param) {
-		pm_runtime_put(&sst_drv_ctx->pci->dev);
-		return -EINVAL;
-	}
-
-	retval = sst_get_stream(str_param);
-	if (retval > 0) {
-		sst_drv_ctx->stream_cnt++;
-		str_info = &sst_drv_ctx->streams[retval];
-		str_info->src = MAD_DRV;
-	} else
-		pm_runtime_put(&sst_drv_ctx->pci->dev);
-
-	return retval;
-}
-
-/*
- * sst_close_pcm_stream - Close PCM interface
- *
- * @str_id: stream id to be closed
- *
- * This function is called by MID sound card driver to close
- * an existing pcm interface
- */
-int sst_close_pcm_stream(unsigned int str_id)
-{
-	struct stream_info *stream;
-
-	pr_debug("sst: stream free called\n");
-	if (sst_validate_strid(str_id))
-		return -EINVAL;
-	stream = &sst_drv_ctx->streams[str_id];
-	free_stream_context(str_id);
-	stream->pcm_substream = NULL;
-	stream->status = STREAM_UN_INIT;
-	stream->period_elapsed = NULL;
-	sst_drv_ctx->stream_cnt--;
-	pr_debug("sst: will call runtime put now\n");
-	pm_runtime_put(&sst_drv_ctx->pci->dev);
-	return 0;
-}
-
-/*
- * sst_device_control - Set Control params
- *
- * @cmd: control cmd to be set
- * @arg: command argument
- *
- * This function is called by MID sound card driver to set
- * SST/Sound card controls for an opened stream.
- * This is registered with MID driver
- */
-int sst_device_control(int cmd, void *arg)
-{
-	int retval = 0, str_id = 0;
-
-	switch (cmd) {
-	case SST_SND_PAUSE:
-	case SST_SND_RESUME:
-	case SST_SND_DROP:
-	case SST_SND_START:
-		sst_drv_ctx->mad_ops.control_op = cmd;
-		sst_drv_ctx->mad_ops.stream_id = *(int *)arg;
-		queue_work(sst_drv_ctx->mad_wq, &sst_drv_ctx->mad_ops.wq);
-		break;
-
-	case SST_SND_STREAM_INIT: {
-		struct pcm_stream_info *str_info;
-		struct stream_info *stream;
-
-		pr_debug("stream init called\n");
-		str_info = (struct pcm_stream_info *)arg;
-		str_id = str_info->str_id;
-		retval = sst_validate_strid(str_id);
-		if (retval)
-			break;
-
-		stream = &sst_drv_ctx->streams[str_id];
-		pr_debug("setting the period ptrs\n");
-		stream->pcm_substream = str_info->mad_substream;
-		stream->period_elapsed = str_info->period_elapsed;
-		stream->sfreq = str_info->sfreq;
-		stream->prev = stream->status;
-		stream->status = STREAM_INIT;
-		break;
-	}
-
-	case SST_SND_BUFFER_POINTER: {
-		struct pcm_stream_info *stream_info;
-		struct snd_sst_tstamp fw_tstamp = {0,};
-		struct stream_info *stream;
-
-
-		stream_info = (struct pcm_stream_info *)arg;
-		str_id = stream_info->str_id;
-		retval = sst_validate_strid(str_id);
-		if (retval)
-			break;
-		stream = &sst_drv_ctx->streams[str_id];
-
-		if (!stream->pcm_substream)
-			break;
-		memcpy_fromio(&fw_tstamp,
-			((void *)(sst_drv_ctx->mailbox + SST_TIME_STAMP)
-			+(str_id * sizeof(fw_tstamp))),
-			sizeof(fw_tstamp));
-
-		pr_debug("Pointer Query on strid = %d ops %d\n",
-						str_id, stream->ops);
-
-		if (stream->ops == STREAM_OPS_PLAYBACK)
-			stream_info->buffer_ptr = fw_tstamp.samples_rendered;
-		else
-			stream_info->buffer_ptr = fw_tstamp.samples_processed;
-		pr_debug("Samples rendered = %llu, buffer ptr %llu\n",
-			fw_tstamp.samples_rendered, stream_info->buffer_ptr);
-		break;
-	}
-	case SST_ENABLE_RX_TIME_SLOT: {
-		int status = *(int *)arg;
-		sst_drv_ctx->rx_time_slot_status = status ;
-		sst_enable_rx_timeslot(status);
-		break;
-	}
-	default:
-		/* Illegal case */
-		pr_warn("illegal req\n");
-		return -EINVAL;
-	}
-
-	return retval;
-}
-
-
-struct intel_sst_pcm_control pcm_ops = {
-	.open = sst_open_pcm_stream,
-	.device_control = sst_device_control,
-	.close = sst_close_pcm_stream,
-};
-
-struct intel_sst_card_ops sst_pmic_ops = {
-	.pcm_control = &pcm_ops,
-};
-
-/*
- * register_sst_card - function for sound card to register
- *
- * @card: pointer to structure of operations
- *
- * This function is called card driver loads and is ready for registration
- */
-int register_sst_card(struct intel_sst_card_ops *card)
-{
-	if (!sst_drv_ctx) {
-		pr_err("No SST driver register card reject\n");
-		return -ENODEV;
-	}
-
-	if (!card || !card->module_name) {
-		pr_err("Null Pointer Passed\n");
-		return -EINVAL;
-	}
-	if (sst_drv_ctx->pmic_state == SND_MAD_UN_INIT) {
-		/* register this driver */
-		if ((strncmp(SST_CARD_NAMES, card->module_name,
-				strlen(SST_CARD_NAMES))) == 0) {
-			sst_drv_ctx->pmic_vendor = card->vendor_id;
-			sst_drv_ctx->scard_ops =  card->scard_ops;
-			sst_pmic_ops.module_name = card->module_name;
-			sst_drv_ctx->pmic_state = SND_MAD_INIT_DONE;
-			sst_drv_ctx->rx_time_slot_status = 0; /*default AMIC*/
-			card->pcm_control = sst_pmic_ops.pcm_control;
-			return 0;
-		} else {
-			pr_err("strcmp fail %s\n", card->module_name);
-			return -EINVAL;
-		}
-
-	} else {
-		/* already registered a driver */
-		pr_err("Repeat for registration..denied\n");
-		return -EBADRQC;
-	}
-	/* The ASoC code doesn't set scard_ops */
-	if (sst_drv_ctx->scard_ops)
-		sst_drv_ctx->scard_ops->card_status = SND_CARD_UN_INIT;
-	return 0;
-}
-EXPORT_SYMBOL_GPL(register_sst_card);
-
-/*
- * unregister_sst_card- function for sound card to un-register
- *
- * @card: pointer to structure of operations
- *
- * This function is called when card driver unloads
- */
-void unregister_sst_card(struct intel_sst_card_ops *card)
-{
-	if (sst_pmic_ops.pcm_control == card->pcm_control) {
-		/* unreg */
-		sst_pmic_ops.module_name = "";
-		sst_drv_ctx->pmic_state = SND_MAD_UN_INIT;
-		pr_debug("Unregistered %s\n", card->module_name);
-	}
-	return;
-}
-EXPORT_SYMBOL_GPL(unregister_sst_card);
diff --git a/drivers/staging/intel_sst/intel_sst_dsp.c b/drivers/staging/intel_sst/intel_sst_dsp.c
deleted file mode 100644
index 426d2b9..0000000
--- a/drivers/staging/intel_sst/intel_sst_dsp.c
+++ /dev/null
@@ -1,496 +0,0 @@
-/*
- *  intel_sst_dsp.c - Intel SST Driver for audio engine
- *
- *  Copyright (C) 2008-10	Intel Corp
- *  Authors:	Vinod Koul <vinod.koul@intel.com>
- *		Harsha Priya <priya.harsha@intel.com>
- *		Dharageswari R <dharageswari.r@intel.com>
- *		KP Jeeja <jeeja.kp@intel.com>
- *  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; version 2 of the License.
- *
- *  This program is distributed in the hope that it will be useful, but
- *  WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *  General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License along
- *  with this program; if not, write to the Free Software Foundation, Inc.,
- *  59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
- *
- * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- *
- *  This driver exposes the audio engine functionalities to the ALSA
- *	and middleware.
- *
- *  This file contains all dsp controlling functions like firmware download,
- * setting/resetting dsp cores, etc
- */
-
-#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
-
-#include <linux/pci.h>
-#include <linux/fs.h>
-#include <linux/firmware.h>
-#include "intel_sst.h"
-#include "intel_sst_ioctl.h"
-#include "intel_sst_fw_ipc.h"
-#include "intel_sst_common.h"
-
-
-/**
- * intel_sst_reset_dsp_mrst - Resetting SST DSP
- *
- * This resets DSP in case of MRST platfroms
- */
-static int intel_sst_reset_dsp_mrst(void)
-{
-	union config_status_reg csr;
-
-	pr_debug("Resetting the DSP in mrst\n");
-	csr.full = sst_shim_read(sst_drv_ctx->shim, SST_CSR);
-	csr.full |= 0x382;
-	sst_shim_write(sst_drv_ctx->shim, SST_CSR, csr.full);
-	csr.full = sst_shim_read(sst_drv_ctx->shim, SST_CSR);
-	csr.part.strb_cntr_rst = 0;
-	csr.part.run_stall = 0x1;
-	csr.part.bypass = 0x7;
-	csr.part.sst_reset = 0x1;
-	sst_shim_write(sst_drv_ctx->shim, SST_CSR, csr.full);
-	return 0;
-}
-
-/**
- * intel_sst_reset_dsp_medfield - Resetting SST DSP
- *
- * This resets DSP in case of Medfield platfroms
- */
-static int intel_sst_reset_dsp_medfield(void)
-{
-	union config_status_reg csr;
-
-	pr_debug("Resetting the DSP in medfield\n");
-	csr.full = sst_shim_read(sst_drv_ctx->shim, SST_CSR);
-	csr.full |= 0x382;
-	sst_shim_write(sst_drv_ctx->shim, SST_CSR, csr.full);
-
-	return 0;
-}
-
-/**
- * sst_start_mrst - Start the SST DSP processor
- *
- * This starts the DSP in MRST platfroms
- */
-static int sst_start_mrst(void)
-{
-	union config_status_reg csr;
-
-	csr.full = sst_shim_read(sst_drv_ctx->shim, SST_CSR);
-	csr.part.bypass = 0;
-	sst_shim_write(sst_drv_ctx->shim, SST_CSR, csr.full);
-	csr.part.run_stall = 0;
-	csr.part.sst_reset = 0;
-	csr.part.strb_cntr_rst = 1;
-	pr_debug("Setting SST to execute_mrst 0x%x\n", csr.full);
-	sst_shim_write(sst_drv_ctx->shim, SST_CSR, csr.full);
-
-	return 0;
-}
-
-/**
- * sst_start_medfield - Start the SST DSP processor
- *
- * This starts the DSP in Medfield platfroms
- */
-static int sst_start_medfield(void)
-{
-	union config_status_reg csr;
-
-	csr.full = sst_shim_read(sst_drv_ctx->shim, SST_CSR);
-	csr.part.bypass = 0;
-	sst_shim_write(sst_drv_ctx->shim, SST_CSR, csr.full);
-	csr.full = sst_shim_read(sst_drv_ctx->shim, SST_CSR);
-	csr.part.mfld_strb = 1;
-	sst_shim_write(sst_drv_ctx->shim, SST_CSR, csr.full);
-	csr.full = sst_shim_read(sst_drv_ctx->shim, SST_CSR);
-	csr.part.run_stall = 0;
-	csr.part.sst_reset = 0;
-	pr_debug("Starting the DSP_medfld %x\n", csr.full);
-	sst_shim_write(sst_drv_ctx->shim, SST_CSR, csr.full);
-	pr_debug("Starting the DSP_medfld\n");
-
-	return 0;
-}
-
-/**
- * sst_parse_module - Parse audio FW modules
- *
- * @module: FW module header
- *
- * Parses modules that need to be placed in SST IRAM and DRAM
- * returns error or 0 if module sizes are proper
- */
-static int sst_parse_module(struct fw_module_header *module)
-{
-	struct dma_block_info *block;
-	u32 count;
-	void __iomem *ram;
-
-	pr_debug("module sign %s size %x blocks %x type %x\n",
-			module->signature, module->mod_size,
-			module->blocks, module->type);
-	pr_debug("module entrypoint 0x%x\n", module->entry_point);
-
-	block = (void *)module + sizeof(*module);
-
-	for (count = 0; count < module->blocks; count++) {
-		if (block->size <= 0) {
-			pr_err("block size invalid\n");
-			return -EINVAL;
-		}
-		switch (block->type) {
-		case SST_IRAM:
-			ram = sst_drv_ctx->iram;
-			break;
-		case SST_DRAM:
-			ram = sst_drv_ctx->dram;
-			break;
-		default:
-			pr_err("wrong ram type0x%x in block0x%x\n",
-					block->type, count);
-			return -EINVAL;
-		}
-		memcpy_toio(ram + block->ram_offset,
-				(void *)block + sizeof(*block), block->size);
-		block = (void *)block + sizeof(*block) + block->size;
-	}
-	return 0;
-}
-
-/**
- * sst_parse_fw_image - parse and load FW
- *
- * @sst_fw: pointer to audio fw
- *
- * This function is called to parse and download the FW image
- */
-static int sst_parse_fw_image(const struct firmware *sst_fw)
-{
-	struct fw_header *header;
-	u32 count;
-	int ret_val;
-	struct fw_module_header *module;
-
-	BUG_ON(!sst_fw);
-
-	/* Read the header information from the data pointer */
-	header = (struct fw_header *)sst_fw->data;
-
-	/* verify FW */
-	if ((strncmp(header->signature, SST_FW_SIGN, 4) != 0) ||
-			(sst_fw->size != header->file_size + sizeof(*header))) {
-		/* Invalid FW signature */
-		pr_err("Invalid FW sign/filesize mismatch\n");
-		return -EINVAL;
-	}
-	pr_debug("header sign=%s size=%x modules=%x fmt=%x size=%x\n",
-			header->signature, header->file_size, header->modules,
-			header->file_format, sizeof(*header));
-	module = (void *)sst_fw->data + sizeof(*header);
-	for (count = 0; count < header->modules; count++) {
-		/* module */
-		ret_val = sst_parse_module(module);
-		if (ret_val)
-			return ret_val;
-		module = (void *)module + sizeof(*module) + module->mod_size ;
-	}
-
-	return 0;
-}
-
-/**
- * sst_load_fw - function to load FW into DSP
- *
- * @fw: Pointer to driver loaded FW
- * @context: driver context
- *
- * This function is called by OS when the FW is loaded into kernel
- */
-int sst_load_fw(const struct firmware *fw, void *context)
-{
-	int ret_val;
-
-	pr_debug("load_fw called\n");
-	BUG_ON(!fw);
-
-	if (sst_drv_ctx->pci_id == SST_MRST_PCI_ID)
-		ret_val = intel_sst_reset_dsp_mrst();
-	else if (sst_drv_ctx->pci_id == SST_MFLD_PCI_ID)
-		ret_val = intel_sst_reset_dsp_medfield();
-	if (ret_val)
-		return ret_val;
-
-	ret_val = sst_parse_fw_image(fw);
-	if (ret_val)
-		return ret_val;
-	mutex_lock(&sst_drv_ctx->sst_lock);
-	sst_drv_ctx->sst_state = SST_FW_LOADED;
-	mutex_unlock(&sst_drv_ctx->sst_lock);
-	/*  7. ask scu to reset the bypass bits */
-	/*  8.bring sst out of reset  */
-	if (sst_drv_ctx->pci_id == SST_MRST_PCI_ID)
-		ret_val = sst_start_mrst();
-	else if (sst_drv_ctx->pci_id == SST_MFLD_PCI_ID)
-		ret_val = sst_start_medfield();
-	if (ret_val)
-		return ret_val;
-
-	pr_debug("fw loaded successful!!!\n");
-	return ret_val;
-}
-
-/*This function is called when any codec/post processing library
- needs to be downloaded*/
-static int sst_download_library(const struct firmware *fw_lib,
-				struct snd_sst_lib_download_info *lib)
-{
-	/* send IPC message and wait */
-	int i;
-	u8 pvt_id;
-	struct ipc_post *msg = NULL;
-	union config_status_reg csr;
-	struct snd_sst_str_type str_type = {0};
-	int retval = 0;
-
-	if (sst_create_large_msg(&msg))
-		return -ENOMEM;
-
-	pvt_id = sst_assign_pvt_id(sst_drv_ctx);
-	i = sst_get_block_stream(sst_drv_ctx);
-	pr_debug("alloc block allocated = %d, pvt_id %d\n", i, pvt_id);
-	if (i < 0) {
-		kfree(msg);
-		return -ENOMEM;
-	}
-	sst_drv_ctx->alloc_block[i].sst_id = pvt_id;
-	sst_fill_header(&msg->header, IPC_IA_PREP_LIB_DNLD, 1, pvt_id);
-	msg->header.part.data = sizeof(u32) + sizeof(str_type);
-	str_type.codec_type = lib->dload_lib.lib_info.lib_type;
-	/*str_type.pvt_id = pvt_id;*/
-	memcpy(msg->mailbox_data, &msg->header, sizeof(u32));
-	memcpy(msg->mailbox_data + sizeof(u32), &str_type, sizeof(str_type));
-	spin_lock(&sst_drv_ctx->list_spin_lock);
-	list_add_tail(&msg->node, &sst_drv_ctx->ipc_dispatch_list);
-	spin_unlock(&sst_drv_ctx->list_spin_lock);
-	sst_post_message(&sst_drv_ctx->ipc_post_msg_wq);
-	retval = sst_wait_timeout(sst_drv_ctx, &sst_drv_ctx->alloc_block[i]);
-	if (retval) {
-		/* error */
-		sst_drv_ctx->alloc_block[i].sst_id = BLOCK_UNINIT;
-		pr_err("Prep codec downloaded failed %d\n",
-				retval);
-		return -EIO;
-	}
-	pr_debug("FW responded, ready for download now...\n");
-	/* downloading on success */
-	mutex_lock(&sst_drv_ctx->sst_lock);
-	sst_drv_ctx->sst_state = SST_FW_LOADED;
-	mutex_unlock(&sst_drv_ctx->sst_lock);
-	csr.full = readl(sst_drv_ctx->shim + SST_CSR);
-	csr.part.run_stall = 1;
-	sst_shim_write(sst_drv_ctx->shim, SST_CSR, csr.full);
-
-	csr.full = sst_shim_read(sst_drv_ctx->shim, SST_CSR);
-	csr.part.bypass = 0x7;
-	sst_shim_write(sst_drv_ctx->shim, SST_CSR, csr.full);
-
-	sst_parse_fw_image(fw_lib);
-
-	/* set the FW to running again */
-	csr.full = sst_shim_read(sst_drv_ctx->shim, SST_CSR);
-	csr.part.bypass = 0x0;
-	sst_shim_write(sst_drv_ctx->shim, SST_CSR, csr.full);
-
-	csr.full = sst_shim_read(sst_drv_ctx->shim, SST_CSR);
-	csr.part.run_stall = 0;
-	sst_shim_write(sst_drv_ctx->shim, SST_CSR, csr.full);
-
-	/* send download complete and wait */
-	if (sst_create_large_msg(&msg)) {
-		sst_drv_ctx->alloc_block[i].sst_id = BLOCK_UNINIT;
-		return -ENOMEM;
-	}
-
-	sst_fill_header(&msg->header, IPC_IA_LIB_DNLD_CMPLT, 1, pvt_id);
-	sst_drv_ctx->alloc_block[i].sst_id = pvt_id;
-	msg->header.part.data = sizeof(u32) + sizeof(*lib);
-	lib->pvt_id = pvt_id;
-	memcpy(msg->mailbox_data, &msg->header, sizeof(u32));
-	memcpy(msg->mailbox_data + sizeof(u32), lib, sizeof(*lib));
-	spin_lock(&sst_drv_ctx->list_spin_lock);
-	list_add_tail(&msg->node, &sst_drv_ctx->ipc_dispatch_list);
-	spin_unlock(&sst_drv_ctx->list_spin_lock);
-	sst_post_message(&sst_drv_ctx->ipc_post_msg_wq);
-	pr_debug("Waiting for FW response Download complete\n");
-	sst_drv_ctx->alloc_block[i].ops_block.condition = false;
-	retval = sst_wait_timeout(sst_drv_ctx, &sst_drv_ctx->alloc_block[i]);
-	if (retval) {
-		/* error */
-		mutex_lock(&sst_drv_ctx->sst_lock);
-		sst_drv_ctx->sst_state = SST_UN_INIT;
-		mutex_unlock(&sst_drv_ctx->sst_lock);
-		sst_drv_ctx->alloc_block[i].sst_id = BLOCK_UNINIT;
-		return -EIO;
-	}
-
-	pr_debug("FW success on Download complete\n");
-	sst_drv_ctx->alloc_block[i].sst_id = BLOCK_UNINIT;
-	mutex_lock(&sst_drv_ctx->sst_lock);
-	sst_drv_ctx->sst_state = SST_FW_RUNNING;
-	mutex_unlock(&sst_drv_ctx->sst_lock);
-	return 0;
-
-}
-
-/* This function is called before downloading the codec/postprocessing
-library is set for download to SST DSP*/
-static int sst_validate_library(const struct firmware *fw_lib,
-		struct lib_slot_info *slot,
-		u32 *entry_point)
-{
-	struct fw_header *header;
-	struct fw_module_header *module;
-	struct dma_block_info *block;
-	unsigned int n_blk, isize = 0, dsize = 0;
-	int err = 0;
-
-	header = (struct fw_header *)fw_lib->data;
-	if (header->modules != 1) {
-		pr_err("Module no mismatch found\n");
-		err = -EINVAL;
-		goto exit;
-	}
-	module = (void *)fw_lib->data + sizeof(*header);
-	*entry_point = module->entry_point;
-	pr_debug("Module entry point 0x%x\n", *entry_point);
-	pr_debug("Module Sign %s, Size 0x%x, Blocks 0x%x Type 0x%x\n",
-			module->signature, module->mod_size,
-			module->blocks, module->type);
-
-	block = (void *)module + sizeof(*module);
-	for (n_blk = 0; n_blk < module->blocks; n_blk++) {
-		switch (block->type) {
-		case SST_IRAM:
-			isize += block->size;
-			break;
-		case SST_DRAM:
-			dsize += block->size;
-			break;
-		default:
-			pr_err("Invalid block type for 0x%x\n", n_blk);
-			err = -EINVAL;
-			goto exit;
-		}
-		block = (void *)block + sizeof(*block) + block->size;
-	}
-	if (isize > slot->iram_size || dsize > slot->dram_size) {
-		pr_err("library exceeds size allocated\n");
-		err = -EINVAL;
-		goto exit;
-	} else
-		pr_debug("Library is safe for download...\n");
-
-	pr_debug("iram 0x%x, dram 0x%x, iram 0x%x, dram 0x%x\n",
-			isize, dsize, slot->iram_size, slot->dram_size);
-exit:
-	return err;
-
-}
-
-/* This function is called when FW requests for a particular library download
-This function prepares the library to download*/
-int sst_load_library(struct snd_sst_lib_download *lib, u8 ops)
-{
-	char buf[20];
-	const char *type, *dir;
-	int len = 0, error = 0;
-	u32 entry_point;
-	const struct firmware *fw_lib;
-	struct snd_sst_lib_download_info dload_info = {{{0},},};
-
-	memset(buf, 0, sizeof(buf));
-
-	pr_debug("Lib Type 0x%x, Slot 0x%x, ops 0x%x\n",
-			lib->lib_info.lib_type, lib->slot_info.slot_num, ops);
-	pr_debug("Version 0x%x, name %s, caps 0x%x media type 0x%x\n",
-		lib->lib_info.lib_version, lib->lib_info.lib_name,
-		lib->lib_info.lib_caps, lib->lib_info.media_type);
-
-	pr_debug("IRAM Size 0x%x, offset 0x%x\n",
-		lib->slot_info.iram_size, lib->slot_info.iram_offset);
-	pr_debug("DRAM Size 0x%x, offset 0x%x\n",
-		lib->slot_info.dram_size, lib->slot_info.dram_offset);
-
-	switch (lib->lib_info.lib_type) {
-	case SST_CODEC_TYPE_MP3:
-		type = "mp3_";
-		break;
-	case SST_CODEC_TYPE_AAC:
-		type = "aac_";
-		break;
-	case SST_CODEC_TYPE_AACP:
-		type = "aac_v1_";
-		break;
-	case SST_CODEC_TYPE_eAACP:
-		type = "aac_v2_";
-		break;
-	case SST_CODEC_TYPE_WMA9:
-		type = "wma9_";
-		break;
-	default:
-		pr_err("Invalid codec type\n");
-		error = -EINVAL;
-		goto wake;
-	}
-
-	if (ops == STREAM_OPS_CAPTURE)
-		dir = "enc_";
-	else
-		dir = "dec_";
-	len = strlen(type) + strlen(dir);
-	strncpy(buf, type, sizeof(buf)-1);
-	strncpy(buf + strlen(type), dir, sizeof(buf)-strlen(type)-1);
-	len += snprintf(buf + len, sizeof(buf) - len, "%d",
-			lib->slot_info.slot_num);
-	len += snprintf(buf + len, sizeof(buf) - len, ".bin");
-
-	pr_debug("Requesting %s\n", buf);
-
-	error = request_firmware(&fw_lib, buf, &sst_drv_ctx->pci->dev);
-	if (error) {
-		pr_err("library load failed %d\n", error);
-		goto wake;
-	}
-	error = sst_validate_library(fw_lib, &lib->slot_info, &entry_point);
-	if (error)
-		goto wake_free;
-
-	lib->mod_entry_pt = entry_point;
-	memcpy(&dload_info.dload_lib, lib, sizeof(*lib));
-	error = sst_download_library(fw_lib, &dload_info);
-	if (error)
-		goto wake_free;
-
-	/* lib is downloaded and init send alloc again */
-	pr_debug("Library is downloaded now...\n");
-wake_free:
-	/* sst_wake_up_alloc_block(sst_drv_ctx, pvt_id, error, NULL); */
-	release_firmware(fw_lib);
-wake:
-	return error;
-}
-
diff --git a/drivers/staging/intel_sst/intel_sst_fw_ipc.h b/drivers/staging/intel_sst/intel_sst_fw_ipc.h
deleted file mode 100644
index 5d0cc56..0000000
--- a/drivers/staging/intel_sst/intel_sst_fw_ipc.h
+++ /dev/null
@@ -1,416 +0,0 @@
-#ifndef __INTEL_SST_FW_IPC_H__
-#define __INTEL_SST_FW_IPC_H__
-/*
-*  intel_sst_fw_ipc.h - Intel SST Driver for audio engine
-*
-*  Copyright (C) 2008-10 Intel Corporation
-*  Author:	Vinod Koul <vinod.koul@intel.com>
-*		Harsha Priya <priya.harsha@intel.com>
-*		Dharageswari R <dharageswari.r@intel.com>
-*		KP Jeeja <jeeja.kp@intel.com>
-*  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-*
-*  This program is free software; you can redistribute it and/or modify
-*  it under the terms of the GNU General Public License as published by
-*  the Free Software Foundation; version 2 of the License.
-*
-*  This program is distributed in the hope that it will be useful, but
-*  WITHOUT ANY WARRANTY; without even the implied warranty of
-*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-*  General Public License for more details.
-*
-*  You should have received a copy of the GNU General Public License along
-*  with this program; if not, write to the Free Software Foundation, Inc.,
-*  59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
-*
-* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-*
-*  This driver exposes the audio engine functionalities to the ALSA
-*	and middleware.
-*  This file has definitions shared between the firmware and driver
-*/
-
-#define MAX_NUM_STREAMS_MRST 3
-#define MAX_NUM_STREAMS_MFLD 6
-#define MAX_NUM_STREAMS 6
-#define MAX_DBG_RW_BYTES 80
-#define MAX_NUM_SCATTER_BUFFERS 8
-#define MAX_LOOP_BACK_DWORDS 8
-/* IPC base address and mailbox, timestamp offsets */
-#define SST_MAILBOX_SIZE 0x0400
-#define SST_MAILBOX_SEND 0x0000
-#define SST_MAILBOX_RCV 0x0804
-#define SST_TIME_STAMP 0x1800
-#define SST_RESERVED_OFFSET 0x1A00
-#define SST_CHEKPOINT_OFFSET 0x1C00
-#define REPLY_MSG 0x80
-
-/* Message ID's for IPC messages */
-/* Bits B7: SST or IA/SC ; B6-B4: Msg Category; B3-B0: Msg Type */
-
-/* I2L Firmware/Codec Download msgs */
-#define IPC_IA_PREP_LIB_DNLD 0x01
-#define IPC_IA_LIB_DNLD_CMPLT 0x02
-
-#define IPC_IA_SET_PMIC_TYPE 0x03
-#define IPC_IA_GET_FW_VERSION 0x04
-#define IPC_IA_GET_FW_BUILD_INF 0x05
-#define IPC_IA_GET_FW_INFO 0x06
-#define IPC_IA_GET_FW_CTXT 0x07
-#define IPC_IA_SET_FW_CTXT 0x08
-
-/* I2L Codec Config/control msgs */
-#define IPC_IA_SET_CODEC_PARAMS 0x10
-#define IPC_IA_GET_CODEC_PARAMS 0x11
-#define IPC_IA_SET_PPP_PARAMS 0x12
-#define IPC_IA_GET_PPP_PARAMS 0x13
-#define IPC_IA_PLAY_FRAMES 0x14
-#define IPC_IA_CAPT_FRAMES 0x15
-#define IPC_IA_PLAY_VOICE 0x16
-#define IPC_IA_CAPT_VOICE 0x17
-#define IPC_IA_DECODE_FRAMES 0x18
-
-#define IPC_IA_ALG_PARAMS 0x1A
-#define IPC_IA_TUNING_PARAMS 0x1B
-
-/* I2L Stream config/control msgs */
-#define IPC_IA_ALLOC_STREAM 0x20 /* Allocate a stream ID */
-#define IPC_IA_FREE_STREAM 0x21 /* Free the stream ID */
-#define IPC_IA_SET_STREAM_PARAMS 0x22
-#define IPC_IA_GET_STREAM_PARAMS 0x23
-#define IPC_IA_PAUSE_STREAM 0x24
-#define IPC_IA_RESUME_STREAM 0x25
-#define IPC_IA_DROP_STREAM 0x26
-#define IPC_IA_DRAIN_STREAM 0x27 /* Short msg with str_id */
-#define IPC_IA_TARGET_DEV_SELECT 0x28
-#define IPC_IA_CONTROL_ROUTING 0x29
-
-#define IPC_IA_SET_STREAM_VOL 0x2A /*Vol for stream, pre mixer */
-#define IPC_IA_GET_STREAM_VOL 0x2B
-#define IPC_IA_SET_STREAM_MUTE 0x2C
-#define IPC_IA_GET_STREAM_MUTE 0x2D
-#define IPC_IA_ENABLE_RX_TIME_SLOT 0x2E /* Enable Rx time slot 0 or 1 */
-
-#define IPC_IA_START_STREAM 0x30 /* Short msg with str_id */
-
-/* Debug msgs */
-#define IPC_IA_DBG_MEM_READ 0x40
-#define IPC_IA_DBG_MEM_WRITE 0x41
-#define IPC_IA_DBG_LOOP_BACK 0x42
-
-/* L2I Firmware/Codec Download msgs */
-#define IPC_IA_FW_INIT_CMPLT 0x81
-#define IPC_IA_LPE_GETTING_STALLED 0x82
-#define IPC_IA_LPE_UNSTALLED 0x83
-
-/* L2I Codec Config/control msgs */
-#define IPC_SST_GET_PLAY_FRAMES 0x90 /* Request IA more data */
-#define IPC_SST_GET_CAPT_FRAMES 0x91 /* Request IA more data */
-#define IPC_SST_BUF_UNDER_RUN 0x92 /* PB Under run and stopped */
-#define IPC_SST_BUF_OVER_RUN 0x93 /* CAP Under run and stopped */
-#define IPC_SST_DRAIN_END 0x94 /* PB Drain complete and stopped */
-#define IPC_SST_CHNGE_SSP_PARAMS 0x95 /* PB SSP parameters changed */
-#define IPC_SST_STREAM_PROCESS_FATAL_ERR 0x96/* error in processing a stream */
-#define IPC_SST_PERIOD_ELAPSED 0x97 /* period elapsed */
-#define IPC_IA_TARGET_DEV_CHNGD 0x98 /* error in processing a stream */
-
-#define IPC_SST_ERROR_EVENT 0x99 /* Buffer over run occurred */
-/* L2S messages */
-#define IPC_SC_DDR_LINK_UP 0xC0
-#define IPC_SC_DDR_LINK_DOWN 0xC1
-#define IPC_SC_SET_LPECLK_REQ 0xC2
-#define IPC_SC_SSP_BIT_BANG 0xC3
-
-/* L2I Error reporting msgs */
-#define IPC_IA_MEM_ALLOC_FAIL 0xE0
-#define IPC_IA_PROC_ERR 0xE1 /* error in processing a
-					stream can be used by playback and
-					capture modules */
-
-/* L2I Debug msgs */
-#define IPC_IA_PRINT_STRING 0xF0
-
-
-
-/* Command Response or Acknowledge message to any IPC message will have
- * same message ID and stream ID information which is sent.
- * There is no specific Ack message ID. The data field is used as response
- * meaning.
- */
-enum ackData {
-	IPC_ACK_SUCCESS = 0,
-	IPC_ACK_FAILURE
-};
-
-
-enum sst_error_codes {
-	/* Error code,response to msgId: Description */
-	/* Common error codes */
-	SST_SUCCESS = 0,	/* Success */
-	SST_ERR_INVALID_STREAM_ID = 1,
-	SST_ERR_INVALID_MSG_ID = 2,
-	SST_ERR_INVALID_STREAM_OP = 3,
-	SST_ERR_INVALID_PARAMS = 4,
-	SST_ERR_INVALID_CODEC = 5,
-	SST_ERR_INVALID_MEDIA_TYPE = 6,
-	SST_ERR_STREAM_ERR = 7,
-
-	/* IPC specific error codes */
-	SST_IPC_ERR_CALL_BACK_NOT_REGD = 8,
-	SST_IPC_ERR_STREAM_NOT_ALLOCATED = 9,
-	SST_IPC_ERR_STREAM_ALLOC_FAILED = 10,
-	SST_IPC_ERR_GET_STREAM_FAILED = 11,
-	SST_ERR_MOD_NOT_AVAIL = 12,
-	SST_ERR_MOD_DNLD_RQD = 13,
-	SST_ERR_STREAM_STOPPED = 14,
-	SST_ERR_STREAM_IN_USE = 15,
-
-	/* Capture specific error codes */
-	SST_CAP_ERR_INCMPLTE_CAPTURE_MSG = 16,
-	SST_CAP_ERR_CAPTURE_FAIL = 17,
-	SST_CAP_ERR_GET_DDR_NEW_SGLIST = 18,
-	SST_CAP_ERR_UNDER_RUN = 19,
-	SST_CAP_ERR_OVERFLOW = 20,
-
-	/* Playback specific error codes*/
-	SST_PB_ERR_INCMPLTE_PLAY_MSG = 21,
-	SST_PB_ERR_PLAY_FAIL = 22,
-	SST_PB_ERR_GET_DDR_NEW_SGLIST = 23,
-
-	/* Codec manager specific error codes */
-	SST_LIB_ERR_LIB_DNLD_REQUIRED = 24,
-	SST_LIB_ERR_LIB_NOT_SUPPORTED = 25,
-
-	/* Library manager specific error codes */
-	SST_SCC_ERR_PREP_DNLD_FAILED = 26,
-	SST_SCC_ERR_LIB_DNLD_RES_FAILED = 27,
-	/* Scheduler specific error codes */
-	SST_SCH_ERR_FAIL = 28,
-
-	/* DMA specific error codes */
-	SST_DMA_ERR_NO_CHNL_AVAILABLE = 29,
-	SST_DMA_ERR_INVALID_INPUT_PARAMS = 30,
-	SST_DMA_ERR_CHNL_ALREADY_SUSPENDED = 31,
-	SST_DMA_ERR_CHNL_ALREADY_STARTED = 32,
-	SST_DMA_ERR_CHNL_NOT_ENABLED = 33,
-	SST_DMA_ERR_TRANSFER_FAILED = 34,
-
-	SST_SSP_ERR_ALREADY_ENABLED = 35,
-	SST_SSP_ERR_ALREADY_DISABLED = 36,
-	SST_SSP_ERR_NOT_INITIALIZED = 37,
-	SST_SSP_ERR_SRAM_NO_DMA_DATA = 38,
-
-	/* Other error codes */
-	SST_ERR_MOD_INIT_FAIL = 39,
-
-	/* FW init error codes */
-	SST_RDR_ERR_IO_DEV_SEL_NOT_ALLOWED = 40,
-	SST_RDR_ERR_ROUTE_ALREADY_STARTED = 41,
-	SST_RDR_ERR_IO_DEV_SEL_FAILED = 42,
-	SST_RDR_PREP_CODEC_DNLD_FAILED = 43,
-
-	/* Memory debug error codes */
-	SST_ERR_DBG_MEM_READ_FAIL = 44,
-	SST_ERR_DBG_MEM_WRITE_FAIL = 45,
-	SST_ERR_INSUFFICIENT_INPUT_SG_LIST = 46,
-	SST_ERR_INSUFFICIENT_OUTPUT_SG_LIST = 47,
-
-	SST_ERR_BUFFER_NOT_AVAILABLE = 48,
-	SST_ERR_BUFFER_NOT_ALLOCATED = 49,
-	SST_ERR_INVALID_REGION_TYPE = 50,
-	SST_ERR_NULL_PTR = 51,
-	SST_ERR_INVALID_BUFFER_SIZE = 52,
-	SST_ERR_INVALID_BUFFER_INDEX = 53,
-
-	/*IIPC specific error codes */
-	SST_IIPC_QUEUE_FULL = 54,
-	SST_IIPC_ERR_MSG_SND_FAILED = 55,
-	SST_PB_ERR_UNDERRUN_OCCURED = 56,
-	SST_RDR_INSUFFICIENT_MIXER_BUFFER = 57,
-	SST_INVALID_TIME_SLOTS = 58,
-};
-
-enum dbg_mem_data_type {
-	/* Data type of debug read/write */
-	DATA_TYPE_U32,
-	DATA_TYPE_U16,
-	DATA_TYPE_U8,
-};
-
-/* CAUTION NOTE: All IPC message body must be multiple of 32 bits.*/
-
-/* IPC Header */
-union ipc_header {
-	struct {
-		u32  msg_id:8; /* Message ID - Max 256 Message Types */
-		u32  str_id:5;
-		u32  large:1;	/* Large Message if large = 1 */
-		u32  reserved:2;	/* Reserved for future use */
-		u32  data:14;	/* Ack/Info for msg, size of msg in Mailbox */
-		u32  done:1; /* bit 30 */
-		u32  busy:1; /* bit 31 */
-	} part;
-	u32 full;
-} __attribute__ ((packed));
-
-/* Firmware build info */
-struct sst_fw_build_info {
-	unsigned char  date[16]; /* Firmware build date */
-	unsigned char  time[16]; /* Firmware build time */
-} __attribute__ ((packed));
-
-struct ipc_header_fw_init {
-	struct snd_sst_fw_version fw_version;/* Firmware version details */
-	struct sst_fw_build_info build_info;
-	u16 result;	/* Fw init result */
-	u8 module_id; /* Module ID in case of error */
-	u8 debug_info; /* Debug info from Module ID in case of fail */
-} __attribute__ ((packed));
-
-/* Address and size info of a frame buffer in DDR */
-struct sst_address_info {
-	u32 addr; /* Address at IA */
-	u32 size; /* Size of the buffer */
-} __attribute__ ((packed));
-
-/* Time stamp */
-struct snd_sst_tstamp {
-	u64 samples_processed;/* capture - data in DDR */
-	u64 samples_rendered;/* playback - data rendered */
-	u64 bytes_processed;/* bytes decoded or encoded */
-	u32 sampling_frequency;/* eg: 48000, 44100 */
-	u32 dma_base_address;/* DMA base address */
-	u16	dma_channel_no;/* DMA Channel used for the data transfer*/
-	u16	reserved;/* 32 bit alignment */
-};
-
-/* Frame info to play or capture */
-struct sst_frame_info {
-	u16  num_entries; /* number of entries to follow */
-	u16  rsrvd;
-	struct sst_address_info  addr[MAX_NUM_SCATTER_BUFFERS];
-} __attribute__ ((packed));
-
-/* Frames info for decode */
-struct snd_sst_decode_info {
-	unsigned long long input_bytes_consumed;
-	unsigned long long output_bytes_produced;
-	struct sst_frame_info frames_in;
-	struct sst_frame_info frames_out;
-} __attribute__ ((packed));
-
-/* SST to IA print debug message*/
-struct ipc_sst_ia_print_params {
-	u32 string_size;/* Max value is 160 */
-	u8 prt_string[160];/* Null terminated Char string */
-} __attribute__ ((packed));
-
-/* Voice data message  */
-struct snd_sst_voice_data {
-	u16 num_bytes;/* Number of valid voice data bytes */
-	u8  pcm_wd_size;/* 0=8 bit, 1=16 bit 2=32 bit */
-	u8  reserved;/* Reserved */
-	u8  voice_data_buf[0];/* Voice data buffer in bytes, little endian */
-} __attribute__ ((packed));
-
-/* SST to IA memory read debug message  */
-struct ipc_sst_ia_dbg_mem_rw  {
-	u16  num_bytes;/* Maximum of MAX_DBG_RW_BYTES */
-	u16  data_type;/* enum: dbg_mem_data_type */
-	u32  address;	/* Memory address of data memory of data_type */
-	u8	rw_bytes[MAX_DBG_RW_BYTES];/* Maximum of 64 bytes can be RW */
-} __attribute__ ((packed));
-
-struct ipc_sst_ia_dbg_loop_back {
-	u16 num_dwords; /* Maximum of MAX_DBG_RW_BYTES */
-	u16 increment_val;/* Increments dwords by this value, 0- no increment */
-	u32 lpbk_dwords[MAX_LOOP_BACK_DWORDS];/* Maximum of 8 dwords loopback */
-} __attribute__ ((packed));
-
-/* Stream type params struture for Alloc stream */
-struct snd_sst_str_type {
-	u8 codec_type;		/* Codec type */
-	u8 str_type;		/* 1 = voice 2 = music */
-	u8 operation;		/* Playback or Capture */
-	u8 protected_str;	/* 0=Non DRM, 1=DRM */
-	u8 time_slots;
-	u8 reserved;		/* Reserved */
-	u16 result;		/* Result used for acknowledgment */
-} __attribute__ ((packed));
-
-/* Library info structure */
-struct module_info {
-	u32 lib_version;
-	u32 lib_type;/*TBD- KLOCKWORK u8 lib_type;*/
-	u32 media_type;
-	u8  lib_name[12];
-	u32 lib_caps;
-	unsigned char  b_date[16]; /* Lib build date */
-	unsigned char  b_time[16]; /* Lib build time */
-} __attribute__ ((packed));
-
-/* Library slot info */
-struct lib_slot_info {
-	u8  slot_num; /* 1 or 2 */
-	u8  reserved1;
-	u16 reserved2;
-	u32 iram_size; /* slot size in IRAM */
-	u32 dram_size; /* slot size in DRAM */
-	u32 iram_offset; /* starting offset of slot in IRAM */
-	u32 dram_offset; /* starting offset of slot in DRAM */
-} __attribute__ ((packed));
-
-struct snd_sst_lib_download {
-	struct module_info lib_info; /* library info type, capabilities etc */
-	struct lib_slot_info slot_info; /* slot info to be downloaded */
-	u32 mod_entry_pt;
-};
-
-struct snd_sst_lib_download_info {
-	struct snd_sst_lib_download dload_lib;
-	u16 result;	/* Result used for acknowledgment */
-	u8 pvt_id; /* Private ID */
-	u8 reserved;  /* for alignment */
-};
-
-/* Alloc stream params structure */
-struct snd_sst_alloc_params {
-	struct snd_sst_str_type str_type;
-	struct snd_sst_stream_params stream_params;
-};
-
-struct snd_sst_fw_get_stream_params {
-	struct snd_sst_stream_params codec_params;
-	struct snd_sst_pmic_config pcm_params;
-};
-
-/* Alloc stream response message */
-struct snd_sst_alloc_response {
-	struct snd_sst_str_type str_type; /* Stream type for allocation */
-	struct snd_sst_lib_download lib_dnld; /* Valid only for codec dnld */
-};
-
-/* Drop response */
-struct snd_sst_drop_response {
-	u32 result;
-	u32 bytes;
-};
-
-/* CSV Voice call routing structure */
-struct snd_sst_control_routing {
-	u8 control; /* 0=start, 1=Stop */
-	u8 reserved[3];	/* Reserved- for 32 bit alignment */
-};
-
-
-struct ipc_post {
-	struct list_head node;
-	union ipc_header header; /* driver specific */
-	char *mailbox_data;
-};
-
-struct snd_sst_ctxt_params {
-	u32 address; /* Physical Address in DDR where the context is stored */
-	u32 size; /* size of the context */
-};
-#endif /* __INTEL_SST_FW_IPC_H__ */
diff --git a/drivers/staging/intel_sst/intel_sst_ioctl.h b/drivers/staging/intel_sst/intel_sst_ioctl.h
deleted file mode 100644
index 5da5ee0..0000000
--- a/drivers/staging/intel_sst/intel_sst_ioctl.h
+++ /dev/null
@@ -1,440 +0,0 @@
-#ifndef __INTEL_SST_IOCTL_H__
-#define __INTEL_SST_IOCTL_H__
-/*
- *  intel_sst_ioctl.h - Intel SST Driver for audio engine
- *
- *  Copyright (C) 2008-10 Intel Corporation
- *  Authors:	Vinod Koul <vinod.koul@intel.com>
- *		Harsha Priya <priya.harsha@intel.com>
- *		Dharageswari R <dharageswari.r@intel.com>
- *		KP Jeeja <jeeja.kp@intel.com>
- *  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; version 2 of the License.
- *
- *  This program is distributed in the hope that it will be useful, but
- *  WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *  General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License along
- *  with this program; if not, write to the Free Software Foundation, Inc.,
- *  59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
- *
- * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- *
- *  This file defines all sst ioctls
- */
-
-/* codec and post/pre processing related info */
-
-#include <linux/types.h>
-
-enum sst_codec_types {
-/*  AUDIO/MUSIC	CODEC Type Definitions */
-	SST_CODEC_TYPE_UNKNOWN = 0,
-	SST_CODEC_TYPE_PCM,	/* Pass through Audio codec */
-	SST_CODEC_TYPE_MP3,
-	SST_CODEC_TYPE_MP24,
-	SST_CODEC_TYPE_AAC,
-	SST_CODEC_TYPE_AACP,
-	SST_CODEC_TYPE_eAACP,
-	SST_CODEC_TYPE_WMA9,
-	SST_CODEC_TYPE_WMA10,
-	SST_CODEC_TYPE_WMA10P,
-	SST_CODEC_TYPE_RA,
-	SST_CODEC_TYPE_DDAC3,
-	SST_CODEC_TYPE_STEREO_TRUE_HD,
-	SST_CODEC_TYPE_STEREO_HD_PLUS,
-
-	/*  VOICE CODEC Type Definitions */
-	SST_CODEC_TYPE_VOICE_PCM = 0x21, /* Pass through voice codec */
-};
-
-enum sst_algo_types {
-	SST_CODEC_SRC = 0x64,
-	SST_CODEC_MIXER = 0x65,
-	SST_CODEC_DOWN_MIXER = 0x66,
-	SST_CODEC_VOLUME_CONTROL = 0x67,
-	SST_CODEC_OEM1 = 0xC8,
-	SST_CODEC_OEM2 = 0xC9,
-};
-
-enum snd_sst_stream_ops {
-	STREAM_OPS_PLAYBACK = 0,	/* Decode */
-	STREAM_OPS_CAPTURE,		/* Encode */
-	STREAM_OPS_PLAYBACK_DRM,	/* Play Audio/Voice */
-	STREAM_OPS_PLAYBACK_ALERT,	/* Play Audio/Voice */
-	STREAM_OPS_CAPTURE_VOICE_CALL,	/* CSV Voice recording */
-};
-
-enum stream_mode {
-	SST_STREAM_MODE_NONE = 0,
-	SST_STREAM_MODE_DNR = 1,
-	SST_STREAM_MODE_FNF = 2,
-	SST_STREAM_MODE_CAPTURE = 3
-};
-
-enum stream_type {
-	SST_STREAM_TYPE_NONE = 0,
-	SST_STREAM_TYPE_MUSIC = 1,
-	SST_STREAM_TYPE_NORMAL = 2,
-	SST_STREAM_TYPE_LONG_PB = 3,
-	SST_STREAM_TYPE_LOW_LATENCY = 4,
-};
-
-enum snd_sst_audio_device_type {
-	SND_SST_DEVICE_HEADSET = 1,
-	SND_SST_DEVICE_IHF,
-	SND_SST_DEVICE_VIBRA,
-	SND_SST_DEVICE_HAPTIC,
-	SND_SST_DEVICE_CAPTURE,
-};
-
-/* Firmware Version info */
-struct snd_sst_fw_version {
-	__u8 build;	/* build number*/
-	__u8 minor;	/* minor number*/
-	__u8 major;	/* major number*/
-	__u8 type; /* build type */
-};
-
-/* Port info structure */
-struct snd_sst_port_info {
-	__u16 port_type;
-	__u16 reserved;
-};
-
-/* Mixer info structure */
-struct snd_sst_mix_info {
-	__u16 max_streams;
-	__u16 reserved;
-};
-
-/* PCM Parameters */
-struct snd_pcm_params {
-	__u16 codec;	/* codec type */
-	__u8 num_chan;	/* 1=Mono, 2=Stereo */
-	__u8 pcm_wd_sz;	/* 16/24 - bit*/
-	__u32 reserved;	/* Bitrate in bits per second */
-	__u32 sfreq;	/* Sampling rate in Hz */
-	__u32 ring_buffer_size;
-	__u32 period_count;	/* period elapsed in samples*/
-	__u32 ring_buffer_addr;
-};
-
-/* MP3 Music Parameters Message */
-struct snd_mp3_params {
-	__u16 codec;
-	__u8  num_chan;	/* 1=Mono, 2=Stereo	*/
-	__u8  pcm_wd_sz; /* 16/24 - bit*/
-	__u32 brate; /* Use the hard coded value. */
-	__u32 sfreq; /* Sampling freq eg. 8000, 441000, 48000 */
-	__u8  crc_check; /* crc_check - disable (0) or enable (1) */
-	__u8  op_align; /* op align 0- 16 bit, 1- MSB, 2 LSB*/
-	__u16 reserved;	/* Unused */
-};
-
-#define AAC_BIT_STREAM_ADTS		0
-#define AAC_BIT_STREAM_ADIF		1
-#define AAC_BIT_STREAM_RAW		2
-
-/* AAC Music Parameters Message */
-struct snd_aac_params {
-	__u16 codec;
-	__u8 num_chan; /* 1=Mono, 2=Stereo*/
-	__u8 pcm_wd_sz; /* 16/24 - bit*/
-	__u32 brate;
-	__u32 sfreq; /* Sampling freq eg. 8000, 441000, 48000 */
-	__u32 aac_srate;	/* Plain AAC decoder operating sample rate */
-	__u8 mpg_id; /* 0=MPEG-2, 1=MPEG-4 */
-	__u8 bs_format; /* input bit stream format adts=0, adif=1, raw=2 */
-	__u8 aac_profile; /* 0=Main Profile, 1=LC profile, 3=SSR profile */
-	__u8 ext_chl; /* No.of external channels */
-	__u8 aot; /* Audio object type. 1=Main , 2=LC , 3=SSR, 4=SBR*/
-	__u8 op_align; /* output alignment 0=16 bit , 1=MSB, 2= LSB align */
-	__u8 brate_type; /* 0=CBR, 1=VBR */
-	__u8 crc_check; /* crc check 0= disable, 1=enable */
-	__s8 bit_stream_format[8]; /* input bit stream format adts/adif/raw */
-	__u8 jstereo; /* Joint stereo Flag */
-	__u8 sbr_present; /* 1 = SBR Present, 0 = SBR absent, for RAW */
-	__u8 downsample;       /* 1 = Downsampling ON, 0 = Downsampling OFF */
-	__u8 num_syntc_elems; /* 1- Mono/stereo, 0 - Dual Mono, 0 - for raw */
-	__s8 syntc_id[2]; /* 0 for ID_SCE(Dula Mono), -1 for raw */
-	__s8 syntc_tag[2]; /* raw - -1 and 0 -16 for rest of the streams */
-	__u8 pce_present; /* Flag. 1- present 0 - not present, for RAW */
-	__u8 sbr_type;		/* sbr_type: 0-plain aac, 1-aac-v1, 2-aac-v2 */
-	__u8 outchmode;  /*0- mono, 1-stereo, 2-dual mono 3-Parametric stereo */
-	__u8 ps_present;
-};
-
-/* WMA Music Parameters Message */
-struct snd_wma_params {
-	__u16 codec;
-	__u8  num_chan;	/* 1=Mono, 2=Stereo */
-	__u8  pcm_wd_sz;	/* 16/24 - bit*/
-	__u32 brate;	/* Use the hard coded value. */
-	__u32 sfreq;	/* Sampling freq eg. 8000, 441000, 48000 */
-	__u32 channel_mask;  /* Channel Mask */
-	__u16 format_tag;	/* Format Tag */
-	__u16 block_align;	/* packet size */
-	__u16 wma_encode_opt;/* Encoder option */
-	__u8 op_align;	/* op align 0- 16 bit, 1- MSB, 2 LSB */
-	__u8 pcm_src;	/* input pcm bit width */
-};
-
-/* Pre processing param structure */
-struct snd_prp_params {
-	__u32 reserved;	/* No pre-processing defined yet */
-};
-
-/* Pre and post processing params structure */
-struct snd_ppp_params {
-	__u8			algo_id;/* Post/Pre processing algorithm ID  */
-	__u8			str_id;	/*Only 5 bits used 0 - 31 are valid*/
-	__u8			enable;	/* 0= disable, 1= enable*/
-	__u8			reserved;
-	__u32			size;	/*Size of parameters for all blocks*/
-	void			*params;
-} __attribute__ ((packed));
-
-struct snd_sst_postproc_info {
-	__u32 src_min;		/* Supported SRC Min sampling freq */
-	__u32 src_max;		/* Supported SRC Max sampling freq */
-	__u8  src;		/* 0=Not supported, 1=Supported */
-	__u8  bass_boost;		/* 0=Not Supported, 1=Supported */
-	__u8  stereo_widening;	/* 0=Not Supported, 1=Supported */
-	__u8  volume_control;	/* 0=Not Supported, 1=Supported */
-	__s16 min_vol;		/* Minimum value of Volume in dB */
-	__s16 max_vol;		/* Maximum value of Volume in dB */
-	__u8 mute_control;	/* 0=No Mute, 1=Mute */
-	__u8 reserved1;
-	__u16 reserved2;
-};
-
-/* pre processing Capability info structure */
-struct snd_sst_prp_info {
-	__s16 min_vol;			/* Minimum value of Volume in dB */
-	__s16 max_vol;			/* Maximum value of Volume in dB */
-	__u8 volume_control;		/* 0=Not Supported, 1=Supported */
-	__u8 reserved1;			/* for 32 bit alignment */
-	__u16 reserved2;		/* for 32 bit alignment */
-} __attribute__ ((packed));
-
-/*Pre / Post processing algorithms support*/
-struct snd_sst_ppp_info {
-	__u32 src:1;		/* 0=Not supported, 1=Supported */
-	__u32 mixer:1;		/* 0=Not supported, 1=Supported */
-	__u32 volume_control:1;	/* 0=Not Supported, 1=Supported */
-	__u32 mute_control:1;	/* 0=Not Supported, 1=Supported */
-	__u32 anc:1;		/* 0=Not Supported, 1=Supported */
-	__u32 side_tone:1;	/* 0=Not Supported, 1=Supported */
-	__u32 dc_removal:1;	/* 0=Not Supported, 1=Supported */
-	__u32 equalizer:1;	/* 0=Not Supported, 1=Supported */
-	__u32 spkr_prot:1;	/* 0=Not Supported, 1=Supported */
-	__u32 bass_boost:1;	/* 0=Not Supported, 1=Supported */
-	__u32 stereo_widening:1;/* 0=Not Supported, 1=Supported */
-	__u32 rsvd1:21;
-	__u32 rsvd2;
-};
-
-/* Firmware capabilities info */
-struct snd_sst_fw_info {
-	struct snd_sst_fw_version fw_version; /* Firmware version */
-	__u8 audio_codecs_supported[8];	/* Codecs supported by FW */
-	__u32 recommend_min_duration; /* Min duration for Lowpower Playback */
-	__u8 max_pcm_streams_supported; /* Max num of PCM streams supported */
-	__u8 max_enc_streams_supported;	/* Max number of Encoded streams  */
-	__u16 reserved;		/* 32 bit alignment*/
-	struct snd_sst_ppp_info ppp_info; /* pre_processing mod cap info */
-	struct snd_sst_postproc_info pop_info; /* Post processing cap info*/
-	struct snd_sst_port_info port_info[3]; /* Port info */
-	struct snd_sst_mix_info mix_info;/* Mixer info */
-	__u32 min_input_buf; /* minmum i/p buffer for decode */
-};
-
-/* Codec params struture */
-union  snd_sst_codec_params {
-	struct snd_pcm_params pcm_params;
-	struct snd_mp3_params mp3_params;
-	struct snd_aac_params aac_params;
-	struct snd_wma_params wma_params;
-};
-
-
-struct snd_sst_stream_params {
-	union snd_sst_codec_params uc;
-} __attribute__ ((packed));
-
-struct snd_sst_params {
-	__u32 result;
-	__u32 stream_id;
-	__u8 codec;
-	__u8 ops;
-	__u8 stream_type;
-	__u8 device_type;
-	struct snd_sst_stream_params sparams;
-};
-
-struct snd_sst_vol {
-	__u32	stream_id;
-	__s32	volume;
-	__u32	ramp_duration;
-	__u32	ramp_type;		/* Ramp type, default=0 */
-};
-
-struct snd_sst_mute {
-	__u32	stream_id;
-	__u32	mute;
-};
-
-/* ioctl related stuff here */
-struct snd_sst_pmic_config {
-	__u32  sfreq;                /* Sampling rate in Hz */
-	__u16  num_chan;             /* Mono =1 or Stereo =2 */
-	__u16  pcm_wd_sz;            /* Number of bits per sample */
-} __attribute__ ((packed));
-
-struct snd_sst_get_stream_params {
-	struct snd_sst_params codec_params;
-	struct snd_sst_pmic_config pcm_params;
-};
-
-enum snd_sst_target_type {
-	SND_SST_TARGET_PMIC = 1,
-	SND_SST_TARGET_LPE,
-	SND_SST_TARGET_MODEM,
-	SND_SST_TARGET_BT,
-	SND_SST_TARGET_FM,
-	SND_SST_TARGET_NONE,
-};
-
-enum snd_sst_device_type {
-	SND_SST_DEVICE_SSP = 1,
-	SND_SST_DEVICE_PCM,
-	SND_SST_DEVICE_OTHER,
-};
-
-enum snd_sst_device_mode {
-
-	SND_SST_DEV_MODE_PCM_MODE1 = 1, /*(16-bit word, bit-length frame sync)*/
-	SND_SST_DEV_MODE_PCM_MODE2,
-	SND_SST_DEV_MODE_PCM_MODE3,
-	SND_SST_DEV_MODE_PCM_MODE4_RIGHT_JUSTIFIED,
-	SND_SST_DEV_MODE_PCM_MODE4_LEFT_JUSTIFIED,
-	SND_SST_DEV_MODE_PCM_MODE4_I2S, /*(I2S mode, 16-bit words)*/
-	SND_SST_DEV_MODE_PCM_MODE5,
-	SND_SST_DEV_MODE_PCM_MODE6,
-};
-
-enum snd_sst_port_action {
-	SND_SST_PORT_PREPARE = 1,
-	SND_SST_PORT_ACTIVATE,
-};
-
-/* Target selection per device structure */
-struct snd_sst_slot_info {
-	__u8 mix_enable;	/* Mixer enable or disable */
-	__u8 device_type;
-	__u8 device_instance;	/* 0, 1, 2 */
-	__u8 target_device;
-	__u16 target_sink;
-	__u8 slot[2];
-	__u8 master;
-	__u8 action;
-	__u8 device_mode;
-	__u8 reserved;
-	struct snd_sst_pmic_config pcm_params;
-} __attribute__ ((packed));
-
-#define SST_MAX_TARGET_DEVICES 3
-/* Target device list structure */
-struct snd_sst_target_device  {
-	__u32 device_route;
-	struct snd_sst_slot_info devices[SST_MAX_TARGET_DEVICES];
-} __attribute__ ((packed));
-
-struct snd_sst_driver_info {
-	__u32 version;	/* Version of the driver */
-	__u32 active_pcm_streams;
-	__u32 active_enc_streams;
-	__u32 max_pcm_streams;
-	__u32 max_enc_streams;
-	__u32 buf_per_stream;
-};
-
-enum snd_sst_buff_type {
-	SST_BUF_USER = 1,
-	SST_BUF_MMAP,
-	SST_BUF_RAR,
-};
-
-struct snd_sst_mmap_buff_entry {
-	unsigned int offset;
-	unsigned int size;
-};
-
-struct snd_sst_mmap_buffs {
-	unsigned int entries;
-	enum snd_sst_buff_type type;
-	struct snd_sst_mmap_buff_entry *buff;
-};
-
-struct snd_sst_buff_entry {
-	void *buffer;
-	unsigned int size;
-};
-
-struct snd_sst_buffs {
-	unsigned int entries;
-	__u8 type;
-	struct snd_sst_buff_entry *buff_entry;
-};
-
-struct snd_sst_dbufs  {
-	unsigned long long input_bytes_consumed;
-	unsigned long long output_bytes_produced;
-	struct snd_sst_buffs *ibufs;
-	struct snd_sst_buffs *obufs;
-};
-
-struct snd_sst_tuning_params {
-	__u8 type;
-	__u8 str_id;
-	__u8 size;
-	__u8 rsvd;
-	__aligned_u64 addr;
-} __attribute__ ((packed));
-/*IOCTL defined here */
-/*SST MMF IOCTLS only */
-#define SNDRV_SST_STREAM_SET_PARAMS _IOR('L', 0x00, \
-					struct snd_sst_stream_params *)
-#define SNDRV_SST_STREAM_GET_PARAMS _IOWR('L', 0x01, \
-					struct snd_sst_get_stream_params *)
-#define SNDRV_SST_STREAM_GET_TSTAMP _IOWR('L', 0x02, __u64 *)
-#define	SNDRV_SST_STREAM_DECODE	_IOWR('L', 0x03, struct snd_sst_dbufs *)
-#define SNDRV_SST_STREAM_BYTES_DECODED _IOWR('L', 0x04, __u64 *)
-#define SNDRV_SST_STREAM_START	_IO('A', 0x42)
-#define SNDRV_SST_STREAM_DROP	_IO('A', 0x43)
-#define SNDRV_SST_STREAM_DRAIN	_IO('A', 0x44)
-#define SNDRV_SST_STREAM_PAUSE	_IOW('A', 0x45, int)
-#define SNDRV_SST_STREAM_RESUME _IO('A', 0x47)
-#define SNDRV_SST_MMAP_PLAY	_IOW('L', 0x05, struct snd_sst_mmap_buffs *)
-#define SNDRV_SST_MMAP_CAPTURE _IOW('L', 0x06, struct snd_sst_mmap_buffs *)
-/*SST common ioctls */
-#define SNDRV_SST_DRIVER_INFO	_IOR('L', 0x10, struct snd_sst_driver_info *)
-#define SNDRV_SST_SET_VOL	_IOW('L', 0x11, struct snd_sst_vol *)
-#define SNDRV_SST_GET_VOL	_IOW('L', 0x12, struct snd_sst_vol *)
-#define SNDRV_SST_MUTE		_IOW('L', 0x13, struct snd_sst_mute *)
-/*AM Ioctly only */
-#define SNDRV_SST_FW_INFO	_IOR('L', 0x20,  struct snd_sst_fw_info *)
-#define SNDRV_SST_SET_TARGET_DEVICE _IOW('L', 0x21, \
-					struct snd_sst_target_device *)
-/*DSP Ioctls on /dev/intel_sst_ctrl only*/
-#define SNDRV_SST_SET_ALGO	_IOW('L', 0x30,  struct snd_ppp_params *)
-#define SNDRV_SST_GET_ALGO	_IOWR('L', 0x31,  struct snd_ppp_params *)
-#define SNDRV_SST_TUNING_PARAMS	_IOW('L', 0x32,  struct snd_sst_tuning_params *)
-
-#endif /* __INTEL_SST_IOCTL_H__ */
diff --git a/drivers/staging/intel_sst/intel_sst_ipc.c b/drivers/staging/intel_sst/intel_sst_ipc.c
deleted file mode 100644
index 5c3444f..0000000
--- a/drivers/staging/intel_sst/intel_sst_ipc.c
+++ /dev/null
@@ -1,774 +0,0 @@
-/*
- *  intel_sst_ipc.c - Intel SST Driver for audio engine
- *
- *  Copyright (C) 2008-10 Intel Corporation
- *  Authors:	Vinod Koul <vinod.koul@intel.com>
- *		Harsha Priya <priya.harsha@intel.com>
- *		Dharageswari R <dharageswari.r@intel.com>
- *		KP Jeeja <jeeja.kp@intel.com>
- *  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; version 2 of the License.
- *
- *  This program is distributed in the hope that it will be useful, but
- *  WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *  General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License along
- *  with this program; if not, write to the Free Software Foundation, Inc.,
- *  59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
- *
- * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- *
- *  This file defines all ipc functions
- */
-
-#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
-
-#include <linux/pci.h>
-#include <linux/firmware.h>
-#include <linux/sched.h>
-#include "intel_sst.h"
-#include "intel_sst_ioctl.h"
-#include "intel_sst_fw_ipc.h"
-#include "intel_sst_common.h"
-
-/*
- * sst_send_sound_card_type - send sound card type
- *
- * this function sends the sound card type to sst dsp engine
- */
-static void sst_send_sound_card_type(void)
-{
-	struct ipc_post *msg = NULL;
-
-	if (sst_create_short_msg(&msg))
-		return;
-
-	sst_fill_header(&msg->header, IPC_IA_SET_PMIC_TYPE, 0, 0);
-	msg->header.part.data = sst_drv_ctx->pmic_vendor;
-	spin_lock(&sst_drv_ctx->list_spin_lock);
-	list_add_tail(&msg->node, &sst_drv_ctx->ipc_dispatch_list);
-	spin_unlock(&sst_drv_ctx->list_spin_lock);
-	sst_post_message(&sst_drv_ctx->ipc_post_msg_wq);
-	return;
-}
-
-/**
-* sst_post_message - Posts message to SST
-*
-* @work: Pointer to work structure
-*
-* This function is called by any component in driver which
-* wants to send an IPC message. This will post message only if
-* busy bit is free
-*/
-void sst_post_message(struct work_struct *work)
-{
-	struct ipc_post *msg;
-	union ipc_header header;
-	union  interrupt_reg imr;
-	int retval = 0;
-	imr.full = 0;
-
-	/*To check if LPE is in stalled state.*/
-	retval = sst_stalled();
-	if (retval < 0) {
-		pr_err("in stalled state\n");
-		return;
-	}
-	pr_debug("post message called\n");
-	spin_lock(&sst_drv_ctx->list_spin_lock);
-
-	/* check list */
-	if (list_empty(&sst_drv_ctx->ipc_dispatch_list)) {
-		/* list is empty, mask imr */
-		pr_debug("Empty msg queue... masking\n");
-		imr.full = readl(sst_drv_ctx->shim + SST_IMRX);
-		imr.part.done_interrupt = 1;
-		/* dummy register for shim workaround */
-		sst_shim_write(sst_drv_ctx->shim, SST_IMRX, imr.full);
-		spin_unlock(&sst_drv_ctx->list_spin_lock);
-		return;
-	}
-
-	/* check busy bit */
-	header.full = sst_shim_read(sst_drv_ctx->shim, SST_IPCX);
-	if (header.part.busy) {
-		/* busy, unmask */
-		pr_debug("Busy not free... unmasking\n");
-		imr.full = readl(sst_drv_ctx->shim + SST_IMRX);
-		imr.part.done_interrupt = 0;
-		/* dummy register for shim workaround */
-		sst_shim_write(sst_drv_ctx->shim, SST_IMRX, imr.full);
-		spin_unlock(&sst_drv_ctx->list_spin_lock);
-		return;
-	}
-	/* copy msg from list */
-	msg = list_entry(sst_drv_ctx->ipc_dispatch_list.next,
-			struct ipc_post, node);
-	list_del(&msg->node);
-	pr_debug("Post message: header = %x\n", msg->header.full);
-	pr_debug("size: = %x\n", msg->header.part.data);
-	if (msg->header.part.large)
-		memcpy_toio(sst_drv_ctx->mailbox + SST_MAILBOX_SEND,
-			msg->mailbox_data, msg->header.part.data);
-	/* dummy register for shim workaround */
-
-	sst_shim_write(sst_drv_ctx->shim, SST_IPCX, msg->header.full);
-	spin_unlock(&sst_drv_ctx->list_spin_lock);
-
-	kfree(msg->mailbox_data);
-	kfree(msg);
-	return;
-}
-
-/*
- * sst_clear_interrupt - clear the SST FW interrupt
- *
- * This function clears the interrupt register after the interrupt
- * bottom half is complete allowing next interrupt to arrive
- */
-void sst_clear_interrupt(void)
-{
-	union interrupt_reg isr;
-	union interrupt_reg imr;
-	union ipc_header clear_ipc;
-
-	imr.full = sst_shim_read(sst_drv_ctx->shim, SST_IMRX);
-	isr.full = sst_shim_read(sst_drv_ctx->shim, SST_ISRX);
-	/*  write 1 to clear  */;
-	isr.part.busy_interrupt = 1;
-	sst_shim_write(sst_drv_ctx->shim, SST_ISRX, isr.full);
-	/* Set IA done bit */
-	clear_ipc.full = sst_shim_read(sst_drv_ctx->shim, SST_IPCD);
-	clear_ipc.part.busy = 0;
-	clear_ipc.part.done = 1;
-	clear_ipc.part.data = IPC_ACK_SUCCESS;
-	sst_shim_write(sst_drv_ctx->shim, SST_IPCD, clear_ipc.full);
-	/* un mask busy interrupt */
-	imr.part.busy_interrupt = 0;
-	sst_shim_write(sst_drv_ctx->shim, SST_IMRX, imr.full);
-}
-
-void sst_restore_fw_context(void)
-{
-	struct snd_sst_ctxt_params fw_context;
-	struct ipc_post *msg = NULL;
-
-	pr_debug("restore_fw_context\n");
-	/*check cpu type*/
-	if (sst_drv_ctx->pci_id != SST_MFLD_PCI_ID)
-		return;
-		/*not supported for rest*/
-	if (!sst_drv_ctx->fw_cntx_size)
-		return;
-		/*nothing to restore*/
-	pr_debug("restoring context......\n");
-	/*send msg to fw*/
-	if (sst_create_large_msg(&msg))
-		return;
-
-	sst_fill_header(&msg->header, IPC_IA_SET_FW_CTXT, 1, 0);
-	msg->header.part.data = sizeof(fw_context) + sizeof(u32);
-	fw_context.address = virt_to_phys((void *)sst_drv_ctx->fw_cntx);
-	fw_context.size = sst_drv_ctx->fw_cntx_size;
-	memcpy(msg->mailbox_data, &msg->header, sizeof(u32));
-	memcpy(msg->mailbox_data + sizeof(u32),
-				&fw_context, sizeof(fw_context));
-	spin_lock(&sst_drv_ctx->list_spin_lock);
-	list_add_tail(&msg->node, &sst_drv_ctx->ipc_dispatch_list);
-	spin_unlock(&sst_drv_ctx->list_spin_lock);
-	sst_post_message(&sst_drv_ctx->ipc_post_msg_wq);
-	return;
-}
-/*
- * process_fw_init - process the FW init msg
- *
- * @msg: IPC message from FW
- *
- * This function processes the FW init msg from FW
- * marks FW state and prints debug info of loaded FW
- */
-int process_fw_init(struct sst_ipc_msg_wq *msg)
-{
-	struct ipc_header_fw_init *init =
-		(struct ipc_header_fw_init *)msg->mailbox;
-	int retval = 0;
-
-	pr_debug("*** FW Init msg came***\n");
-	if (init->result) {
-		mutex_lock(&sst_drv_ctx->sst_lock);
-		sst_drv_ctx->sst_state = SST_ERROR;
-		mutex_unlock(&sst_drv_ctx->sst_lock);
-		pr_debug("FW Init failed, Error %x\n", init->result);
-		pr_err("FW Init failed, Error %x\n", init->result);
-		retval = -init->result;
-		return retval;
-	}
-	if (sst_drv_ctx->pci_id == SST_MRST_PCI_ID)
-		sst_send_sound_card_type();
-	mutex_lock(&sst_drv_ctx->sst_lock);
-	sst_drv_ctx->sst_state = SST_FW_RUNNING;
-	sst_drv_ctx->lpe_stalled = 0;
-	mutex_unlock(&sst_drv_ctx->sst_lock);
-	pr_debug("FW Version %02x.%02x.%02x\n", init->fw_version.major,
-			init->fw_version.minor, init->fw_version.build);
-	pr_debug("Build Type %x\n", init->fw_version.type);
-	pr_debug(" Build date %s Time %s\n",
-			init->build_info.date, init->build_info.time);
-	sst_wake_up_alloc_block(sst_drv_ctx, FW_DWNL_ID, retval, NULL);
-	sst_restore_fw_context();
-	return retval;
-}
-/**
-* sst_process_message - Processes message from SST
-*
-* @work:	Pointer to work structure
-*
-* This function is scheduled by ISR
-* It take a msg from process_queue and does action based on msg
-*/
-void sst_process_message(struct work_struct *work)
-{
-	struct sst_ipc_msg_wq *msg =
-			container_of(work, struct sst_ipc_msg_wq, wq);
-	int str_id = msg->header.part.str_id;
-
-	pr_debug("IPC process for %x\n", msg->header.full);
-
-	/* based on msg in list call respective handler */
-	switch (msg->header.part.msg_id) {
-	case IPC_SST_BUF_UNDER_RUN:
-	case IPC_SST_BUF_OVER_RUN:
-		if (sst_validate_strid(str_id)) {
-			pr_err("stream id %d invalid\n", str_id);
-			break;
-		}
-		pr_err("Buffer under/overrun for %d\n",
-				msg->header.part.str_id);
-		pr_err("Got Underrun & not to send data...ignore\n");
-		break;
-
-	case IPC_SST_GET_PLAY_FRAMES:
-		if (sst_drv_ctx->pci_id == SST_MRST_PCI_ID) {
-			struct stream_info *stream ;
-
-			if (sst_validate_strid(str_id)) {
-				pr_err("strid %d invalid\n", str_id);
-				break;
-			}
-			/* call sst_play_frame */
-			stream = &sst_drv_ctx->streams[str_id];
-			pr_debug("sst_play_frames for %d\n",
-					msg->header.part.str_id);
-			mutex_lock(&sst_drv_ctx->streams[str_id].lock);
-			sst_play_frame(msg->header.part.str_id);
-			mutex_unlock(&sst_drv_ctx->streams[str_id].lock);
-			break;
-		} else
-			pr_err("sst_play_frames for Penwell!!\n");
-
-	case IPC_SST_GET_CAPT_FRAMES:
-		if (sst_drv_ctx->pci_id == SST_MRST_PCI_ID) {
-			struct stream_info *stream;
-			/* call sst_capture_frame */
-			if (sst_validate_strid(str_id)) {
-				pr_err("str id %d invalid\n", str_id);
-				break;
-			}
-			stream = &sst_drv_ctx->streams[str_id];
-			pr_debug("sst_capture_frames for %d\n",
-					msg->header.part.str_id);
-			mutex_lock(&stream->lock);
-			if (stream->mmapped == false &&
-					stream->src == SST_DRV) {
-				pr_debug("waking up block for copy.\n");
-				stream->data_blk.ret_code = 0;
-				stream->data_blk.condition = true;
-				stream->data_blk.on = false;
-				wake_up(&sst_drv_ctx->wait_queue);
-			} else
-				sst_capture_frame(msg->header.part.str_id);
-			mutex_unlock(&stream->lock);
-		} else
-			pr_err("sst_play_frames for Penwell!!\n");
-		break;
-
-	case IPC_IA_PRINT_STRING:
-		pr_debug("been asked to print something by fw\n");
-		/* TBD */
-		break;
-
-	case IPC_IA_FW_INIT_CMPLT: {
-		/* send next data to FW */
-		process_fw_init(msg);
-		break;
-	}
-
-	case IPC_SST_STREAM_PROCESS_FATAL_ERR:
-		if (sst_validate_strid(str_id)) {
-			pr_err("stream id %d invalid\n", str_id);
-			break;
-		}
-		pr_err("codec fatal error %x stream %d...\n",
-				msg->header.full, msg->header.part.str_id);
-		pr_err("Dropping the stream\n");
-		sst_drop_stream(msg->header.part.str_id);
-		break;
-	case IPC_IA_LPE_GETTING_STALLED:
-		sst_drv_ctx->lpe_stalled = 1;
-		break;
-	case IPC_IA_LPE_UNSTALLED:
-		sst_drv_ctx->lpe_stalled = 0;
-		break;
-	default:
-		/* Illegal case */
-		pr_err("Unhandled msg %x header %x\n",
-		msg->header.part.msg_id, msg->header.full);
-	}
-	sst_clear_interrupt();
-	return;
-}
-
-/**
-* sst_process_reply - Processes reply message from SST
-*
-* @work:	Pointer to work structure
-*
-* This function is scheduled by ISR
-* It take a reply msg from response_queue and
-* does action based on msg
-*/
-void sst_process_reply(struct work_struct *work)
-{
-	struct sst_ipc_msg_wq *msg =
-			container_of(work, struct sst_ipc_msg_wq, wq);
-
-	int str_id = msg->header.part.str_id;
-	struct stream_info *str_info;
-
-	switch (msg->header.part.msg_id) {
-	case IPC_IA_TARGET_DEV_SELECT:
-		if (!msg->header.part.data) {
-			sst_drv_ctx->tgt_dev_blk.ret_code = 0;
-		} else {
-			pr_err(" Msg %x reply error %x\n",
-			msg->header.part.msg_id, msg->header.part.data);
-			sst_drv_ctx->tgt_dev_blk.ret_code =
-					-msg->header.part.data;
-		}
-
-		if (sst_drv_ctx->tgt_dev_blk.on == true) {
-				sst_drv_ctx->tgt_dev_blk.condition = true;
-				wake_up(&sst_drv_ctx->wait_queue);
-		}
-		break;
-	case IPC_IA_ALG_PARAMS: {
-		pr_debug("sst:IPC_ALG_PARAMS response %x\n", msg->header.full);
-		pr_debug("sst: data value %x\n", msg->header.part.data);
-		pr_debug("sst: large value %x\n", msg->header.part.large);
-
-		if (!msg->header.part.large) {
-			if (!msg->header.part.data) {
-				pr_debug("sst: alg set success\n");
-				sst_drv_ctx->ppp_params_blk.ret_code = 0;
-			} else {
-				pr_debug("sst: alg set failed\n");
-				sst_drv_ctx->ppp_params_blk.ret_code =
-							-msg->header.part.data;
-			}
-
-		} else if (msg->header.part.data) {
-			struct snd_ppp_params *mailbox_params, *get_params;
-			char *params;
-
-			pr_debug("sst: alg get success\n");
-			mailbox_params = (struct snd_ppp_params *)msg->mailbox;
-			get_params = kzalloc(sizeof(*get_params), GFP_KERNEL);
-			if (get_params == NULL) {
-				pr_err("sst: out of memory for ALG PARAMS");
-				break;
-			}
-			memcpy_fromio(get_params, mailbox_params,
-							sizeof(*get_params));
-			get_params->params = kzalloc(mailbox_params->size,
-							GFP_KERNEL);
-			if (get_params->params == NULL) {
-				kfree(get_params);
-				pr_err("sst: out of memory for ALG PARAMS block");
-				break;
-			}
-			params = msg->mailbox;
-			params = params + sizeof(*mailbox_params) - sizeof(u32);
-			memcpy_fromio(get_params->params, params,
-							get_params->size);
-			sst_drv_ctx->ppp_params_blk.ret_code = 0;
-			sst_drv_ctx->ppp_params_blk.data = get_params;
-		}
-
-		if (sst_drv_ctx->ppp_params_blk.on == true) {
-			sst_drv_ctx->ppp_params_blk.condition = true;
-			wake_up(&sst_drv_ctx->wait_queue);
-		}
-		break;
-	}
-
-	case IPC_IA_TUNING_PARAMS: {
-		pr_debug("sst:IPC_TUNING_PARAMS resp: %x\n", msg->header.full);
-		pr_debug("data value %x\n", msg->header.part.data);
-		if (msg->header.part.large) {
-			pr_debug("alg set failed\n");
-			sst_drv_ctx->ppp_params_blk.ret_code =
-							-msg->header.part.data;
-		} else {
-			pr_debug("alg set success\n");
-			sst_drv_ctx->ppp_params_blk.ret_code = 0;
-		}
-		if (sst_drv_ctx->ppp_params_blk.on == true) {
-			sst_drv_ctx->ppp_params_blk.condition = true;
-			wake_up(&sst_drv_ctx->wait_queue);
-		}
-	}
-
-	case IPC_IA_GET_FW_INFO: {
-		struct snd_sst_fw_info *fw_info =
-			(struct snd_sst_fw_info *)msg->mailbox;
-		if (msg->header.part.large) {
-			int major = fw_info->fw_version.major;
-			int minor = fw_info->fw_version.minor;
-			int build = fw_info->fw_version.build;
-			pr_debug("Msg succeeded %x\n",
-				       msg->header.part.msg_id);
-			pr_debug("INFO: ***FW*** = %02d.%02d.%02d\n",
-					major, minor, build);
-			memcpy_fromio(sst_drv_ctx->fw_info_blk.data,
-				((struct snd_sst_fw_info *)(msg->mailbox)),
-				sizeof(struct snd_sst_fw_info));
-			sst_drv_ctx->fw_info_blk.ret_code = 0;
-		} else {
-			pr_err(" Msg %x reply error %x\n",
-			msg->header.part.msg_id, msg->header.part.data);
-			sst_drv_ctx->fw_info_blk.ret_code =
-					-msg->header.part.data;
-		}
-		if (sst_drv_ctx->fw_info_blk.on == true) {
-			pr_debug("Memcopy succeeded\n");
-			sst_drv_ctx->fw_info_blk.on = false;
-			sst_drv_ctx->fw_info_blk.condition = true;
-			wake_up(&sst_drv_ctx->wait_queue);
-		}
-		break;
-	}
-	case IPC_IA_SET_STREAM_MUTE:
-		if (!msg->header.part.data) {
-			pr_debug("Msg succeeded %x\n",
-				       msg->header.part.msg_id);
-			sst_drv_ctx->mute_info_blk.ret_code = 0;
-		} else {
-			pr_err(" Msg %x reply error %x\n",
-			msg->header.part.msg_id, msg->header.part.data);
-			sst_drv_ctx->mute_info_blk.ret_code =
-					-msg->header.part.data;
-
-		}
-		if (sst_drv_ctx->mute_info_blk.on == true) {
-			sst_drv_ctx->mute_info_blk.on = false;
-			sst_drv_ctx->mute_info_blk.condition = true;
-			wake_up(&sst_drv_ctx->wait_queue);
-		}
-		break;
-	case IPC_IA_SET_STREAM_VOL:
-		if (!msg->header.part.data) {
-			pr_debug("Msg succeeded %x\n",
-				       msg->header.part.msg_id);
-			sst_drv_ctx->vol_info_blk.ret_code = 0;
-		} else {
-			pr_err(" Msg %x reply error %x\n",
-					msg->header.part.msg_id,
-			msg->header.part.data);
-			sst_drv_ctx->vol_info_blk.ret_code =
-					-msg->header.part.data;
-
-		}
-
-		if (sst_drv_ctx->vol_info_blk.on == true) {
-			sst_drv_ctx->vol_info_blk.on = false;
-			sst_drv_ctx->vol_info_blk.condition = true;
-			wake_up(&sst_drv_ctx->wait_queue);
-		}
-		break;
-	case IPC_IA_GET_STREAM_VOL:
-		if (msg->header.part.large) {
-			pr_debug("Large Msg Received Successfully\n");
-			pr_debug("Msg succeeded %x\n",
-				       msg->header.part.msg_id);
-			memcpy_fromio(sst_drv_ctx->vol_info_blk.data,
-				(void *) msg->mailbox,
-				sizeof(struct snd_sst_vol));
-			sst_drv_ctx->vol_info_blk.ret_code = 0;
-		} else {
-			pr_err("Msg %x reply error %x\n",
-			msg->header.part.msg_id, msg->header.part.data);
-			sst_drv_ctx->vol_info_blk.ret_code =
-					-msg->header.part.data;
-		}
-		if (sst_drv_ctx->vol_info_blk.on == true) {
-			sst_drv_ctx->vol_info_blk.on = false;
-			sst_drv_ctx->vol_info_blk.condition = true;
-			wake_up(&sst_drv_ctx->wait_queue);
-		}
-		break;
-
-	case IPC_IA_GET_STREAM_PARAMS:
-		if (sst_validate_strid(str_id)) {
-			pr_err("stream id %d invalid\n", str_id);
-			break;
-		}
-		str_info = &sst_drv_ctx->streams[str_id];
-		if (msg->header.part.large) {
-			pr_debug("Get stream large success\n");
-			memcpy_fromio(str_info->ctrl_blk.data,
-				((void *)(msg->mailbox)),
-				sizeof(struct snd_sst_fw_get_stream_params));
-			str_info->ctrl_blk.ret_code = 0;
-		} else {
-			pr_err("Msg %x reply error %x\n",
-				msg->header.part.msg_id, msg->header.part.data);
-			str_info->ctrl_blk.ret_code = -msg->header.part.data;
-		}
-		if (str_info->ctrl_blk.on == true) {
-			str_info->ctrl_blk.on = false;
-			str_info->ctrl_blk.condition = true;
-			wake_up(&sst_drv_ctx->wait_queue);
-		}
-		break;
-	case IPC_IA_DECODE_FRAMES:
-		if (sst_validate_strid(str_id)) {
-			pr_err("stream id %d invalid\n", str_id);
-			break;
-		}
-		str_info = &sst_drv_ctx->streams[str_id];
-		if (msg->header.part.large) {
-			pr_debug("Msg succeeded %x\n",
-				       msg->header.part.msg_id);
-			memcpy_fromio(str_info->data_blk.data,
-					((void *)(msg->mailbox)),
-					sizeof(struct snd_sst_decode_info));
-			str_info->data_blk.ret_code = 0;
-		} else {
-			pr_err("Msg %x reply error %x\n",
-				msg->header.part.msg_id, msg->header.part.data);
-			str_info->data_blk.ret_code = -msg->header.part.data;
-		}
-		if (str_info->data_blk.on == true) {
-			str_info->data_blk.on = false;
-			str_info->data_blk.condition = true;
-			wake_up(&sst_drv_ctx->wait_queue);
-		}
-		break;
-	case IPC_IA_DRAIN_STREAM:
-		if (sst_validate_strid(str_id)) {
-			pr_err("stream id %d invalid\n", str_id);
-			break;
-		}
-		str_info = &sst_drv_ctx->streams[str_id];
-		if (!msg->header.part.data) {
-			pr_debug("Msg succeeded %x\n",
-					msg->header.part.msg_id);
-			str_info->ctrl_blk.ret_code = 0;
-
-		} else {
-			pr_err(" Msg %x reply error %x\n",
-				msg->header.part.msg_id, msg->header.part.data);
-			str_info->ctrl_blk.ret_code = -msg->header.part.data;
-
-		}
-		str_info = &sst_drv_ctx->streams[str_id];
-		if (str_info->data_blk.on == true) {
-			str_info->data_blk.on = false;
-			str_info->data_blk.condition = true;
-			wake_up(&sst_drv_ctx->wait_queue);
-		}
-		break;
-
-	case IPC_IA_DROP_STREAM:
-		if (sst_validate_strid(str_id)) {
-			pr_err("str id %d invalid\n", str_id);
-			break;
-		}
-		str_info = &sst_drv_ctx->streams[str_id];
-		if (msg->header.part.large) {
-			struct snd_sst_drop_response *drop_resp =
-				(struct snd_sst_drop_response *)msg->mailbox;
-
-			pr_debug("Drop ret bytes %x\n", drop_resp->bytes);
-
-			str_info->curr_bytes = drop_resp->bytes;
-			str_info->ctrl_blk.ret_code =  0;
-		} else {
-			pr_err(" Msg %x reply error %x\n",
-				msg->header.part.msg_id, msg->header.part.data);
-			str_info->ctrl_blk.ret_code = -msg->header.part.data;
-		}
-		if (str_info->ctrl_blk.on == true) {
-			str_info->ctrl_blk.on = false;
-			str_info->ctrl_blk.condition = true;
-			wake_up(&sst_drv_ctx->wait_queue);
-		}
-		break;
-	case IPC_IA_ENABLE_RX_TIME_SLOT:
-		if (!msg->header.part.data) {
-			pr_debug("RX_TIME_SLOT success\n");
-			sst_drv_ctx->hs_info_blk.ret_code = 0;
-		} else {
-			pr_err(" Msg %x reply error %x\n",
-				msg->header.part.msg_id,
-				msg->header.part.data);
-			sst_drv_ctx->hs_info_blk.ret_code =
-				-msg->header.part.data;
-		}
-		if (sst_drv_ctx->hs_info_blk.on == true) {
-			sst_drv_ctx->hs_info_blk.on = false;
-			sst_drv_ctx->hs_info_blk.condition = true;
-			wake_up(&sst_drv_ctx->wait_queue);
-		}
-		break;
-	case IPC_IA_PAUSE_STREAM:
-	case IPC_IA_RESUME_STREAM:
-	case IPC_IA_SET_STREAM_PARAMS:
-		str_info = &sst_drv_ctx->streams[str_id];
-		if (!msg->header.part.data) {
-			pr_debug("Msg succeeded %x\n",
-					msg->header.part.msg_id);
-			str_info->ctrl_blk.ret_code = 0;
-		} else {
-			pr_err(" Msg %x reply error %x\n",
-					msg->header.part.msg_id,
-					msg->header.part.data);
-			str_info->ctrl_blk.ret_code = -msg->header.part.data;
-		}
-		if (sst_validate_strid(str_id)) {
-			pr_err(" stream id %d invalid\n", str_id);
-			break;
-		}
-
-		if (str_info->ctrl_blk.on == true) {
-			str_info->ctrl_blk.on = false;
-			str_info->ctrl_blk.condition = true;
-			wake_up(&sst_drv_ctx->wait_queue);
-		}
-		break;
-
-	case IPC_IA_FREE_STREAM:
-		str_info = &sst_drv_ctx->streams[str_id];
-		if (!msg->header.part.data) {
-			pr_debug("Stream %d freed\n", str_id);
-		} else {
-			pr_err("Free for %d ret error %x\n",
-				       str_id, msg->header.part.data);
-		}
-		if (str_info->ctrl_blk.on == true) {
-			str_info->ctrl_blk.on = false;
-			str_info->ctrl_blk.condition = true;
-			wake_up(&sst_drv_ctx->wait_queue);
-		}
-		break;
-	case IPC_IA_ALLOC_STREAM: {
-		/* map to stream, call play */
-		struct snd_sst_alloc_response *resp =
-				(struct snd_sst_alloc_response *)msg->mailbox;
-		if (resp->str_type.result)
-			pr_err("error alloc stream = %x\n",
-				       resp->str_type.result);
-		sst_alloc_stream_response(str_id, resp);
-		break;
-	}
-
-	case IPC_IA_PLAY_FRAMES:
-	case IPC_IA_CAPT_FRAMES:
-		if (sst_validate_strid(str_id)) {
-			pr_err("stream id %d invalid\n", str_id);
-			break;
-		}
-		pr_debug("Ack for play/capt frames received\n");
-		break;
-
-	case IPC_IA_PREP_LIB_DNLD: {
-		struct snd_sst_str_type *str_type =
-			(struct snd_sst_str_type *)msg->mailbox;
-		pr_debug("Prep Lib download %x\n",
-				msg->header.part.msg_id);
-		if (str_type->result)
-			pr_err("Prep lib download %x\n", str_type->result);
-		else
-			pr_debug("Can download codec now...\n");
-		sst_wake_up_alloc_block(sst_drv_ctx, str_id,
-				str_type->result, NULL);
-		break;
-	}
-
-	case IPC_IA_LIB_DNLD_CMPLT: {
-		struct snd_sst_lib_download_info *resp =
-			(struct snd_sst_lib_download_info *)msg->mailbox;
-		int retval = resp->result;
-
-		pr_debug("Lib downloaded %x\n", msg->header.part.msg_id);
-		if (resp->result) {
-			pr_err("err in lib dload %x\n", resp->result);
-		} else {
-			pr_debug("Codec download complete...\n");
-			pr_debug("codec Type %d Ver %d Built %s: %s\n",
-				resp->dload_lib.lib_info.lib_type,
-				resp->dload_lib.lib_info.lib_version,
-				resp->dload_lib.lib_info.b_date,
-				resp->dload_lib.lib_info.b_time);
-		}
-		sst_wake_up_alloc_block(sst_drv_ctx, str_id,
-						retval, NULL);
-		break;
-	}
-
-	case IPC_IA_GET_FW_VERSION: {
-		struct ipc_header_fw_init *version =
-				(struct ipc_header_fw_init *)msg->mailbox;
-		int major = version->fw_version.major;
-		int minor = version->fw_version.minor;
-		int build = version->fw_version.build;
-		dev_info(&sst_drv_ctx->pci->dev,
-			"INFO: ***LOADED SST FW VERSION*** = %02d.%02d.%02d\n",
-		major, minor, build);
-		break;
-	}
-	case IPC_IA_GET_FW_BUILD_INF: {
-		struct sst_fw_build_info *build =
-			(struct sst_fw_build_info *)msg->mailbox;
-		pr_debug("Build date:%sTime:%s", build->date, build->time);
-		break;
-	}
-	case IPC_IA_SET_PMIC_TYPE:
-		break;
-	case IPC_IA_START_STREAM:
-		pr_debug("reply for START STREAM %x\n", msg->header.full);
-		break;
-
-	case IPC_IA_GET_FW_CTXT:
-		pr_debug("reply for get fw ctxt  %x\n", msg->header.full);
-		if (msg->header.part.data)
-			sst_drv_ctx->fw_cntx_size = 0;
-		else
-			sst_drv_ctx->fw_cntx_size = *sst_drv_ctx->fw_cntx;
-		pr_debug("fw copied data %x\n", sst_drv_ctx->fw_cntx_size);
-		sst_wake_up_alloc_block(
-			sst_drv_ctx, str_id, msg->header.part.data, NULL);
-		break;
-	default:
-		/* Illegal case */
-		pr_err("process reply:default = %x\n", msg->header.full);
-	}
-	sst_clear_interrupt();
-	return;
-}
diff --git a/drivers/staging/intel_sst/intel_sst_pvt.c b/drivers/staging/intel_sst/intel_sst_pvt.c
deleted file mode 100644
index e034bea..0000000
--- a/drivers/staging/intel_sst/intel_sst_pvt.c
+++ /dev/null
@@ -1,313 +0,0 @@
-/*
- *  intel_sst_pvt.c - Intel SST Driver for audio engine
- *
- *  Copyright (C) 2008-10	Intel Corp
- *  Authors:	Vinod Koul <vinod.koul@intel.com>
- *		Harsha Priya <priya.harsha@intel.com>
- *		Dharageswari R <dharageswari.r@intel.com>
- *		KP Jeeja <jeeja.kp@intel.com>
- *  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; version 2 of the License.
- *
- *  This program is distributed in the hope that it will be useful, but
- *  WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *  General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License along
- *  with this program; if not, write to the Free Software Foundation, Inc.,
- *  59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
- *
- * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- *
- *  This driver exposes the audio engine functionalities to the ALSA
- *	and middleware.
- *
- *  This file contains all private functions
- */
-
-#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
-
-#include <linux/pci.h>
-#include <linux/fs.h>
-#include <linux/firmware.h>
-#include <linux/sched.h>
-#include "intel_sst.h"
-#include "intel_sst_ioctl.h"
-#include "intel_sst_fw_ipc.h"
-#include "intel_sst_common.h"
-
-/*
- * sst_get_block_stream - get a new block stream
- *
- * @sst_drv_ctx: Driver context structure
- *
- * This function assigns a block for the calls that dont have stream context yet
- * the blocks are used for waiting on Firmware's response for any operation
- * Should be called with stream lock held
- */
-int sst_get_block_stream(struct intel_sst_drv *sst_drv_ctx)
-{
-	int i;
-
-	for (i = 0; i < MAX_ACTIVE_STREAM; i++) {
-		if (sst_drv_ctx->alloc_block[i].sst_id == BLOCK_UNINIT) {
-			sst_drv_ctx->alloc_block[i].ops_block.condition = false;
-			sst_drv_ctx->alloc_block[i].ops_block.ret_code = 0;
-			sst_drv_ctx->alloc_block[i].sst_id = 0;
-			break;
-		}
-	}
-	if (i == MAX_ACTIVE_STREAM) {
-		pr_err("max alloc_stream reached\n");
-		i = -EBUSY; /* active stream limit reached */
-	}
-	return i;
-}
-
-/*
- * sst_wait_interruptible - wait on event
- *
- * @sst_drv_ctx: Driver context
- * @block: Driver block to wait on
- *
- * This function waits without a timeout (and is interruptable) for a
- * given block event
- */
-int sst_wait_interruptible(struct intel_sst_drv *sst_drv_ctx,
-				struct sst_block *block)
-{
-	int retval = 0;
-
-	if (!wait_event_interruptible(sst_drv_ctx->wait_queue,
-				block->condition)) {
-		/* event wake */
-		if (block->ret_code < 0) {
-			pr_err("stream failed %d\n", block->ret_code);
-			retval = -EBUSY;
-		} else {
-			pr_debug("event up\n");
-			retval = 0;
-		}
-	} else {
-		pr_err("signal interrupted\n");
-		retval = -EINTR;
-	}
-	return retval;
-
-}
-
-
-/*
- * sst_wait_interruptible_timeout - wait on event interruptable
- *
- * @sst_drv_ctx: Driver context
- * @block: Driver block to wait on
- * @timeout: time for wait on
- *
- * This function waits with a timeout value (and is interruptible) on a
- * given block event
- */
-int sst_wait_interruptible_timeout(
-			struct intel_sst_drv *sst_drv_ctx,
-			struct sst_block *block, int timeout)
-{
-	int retval = 0;
-
-	pr_debug("sst_wait_interruptible_timeout - waiting....\n");
-	if (wait_event_interruptible_timeout(sst_drv_ctx->wait_queue,
-						block->condition,
-						msecs_to_jiffies(timeout))) {
-		if (block->ret_code < 0)
-			pr_err("stream failed %d\n", block->ret_code);
-		else
-			pr_debug("event up\n");
-		retval = block->ret_code;
-	} else {
-		block->on = false;
-		pr_err("timeout occurred...\n");
-		/*setting firmware state as uninit so that the
-		firmware will get re-downloaded on next request
-		this is because firmare not responding for 5 sec
-		is equalant to some unrecoverable error of FW
-		sst_drv_ctx->sst_state = SST_UN_INIT;*/
-		retval = -EBUSY;
-	}
-	return retval;
-
-}
-
-
-/*
- * sst_wait_timeout - wait on event for timeout
- *
- * @sst_drv_ctx: Driver context
- * @block: Driver block to wait on
- *
- * This function waits with a timeout value (and is not interruptible) on a
- * given block event
- */
-int sst_wait_timeout(struct intel_sst_drv *sst_drv_ctx,
-		struct stream_alloc_block *block)
-{
-	int retval = 0;
-
-	/* NOTE:
-	Observed that FW processes the alloc msg and replies even
-	before the alloc thread has finished execution */
-	pr_debug("waiting for %x, condition %x\n",
-		       block->sst_id, block->ops_block.condition);
-	if (wait_event_interruptible_timeout(sst_drv_ctx->wait_queue,
-				block->ops_block.condition,
-				msecs_to_jiffies(SST_BLOCK_TIMEOUT))) {
-		/* event wake */
-		pr_debug("Event wake %x\n", block->ops_block.condition);
-		pr_debug("message ret: %d\n", block->ops_block.ret_code);
-		retval = block->ops_block.ret_code;
-	} else {
-		block->ops_block.on = false;
-		pr_err("Wait timed-out %x\n", block->ops_block.condition);
-		/* settign firmware state as uninit so that the
-		firmware will get redownloaded on next request
-		this is because firmare not responding for 5 sec
-		is equalant to some unrecoverable error of FW
-		sst_drv_ctx->sst_state = SST_UN_INIT;*/
-		retval = -EBUSY;
-	}
-	return retval;
-
-}
-
-/*
- * sst_create_large_msg - create a large IPC message
- *
- * @arg: ipc message
- *
- * this function allocates structures to send a large message to the firmware
- */
-int sst_create_large_msg(struct ipc_post **arg)
-{
-	struct ipc_post *msg;
-
-	msg = kzalloc(sizeof(struct ipc_post), GFP_ATOMIC);
-	if (!msg) {
-		pr_err("kzalloc msg failed\n");
-		return -ENOMEM;
-	}
-
-	msg->mailbox_data = kzalloc(SST_MAILBOX_SIZE, GFP_ATOMIC);
-	if (!msg->mailbox_data) {
-		kfree(msg);
-		pr_err("kzalloc mailbox_data failed");
-		return -ENOMEM;
-	}
-	*arg = msg;
-	return 0;
-}
-
-/*
- * sst_create_short_msg - create a short IPC message
- *
- * @arg: ipc message
- *
- * this function allocates structures to send a short message to the firmware
- */
-int sst_create_short_msg(struct ipc_post **arg)
-{
-	struct ipc_post *msg;
-
-	msg = kzalloc(sizeof(*msg), GFP_ATOMIC);
-	if (!msg) {
-		pr_err("kzalloc msg failed\n");
-		return -ENOMEM;
-	}
-	msg->mailbox_data = NULL;
-	*arg = msg;
-	return 0;
-}
-
-/*
- * sst_clean_stream - clean the stream context
- *
- * @stream: stream structure
- *
- * this function resets the stream contexts
- * should be called in free
- */
-void sst_clean_stream(struct stream_info *stream)
-{
-	struct sst_stream_bufs *bufs = NULL, *_bufs;
-	stream->status = STREAM_UN_INIT;
-	stream->prev = STREAM_UN_INIT;
-	mutex_lock(&stream->lock);
-	list_for_each_entry_safe(bufs, _bufs, &stream->bufs, node) {
-		list_del(&bufs->node);
-		kfree(bufs);
-	}
-	mutex_unlock(&stream->lock);
-
-	if (stream->ops != STREAM_OPS_PLAYBACK_DRM)
-		kfree(stream->decode_ibuf);
-}
-
-/*
- * sst_wake_up_alloc_block - wake up waiting block
- *
- * @sst_drv_ctx: Driver context
- * @sst_id: stream id
- * @status: status of wakeup
- * @data: data pointer of wakeup
- *
- * This function wakes up a sleeping block event based on the response
- */
-void sst_wake_up_alloc_block(struct intel_sst_drv *sst_drv_ctx,
-		u8 sst_id, int status, void *data)
-{
-	int i;
-
-	/* Unblock with retval code */
-	for (i = 0; i < MAX_ACTIVE_STREAM; i++) {
-		if (sst_id == sst_drv_ctx->alloc_block[i].sst_id) {
-			sst_drv_ctx->alloc_block[i].ops_block.condition = true;
-			sst_drv_ctx->alloc_block[i].ops_block.ret_code = status;
-			sst_drv_ctx->alloc_block[i].ops_block.data = data;
-			wake_up(&sst_drv_ctx->wait_queue);
-			break;
-		}
-	}
-}
-
-/*
- * sst_enable_rx_timeslot - Send msg to query for stream parameters
- * @status: rx timeslot to be enabled
- *
- * This function is called when the RX timeslot is required to be enabled
- */
-int sst_enable_rx_timeslot(int status)
-{
-	int retval = 0;
-	struct ipc_post *msg = NULL;
-
-	if (sst_create_short_msg(&msg)) {
-		pr_err("mem allocation failed\n");
-			return -ENOMEM;
-	}
-	pr_debug("ipc message sending: ENABLE_RX_TIME_SLOT\n");
-	sst_fill_header(&msg->header, IPC_IA_ENABLE_RX_TIME_SLOT, 0, 0);
-	msg->header.part.data = status;
-	sst_drv_ctx->hs_info_blk.condition = false;
-	sst_drv_ctx->hs_info_blk.ret_code = 0;
-	sst_drv_ctx->hs_info_blk.on = true;
-	spin_lock(&sst_drv_ctx->list_spin_lock);
-	list_add_tail(&msg->node,
-			&sst_drv_ctx->ipc_dispatch_list);
-	spin_unlock(&sst_drv_ctx->list_spin_lock);
-	sst_post_message(&sst_drv_ctx->ipc_post_msg_wq);
-	retval = sst_wait_interruptible_timeout(sst_drv_ctx,
-				&sst_drv_ctx->hs_info_blk, SST_BLOCK_TIMEOUT);
-	return retval;
-}
-
diff --git a/drivers/staging/intel_sst/intel_sst_stream.c b/drivers/staging/intel_sst/intel_sst_stream.c
deleted file mode 100644
index be4565e..0000000
--- a/drivers/staging/intel_sst/intel_sst_stream.c
+++ /dev/null
@@ -1,583 +0,0 @@
-/*
- *  intel_sst_stream.c - Intel SST Driver for audio engine
- *
- *  Copyright (C) 2008-10 Intel Corp
- *  Authors:	Vinod Koul <vinod.koul@intel.com>
- *		Harsha Priya <priya.harsha@intel.com>
- *		Dharageswari R <dharageswari.r@intel.com>
- *		KP Jeeja <jeeja.kp@intel.com>
- *  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; version 2 of the License.
- *
- *  This program is distributed in the hope that it will be useful, but
- *  WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *  General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License along
- *  with this program; if not, write to the Free Software Foundation, Inc.,
- *  59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
- *
- * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- *
- *  This file contains the stream operations of SST driver
- */
-
-#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
-
-#include <linux/pci.h>
-#include <linux/firmware.h>
-#include <linux/sched.h>
-#include <linux/delay.h>
-#include "intel_sst_ioctl.h"
-#include "intel_sst.h"
-#include "intel_sst_fw_ipc.h"
-#include "intel_sst_common.h"
-
-/*
- * sst_check_device_type - Check the medfield device type
- *
- * @device: Device to be checked
- * @num_ch: Number of channels queried
- * @pcm_slot: slot to be enabled for this device
- *
- * This checks the deivce against the map and calculates pcm_slot value
- */
-int sst_check_device_type(u32 device, u32 num_chan, u32 *pcm_slot)
-{
-	if (device >= MAX_NUM_STREAMS_MFLD) {
-		pr_debug("device type invalid %d\n", device);
-		return -EINVAL;
-	}
-	if (sst_drv_ctx->streams[device].status == STREAM_UN_INIT) {
-		if (device == SND_SST_DEVICE_VIBRA && num_chan == 1)
-			*pcm_slot = 0x10;
-		else if (device == SND_SST_DEVICE_HAPTIC && num_chan == 1)
-			*pcm_slot = 0x20;
-		else if (device == SND_SST_DEVICE_IHF && num_chan == 1)
-			*pcm_slot = 0x04;
-		else if (device == SND_SST_DEVICE_IHF && num_chan == 2)
-			*pcm_slot = 0x0C;
-		else if (device == SND_SST_DEVICE_HEADSET && num_chan == 1)
-			*pcm_slot = 0x01;
-		else if (device == SND_SST_DEVICE_HEADSET && num_chan == 2)
-			*pcm_slot = 0x03;
-		else if (device == SND_SST_DEVICE_CAPTURE && num_chan == 1)
-			*pcm_slot = 0x01;
-		else if (device == SND_SST_DEVICE_CAPTURE && num_chan == 2)
-			*pcm_slot = 0x03;
-		else if (device == SND_SST_DEVICE_CAPTURE && num_chan == 3)
-			*pcm_slot = 0x07;
-		else if (device == SND_SST_DEVICE_CAPTURE && num_chan == 4)
-			*pcm_slot = 0x0F;
-		else if (device == SND_SST_DEVICE_CAPTURE && num_chan > 4)
-			*pcm_slot = 0x1F;
-		else {
-			pr_debug("No condition satisfied.. ret err\n");
-			return -EINVAL;
-		}
-	} else {
-		pr_debug("this stream state is not uni-init, is %d\n",
-				sst_drv_ctx->streams[device].status);
-		return -EBADRQC;
-	}
-	pr_debug("returning slot %x\n", *pcm_slot);
-	return 0;
-}
-/**
- * get_mrst_stream_id	-	gets a new stream id for use
- *
- * This functions searches the current streams and allocated an empty stream
- * lock stream_lock required to be held before calling this
- */
-static unsigned int get_mrst_stream_id(void)
-{
-	int i;
-
-	for (i = 1; i <= MAX_NUM_STREAMS_MRST; i++) {
-		if (sst_drv_ctx->streams[i].status == STREAM_UN_INIT)
-			return i;
-	}
-	pr_debug("Didn't find empty stream for mrst\n");
-	return -EBUSY;
-}
-
-/**
- * sst_alloc_stream - Send msg for a new stream ID
- *
- * @params:	stream params
- * @stream_ops:	operation of stream PB/capture
- * @codec:	codec for stream
- * @device:	device stream to be allocated for
- *
- * This function is called by any function which wants to start
- * a new stream. This also check if a stream exists which is idle
- * it initializes idle stream id to this request
- */
-int sst_alloc_stream(char *params, unsigned int stream_ops,
-	       u8 codec, unsigned int device)
-{
-	struct ipc_post *msg = NULL;
-	struct snd_sst_alloc_params alloc_param;
-	unsigned int pcm_slot = 0, num_ch;
-	int str_id;
-	struct snd_sst_stream_params *sparams;
-	struct stream_info *str_info;
-
-	pr_debug("SST DBG:entering sst_alloc_stream\n");
-	pr_debug("SST DBG:%d %d %d\n", stream_ops, codec, device);
-
-	BUG_ON(!params);
-	sparams = (struct snd_sst_stream_params *)params;
-	num_ch = sparams->uc.pcm_params.num_chan;
-	/*check the device type*/
-	if (sst_drv_ctx->pci_id == SST_MFLD_PCI_ID) {
-		if (sst_check_device_type(device, num_ch, &pcm_slot))
-			return -EINVAL;
-		mutex_lock(&sst_drv_ctx->stream_lock);
-		str_id = device;
-		mutex_unlock(&sst_drv_ctx->stream_lock);
-		pr_debug("SST_DBG: slot %x\n", pcm_slot);
-	} else {
-		mutex_lock(&sst_drv_ctx->stream_lock);
-		str_id = get_mrst_stream_id();
-		mutex_unlock(&sst_drv_ctx->stream_lock);
-		if (str_id <= 0)
-			return -EBUSY;
-	}
-	/*allocate device type context*/
-	sst_init_stream(&sst_drv_ctx->streams[str_id], codec,
-			str_id, stream_ops, pcm_slot, device);
-	/* send msg to FW to allocate a stream */
-	if (sst_create_large_msg(&msg))
-		return -ENOMEM;
-
-	sst_fill_header(&msg->header, IPC_IA_ALLOC_STREAM, 1, str_id);
-	msg->header.part.data = sizeof(alloc_param) + sizeof(u32);
-	alloc_param.str_type.codec_type = codec;
-	alloc_param.str_type.str_type = SST_STREAM_TYPE_MUSIC;
-	alloc_param.str_type.operation = stream_ops;
-	alloc_param.str_type.protected_str = 0; /* non drm */
-	alloc_param.str_type.time_slots = pcm_slot;
-	alloc_param.str_type.result = alloc_param.str_type.reserved = 0;
-	memcpy(&alloc_param.stream_params, params,
-			sizeof(struct snd_sst_stream_params));
-
-	memcpy(msg->mailbox_data, &msg->header, sizeof(u32));
-	memcpy(msg->mailbox_data + sizeof(u32), &alloc_param,
-			sizeof(alloc_param));
-	str_info = &sst_drv_ctx->streams[str_id];
-	str_info->ctrl_blk.condition = false;
-	str_info->ctrl_blk.ret_code = 0;
-	str_info->ctrl_blk.on = true;
-	spin_lock(&sst_drv_ctx->list_spin_lock);
-	list_add_tail(&msg->node, &sst_drv_ctx->ipc_dispatch_list);
-	spin_unlock(&sst_drv_ctx->list_spin_lock);
-	sst_post_message(&sst_drv_ctx->ipc_post_msg_wq);
-	pr_debug("SST DBG:alloc stream done\n");
-	return str_id;
-}
-
-
-/*
- * sst_alloc_stream_response - process alloc reply
- *
- * @str_id:	stream id for which the stream has been allocated
- * @resp		the stream response from firware
- *
- * This function is called by firmware as a response to stream allcoation
- * request
- */
-int sst_alloc_stream_response(unsigned int str_id,
-				struct snd_sst_alloc_response *resp)
-{
-	int retval = 0;
-	struct stream_info *str_info;
-	struct snd_sst_lib_download *lib_dnld;
-
-	pr_debug("SST DEBUG: stream number given = %d\n", str_id);
-	str_info = &sst_drv_ctx->streams[str_id];
-	if (resp->str_type.result == SST_LIB_ERR_LIB_DNLD_REQUIRED) {
-		lib_dnld = kzalloc(sizeof(*lib_dnld), GFP_KERNEL);
-		memcpy(lib_dnld, &resp->lib_dnld, sizeof(*lib_dnld));
-	} else
-		lib_dnld = NULL;
-	if (str_info->ctrl_blk.on == true) {
-		str_info->ctrl_blk.on = false;
-		str_info->ctrl_blk.data = lib_dnld;
-		str_info->ctrl_blk.condition = true;
-		str_info->ctrl_blk.ret_code = resp->str_type.result;
-		pr_debug("SST DEBUG: sst_alloc_stream_response: waking up.\n");
-		wake_up(&sst_drv_ctx->wait_queue);
-	}
-	return retval;
-}
-
-
-/**
-* sst_get_fw_info - Send msg to query for firmware configurations
-* @info: out param that holds the firmare configurations
-*
-* This function is called when the firmware configurations are queiried for
-*/
-int sst_get_fw_info(struct snd_sst_fw_info *info)
-{
-	int retval = 0;
-	struct ipc_post *msg = NULL;
-
-	pr_debug("SST DBG:sst_get_fw_info called\n");
-
-	if (sst_create_short_msg(&msg)) {
-		pr_err("SST ERR: message creation failed\n");
-		return -ENOMEM;
-	}
-
-	sst_fill_header(&msg->header, IPC_IA_GET_FW_INFO, 0, 0);
-	sst_drv_ctx->fw_info_blk.condition = false;
-	sst_drv_ctx->fw_info_blk.ret_code = 0;
-	sst_drv_ctx->fw_info_blk.on = true;
-	sst_drv_ctx->fw_info_blk.data = info;
-	spin_lock(&sst_drv_ctx->list_spin_lock);
-	list_add_tail(&msg->node, &sst_drv_ctx->ipc_dispatch_list);
-	spin_unlock(&sst_drv_ctx->list_spin_lock);
-	sst_post_message(&sst_drv_ctx->ipc_post_msg_wq);
-	retval = sst_wait_interruptible_timeout(sst_drv_ctx,
-			&sst_drv_ctx->fw_info_blk, SST_BLOCK_TIMEOUT);
-	if (retval) {
-		pr_err("SST ERR: error in fw_info = %d\n", retval);
-		retval = -EIO;
-	}
-	return retval;
-}
-
-
-/**
-* sst_pause_stream - Send msg for a pausing stream
-* @str_id:	 stream ID
-*
-* This function is called by any function which wants to pause
-* an already running stream.
-*/
-int sst_start_stream(int str_id)
-{
-	int retval = 0;
-	struct ipc_post *msg = NULL;
-	struct stream_info *str_info;
-
-	pr_debug("sst_start_stream for %d\n", str_id);
-	retval = sst_validate_strid(str_id);
-	if (retval)
-		return retval;
-	str_info = &sst_drv_ctx->streams[str_id];
-	if (str_info->status != STREAM_INIT)
-		return -EBADRQC;
-	if (sst_create_short_msg(&msg))
-		return -ENOMEM;
-
-	sst_fill_header(&msg->header, IPC_IA_START_STREAM, 0, str_id);
-	spin_lock(&sst_drv_ctx->list_spin_lock);
-	list_add_tail(&msg->node, &sst_drv_ctx->ipc_dispatch_list);
-	spin_unlock(&sst_drv_ctx->list_spin_lock);
-	sst_post_message(&sst_drv_ctx->ipc_post_msg_wq);
-	return retval;
-}
-
-/*
- * sst_pause_stream - Send msg for a pausing stream
- * @str_id:	 stream ID
- *
- * This function is called by any function which wants to pause
- * an already running stream.
- */
-int sst_pause_stream(int str_id)
-{
-	int retval = 0;
-	struct ipc_post *msg = NULL;
-	struct stream_info *str_info;
-
-	pr_debug("SST DBG:sst_pause_stream for %d\n", str_id);
-	retval = sst_validate_strid(str_id);
-	if (retval)
-		return retval;
-	str_info = &sst_drv_ctx->streams[str_id];
-	if (str_info->status == STREAM_PAUSED)
-		return 0;
-	if (str_info->status == STREAM_RUNNING ||
-		str_info->status == STREAM_INIT) {
-		if (str_info->prev == STREAM_UN_INIT)
-			return -EBADRQC;
-		if (str_info->ctrl_blk.on == true) {
-			pr_err("SST ERR: control path is in use\n");
-			return -EINVAL;
-		}
-		if (sst_create_short_msg(&msg))
-			return -ENOMEM;
-
-		sst_fill_header(&msg->header, IPC_IA_PAUSE_STREAM, 0, str_id);
-		str_info->ctrl_blk.condition = false;
-		str_info->ctrl_blk.ret_code = 0;
-		str_info->ctrl_blk.on = true;
-		spin_lock(&sst_drv_ctx->list_spin_lock);
-		list_add_tail(&msg->node,
-				&sst_drv_ctx->ipc_dispatch_list);
-		spin_unlock(&sst_drv_ctx->list_spin_lock);
-		sst_post_message(&sst_drv_ctx->ipc_post_msg_wq);
-		retval = sst_wait_interruptible_timeout(sst_drv_ctx,
-				&str_info->ctrl_blk, SST_BLOCK_TIMEOUT);
-		if (retval == 0) {
-			str_info->prev = str_info->status;
-			str_info->status = STREAM_PAUSED;
-		} else if (retval == SST_ERR_INVALID_STREAM_ID) {
-			retval = -EINVAL;
-			mutex_lock(&sst_drv_ctx->stream_lock);
-			sst_clean_stream(str_info);
-			mutex_unlock(&sst_drv_ctx->stream_lock);
-		}
-	} else {
-		retval = -EBADRQC;
-		pr_err("SST ERR: BADQRC for stream\n");
-	}
-
-	return retval;
-}
-
-/**
- * sst_resume_stream - Send msg for resuming stream
- * @str_id:		stream ID
- *
- * This function is called by any function which wants to resume
- * an already paused stream.
- */
-int sst_resume_stream(int str_id)
-{
-	int retval = 0;
-	struct ipc_post *msg = NULL;
-	struct stream_info *str_info;
-
-	pr_debug("SST DBG:sst_resume_stream for %d\n", str_id);
-	retval = sst_validate_strid(str_id);
-	if (retval)
-		return retval;
-	str_info = &sst_drv_ctx->streams[str_id];
-	if (str_info->status == STREAM_RUNNING)
-			return 0;
-	if (str_info->status == STREAM_PAUSED) {
-		if (str_info->ctrl_blk.on == true) {
-			pr_err("SST ERR: control path in use\n");
-			return -EINVAL;
-		}
-		if (sst_create_short_msg(&msg)) {
-			pr_err("SST ERR: mem allocation failed\n");
-			return -ENOMEM;
-		}
-		sst_fill_header(&msg->header, IPC_IA_RESUME_STREAM, 0, str_id);
-		str_info->ctrl_blk.condition = false;
-		str_info->ctrl_blk.ret_code = 0;
-		str_info->ctrl_blk.on = true;
-		spin_lock(&sst_drv_ctx->list_spin_lock);
-		list_add_tail(&msg->node,
-				&sst_drv_ctx->ipc_dispatch_list);
-		spin_unlock(&sst_drv_ctx->list_spin_lock);
-		sst_post_message(&sst_drv_ctx->ipc_post_msg_wq);
-		retval = sst_wait_interruptible_timeout(sst_drv_ctx,
-				&str_info->ctrl_blk, SST_BLOCK_TIMEOUT);
-		if (!retval) {
-			if (str_info->prev == STREAM_RUNNING)
-				str_info->status = STREAM_RUNNING;
-			else
-				str_info->status = STREAM_INIT;
-			str_info->prev = STREAM_PAUSED;
-		} else if (retval == -SST_ERR_INVALID_STREAM_ID) {
-			retval = -EINVAL;
-			mutex_lock(&sst_drv_ctx->stream_lock);
-			sst_clean_stream(str_info);
-			mutex_unlock(&sst_drv_ctx->stream_lock);
-		}
-	} else {
-		retval = -EBADRQC;
-		pr_err("SST ERR: BADQRC for stream\n");
-	}
-
-	return retval;
-}
-
-
-/**
- * sst_drop_stream - Send msg for stopping stream
- * @str_id:		stream ID
- *
- * This function is called by any function which wants to stop
- * a stream.
- */
-int sst_drop_stream(int str_id)
-{
-	int retval = 0;
-	struct ipc_post *msg = NULL;
-	struct sst_stream_bufs *bufs = NULL, *_bufs;
-	struct stream_info *str_info;
-
-	pr_debug("SST DBG:sst_drop_stream for %d\n", str_id);
-	retval = sst_validate_strid(str_id);
-	if (retval)
-		return retval;
-	str_info = &sst_drv_ctx->streams[str_id];
-
-	if (str_info->status != STREAM_UN_INIT &&
-		str_info->status != STREAM_DECODE) {
-		if (str_info->ctrl_blk.on == true) {
-			pr_err("SST ERR: control path in use\n");
-			return -EINVAL;
-		}
-		if (sst_create_short_msg(&msg)) {
-			pr_err("SST ERR: mem allocation failed\n");
-			return -ENOMEM;
-		}
-		sst_fill_header(&msg->header, IPC_IA_DROP_STREAM, 0, str_id);
-		str_info->ctrl_blk.condition = false;
-		str_info->ctrl_blk.ret_code = 0;
-		str_info->ctrl_blk.on = true;
-		spin_lock(&sst_drv_ctx->list_spin_lock);
-		list_add_tail(&msg->node,
-				&sst_drv_ctx->ipc_dispatch_list);
-		spin_unlock(&sst_drv_ctx->list_spin_lock);
-		sst_post_message(&sst_drv_ctx->ipc_post_msg_wq);
-		retval = sst_wait_interruptible_timeout(sst_drv_ctx,
-				&str_info->ctrl_blk, SST_BLOCK_TIMEOUT);
-		if (!retval) {
-			pr_debug("SST DBG:drop success\n");
-			str_info->prev = STREAM_UN_INIT;
-			str_info->status = STREAM_INIT;
-			if (str_info->src != MAD_DRV) {
-				mutex_lock(&str_info->lock);
-				list_for_each_entry_safe(bufs, _bufs,
-							&str_info->bufs, node) {
-					list_del(&bufs->node);
-					kfree(bufs);
-				}
-				mutex_unlock(&str_info->lock);
-			}
-			str_info->cumm_bytes += str_info->curr_bytes;
-		} else if (retval == -SST_ERR_INVALID_STREAM_ID) {
-			retval = -EINVAL;
-			mutex_lock(&sst_drv_ctx->stream_lock);
-			sst_clean_stream(str_info);
-			mutex_unlock(&sst_drv_ctx->stream_lock);
-		}
-		if (str_info->data_blk.on == true) {
-			str_info->data_blk.condition = true;
-			str_info->data_blk.ret_code = retval;
-			wake_up(&sst_drv_ctx->wait_queue);
-		}
-	} else {
-		retval = -EBADRQC;
-		pr_err("SST ERR: BADQRC for stream\n");
-	}
-	return retval;
-}
-
-/**
-* sst_drain_stream - Send msg for draining stream
-* @str_id:		stream ID
-*
-* This function is called by any function which wants to drain
-* a stream.
-*/
-int sst_drain_stream(int str_id)
-{
-	int retval = 0;
-	struct ipc_post *msg = NULL;
-	struct stream_info *str_info;
-
-	pr_debug("SST DBG:sst_drain_stream for %d\n", str_id);
-	retval = sst_validate_strid(str_id);
-	if (retval)
-		return retval;
-	str_info = &sst_drv_ctx->streams[str_id];
-
-	if (str_info->status != STREAM_RUNNING &&
-		str_info->status != STREAM_INIT &&
-		str_info->status != STREAM_PAUSED) {
-			pr_err("SST ERR: BADQRC for stream = %d\n",
-				       str_info->status);
-			return -EBADRQC;
-	}
-
-	if (str_info->status == STREAM_INIT) {
-		if (sst_create_short_msg(&msg)) {
-			pr_err("SST ERR: mem allocation failed\n");
-			return -ENOMEM;
-		}
-		sst_fill_header(&msg->header, IPC_IA_DRAIN_STREAM, 0, str_id);
-		spin_lock(&sst_drv_ctx->list_spin_lock);
-		list_add_tail(&msg->node, &sst_drv_ctx->ipc_dispatch_list);
-		spin_unlock(&sst_drv_ctx->list_spin_lock);
-		sst_post_message(&sst_drv_ctx->ipc_post_msg_wq);
-	} else
-		str_info->need_draining = true;
-	str_info->data_blk.condition = false;
-	str_info->data_blk.ret_code = 0;
-	str_info->data_blk.on = true;
-	retval = sst_wait_interruptible(sst_drv_ctx, &str_info->data_blk);
-	str_info->need_draining = false;
-	return retval;
-}
-
-/**
- * sst_free_stream - Frees a stream
- * @str_id:		stream ID
- *
- * This function is called by any function which wants to free
- * a stream.
- */
-int sst_free_stream(int str_id)
-{
-	int retval = 0;
-	struct ipc_post *msg = NULL;
-	struct stream_info *str_info;
-
-	pr_debug("SST DBG:sst_free_stream for %d\n", str_id);
-
-	retval = sst_validate_strid(str_id);
-	if (retval)
-		return retval;
-	str_info = &sst_drv_ctx->streams[str_id];
-
-	if (str_info->status != STREAM_UN_INIT) {
-		if (sst_create_short_msg(&msg)) {
-			pr_err("SST ERR: mem allocation failed\n");
-			return -ENOMEM;
-		}
-		sst_fill_header(&msg->header, IPC_IA_FREE_STREAM, 0, str_id);
-		spin_lock(&sst_drv_ctx->list_spin_lock);
-		list_add_tail(&msg->node, &sst_drv_ctx->ipc_dispatch_list);
-		spin_unlock(&sst_drv_ctx->list_spin_lock);
-		sst_post_message(&sst_drv_ctx->ipc_post_msg_wq);
-		str_info->prev =  str_info->status;
-		str_info->status = STREAM_UN_INIT;
-		if (str_info->data_blk.on == true) {
-			str_info->data_blk.condition = true;
-			str_info->data_blk.ret_code = 0;
-			wake_up(&sst_drv_ctx->wait_queue);
-		}
-		str_info->data_blk.on = true;
-		str_info->data_blk.condition = false;
-		retval = sst_wait_interruptible_timeout(sst_drv_ctx,
-				&str_info->ctrl_blk, SST_BLOCK_TIMEOUT);
-		pr_debug("wait for free returned %d\n", retval);
-		msleep(100);
-		mutex_lock(&sst_drv_ctx->stream_lock);
-		sst_clean_stream(str_info);
-		mutex_unlock(&sst_drv_ctx->stream_lock);
-		pr_debug("SST DBG:Stream freed\n");
-	} else {
-		retval = -EBADRQC;
-		pr_debug("SST DBG:BADQRC for stream\n");
-	}
-
-	return retval;
-}
-
-
diff --git a/drivers/staging/intel_sst/intel_sst_stream_encoded.c b/drivers/staging/intel_sst/intel_sst_stream_encoded.c
deleted file mode 100644
index 2be58c5..0000000
--- a/drivers/staging/intel_sst/intel_sst_stream_encoded.c
+++ /dev/null
@@ -1,1273 +0,0 @@
-/*
- *  intel_sst_stream.c - Intel SST Driver for audio engine
- *
- *  Copyright (C) 2008-10 Intel Corp
- *  Authors:	Vinod Koul <vinod.koul@intel.com>
- *		Harsha Priya <priya.harsha@intel.com>
- *		Dharageswari R <dharageswari.r@intel.com>
- *		KP Jeeja <jeeja.kp@intel.com>
- *  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; version 2 of the License.
- *
- *  This program is distributed in the hope that it will be useful, but
- *  WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *  General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License along
- *  with this program; if not, write to the Free Software Foundation, Inc.,
- *  59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
- *
- * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- *
- *  This file contains the stream operations of SST driver
- */
-
-#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
-
-#include <linux/pci.h>
-#include <linux/syscalls.h>
-#include <linux/firmware.h>
-#include <linux/sched.h>
-#ifdef CONFIG_MRST_RAR_HANDLER
-#include <linux/rar_register.h>
-#include "../memrar/memrar.h"
-#endif
-#include "intel_sst_ioctl.h"
-#include "intel_sst.h"
-#include "intel_sst_fw_ipc.h"
-#include "intel_sst_common.h"
-/**
-* sst_get_stream_params - Send msg to query for stream parameters
-* @str_id:	stream id for which the parameters are queried for
-* @get_params:	out parameters to which the parameters are copied to
-*
-* This function is called when the stream parameters are queiried for
-*/
-int sst_get_stream_params(int str_id,
-			struct snd_sst_get_stream_params *get_params)
-{
-	int retval = 0;
-	struct ipc_post *msg = NULL;
-	struct stream_info *str_info;
-	struct snd_sst_fw_get_stream_params *fw_params;
-
-	pr_debug("get_stream for %d\n", str_id);
-	retval = sst_validate_strid(str_id);
-	if (retval)
-		return retval;
-
-	str_info = &sst_drv_ctx->streams[str_id];
-	if (str_info->status != STREAM_UN_INIT) {
-		if (str_info->ctrl_blk.on == true) {
-			pr_err("control path in use\n");
-			return -EINVAL;
-		}
-		if (sst_create_short_msg(&msg)) {
-			pr_err("message creation failed\n");
-			return -ENOMEM;
-		}
-		fw_params = kzalloc(sizeof(*fw_params), GFP_ATOMIC);
-		if (!fw_params) {
-			pr_err("mem allocation failed\n");
-			kfree(msg);
-			return -ENOMEM;
-		}
-
-		sst_fill_header(&msg->header, IPC_IA_GET_STREAM_PARAMS,
-					0, str_id);
-		str_info->ctrl_blk.condition = false;
-		str_info->ctrl_blk.ret_code = 0;
-		str_info->ctrl_blk.on = true;
-		str_info->ctrl_blk.data = (void *) fw_params;
-		spin_lock(&sst_drv_ctx->list_spin_lock);
-		list_add_tail(&msg->node, &sst_drv_ctx->ipc_dispatch_list);
-		spin_unlock(&sst_drv_ctx->list_spin_lock);
-		sst_post_message(&sst_drv_ctx->ipc_post_msg_wq);
-		retval = sst_wait_interruptible_timeout(sst_drv_ctx,
-				&str_info->ctrl_blk, SST_BLOCK_TIMEOUT);
-		if (retval) {
-			get_params->codec_params.result = retval;
-			kfree(fw_params);
-			return -EIO;
-		}
-		memcpy(&get_params->pcm_params, &fw_params->pcm_params,
-				sizeof(fw_params->pcm_params));
-		memcpy(&get_params->codec_params.sparams,
-				&fw_params->codec_params,
-				sizeof(fw_params->codec_params));
-		get_params->codec_params.result = 0;
-		get_params->codec_params.stream_id = str_id;
-		get_params->codec_params.codec = str_info->codec;
-		get_params->codec_params.ops = str_info->ops;
-		get_params->codec_params.stream_type = str_info->str_type;
-		kfree(fw_params);
-	} else {
-		pr_debug("Stream is not in the init state\n");
-	}
-	return retval;
-}
-
-/**
- * sst_set_stream_param - Send msg for setting stream parameters
- *
- * @str_id: stream id
- * @str_param: stream params
- *
- * This function sets stream params during runtime
- */
-int sst_set_stream_param(int str_id, struct snd_sst_params *str_param)
-{
-	int retval = 0;
-	struct ipc_post *msg = NULL;
-	struct stream_info *str_info;
-
-	BUG_ON(!str_param);
-	if (sst_drv_ctx->streams[str_id].ops != str_param->ops) {
-		pr_err("Invalid operation\n");
-		return -EINVAL;
-	}
-	retval = sst_validate_strid(str_id);
-	if (retval)
-		return retval;
-	pr_debug("set_stream for %d\n", str_id);
-	str_info =  &sst_drv_ctx->streams[str_id];
-	if (sst_drv_ctx->streams[str_id].status == STREAM_INIT) {
-		if (str_info->ctrl_blk.on == true) {
-			pr_err("control path in use\n");
-			return -EAGAIN;
-		}
-		if (sst_create_large_msg(&msg))
-			return -ENOMEM;
-
-		sst_fill_header(&msg->header,
-				IPC_IA_SET_STREAM_PARAMS, 1, str_id);
-		str_info->ctrl_blk.condition = false;
-		str_info->ctrl_blk.ret_code = 0;
-		str_info->ctrl_blk.on = true;
-		msg->header.part.data = sizeof(u32) +
-				sizeof(str_param->sparams);
-		memcpy(msg->mailbox_data, &msg->header, sizeof(u32));
-		memcpy(msg->mailbox_data + sizeof(u32), &str_param->sparams,
-				sizeof(str_param->sparams));
-		spin_lock(&sst_drv_ctx->list_spin_lock);
-		list_add_tail(&msg->node, &sst_drv_ctx->ipc_dispatch_list);
-		spin_unlock(&sst_drv_ctx->list_spin_lock);
-		sst_post_message(&sst_drv_ctx->ipc_post_msg_wq);
-		retval = sst_wait_interruptible_timeout(sst_drv_ctx,
-				&str_info->ctrl_blk, SST_BLOCK_TIMEOUT);
-		if (retval < 0) {
-			retval = -EIO;
-			sst_clean_stream(str_info);
-		}
-	} else {
-		retval = -EBADRQC;
-		pr_err("BADQRC for stream\n");
-	}
-	return retval;
-}
-
-/**
-* sst_get_vol - This function allows to get the premix gain or gain of a stream
-*
-* @get_vol: this is an output param through which the volume
-*	structure is passed back to user
-*
-* This function is called when the premix gain or stream gain is queried for
-*/
-int sst_get_vol(struct snd_sst_vol *get_vol)
-{
-	int retval = 0;
-	struct ipc_post *msg = NULL;
-	struct snd_sst_vol *fw_get_vol;
-	int str_id = get_vol->stream_id;
-
-	pr_debug("get vol called\n");
-
-	if (sst_create_short_msg(&msg))
-		return -ENOMEM;
-
-	sst_fill_header(&msg->header,
-				IPC_IA_GET_STREAM_VOL, 0, str_id);
-	sst_drv_ctx->vol_info_blk.condition = false;
-	sst_drv_ctx->vol_info_blk.ret_code = 0;
-	sst_drv_ctx->vol_info_blk.on = true;
-	fw_get_vol = kzalloc(sizeof(*fw_get_vol), GFP_ATOMIC);
-	if (!fw_get_vol) {
-		pr_err("mem allocation failed\n");
-		kfree(msg);
-		return -ENOMEM;
-	}
-	sst_drv_ctx->vol_info_blk.data = (void *)fw_get_vol;
-	spin_lock(&sst_drv_ctx->list_spin_lock);
-	list_add_tail(&msg->node, &sst_drv_ctx->ipc_dispatch_list);
-	spin_unlock(&sst_drv_ctx->list_spin_lock);
-	sst_post_message(&sst_drv_ctx->ipc_post_msg_wq);
-	retval = sst_wait_interruptible_timeout(sst_drv_ctx,
-			&sst_drv_ctx->vol_info_blk, SST_BLOCK_TIMEOUT);
-	if (retval)
-		retval = -EIO;
-	else {
-		pr_debug("stream id %d\n", fw_get_vol->stream_id);
-		pr_debug("volume %d\n", fw_get_vol->volume);
-		pr_debug("ramp duration %d\n", fw_get_vol->ramp_duration);
-		pr_debug("ramp_type %d\n", fw_get_vol->ramp_type);
-		memcpy(get_vol, fw_get_vol, sizeof(*fw_get_vol));
-	}
-	return retval;
-}
-
-/**
-* sst_set_vol - This function allows to set the premix gain or gain of a stream
-*
-* @set_vol:	this holds the volume structure that needs to be set
-*
-* This function is called when premix gain or stream gain is requested to be set
-*/
-int sst_set_vol(struct snd_sst_vol *set_vol)
-{
-
-	int retval = 0;
-	struct ipc_post *msg = NULL;
-
-	pr_debug("set vol called\n");
-
-	if (sst_create_large_msg(&msg)) {
-		pr_err("message creation failed\n");
-		return -ENOMEM;
-	}
-	sst_fill_header(&msg->header, IPC_IA_SET_STREAM_VOL, 1,
-				set_vol->stream_id);
-
-	msg->header.part.data = sizeof(u32) + sizeof(*set_vol);
-	memcpy(msg->mailbox_data, &msg->header, sizeof(u32));
-	memcpy(msg->mailbox_data + sizeof(u32), set_vol, sizeof(*set_vol));
-	sst_drv_ctx->vol_info_blk.condition = false;
-	sst_drv_ctx->vol_info_blk.ret_code = 0;
-	sst_drv_ctx->vol_info_blk.on = true;
-	sst_drv_ctx->vol_info_blk.data = set_vol;
-	spin_lock(&sst_drv_ctx->list_spin_lock);
-	list_add_tail(&msg->node, &sst_drv_ctx->ipc_dispatch_list);
-	spin_unlock(&sst_drv_ctx->list_spin_lock);
-	sst_post_message(&sst_drv_ctx->ipc_post_msg_wq);
-	retval = sst_wait_interruptible_timeout(sst_drv_ctx,
-			&sst_drv_ctx->vol_info_blk, SST_BLOCK_TIMEOUT);
-	if (retval) {
-		pr_err("error in set_vol = %d\n", retval);
-		retval = -EIO;
-	}
-	return retval;
-}
-
-/**
-* sst_set_mute - This function sets premix mute or soft mute of a stream
-*
-* @set_mute:	this holds the mute structure that needs to be set
-*
-* This function is called when premix mute or stream mute requested to be set
-*/
-int sst_set_mute(struct snd_sst_mute *set_mute)
-{
-
-	int retval = 0;
-	struct ipc_post *msg = NULL;
-
-	pr_debug("set mute called\n");
-
-	if (sst_create_large_msg(&msg)) {
-		pr_err("message creation failed\n");
-		return -ENOMEM;
-	}
-	sst_fill_header(&msg->header, IPC_IA_SET_STREAM_MUTE, 1,
-				set_mute->stream_id);
-	sst_drv_ctx->mute_info_blk.condition = false;
-	sst_drv_ctx->mute_info_blk.ret_code = 0;
-	sst_drv_ctx->mute_info_blk.on = true;
-	sst_drv_ctx->mute_info_blk.data = set_mute;
-
-	msg->header.part.data = sizeof(u32) + sizeof(*set_mute);
-	memcpy(msg->mailbox_data, &msg->header, sizeof(u32));
-	memcpy(msg->mailbox_data + sizeof(u32), set_mute,
-			sizeof(*set_mute));
-	spin_lock(&sst_drv_ctx->list_spin_lock);
-	list_add_tail(&msg->node, &sst_drv_ctx->ipc_dispatch_list);
-	spin_unlock(&sst_drv_ctx->list_spin_lock);
-	sst_post_message(&sst_drv_ctx->ipc_post_msg_wq);
-	retval = sst_wait_interruptible_timeout(sst_drv_ctx,
-			&sst_drv_ctx->mute_info_blk, SST_BLOCK_TIMEOUT);
-	if (retval) {
-		pr_err("error in set_mute = %d\n", retval);
-		retval = -EIO;
-	}
-	return retval;
-}
-
-int sst_prepare_target(struct snd_sst_slot_info *slot)
-{
-	if (slot->target_device == SND_SST_TARGET_PMIC
-		&& slot->device_instance == 1) {
-			/*music mode*/
-			if (sst_drv_ctx->pmic_port_instance == 0)
-				sst_drv_ctx->scard_ops->set_voice_port(
-					DEACTIVATE);
-	} else if ((slot->target_device == SND_SST_TARGET_PMIC ||
-			slot->target_device == SND_SST_TARGET_MODEM) &&
-			slot->device_instance == 0) {
-				/*voip mode where pcm0 is active*/
-				if (sst_drv_ctx->pmic_port_instance == 1)
-					sst_drv_ctx->scard_ops->set_audio_port(
-						DEACTIVATE);
-	}
-	return 0;
-}
-
-int sst_activate_target(struct snd_sst_slot_info *slot)
-{
-	if (slot->target_device == SND_SST_TARGET_PMIC &&
-		slot->device_instance == 1) {
-			/*music mode*/
-			sst_drv_ctx->pmic_port_instance = 1;
-			sst_drv_ctx->scard_ops->set_audio_port(ACTIVATE);
-			sst_drv_ctx->scard_ops->set_pcm_audio_params(
-				slot->pcm_params.sfreq,
-				slot->pcm_params.pcm_wd_sz,
-				slot->pcm_params.num_chan);
-			if (sst_drv_ctx->pb_streams)
-				sst_drv_ctx->scard_ops->power_up_pmic_pb(1);
-			if (sst_drv_ctx->cp_streams)
-				sst_drv_ctx->scard_ops->power_up_pmic_cp(1);
-	} else if ((slot->target_device == SND_SST_TARGET_PMIC ||
-			slot->target_device == SND_SST_TARGET_MODEM) &&
-			slot->device_instance == 0) {
-				/*voip mode where pcm0 is active*/
-				sst_drv_ctx->pmic_port_instance = 0;
-				sst_drv_ctx->scard_ops->set_voice_port(
-					ACTIVATE);
-				sst_drv_ctx->scard_ops->power_up_pmic_pb(0);
-				/*sst_drv_ctx->scard_ops->power_up_pmic_cp(0);*/
-	}
-	return 0;
-}
-
-int sst_parse_target(struct snd_sst_slot_info *slot)
-{
-	int retval = 0;
-
-	if (slot->action == SND_SST_PORT_ACTIVATE &&
-		slot->device_type == SND_SST_DEVICE_PCM) {
-			retval = sst_activate_target(slot);
-			if (retval)
-				pr_err("SST_Activate_target_fail\n");
-			else
-				pr_err("SST_Activate_target_pass\n");
-	} else if (slot->action == SND_SST_PORT_PREPARE &&
-			slot->device_type == SND_SST_DEVICE_PCM) {
-				retval = sst_prepare_target(slot);
-			if (retval)
-				pr_err("SST_prepare_target_fail\n");
-			else
-				pr_err("SST_prepare_target_pass\n");
-	} else {
-		pr_err("slot_action : %d, device_type: %d\n",
-				slot->action, slot->device_type);
-	}
-	return retval;
-}
-
-int sst_send_target(struct snd_sst_target_device *target)
-{
-	int retval;
-	struct ipc_post *msg;
-
-	if (sst_create_large_msg(&msg)) {
-		pr_err("message creation failed\n");
-		return -ENOMEM;
-	}
-	sst_fill_header(&msg->header, IPC_IA_TARGET_DEV_SELECT, 1, 0);
-	sst_drv_ctx->tgt_dev_blk.condition = false;
-	sst_drv_ctx->tgt_dev_blk.ret_code = 0;
-	sst_drv_ctx->tgt_dev_blk.on = true;
-
-	msg->header.part.data = sizeof(u32) + sizeof(*target);
-	memcpy(msg->mailbox_data, &msg->header, sizeof(u32));
-	memcpy(msg->mailbox_data + sizeof(u32), target,
-			sizeof(*target));
-	spin_lock(&sst_drv_ctx->list_spin_lock);
-	list_add_tail(&msg->node, &sst_drv_ctx->ipc_dispatch_list);
-	spin_unlock(&sst_drv_ctx->list_spin_lock);
-	sst_post_message(&sst_drv_ctx->ipc_post_msg_wq);
-	pr_debug("message sent- waiting\n");
-	retval = sst_wait_interruptible_timeout(sst_drv_ctx,
-			&sst_drv_ctx->tgt_dev_blk, TARGET_DEV_BLOCK_TIMEOUT);
-	if (retval)
-		pr_err("target device ipc failed = 0x%x\n", retval);
-	return retval;
-
-}
-
-int sst_target_device_validate(struct snd_sst_target_device *target)
-{
-	int retval = 0;
-       int i;
-
-	for (i = 0; i < SST_MAX_TARGET_DEVICES; i++) {
-		if (target->devices[i].device_type == SND_SST_DEVICE_PCM) {
-			/*pcm device, check params*/
-			if (target->devices[i].device_instance == 1) {
-				if ((target->devices[i].device_mode !=
-				SND_SST_DEV_MODE_PCM_MODE4_I2S) &&
-				(target->devices[i].device_mode !=
-				SND_SST_DEV_MODE_PCM_MODE4_RIGHT_JUSTIFIED)
-				&& (target->devices[i].device_mode !=
-				SND_SST_DEV_MODE_PCM_MODE1))
-					goto err;
-			} else if (target->devices[i].device_instance == 0) {
-				if ((target->devices[i].device_mode !=
-						SND_SST_DEV_MODE_PCM_MODE2)
-					&& (target->devices[i].device_mode !=
-						SND_SST_DEV_MODE_PCM_MODE4_I2S)
-					&& (target->devices[i].device_mode !=
-						SND_SST_DEV_MODE_PCM_MODE1))
-					goto err;
-				if (target->devices[i].pcm_params.sfreq != 8000
-				|| target->devices[i].pcm_params.num_chan != 1
-				|| target->devices[i].pcm_params.pcm_wd_sz !=
-									16)
-					goto err;
-			} else {
-err:
-				pr_err("i/p params incorrect\n");
-				return -EINVAL;
-			}
-		}
-	}
-    return retval;
-}
-
-/**
- * sst_target_device_select - This function sets the target device configurations
- *
- * @target: this parameter holds the configurations to be set
- *
- * This function is called when the user layer wants to change the target
- * device's configurations
- */
-
-int sst_target_device_select(struct snd_sst_target_device *target)
-{
-	int retval, i, prepare_count = 0;
-
-	pr_debug("Target Device Select\n");
-
-	if (target->device_route < 0 || target->device_route > 2) {
-		pr_err("device route is invalid\n");
-		return -EINVAL;
-	}
-
-	if (target->device_route != 0) {
-		pr_err("Unsupported config\n");
-		return -EIO;
-	}
-	retval = sst_target_device_validate(target);
-	if (retval)
-		return retval;
-
-	retval = sst_send_target(target);
-	if (retval)
-		return retval;
-	for (i = 0; i < SST_MAX_TARGET_DEVICES; i++) {
-		if (target->devices[i].action == SND_SST_PORT_ACTIVATE) {
-			pr_debug("activate called in %d\n", i);
-			retval = sst_parse_target(&target->devices[i]);
-			if (retval)
-				return retval;
-		} else if (target->devices[i].action == SND_SST_PORT_PREPARE) {
-			pr_debug("PREPARE in %d, Forwarding\n", i);
-			retval = sst_parse_target(&target->devices[i]);
-			if (retval) {
-				pr_err("Parse Target fail %d\n", retval);
-				return retval;
-			}
-			pr_debug("Parse Target successful %d\n", retval);
-			if (target->devices[i].device_type ==
-						SND_SST_DEVICE_PCM)
-				prepare_count++;
-		}
-	}
-	if (target->devices[0].action == SND_SST_PORT_PREPARE &&
-		prepare_count == 0)
-			sst_drv_ctx->scard_ops->power_down_pmic();
-
-	return retval;
-}
-#ifdef CONFIG_MRST_RAR_HANDLER
-/*This function gets the physical address of the secure memory from the handle*/
-static inline int sst_get_RAR(struct RAR_buffer *buffers, int count)
-{
-	int retval = 0, rar_status = 0;
-
-	rar_status = rar_handle_to_bus(buffers, count);
-
-	if (count != rar_status) {
-		pr_err("The rar CALL Failed");
-		retval = -EIO;
-	}
-	if (buffers->info.type != RAR_TYPE_AUDIO) {
-		pr_err("Invalid RAR type\n");
-		return -EINVAL;
-	}
-	return retval;
-}
-
-#endif
-
-/* This function creates the scatter gather list to be sent to firmware to
-capture/playback data*/
-static int sst_create_sg_list(struct stream_info *stream,
-		struct sst_frame_info *sg_list)
-{
-	struct sst_stream_bufs *kbufs = NULL;
-#ifdef CONFIG_MRST_RAR_HANDLER
-	struct RAR_buffer rar_buffers;
-	int retval = 0;
-#endif
-	int i = 0;
-	list_for_each_entry(kbufs, &stream->bufs, node) {
-		if (kbufs->in_use == false) {
-#ifdef CONFIG_MRST_RAR_HANDLER
-			if (stream->ops == STREAM_OPS_PLAYBACK_DRM) {
-				pr_debug("DRM playback handling\n");
-				rar_buffers.info.handle = (__u32)kbufs->addr;
-				rar_buffers.info.size = kbufs->size;
-				pr_debug("rar handle 0x%x size=0x%x\n",
-					rar_buffers.info.handle,
-					rar_buffers.info.size);
-				retval =  sst_get_RAR(&rar_buffers, 1);
-
-				if (retval)
-					return retval;
-				sg_list->addr[i].addr = rar_buffers.bus_address;
-				/* rar_buffers.info.size; */
-				sg_list->addr[i].size = (__u32)kbufs->size;
-				pr_debug("phyaddr[%d] 0x%x Size:0x%x\n"
-					, i, sg_list->addr[i].addr,
-					sg_list->addr[i].size);
-			}
-#endif
-			if (stream->ops != STREAM_OPS_PLAYBACK_DRM) {
-				sg_list->addr[i].addr =
-					virt_to_phys((void *)
-						kbufs->addr + kbufs->offset);
-				sg_list->addr[i].size = kbufs->size;
-				pr_debug("phyaddr[%d]:0x%x Size:0x%x\n"
-				, i , sg_list->addr[i].addr, kbufs->size);
-			}
-			stream->curr_bytes += sg_list->addr[i].size;
-			kbufs->in_use = true;
-			i++;
-		}
-		if (i >= MAX_NUM_SCATTER_BUFFERS)
-			break;
-	}
-
-	sg_list->num_entries = i;
-	pr_debug("sg list entries = %d\n", sg_list->num_entries);
-	return i;
-}
-
-
-/**
- * sst_play_frame - Send msg for sending stream frames
- *
- * @str_id:	ID of stream
- *
- * This function is called to send data to be played out
- * to the firmware
- */
-int sst_play_frame(int str_id)
-{
-	int i = 0, retval = 0;
-	struct ipc_post *msg = NULL;
-	struct sst_frame_info sg_list = {0};
-	struct sst_stream_bufs *kbufs = NULL, *_kbufs;
-	struct stream_info *stream;
-
-	pr_debug("play frame for %d\n", str_id);
-	retval = sst_validate_strid(str_id);
-	if (retval)
-		return retval;
-
-	stream = &sst_drv_ctx->streams[str_id];
-	/* clear prev sent buffers */
-	list_for_each_entry_safe(kbufs, _kbufs, &stream->bufs, node) {
-		if (kbufs->in_use == true) {
-			spin_lock(&stream->pcm_lock);
-			list_del(&kbufs->node);
-			spin_unlock(&stream->pcm_lock);
-			kfree(kbufs);
-		}
-	}
-	/* update bytes sent */
-	stream->cumm_bytes += stream->curr_bytes;
-	stream->curr_bytes = 0;
-	if (list_empty(&stream->bufs)) {
-		/* no user buffer available */
-		pr_debug("Null buffer stream status %d\n", stream->status);
-		stream->prev = stream->status;
-		stream->status = STREAM_INIT;
-		pr_debug("new stream status = %d\n", stream->status);
-		if (stream->need_draining == true) {
-			pr_debug("draining stream\n");
-			if (sst_create_short_msg(&msg)) {
-				pr_err("mem allocation failed\n");
-				return -ENOMEM;
-			}
-			sst_fill_header(&msg->header, IPC_IA_DRAIN_STREAM,
-						0, str_id);
-			spin_lock(&sst_drv_ctx->list_spin_lock);
-			list_add_tail(&msg->node,
-					&sst_drv_ctx->ipc_dispatch_list);
-			spin_unlock(&sst_drv_ctx->list_spin_lock);
-			sst_post_message(&sst_drv_ctx->ipc_post_msg_wq);
-		} else if (stream->data_blk.on == true) {
-			pr_debug("user list empty.. wake\n");
-			/* unblock */
-			stream->data_blk.ret_code = 0;
-			stream->data_blk.condition = true;
-			stream->data_blk.on = false;
-			wake_up(&sst_drv_ctx->wait_queue);
-		}
-		return 0;
-	}
-
-	/* create list */
-	i = sst_create_sg_list(stream, &sg_list);
-
-	/* post msg */
-	if (sst_create_large_msg(&msg))
-		return -ENOMEM;
-
-	sst_fill_header(&msg->header, IPC_IA_PLAY_FRAMES, 1, str_id);
-	msg->header.part.data = sizeof(u32) + sizeof(sg_list);
-	memcpy(msg->mailbox_data, &msg->header, sizeof(u32));
-	memcpy(msg->mailbox_data + sizeof(u32), &sg_list, sizeof(sg_list));
-	spin_lock(&sst_drv_ctx->list_spin_lock);
-	list_add_tail(&msg->node, &sst_drv_ctx->ipc_dispatch_list);
-	spin_unlock(&sst_drv_ctx->list_spin_lock);
-	sst_post_message(&sst_drv_ctx->ipc_post_msg_wq);
-	return 0;
-
-}
-
-/**
- * sst_capture_frame - Send msg for sending stream frames
- *
- * @str_id:	ID of stream
- *
- * This function is called to capture data from the firmware
- */
-int sst_capture_frame(int str_id)
-{
-	int i = 0, retval = 0;
-	struct ipc_post *msg = NULL;
-	struct sst_frame_info sg_list = {0};
-	struct sst_stream_bufs *kbufs = NULL, *_kbufs;
-	struct stream_info *stream;
-
-
-	pr_debug("capture frame for %d\n", str_id);
-	retval = sst_validate_strid(str_id);
-	if (retval)
-		return retval;
-	stream = &sst_drv_ctx->streams[str_id];
-	/* clear prev sent buffers */
-	list_for_each_entry_safe(kbufs, _kbufs, &stream->bufs, node) {
-		if (kbufs->in_use == true) {
-			list_del(&kbufs->node);
-			kfree(kbufs);
-			pr_debug("del node\n");
-		}
-	}
-	if (list_empty(&stream->bufs)) {
-		/* no user buffer available */
-		pr_debug("Null buffer!!!!stream status %d\n",
-			       stream->status);
-		stream->prev = stream->status;
-		stream->status = STREAM_INIT;
-		pr_debug("new stream status = %d\n",
-			       stream->status);
-		if (stream->data_blk.on == true) {
-			pr_debug("user list empty.. wake\n");
-			/* unblock */
-			stream->data_blk.ret_code = 0;
-			stream->data_blk.condition = true;
-			stream->data_blk.on = false;
-			wake_up(&sst_drv_ctx->wait_queue);
-
-		}
-		return 0;
-	}
-	/* create new sg list */
-	i = sst_create_sg_list(stream, &sg_list);
-
-	/* post msg */
-	if (sst_create_large_msg(&msg))
-		return -ENOMEM;
-
-	sst_fill_header(&msg->header, IPC_IA_CAPT_FRAMES, 1, str_id);
-	msg->header.part.data = sizeof(u32) + sizeof(sg_list);
-	memcpy(msg->mailbox_data, &msg->header, sizeof(u32));
-	memcpy(msg->mailbox_data + sizeof(u32), &sg_list, sizeof(sg_list));
-	spin_lock(&sst_drv_ctx->list_spin_lock);
-	list_add_tail(&msg->node, &sst_drv_ctx->ipc_dispatch_list);
-	spin_unlock(&sst_drv_ctx->list_spin_lock);
-	sst_post_message(&sst_drv_ctx->ipc_post_msg_wq);
-
-
-	/*update bytes recevied*/
-	stream->cumm_bytes += stream->curr_bytes;
-	stream->curr_bytes = 0;
-
-    pr_debug("Cum bytes  = %d\n", stream->cumm_bytes);
-	return 0;
-}
-
-/*This function is used to calculate the minimum size of input buffers given*/
-static unsigned int calculate_min_size(struct snd_sst_buffs *bufs)
-{
-	int i, min_val = bufs->buff_entry[0].size;
-	for (i = 1 ; i < bufs->entries; i++) {
-		if (bufs->buff_entry[i].size < min_val)
-			min_val = bufs->buff_entry[i].size;
-	}
-	pr_debug("min_val = %d\n", min_val);
-	return min_val;
-}
-
-static unsigned int calculate_max_size(struct snd_sst_buffs *bufs)
-{
-	int i, max_val = bufs->buff_entry[0].size;
-	for (i = 1 ; i < bufs->entries; i++) {
-		if (bufs->buff_entry[i].size > max_val)
-			max_val = bufs->buff_entry[i].size;
-	}
-	pr_debug("max_val = %d\n", max_val);
-	return max_val;
-}
-
-/*This function is used to allocate input and output buffers to be sent to
-the firmware that will take encoded data and return decoded data*/
-static int sst_allocate_decode_buf(struct stream_info *str_info,
-				struct snd_sst_dbufs *dbufs,
-				unsigned int cum_input_given,
-				unsigned int cum_output_given)
-{
-#ifdef CONFIG_MRST_RAR_HANDLER
-	if (str_info->ops == STREAM_OPS_PLAYBACK_DRM) {
-
-		if (dbufs->ibufs->type == SST_BUF_RAR  &&
-			dbufs->obufs->type == SST_BUF_RAR) {
-			if (dbufs->ibufs->entries == dbufs->obufs->entries)
-				return 0;
-			else {
-				pr_err("RAR entries dont match\n");
-				 return -EINVAL;
-			}
-		} else
-			str_info->decode_osize = cum_output_given;
-		return 0;
-
-	}
-#endif
-	if (!str_info->decode_ibuf) {
-		pr_debug("no i/p buffers, trying full size\n");
-		str_info->decode_isize = cum_input_given;
-		str_info->decode_ibuf = kzalloc(str_info->decode_isize,
-						GFP_KERNEL);
-		str_info->idecode_alloc = str_info->decode_isize;
-	}
-	if (!str_info->decode_ibuf) {
-		pr_debug("buff alloc failed, try max size\n");
-		str_info->decode_isize = calculate_max_size(dbufs->ibufs);
-		str_info->decode_ibuf = kzalloc(
-				str_info->decode_isize, GFP_KERNEL);
-		str_info->idecode_alloc = str_info->decode_isize;
-	}
-	if (!str_info->decode_ibuf) {
-		pr_debug("buff alloc failed, try min size\n");
-		str_info->decode_isize = calculate_min_size(dbufs->ibufs);
-		str_info->decode_ibuf = kzalloc(str_info->decode_isize,
-						GFP_KERNEL);
-		if (!str_info->decode_ibuf) {
-			pr_err("mem allocation failed\n");
-			return -ENOMEM;
-		}
-		str_info->idecode_alloc = str_info->decode_isize;
-	}
-	str_info->decode_osize = cum_output_given;
-	if (str_info->decode_osize > sst_drv_ctx->mmap_len)
-		str_info->decode_osize = sst_drv_ctx->mmap_len;
-	return 0;
-}
-
-/*This function is used to send the message to firmware to decode the data*/
-static int sst_send_decode_mess(int str_id, struct stream_info *str_info,
-				struct snd_sst_decode_info *dec_info)
-{
-	struct ipc_post *msg = NULL;
-	int retval = 0;
-
-	pr_debug("SST DBG:sst_set_mute:called\n");
-
-	if (str_info->decode_ibuf_type == SST_BUF_RAR) {
-#ifdef CONFIG_MRST_RAR_HANDLER
-			dec_info->frames_in.addr[0].addr =
-				(unsigned long)str_info->decode_ibuf;
-			dec_info->frames_in.addr[0].size =
-							str_info->decode_isize;
-#endif
-
-	} else {
-		dec_info->frames_in.addr[0].addr = virt_to_phys((void *)
-					str_info->decode_ibuf);
-		dec_info->frames_in.addr[0].size = str_info->decode_isize;
-	}
-
-
-	if (str_info->decode_obuf_type == SST_BUF_RAR) {
-#ifdef CONFIG_MRST_RAR_HANDLER
-		dec_info->frames_out.addr[0].addr =
-				(unsigned long)str_info->decode_obuf;
-		dec_info->frames_out.addr[0].size = str_info->decode_osize;
-#endif
-
-	} else {
-		dec_info->frames_out.addr[0].addr = virt_to_phys((void *)
-						str_info->decode_obuf) ;
-		dec_info->frames_out.addr[0].size = str_info->decode_osize;
-	}
-
-	dec_info->frames_in.num_entries = 1;
-	dec_info->frames_out.num_entries = 1;
-	dec_info->frames_in.rsrvd = 0;
-	dec_info->frames_out.rsrvd = 0;
-	dec_info->input_bytes_consumed = 0;
-	dec_info->output_bytes_produced = 0;
-	if (sst_create_large_msg(&msg)) {
-		pr_err("message creation failed\n");
-		return -ENOMEM;
-	}
-
-	sst_fill_header(&msg->header, IPC_IA_DECODE_FRAMES, 1, str_id);
-	msg->header.part.data = sizeof(u32) + sizeof(*dec_info);
-	memcpy(msg->mailbox_data, &msg->header, sizeof(u32));
-	memcpy(msg->mailbox_data + sizeof(u32), dec_info,
-			sizeof(*dec_info));
-	spin_lock(&sst_drv_ctx->list_spin_lock);
-	list_add_tail(&msg->node, &sst_drv_ctx->ipc_dispatch_list);
-	spin_unlock(&sst_drv_ctx->list_spin_lock);
-	str_info->data_blk.condition = false;
-	str_info->data_blk.ret_code = 0;
-	str_info->data_blk.on = true;
-	str_info->data_blk.data = dec_info;
-	sst_post_message(&sst_drv_ctx->ipc_post_msg_wq);
-	retval = sst_wait_interruptible(sst_drv_ctx, &str_info->data_blk);
-	return retval;
-}
-
-#ifdef CONFIG_MRST_RAR_HANDLER
-static int sst_prepare_input_buffers_rar(struct stream_info *str_info,
-			struct snd_sst_dbufs *dbufs,
-			int *input_index, int *in_copied,
-			int *input_index_valid_size, int *new_entry_flag)
-{
-	int retval = 0, i;
-
-	if (str_info->ops == STREAM_OPS_PLAYBACK_DRM) {
-		struct RAR_buffer rar_buffers;
-		__u32 info;
-		retval = copy_from_user((void *) &info,
-				dbufs->ibufs->buff_entry[i].buffer,
-				sizeof(__u32));
-		if (retval) {
-			pr_err("cpy from user fail\n");
-			return -EAGAIN;
-		}
-		rar_buffers.info.type = dbufs->ibufs->type;
-		rar_buffers.info.size = dbufs->ibufs->buff_entry[i].size;
-		rar_buffers.info.handle =  info;
-		pr_debug("rar in DnR(input buffer function)=0x%x size=0x%x",
-				rar_buffers.info.handle,
-				rar_buffers.info.size);
-		retval =  sst_get_RAR(&rar_buffers, 1);
-		if (retval) {
-			pr_debug("SST ERR: RAR API failed\n");
-			return retval;
-		}
-		str_info->decode_ibuf =
-		(void *) ((unsigned long) rar_buffers.bus_address);
-		pr_debug("RAR buf addr in DnR (input buffer function)0x%lu",
-				 (unsigned long) str_info->decode_ibuf);
-		pr_debug("rar in DnR decode function/output b_add rar =0x%lu",
-				(unsigned long) rar_buffers.bus_address);
-		*input_index = i + 1;
-		str_info->decode_isize = dbufs->ibufs->buff_entry[i].size;
-		str_info->decode_ibuf_type = dbufs->ibufs->type;
-		*in_copied = str_info->decode_isize;
-	}
-	return retval;
-}
-#endif
-/*This function is used to prepare the kernel input buffers with contents
-before sending for decode*/
-static int sst_prepare_input_buffers(struct stream_info *str_info,
-			struct snd_sst_dbufs *dbufs,
-			int *input_index, int *in_copied,
-			int *input_index_valid_size, int *new_entry_flag)
-{
-	int i, cpy_size, retval = 0;
-
-	pr_debug("input_index = %d, input entries = %d\n",
-			 *input_index, dbufs->ibufs->entries);
-	for (i = *input_index; i < dbufs->ibufs->entries; i++) {
-#ifdef CONFIG_MRST_RAR_HANDLER
-		retval = sst_prepare_input_buffers_rar(str_info,
-			dbufs, input_index, in_copied,
-				input_index_valid_size, new_entry_flag);
-		if (retval) {
-			pr_err("In prepare input buffers for RAR\n");
-			return -EIO;
-		}
-#endif
-		*input_index = i;
-		if (*input_index_valid_size == 0)
-			*input_index_valid_size =
-				dbufs->ibufs->buff_entry[i].size;
-		pr_debug("inout addr = %p, size = %d\n",
-			dbufs->ibufs->buff_entry[i].buffer,
-			*input_index_valid_size);
-		pr_debug("decode_isize = %d, in_copied %d\n",
-			str_info->decode_isize, *in_copied);
-		if (*input_index_valid_size <=
-					(str_info->decode_isize - *in_copied))
-			cpy_size = *input_index_valid_size;
-		else
-			cpy_size = str_info->decode_isize - *in_copied;
-
-		pr_debug("cpy size = %d\n", cpy_size);
-		if (!dbufs->ibufs->buff_entry[i].buffer) {
-			pr_err("i/p buffer is null\n");
-			return -EINVAL;
-		}
-		pr_debug("Try copy To %p, From %p, size %d\n",
-				str_info->decode_ibuf + *in_copied,
-				dbufs->ibufs->buff_entry[i].buffer, cpy_size);
-
-		retval =
-		copy_from_user((void *)(str_info->decode_ibuf + *in_copied),
-				(void *) dbufs->ibufs->buff_entry[i].buffer,
-				cpy_size);
-		if (retval) {
-			pr_err("copy from user failed\n");
-			return -EIO;
-		}
-		*in_copied += cpy_size;
-		*input_index_valid_size -= cpy_size;
-		pr_debug("in buff size = %d, in_copied = %d\n",
-			*input_index_valid_size, *in_copied);
-		if (*input_index_valid_size != 0) {
-			pr_debug("more input buffers left\n");
-			dbufs->ibufs->buff_entry[i].buffer += cpy_size;
-			break;
-		}
-		if (*in_copied == str_info->decode_isize &&
-			*input_index_valid_size == 0 &&
-			(i+1) <= dbufs->ibufs->entries) {
-			pr_debug("all input buffers copied\n");
-			*new_entry_flag = true;
-			*input_index = i + 1;
-			break;
-		}
-	}
-	return retval;
-}
-
-/* This function is used to copy the decoded data from kernel buffers to
-the user output buffers with contents after decode*/
-static int sst_prepare_output_buffers(struct stream_info *str_info,
-			struct snd_sst_dbufs *dbufs,
-			int *output_index, int output_size,
-			int *out_copied)
-
-{
-	int i, cpy_size, retval = 0;
-	pr_debug("output_index = %d, output entries = %d\n",
-				*output_index,
-				dbufs->obufs->entries);
-	for (i = *output_index; i < dbufs->obufs->entries; i++) {
-		*output_index = i;
-		pr_debug("output addr = %p, size = %d\n",
-			dbufs->obufs->buff_entry[i].buffer,
-			dbufs->obufs->buff_entry[i].size);
-		pr_debug("output_size = %d, out_copied = %d\n",
-				output_size, *out_copied);
-		if (dbufs->obufs->buff_entry[i].size <
-				(output_size - *out_copied))
-			cpy_size = dbufs->obufs->buff_entry[i].size;
-		else
-			cpy_size = output_size - *out_copied;
-		pr_debug("cpy size = %d\n", cpy_size);
-		pr_debug("Try copy To: %p, From %p, size %d\n",
-				dbufs->obufs->buff_entry[i].buffer,
-				sst_drv_ctx->mmap_mem + *out_copied,
-				cpy_size);
-		retval = copy_to_user(dbufs->obufs->buff_entry[i].buffer,
-					sst_drv_ctx->mmap_mem + *out_copied,
-					cpy_size);
-		if (retval) {
-			pr_err("copy to user failed\n");
-			return -EIO;
-		} else
-			pr_debug("copy to user passed\n");
-		*out_copied += cpy_size;
-		dbufs->obufs->buff_entry[i].size -= cpy_size;
-		pr_debug("o/p buff size %d, out_copied %d\n",
-			dbufs->obufs->buff_entry[i].size, *out_copied);
-		if (dbufs->obufs->buff_entry[i].size != 0) {
-			*output_index = i;
-			dbufs->obufs->buff_entry[i].buffer += cpy_size;
-			break;
-		} else if (*out_copied == output_size) {
-			*output_index = i + 1;
-			break;
-		}
-	}
-	return retval;
-}
-
-/**
- * sst_decode - Send msg for decoding frames
- *
- * @str_id: ID of stream
- * @dbufs: param that holds the user input and output buffers and size
- *
- * This function is called to decode data from the firmware
- */
-int sst_decode(int str_id, struct snd_sst_dbufs *dbufs)
-{
-	int retval = 0, i;
-	unsigned long long total_input = 0 , total_output = 0;
-	unsigned int cum_input_given = 0 , cum_output_given = 0;
-	int copy_in_done = false, copy_out_done = false;
-	int input_index = 0, output_index = 0;
-	int input_index_valid_size = 0;
-	int in_copied, out_copied;
-	int new_entry_flag;
-	u64 output_size;
-	struct stream_info *str_info;
-	struct snd_sst_decode_info dec_info;
-	unsigned long long input_bytes, output_bytes;
-
-	sst_drv_ctx->scard_ops->power_down_pmic();
-	pr_debug("Powering_down_PMIC...\n");
-
-	retval = sst_validate_strid(str_id);
-	if (retval)
-		return retval;
-
-	str_info = &sst_drv_ctx->streams[str_id];
-	if (str_info->status != STREAM_INIT) {
-		pr_err("invalid stream state = %d\n",
-			       str_info->status);
-		return -EINVAL;
-	}
-
-	str_info->prev = str_info->status;
-	str_info->status = STREAM_DECODE;
-
-	for (i = 0; i < dbufs->ibufs->entries; i++)
-		cum_input_given += dbufs->ibufs->buff_entry[i].size;
-	for (i = 0; i < dbufs->obufs->entries; i++)
-		cum_output_given += dbufs->obufs->buff_entry[i].size;
-
-	/* input and output buffer allocation */
-	retval =  sst_allocate_decode_buf(str_info, dbufs,
-				cum_input_given, cum_output_given);
-	if (retval) {
-		pr_err("mem allocation failed, abort!!!\n");
-		retval = -ENOMEM;
-		goto finish;
-	}
-
-	str_info->decode_isize = str_info->idecode_alloc;
-	str_info->decode_ibuf_type = dbufs->ibufs->type;
-	str_info->decode_obuf_type = dbufs->obufs->type;
-
-	while ((copy_out_done == false) && (copy_in_done == false)) {
-		in_copied = 0;
-		new_entry_flag = false;
-		retval = sst_prepare_input_buffers(str_info,\
-			dbufs, &input_index, &in_copied,
-			&input_index_valid_size, &new_entry_flag);
-		if (retval) {
-			pr_err("prepare in buffers failed\n");
-			goto finish;
-		}
-
-		if (str_info->ops != STREAM_OPS_PLAYBACK_DRM)
-			str_info->decode_obuf = sst_drv_ctx->mmap_mem;
-
-#ifdef CONFIG_MRST_RAR_HANDLER
-		else {
-			if (dbufs->obufs->type == SST_BUF_RAR) {
-				struct RAR_buffer rar_buffers;
-				__u32 info;
-
-				pr_debug("DRM");
-				retval = copy_from_user((void *) &info,
-						dbufs->obufs->
-						buff_entry[output_index].buffer,
-						sizeof(__u32));
-
-				rar_buffers.info.size = dbufs->obufs->
-					buff_entry[output_index].size;
-				rar_buffers.info.handle =  info;
-				retval =  sst_get_RAR(&rar_buffers, 1);
-				if (retval)
-					return retval;
-
-				str_info->decode_obuf = (void *)((unsigned long)
-						rar_buffers.bus_address);
-				str_info->decode_osize = dbufs->obufs->
-					buff_entry[output_index].size;
-				str_info->decode_obuf_type = dbufs->obufs->type;
-				pr_debug("DRM handling\n");
-				pr_debug("o/p_add=0x%lu Size=0x%x\n",
-					(unsigned long) str_info->decode_obuf,
-					str_info->decode_osize);
-			} else {
-				str_info->decode_obuf = sst_drv_ctx->mmap_mem;
-				str_info->decode_osize = dbufs->obufs->
-					buff_entry[output_index].size;
-
-			}
-		}
-#endif
-		if (str_info->ops != STREAM_OPS_PLAYBACK_DRM) {
-			if (str_info->decode_isize > in_copied) {
-				str_info->decode_isize = in_copied;
-				pr_debug("i/p size = %d\n",
-						str_info->decode_isize);
-			}
-		}
-
-
-		retval = sst_send_decode_mess(str_id, str_info, &dec_info);
-		if (retval || dec_info.input_bytes_consumed == 0) {
-			pr_err("SST ERR: mess failed or no input consumed\n");
-			goto finish;
-		}
-		input_bytes = dec_info.input_bytes_consumed;
-		output_bytes = dec_info.output_bytes_produced;
-
-		pr_debug("in_copied=%d, con=%lld, prod=%lld\n",
-			in_copied, input_bytes, output_bytes);
-		if (dbufs->obufs->type == SST_BUF_RAR) {
-			output_index += 1;
-			if (output_index == dbufs->obufs->entries) {
-				copy_in_done = true;
-				pr_debug("all i/p cpy done\n");
-			}
-			total_output += output_bytes;
-		} else {
-			out_copied = 0;
-			output_size = output_bytes;
-			retval = sst_prepare_output_buffers(str_info, dbufs,
-				&output_index, output_size, &out_copied);
-			if (retval) {
-				pr_err("prep out buff fail\n");
-				goto finish;
-			}
-			if (str_info->ops != STREAM_OPS_PLAYBACK_DRM) {
-				if (in_copied != input_bytes) {
-					int bytes_left = in_copied -
-								input_bytes;
-					pr_debug("bytes %d\n",
-							bytes_left);
-					if (new_entry_flag == true)
-						input_index--;
-					while (bytes_left) {
-						struct snd_sst_buffs *ibufs;
-						struct snd_sst_buff_entry
-								*buff_entry;
-						unsigned int size_sent;
-
-						ibufs = dbufs->ibufs;
-						buff_entry =
-						&ibufs->buff_entry[input_index];
-						size_sent = buff_entry->size -\
-							input_index_valid_size;
-						if (bytes_left == size_sent) {
-								bytes_left = 0;
-						} else if (bytes_left <
-								size_sent) {
-							buff_entry->buffer +=
-							 (size_sent -
-								bytes_left);
-							buff_entry->size -=
-							 (size_sent -
-								bytes_left);
-							bytes_left = 0;
-						} else {
-							bytes_left -= size_sent;
-							input_index--;
-							input_index_valid_size =
-									0;
-						}
-					}
-
-				}
-			}
-
-			total_output += out_copied;
-			if (str_info->decode_osize != out_copied) {
-				str_info->decode_osize -= out_copied;
-				pr_debug("output size modified = %d\n",
-						str_info->decode_osize);
-			}
-		}
-		total_input += input_bytes;
-
-		if (str_info->ops == STREAM_OPS_PLAYBACK_DRM) {
-			if (total_input == cum_input_given)
-				copy_in_done = true;
-			copy_out_done = true;
-
-		} else {
-			if (total_output == cum_output_given) {
-				copy_out_done = true;
-				pr_debug("all o/p cpy done\n");
-			}
-
-			if (total_input == cum_input_given) {
-				copy_in_done = true;
-				pr_debug("all i/p cpy done\n");
-			}
-		}
-
-		pr_debug("copy_out = %d, copy_in = %d\n",
-				copy_out_done, copy_in_done);
-	}
-
-finish:
-	dbufs->input_bytes_consumed = total_input;
-	dbufs->output_bytes_produced = total_output;
-	str_info->status = str_info->prev;
-	str_info->prev = STREAM_DECODE;
-	kfree(str_info->decode_ibuf);
-	str_info->decode_ibuf = NULL;
-	return retval;
-}
diff --git a/drivers/staging/intel_sst/intelmid.c b/drivers/staging/intel_sst/intelmid.c
deleted file mode 100644
index 492b660..0000000
--- a/drivers/staging/intel_sst/intelmid.c
+++ /dev/null
@@ -1,1022 +0,0 @@
-/*
- *   intelmid.c - Intel Sound card driver for MID
- *
- *  Copyright (C) 2008-10 Intel Corp
- *  Authors:	Harsha Priya <priya.harsha@intel.com>
- *		Vinod Koul <vinod.koul@intel.com>
- *		Dharageswari R <dharageswari.r@intel.com>
- *		KP Jeeja <jeeja.kp@intel.com>
- *  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; version 2 of the License.
- *
- *  This program is distributed in the hope that it will be useful, but
- *  WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *  General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License along
- *  with this program; if not, write to the Free Software Foundation, Inc.,
- *  59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
- *
- * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- * ALSA driver for Intel MID sound card chipset
- */
-
-#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
-
-#include <linux/module.h>
-#include <linux/slab.h>
-#include <linux/io.h>
-#include <linux/platform_device.h>
-#include <linux/interrupt.h>
-#include <linux/sched.h>
-#include <linux/firmware.h>
-#include <linux/input.h>
-#include <sound/control.h>
-#include <asm/mrst.h>
-#include <sound/pcm.h>
-#include <sound/jack.h>
-#include <sound/pcm_params.h>
-#include <sound/initval.h>
-#include <linux/gpio.h>
-#include "intel_sst.h"
-#include "intel_sst_ioctl.h"
-#include "intel_sst_fw_ipc.h"
-#include "intel_sst_common.h"
-#include "intelmid_snd_control.h"
-#include "intelmid_adc_control.h"
-#include "intelmid.h"
-
-MODULE_AUTHOR("Vinod Koul <vinod.koul@intel.com>");
-MODULE_AUTHOR("Harsha Priya <priya.harsha@intel.com>");
-MODULE_AUTHOR("Dharageswari R <dharageswari.r@intel.com>");
-MODULE_AUTHOR("KP Jeeja <jeeja.kp@intel.com>");
-MODULE_DESCRIPTION("Intel MAD Sound card driver");
-MODULE_LICENSE("GPL v2");
-MODULE_SUPPORTED_DEVICE("{Intel,Intel_MAD}");
-
-
-static int card_index = SNDRV_DEFAULT_IDX1;/* Index 0-MAX */
-static char *card_id = SNDRV_DEFAULT_STR1;	/* ID for this card */
-
-module_param(card_index, int, 0444);
-MODULE_PARM_DESC(card_index, "Index value for INTELMAD soundcard.");
-module_param(card_id, charp, 0444);
-MODULE_PARM_DESC(card_id, "ID string for INTELMAD soundcard.");
-
-int	sst_card_vendor_id;
-int intelmid_audio_interrupt_enable;/*checkpatch fix*/
-struct snd_intelmad *intelmad_drv;
-
-#define INFO(_cpu_id, _irq_cache, _size) \
-	((kernel_ulong_t)&(struct snd_intelmad_probe_info) {	\
-		.cpu_id = (_cpu_id),			\
-		.irq_cache = (_irq_cache),			\
-		.size = (_size),				\
-	})
-/* Data path functionalities */
-static struct snd_pcm_hardware snd_intelmad_stream = {
-	.info =	(SNDRV_PCM_INFO_INTERLEAVED |
-			SNDRV_PCM_INFO_DOUBLE |
-			SNDRV_PCM_INFO_PAUSE |
-			SNDRV_PCM_INFO_RESUME |
-			SNDRV_PCM_INFO_MMAP|
-			SNDRV_PCM_INFO_MMAP_VALID |
-			SNDRV_PCM_INFO_BLOCK_TRANSFER |
-			SNDRV_PCM_INFO_SYNC_START),
-	.formats = (SNDRV_PCM_FMTBIT_S16 | SNDRV_PCM_FMTBIT_U16 |
-			SNDRV_PCM_FMTBIT_S24 | SNDRV_PCM_FMTBIT_U24 |
-			SNDRV_PCM_FMTBIT_S32 | SNDRV_PCM_FMTBIT_U32),
-	.rates = (SNDRV_PCM_RATE_8000|
-			SNDRV_PCM_RATE_44100 |
-			SNDRV_PCM_RATE_48000),
-	.rate_min = MIN_RATE,
-
-	.rate_max = MAX_RATE,
-	.channels_min =	MIN_CHANNEL,
-	.channels_max =	MAX_CHANNEL_AMIC,
-	.buffer_bytes_max = MAX_BUFFER,
-	.period_bytes_min = MIN_PERIOD_BYTES,
-	.period_bytes_max = MAX_PERIOD_BYTES,
-	.periods_min = MIN_PERIODS,
-	.periods_max = MAX_PERIODS,
-	.fifo_size = FIFO_SIZE,
-};
-
-
-/**
- * snd_intelmad_pcm_trigger - stream activities are handled here
- *
- * @substream:substream for which the stream function is called
- * @cmd:the stream commamd that requested from upper layer
- *
- * This function is called whenever an a stream activity is invoked
- */
-static int snd_intelmad_pcm_trigger(struct snd_pcm_substream *substream,
-					int cmd)
-{
-	int ret_val = 0, str_id;
-	struct snd_intelmad *intelmaddata;
-	struct mad_stream_pvt *stream;
-	struct intel_sst_pcm_control *sst_ops;
-
-	WARN_ON(!substream);
-
-	intelmaddata = snd_pcm_substream_chip(substream);
-	stream = substream->runtime->private_data;
-
-	WARN_ON(!intelmaddata->sstdrv_ops);
-	WARN_ON(!intelmaddata->sstdrv_ops->scard_ops);
-	sst_ops  = intelmaddata->sstdrv_ops->pcm_control;
-	str_id = stream->stream_info.str_id;
-
-	switch (cmd) {
-	case SNDRV_PCM_TRIGGER_START:
-		pr_debug("Trigger Start\n");
-		ret_val = sst_ops->device_control(SST_SND_START, &str_id);
-		if (ret_val)
-			return ret_val;
-		stream->stream_status = RUNNING;
-		stream->substream = substream;
-		break;
-	case SNDRV_PCM_TRIGGER_STOP:
-		pr_debug("in stop\n");
-		ret_val = sst_ops->device_control(SST_SND_DROP, &str_id);
-		if (ret_val)
-			return ret_val;
-		stream->stream_status = DROPPED;
-		break;
-	case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
-		pr_debug("in pause\n");
-		ret_val = sst_ops->device_control(SST_SND_PAUSE, &str_id);
-		if (ret_val)
-			return ret_val;
-		stream->stream_status = PAUSED;
-		break;
-	case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
-		pr_debug("in pause release\n");
-		ret_val = sst_ops->device_control(SST_SND_RESUME, &str_id);
-		if (ret_val)
-			return ret_val;
-		stream->stream_status = RUNNING;
-		break;
-	default:
-		return -EINVAL;
-	}
-	return ret_val;
-}
-
-/**
-* snd_intelmad_pcm_prepare- internal preparation before starting a stream
-*
-* @substream:  substream for which the function is called
-*
-* This function is called when a stream is started for internal preparation.
-*/
-static int snd_intelmad_pcm_prepare(struct snd_pcm_substream *substream)
-{
-	struct mad_stream_pvt *stream;
-	int ret_val = 0;
-	struct snd_intelmad *intelmaddata;
-
-	pr_debug("pcm_prepare called\n");
-
-	WARN_ON(!substream);
-	stream = substream->runtime->private_data;
-	intelmaddata = snd_pcm_substream_chip(substream);
-	pr_debug("pb cnt = %d cap cnt = %d\n",\
-		intelmaddata->playback_cnt,
-		intelmaddata->capture_cnt);
-
-	if (stream->stream_info.str_id) {
-		pr_debug("Prepare called for already set stream\n");
-		ret_val = intelmaddata->sstdrv_ops->pcm_control->device_control(
-				SST_SND_DROP, &stream->stream_info.str_id);
-		return ret_val;
-	}
-
-	ret_val = snd_intelmad_alloc_stream(substream);
-	if (ret_val < 0)
-		return ret_val;
-	stream->dbg_cum_bytes = 0;
-	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
-			intelmaddata->playback_cnt++;
-	else
-		intelmaddata->capture_cnt++;
-	/* return back the stream id */
-	snprintf(substream->pcm->id, sizeof(substream->pcm->id),
-			"%d", stream->stream_info.str_id);
-	pr_debug("stream id to user = %s\n",
-			substream->pcm->id);
-
-	ret_val = snd_intelmad_init_stream(substream);
-	if (ret_val)
-		return ret_val;
-	substream->runtime->hw.info = SNDRV_PCM_INFO_BLOCK_TRANSFER;
-	return ret_val;
-}
-
-static int snd_intelmad_hw_params(struct snd_pcm_substream *substream,
-				    struct snd_pcm_hw_params *hw_params)
-{
-	int ret_val;
-
-	pr_debug("snd_intelmad_hw_params called\n");
-	ret_val = snd_pcm_lib_malloc_pages(substream,
-			params_buffer_bytes(hw_params));
-	memset(substream->runtime->dma_area, 0,
-			params_buffer_bytes(hw_params));
-
-	return ret_val;
-}
-
-static int snd_intelmad_hw_free(struct snd_pcm_substream *substream)
-{
-	pr_debug("snd_intelmad_hw_free called\n");
-	return snd_pcm_lib_free_pages(substream);
-}
-
-/**
- * snd_intelmad_pcm_pointer- to send the current buffer pointer processed by hw
- *
- * @substream:  substream for which the function is called
- *
- * This function is called by ALSA framework to get the current hw buffer ptr
- * when a period is elapsed
- */
-static snd_pcm_uframes_t snd_intelmad_pcm_pointer
-			(struct snd_pcm_substream *substream)
-{
-	/* struct snd_pcm_runtime *runtime = substream->runtime; */
-	struct mad_stream_pvt *stream;
-	struct snd_intelmad *intelmaddata;
-	int ret_val;
-
-	WARN_ON(!substream);
-
-	intelmaddata = snd_pcm_substream_chip(substream);
-	stream = substream->runtime->private_data;
-	if (stream->stream_status == INIT)
-		return 0;
-
-	ret_val = intelmaddata->sstdrv_ops->pcm_control->device_control(
-			SST_SND_BUFFER_POINTER, &stream->stream_info);
-	if (ret_val) {
-		pr_err("error code = 0x%x\n", ret_val);
-		return ret_val;
-	}
-	pr_debug("samples reported out 0x%llx\n",
-			stream->stream_info.buffer_ptr);
-	pr_debug("Frame bits:: %d period_count :: %d\n",
-			(int)substream->runtime->frame_bits,
-			(int)substream->runtime->period_size);
-
-	return stream->stream_info.buffer_ptr;
-
-}
-
-/**
- * snd_intelmad_close- to free parameteres when stream is stopped
- *
- * @substream:  substream for which the function is called
- *
- * This function is called by ALSA framework when stream is stopped
- */
-static int snd_intelmad_close(struct snd_pcm_substream *substream)
-{
-	struct snd_intelmad *intelmaddata;
-	struct mad_stream_pvt *stream;
-	int ret_val = 0, str_id;
-
-	WARN_ON(!substream);
-
-	stream = substream->runtime->private_data;
-	str_id = stream->stream_info.str_id;
-
-	pr_debug("sst: snd_intelmad_close called for %d\n", str_id);
-	intelmaddata = snd_pcm_substream_chip(substream);
-
-	pr_debug("str id = %d\n", stream->stream_info.str_id);
-	if (stream->stream_info.str_id) {
-		/* SST API to actually stop/free the stream */
-		ret_val = intelmaddata->sstdrv_ops->pcm_control->close(str_id);
-		if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
-			intelmaddata->playback_cnt--;
-		else
-			intelmaddata->capture_cnt--;
-	}
-	pr_debug("snd_intelmad_close : pb cnt = %d cap cnt = %d\n",
-		intelmaddata->playback_cnt, intelmaddata->capture_cnt);
-	kfree(substream->runtime->private_data);
-	return ret_val;
-}
-
-/**
- * snd_intelmad_open- to set runtime parameters during stream start
- *
- * @substream:  substream for which the function is called
- * @type: audio device type
- *
- * This function is called by ALSA framework when stream is started
- */
-static int snd_intelmad_open(struct snd_pcm_substream *substream,
-			enum snd_sst_audio_device_type type)
-{
-	struct snd_intelmad *intelmaddata;
-	struct snd_pcm_runtime *runtime;
-	struct mad_stream_pvt *stream;
-
-	WARN_ON(!substream);
-
-	pr_debug("snd_intelmad_open called\n");
-
-	intelmaddata = snd_pcm_substream_chip(substream);
-	runtime = substream->runtime;
-	/* set the runtime hw parameter with local snd_pcm_hardware struct */
-	runtime->hw = snd_intelmad_stream;
-	if (intelmaddata->cpu_id == CPU_CHIP_LINCROFT) {
-		/*
-		 * MRST firmware currently denies stereo recording requests.
-		 */
-		if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) {
-			runtime->hw.formats = (SNDRV_PCM_FMTBIT_S16 |
-					       SNDRV_PCM_FMTBIT_U16);
-			runtime->hw.channels_max = 1;
-		}
-	}
-	if (intelmaddata->cpu_id == CPU_CHIP_PENWELL) {
-		runtime->hw = snd_intelmad_stream;
-		runtime->hw.rates = SNDRV_PCM_RATE_48000;
-		runtime->hw.rate_min = MAX_RATE;
-		runtime->hw.formats = (SNDRV_PCM_FMTBIT_S24 |
-						SNDRV_PCM_FMTBIT_U24);
-		if (intelmaddata->sstdrv_ops->scard_ops->input_dev_id == AMIC)
-			runtime->hw.channels_max = MAX_CHANNEL_AMIC;
-		else
-			runtime->hw.channels_max = MAX_CHANNEL_DMIC;
-
-	}
-	/* setup the internal datastruture stream pointers based on it being
-	playback or capture stream */
-	stream = kzalloc(sizeof(*stream), GFP_KERNEL);
-	if (!stream)
-		return -ENOMEM;
-	stream->stream_info.str_id = 0;
-	stream->device = type;
-	stream->stream_status = INIT;
-	runtime->private_data = stream;
-	return snd_pcm_hw_constraint_integer(runtime,
-			 SNDRV_PCM_HW_PARAM_PERIODS);
-}
-
-static int snd_intelmad_headset_open(struct snd_pcm_substream *substream)
-{
-	return snd_intelmad_open(substream, SND_SST_DEVICE_HEADSET);
-}
-
-static int snd_intelmad_ihf_open(struct snd_pcm_substream *substream)
-{
-	return snd_intelmad_open(substream, SND_SST_DEVICE_IHF);
-}
-
-static int snd_intelmad_vibra_open(struct snd_pcm_substream *substream)
-{
-	return snd_intelmad_open(substream, SND_SST_DEVICE_VIBRA);
-}
-
-static int snd_intelmad_haptic_open(struct snd_pcm_substream *substream)
-{
-	return snd_intelmad_open(substream, SND_SST_DEVICE_HAPTIC);
-}
-
-static struct snd_pcm_ops snd_intelmad_headset_ops = {
-	.open = snd_intelmad_headset_open,
-	.close = snd_intelmad_close,
-	.ioctl = snd_pcm_lib_ioctl,
-	.hw_params = snd_intelmad_hw_params,
-	.hw_free = snd_intelmad_hw_free,
-	.prepare = snd_intelmad_pcm_prepare,
-	.trigger = snd_intelmad_pcm_trigger,
-	.pointer = snd_intelmad_pcm_pointer,
-};
-
-static struct snd_pcm_ops snd_intelmad_ihf_ops = {
-	.open = snd_intelmad_ihf_open,
-	.close = snd_intelmad_close,
-	.ioctl = snd_pcm_lib_ioctl,
-	.hw_params = snd_intelmad_hw_params,
-	.hw_free = snd_intelmad_hw_free,
-	.prepare = snd_intelmad_pcm_prepare,
-	.trigger = snd_intelmad_pcm_trigger,
-	.pointer = snd_intelmad_pcm_pointer,
-};
-
-static struct snd_pcm_ops snd_intelmad_vibra_ops = {
-	.open = snd_intelmad_vibra_open,
-	.close = snd_intelmad_close,
-	.ioctl = snd_pcm_lib_ioctl,
-	.hw_params = snd_intelmad_hw_params,
-	.hw_free = snd_intelmad_hw_free,
-	.prepare = snd_intelmad_pcm_prepare,
-	.trigger = snd_intelmad_pcm_trigger,
-	.pointer = snd_intelmad_pcm_pointer,
-};
-
-static struct snd_pcm_ops snd_intelmad_haptic_ops = {
-	.open = snd_intelmad_haptic_open,
-	.close = snd_intelmad_close,
-	.ioctl = snd_pcm_lib_ioctl,
-	.hw_params = snd_intelmad_hw_params,
-	.hw_free = snd_intelmad_hw_free,
-	.prepare = snd_intelmad_pcm_prepare,
-	.trigger = snd_intelmad_pcm_trigger,
-	.pointer = snd_intelmad_pcm_pointer,
-};
-
-static struct snd_pcm_ops snd_intelmad_capture_ops = {
-	.open = snd_intelmad_headset_open,
-	.close = snd_intelmad_close,
-	.ioctl = snd_pcm_lib_ioctl,
-	.hw_params = snd_intelmad_hw_params,
-	.hw_free = snd_intelmad_hw_free,
-	.prepare = snd_intelmad_pcm_prepare,
-	.trigger = snd_intelmad_pcm_trigger,
-	.pointer = snd_intelmad_pcm_pointer,
-};
-
-int intelmad_get_mic_bias(void)
-{
-	struct snd_pmic_ops *pmic_ops;
-
-	if (!intelmad_drv || !intelmad_drv->sstdrv_ops)
-		return -ENODEV;
-	pmic_ops = intelmad_drv->sstdrv_ops->scard_ops;
-	if (pmic_ops && pmic_ops->pmic_get_mic_bias)
-		return pmic_ops->pmic_get_mic_bias(intelmad_drv);
-	else
-		return -ENODEV;
-}
-EXPORT_SYMBOL_GPL(intelmad_get_mic_bias);
-
-int intelmad_set_headset_state(int state)
-{
-	struct snd_pmic_ops *pmic_ops;
-
-	if (!intelmad_drv || !intelmad_drv->sstdrv_ops)
-		return -ENODEV;
-	pmic_ops = intelmad_drv->sstdrv_ops->scard_ops;
-	if (pmic_ops && pmic_ops->pmic_set_headset_state)
-		return pmic_ops->pmic_set_headset_state(state);
-	else
-		return -ENODEV;
-}
-EXPORT_SYMBOL_GPL(intelmad_set_headset_state);
-
-void sst_process_mad_jack_detection(struct work_struct *work)
-{
-	u8 interrupt_status;
-	struct mad_jack_msg_wq *mad_jack_detect =
-			container_of(work, struct mad_jack_msg_wq, wq);
-
-	struct snd_intelmad *intelmaddata =
-			mad_jack_detect->intelmaddata;
-
-	if (!intelmaddata)
-		return;
-
-	interrupt_status = mad_jack_detect->intsts;
-	if (intelmaddata->sstdrv_ops && intelmaddata->sstdrv_ops->scard_ops
-			&& intelmaddata->sstdrv_ops->scard_ops->pmic_irq_cb) {
-		intelmaddata->sstdrv_ops->scard_ops->pmic_irq_cb(
-			(void *)intelmaddata, interrupt_status);
-		intelmaddata->sstdrv_ops->scard_ops->pmic_jack_enable();
-	}
-	kfree(mad_jack_detect);
-}
-/**
- * snd_intelmad_intr_handler- interrupt handler
- *
- * @irq :  irq number of the interrupt received
- * @dev: device context
- *
- * This function is called when an interrupt is raised at the sound card
- */
-static irqreturn_t snd_intelmad_intr_handler(int irq, void *dev)
-{
-	struct snd_intelmad *intelmaddata =
-			(struct snd_intelmad *)dev;
-	u8 interrupt_status;
-	struct mad_jack_msg_wq  *mad_jack_msg;
-	memcpy_fromio(&interrupt_status,
-			((void *)(intelmaddata->int_base)),
-			sizeof(u8));
-
-	mad_jack_msg = kzalloc(sizeof(*mad_jack_msg), GFP_ATOMIC);
-	mad_jack_msg->intsts = interrupt_status;
-	mad_jack_msg->intelmaddata = intelmaddata;
-	INIT_WORK(&mad_jack_msg->wq, sst_process_mad_jack_detection);
-	queue_work(intelmaddata->mad_jack_wq, &mad_jack_msg->wq);
-
-	return IRQ_HANDLED;
-}
-
-void sst_mad_send_jack_report(struct snd_jack *jack,
-				int buttonpressevent , int status)
-{
-
-	if (!jack) {
-		pr_debug("MAD error jack empty\n");
-
-	} else {
-		snd_jack_report(jack, status);
-		/* button pressed and released */
-		if (buttonpressevent)
-			snd_jack_report(jack, 0);
-		pr_debug("MAD sending jack report Done !!!\n");
-	}
-}
-
-static int __devinit snd_intelmad_register_irq(
-		struct snd_intelmad *intelmaddata, unsigned int regbase,
-		unsigned int regsize)
-{
-	int ret_val;
-	char *drv_name;
-
-	pr_debug("irq reg regbase 0x%x, regsize 0x%x\n",
-					regbase, regsize);
-	intelmaddata->int_base = ioremap_nocache(regbase, regsize);
-	if (!intelmaddata->int_base)
-		pr_err("Mapping of cache failed\n");
-	pr_debug("irq = 0x%x\n", intelmaddata->irq);
-	if (intelmaddata->cpu_id == CPU_CHIP_PENWELL)
-		drv_name = DRIVER_NAME_MFLD;
-	else
-		drv_name = DRIVER_NAME_MRST;
-	ret_val = request_irq(intelmaddata->irq,
-				snd_intelmad_intr_handler,
-				IRQF_SHARED, drv_name,
-				intelmaddata);
-	if (ret_val)
-		pr_err("cannot register IRQ\n");
-	return ret_val;
-}
-
-static int __devinit snd_intelmad_sst_register(
-			struct snd_intelmad *intelmaddata)
-{
-	int ret_val = 0;
-	struct snd_pmic_ops *intelmad_vendor_ops[MAX_VENDORS] = {
-		&snd_pmic_ops_fs,
-		&snd_pmic_ops_mx,
-		&snd_pmic_ops_nc,
-		&snd_msic_ops
-	};
-
-	struct sc_reg_access vendor_addr = {0x00, 0x00, 0x00};
-
-	if (intelmaddata->cpu_id == CPU_CHIP_LINCROFT) {
-		ret_val = sst_sc_reg_access(&vendor_addr, PMIC_READ, 1);
-		if (ret_val)
-			return ret_val;
-		sst_card_vendor_id = (vendor_addr.value & (MASK2|MASK1|MASK0));
-		pr_debug("original n extrated vendor id = 0x%x %d\n",
-				vendor_addr.value, sst_card_vendor_id);
-		if (sst_card_vendor_id < 0 || sst_card_vendor_id > 2) {
-			pr_err("vendor card not supported!!\n");
-			return -EIO;
-		}
-	} else
-		sst_card_vendor_id = 0x3;
-
-	intelmaddata->sstdrv_ops->module_name = SST_CARD_NAMES;
-	intelmaddata->sstdrv_ops->vendor_id = sst_card_vendor_id;
-	BUG_ON(!intelmad_vendor_ops[sst_card_vendor_id]);
-	intelmaddata->sstdrv_ops->scard_ops =
-			intelmad_vendor_ops[sst_card_vendor_id];
-
-	if (intelmaddata->cpu_id == CPU_CHIP_PENWELL) {
-		intelmaddata->sstdrv_ops->scard_ops->pb_on = 0;
-		intelmaddata->sstdrv_ops->scard_ops->cap_on = 0;
-		intelmaddata->sstdrv_ops->scard_ops->input_dev_id = DMIC;
-		intelmaddata->sstdrv_ops->scard_ops->output_dev_id =
-							STEREO_HEADPHONE;
-		intelmaddata->sstdrv_ops->scard_ops->lineout_dev_id = NONE;
-	}
-
-	/* registering with SST driver to get access to SST APIs to use */
-	ret_val = register_sst_card(intelmaddata->sstdrv_ops);
-	if (ret_val) {
-		pr_err("sst card registration failed\n");
-		return ret_val;
-	}
-	sst_card_vendor_id = intelmaddata->sstdrv_ops->vendor_id;
-	intelmaddata->pmic_status = PMIC_UNINIT;
-	return ret_val;
-}
-
-static void snd_intelmad_page_free(struct snd_pcm *pcm)
-{
-	snd_pcm_lib_preallocate_free_for_all(pcm);
-}
-/* Driver Init/exit functionalities */
-/**
- * snd_intelmad_pcm_new - to setup pcm for the card
- *
- * @card:  pointer to the sound card structure
- * @intelmaddata: pointer to internal context
- * @pb: playback count for this card
- * @cap: capture count for this card
- * @index: device index
- *
- * This function is called from probe function to set up pcm params
- * and functions
- */
-static int __devinit snd_intelmad_pcm_new(struct snd_card *card,
-			struct snd_intelmad *intelmaddata,
-			unsigned int pb, unsigned int cap, unsigned int index)
-{
-	int ret_val = 0;
-	struct snd_pcm *pcm;
-	char name[32] = INTEL_MAD;
-	struct snd_pcm_ops *pb_ops = NULL, *cap_ops = NULL;
-
-	pr_debug("called for pb %d, cp %d, idx %d\n", pb, cap, index);
-	ret_val = snd_pcm_new(card, name, index, pb, cap, &pcm);
-	if (ret_val)
-		return ret_val;
-	/* setup the ops for playback and capture streams */
-	switch (index) {
-	case 0:
-		pb_ops = &snd_intelmad_headset_ops;
-		cap_ops = &snd_intelmad_capture_ops;
-		break;
-	case 1:
-		pb_ops = &snd_intelmad_ihf_ops;
-		cap_ops = &snd_intelmad_capture_ops;
-		break;
-	case 2:
-		pb_ops = &snd_intelmad_vibra_ops;
-		cap_ops = &snd_intelmad_capture_ops;
-		break;
-	case 3:
-		pb_ops = &snd_intelmad_haptic_ops;
-		cap_ops = &snd_intelmad_capture_ops;
-		break;
-	}
-	if (pb)
-		snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, pb_ops);
-	if (cap)
-		snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, cap_ops);
-	/* setup private data which can be retrieved when required */
-	pcm->private_data = intelmaddata;
-	pcm->private_free = snd_intelmad_page_free;
-	pcm->info_flags = 0;
-	strncpy(pcm->name, card->shortname, strlen(card->shortname));
-	/* allocate dma pages for ALSA stream operations */
-	snd_pcm_lib_preallocate_pages_for_all(pcm,
-			SNDRV_DMA_TYPE_CONTINUOUS,
-			snd_dma_continuous_data(GFP_KERNEL),
-			MIN_BUFFER, MAX_BUFFER);
-	return ret_val;
-}
-
-static int __devinit snd_intelmad_pcm(struct snd_card *card,
-				struct snd_intelmad *intelmaddata)
-{
-	int ret_val = 0;
-
-	WARN_ON(!card);
-	WARN_ON(!intelmaddata);
-	pr_debug("snd_intelmad_pcm called\n");
-	ret_val = snd_intelmad_pcm_new(card, intelmaddata, 1, 1, 0);
-	if (intelmaddata->cpu_id == CPU_CHIP_LINCROFT)
-		return ret_val;
-	ret_val = snd_intelmad_pcm_new(card, intelmaddata, 1, 0, 1);
-	if (ret_val)
-		return ret_val;
-	ret_val = snd_intelmad_pcm_new(card, intelmaddata, 1, 0, 2);
-	if (ret_val)
-		return ret_val;
-	return snd_intelmad_pcm_new(card, intelmaddata, 1, 0, 3);
-}
-
-/**
- * snd_intelmad_jack- to setup jack settings of the card
- *
- * @intelmaddata: pointer to internal context
- *
- * This function is called send jack events
- */
-static int snd_intelmad_jack(struct snd_intelmad *intelmaddata)
-{
-	struct snd_jack *jack;
-	int retval;
-
-	pr_debug("snd_intelmad_jack called\n");
-	jack = &intelmaddata->jack[0].jack;
-	snd_jack_set_key(jack, SND_JACK_BTN_0, KEY_PHONE);
-	retval = snd_jack_new(intelmaddata->card, "Intel(R) MID Audio Jack",
-		SND_JACK_HEADPHONE | SND_JACK_HEADSET |
-		SW_JACK_PHYSICAL_INSERT | SND_JACK_BTN_0
-		| SND_JACK_BTN_1, &jack);
-	pr_debug("snd_intelmad_jack called\n");
-	if (retval < 0)
-		return retval;
-	snd_jack_report(jack, 0);
-
-	jack->private_data = jack;
-	intelmaddata->jack[0].jack = *jack;
-
-	return retval;
-}
-
-/**
- * snd_intelmad_mixer- to setup mixer settings of the card
- *
- * @intelmaddata: pointer to internal context
- *
- * This function is called from probe function to set up mixer controls
- */
-static int __devinit snd_intelmad_mixer(struct snd_intelmad *intelmaddata)
-{
-	struct snd_card *card;
-	unsigned int idx;
-	int ret_val = 0, max_controls = 0;
-	char *mixername = "IntelMAD Controls";
-	struct snd_kcontrol_new *controls;
-
-	WARN_ON(!intelmaddata);
-
-	card = intelmaddata->card;
-	strncpy(card->mixername, mixername, sizeof(card->mixername)-1);
-	/* add all widget controls and expose the same */
-	if (intelmaddata->cpu_id == CPU_CHIP_PENWELL) {
-		max_controls = MAX_CTRL_MFLD;
-		controls = snd_intelmad_controls_mfld;
-	} else {
-		max_controls = MAX_CTRL_MRST;
-		controls = snd_intelmad_controls_mrst;
-	}
-	for (idx = 0; idx < max_controls; idx++) {
-		ret_val = snd_ctl_add(card,
-				snd_ctl_new1(&controls[idx],
-				intelmaddata));
-		pr_debug("mixer[idx]=%d added\n", idx);
-		if (ret_val) {
-			pr_err("in adding of control index = %d\n", idx);
-			break;
-		}
-	}
-	return ret_val;
-}
-
-static int snd_intelmad_dev_free(struct snd_device *device)
-{
-	struct snd_intelmad *intelmaddata;
-
-	WARN_ON(!device);
-
-	intelmaddata = device->device_data;
-
-	pr_debug("snd_intelmad_dev_free called\n");
-	unregister_sst_card(intelmaddata->sstdrv_ops);
-
-	/* free allocated memory for internal context */
-	destroy_workqueue(intelmaddata->mad_jack_wq);
-	device->device_data = NULL;
-	kfree(intelmaddata->sstdrv_ops);
-	kfree(intelmaddata);
-
-	return 0;
-}
-
-static int __devinit snd_intelmad_create(
-		struct snd_intelmad *intelmaddata,
-		struct snd_card *card)
-{
-	int ret_val;
-	static struct snd_device_ops ops = {
-		.dev_free =	snd_intelmad_dev_free,
-	};
-
-	WARN_ON(!intelmaddata);
-	WARN_ON(!card);
-	/* ALSA api to register for the device */
-	ret_val = snd_device_new(card, SNDRV_DEV_LOWLEVEL, intelmaddata, &ops);
-	return ret_val;
-}
-
-/**
-* snd_intelmad_probe- function registred for init
-* @pdev :  pointer to the device struture
-* This function is called when the device is initialized
-*/
-int __devinit snd_intelmad_probe(struct platform_device *pdev)
-{
-	struct snd_card *card;
-	int ret_val;
-	struct snd_intelmad *intelmaddata;
-	const struct platform_device_id *id = platform_get_device_id(pdev);
-	struct snd_intelmad_probe_info *info = (void *)id->driver_data;
-
-	pr_debug("probe for %s cpu_id %d\n", pdev->name, info->cpu_id);
-	pr_debug("rq_chache %x of size %x\n", info->irq_cache, info->size);
-	if (!strcmp(pdev->name, DRIVER_NAME_MRST))
-		pr_debug("detected MRST\n");
-	else if (!strcmp(pdev->name, DRIVER_NAME_MFLD))
-		pr_debug("detected MFLD\n");
-	else {
-		pr_err("detected unknown device abort!!\n");
-		return -EIO;
-	}
-	if ((info->cpu_id < CPU_CHIP_LINCROFT) ||
-				(info->cpu_id > CPU_CHIP_PENWELL)) {
-		pr_err("detected unknown cpu_id abort!!\n");
-		return -EIO;
-	}
-	/* allocate memory for saving internal context and working */
-	intelmaddata = kzalloc(sizeof(*intelmaddata), GFP_KERNEL);
-	if (!intelmaddata) {
-		pr_debug("mem alloctn fail\n");
-		return -ENOMEM;
-	}
-	intelmad_drv = intelmaddata;
-
-	/* allocate memory for LPE API set */
-	intelmaddata->sstdrv_ops = kzalloc(sizeof(struct intel_sst_card_ops),
-					GFP_KERNEL);
-	if (!intelmaddata->sstdrv_ops) {
-		pr_err("mem allocation for ops fail\n");
-		kfree(intelmaddata);
-		return -ENOMEM;
-	}
-
-	intelmaddata->cpu_id = info->cpu_id;
-	/* create a card instance with ALSA framework */
-	ret_val = snd_card_create(card_index, card_id, THIS_MODULE, 0, &card);
-	if (ret_val) {
-		pr_err("snd_card_create fail\n");
-		goto free_allocs;
-	}
-
-	intelmaddata->pdev = pdev;
-	intelmaddata->irq = platform_get_irq(pdev, 0);
-	platform_set_drvdata(pdev, intelmaddata);
-	intelmaddata->card = card;
-	intelmaddata->card_id = card_id;
-	intelmaddata->card_index = card_index;
-	intelmaddata->master_mute = UNMUTE;
-	intelmaddata->playback_cnt =  intelmaddata->capture_cnt = 0;
-	strncpy(card->driver, INTEL_MAD, strlen(INTEL_MAD));
-	strncpy(card->shortname, INTEL_MAD, strlen(INTEL_MAD));
-
-	intelmaddata->sstdrv_ops->module_name = SST_CARD_NAMES;
-	/* registering with LPE driver to get access to SST APIs to use */
-	ret_val = snd_intelmad_sst_register(intelmaddata);
-	if (ret_val) {
-		pr_err("snd_intelmad_sst_register failed\n");
-		goto set_null_data;
-	}
-
-	intelmaddata->pmic_status = PMIC_INIT;
-
-	ret_val = snd_intelmad_pcm(card, intelmaddata);
-	if (ret_val) {
-		pr_err("snd_intelmad_pcm failed\n");
-		goto free_sst;
-	}
-
-	ret_val = snd_intelmad_mixer(intelmaddata);
-	if (ret_val) {
-		pr_err("snd_intelmad_mixer failed\n");
-		goto free_card;
-	}
-
-	ret_val = snd_intelmad_jack(intelmaddata);
-	if (ret_val) {
-		pr_err("snd_intelmad_jack failed\n");
-		goto free_card;
-	}
-	intelmaddata->adc_address = mid_initialize_adc();
-
-	/*create work queue for jack interrupt*/
-	INIT_WORK(&intelmaddata->mad_jack_msg.wq,
-		sst_process_mad_jack_detection);
-
-	intelmaddata->mad_jack_wq = create_workqueue("sst_mad_jack_wq");
-	if (!intelmaddata->mad_jack_wq)
-		goto free_card;
-
-	ret_val = snd_intelmad_register_irq(intelmaddata,
-					info->irq_cache, info->size);
-	if (ret_val) {
-		pr_err("snd_intelmad_register_irq fail\n");
-		goto free_mad_jack_wq;
-	}
-
-	/* internal function call to register device with ALSA */
-	ret_val = snd_intelmad_create(intelmaddata, card);
-	if (ret_val) {
-		pr_err("snd_intelmad_create failed\n");
-		goto set_pvt_data;
-	}
-	card->private_data = &intelmaddata;
-	snd_card_set_dev(card, &pdev->dev);
-	ret_val = snd_card_register(card);
-	if (ret_val) {
-		pr_err("snd_card_register failed\n");
-		goto set_pvt_data;
-	}
-	if (pdev->dev.platform_data) {
-		int gpio_amp = *(int *)pdev->dev.platform_data;
-		if (gpio_request_one(gpio_amp, GPIOF_OUT_INIT_LOW, "amp power"))
-			gpio_amp = 0;
-		intelmaddata->sstdrv_ops->scard_ops->gpio_amp = gpio_amp;
-	}
-
-	pr_debug("snd_intelmad_probe complete\n");
-	return ret_val;
-
-set_pvt_data:
-	card->private_data = NULL;
-free_mad_jack_wq:
-	destroy_workqueue(intelmaddata->mad_jack_wq);
-free_card:
-	snd_card_free(intelmaddata->card);
-free_sst:
-	unregister_sst_card(intelmaddata->sstdrv_ops);
-set_null_data:
-	platform_set_drvdata(pdev, NULL);
-free_allocs:
-	pr_err("probe failed\n");
-	snd_card_free(card);
-	kfree(intelmaddata->sstdrv_ops);
-	kfree(intelmaddata);
-	return ret_val;
-}
-
-
-static int snd_intelmad_remove(struct platform_device *pdev)
-{
-	struct snd_intelmad *intelmaddata = platform_get_drvdata(pdev);
-
-	if (intelmaddata) {
-		if (intelmaddata->sstdrv_ops->scard_ops->gpio_amp)
-			gpio_free(intelmaddata->sstdrv_ops->scard_ops->gpio_amp);
-		free_irq(intelmaddata->irq, intelmaddata);
-		snd_card_free(intelmaddata->card);
-	}
-	intelmad_drv = NULL;
-	platform_set_drvdata(pdev, NULL);
-	return 0;
-}
-
-/*********************************************************************
- *		Driver initialization and exit
- *********************************************************************/
-static const struct platform_device_id snd_intelmad_ids[] = {
-	{DRIVER_NAME_MRST, INFO(CPU_CHIP_LINCROFT, AUDINT_BASE, 1)},
-	{DRIVER_NAME_MFLD, INFO(CPU_CHIP_PENWELL, 0xFFFF7FCD, 1)},
-	{"", 0},
-
-};
-
-static struct platform_driver snd_intelmad_driver = {
-	.driver = {
-		.owner = THIS_MODULE,
-		.name = "intel_mid_sound_card",
-	},
-	.id_table = snd_intelmad_ids,
-	.probe = snd_intelmad_probe,
-	.remove = __devexit_p(snd_intelmad_remove),
-};
-
-/*
- * alsa_card_intelmad_init- driver init function
- *
- * This function is called when driver module is inserted
- */
-static int __init alsa_card_intelmad_init(void)
-{
-	pr_debug("mad_init called\n");
-	return platform_driver_register(&snd_intelmad_driver);
-}
-
-/**
- * alsa_card_intelmad_exit- driver exit function
- *
- * This function is called when driver module is removed
- */
-static void __exit alsa_card_intelmad_exit(void)
-{
-	pr_debug("mad_exit called\n");
-	return platform_driver_unregister(&snd_intelmad_driver);
-}
-
-module_init(alsa_card_intelmad_init)
-module_exit(alsa_card_intelmad_exit)
-
diff --git a/drivers/staging/intel_sst/intelmid.h b/drivers/staging/intel_sst/intelmid.h
deleted file mode 100644
index 14a7ba0..0000000
--- a/drivers/staging/intel_sst/intelmid.h
+++ /dev/null
@@ -1,209 +0,0 @@
-/*
- *  intelmid.h - Intel Sound card driver for MID
- *
- *  Copyright (C) 2008-10 Intel Corp
- *  Authors:	Harsha Priya <priya.harsha@intel.com>
- *		Vinod Koul <vinod.koul@intel.com>
- *		Dharageswari R <dharageswari.r@intel.com>
- *		KP Jeeja <jeeja.kp@intel.com>
- *  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation version 2 of the License.
- *
- *  This program is distributed in the hope that it will be useful, but
- *  WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *  General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License along
- *  with this program; if not, write to the Free Software Foundation, Inc.,
- *  59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
- *
- * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- *  ALSA driver header for Intel MAD chipset
- */
-#ifndef __INTELMID_H
-#define __INTELMID_H
-
-#include <linux/time.h>
-#include <sound/jack.h>
-
-#define DRIVER_NAME_MFLD "msic_audio"
-#define DRIVER_NAME_MRST "pmic_audio"
-#define DRIVER_NAME "intelmid_audio"
-#define PMIC_SOUND_IRQ_TYPE_MASK (1 << 15)
-#define AUDINT_BASE (0xFFFFEFF8 + (6 * sizeof(u8)))
-#define REG_IRQ
-/* values #defined   */
-/* will differ for different hw - to be taken from config  */
-#define MAX_DEVICES		1
-#define MIN_RATE		8000
-#define MAX_RATE		48000
-#define MAX_BUFFER		(800*1024) /* for PCM */
-#define MIN_BUFFER		(800*1024)
-#define MAX_PERIODS		(1024*2)
-#define MIN_PERIODS		2
-#define MAX_PERIOD_BYTES MAX_BUFFER
-#define MIN_PERIOD_BYTES 32
-/*#define MIN_PERIOD_BYTES 160*/
-#define MAX_MUTE		1
-#define MIN_MUTE		0
-#define MONO_CNTL		1
-#define STEREO_CNTL		2
-#define MIN_CHANNEL		1
-#define MAX_CHANNEL_AMIC	2
-#define MAX_CHANNEL_DMIC	5
-#define FIFO_SIZE		0 /* fifo not being used */
-#define INTEL_MAD		"Intel MAD"
-#define MAX_CTRL_MRST		8
-#define MAX_CTRL_MFLD		7
-#define MAX_CTRL		8
-#define MAX_VENDORS		4
-/* TODO +6 db */
-#define MAX_VOL		64
-/* TODO -57 db */
-#define MIN_VOL		0
-#define PLAYBACK_COUNT  1
-#define CAPTURE_COUNT	1
-#define ADC_ONE_LSB_MULTIPLIER 2346
-
-#define MID_JACK_HS_LONG_PRESS SND_JACK_BTN_0
-#define MID_JACK_HS_SHORT_PRESS SND_JACK_BTN_1
-
-extern int	sst_card_vendor_id;
-
-struct mad_jack {
-	struct snd_jack jack;
-	int jack_status;
-	int jack_dev_state;
-	struct timeval buttonpressed;
-	struct timeval  buttonreleased;
-};
-
-struct mad_jack_msg_wq {
-	u8 intsts;
-	struct snd_intelmad *intelmaddata;
-	struct work_struct	wq;
-
-};
-
-struct snd_intelmad_probe_info {
-	unsigned int cpu_id;
-	unsigned int irq_cache;
-	unsigned int size;
-};
-
-/**
- * struct snd_intelmad - intelmad driver structure
- *
- * @card: ptr to the card details
- * @card_index: sound card index
- * @card_id: sound card id detected
- * @sstdrv_ops: ptr to sst driver ops
- * @pdev: ptr to platform device
- * @irq: interrupt number detected
- * @pmic_status: Device status of sound card
- * @int_base: ptr to MMIO interrupt region
- * @output_sel: device selected as o/p
- * @input_sel: device selected as i/p
- * @master_mute: master mute status
- * @jack: jack status
- * @playback_cnt: active pb streams
- * @capture_cnt: active cp streams
- * @mad_jack_msg: wq struct for jack interrupt processing
- * @mad_jack_wq: wq for jack interrupt processing
- * @jack_prev_state: Previos state of jack detected
- * @cpu_id: current cpu id loaded for
- */
-struct snd_intelmad {
-	struct snd_card	*card; /* ptr to the card details */
-	int		card_index;/*  card index  */
-	char		*card_id; /* card id */
-	struct intel_sst_card_ops *sstdrv_ops;/* ptr to sst driver ops */
-	struct platform_device *pdev;
-	int irq;
-	int pmic_status;
-	void __iomem *int_base;
-	int output_sel;
-	int input_sel;
-	int lineout_sel;
-	int master_mute;
-	struct mad_jack jack[4];
-	int playback_cnt;
-	int capture_cnt;
-	u16 adc_address;
-	struct mad_jack_msg_wq  mad_jack_msg;
-	struct workqueue_struct *mad_jack_wq;
-	u8 jack_prev_state;
-	unsigned int cpu_id;
-};
-
-struct snd_control_val {
-	int	playback_vol_max;
-	int	playback_vol_min;
-	int	capture_vol_max;
-	int	capture_vol_min;
-	int	master_vol_max;
-	int	master_vol_min;
-};
-
-struct mad_stream_pvt {
-	int			stream_status;
-	int			stream_ops;
-	struct snd_pcm_substream *substream;
-	struct pcm_stream_info stream_info;
-	ssize_t		dbg_cum_bytes;
-	enum snd_sst_device_type device;
-};
-
-enum mad_drv_status {
-    INIT = 1,
-    STARTED,
-    RUNNING,
-    PAUSED,
-    DROPPED,
-};
-
-enum mad_pmic_status {
-	PMIC_UNINIT = 1,
-	PMIC_INIT,
-};
-enum _widget_ctrl {
-	OUTPUT_SEL = 1,
-	INPUT_SEL,
-	PLAYBACK_VOL,
-	PLAYBACK_MUTE,
-	CAPTURE_VOL,
-	CAPTURE_MUTE,
-	MASTER_VOL,
-	MASTER_MUTE
-};
-enum _widget_ctrl_mfld {
-	LINEOUT_SEL_MFLD = 3,
-};
-enum hw_chs {
-	HW_CH0 = 0,
-	HW_CH1,
-	HW_CH2,
-	HW_CH3
-};
-
-void period_elapsed(void *mad_substream);
-int snd_intelmad_alloc_stream(struct snd_pcm_substream *substream);
-int snd_intelmad_init_stream(struct snd_pcm_substream *substream);
-
-int sst_sc_reg_access(struct sc_reg_access *sc_access,
-					int type, int num_val);
-#define CPU_CHIP_LINCROFT       1 /* System running lincroft */
-#define CPU_CHIP_PENWELL        2 /* System running penwell */
-
-extern struct snd_control_val intelmad_ctrl_val[];
-extern struct snd_kcontrol_new snd_intelmad_controls_mrst[];
-extern struct snd_kcontrol_new snd_intelmad_controls_mfld[];
-extern struct snd_pmic_ops *intelmad_vendor_ops[];
-void sst_mad_send_jack_report(struct snd_jack *jack,
-			int buttonpressevent , int status);
-
-#endif /* __INTELMID_H */
diff --git a/drivers/staging/intel_sst/intelmid_adc_control.h b/drivers/staging/intel_sst/intelmid_adc_control.h
deleted file mode 100644
index 65d5c39..0000000
--- a/drivers/staging/intel_sst/intelmid_adc_control.h
+++ /dev/null
@@ -1,193 +0,0 @@
-#ifndef __INTELMID_ADC_CONTROL_H__
-#define __INTELMID_ADC_CONTROL_H_
-/*
- *  intelmid_adc_control.h - Intel SST Driver for audio engine
- *
- *  Copyright (C) 2008-10 Intel Corporation
- *  Authors:	R Durgadadoss <r.durgadoss@intel.com>
- *		Dharageswari R <dharageswari.r@intel.com>
- *  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; version 2 of the License.
- *
- *  This program is distributed in the hope that it will be useful, but
- *  WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *  General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License along
- *  with this program; if not, write to the Free Software Foundation, Inc.,
- *  59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
- *
- * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- *
- *  Common private ADC declarations for SST
- */
-
-
-#define MSIC_ADC1CNTL1		0x1C0
-#define MSIC_ADC_ENBL		0x10
-#define MSIC_ADC_START		0x08
-
-#define MSIC_ADC1CNTL3		0x1C2
-#define MSIC_ADCTHERM_ENBL	0x04
-#define MSIC_ADCRRDATA_ENBL	0x05
-
-#define MSIC_STOPBIT_MASK	16
-#define MSIC_ADCTHERM_MASK	4
-
-#define ADC_CHANLS_MAX		15 /* Number of ADC channels */
-#define ADC_LOOP_MAX		(ADC_CHANLS_MAX - 1)
-
-/* ADC channel code values */
-#define AUDIO_DETECT_CODE	0x06
-
-/* ADC base addresses */
-#define ADC_CHNL_START_ADDR	0x1C5	/* increments by 1 */
-#define ADC_DATA_START_ADDR     0x1D4   /* increments by 2 */
-
-
-/**
- * configure_adc - enables/disables the ADC for conversion
- * @val: zero: disables the ADC non-zero:enables the ADC
- *
- * Enable/Disable the ADC depending on the argument
- *
- * Can sleep
- */
-static inline int configure_adc(int val)
-{
-	int ret;
-	struct sc_reg_access sc_access = {0,};
-
-
-	sc_access.reg_addr = MSIC_ADC1CNTL1;
-	ret = sst_sc_reg_access(&sc_access, PMIC_READ, 1);
-	if (ret)
-		return ret;
-
-	if (val)
-		/* Enable and start the ADC */
-		sc_access.value |= (MSIC_ADC_ENBL | MSIC_ADC_START);
-	else
-		/* Just stop the ADC */
-		sc_access.value &= (~MSIC_ADC_START);
-	sc_access.reg_addr = MSIC_ADC1CNTL1;
-	return sst_sc_reg_access(&sc_access, PMIC_WRITE, 1);
-}
-
-/**
- * reset_stopbit - sets the stop bit to 0 on the given channel
- * @addr: address of the channel
- *
- * Can sleep
- */
-static inline int reset_stopbit(uint16_t addr)
-{
-	int ret;
-	struct sc_reg_access sc_access = {0,};
-	sc_access.reg_addr = addr;
-	ret = sst_sc_reg_access(&sc_access, PMIC_READ, 1);
-	if (ret)
-		return ret;
-	/* Set the stop bit to zero */
-	sc_access.reg_addr = addr;
-	sc_access.value = (sc_access.value) & 0xEF;
-	return sst_sc_reg_access(&sc_access, PMIC_WRITE, 1);
-}
-
-/**
- * find_free_channel - finds an empty channel for conversion
- *
- * If the ADC is not enabled then start using 0th channel
- * itself. Otherwise find an empty channel by looking for a
- * channel in which the stopbit is set to 1. returns the index
- * of the first free channel if succeeds or an error code.
- *
- * Context: can sleep
- *
- */
-static inline int find_free_channel(void)
-{
-	int ret;
-	int i;
-
-	struct sc_reg_access sc_access = {0,};
-
-	/* check whether ADC is enabled */
-	sc_access.reg_addr = MSIC_ADC1CNTL1;
-	ret = sst_sc_reg_access(&sc_access, PMIC_READ, 1);
-	if (ret)
-		return ret;
-
-	if ((sc_access.value & MSIC_ADC_ENBL) == 0)
-		return 0;
-
-	/* ADC is already enabled; Looking for an empty channel */
-	for (i = 0; i < ADC_CHANLS_MAX; i++) {
-
-		sc_access.reg_addr = ADC_CHNL_START_ADDR + i;
-		ret = sst_sc_reg_access(&sc_access, PMIC_READ, 1);
-		if (ret)
-			return ret;
-
-		if (sc_access.value & MSIC_STOPBIT_MASK) {
-			ret = i;
-			break;
-		}
-	}
-	return (ret > ADC_LOOP_MAX) ? (-EINVAL) : ret;
-}
-
-/**
- * mid_initialize_adc - initializing the ADC
- * @dev: our device structure
- *
- * Initialize the ADC for reading thermistor values. Can sleep.
- */
-static inline int mid_initialize_adc(void)
-{
-	int base_addr, chnl_addr;
-	int ret;
-	static int channel_index;
-	struct sc_reg_access sc_access = {0,};
-
-	/* Index of the first channel in which the stop bit is set */
-	channel_index = find_free_channel();
-	if (channel_index < 0) {
-		pr_err("No free ADC channels");
-		return channel_index;
-	}
-
-	base_addr = ADC_CHNL_START_ADDR + channel_index;
-
-	if (!(channel_index == 0 || channel_index == ADC_LOOP_MAX)) {
-		/* Reset stop bit for channels other than 0 and 12 */
-		ret = reset_stopbit(base_addr);
-		if (ret)
-			return ret;
-
-		/* Index of the first free channel */
-		base_addr++;
-		channel_index++;
-	}
-
-	/* Since this is the last channel, set the stop bit
-	   to 1 by ORing the DIE_SENSOR_CODE with 0x10 */
-	sc_access.reg_addr = base_addr;
-	sc_access.value = AUDIO_DETECT_CODE | 0x10;
-	ret = sst_sc_reg_access(&sc_access, PMIC_WRITE, 1);
-	if (ret) {
-		pr_err("unable to enable ADC");
-		return ret;
-	}
-
-	chnl_addr = ADC_DATA_START_ADDR + 2 * channel_index;
-	pr_debug("mid_initialize : %x", chnl_addr);
-	configure_adc(1);
-	return chnl_addr;
-}
-#endif
-
diff --git a/drivers/staging/intel_sst/intelmid_ctrl.c b/drivers/staging/intel_sst/intelmid_ctrl.c
deleted file mode 100644
index 19ec474..0000000
--- a/drivers/staging/intel_sst/intelmid_ctrl.c
+++ /dev/null
@@ -1,921 +0,0 @@
-/*
- *  intelmid_ctrl.c - Intel Sound card driver for MID
- *
- *  Copyright (C) 2008-10 Intel Corp
- *  Authors:	Harsha Priya <priya.harsha@intel.com>
- *		Vinod Koul <vinod.koul@intel.com>
- *		Dharageswari R <dharageswari.r@intel.com>
- *		KP Jeeja <jeeja.kp@intel.com>
- *  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation version 2 of the License.
- *
- *  This program is distributed in the hope that it will be useful, but
- *  WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *  General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License along
- *  with this program; if not, write to the Free Software Foundation, Inc.,
- *  59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
- *
- * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- *  ALSA driver handling mixer controls for Intel MAD chipset
- */
-
-#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
-
-#include <sound/core.h>
-#include <sound/control.h>
-#include "intel_sst.h"
-#include "intel_sst_ioctl.h"
-#include "intelmid_snd_control.h"
-#include "intelmid.h"
-
-#define HW_CH_BASE 4
-
-
-#define HW_CH_0	"Hw1"
-#define HW_CH_1	"Hw2"
-#define HW_CH_2	"Hw3"
-#define HW_CH_3	"Hw4"
-
-static char *router_dmics[] = {	"DMIC1",
-				"DMIC2",
-				"DMIC3",
-				"DMIC4",
-				"DMIC5",
-				"DMIC6"
-				};
-
-static char *out_names_mrst[] = {"Headphones",
-				"Internal speakers"};
-static char *in_names_mrst[] = {"AMIC",
-				"DMIC",
-				"HS_MIC"};
-static char *line_out_names_mfld[] = {"Headset",
-				"IHF    ",
-				"Vibra1 ",
-				"Vibra2 ",
-				"NONE   "};
-static char *out_names_mfld[] = {"Headset ",
-				"EarPiece  "};
-static char *in_names_mfld[] = {"AMIC",
-				"DMIC"};
-
-struct snd_control_val intelmad_ctrl_val[MAX_VENDORS] = {
-	{
-		.playback_vol_max = 63,
-		.playback_vol_min = 0,
-		.capture_vol_max = 63,
-		.capture_vol_min = 0,
-	},
-	{
-		.playback_vol_max = 0,
-		.playback_vol_min = -31,
-		.capture_vol_max = 0,
-		.capture_vol_min = -20,
-	},
-	{
-		.playback_vol_max = 0,
-		.playback_vol_min = -31,
-		.capture_vol_max = 0,
-		.capture_vol_min = -31,
-		.master_vol_max = 0,
-		.master_vol_min = -126,
-	},
-};
-
-/* control path functionalities */
-
-static inline int snd_intelmad_volume_info(struct snd_ctl_elem_info *uinfo,
-					int control_type, int max, int min)
-{
-	WARN_ON(!uinfo);
-
-	uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
-	uinfo->count = control_type;
-	uinfo->value.integer.min = min;
-	uinfo->value.integer.max = max;
-	return 0;
-}
-
-/**
-* snd_intelmad_mute_info - provides information about the mute controls
-*
-* @kcontrol:	pointer to the control
-* @uinfo:	pointer to the structure where the control's info need
-*		to be filled
-*
-* This function is called when a mixer application requests for control's info
-*/
-static int snd_intelmad_mute_info(struct snd_kcontrol *kcontrol,
-					struct snd_ctl_elem_info *uinfo)
-{
-	WARN_ON(!uinfo);
-	WARN_ON(!kcontrol);
-
-	/* set up the mute as a boolean mono control with min-max values */
-	uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
-	uinfo->count = MONO_CNTL;
-	uinfo->value.integer.min = MIN_MUTE;
-	uinfo->value.integer.max = MAX_MUTE;
-	return 0;
-}
-
-/**
-* snd_intelmad_capture_volume_info - provides info about the volume control
-*
-* @kcontrol:	pointer to the control
-* @uinfo:	pointer to the structure where the control's info need
-*		to be filled
-*
-* This function is called when a mixer application requests for control's info
-*/
-static int snd_intelmad_capture_volume_info(struct snd_kcontrol *kcontrol,
-					struct snd_ctl_elem_info *uinfo)
-{
-	snd_intelmad_volume_info(uinfo, MONO_CNTL,
-		intelmad_ctrl_val[sst_card_vendor_id].capture_vol_max,
-		intelmad_ctrl_val[sst_card_vendor_id].capture_vol_min);
-	return 0;
-}
-
-/**
-* snd_intelmad_playback_volume_info - provides info about the volume control
-*
-* @kcontrol:	pointer to the control
-* @uinfo:	pointer to the structure where the control's info need
-*		to be filled
-*
-* This function is called when a mixer application requests for control's info
-*/
-static int snd_intelmad_playback_volume_info(struct snd_kcontrol *kcontrol,
-					struct snd_ctl_elem_info *uinfo)
-{
-	snd_intelmad_volume_info(uinfo, STEREO_CNTL,
-		intelmad_ctrl_val[sst_card_vendor_id].playback_vol_max,
-		intelmad_ctrl_val[sst_card_vendor_id].playback_vol_min);
-	return 0;
-}
-
-static int snd_intelmad_master_volume_info(struct snd_kcontrol *kcontrol,
-					struct snd_ctl_elem_info *uinfo)
-{
-	snd_intelmad_volume_info(uinfo, STEREO_CNTL,
-		intelmad_ctrl_val[sst_card_vendor_id].master_vol_max,
-		intelmad_ctrl_val[sst_card_vendor_id].master_vol_min);
-	return 0;
-}
-
-/**
-* snd_intelmad_device_info_mrst - provides information about the devices available
-*
-* @kcontrol:	pointer to the control
-* @uinfo:	pointer to the structure where the devices's info need
-*		to be filled
-*
-* This function is called when a mixer application requests for device's info
-*/
-static int snd_intelmad_device_info_mrst(struct snd_kcontrol *kcontrol,
-					struct snd_ctl_elem_info *uinfo)
-{
-
-	WARN_ON(!kcontrol);
-	WARN_ON(!uinfo);
-
-	/* setup device select as drop down controls with different values */
-	if (kcontrol->id.numid == OUTPUT_SEL)
-		uinfo->value.enumerated.items = ARRAY_SIZE(out_names_mrst);
-	else
-		uinfo->value.enumerated.items = ARRAY_SIZE(in_names_mrst);
-	uinfo->count = MONO_CNTL;
-	uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
-
-	if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items)
-		uinfo->value.enumerated.item = 1;
-	if (kcontrol->id.numid == OUTPUT_SEL)
-		strncpy(uinfo->value.enumerated.name,
-			out_names_mrst[uinfo->value.enumerated.item],
-			sizeof(uinfo->value.enumerated.name)-1);
-	else
-		strncpy(uinfo->value.enumerated.name,
-			in_names_mrst[uinfo->value.enumerated.item],
-			sizeof(uinfo->value.enumerated.name)-1);
-	return 0;
-}
-
-static int snd_intelmad_device_info_mfld(struct snd_kcontrol *kcontrol,
-					struct snd_ctl_elem_info *uinfo)
-{
-	struct snd_pmic_ops *scard_ops;
-	struct snd_intelmad *intelmaddata;
-
-	WARN_ON(!kcontrol);
-	WARN_ON(!uinfo);
-
-	intelmaddata = kcontrol->private_data;
-
-	WARN_ON(!intelmaddata->sstdrv_ops);
-
-	scard_ops = intelmaddata->sstdrv_ops->scard_ops;
-	/* setup device select as drop down controls with different values */
-	if (kcontrol->id.numid == OUTPUT_SEL)
-		uinfo->value.enumerated.items = ARRAY_SIZE(out_names_mfld);
-	else if (kcontrol->id.numid == INPUT_SEL)
-		uinfo->value.enumerated.items = ARRAY_SIZE(in_names_mfld);
-	else if (kcontrol->id.numid == LINEOUT_SEL_MFLD) {
-		uinfo->value.enumerated.items = ARRAY_SIZE(line_out_names_mfld);
-		scard_ops->line_out_names_cnt = uinfo->value.enumerated.items;
-	} else
-		return -EINVAL;
-	uinfo->count = MONO_CNTL;
-	uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
-
-	if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items)
-		uinfo->value.enumerated.item = 1;
-	if (kcontrol->id.numid == OUTPUT_SEL)
-		strncpy(uinfo->value.enumerated.name,
-			out_names_mfld[uinfo->value.enumerated.item],
-			sizeof(uinfo->value.enumerated.name)-1);
-	else if (kcontrol->id.numid == INPUT_SEL)
-		strncpy(uinfo->value.enumerated.name,
-			in_names_mfld[uinfo->value.enumerated.item],
-			sizeof(uinfo->value.enumerated.name)-1);
-	else if (kcontrol->id.numid == LINEOUT_SEL_MFLD)
-		strncpy(uinfo->value.enumerated.name,
-			line_out_names_mfld[uinfo->value.enumerated.item],
-			sizeof(uinfo->value.enumerated.name)-1);
-	else
-		return -EINVAL;
-	return 0;
-}
-
-/**
-* snd_intelmad_volume_get - gets the current volume for the control
-*
-* @kcontrol:	pointer to the control
-* @uval:	pointer to the structure where the control's info need
-*		to be filled
-*
-* This function is called when .get function of a control is invoked from app
-*/
-static int snd_intelmad_volume_get(struct snd_kcontrol *kcontrol,
-				struct snd_ctl_elem_value *uval)
-{
-	int ret_val = 0, cntl_list[2] = {0,};
-	int value = 0;
-	struct snd_intelmad *intelmaddata;
-	struct snd_pmic_ops *scard_ops;
-
-	pr_debug("snd_intelmad_volume_get called\n");
-
-	WARN_ON(!uval);
-	WARN_ON(!kcontrol);
-
-	intelmaddata = kcontrol->private_data;
-
-	WARN_ON(!intelmaddata->sstdrv_ops);
-
-	scard_ops = intelmaddata->sstdrv_ops->scard_ops;
-
-	WARN_ON(!scard_ops);
-
-	switch (kcontrol->id.numid) {
-	case PLAYBACK_VOL:
-		cntl_list[0] = PMIC_SND_RIGHT_PB_VOL;
-		cntl_list[1] = PMIC_SND_LEFT_PB_VOL;
-		break;
-
-	case CAPTURE_VOL:
-		cntl_list[0] = PMIC_SND_CAPTURE_VOL;
-		break;
-
-	case MASTER_VOL:
-		cntl_list[0] = PMIC_SND_RIGHT_MASTER_VOL;
-		cntl_list[1] = PMIC_SND_LEFT_MASTER_VOL;
-		break;
-	default:
-		return -EINVAL;
-	}
-
-	ret_val = scard_ops->get_vol(cntl_list[0], &value);
-	uval->value.integer.value[0] = value;
-
-	if (ret_val)
-		return ret_val;
-
-	if (kcontrol->id.numid == PLAYBACK_VOL ||
-		kcontrol->id.numid == MASTER_VOL) {
-		ret_val = scard_ops->get_vol(cntl_list[1], &value);
-		uval->value.integer.value[1] = value;
-	}
-	return ret_val;
-}
-
-/**
-* snd_intelmad_mute_get - gets the current mute status for the control
-*
-* @kcontrol:	pointer to the control
-* @uval:	pointer to the structure where the control's info need
-*		to be filled
-*
-* This function is called when .get function of a control is invoked from app
-*/
-static int snd_intelmad_mute_get(struct snd_kcontrol *kcontrol,
-					struct snd_ctl_elem_value *uval)
-{
-
-	int cntl_list = 0, ret_val = 0;
-	u8 value = 0;
-	struct snd_intelmad *intelmaddata;
-	struct snd_pmic_ops *scard_ops;
-
-	pr_debug("Mute_get called\n");
-
-	WARN_ON(!uval);
-	WARN_ON(!kcontrol);
-
-	intelmaddata = kcontrol->private_data;
-
-	WARN_ON(!intelmaddata->sstdrv_ops);
-
-	scard_ops = intelmaddata->sstdrv_ops->scard_ops;
-
-	WARN_ON(!scard_ops);
-
-	switch (kcontrol->id.numid) {
-	case PLAYBACK_MUTE:
-		if (intelmaddata->output_sel == STEREO_HEADPHONE)
-			cntl_list = PMIC_SND_LEFT_HP_MUTE;
-		else if ((intelmaddata->output_sel == INTERNAL_SPKR) ||
-			(intelmaddata->output_sel == MONO_EARPIECE))
-			cntl_list = PMIC_SND_LEFT_SPEAKER_MUTE;
-		break;
-
-	case CAPTURE_MUTE:
-		if (intelmaddata->input_sel == DMIC)
-			cntl_list = PMIC_SND_DMIC_MUTE;
-		else if (intelmaddata->input_sel == AMIC)
-			cntl_list = PMIC_SND_AMIC_MUTE;
-		else if (intelmaddata->input_sel == HS_MIC)
-			cntl_list = PMIC_SND_HP_MIC_MUTE;
-		break;
-	case MASTER_MUTE:
-		uval->value.integer.value[0] = intelmaddata->master_mute;
-		return 0;
-	default:
-		return -EINVAL;
-	}
-
-	ret_val = scard_ops->get_mute(cntl_list, &value);
-	uval->value.integer.value[0] = value;
-	return ret_val;
-}
-
-/**
-* snd_intelmad_volume_set - sets the volume control's info
-*
-* @kcontrol:	pointer to the control
-* @uval:	pointer to the structure where the control's info is
-*		available to be set
-*
-* This function is called when .set function of a control is invoked from app
-*/
-static int snd_intelmad_volume_set(struct snd_kcontrol *kcontrol,
-					struct snd_ctl_elem_value *uval)
-{
-
-	int ret_val, cntl_list[2] = {0,};
-	struct snd_intelmad *intelmaddata;
-	struct snd_pmic_ops *scard_ops;
-
-	pr_debug("volume set called:%ld %ld\n",
-			uval->value.integer.value[0],
-			uval->value.integer.value[1]);
-
-	WARN_ON(!uval);
-	WARN_ON(!kcontrol);
-
-	intelmaddata = kcontrol->private_data;
-
-	WARN_ON(!intelmaddata->sstdrv_ops);
-
-	scard_ops = intelmaddata->sstdrv_ops->scard_ops;
-
-	WARN_ON(!scard_ops);
-
-	switch (kcontrol->id.numid) {
-	case PLAYBACK_VOL:
-		cntl_list[0] = PMIC_SND_LEFT_PB_VOL;
-		cntl_list[1] = PMIC_SND_RIGHT_PB_VOL;
-		break;
-
-	case CAPTURE_VOL:
-		cntl_list[0] = PMIC_SND_CAPTURE_VOL;
-		break;
-
-	case MASTER_VOL:
-		cntl_list[0] = PMIC_SND_LEFT_MASTER_VOL;
-		cntl_list[1] = PMIC_SND_RIGHT_MASTER_VOL;
-		break;
-
-	default:
-		return -EINVAL;
-	}
-
-	ret_val = scard_ops->set_vol(cntl_list[0],
-				uval->value.integer.value[0]);
-	if (ret_val)
-		return ret_val;
-
-	if (kcontrol->id.numid == PLAYBACK_VOL ||
-		kcontrol->id.numid == MASTER_VOL)
-		ret_val = scard_ops->set_vol(cntl_list[1],
-				uval->value.integer.value[1]);
-	return ret_val;
-}
-
-/**
-* snd_intelmad_mute_set - sets the mute control's info
-*
-* @kcontrol:	pointer to the control
-* @uval:	pointer to the structure where the control's info is
-*		available to be set
-*
-* This function is called when .set function of a control is invoked from app
-*/
-static int snd_intelmad_mute_set(struct snd_kcontrol *kcontrol,
-					struct snd_ctl_elem_value *uval)
-{
-	int cntl_list[2] = {0,}, ret_val;
-	struct snd_intelmad *intelmaddata;
-	struct snd_pmic_ops *scard_ops;
-
-	pr_debug("snd_intelmad_mute_set called\n");
-
-	WARN_ON(!uval);
-	WARN_ON(!kcontrol);
-
-	intelmaddata = kcontrol->private_data;
-
-	WARN_ON(!intelmaddata->sstdrv_ops);
-
-	scard_ops = intelmaddata->sstdrv_ops->scard_ops;
-
-	WARN_ON(!scard_ops);
-
-	kcontrol->private_value = uval->value.integer.value[0];
-
-	switch (kcontrol->id.numid) {
-	case PLAYBACK_MUTE:
-		if (intelmaddata->output_sel == STEREO_HEADPHONE) {
-			cntl_list[0] = PMIC_SND_LEFT_HP_MUTE;
-			cntl_list[1] = PMIC_SND_RIGHT_HP_MUTE;
-		} else if ((intelmaddata->output_sel == INTERNAL_SPKR) ||
-				(intelmaddata->output_sel == MONO_EARPIECE)) {
-			cntl_list[0] = PMIC_SND_LEFT_SPEAKER_MUTE;
-			cntl_list[1] = PMIC_SND_RIGHT_SPEAKER_MUTE;
-		}
-		break;
-
-	case CAPTURE_MUTE:/*based on sel device mute the i/p dev*/
-		if (intelmaddata->input_sel == DMIC)
-			cntl_list[0] = PMIC_SND_DMIC_MUTE;
-		else if (intelmaddata->input_sel == AMIC)
-			cntl_list[0] = PMIC_SND_AMIC_MUTE;
-		else if (intelmaddata->input_sel == HS_MIC)
-			cntl_list[0] = PMIC_SND_HP_MIC_MUTE;
-		break;
-	case MASTER_MUTE:
-		cntl_list[0] = PMIC_SND_MUTE_ALL;
-		intelmaddata->master_mute = uval->value.integer.value[0];
-		break;
-	default:
-		return -EINVAL;
-	}
-
-	ret_val = scard_ops->set_mute(cntl_list[0],
-				uval->value.integer.value[0]);
-	if (ret_val)
-		return ret_val;
-
-	if (kcontrol->id.numid == PLAYBACK_MUTE)
-		ret_val = scard_ops->set_mute(cntl_list[1],
-					uval->value.integer.value[0]);
-	return ret_val;
-}
-
-/**
-* snd_intelmad_device_get - get the device select control's info
-*
-* @kcontrol:	pointer to the control
-* @uval:	pointer to the structure where the control's info is
-*		to be filled
-*
-* This function is called when .get function of a control is invoked from app
-*/
-static int snd_intelmad_device_get(struct snd_kcontrol *kcontrol,
-					struct snd_ctl_elem_value *uval)
-{
-	struct snd_intelmad *intelmaddata;
-	struct snd_pmic_ops *scard_ops;
-	pr_debug("device_get called\n");
-
-	WARN_ON(!uval);
-	WARN_ON(!kcontrol);
-
-	intelmaddata = kcontrol->private_data;
-	scard_ops = intelmaddata->sstdrv_ops->scard_ops;
-	if (intelmaddata->cpu_id == CPU_CHIP_PENWELL) {
-		if (kcontrol->id.numid == OUTPUT_SEL)
-			uval->value.enumerated.item[0] =
-					scard_ops->output_dev_id;
-		else if (kcontrol->id.numid == INPUT_SEL)
-			uval->value.enumerated.item[0] =
-					scard_ops->input_dev_id;
-		else if (kcontrol->id.numid == LINEOUT_SEL_MFLD)
-			uval->value.enumerated.item[0] =
-					scard_ops->lineout_dev_id;
-		else
-			return -EINVAL;
-	} else if (intelmaddata->cpu_id == CPU_CHIP_LINCROFT) {
-		if (kcontrol->id.numid == OUTPUT_SEL)
-			/* There is a mismatch here.
-			 * ALSA expects 1 for internal speaker.
-			 * But internally, we may give 2 for internal speaker.
-			 */
-			if (scard_ops->output_dev_id == MONO_EARPIECE ||
-			    scard_ops->output_dev_id == INTERNAL_SPKR)
-				uval->value.enumerated.item[0] = MONO_EARPIECE;
-			else if (scard_ops->output_dev_id == STEREO_HEADPHONE)
-				uval->value.enumerated.item[0] =
-					STEREO_HEADPHONE;
-			else
-				return -EINVAL;
-		else if (kcontrol->id.numid == INPUT_SEL)
-			uval->value.enumerated.item[0] =
-					scard_ops->input_dev_id;
-		else
-			return -EINVAL;
-	} else
-	uval->value.enumerated.item[0] = kcontrol->private_value;
-	return 0;
-}
-
-/**
-* snd_intelmad_device_set - set the device select control's info
-*
-* @kcontrol:	pointer to the control
-* @uval:	pointer to the structure where the control's info is
-*		available to be set
-*
-* This function is called when .set function of a control is invoked from app
-*/
-static int snd_intelmad_device_set(struct snd_kcontrol *kcontrol,
-					struct snd_ctl_elem_value *uval)
-{
-	struct snd_intelmad *intelmaddata;
-	struct snd_pmic_ops *scard_ops;
-	int ret_val = 0, vendor, status;
-	struct intel_sst_pcm_control *pcm_control;
-
-	pr_debug("snd_intelmad_device_set called\n");
-
-	WARN_ON(!uval);
-	WARN_ON(!kcontrol);
-	status = -1;
-
-	intelmaddata = kcontrol->private_data;
-
-	WARN_ON(!intelmaddata->sstdrv_ops);
-
-	scard_ops = intelmaddata->sstdrv_ops->scard_ops;
-
-	WARN_ON(!scard_ops);
-
-	/* store value with driver */
-	kcontrol->private_value = uval->value.enumerated.item[0];
-
-	switch (kcontrol->id.numid) {
-	case OUTPUT_SEL:
-		ret_val = scard_ops->set_output_dev(
-				uval->value.enumerated.item[0]);
-		intelmaddata->output_sel = uval->value.enumerated.item[0];
-		break;
-	case INPUT_SEL:
-		vendor = intelmaddata->sstdrv_ops->vendor_id;
-		if ((vendor == SND_MX) || (vendor == SND_FS)) {
-			pcm_control = intelmaddata->sstdrv_ops->pcm_control;
-			if (uval->value.enumerated.item[0] == HS_MIC)
-				status = 1;
-			else
-				status = 0;
-			pcm_control->device_control(
-					SST_ENABLE_RX_TIME_SLOT, &status);
-		}
-		ret_val = scard_ops->set_input_dev(
-				uval->value.enumerated.item[0]);
-		intelmaddata->input_sel = uval->value.enumerated.item[0];
-		break;
-	case LINEOUT_SEL_MFLD:
-		ret_val = scard_ops->set_lineout_dev(
-					uval->value.enumerated.item[0]);
-		intelmaddata->lineout_sel = uval->value.enumerated.item[0];
-		break;
-	default:
-		return -EINVAL;
-	}
-	kcontrol->private_value = uval->value.enumerated.item[0];
-	return ret_val;
-}
-
-static int snd_intelmad_device_dmic_get(struct snd_kcontrol *kcontrol,
-					struct snd_ctl_elem_value *uval)
-{
-	struct snd_intelmad *intelmaddata;
-	struct snd_pmic_ops *scard_ops;
-
-	WARN_ON(!uval);
-	WARN_ON(!kcontrol);
-
-	intelmaddata = kcontrol->private_data;
-	scard_ops = intelmaddata->sstdrv_ops->scard_ops;
-
-	if (scard_ops->input_dev_id != DMIC) {
-		pr_debug("input dev = 0x%x\n", scard_ops->input_dev_id);
-		return 0;
-	}
-
-	if (intelmaddata->cpu_id == CPU_CHIP_PENWELL)
-		uval->value.enumerated.item[0] = kcontrol->private_value;
-	else
-		pr_debug(" CPU id = 0x%xis invalid.\n",
-			intelmaddata->cpu_id);
-	return 0;
-}
-
-void msic_set_bit(u8 index, unsigned int *available_dmics)
-{
-	*available_dmics |= (1 << index);
-}
-
-void msic_clear_bit(u8 index, unsigned int *available_dmics)
-{
-	*available_dmics &= ~(1 << index);
-}
-
-int msic_is_set_bit(u8 index, unsigned int *available_dmics)
-{
-	int ret_val;
-
-	ret_val = (*available_dmics & (1 << index));
-	return ret_val;
-}
-
-static int snd_intelmad_device_dmic_set(struct snd_kcontrol *kcontrol,
-					struct snd_ctl_elem_value *uval)
-{
-	struct snd_intelmad *intelmaddata;
-	struct snd_pmic_ops *scard_ops;
-	int i, dmic_index;
-	unsigned int available_dmics;
-	int jump_count;
-	int max_dmics = ARRAY_SIZE(router_dmics);
-
-	WARN_ON(!uval);
-	WARN_ON(!kcontrol);
-
-	intelmaddata = kcontrol->private_data;
-	WARN_ON(!intelmaddata->sstdrv_ops);
-
-	scard_ops = intelmaddata->sstdrv_ops->scard_ops;
-	WARN_ON(!scard_ops);
-
-	if (scard_ops->input_dev_id != DMIC) {
-		pr_debug("input dev = 0x%x\n", scard_ops->input_dev_id);
-		return 0;
-	}
-
-	available_dmics = scard_ops->available_dmics;
-
-	if (kcontrol->private_value > uval->value.enumerated.item[0]) {
-		pr_debug("jump count -1.\n");
-		jump_count = -1;
-	} else {
-		pr_debug("jump count 1.\n");
-		jump_count = 1;
-	}
-
-	dmic_index =  uval->value.enumerated.item[0];
-	pr_debug("set function. dmic_index = %d, avl_dmic = 0x%x\n",
-			 dmic_index, available_dmics);
-	for (i = 0; i < max_dmics; i++) {
-		pr_debug("set function. loop index = 0x%x.  dmic_index = 0x%x\n",
-			 i, dmic_index);
-		if (!msic_is_set_bit(dmic_index, &available_dmics)) {
-			msic_clear_bit(kcontrol->private_value,
-						&available_dmics);
-			msic_set_bit(dmic_index, &available_dmics);
-			kcontrol->private_value = dmic_index;
-			scard_ops->available_dmics = available_dmics;
-			scard_ops->hw_dmic_map[kcontrol->id.numid-HW_CH_BASE] =
-				kcontrol->private_value;
-			scard_ops->set_hw_dmic_route
-				(kcontrol->id.numid-HW_CH_BASE);
-			return 0;
-		}
-
-		dmic_index += jump_count;
-
-		if (dmic_index > (max_dmics - 1) && jump_count == 1) {
-			pr_debug("Resettingthe dmic index to 0.\n");
-			dmic_index = 0;
-		} else if (dmic_index == -1 && jump_count == -1) {
-			pr_debug("Resetting the dmic index to 5.\n");
-			dmic_index = max_dmics - 1;
-		}
-	}
-
-	return -EINVAL;
-}
-
-static int snd_intelmad_device_dmic_info_mfld(struct snd_kcontrol *kcontrol,
-					struct snd_ctl_elem_info *uinfo)
-{
-	struct snd_intelmad *intelmaddata;
-	struct snd_pmic_ops *scard_ops;
-
-	uinfo->count                  = MONO_CNTL;
-	uinfo->type                   = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
-	uinfo->value.enumerated.items = ARRAY_SIZE(router_dmics);
-
-	intelmaddata = kcontrol->private_data;
-	WARN_ON(!intelmaddata->sstdrv_ops);
-
-	scard_ops = intelmaddata->sstdrv_ops->scard_ops;
-	WARN_ON(!scard_ops);
-
-	if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items)
-		uinfo->value.enumerated.item =
-			uinfo->value.enumerated.items - 1;
-
-	strncpy(uinfo->value.enumerated.name,
-	router_dmics[uinfo->value.enumerated.item],
-	sizeof(uinfo->value.enumerated.name)-1);
-
-
-	msic_set_bit(kcontrol->private_value, &scard_ops->available_dmics);
-	pr_debug("info function. avl_dmic = 0x%x",
-		scard_ops->available_dmics);
-
-	scard_ops->hw_dmic_map[kcontrol->id.numid-HW_CH_BASE] =
-		kcontrol->private_value;
-
-	return 0;
-}
-
-struct snd_kcontrol_new snd_intelmad_controls_mrst[MAX_CTRL] __devinitdata = {
-{
-	.iface		=	SNDRV_CTL_ELEM_IFACE_MIXER,
-	.name		=	"PCM Playback Source",
-	.access		=	SNDRV_CTL_ELEM_ACCESS_READWRITE,
-	.info		=	snd_intelmad_device_info_mrst,
-	.get		=	snd_intelmad_device_get,
-	.put		=	snd_intelmad_device_set,
-	.private_value	=	0,
-},
-{
-	.iface		=	SNDRV_CTL_ELEM_IFACE_MIXER,
-	.name		=	"PCM Capture Source",
-	.access		=	SNDRV_CTL_ELEM_ACCESS_READWRITE,
-	.info		=	snd_intelmad_device_info_mrst,
-	.get		=	snd_intelmad_device_get,
-	.put		=	snd_intelmad_device_set,
-	.private_value	=	0,
-},
-{
-	.iface		=	SNDRV_CTL_ELEM_IFACE_MIXER,
-	.name		=	"PCM Playback Volume",
-	.access		=	SNDRV_CTL_ELEM_ACCESS_READWRITE,
-	.info		=	snd_intelmad_playback_volume_info,
-	.get		=	snd_intelmad_volume_get,
-	.put		=	snd_intelmad_volume_set,
-	.private_value	=	0,
-},
-{
-	.iface		=	SNDRV_CTL_ELEM_IFACE_MIXER,
-	.name		=	"PCM Playback Switch",
-	.access		=	SNDRV_CTL_ELEM_ACCESS_READWRITE,
-	.info		=	snd_intelmad_mute_info,
-	.get		=	snd_intelmad_mute_get,
-	.put		=	snd_intelmad_mute_set,
-	.private_value	=	0,
-},
-{
-	.iface		=	SNDRV_CTL_ELEM_IFACE_MIXER,
-	.name		=	"PCM Capture Volume",
-	.access		=	SNDRV_CTL_ELEM_ACCESS_READWRITE,
-	.info		=	snd_intelmad_capture_volume_info,
-	.get		=	snd_intelmad_volume_get,
-	.put		=	snd_intelmad_volume_set,
-	.private_value	=	0,
-},
-{
-	.iface		=	SNDRV_CTL_ELEM_IFACE_MIXER,
-	.name		=	"PCM Capture Switch",
-	.access		=	SNDRV_CTL_ELEM_ACCESS_READWRITE,
-	.info		=	snd_intelmad_mute_info,
-	.get		=	snd_intelmad_mute_get,
-	.put		=	snd_intelmad_mute_set,
-	.private_value	=	0,
-},
-{
-	.iface		=	SNDRV_CTL_ELEM_IFACE_MIXER,
-	.name		=	"Master Playback Volume",
-	.access		=	SNDRV_CTL_ELEM_ACCESS_READWRITE,
-	.info		=	snd_intelmad_master_volume_info,
-	.get		=	snd_intelmad_volume_get,
-	.put		=	snd_intelmad_volume_set,
-	.private_value	=	0,
-},
-{
-	.iface		=	SNDRV_CTL_ELEM_IFACE_MIXER,
-	.name		=	"Master Playback Switch",
-	.access		=	SNDRV_CTL_ELEM_ACCESS_READWRITE,
-	.info		=	snd_intelmad_mute_info,
-	.get		=	snd_intelmad_mute_get,
-	.put		=	snd_intelmad_mute_set,
-	.private_value	=	0,
-},
-};
-
-struct snd_kcontrol_new
-snd_intelmad_controls_mfld[MAX_CTRL_MFLD] __devinitdata = {
-{
-	.iface		=	SNDRV_CTL_ELEM_IFACE_MIXER,
-	.name		=	"PCM Playback Source",
-	.access		=	SNDRV_CTL_ELEM_ACCESS_READWRITE,
-	.info		=	snd_intelmad_device_info_mfld,
-	.get		=	snd_intelmad_device_get,
-	.put		=	snd_intelmad_device_set,
-	.private_value	=	0,
-},
-{
-	.iface		=	SNDRV_CTL_ELEM_IFACE_MIXER,
-	.name		=	"PCM Capture Source",
-	.access		=	SNDRV_CTL_ELEM_ACCESS_READWRITE,
-	.info		=	snd_intelmad_device_info_mfld,
-	.get		=	snd_intelmad_device_get,
-	.put		=	snd_intelmad_device_set,
-	.private_value	=	0,
-},
-{
-	.iface		=	SNDRV_CTL_ELEM_IFACE_MIXER,
-	.name		=	"Line out",
-	.access		=	SNDRV_CTL_ELEM_ACCESS_READWRITE,
-	.info		=	snd_intelmad_device_info_mfld,
-	.get		=	snd_intelmad_device_get,
-	.put		=	snd_intelmad_device_set,
-	.private_value	=	0,
-},
-{
-	.iface		=	SNDRV_CTL_ELEM_IFACE_MIXER,
-	.name		=	HW_CH_0,
-	.access		=	SNDRV_CTL_ELEM_ACCESS_READWRITE,
-	.info		=	snd_intelmad_device_dmic_info_mfld,
-	.get		=	snd_intelmad_device_dmic_get,
-	.put		=	snd_intelmad_device_dmic_set,
-	.private_value	=	0
-},
-{
-	.iface		=	SNDRV_CTL_ELEM_IFACE_MIXER,
-	.name		=	HW_CH_1,
-	.access		=	SNDRV_CTL_ELEM_ACCESS_READWRITE,
-	.info		=	snd_intelmad_device_dmic_info_mfld,
-	.get		=	snd_intelmad_device_dmic_get,
-	.put		=	snd_intelmad_device_dmic_set,
-	.private_value	=	1
-},
-{
-	.iface		=	SNDRV_CTL_ELEM_IFACE_MIXER,
-	.name		=	HW_CH_2,
-	.access		=	SNDRV_CTL_ELEM_ACCESS_READWRITE,
-	.info		=	snd_intelmad_device_dmic_info_mfld,
-	.get		=	snd_intelmad_device_dmic_get,
-	.put		=	snd_intelmad_device_dmic_set,
-	.private_value	=	2
-},
-{
-	.iface		=	SNDRV_CTL_ELEM_IFACE_MIXER,
-	.name		=	HW_CH_3,
-	.access		=	SNDRV_CTL_ELEM_ACCESS_READWRITE,
-	.info		=	snd_intelmad_device_dmic_info_mfld,
-	.get		=	snd_intelmad_device_dmic_get,
-	.put		=	snd_intelmad_device_dmic_set,
-	.private_value	=	3
-}
-};
-
diff --git a/drivers/staging/intel_sst/intelmid_msic_control.c b/drivers/staging/intel_sst/intelmid_msic_control.c
deleted file mode 100644
index 70cdb16..0000000
--- a/drivers/staging/intel_sst/intelmid_msic_control.c
+++ /dev/null
@@ -1,1047 +0,0 @@
-/*
- *  intelmid_vm_control.c - Intel Sound card driver for MID
- *
- *  Copyright (C) 2010 Intel Corp
- *  Authors:	Vinod Koul <vinod.koul@intel.com>
- *
- *  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; version 2 of the License.
- *
- *  This program is distributed in the hope that it will be useful, but
- *  WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *  General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License along
- *  with this program; if not, write to the Free Software Foundation, Inc.,
- *  59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
- *
- * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- *
- * This file contains the control operations of msic vendors
- */
-
-#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
-
-#include <linux/pci.h>
-#include <linux/file.h>
-#include <linux/delay.h>
-#include <sound/control.h>
-#include "intel_sst.h"
-#include <linux/input.h>
-#include "intelmid_snd_control.h"
-#include "intelmid.h"
-
-#define AUDIOMUX12  0x24c
-#define AUDIOMUX34  0x24d
-
-static int msic_init_card(void)
-{
-	struct sc_reg_access sc_access[] = {
-		/* dmic configuration */
-		{0x241, 0x85, 0},
-		{0x242, 0x02, 0},
-		/* audio paths config */
-		{0x24C, 0x10, 0},
-		{0x24D, 0x32, 0},
-		/* PCM2 interface slots */
-		/* preconfigured slots for 0-5 both tx, rx */
-		{0x272, 0x10, 0},
-		{0x273, 0x32, 0},
-		{0x274, 0xFF, 0},
-		{0x275, 0x10, 0},
-		{0x276, 0x32, 0},
-		{0x277, 0x54, 0},
-		/*Sinc5 decimator*/
-		{0x24E, 0x28, 0},
-		/*TI vibra w/a settings*/
-		{0x384, 0x80, 0},
-		{0x385, 0x80, 0},
-		{0x267, 0x00, 0},
-		{0x261, 0x00, 0},
-		/* pcm port setting */
-		{0x278, 0x00, 0},
-		{0x27B, 0x01, 0},
-		{0x27C, 0x0a, 0},
-		/* Set vol HSLRVOLCTRL, IHFVOL */
-		{0x259, 0x08, 0},
-		{0x25A, 0x08, 0},
-		{0x25B, 0x08, 0},
-		{0x25C, 0x08, 0},
-		/* HSEPRXCTRL  Enable the headset left and right FIR filters  */
-		{0x250, 0x30, 0},
-		/* HSMIXER */
-		{0x256, 0x11, 0},
-		/* amic configuration */
-		{0x249, 0x01, 0x0},
-		{0x24A, 0x01, 0x0},
-		/* unmask ocaudio/accdet interrupts */
-		{0x1d, 0x00, 0x00},
-		{0x1e, 0x00, 0x00},
-	};
-	snd_msic_ops.card_status = SND_CARD_INIT_DONE;
-	sst_sc_reg_access(sc_access, PMIC_WRITE, 28);
-	snd_msic_ops.pb_on = 0;
-	snd_msic_ops.pbhs_on = 0;
-	snd_msic_ops.cap_on = 0;
-	snd_msic_ops.input_dev_id = DMIC; /*def dev*/
-	snd_msic_ops.output_dev_id = STEREO_HEADPHONE;
-	snd_msic_ops.jack_interrupt_status = false;
-	pr_debug("msic init complete!!\n");
-	return 0;
-}
-static int msic_line_out_restore(u8 value)
-{
-	struct sc_reg_access hs_drv_en[] = {
-		{0x25d, 0x03, 0x03},
-	};
-	struct sc_reg_access ep_drv_en[] = {
-		{0x25d, 0x40, 0x40},
-	};
-	struct sc_reg_access ihf_drv_en[] = {
-		{0x25d, 0x0c, 0x0c},
-	};
-	struct sc_reg_access vib1_drv_en[] = {
-		{0x25d, 0x10, 0x10},
-	};
-	struct sc_reg_access vib2_drv_en[] = {
-		{0x25d, 0x20, 0x20},
-	};
-	struct sc_reg_access pmode_enable[] = {
-		{0x381, 0x10, 0x10},
-	};
-	int retval = 0;
-
-	pr_debug("msic_lineout_restore_lineout_dev:%d\n", value);
-
-	switch (value) {
-	case HEADSET:
-		pr_debug("Selecting Lineout-HEADSET-restore\n");
-		if (snd_msic_ops.output_dev_id == STEREO_HEADPHONE)
-			retval = sst_sc_reg_access(hs_drv_en,
-							PMIC_READ_MODIFY, 1);
-		else
-			retval = sst_sc_reg_access(ep_drv_en,
-							PMIC_READ_MODIFY, 1);
-		break;
-	case IHF:
-		pr_debug("Selecting Lineout-IHF-restore\n");
-		retval = sst_sc_reg_access(ihf_drv_en, PMIC_READ_MODIFY, 1);
-		if (retval)
-			return retval;
-		retval = sst_sc_reg_access(pmode_enable, PMIC_READ_MODIFY, 1);
-		break;
-	case VIBRA1:
-		pr_debug("Selecting Lineout-Vibra1-restore\n");
-		retval = sst_sc_reg_access(vib1_drv_en, PMIC_READ_MODIFY, 1);
-		break;
-	case VIBRA2:
-		pr_debug("Selecting Lineout-VIBRA2-restore\n");
-		retval = sst_sc_reg_access(vib2_drv_en, PMIC_READ_MODIFY, 1);
-		break;
-	case NONE:
-		pr_debug("Selecting Lineout-NONE-restore\n");
-		break;
-	default:
-		return -EINVAL;
-	}
-	return retval;
-}
-static int msic_get_lineout_prvstate(void)
-{
-	struct sc_reg_access hs_ihf_drv[2] = {
-		{0x257, 0x0, 0x0},
-		{0x25d, 0x0, 0x0},
-	};
-	struct sc_reg_access vib1drv[2] = {
-		{0x264, 0x0, 0x0},
-		{0x25D, 0x0, 0x0},
-	};
-	struct sc_reg_access vib2drv[2] = {
-		{0x26A, 0x0, 0x0},
-		{0x25D, 0x0, 0x0},
-	};
-	int retval = 0, drv_en, dac_en, dev_id, mask;
-	for (dev_id = 0; dev_id < snd_msic_ops.line_out_names_cnt; dev_id++) {
-		switch (dev_id) {
-		case HEADSET:
-			pr_debug("msic_get_lineout_prvs_state: HEADSET\n");
-			sst_sc_reg_access(hs_ihf_drv, PMIC_READ, 2);
-
-			mask = (MASK0|MASK1);
-			dac_en = (hs_ihf_drv[0].value) & mask;
-
-			mask = ((MASK0|MASK1)|MASK6);
-			drv_en = (hs_ihf_drv[1].value) & mask;
-
-			if (dac_en && (!drv_en)) {
-				snd_msic_ops.prev_lineout_dev_id = HEADSET;
-				return retval;
-			}
-			break;
-		case IHF:
-			pr_debug("msic_get_lineout_prvstate: IHF\n");
-			sst_sc_reg_access(hs_ihf_drv, PMIC_READ, 2);
-
-			mask = (MASK2 | MASK3);
-			dac_en = (hs_ihf_drv[0].value) & mask;
-
-			mask = (MASK2 | MASK3);
-			drv_en = (hs_ihf_drv[1].value) & mask;
-
-			if (dac_en && (!drv_en)) {
-				snd_msic_ops.prev_lineout_dev_id = IHF;
-				return retval;
-			}
-			break;
-		case VIBRA1:
-			pr_debug("msic_get_lineout_prvstate: vibra1\n");
-			sst_sc_reg_access(vib1drv, PMIC_READ, 2);
-
-			mask = MASK1;
-			dac_en = (vib1drv[0].value) & mask;
-
-			mask = MASK4;
-			drv_en = (vib1drv[1].value) & mask;
-
-			if (dac_en && (!drv_en)) {
-				snd_msic_ops.prev_lineout_dev_id = VIBRA1;
-				return retval;
-			}
-			break;
-		case VIBRA2:
-			pr_debug("msic_get_lineout_prvstate: vibra2\n");
-			sst_sc_reg_access(vib2drv, PMIC_READ, 2);
-
-			mask = MASK1;
-			dac_en = (vib2drv[0].value) & mask;
-
-			mask = MASK5;
-			drv_en = ((vib2drv[1].value) & mask);
-
-			if (dac_en && (!drv_en)) {
-				snd_msic_ops.prev_lineout_dev_id = VIBRA2;
-				return retval;
-			}
-			break;
-		case NONE:
-			pr_debug("msic_get_lineout_prvstate: NONE\n");
-			snd_msic_ops.prev_lineout_dev_id = NONE;
-			return retval;
-		default:
-			pr_debug("Invalid device id\n");
-			snd_msic_ops.prev_lineout_dev_id = NONE;
-			return -EINVAL;
-		}
-	}
-	return retval;
-}
-static int msic_set_selected_lineout_dev(u8 value)
-{
-	struct sc_reg_access lout_hs[] = {
-		{0x25e, 0x33, 0xFF},
-		{0x25d, 0x0, 0x43},
-	};
-	struct sc_reg_access lout_ihf[] = {
-		{0x25e, 0x55, 0xff},
-		{0x25d, 0x0, 0x0c},
-	};
-	struct sc_reg_access lout_vibra1[] = {
-
-		{0x25e, 0x61, 0xff},
-		{0x25d, 0x0, 0x10},
-	};
-	struct sc_reg_access lout_vibra2[] = {
-
-		{0x25e, 0x16, 0xff},
-		{0x25d, 0x0, 0x20},
-	};
-	struct sc_reg_access lout_def[] = {
-		{0x25e, 0x66, 0x0},
-	};
-	struct sc_reg_access pmode_disable[] = {
-		{0x381, 0x00, 0x10},
-	};
-	struct sc_reg_access pmode_enable[] = {
-		{0x381, 0x10, 0x10},
-	};
-	int retval = 0;
-
-	pr_debug("msic_set_selected_lineout_dev:%d\n", value);
-	msic_get_lineout_prvstate();
-	msic_line_out_restore(snd_msic_ops.prev_lineout_dev_id);
-	snd_msic_ops.lineout_dev_id = value;
-
-	switch (value) {
-	case HEADSET:
-		pr_debug("Selecting Lineout-HEADSET\n");
-		if (snd_msic_ops.pb_on)
-			retval = sst_sc_reg_access(lout_hs,
-					PMIC_READ_MODIFY, 2);
-			if (retval)
-				return retval;
-			retval = sst_sc_reg_access(pmode_disable,
-					PMIC_READ_MODIFY, 1);
-		break;
-	case IHF:
-		pr_debug("Selecting Lineout-IHF\n");
-		if (snd_msic_ops.pb_on)
-			retval = sst_sc_reg_access(lout_ihf,
-							PMIC_READ_MODIFY, 2);
-			if (retval)
-				return retval;
-			retval = sst_sc_reg_access(pmode_enable,
-					PMIC_READ_MODIFY, 1);
-		break;
-	case VIBRA1:
-		pr_debug("Selecting Lineout-Vibra1\n");
-		if (snd_msic_ops.pb_on)
-			retval = sst_sc_reg_access(lout_vibra1,
-							PMIC_READ_MODIFY, 2);
-			if (retval)
-				return retval;
-			retval = sst_sc_reg_access(pmode_disable,
-					PMIC_READ_MODIFY, 1);
-		break;
-	case VIBRA2:
-		pr_debug("Selecting Lineout-VIBRA2\n");
-		if (snd_msic_ops.pb_on)
-			retval = sst_sc_reg_access(lout_vibra2,
-							PMIC_READ_MODIFY, 2);
-			if (retval)
-				return retval;
-			retval = sst_sc_reg_access(pmode_disable,
-					PMIC_READ_MODIFY, 1);
-		break;
-	case NONE:
-		pr_debug("Selecting Lineout-NONE\n");
-			retval = sst_sc_reg_access(lout_def,
-							PMIC_WRITE, 1);
-			if (retval)
-				return retval;
-			retval = sst_sc_reg_access(pmode_disable,
-					PMIC_READ_MODIFY, 1);
-		break;
-	default:
-		return -EINVAL;
-	}
-	return retval;
-}
-
-
-static int msic_power_up_pb(unsigned int device)
-{
-	struct sc_reg_access vaud[] = {
-		/* turn on the audio power supplies */
-		{0x0DB, 0x07, 0},
-	};
-	struct sc_reg_access pll[] = {
-		/* turn on PLL */
-		{0x240, 0x20, 0},
-	};
-	struct sc_reg_access vhs[] = {
-		/*  VHSP */
-		{0x0DC, 0x3D, 0},
-		/*  VHSN */
-		{0x0DD, 0x3F, 0},
-	};
-	struct sc_reg_access hsdac[] = {
-		{0x382, 0x40, 0x40},
-		/*  disable driver */
-		{0x25D, 0x0, 0x43},
-		/* DAC CONFIG ; both HP, LP on */
-		{0x257, 0x03, 0x03},
-	};
-	struct sc_reg_access hs_filter[] = {
-		/* HSEPRXCTRL  Enable the headset left and right FIR filters  */
-		{0x250, 0x30, 0},
-		/* HSMIXER */
-		{0x256, 0x11, 0},
-	};
-	struct sc_reg_access hs_enable[] = {
-		/* enable driver */
-		{0x25D, 0x3, 0x3},
-		{0x26C, 0x0, 0x2},
-		/* unmute the headset */
-		{ 0x259, 0x80, 0x80},
-		{ 0x25A, 0x80, 0x80},
-	};
-	struct sc_reg_access vihf[] = {
-		/*  VIHF ON */
-		{0x0C9, 0x27, 0x00},
-	};
-	struct sc_reg_access ihf_filter[] = {
-		/*  disable driver */
-		{0x25D, 0x00, 0x0C},
-		/*Filer DAC enable*/
-		{0x251, 0x03, 0x03},
-		{0x257, 0x0C, 0x0C},
-	};
-	struct sc_reg_access ihf_en[] = {
-		/*enable drv*/
-		{0x25D, 0x0C, 0x0c},
-	};
-	struct sc_reg_access ihf_unmute[] = {
-		/*unmute headset*/
-		{0x25B, 0x80, 0x80},
-		{0x25C, 0x80, 0x80},
-	};
-	struct sc_reg_access epdac[] = {
-		/*  disable driver */
-		{0x25D, 0x0, 0x43},
-		/* DAC CONFIG ; both HP, LP on */
-		{0x257, 0x03, 0x03},
-	};
-	struct sc_reg_access ep_enable[] = {
-		/* enable driver */
-		{0x25D, 0x40, 0x40},
-		/* unmute the headset */
-		{ 0x259, 0x80, 0x80},
-		{ 0x25A, 0x80, 0x80},
-	};
-	struct sc_reg_access vib1_en[] = {
-		/* enable driver, ADC */
-		{0x25D, 0x10, 0x10},
-		{0x264, 0x02, 0x82},
-	};
-	struct sc_reg_access vib2_en[] = {
-		/* enable driver, ADC */
-		{0x25D, 0x20, 0x20},
-		{0x26A, 0x02, 0x82},
-	};
-	struct sc_reg_access pcm2_en[] = {
-		/* enable pcm 2 */
-		{0x27C, 0x1, 0x1},
-	};
-	int retval = 0;
-
-	if (snd_msic_ops.card_status == SND_CARD_UN_INIT) {
-		retval = msic_init_card();
-		if (retval)
-			return retval;
-	}
-
-	pr_debug("powering up pb.... Device %d\n", device);
-	sst_sc_reg_access(vaud, PMIC_WRITE, 1);
-	msleep(1);
-	sst_sc_reg_access(pll, PMIC_WRITE, 1);
-	msleep(1);
-	switch (device) {
-	case SND_SST_DEVICE_HEADSET:
-		snd_msic_ops.pb_on = 1;
-		snd_msic_ops.pbhs_on = 1;
-		if (snd_msic_ops.output_dev_id == STEREO_HEADPHONE) {
-			sst_sc_reg_access(vhs, PMIC_WRITE, 2);
-			sst_sc_reg_access(hsdac, PMIC_READ_MODIFY, 3);
-			sst_sc_reg_access(hs_filter, PMIC_WRITE, 2);
-			sst_sc_reg_access(hs_enable, PMIC_READ_MODIFY, 4);
-		} else {
-			sst_sc_reg_access(epdac, PMIC_READ_MODIFY, 2);
-			sst_sc_reg_access(hs_filter, PMIC_WRITE, 2);
-			sst_sc_reg_access(ep_enable, PMIC_READ_MODIFY, 3);
-		}
-		if (snd_msic_ops.lineout_dev_id == HEADSET)
-			msic_set_selected_lineout_dev(HEADSET);
-		break;
-	case SND_SST_DEVICE_IHF:
-		snd_msic_ops.pb_on = 1;
-		sst_sc_reg_access(vihf, PMIC_WRITE, 1);
-		sst_sc_reg_access(ihf_filter, PMIC_READ_MODIFY, 3);
-		sst_sc_reg_access(ihf_en, PMIC_READ_MODIFY, 1);
-		sst_sc_reg_access(ihf_unmute, PMIC_READ_MODIFY, 2);
-		if (snd_msic_ops.lineout_dev_id == IHF)
-			msic_set_selected_lineout_dev(IHF);
-		break;
-
-	case SND_SST_DEVICE_VIBRA:
-		snd_msic_ops.pb_on = 1;
-		sst_sc_reg_access(vib1_en, PMIC_READ_MODIFY, 2);
-		if (snd_msic_ops.lineout_dev_id == VIBRA1)
-			msic_set_selected_lineout_dev(VIBRA1);
-		break;
-
-	case SND_SST_DEVICE_HAPTIC:
-		snd_msic_ops.pb_on = 1;
-		sst_sc_reg_access(vib2_en, PMIC_READ_MODIFY, 2);
-		if (snd_msic_ops.lineout_dev_id == VIBRA2)
-			msic_set_selected_lineout_dev(VIBRA2);
-		break;
-
-	default:
-		pr_warn("Wrong Device %d, selected %d\n",
-			       device, snd_msic_ops.output_dev_id);
-	}
-	return sst_sc_reg_access(pcm2_en, PMIC_READ_MODIFY, 1);
-}
-
-static int msic_power_up_cp(unsigned int device)
-{
-	struct sc_reg_access vaud[] = {
-		/* turn on the audio power supplies */
-		{0x0DB, 0x07, 0},
-	};
-	struct sc_reg_access pll[] = {
-		/* turn on PLL */
-		{0x240, 0x20, 0},
-	};
-	struct sc_reg_access dmic_bias[] = {
-		/*  Turn on AMIC supply  */
-		{0x247, 0xA0, 0xA0},
-	};
-	struct sc_reg_access dmic[] = {
-		/* mic demux enable */
-		{0x245, 0x3F, 0x3F},
-		{0x246, 0x07, 0x07},
-
-	};
-	struct sc_reg_access amic_bias[] = {
-		/*  Turn on AMIC supply  */
-		{0x247, 0xFC, 0xFC},
-	};
-	struct sc_reg_access amic[] = {
-		/*MIC EN*/
-		{0x249, 0x01, 0x01},
-		{0x24A, 0x01, 0x01},
-		/*ADC EN*/
-		{0x248, 0x05, 0x0F},
-
-	};
-	struct sc_reg_access pcm2[] = {
-		/* enable pcm 2 */
-		{0x27C, 0x1, 0x1},
-	};
-	struct sc_reg_access tx_on[] = {
-		/*wait for mic to stabalize before turning on audio channels*/
-		{0x24F, 0x3C, 0x0},
-	};
-	int retval = 0;
-
-	if (snd_msic_ops.card_status == SND_CARD_UN_INIT) {
-		retval = msic_init_card();
-		if (retval)
-			return retval;
-	}
-
-	pr_debug("powering up cp....%d\n", snd_msic_ops.input_dev_id);
-	sst_sc_reg_access(vaud, PMIC_WRITE, 1);
-	msleep(500);/*FIXME need optimzed value here*/
-	sst_sc_reg_access(pll, PMIC_WRITE, 1);
-	msleep(1);
-	snd_msic_ops.cap_on = 1;
-	if (snd_msic_ops.input_dev_id == AMIC) {
-		sst_sc_reg_access(amic_bias, PMIC_READ_MODIFY, 1);
-		msleep(1);
-		sst_sc_reg_access(amic, PMIC_READ_MODIFY, 3);
-	} else {
-		sst_sc_reg_access(dmic_bias, PMIC_READ_MODIFY, 1);
-		msleep(1);
-		sst_sc_reg_access(dmic, PMIC_READ_MODIFY, 2);
-	}
-	msleep(1);
-	sst_sc_reg_access(tx_on, PMIC_WRITE, 1);
-	return sst_sc_reg_access(pcm2, PMIC_READ_MODIFY, 1);
-}
-
-static int msic_power_down(void)
-{
-	struct sc_reg_access power_dn[] = {
-		/*  VHSP */
-		{0x0DC, 0xC4, 0},
-		/*  VHSN */
-		{0x0DD, 0x04, 0},
-		/*  VIHF */
-		{0x0C9, 0x24, 0},
-	};
-	struct sc_reg_access pll[] = {
-		/* turn off PLL*/
-		{0x240, 0x00, 0x0},
-	};
-	struct sc_reg_access vaud[] = {
-		/* turn off VAUD*/
-		{0x0DB, 0x04, 0},
-	};
-
-	pr_debug("powering dn msic\n");
-	snd_msic_ops.pbhs_on = 0;
-	snd_msic_ops.pb_on = 0;
-	snd_msic_ops.cap_on = 0;
-	sst_sc_reg_access(power_dn, PMIC_WRITE, 3);
-	msleep(1);
-	sst_sc_reg_access(pll, PMIC_WRITE, 1);
-	msleep(1);
-	sst_sc_reg_access(vaud, PMIC_WRITE, 1);
-	return 0;
-}
-
-static int msic_power_down_pb(unsigned int device)
-{
-	struct sc_reg_access drv_enable[] = {
-		{0x25D, 0x00, 0x00},
-	};
-	struct sc_reg_access hs_mute[] = {
-		{0x259, 0x80, 0x80},
-		{0x25A, 0x80, 0x80},
-		{0x26C, 0x02, 0x02},
-	};
-	struct sc_reg_access hs_off[] = {
-		{0x257, 0x00, 0x03},
-		{0x250, 0x00, 0x30},
-		{0x382, 0x00, 0x40},
-	};
-	struct sc_reg_access ihf_mute[] = {
-		{0x25B, 0x80, 0x80},
-		{0x25C, 0x80, 0x80},
-	};
-	struct sc_reg_access ihf_off[] = {
-		{0x257, 0x00, 0x0C},
-		{0x251, 0x00, 0x03},
-	};
-	struct sc_reg_access vib1_off[] = {
-		{0x264, 0x00, 0x82},
-	};
-	struct sc_reg_access vib2_off[] = {
-		{0x26A, 0x00, 0x82},
-	};
-	struct sc_reg_access lout_off[] = {
-		{0x25e, 0x66, 0x00},
-	};
-	struct sc_reg_access pmode_disable[] = {
-		{0x381, 0x00, 0x10},
-	};
-
-
-
-	pr_debug("powering dn pb for device %d\n", device);
-	switch (device) {
-	case SND_SST_DEVICE_HEADSET:
-		snd_msic_ops.pbhs_on = 0;
-		sst_sc_reg_access(hs_mute, PMIC_READ_MODIFY, 3);
-		drv_enable[0].mask = 0x43;
-		sst_sc_reg_access(drv_enable, PMIC_READ_MODIFY, 1);
-		sst_sc_reg_access(hs_off, PMIC_READ_MODIFY, 3);
-		if (snd_msic_ops.lineout_dev_id == HEADSET)
-			sst_sc_reg_access(lout_off, PMIC_WRITE, 1);
-		break;
-
-	case SND_SST_DEVICE_IHF:
-		sst_sc_reg_access(ihf_mute, PMIC_READ_MODIFY, 2);
-		drv_enable[0].mask = 0x0C;
-		sst_sc_reg_access(drv_enable, PMIC_READ_MODIFY, 1);
-		sst_sc_reg_access(ihf_off, PMIC_READ_MODIFY, 2);
-		if (snd_msic_ops.lineout_dev_id == IHF) {
-			sst_sc_reg_access(lout_off, PMIC_WRITE, 1);
-			sst_sc_reg_access(pmode_disable, PMIC_READ_MODIFY, 1);
-		}
-		break;
-
-	case SND_SST_DEVICE_VIBRA:
-		sst_sc_reg_access(vib1_off, PMIC_READ_MODIFY, 1);
-		drv_enable[0].mask = 0x10;
-		sst_sc_reg_access(drv_enable, PMIC_READ_MODIFY, 1);
-		if (snd_msic_ops.lineout_dev_id == VIBRA1)
-			sst_sc_reg_access(lout_off, PMIC_WRITE, 1);
-		break;
-
-	case SND_SST_DEVICE_HAPTIC:
-		sst_sc_reg_access(vib2_off, PMIC_READ_MODIFY, 1);
-		drv_enable[0].mask = 0x20;
-		sst_sc_reg_access(drv_enable, PMIC_READ_MODIFY, 1);
-		if (snd_msic_ops.lineout_dev_id == VIBRA2)
-			sst_sc_reg_access(lout_off, PMIC_WRITE, 1);
-		break;
-	}
-	return 0;
-}
-
-static int msic_power_down_cp(unsigned int device)
-{
-	struct sc_reg_access dmic[] = {
-		{0x247, 0x00, 0xA0},
-		{0x245, 0x00, 0x38},
-		{0x246, 0x00, 0x07},
-	};
-	struct sc_reg_access amic[] = {
-		{0x248, 0x00, 0x05},
-		{0x249, 0x00, 0x01},
-		{0x24A, 0x00, 0x01},
-		{0x247, 0x00, 0xA3},
-	};
-	struct sc_reg_access tx_off[] = {
-		{0x24F, 0x00, 0x3C},
-	};
-
-	pr_debug("powering dn cp....\n");
-	snd_msic_ops.cap_on = 0;
-	sst_sc_reg_access(tx_off, PMIC_READ_MODIFY, 1);
-	if (snd_msic_ops.input_dev_id == DMIC)
-		sst_sc_reg_access(dmic, PMIC_READ_MODIFY, 3);
-	else
-		sst_sc_reg_access(amic, PMIC_READ_MODIFY, 4);
-	return 0;
-}
-
-static int msic_set_selected_output_dev(u8 value)
-{
-	int retval = 0;
-
-	pr_debug("msic set selected output:%d\n", value);
-	snd_msic_ops.output_dev_id = value;
-	if (snd_msic_ops.pbhs_on)
-		msic_power_up_pb(SND_SST_DEVICE_HEADSET);
-	return retval;
-}
-
-static int msic_set_selected_input_dev(u8 value)
-{
-
-	struct sc_reg_access sc_access_dmic[] = {
-		{0x24C, 0x10, 0x0},
-	};
-	struct sc_reg_access sc_access_amic[] = {
-		{0x24C, 0x76, 0x0},
-
-	};
-	int retval = 0;
-
-	pr_debug("msic_set_selected_input_dev:%d\n", value);
-	snd_msic_ops.input_dev_id = value;
-	switch (value) {
-	case AMIC:
-		pr_debug("Selecting AMIC1\n");
-		retval = sst_sc_reg_access(sc_access_amic, PMIC_WRITE, 1);
-		break;
-	case DMIC:
-		pr_debug("Selecting DMIC1\n");
-		retval = sst_sc_reg_access(sc_access_dmic, PMIC_WRITE, 1);
-		break;
-	default:
-		return -EINVAL;
-
-	}
-	if (snd_msic_ops.cap_on)
-		retval = msic_power_up_cp(SND_SST_DEVICE_CAPTURE);
-	return retval;
-}
-
-static int msic_set_hw_dmic_route(u8 hw_ch_index)
-{
-	struct sc_reg_access sc_access_router;
-	int    retval = -EINVAL;
-
-	switch (hw_ch_index) {
-	case HW_CH0:
-		sc_access_router.reg_addr = AUDIOMUX12;
-		sc_access_router.value    = snd_msic_ops.hw_dmic_map[0];
-		sc_access_router.mask     = (MASK2 | MASK1 | MASK0);
-		pr_debug("hw_ch0.  value = 0x%x\n",
-				sc_access_router.value);
-		retval = sst_sc_reg_access(&sc_access_router,
-				PMIC_READ_MODIFY, 1);
-		break;
-
-	case HW_CH1:
-		sc_access_router.reg_addr = AUDIOMUX12;
-		sc_access_router.value    = (snd_msic_ops.hw_dmic_map[1]) << 4;
-		sc_access_router.mask     = (MASK6 | MASK5 | MASK4);
-		pr_debug("### hw_ch1.  value = 0x%x\n",
-				sc_access_router.value);
-		retval = sst_sc_reg_access(&sc_access_router,
-				PMIC_READ_MODIFY, 1);
-		break;
-
-	case HW_CH2:
-		sc_access_router.reg_addr = AUDIOMUX34;
-		sc_access_router.value    = snd_msic_ops.hw_dmic_map[2];
-		sc_access_router.mask     = (MASK2 | MASK1 | MASK0);
-		pr_debug("hw_ch2.  value = 0x%x\n",
-				sc_access_router.value);
-		retval = sst_sc_reg_access(&sc_access_router,
-				PMIC_READ_MODIFY, 1);
-		break;
-
-	case HW_CH3:
-		sc_access_router.reg_addr = AUDIOMUX34;
-		sc_access_router.value    = (snd_msic_ops.hw_dmic_map[3]) << 4;
-		sc_access_router.mask     = (MASK6 | MASK5 | MASK4);
-		pr_debug("hw_ch3.  value = 0x%x\n",
-				sc_access_router.value);
-		retval = sst_sc_reg_access(&sc_access_router,
-				PMIC_READ_MODIFY, 1);
-		break;
-	}
-
-	return retval;
-}
-
-
-static int msic_set_pcm_voice_params(void)
-{
-	return 0;
-}
-
-static int msic_set_pcm_audio_params(int sfreq, int word_size, int num_channel)
-{
-	return 0;
-}
-
-static int msic_set_audio_port(int status)
-{
-	return 0;
-}
-
-static int msic_set_voice_port(int status)
-{
-	return 0;
-}
-
-static int msic_set_mute(int dev_id, u8 value)
-{
-	return 0;
-}
-
-static int msic_set_vol(int dev_id, int value)
-{
-	return 0;
-}
-
-static int msic_get_mute(int dev_id, u8 *value)
-{
-	return 0;
-}
-
-static int msic_get_vol(int dev_id, int *value)
-{
-	return 0;
-}
-
-static int msic_set_headset_state(int state)
-{
-	struct sc_reg_access hs_enable[] = {
-		{0x25D, 0x03, 0x03},
-	};
-
-	if (state)
-		/*enable*/
-		sst_sc_reg_access(hs_enable, PMIC_READ_MODIFY, 1);
-	else {
-		hs_enable[0].value = 0;
-		sst_sc_reg_access(hs_enable, PMIC_READ_MODIFY, 1);
-	}
-	return 0;
-}
-
-static int msic_enable_mic_bias(void)
-{
-	struct sc_reg_access jack_interrupt_reg[] = {
-		{0x0DB, 0x07, 0x00},
-
-	};
-	struct sc_reg_access jack_bias_reg[] = {
-		{0x247, 0x0C, 0x0C},
-	};
-
-	sst_sc_reg_access(jack_interrupt_reg, PMIC_WRITE, 1);
-	sst_sc_reg_access(jack_bias_reg, PMIC_READ_MODIFY, 1);
-	return 0;
-}
-
-static int msic_disable_mic_bias(void)
-{
-	if (snd_msic_ops.jack_interrupt_status == true)
-		return 0;
-	if (!(snd_msic_ops.pb_on || snd_msic_ops.cap_on))
-		msic_power_down();
-	return 0;
-}
-
-static int msic_disable_jack_btn(void)
-{
-	struct sc_reg_access btn_disable[] = {
-		{0x26C, 0x00, 0x01}
-	};
-
-	if (!(snd_msic_ops.pb_on || snd_msic_ops.cap_on))
-		msic_power_down();
-	snd_msic_ops.jack_interrupt_status = false;
-	return sst_sc_reg_access(btn_disable, PMIC_READ_MODIFY, 1);
-}
-
-static int msic_enable_jack_btn(void)
-{
-	struct sc_reg_access btn_enable[] = {
-			{0x26b, 0x77, 0x00},
-			{0x26C, 0x01, 0x00},
-	};
-	return sst_sc_reg_access(btn_enable, PMIC_WRITE, 2);
-}
-static int msic_convert_adc_to_mvolt(unsigned int mic_bias)
-{
-	return (ADC_ONE_LSB_MULTIPLIER * mic_bias) / 1000;
-}
-int msic_get_headset_state(int mic_bias)
-{
-	struct sc_reg_access msic_hs_toggle[] = {
-		{0x070, 0x00, 0x01},
-	};
-	if (mic_bias >= 0 && mic_bias < 400) {
-
-		pr_debug("Detected Headphone!!!\n");
-		sst_sc_reg_access(msic_hs_toggle, PMIC_READ_MODIFY, 1);
-
-	} else if (mic_bias > 400 && mic_bias < 650) {
-
-		pr_debug("Detected American headset\n");
-		msic_hs_toggle[0].value = 0x01;
-		sst_sc_reg_access(msic_hs_toggle, PMIC_READ_MODIFY, 1);
-
-	} else if (mic_bias >= 650 && mic_bias < 2000) {
-
-		pr_debug("Detected Headset!!!\n");
-		sst_sc_reg_access(msic_hs_toggle, PMIC_READ_MODIFY, 1);
-		/*power on jack and btn*/
-		snd_msic_ops.jack_interrupt_status = true;
-		msic_enable_jack_btn();
-		msic_enable_mic_bias();
-		return SND_JACK_HEADSET;
-
-	} else
-		pr_debug("Detected Open Cable!!!\n");
-
-	return SND_JACK_HEADPHONE;
-}
-
-static int msic_get_mic_bias(void *arg)
-{
-	struct snd_intelmad *intelmad_drv = (struct snd_intelmad *)arg;
-	u16 adc_adr = intelmad_drv->adc_address;
-	u16 adc_val;
-	int ret;
-	struct sc_reg_access adc_ctrl3[2] = {
-			{0x1C2, 0x05, 0x0},
-	};
-
-	struct sc_reg_access audio_adc_reg1 = {0,};
-	struct sc_reg_access audio_adc_reg2 = {0,};
-
-	msic_enable_mic_bias();
-	/* Enable the msic for conversion before reading */
-	ret = sst_sc_reg_access(adc_ctrl3, PMIC_WRITE, 1);
-	if (ret)
-		return ret;
-	adc_ctrl3[0].value = 0x04;
-	/* Re-toggle the RRDATARD bit */
-	ret = sst_sc_reg_access(adc_ctrl3, PMIC_WRITE, 1);
-	if (ret)
-		return ret;
-
-	audio_adc_reg1.reg_addr = adc_adr;
-	/* Read the higher bits of data */
-	msleep(1000);
-	ret = sst_sc_reg_access(&audio_adc_reg1, PMIC_READ, 1);
-	if (ret)
-		return ret;
-	pr_debug("adc read value %x", audio_adc_reg1.value);
-
-	/* Shift bits to accomodate the lower two data bits */
-	adc_val = (audio_adc_reg1.value << 2);
-	adc_adr++;
-	audio_adc_reg2. reg_addr = adc_adr;
-	ret = sst_sc_reg_access(&audio_adc_reg2, PMIC_READ, 1);
-	if (ret)
-		return ret;
-	pr_debug("adc read value %x", audio_adc_reg2.value);
-
-	/* Adding lower two bits to the higher bits */
-	audio_adc_reg2.value &= 03;
-	adc_val += audio_adc_reg2.value;
-
-	pr_debug("ADC value 0x%x", adc_val);
-	msic_disable_mic_bias();
-	return adc_val;
-}
-
-static void msic_pmic_irq_cb(void *cb_data, u8 intsts)
-{
-	struct mad_jack *mjack = NULL;
-	unsigned int present = 0, jack_event_flag = 0, buttonpressflag = 0;
-	struct snd_intelmad *intelmaddata = cb_data;
-	int retval = 0;
-
-	pr_debug("value returned = 0x%x\n", intsts);
-
-	if (snd_msic_ops.card_status == SND_CARD_UN_INIT) {
-		retval = msic_init_card();
-		if (retval)
-			return;
-	  }
-
-	mjack = &intelmaddata->jack[0];
-	if (intsts & 0x1) {
-		pr_debug("MAD short_push detected\n");
-		present = SND_JACK_BTN_0;
-		jack_event_flag = buttonpressflag = 1;
-		mjack->jack.type = SND_JACK_BTN_0;
-		mjack->jack.key[0] = BTN_0 ;
-	}
-
-	if (intsts & 0x2) {
-		pr_debug(":MAD long_push detected\n");
-		jack_event_flag = buttonpressflag = 1;
-		mjack->jack.type = present = SND_JACK_BTN_1;
-		mjack->jack.key[1] = BTN_1;
-	}
-
-	if (intsts & 0x4) {
-		unsigned int mic_bias;
-		jack_event_flag = 1;
-		buttonpressflag = 0;
-		mic_bias = msic_get_mic_bias(intelmaddata);
-		pr_debug("mic_bias = %d\n", mic_bias);
-		mic_bias = msic_convert_adc_to_mvolt(mic_bias);
-		pr_debug("mic_bias after conversion = %d mV\n", mic_bias);
-		mjack->jack_dev_state = msic_get_headset_state(mic_bias);
-		mjack->jack.type = present = mjack->jack_dev_state;
-	}
-
-	if (intsts & 0x8) {
-		mjack->jack.type = mjack->jack_dev_state;
-		present = 0;
-		jack_event_flag = 1;
-		buttonpressflag = 0;
-		msic_disable_jack_btn();
-		msic_disable_mic_bias();
-	}
-	if (jack_event_flag)
-		sst_mad_send_jack_report(&mjack->jack,
-					buttonpressflag, present);
-}
-
-
-
-struct snd_pmic_ops snd_msic_ops = {
-	.set_input_dev	=	msic_set_selected_input_dev,
-	.set_output_dev =	msic_set_selected_output_dev,
-	.set_lineout_dev =	msic_set_selected_lineout_dev,
-	.set_hw_dmic_route =    msic_set_hw_dmic_route,
-	.set_mute	=	msic_set_mute,
-	.get_mute	=	msic_get_mute,
-	.set_vol	=	msic_set_vol,
-	.get_vol	=	msic_get_vol,
-	.init_card	=	msic_init_card,
-	.set_pcm_audio_params	= msic_set_pcm_audio_params,
-	.set_pcm_voice_params	= msic_set_pcm_voice_params,
-	.set_voice_port = msic_set_voice_port,
-	.set_audio_port = msic_set_audio_port,
-	.power_up_pmic_pb =	msic_power_up_pb,
-	.power_up_pmic_cp =	msic_power_up_cp,
-	.power_down_pmic_pb =	msic_power_down_pb,
-	.power_down_pmic_cp =	msic_power_down_cp,
-	.power_down_pmic	=	msic_power_down,
-	.pmic_irq_cb	=	msic_pmic_irq_cb,
-	.pmic_jack_enable = msic_enable_mic_bias,
-	.pmic_get_mic_bias	= msic_get_mic_bias,
-	.pmic_set_headset_state = msic_set_headset_state,
-};
diff --git a/drivers/staging/intel_sst/intelmid_pvt.c b/drivers/staging/intel_sst/intelmid_pvt.c
deleted file mode 100644
index 90e0e64..0000000
--- a/drivers/staging/intel_sst/intelmid_pvt.c
+++ /dev/null
@@ -1,173 +0,0 @@
-/*
- *   intelmid_pvt.h - Intel Sound card driver for MID
- *
- *  Copyright (C) 2008-10 Intel Corp
- *  Authors:	Harsha Priya <priya.harsha@intel.com>
- *		Vinod Koul <vinod.koul@intel.com>
- *		KP Jeeja <jeeja.kp@intel.com>
- *  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; version 2 of the License.
- *
- *  This program is distributed in the hope that it will be useful, but
- *  WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *  General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License along
- *  with this program; if not, write to the Free Software Foundation, Inc.,
- *  59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
- *
- * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- * ALSA driver for Intel MID sound card chipset - holding private functions
- */
-
-#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
-
-#include <linux/io.h>
-#include <asm/intel_scu_ipc.h>
-#include <sound/core.h>
-#include <sound/control.h>
-#include <sound/pcm.h>
-#include "intel_sst.h"
-#include "intel_sst_ioctl.h"
-#include "intelmid_snd_control.h"
-#include "intelmid.h"
-
-
-void period_elapsed(void *mad_substream)
-{
-	struct snd_pcm_substream *substream = mad_substream;
-	struct mad_stream_pvt *stream;
-
-
-
-	if (!substream || !substream->runtime)
-		return;
-	stream = substream->runtime->private_data;
-	if (!stream)
-		return;
-
-	if (stream->stream_status != RUNNING)
-		return;
-	pr_debug("calling period elapsed\n");
-	snd_pcm_period_elapsed(substream);
-	return;
-}
-
-
-int snd_intelmad_alloc_stream(struct snd_pcm_substream *substream)
-{
-	struct snd_intelmad *intelmaddata = snd_pcm_substream_chip(substream);
-	struct mad_stream_pvt *stream = substream->runtime->private_data;
-	struct snd_sst_stream_params param = {{{0,},},};
-	struct snd_sst_params str_params = {0};
-	int ret_val;
-
-	/* set codec params and inform SST driver the same */
-
-	param.uc.pcm_params.codec = SST_CODEC_TYPE_PCM;
-	param.uc.pcm_params.num_chan = (u8) substream->runtime->channels;
-	param.uc.pcm_params.pcm_wd_sz = substream->runtime->sample_bits;
-	param.uc.pcm_params.reserved = 0;
-	param.uc.pcm_params.sfreq = substream->runtime->rate;
-	param.uc.pcm_params.ring_buffer_size =
-					snd_pcm_lib_buffer_bytes(substream);
-	param.uc.pcm_params.period_count = substream->runtime->period_size;
-	param.uc.pcm_params.ring_buffer_addr =
-				virt_to_phys(substream->runtime->dma_area);
-	pr_debug("period_cnt = %d\n", param.uc.pcm_params.period_count);
-	pr_debug("sfreq= %d, wd_sz = %d\n",
-		 param.uc.pcm_params.sfreq, param.uc.pcm_params.pcm_wd_sz);
-
-	str_params.sparams = param;
-	str_params.codec = SST_CODEC_TYPE_PCM;
-
-	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
-		str_params.ops = STREAM_OPS_PLAYBACK;
-		pr_debug("Playbck stream,Device %d\n", stream->device);
-	} else {
-		str_params.ops = STREAM_OPS_CAPTURE;
-		stream->device = SND_SST_DEVICE_CAPTURE;
-		pr_debug("Capture stream,Device %d\n", stream->device);
-	}
-	str_params.device_type = stream->device;
-	ret_val = intelmaddata->sstdrv_ops->pcm_control->open(&str_params);
-	pr_debug("sst: SST_SND_PLAY/CAPTURE ret_val = %x\n", ret_val);
-	if (ret_val < 0)
-		return ret_val;
-
-	stream->stream_info.str_id = ret_val;
-	stream->stream_status = INIT;
-	stream->stream_info.buffer_ptr = 0;
-	pr_debug("str id :  %d\n", stream->stream_info.str_id);
-
-	return ret_val;
-}
-
-int snd_intelmad_init_stream(struct snd_pcm_substream *substream)
-{
-	struct mad_stream_pvt *stream = substream->runtime->private_data;
-	struct snd_intelmad *intelmaddata = snd_pcm_substream_chip(substream);
-	int ret_val;
-
-	pr_debug("setting buffer ptr param\n");
-	stream->stream_info.period_elapsed = period_elapsed;
-	stream->stream_info.mad_substream = substream;
-	stream->stream_info.buffer_ptr = 0;
-	stream->stream_info.sfreq = substream->runtime->rate;
-	ret_val = intelmaddata->sstdrv_ops->pcm_control->device_control(
-			SST_SND_STREAM_INIT, &stream->stream_info);
-	if (ret_val)
-		pr_err("control_set ret error %d\n", ret_val);
-	return ret_val;
-
-}
-
-
-/**
- * sst_sc_reg_access - IPC read/write wrapper
- *
- * @sc_access:  array of data, addresses and mask
- * @type: operation type
- * @num_val: number of reg to opertae on
- *
- * Reads/writes/read-modify operations on registers accessed through SCU (sound
- * card and few SST DSP regsisters that are not accissible to IA)
- */
-int sst_sc_reg_access(struct sc_reg_access *sc_access,
-					int type, int num_val)
-{
-	int i, retval = 0;
-	if (type == PMIC_WRITE) {
-		for (i = 0; i < num_val; i++) {
-			retval = intel_scu_ipc_iowrite8(sc_access[i].reg_addr,
-							sc_access[i].value);
-			if (retval)
-				goto err;
-		}
-	} else if (type == PMIC_READ) {
-		for (i = 0; i < num_val; i++) {
-			retval = intel_scu_ipc_ioread8(sc_access[i].reg_addr,
-							&(sc_access[i].value));
-			if (retval)
-				goto err;
-		}
-	} else {
-		for (i = 0; i < num_val; i++) {
-			retval = intel_scu_ipc_update_register(
-				sc_access[i].reg_addr, sc_access[i].value,
-				sc_access[i].mask);
-			if (retval)
-				goto err;
-		}
-	}
-	return 0;
-err:
-	pr_err("IPC failed for cmd %d, %d\n", retval, type);
-	pr_err("reg:0x%2x addr:0x%2x\n",
-		sc_access[i].reg_addr, sc_access[i].value);
- 	return retval;
-}
diff --git a/drivers/staging/intel_sst/intelmid_snd_control.h b/drivers/staging/intel_sst/intelmid_snd_control.h
deleted file mode 100644
index 06ad3a1..0000000
--- a/drivers/staging/intel_sst/intelmid_snd_control.h
+++ /dev/null
@@ -1,123 +0,0 @@
-#ifndef __INTELMID_SND_CTRL_H__
-#define __INTELMID_SND_CTRL_H__
-/*
- *  intelmid_snd_control.h - Intel Sound card driver for MID
- *
- *  Copyright (C) 2008-10 Intel Corporation
- *  Authors:	Vinod Koul <vinod.koul@intel.com>
- *		Harsha Priya <priya.harsha@intel.com>
- *		Dharageswari R <dharageswari.r@intel.com>
- *		KP Jeeja <jeeja.kp@intel.com>
- *  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; version 2 of the License.
- *
- *  This program is distributed in the hope that it will be useful, but
- *  WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *  General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License along
- *  with this program; if not, write to the Free Software Foundation, Inc.,
- *  59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
- *
- * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- *
- *  This file defines all snd control functions
- */
-
-/*
-Mask bits
-*/
-#define MASK0 0x01	/* 0000 0001 */
-#define MASK1 0x02	/* 0000 0010 */
-#define MASK2 0x04	/* 0000 0100 */
-#define MASK3 0x08	/* 0000 1000 */
-#define MASK4 0x10	/* 0001 0000 */
-#define MASK5 0x20	/* 0010 0000 */
-#define MASK6 0x40	/* 0100 0000 */
-#define MASK7 0x80	/* 1000 0000 */
-/*
-value bits
-*/
-#define VALUE0	0x01	/* 0000 0001 */
-#define VALUE1	0x02	/* 0000 0010 */
-#define VALUE2	0x04	/* 0000 0100 */
-#define VALUE3	0x08	/* 0000 1000 */
-#define VALUE4	0x10	/* 0001 0000 */
-#define VALUE5	0x20	/* 0010 0000 */
-#define VALUE6	0x40	/* 0100 0000 */
-#define VALUE7	0x80	/* 1000 0000 */
-
-#define MUTE 0    /* ALSA Passes 0 for mute */
-#define UNMUTE 1  /* ALSA Passes 1 for unmute */
-
-#define MAX_VOL_PMIC_VENDOR0    0x3f /* max vol in dB for stereo & voice DAC */
-#define MIN_VOL_PMIC_VENDOR0    0 /* min vol in dB for stereo & voice DAC */
-/* Head phone volume control  */
-#define MAX_HP_VOL_PMIC_VENDOR1    6 /* max volume in dB for HP */
-#define MIN_HP_VOL_PMIC_VENDOR1    (-84) /* min volume in dB for HP */
-#define MAX_HP_VOL_INDX_PMIC_VENDOR1 40 /* Number of HP volume control values */
-
-/* Mono Earpiece Volume control */
-#define MAX_EP_VOL_PMIC_VENDOR1    0 /* max volume in dB for EP */
-#define MIN_EP_VOL_PMIC_VENDOR1    (-75) /* min volume in dB for EP */
-#define MAX_EP_VOL_INDX_PMIC_VENDOR1 32 /* Number of EP volume control values */
-
-int sst_sc_reg_access(struct sc_reg_access *sc_access,
-					int type, int num_val);
-extern struct snd_pmic_ops snd_pmic_ops_fs;
-extern struct snd_pmic_ops snd_pmic_ops_mx;
-extern struct snd_pmic_ops snd_pmic_ops_nc;
-extern struct snd_pmic_ops snd_msic_ops;
-
-/* device */
-enum SND_INPUT_DEVICE {
-	AMIC,
-	DMIC,
-	HS_MIC,
-	IN_UNDEFINED
-};
-enum SND_LINE_OUT_DEVICE {
-	HEADSET,
-	IHF,
-	VIBRA1,
-	VIBRA2,
-	NONE,
-};
-
-enum SND_OUTPUT_DEVICE {
-	STEREO_HEADPHONE,
-	MONO_EARPIECE,
-
-	INTERNAL_SPKR,
-	RECEIVER,
-	OUT_UNDEFINED
-};
-
-enum pmic_controls {
-	PMIC_SND_HP_MIC_MUTE =			0x0001,
-	PMIC_SND_AMIC_MUTE =			0x0002,
-	PMIC_SND_DMIC_MUTE =			0x0003,
-	PMIC_SND_CAPTURE_VOL =			0x0004,
-/* Output controls */
-	PMIC_SND_LEFT_PB_VOL =			0x0010,
-	PMIC_SND_RIGHT_PB_VOL =			0x0011,
-	PMIC_SND_LEFT_HP_MUTE =			0x0012,
-	PMIC_SND_RIGHT_HP_MUTE =		0x0013,
-	PMIC_SND_LEFT_SPEAKER_MUTE =		0x0014,
-	PMIC_SND_RIGHT_SPEAKER_MUTE =		0x0015,
-	PMIC_SND_RECEIVER_VOL =			0x0016,
-	PMIC_SND_RECEIVER_MUTE =		0x0017,
-	PMIC_SND_LEFT_MASTER_VOL =		0x0018,
-	PMIC_SND_RIGHT_MASTER_VOL =		0x0019,
-/* Other controls */
-	PMIC_SND_MUTE_ALL =			0x0020,
-	PMIC_MAX_CONTROLS =			0x0020,
-};
-
-#endif /* __INTELMID_SND_CTRL_H__ */
-
-
diff --git a/drivers/staging/intel_sst/intelmid_v0_control.c b/drivers/staging/intel_sst/intelmid_v0_control.c
deleted file mode 100644
index b8dfdb9..0000000
--- a/drivers/staging/intel_sst/intelmid_v0_control.c
+++ /dev/null
@@ -1,866 +0,0 @@
-/*
- *  intel_sst_v0_control.c - Intel SST Driver for audio engine
- *
- *  Copyright (C) 2008-10 Intel Corporation
- *  Authors:	Vinod Koul <vinod.koul@intel.com>
- *		Harsha Priya <priya.harsha@intel.com>
- *		Dharageswari R <dharageswari.r@intel.com>
- *		KP Jeeja <jeeja.kp@intel.com>
- *  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; version 2 of the License.
- *
- *  This program is distributed in the hope that it will be useful, but
- *  WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *  General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License along
- *  with this program; if not, write to the Free Software Foundation, Inc.,
- *  59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
- *
- * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- *
- *  This file contains the control operations of vendor 1
- */
-
-#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
-
-#include <linux/pci.h>
-#include <linux/file.h>
-#include <sound/control.h>
-#include "intel_sst.h"
-#include "intelmid_snd_control.h"
-#include "intelmid.h"
-
-enum _reg_v1 {
-	VOICEPORT1 = 0x180,
-	VOICEPORT2 = 0x181,
-	AUDIOPORT1 = 0x182,
-	AUDIOPORT2 = 0x183,
-	MISCVOICECTRL = 0x184,
-	MISCAUDCTRL = 0x185,
-	DMICCTRL1 = 0x186,
-	AUDIOBIAS = 0x187,
-	MICCTRL = 0x188,
-	MICLICTRL1 = 0x189,
-	MICLICTRL2 = 0x18A,
-	MICLICTRL3 = 0x18B,
-	VOICEDACCTRL1 = 0x18C,
-	STEREOADCCTRL = 0x18D,
-	AUD15 = 0x18E,
-	AUD16 = 0x18F,
-	AUD17 = 0x190,
-	AUD18 = 0x191,
-	RMIXOUTSEL = 0x192,
-	ANALOGLBR = 0x193,
-	ANALOGLBL = 0x194,
-	POWERCTRL1 = 0x195,
-	POWERCTRL2 = 0x196,
-	HEADSETDETECTINT = 0x197,
-	HEADSETDETECTINTMASK = 0x198,
-	TRIMENABLE = 0x199,
-};
-
-int rev_id = 0x20;
-static bool jack_det_enabled;
-
-/****
- * fs_init_card - initialize the sound card
- *
- * This initializes the audio paths to know values in case of this sound card
- */
-static int fs_init_card(void)
-{
-	struct sc_reg_access sc_access[] = {
-		{0x180, 0x00, 0x0},
-		{0x181, 0x00, 0x0},
-		{0x182, 0xF8, 0x0},
-		{0x183, 0x08, 0x0},
-		{0x184, 0x00, 0x0},
-		{0x185, 0x40, 0x0},
-		{0x186, 0x06, 0x0},
-		{0x187, 0x80, 0x0},
-		{0x188, 0x40, 0x0},
-		{0x189, 0x39, 0x0},
-		{0x18a, 0x39, 0x0},
-		{0x18b, 0x1F, 0x0},
-		{0x18c, 0x00, 0x0},
-		{0x18d, 0x00, 0x0},
-		{0x18e, 0x39, 0x0},
-		{0x18f, 0x39, 0x0},
-		{0x190, 0x39, 0x0},
-		{0x191, 0x11, 0x0},
-		{0x192, 0x0E, 0x0},
-		{0x193, 0x00, 0x0},
-		{0x194, 0x00, 0x0},
-		{0x195, 0x00, 0x0},
-		{0x196, 0x7C, 0x0},
-		{0x197, 0x00, 0x0},
-		{0x198, 0x0B, 0x0},
-		{0x199, 0x00, 0x0},
-		{0x037, 0x3F, 0x0},
-	};
-
-	snd_pmic_ops_fs.card_status = SND_CARD_INIT_DONE;
-	snd_pmic_ops_fs.master_mute = UNMUTE;
-	snd_pmic_ops_fs.mute_status = UNMUTE;
-	snd_pmic_ops_fs.num_channel = 2;
-	return sst_sc_reg_access(sc_access, PMIC_WRITE, 27);
-}
-
-static int fs_enable_audiodac(int value)
-{
-	struct sc_reg_access sc_access[3];
-	sc_access[0].reg_addr = AUD16;
-	sc_access[1].reg_addr = AUD17;
-	sc_access[2].reg_addr = AUD15;
-	sc_access[0].mask = sc_access[1].mask = sc_access[2].mask = MASK7;
-
-	if (snd_pmic_ops_fs.mute_status == MUTE)
-		return 0;
-	if (value == MUTE) {
-			sc_access[0].value = sc_access[1].value =
-				sc_access[2].value = 0x80;
-
-		} else {
-			sc_access[0].value = sc_access[1].value =
-			sc_access[2].value =  0x0;
-		}
-	if (snd_pmic_ops_fs.num_channel == 1)
-		sc_access[1].value = sc_access[2].value = 0x80;
-	return sst_sc_reg_access(sc_access, PMIC_READ_MODIFY, 3);
-
-}
-
-static int fs_power_up_pb(unsigned int port)
-{
-	struct sc_reg_access sc_access[] = {
-		{AUDIOBIAS, 0x00, MASK7},
-		{POWERCTRL1, 0xC6, 0xC6},
-		{POWERCTRL2, 0x30, 0x30},
-
-	};
-	int retval = 0;
-
-	if (snd_pmic_ops_fs.card_status == SND_CARD_UN_INIT)
-		retval = fs_init_card();
-	if (retval)
-		return retval;
-	retval = fs_enable_audiodac(MUTE);
-	retval = sst_sc_reg_access(sc_access, PMIC_READ_MODIFY, 3);
-
-	if (retval)
-		return retval;
-
-	pr_debug("in fs power up pb\n");
-	return fs_enable_audiodac(UNMUTE);
-}
-
-static int fs_power_down_pb(unsigned int device)
-{
-	struct sc_reg_access sc_access[] = {
-		{POWERCTRL1, 0x00, 0xC6},
-		{POWERCTRL2, 0x00, 0x30},
-	};
-	int retval = 0;
-
-	if (snd_pmic_ops_fs.card_status == SND_CARD_UN_INIT)
-		retval = fs_init_card();
-	if (retval)
-		return retval;
-	retval = fs_enable_audiodac(MUTE);
-	retval = sst_sc_reg_access(sc_access, PMIC_READ_MODIFY, 2);
-
-	if (retval)
-		return retval;
-
-	pr_debug("in fsl power down pb\n");
-	return fs_enable_audiodac(UNMUTE);
-}
-
-static int fs_power_up_cp(unsigned int port)
-{
-	struct sc_reg_access sc_access[] = {
-		{POWERCTRL2, 0x32, 0x32}, /*NOTE power up A ADC only as*/
-		{AUDIOBIAS, 0x00, MASK7},
-					/*as turning on V ADC causes noise*/
-	};
-	int retval = 0;
-
-	if (snd_pmic_ops_fs.card_status == SND_CARD_UN_INIT)
-		retval = fs_init_card();
-	if (retval)
-		return retval;
-	return sst_sc_reg_access(sc_access, PMIC_READ_MODIFY, 2);
-}
-
-static int fs_power_down_cp(unsigned int device)
-{
-	struct sc_reg_access sc_access[] = {
-		{POWERCTRL2, 0x00, 0x03},
-	};
-	int retval = 0;
-
-	if (snd_pmic_ops_fs.card_status == SND_CARD_UN_INIT)
-		retval = fs_init_card();
-	if (retval)
-		return retval;
-	return sst_sc_reg_access(sc_access, PMIC_READ_MODIFY, 1);
-}
-
-static int fs_power_down(void)
-{
-	int retval = 0;
-	struct sc_reg_access sc_access[] = {
-		{AUDIOBIAS, MASK7, MASK7},
-	};
-
-	if (snd_pmic_ops_fs.card_status == SND_CARD_UN_INIT)
-		retval = fs_init_card();
-	if (retval)
-		return retval;
-	return sst_sc_reg_access(sc_access, PMIC_READ_MODIFY, 1);
-}
-
-static int fs_set_pcm_voice_params(void)
-{
-	struct sc_reg_access sc_access[] = {
-		{0x180, 0xA0, 0},
-		{0x181, 0x04, 0},
-		{0x182, 0x0, 0},
-		{0x183, 0x0, 0},
-		{0x184, 0x18, 0},
-		{0x185, 0x40, 0},
-		{0x186, 0x06, 0},
-		{0x187, 0x0, 0},
-		{0x188, 0x10, 0},
-		{0x189, 0x39, 0},
-		{0x18a, 0x39, 0},
-		{0x18b, 0x02, 0},
-		{0x18c, 0x0, 0},
-		{0x18d, 0x0, 0},
-		{0x18e, 0x39, 0},
-		{0x18f, 0x0, 0},
-		{0x190, 0x0, 0},
-		{0x191, 0x20, 0},
-		{0x192, 0x20, 0},
-		{0x193, 0x0, 0},
-		{0x194, 0x0, 0},
-		{0x195, 0x06, 0},
-		{0x196, 0x25, 0},
-		{0x197, 0x0, 0},
-		{0x198, 0xF, 0},
-		{0x199, 0x0, 0},
-	};
-	int retval = 0;
-
-	if (snd_pmic_ops_fs.card_status == SND_CARD_UN_INIT)
-		retval = fs_init_card();
-	if (retval)
-		return retval;
-	return sst_sc_reg_access(sc_access, PMIC_WRITE, 26);
-}
-
-static int fs_set_audio_port(int status)
-{
-	struct sc_reg_access sc_access[2];
-	int retval = 0;
-
-	if (snd_pmic_ops_fs.card_status == SND_CARD_UN_INIT)
-		retval = fs_init_card();
-	if (retval)
-		return retval;
-	if (status == DEACTIVATE) {
-		/* Deactivate audio port-tristate and power */
-		sc_access[0].value = 0x00;
-		sc_access[0].mask = MASK6|MASK7;
-		sc_access[0].reg_addr = AUDIOPORT1;
-		sc_access[1].value = 0x00;
-		sc_access[1].mask = MASK4|MASK5;
-		sc_access[1].reg_addr = POWERCTRL2;
-		return sst_sc_reg_access(sc_access, PMIC_READ_MODIFY, 2);
-	} else if (status == ACTIVATE) {
-		/* activate audio port */
-		sc_access[0].value = 0xC0;
-		sc_access[0].mask = MASK6|MASK7;
-		sc_access[0].reg_addr = AUDIOPORT1;
-		sc_access[1].value = 0x30;
-		sc_access[1].mask = MASK4|MASK5;
-		sc_access[1].reg_addr = POWERCTRL2;
-		return sst_sc_reg_access(sc_access, PMIC_READ_MODIFY, 2);
-	} else
-		return -EINVAL;
-}
-
-static int fs_set_voice_port(int status)
-{
-	struct sc_reg_access sc_access[2];
-	int retval = 0;
-
-	if (snd_pmic_ops_fs.card_status == SND_CARD_UN_INIT)
-		retval = fs_init_card();
-	if (retval)
-		return retval;
-	if (status == DEACTIVATE) {
-		/* Deactivate audio port-tristate and power */
-		sc_access[0].value = 0x00;
-		sc_access[0].mask = MASK6|MASK7;
-		sc_access[0].reg_addr = VOICEPORT1;
-		sc_access[1].value = 0x00;
-		sc_access[1].mask = MASK0|MASK1;
-		sc_access[1].reg_addr = POWERCTRL2;
-		return sst_sc_reg_access(sc_access, PMIC_READ_MODIFY, 2);
-	} else if (status == ACTIVATE) {
-		/* activate audio port */
-		sc_access[0].value = 0xC0;
-		sc_access[0].mask = MASK6|MASK7;
-		sc_access[0].reg_addr = VOICEPORT1;
-		sc_access[1].value = 0x03;
-		sc_access[1].mask = MASK0|MASK1;
-		sc_access[1].reg_addr = POWERCTRL2;
-		return sst_sc_reg_access(sc_access, PMIC_READ_MODIFY, 2);
-	} else
-		return -EINVAL;
-}
-
-static int fs_set_pcm_audio_params(int sfreq, int word_size, int num_channel)
-{
-	u8 config1 = 0;
-	struct sc_reg_access sc_access[4];
-	int retval = 0, num_value = 0;
-
-	if (snd_pmic_ops_fs.card_status == SND_CARD_UN_INIT)
-		retval = fs_init_card();
-	if (retval)
-		return retval;
-	switch (sfreq) {
-	case 8000:
-		config1 = 0x00;
-		break;
-	case 11025:
-		config1 = 0x01;
-		break;
-	case 12000:
-		config1 = 0x02;
-		break;
-	case 16000:
-		config1 = 0x03;
-		break;
-	case 22050:
-		config1 = 0x04;
-		break;
-	case 24000:
-		config1 = 0x05;
-		break;
-	case 26000:
-		config1 = 0x06;
-		break;
-	case 32000:
-		config1 = 0x07;
-		break;
-	case 44100:
-		config1 = 0x08;
-		break;
-	case 48000:
-		config1 = 0x09;
-		break;
-	}
-	snd_pmic_ops_fs.num_channel = num_channel;
-	if (snd_pmic_ops_fs.num_channel == 1)	{
-		sc_access[0].reg_addr = AUD17;
-		sc_access[1].reg_addr = AUD15;
-		sc_access[0].mask = sc_access[1].mask = MASK7;
-		sc_access[0].value = sc_access[1].value = 0x80;
-		sst_sc_reg_access(sc_access, PMIC_READ_MODIFY, 2);
-
-	} else {
-		sc_access[0].reg_addr = AUD17;
-		sc_access[1].reg_addr = AUD15;
-		sc_access[0].mask = sc_access[1].mask = MASK7;
-		sc_access[0].value = sc_access[1].value = 0x00;
-		sst_sc_reg_access(sc_access, PMIC_READ_MODIFY, 2);
-
-	}
-	pr_debug("sfreq:%d,Register value = %x\n", sfreq, config1);
-
-	if (word_size == 24) {
-		sc_access[0].reg_addr  = AUDIOPORT1;
-		sc_access[0].mask = MASK0|MASK1|MASK2|MASK3;
-		sc_access[0].value = 0xFB;
-
-
-		sc_access[1].reg_addr  = AUDIOPORT2;
-		sc_access[1].value = config1 | 0x10;
-		sc_access[1].mask = MASK0 | MASK1 | MASK2 | MASK3
-					| MASK4 | MASK5 | MASK6;
-
-		sc_access[2].reg_addr  = MISCAUDCTRL;
-		sc_access[2].value = 0x02;
-		sc_access[2].mask = 0x02;
-
-		num_value = 3 ;
-
-	} else {
-
-		sc_access[0].reg_addr  = AUDIOPORT2;
-		sc_access[0].value = config1;
-		sc_access[0].mask = MASK0|MASK1|MASK2|MASK3;
-
-		sc_access[1].reg_addr  = MISCAUDCTRL;
-		sc_access[1].value = 0x00;
-		sc_access[1].mask = 0x02;
-		num_value = 2;
-	}
-	return sst_sc_reg_access(sc_access, PMIC_READ_MODIFY, num_value);
-
-}
-
-static int fs_set_selected_input_dev(u8 value)
-{
-	struct sc_reg_access sc_access_dmic[] = {
-		{MICCTRL, 0x81, 0xf7},
-		{MICLICTRL3, 0x00, 0xE0},
-	};
-	struct sc_reg_access sc_access_mic[] = {
-		{MICCTRL, 0x40, MASK2|MASK4|MASK5|MASK6|MASK7},
-		{MICLICTRL3, 0x00, 0xE0},
-	};
-	struct sc_reg_access sc_access_hsmic[] = {
-		{MICCTRL, 0x10, MASK2|MASK4|MASK5|MASK6|MASK7},
-		{MICLICTRL3, 0x00, 0xE0},
-	};
-
-	int retval = 0;
-
-	if (snd_pmic_ops_fs.card_status == SND_CARD_UN_INIT)
-		retval = fs_init_card();
-	if (retval)
-		return retval;
-
-	switch (value) {
-	case AMIC:
-		pr_debug("Selecting amic not supported in mono cfg\n");
-		return sst_sc_reg_access(sc_access_mic, PMIC_READ_MODIFY, 2);
-		break;
-
-	case HS_MIC:
-		pr_debug("Selecting hsmic\n");
-		return sst_sc_reg_access(sc_access_hsmic,
-				PMIC_READ_MODIFY, 2);
-		break;
-
-	case DMIC:
-		pr_debug("Selecting dmic\n");
-		return sst_sc_reg_access(sc_access_dmic, PMIC_READ_MODIFY, 2);
-		break;
-
-	default:
-		return -EINVAL;
-
-	}
-}
-
-static int fs_set_selected_output_dev(u8 value)
-{
-	struct sc_reg_access sc_access_hp[] = {
-		{0x191, 0x11, 0x0},
-		{0x192, 0x0E, 0x0},
-	};
-	struct sc_reg_access sc_access_is[] = {
-		{0x191, 0x17, 0xFF},
-		{0x192, 0x08, 0xFF},
-	};
-	int retval = 0;
-
-	if (snd_pmic_ops_fs.card_status == SND_CARD_UN_INIT)
-		retval = fs_init_card();
-	if (retval)
-		return retval;
-
-	switch (value) {
-	case STEREO_HEADPHONE:
-		pr_debug("SST DBG:Selecting headphone\n");
-		return sst_sc_reg_access(sc_access_hp, PMIC_WRITE, 2);
-		break;
-	case MONO_EARPIECE:
-	case INTERNAL_SPKR:
-		pr_debug("SST DBG:Selecting internal spkr\n");
-		return sst_sc_reg_access(sc_access_is, PMIC_READ_MODIFY, 2);
-		break;
-
-	default:
-		return -EINVAL;
-
-	}
-}
-
-static int fs_set_mute(int dev_id, u8 value)
-{
-	struct sc_reg_access sc_access[6] = {{0,},};
-	int reg_num = 0;
-	int retval = 0;
-
-	if (snd_pmic_ops_fs.card_status == SND_CARD_UN_INIT)
-		retval = fs_init_card();
-	if (retval)
-		return retval;
-
-
-	pr_debug("dev_id:0x%x value:0x%x\n", dev_id, value);
-	switch (dev_id) {
-	case PMIC_SND_DMIC_MUTE:
-		sc_access[0].reg_addr = MICCTRL;
-		sc_access[1].reg_addr = MICLICTRL1;
-		sc_access[2].reg_addr = MICLICTRL2;
-		sc_access[0].mask = MASK5;
-		sc_access[1].mask = sc_access[2].mask = MASK6;
-		if (value == MUTE) {
-			sc_access[0].value = 0x20;
-			sc_access[2].value = sc_access[1].value = 0x40;
-		} else
-			sc_access[0].value = sc_access[1].value
-			= sc_access[2].value = 0x0;
-		reg_num = 3;
-		break;
-	case PMIC_SND_HP_MIC_MUTE:
-	case PMIC_SND_AMIC_MUTE:
-		sc_access[0].reg_addr = MICLICTRL1;
-		sc_access[1].reg_addr = MICLICTRL2;
-		sc_access[0].mask = sc_access[1].mask = MASK6;
-		if (value == MUTE)
-			sc_access[0].value = sc_access[1].value = 0x40;
-		else
-			sc_access[0].value = sc_access[1].value = 0x0;
-		reg_num = 2;
-		break;
-	case PMIC_SND_LEFT_SPEAKER_MUTE:
-	case PMIC_SND_LEFT_HP_MUTE:
-		sc_access[0].reg_addr = AUD16;
-		sc_access[1].reg_addr = AUD15;
-
-		sc_access[0].mask = sc_access[1].mask = MASK7;
-		if (value == MUTE)
-			sc_access[0].value = sc_access[1].value = 0x80;
-		else
-			sc_access[0].value = sc_access[1].value = 0x0;
-		reg_num = 2;
-		snd_pmic_ops_fs.mute_status = value;
-		break;
-	case PMIC_SND_RIGHT_HP_MUTE:
-	case PMIC_SND_RIGHT_SPEAKER_MUTE:
-		sc_access[0].reg_addr = AUD17;
-		sc_access[1].reg_addr = AUD15;
-		sc_access[0].mask = sc_access[1].mask = MASK7;
-		if (value == MUTE)
-			sc_access[0].value = sc_access[1].value = 0x80;
-		else
-			sc_access[0].value = sc_access[1].value = 0x0;
-		snd_pmic_ops_fs.mute_status = value;
-		if (snd_pmic_ops_fs.num_channel == 1)
-			sc_access[0].value = sc_access[1].value = 0x80;
-		reg_num = 2;
-		break;
-	case PMIC_SND_MUTE_ALL:
-		sc_access[0].reg_addr = AUD16;
-		sc_access[1].reg_addr = AUD17;
-		sc_access[2].reg_addr = AUD15;
-		sc_access[3].reg_addr = MICCTRL;
-		sc_access[4].reg_addr = MICLICTRL1;
-		sc_access[5].reg_addr = MICLICTRL2;
-		sc_access[0].mask = sc_access[1].mask =
-				sc_access[2].mask = MASK7;
-		sc_access[3].mask = MASK5;
-		sc_access[4].mask = sc_access[5].mask = MASK6;
-
-		if (value == MUTE) {
-			sc_access[0].value =
-			sc_access[1].value = sc_access[2].value = 0x80;
-			sc_access[3].value = 0x20;
-			sc_access[4].value = sc_access[5].value = 0x40;
-
-		} else {
-			sc_access[0].value = sc_access[1].value =
-			sc_access[2].value = sc_access[3].value =
-			sc_access[4].value = sc_access[5].value = 0x0;
-		}
-		if (snd_pmic_ops_fs.num_channel == 1)
-			sc_access[1].value = sc_access[2].value = 0x80;
-		reg_num = 6;
-		snd_pmic_ops_fs.mute_status = value;
-		snd_pmic_ops_fs.master_mute = value;
-		break;
-
-	}
-	return sst_sc_reg_access(sc_access, PMIC_READ_MODIFY, reg_num);
-}
-
-static int fs_set_vol(int dev_id, int value)
-{
-	struct sc_reg_access sc_acces, sc_access[4] = {{0},};
-	int reg_num = 0;
-	int retval = 0;
-
-	if (snd_pmic_ops_fs.card_status == SND_CARD_UN_INIT)
-		retval = fs_init_card();
-	if (retval)
-		return retval;
-
-	switch (dev_id) {
-	case PMIC_SND_LEFT_PB_VOL:
-		pr_debug("PMIC_SND_LEFT_PB_VOL:%d\n", value);
-		sc_access[0].value = sc_access[1].value = value;
-		sc_access[0].reg_addr = AUD16;
-		sc_access[1].reg_addr = AUD15;
-		sc_access[0].mask = sc_access[1].mask =
-			(MASK0|MASK1|MASK2|MASK3|MASK4|MASK5);
-		reg_num = 2;
-		break;
-
-	case PMIC_SND_RIGHT_PB_VOL:
-		pr_debug("PMIC_SND_RIGHT_PB_VOL:%d\n", value);
-		sc_access[0].value = sc_access[1].value = value;
-		sc_access[0].reg_addr = AUD17;
-		sc_access[1].reg_addr = AUD15;
-		sc_access[0].mask = sc_access[1].mask =
-			(MASK0|MASK1|MASK2|MASK3|MASK4|MASK5);
-		if (snd_pmic_ops_fs.num_channel == 1) {
-			sc_access[0].value = sc_access[1].value = 0x80;
-			sc_access[0].mask = sc_access[1].mask = MASK7;
-		}
-		reg_num = 2;
-		break;
-	case PMIC_SND_CAPTURE_VOL:
-		pr_debug("PMIC_SND_CAPTURE_VOL:%d\n", value);
-		sc_access[0].reg_addr = MICLICTRL1;
-		sc_access[1].reg_addr = MICLICTRL2;
-		sc_access[2].reg_addr = DMICCTRL1;
-		sc_access[2].value = value;
-		sc_access[0].value = sc_access[1].value = value;
-		sc_acces.reg_addr = MICLICTRL3;
-		sc_acces.value = value;
-		sc_acces.mask = (MASK0|MASK1|MASK2|MASK3|MASK5|MASK6|MASK7);
-		retval = sst_sc_reg_access(&sc_acces, PMIC_READ_MODIFY, 1);
-		sc_access[0].mask = sc_access[1].mask =
-		sc_access[2].mask = (MASK0|MASK1|MASK2|MASK3|MASK4|MASK5);
-		reg_num = 3;
-		break;
-
-	default:
-		return -EINVAL;
-	}
-
-	return sst_sc_reg_access(sc_access, PMIC_READ_MODIFY, reg_num);
-}
-
-static int fs_get_mute(int dev_id, u8 *value)
-{
-	struct sc_reg_access sc_access[6] = {{0,},};
-
-	int retval = 0, temp_value = 0, mask = 0;
-
-	if (snd_pmic_ops_fs.card_status == SND_CARD_UN_INIT)
-		retval = fs_init_card();
-	if (retval)
-		return retval;
-
-	switch (dev_id) {
-
-	case PMIC_SND_AMIC_MUTE:
-	case PMIC_SND_HP_MIC_MUTE:
-		sc_access[0].reg_addr = MICLICTRL1;
-		mask = MASK6;
-		retval = sst_sc_reg_access(sc_access, PMIC_READ, 1);
-		if (sc_access[0].value & mask)
-			*value = MUTE;
-		else
-			*value = UNMUTE;
-		break;
-	case PMIC_SND_DMIC_MUTE:
-		sc_access[0].reg_addr = MICCTRL;
-		mask = MASK5;
-		retval = sst_sc_reg_access(sc_access, PMIC_READ, 1);
-		temp_value = (sc_access[0].value & mask);
-		if (temp_value == 0)
-			*value = UNMUTE;
-		else
-			*value = MUTE;
-		break;
-
-	case PMIC_SND_LEFT_HP_MUTE:
-	case PMIC_SND_LEFT_SPEAKER_MUTE:
-		sc_access[0].reg_addr = AUD16;
-		mask = MASK7;
-		retval = sst_sc_reg_access(sc_access, PMIC_READ, 1);
-		temp_value = sc_access[0].value & mask;
-		if (temp_value == 0)
-			*value = UNMUTE;
-		else
-			*value = MUTE;
-		break;
-	case PMIC_SND_RIGHT_HP_MUTE:
-	case PMIC_SND_RIGHT_SPEAKER_MUTE:
-		sc_access[0].reg_addr = AUD17;
-		mask = MASK7;
-		retval = sst_sc_reg_access(sc_access, PMIC_READ, 1);
-		temp_value = sc_access[0].value & mask;
-		if (temp_value == 0)
-			*value = UNMUTE;
-		else
-			*value = MUTE;
-		break;
-	default:
-		return -EINVAL;
-	}
-
-	return retval;
-}
-
-static int fs_get_vol(int dev_id, int *value)
-{
-	struct sc_reg_access sc_access = {0,};
-	int retval = 0, mask = 0;
-
-	if (snd_pmic_ops_fs.card_status == SND_CARD_UN_INIT)
-		retval = fs_init_card();
-	if (retval)
-		return retval;
-
-	switch (dev_id) {
-	case PMIC_SND_CAPTURE_VOL:
-		pr_debug("PMIC_SND_CAPTURE_VOL\n");
-		sc_access.reg_addr = MICLICTRL1;
-		mask = (MASK5|MASK4|MASK3|MASK2|MASK1|MASK0);
-		break;
-	case PMIC_SND_LEFT_PB_VOL:
-		pr_debug("PMIC_SND_LEFT_PB_VOL\n");
-		sc_access.reg_addr = AUD16;
-		mask = (MASK5|MASK4|MASK3|MASK2|MASK1|MASK0);
-		break;
-	case PMIC_SND_RIGHT_PB_VOL:
-		pr_debug("PMIC_SND_RT_PB_VOL\n");
-		sc_access.reg_addr = AUD17;
-		mask = (MASK5|MASK4|MASK3|MASK2|MASK1|MASK0);
-		break;
-	default:
-		return -EINVAL;
-	}
-
-	retval = sst_sc_reg_access(&sc_access, PMIC_READ, 1);
-	pr_debug("value read = 0x%x\n", sc_access.value);
-	*value = (int) (sc_access.value & mask);
-	pr_debug("value returned = 0x%x\n", *value);
-	return retval;
-}
-
-static void fs_pmic_irq_enable(void *data)
-{
-	struct snd_intelmad *intelmaddata = data;
-	struct sc_reg_access sc_access[] = {
-				{0x187, 0x00, MASK7},
-				{0x188, 0x10, MASK4},
-				{0x18b, 0x10, MASK4},
-	};
-
-	struct sc_reg_access sc_access_write[] = {
-				{0x198, 0x00, 0x0},
-	};
-	pr_debug("Audio interrupt enable\n");
-	sst_sc_reg_access(sc_access, PMIC_READ_MODIFY, 3);
-	sst_sc_reg_access(sc_access_write, PMIC_WRITE, 1);
-
-	intelmaddata->jack[0].jack_status = 0;
-	/*intelmaddata->jack[1].jack_status = 0;*/
-
-	jack_det_enabled = true;
-	return;
-}
-
-static void fs_pmic_irq_cb(void *cb_data, u8 value)
-{
-	struct mad_jack *mjack = NULL;
-	struct snd_intelmad *intelmaddata = cb_data;
-	unsigned int present = 0, jack_event_flag = 0, buttonpressflag = 0;
-
-	mjack = &intelmaddata->jack[0];
-
-	if (value & 0x4) {
-		if (!jack_det_enabled)
-			fs_pmic_irq_enable(intelmaddata);
-
-		/* send headphone detect */
-		pr_debug(":MAD headphone %d\n", value & 0x4);
-		present = !(mjack->jack_status);
-		mjack->jack_status = present;
-		jack_event_flag = 1;
-		mjack->jack.type = SND_JACK_HEADPHONE;
-	}
-
-	if (value & 0x2) {
-		/* send short push */
-		pr_debug(":MAD short push %d\n", value & 0x2);
-		present = 1;
-		jack_event_flag = 1;
-		buttonpressflag = 1;
-		mjack->jack.type = MID_JACK_HS_SHORT_PRESS;
-	}
-
-	if (value & 0x1) {
-		/* send long push */
-		pr_debug(":MAD long push %d\n", value & 0x1);
-		present = 1;
-		jack_event_flag = 1;
-		buttonpressflag = 1;
-		mjack->jack.type = MID_JACK_HS_LONG_PRESS;
-	}
-
-	if (value & 0x8) {
-		if (!jack_det_enabled)
-			fs_pmic_irq_enable(intelmaddata);
-		/* send headset detect */
-		pr_debug(":MAD headset = %d\n", value & 0x8);
-		present = !(mjack->jack_status);
-		mjack->jack_status = present;
-		jack_event_flag = 1;
-		mjack->jack.type = SND_JACK_HEADSET;
-	}
-
-
-	if (jack_event_flag)
-		sst_mad_send_jack_report(&mjack->jack,
-						buttonpressflag, present);
-
-	return;
-}
-static int fs_jack_enable(void)
-{
-	return 0;
-}
-
-struct snd_pmic_ops snd_pmic_ops_fs = {
-	.set_input_dev = fs_set_selected_input_dev,
-	.set_output_dev = fs_set_selected_output_dev,
-	.set_mute = fs_set_mute,
-	.get_mute = fs_get_mute,
-	.set_vol = fs_set_vol,
-	.get_vol = fs_get_vol,
-	.init_card = fs_init_card,
-	.set_pcm_audio_params = fs_set_pcm_audio_params,
-	.set_pcm_voice_params = fs_set_pcm_voice_params,
-	.set_voice_port = fs_set_voice_port,
-	.set_audio_port = fs_set_audio_port,
-	.power_up_pmic_pb =	fs_power_up_pb,
-	.power_up_pmic_cp =	fs_power_up_cp,
-	.power_down_pmic_pb =	fs_power_down_pb,
-	.power_down_pmic_cp =	fs_power_down_cp,
-	.power_down_pmic	=	fs_power_down,
-	.pmic_irq_cb	=	fs_pmic_irq_cb,
-	/*
-	 * Jack detection enabling
-	 * need be delayed till first IRQ happen.
-	 */
-	.pmic_irq_enable =	NULL,
-	.pmic_jack_enable = fs_jack_enable,
-};
diff --git a/drivers/staging/intel_sst/intelmid_v1_control.c b/drivers/staging/intel_sst/intelmid_v1_control.c
deleted file mode 100644
index 9d00728..0000000
--- a/drivers/staging/intel_sst/intelmid_v1_control.c
+++ /dev/null
@@ -1,978 +0,0 @@
-/*  intel_sst_v1_control.c - Intel SST Driver for audio engine
- *
- *  Copyright (C) 2008-10 Intel Corp
- *  Authors:	Vinod Koul <vinod.koul@intel.com>
- *	Harsha Priya <priya.harsha@intel.com>
- *	Dharageswari R <dharageswari.r@intel.com>
- *	KP Jeeja <jeeja.kp@intel.com>
- *  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; version 2 of the License.
- *
- *  This program is distributed in the hope that it will be useful, but
- *  WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *  General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License along
- *  with this program; if not, write to the Free Software Foundation, Inc.,
- *  59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
- *
- * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- *
- *  This file contains the control operations of vendor 2
- */
-
-#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
-
-#include <linux/pci.h>
-#include <linux/delay.h>
-#include <linux/file.h>
-#include <asm/mrst.h>
-#include <sound/pcm.h>
-#include <sound/pcm_params.h>
-#include <sound/control.h>
-#include <sound/initval.h>
-#include "intel_sst.h"
-#include "intel_sst_ioctl.h"
-#include "intelmid.h"
-#include "intelmid_snd_control.h"
-
-#include <linux/gpio.h>
-#define KOSKI_VOICE_CODEC_ENABLE 46
-
-enum _reg_v2 {
-
-	MASTER_CLOCK_PRESCALAR  = 0x205,
-	SET_MASTER_AND_LR_CLK1	= 0x20b,
-	SET_MASTER_AND_LR_CLK2	= 0x20c,
-	MASTER_MODE_AND_DATA_DELAY = 0x20d,
-	DIGITAL_INTERFACE_TO_DAI2 = 0x20e,
-	CLK_AND_FS1 = 0x208,
-	CLK_AND_FS2 = 0x209,
-	DAI2_TO_DAC_HP = 0x210,
-	HP_OP_SINGLE_ENDED = 0x224,
-	ENABLE_OPDEV_CTRL = 0x226,
-	ENABLE_DEV_AND_USE_XTAL = 0x227,
-
-	/* Max audio subsystem (PQ49) MAX 8921 */
-	AS_IP_MODE_CTL = 0xF9,
-	AS_LEFT_SPKR_VOL_CTL = 0xFA, /* Mono Earpiece volume control */
-	AS_RIGHT_SPKR_VOL_CTL = 0xFB,
-	AS_LEFT_HP_VOL_CTL = 0xFC,
-	AS_RIGHT_HP_VOL_CTL = 0xFD,
-	AS_OP_MIX_CTL = 0xFE,
-	AS_CONFIG = 0xFF,
-
-	/* Headphone volume control & mute registers */
-	VOL_CTRL_LT = 0x21c,
-	VOL_CTRL_RT = 0x21d,
-
-};
-/**
- * mx_init_card - initialize the sound card
- *
- * This initializes the audio paths to know values in case of this sound card
- */
-static int mx_init_card(void)
-{
-	struct sc_reg_access sc_access[] = {
-		{0x200, 0x80, 0x00},
-		{0x201, 0xC0, 0x00},
-		{0x202, 0x00, 0x00},
-		{0x203, 0x00, 0x00},
-		{0x204, 0x02, 0x00},
-		{0x205, 0x10, 0x00},
-		{0x206, 0x60, 0x00},
-		{0x207, 0x00, 0x00},
-		{0x208, 0x90, 0x00},
-		{0x209, 0x51, 0x00},
-		{0x20a, 0x00, 0x00},
-		{0x20b, 0x10, 0x00},
-		{0x20c, 0x00, 0x00},
-		{0x20d, 0x00, 0x00},
-		{0x20e, 0x21, 0x00},
-		{0x20f, 0x00, 0x00},
-		{0x210, 0x84, 0x00},
-		{0x211, 0xB3, 0x00},
-		{0x212, 0x00, 0x00},
-		{0x213, 0x00, 0x00},
-		{0x214, 0x41, 0x00},
-		{0x215, 0x00, 0x00},
-		{0x216, 0x00, 0x00},
-		{0x217, 0x00, 0x00},
-		{0x218, 0x03, 0x00},
-		{0x219, 0x03, 0x00},
-		{0x21a, 0x00, 0x00},
-		{0x21b, 0x00, 0x00},
-		{0x21c, 0x00, 0x00},
-		{0x21d, 0x00, 0x00},
-		{0x21e, 0x00, 0x00},
-		{0x21f, 0x00, 0x00},
-		{0x220, 0x20, 0x00},
-		{0x221, 0x20, 0x00},
-		{0x222, 0x51, 0x00},
-		{0x223, 0x20, 0x00},
-		{0x224, 0x04, 0x00},
-		{0x225, 0x80, 0x00},
-		{0x226, 0x0F, 0x00},
-		{0x227, 0x08, 0x00},
-		{0xf9,  0x40, 0x00},
-		{0xfa,  0x1f, 0x00},
-		{0xfb,  0x1f, 0x00},
-		{0xfc,  0x1f, 0x00},
-		{0xfd,  0x1f, 0x00},
-		{0xfe,  0x00, 0x00},
-		{0xff,  0x0c, 0x00},
-	};
-	snd_pmic_ops_mx.card_status = SND_CARD_INIT_DONE;
-	snd_pmic_ops_mx.num_channel = 2;
-	snd_pmic_ops_mx.master_mute = UNMUTE;
-	snd_pmic_ops_mx.mute_status = UNMUTE;
-	return sst_sc_reg_access(sc_access, PMIC_WRITE, 47);
-}
-
-static int mx_enable_audiodac(int value)
-{
-	struct sc_reg_access sc_access[3];
-	int mute_val = 0;
-	int mute_val1 = 0;
-	int retval = 0;
-
-	sc_access[0].reg_addr = AS_LEFT_HP_VOL_CTL;
-	sc_access[1].reg_addr = AS_RIGHT_HP_VOL_CTL;
-
-	if (value == UNMUTE) {
-		mute_val = 0x1F;
-		mute_val1 = 0x00;
-	} else {
-		mute_val = 0x00;
-		mute_val1 = 0x40;
-	}
-	sc_access[0].mask = sc_access[1].mask = MASK0|MASK1|MASK2|MASK3|MASK4;
-	sc_access[0].value = sc_access[1].value = (u8)mute_val;
-	retval = sst_sc_reg_access(sc_access, PMIC_READ_MODIFY, 2);
-	if (retval)
-		return retval;
-	pr_debug("mute status = %d\n", snd_pmic_ops_mx.mute_status);
-	if (snd_pmic_ops_mx.mute_status == MUTE ||
-				snd_pmic_ops_mx.master_mute == MUTE)
-		return retval;
-
-	sc_access[0].reg_addr = VOL_CTRL_LT;
-	sc_access[1].reg_addr = VOL_CTRL_RT;
-	sc_access[0].mask = sc_access[1].mask = MASK6;
-	sc_access[0].value = sc_access[1].value = mute_val1;
-	if (snd_pmic_ops_mx.num_channel == 1)
-		sc_access[1].value = 0x40;
-	return sst_sc_reg_access(sc_access, PMIC_READ_MODIFY, 2);
-}
-
-static int mx_power_up_pb(unsigned int port)
-{
-
-	int retval = 0;
-	struct sc_reg_access sc_access[3];
-
-	if (snd_pmic_ops_mx.card_status == SND_CARD_UN_INIT) {
-		retval = mx_init_card();
-		if (retval)
-			return retval;
-	}
-	retval = mx_enable_audiodac(MUTE);
-	if (retval)
-		return retval;
-
-	msleep(10);
-
-	sc_access[0].reg_addr = AS_CONFIG;
-	sc_access[0].mask  = MASK7;
-	sc_access[0].value = 0x80;
-	retval = sst_sc_reg_access(sc_access, PMIC_READ_MODIFY, 1);
-	if (retval)
-		return retval;
-
-	sc_access[0].reg_addr = ENABLE_OPDEV_CTRL;
-	sc_access[0].mask  = 0xff;
-	sc_access[0].value = 0x3C;
-	retval = sst_sc_reg_access(sc_access, PMIC_READ_MODIFY, 1);
-	if (retval)
-		return retval;
-
-	sc_access[0].reg_addr = ENABLE_DEV_AND_USE_XTAL;
-	sc_access[0].mask  = 0x80;
-	sc_access[0].value = 0x80;
-	retval = sst_sc_reg_access(sc_access, PMIC_READ_MODIFY, 1);
-	if (retval)
-		return retval;
-
-	return mx_enable_audiodac(UNMUTE);
-}
-
-static int mx_power_down_pb(unsigned int device)
-{
-	struct sc_reg_access sc_access[3];
-	int retval = 0;
-
-	if (snd_pmic_ops_mx.card_status == SND_CARD_UN_INIT) {
-		retval = mx_init_card();
-		if (retval)
-			return retval;
-	}
-
-	retval = mx_enable_audiodac(MUTE);
-	if (retval)
-		return retval;
-
-	sc_access[0].reg_addr = ENABLE_OPDEV_CTRL;
-	sc_access[0].mask  = MASK3|MASK2;
-	sc_access[0].value = 0x00;
-
-	retval = sst_sc_reg_access(sc_access, PMIC_READ_MODIFY, 1);
-	if (retval)
-		return retval;
-
-	return mx_enable_audiodac(UNMUTE);
-}
-
-static int mx_power_up_cp(unsigned int port)
-{
-	int retval = 0;
-	struct sc_reg_access sc_access[] = {
-		{ENABLE_DEV_AND_USE_XTAL, 0x80, MASK7},
-		{ENABLE_OPDEV_CTRL, 0x3, 0x3},
-	};
-
-	if (snd_pmic_ops_mx.card_status == SND_CARD_UN_INIT) {
-		retval = mx_init_card();
-		if (retval)
-			return retval;
-	}
-
-	return sst_sc_reg_access(sc_access, PMIC_READ_MODIFY, 2);
-}
-
-static int mx_power_down_cp(unsigned int device)
-{
-	struct sc_reg_access sc_access[] = {
-		{ENABLE_OPDEV_CTRL, 0x00, MASK1|MASK0},
-	};
-	int retval = 0;
-
-	if (snd_pmic_ops_mx.card_status == SND_CARD_UN_INIT) {
-		retval = mx_init_card();
-		if (retval)
-			return retval;
-	}
-
-	return sst_sc_reg_access(sc_access, PMIC_READ_MODIFY, 1);
-}
-
-static int mx_power_down(void)
-{
-	int retval = 0;
-	struct sc_reg_access sc_access[3];
-
-	if (snd_pmic_ops_mx.card_status == SND_CARD_UN_INIT) {
-		retval = mx_init_card();
-		if (retval)
-			return retval;
-	}
-
-	retval = mx_enable_audiodac(MUTE);
-	if (retval)
-		return retval;
-
-	sc_access[0].reg_addr = AS_CONFIG;
-	sc_access[0].mask  = MASK7;
-	sc_access[0].value = 0x00;
-	retval = sst_sc_reg_access(sc_access, PMIC_READ_MODIFY, 1);
-	if (retval)
-		return retval;
-
-	sc_access[0].reg_addr = ENABLE_DEV_AND_USE_XTAL;
-	sc_access[0].mask  = MASK7;
-	sc_access[0].value = 0x00;
-	retval = sst_sc_reg_access(sc_access, PMIC_READ_MODIFY, 1);
-	if (retval)
-		return retval;
-
-	sc_access[0].reg_addr = ENABLE_OPDEV_CTRL;
-	sc_access[0].mask  = MASK3|MASK2;
-	sc_access[0].value = 0x00;
-	retval = sst_sc_reg_access(sc_access, PMIC_READ_MODIFY, 1);
-	if (retval)
-		return retval;
-
-	return mx_enable_audiodac(UNMUTE);
-}
-
-static int mx_set_pcm_voice_params(void)
-{
-	int retval = 0;
-	struct sc_reg_access sc_access[] = {
-		{0x200, 0x80, 0x00},
-		{0x201, 0xC0, 0x00},
-		{0x202, 0x00, 0x00},
-		{0x203, 0x00, 0x00},
-		{0x204, 0x0e, 0x00},
-		{0x205, 0x20, 0x00},
-		{0x206, 0x8f, 0x00},
-		{0x207, 0x21, 0x00},
-		{0x208, 0x18, 0x00},
-		{0x209, 0x32, 0x00},
-		{0x20a, 0x00, 0x00},
-		{0x20b, 0x5A, 0x00},
-		{0x20c, 0xBE, 0x00},/* 0x00 -> 0xBE Koski */
-		{0x20d, 0x00, 0x00}, /* DAI2 'off' */
-		{0x20e, 0x40, 0x00},
-		{0x20f, 0x00, 0x00},
-		{0x210, 0x84, 0x00},
-		{0x211, 0x33, 0x00}, /* Voice filter */
-		{0x212, 0x00, 0x00},
-		{0x213, 0x00, 0x00},
-		{0x214, 0x41, 0x00},
-		{0x215, 0x00, 0x00},
-		{0x216, 0x00, 0x00},
-		{0x217, 0x20, 0x00},
-		{0x218, 0x00, 0x00},
-		{0x219, 0x00, 0x00},
-		{0x21a, 0x40, 0x00},
-		{0x21b, 0x40, 0x00},
-		{0x21c, 0x09, 0x00},
-		{0x21d, 0x09, 0x00},
-		{0x21e, 0x00, 0x00},
-		{0x21f, 0x00, 0x00},
-		{0x220, 0x00, 0x00}, /* Microphone configurations */
-		{0x221, 0x00, 0x00}, /* Microphone configurations */
-		{0x222, 0x50, 0x00}, /* Microphone configurations */
-		{0x223, 0x21, 0x00}, /* Microphone configurations */
-		{0x224, 0x00, 0x00},
-		{0x225, 0x80, 0x00},
-		{0xf9, 0x40, 0x00},
-		{0xfa, 0x19, 0x00},
-		{0xfb, 0x19, 0x00},
-		{0xfc, 0x12, 0x00},
-		{0xfd, 0x12, 0x00},
-		{0xfe, 0x00, 0x00},
-	};
-
-	if (snd_pmic_ops_mx.card_status == SND_CARD_UN_INIT) {
-		retval = mx_init_card();
-		if (retval)
-			return retval;
-	}
-	pr_debug("SST DBG:mx_set_pcm_voice_params called\n");
-	return sst_sc_reg_access(sc_access, PMIC_WRITE, 44);
-}
-
-static int mx_set_pcm_audio_params(int sfreq, int word_size, int num_channel)
-{
-	int retval = 0;
-
-	int config1 = 0, config2 = 0, filter = 0xB3;
-	struct sc_reg_access sc_access[5];
-
-	if (snd_pmic_ops_mx.card_status == SND_CARD_UN_INIT) {
-		retval = mx_init_card();
-		if (retval)
-			return retval;
-	}
-
-	switch (sfreq) {
-	case 8000:
-		config1 = 0x10;
-		config2 = 0x00;
-		filter = 0x33;
-		break;
-	case 11025:
-		config1 = 0x16;
-		config2 = 0x0d;
-		break;
-	case 12000:
-		config1 = 0x18;
-		config2 = 0x00;
-		break;
-	case 16000:
-		config1 = 0x20;
-		config2 = 0x00;
-		break;
-	case 22050:
-		config1 = 0x2c;
-		config2 = 0x1a;
-		break;
-	case 24000:
-		config1 = 0x30;
-		config2 = 0x00;
-		break;
-	case 32000:
-		config1 = 0x40;
-		config2 = 0x00;
-		break;
-	case 44100:
-		config1 = 0x58;
-		config2 = 0x33;
-		break;
-	case 48000:
-		config1 = 0x60;
-		config2 = 0x00;
-		break;
-	}
-	snd_pmic_ops_mx.num_channel = num_channel;
-	/*mute the right channel if MONO*/
-	if (snd_pmic_ops_mx.num_channel == 1)	{
-		sc_access[0].reg_addr = VOL_CTRL_RT;
-		sc_access[0].value = 0x40;
-		sc_access[0].mask = MASK6;
-
-		sc_access[1].reg_addr = 0x224;
-		sc_access[1].value = 0x05;
-		sc_access[1].mask = MASK0|MASK1|MASK2;
-
-		retval = sst_sc_reg_access(sc_access, PMIC_READ_MODIFY, 2);
-		if (retval)
-			return retval;
-	} else {
-		sc_access[0].reg_addr = VOL_CTRL_RT;
-		sc_access[0].value = 0x00;
-		sc_access[0].mask = MASK6;
-
-		sc_access[1].reg_addr = 0x224;
-		sc_access[1].value = 0x04;
-		sc_access[1].mask = MASK0|MASK1|MASK2;
-
-		retval = sst_sc_reg_access(sc_access, PMIC_READ_MODIFY, 2);
-		if (retval)
-			return retval;
-	}
-	sc_access[0].reg_addr =	0x206;
-	sc_access[0].value = config1;
-	sc_access[1].reg_addr = 0x207;
-	sc_access[1].value = config2;
-
-	if (word_size == 16) {
-		sc_access[2].value = 0x51;
-		sc_access[3].value = 0x31;
-	} else if (word_size == 24) {
-		sc_access[2].value = 0x52;
-		sc_access[3].value = 0x92;
-	}
-
-	sc_access[2].reg_addr = 0x209;
-	sc_access[3].reg_addr = 0x20e;
-
-	sc_access[4].reg_addr = 0x211;
-	sc_access[4].value = filter;
-
-	return sst_sc_reg_access(sc_access, PMIC_WRITE, 5);
-}
-
-static int mx_set_selected_output_dev(u8 dev_id)
-{
-	struct sc_reg_access sc_access[2];
-	int num_reg = 0;
-	int retval = 0;
-
-	if (snd_pmic_ops_mx.card_status == SND_CARD_UN_INIT) {
-		retval = mx_init_card();
-		if (retval)
-			return retval;
-	}
-
-	pr_debug("mx_set_selected_output_dev dev_id:0x%x\n", dev_id);
-	snd_pmic_ops_mx.output_dev_id = dev_id;
-	switch (dev_id) {
-	case STEREO_HEADPHONE:
-		sc_access[0].reg_addr = 0xFF;
-		sc_access[0].value = 0x8C;
-		sc_access[0].mask =
-			MASK2|MASK3|MASK5|MASK6|MASK4;
-
-		num_reg = 1;
-		break;
-	case MONO_EARPIECE:
-	case INTERNAL_SPKR:
-		sc_access[0].reg_addr = 0xFF;
-		sc_access[0].value = 0xb0;
-		sc_access[0].mask =  MASK2|MASK3|MASK5|MASK6|MASK4;
-
-		num_reg = 1;
-		break;
-	case RECEIVER:
-		pr_debug("RECEIVER Koski selected\n");
-
-		/* configuration - AS enable, receiver enable */
-		sc_access[0].reg_addr = 0xFF;
-		sc_access[0].value = 0x81;
-		sc_access[0].mask = 0xff;
-
-		num_reg = 1;
-		break;
-	default:
-		pr_err("Not a valid output dev\n");
-		return 0;
-	}
-	return sst_sc_reg_access(sc_access, PMIC_WRITE, num_reg);
-}
-
-
-static int mx_set_voice_port(int status)
-{
-	int retval = 0;
-
-	if (snd_pmic_ops_mx.card_status == SND_CARD_UN_INIT) {
-		retval = mx_init_card();
-		if (retval)
-			return retval;
-	}
-	if (status == ACTIVATE)
-		retval = mx_set_pcm_voice_params();
-
-	return retval;
-}
-
-static int mx_set_audio_port(int status)
-{
-	return 0;
-}
-
-static int mx_set_selected_input_dev(u8 dev_id)
-{
-	struct sc_reg_access sc_access[2];
-	int num_reg = 0;
-	int retval = 0;
-
-	if (snd_pmic_ops_mx.card_status == SND_CARD_UN_INIT) {
-		retval = mx_init_card();
-		if (retval)
-			return retval;
-	}
-	snd_pmic_ops_mx.input_dev_id = dev_id;
-	pr_debug("mx_set_selected_input_dev dev_id:0x%x\n", dev_id);
-
-	switch (dev_id) {
-	case AMIC:
-		sc_access[0].reg_addr = 0x223;
-		sc_access[0].value = 0x00;
-		sc_access[0].mask = MASK7|MASK6|MASK5|MASK4|MASK0;
-		sc_access[1].reg_addr = 0x222;
-		sc_access[1].value = 0x50;
-		sc_access[1].mask = MASK7|MASK6|MASK5|MASK4;
-		num_reg = 2;
-		break;
-
-	case HS_MIC:
-		sc_access[0].reg_addr = 0x223;
-		sc_access[0].value = 0x20;
-		sc_access[0].mask = MASK7|MASK6|MASK5|MASK4|MASK0;
-		sc_access[1].reg_addr = 0x222;
-		sc_access[1].value = 0x51;
-		sc_access[1].mask = MASK7|MASK6|MASK5|MASK4;
-		num_reg = 2;
-		break;
-	case DMIC:
-		sc_access[1].reg_addr = 0x222;
-		sc_access[1].value = 0x00;
-		sc_access[1].mask = MASK7|MASK6|MASK5|MASK4|MASK0;
-		sc_access[0].reg_addr = 0x223;
-		sc_access[0].value = 0x20;
-		sc_access[0].mask = MASK7|MASK6|MASK5|MASK4|MASK0;
-		num_reg = 2;
-		break;
-	}
-	return sst_sc_reg_access(sc_access, PMIC_WRITE, num_reg);
-}
-
-static int mx_set_mute(int dev_id, u8 value)
-{
-	struct sc_reg_access sc_access[5];
-	int num_reg = 0;
-	int retval = 0;
-
-	if (snd_pmic_ops_mx.card_status == SND_CARD_UN_INIT) {
-		retval = mx_init_card();
-		if (retval)
-			return retval;
-	}
-
-
-	pr_debug("set_mute dev_id:0x%x , value:%d\n", dev_id, value);
-
-	switch (dev_id) {
-	case PMIC_SND_DMIC_MUTE:
-	case PMIC_SND_AMIC_MUTE:
-	case PMIC_SND_HP_MIC_MUTE:
-		sc_access[0].reg_addr =	0x220;
-		sc_access[1].reg_addr =	0x221;
-		sc_access[2].reg_addr =	0x223;
-		if (value == MUTE) {
-			sc_access[0].value = 0x00;
-			sc_access[1].value = 0x00;
-			if (snd_pmic_ops_mx.input_dev_id == DMIC)
-				sc_access[2].value = 0x00;
-			else
-				sc_access[2].value = 0x20;
-		} else {
-			sc_access[0].value = 0x20;
-			sc_access[1].value = 0x20;
-			if (snd_pmic_ops_mx.input_dev_id == DMIC)
-				sc_access[2].value = 0x20;
-			else
-				sc_access[2].value = 0x00;
-		}
-		sc_access[0].mask = MASK5|MASK6;
-		sc_access[1].mask = MASK5|MASK6;
-		sc_access[2].mask = MASK5|MASK6;
-		num_reg = 3;
-		break;
-	case PMIC_SND_LEFT_SPEAKER_MUTE:
-	case PMIC_SND_LEFT_HP_MUTE:
-		sc_access[0].reg_addr =	VOL_CTRL_LT;
-		if (value == MUTE)
-			sc_access[0].value = 0x40;
-		else
-			sc_access[0].value = 0x00;
-		sc_access[0].mask = MASK6;
-		num_reg = 1;
-		snd_pmic_ops_mx.mute_status = value;
-		break;
-	case PMIC_SND_RIGHT_SPEAKER_MUTE:
-	case PMIC_SND_RIGHT_HP_MUTE:
-		sc_access[0].reg_addr = VOL_CTRL_RT;
-		if (snd_pmic_ops_mx.num_channel == 1)
-			value = MUTE;
-		if (value == MUTE)
-			sc_access[0].value = 0x40;
-		else
-			sc_access[0].value = 0x00;
-		sc_access[0].mask = MASK6;
-		num_reg = 1;
-		snd_pmic_ops_mx.mute_status = value;
-		break;
-	case PMIC_SND_MUTE_ALL:
-		sc_access[0].reg_addr = VOL_CTRL_RT;
-		sc_access[1].reg_addr = VOL_CTRL_LT;
-		sc_access[2].reg_addr =	0x220;
-		sc_access[3].reg_addr =	0x221;
-		sc_access[4].reg_addr =	0x223;
-		snd_pmic_ops_mx.master_mute = value;
-		if (value == MUTE) {
-			sc_access[0].value = sc_access[1].value = 0x40;
-			sc_access[2].value = 0x00;
-			sc_access[3].value = 0x00;
-			if (snd_pmic_ops_mx.input_dev_id == DMIC)
-				sc_access[4].value = 0x00;
-			else
-				sc_access[4].value = 0x20;
-
-		} else {
-			sc_access[0].value = sc_access[1].value = 0x00;
-			sc_access[2].value = sc_access[3].value = 0x20;
-				sc_access[4].value = 0x20;
-			if (snd_pmic_ops_mx.input_dev_id == DMIC)
-				sc_access[4].value = 0x20;
-			else
-				sc_access[4].value = 0x00;
-
-
-		}
-		if (snd_pmic_ops_mx.num_channel == 1)
-			sc_access[0].value = 0x40;
-		sc_access[0].mask = sc_access[1].mask = MASK6;
-		sc_access[2].mask = MASK5|MASK6;
-		sc_access[3].mask = MASK5|MASK6|MASK2|MASK4;
-		sc_access[4].mask = MASK5|MASK6|MASK4;
-
-		num_reg = 5;
-		break;
-	case PMIC_SND_RECEIVER_MUTE:
-		sc_access[0].reg_addr =  VOL_CTRL_RT;
-		if (value == MUTE)
-			sc_access[0].value = 0x40;
-		else
-			sc_access[0].value = 0x00;
-		sc_access[0].mask = MASK6;
-		num_reg = 1;
-		break;
-	}
-
-	return sst_sc_reg_access(sc_access, PMIC_READ_MODIFY, num_reg);
-}
-
-static int mx_set_vol(int dev_id, int value)
-{
-	struct sc_reg_access sc_access[2] = {{0},};
-	int num_reg = 0;
-	int retval = 0;
-
-	if (snd_pmic_ops_mx.card_status == SND_CARD_UN_INIT) {
-		retval = mx_init_card();
-		if (retval)
-			return retval;
-	}
-	pr_debug("set_vol dev_id:0x%x ,value:%d\n", dev_id, value);
-	switch (dev_id) {
-	case PMIC_SND_RECEIVER_VOL:
-		return 0;
-		break;
-	case PMIC_SND_CAPTURE_VOL:
-		sc_access[0].reg_addr =	0x220;
-		sc_access[1].reg_addr =	0x221;
-		sc_access[0].value = sc_access[1].value = -value;
-		sc_access[0].mask = sc_access[1].mask =
-			(MASK0|MASK1|MASK2|MASK3|MASK4);
-		num_reg = 2;
-		break;
-	case PMIC_SND_LEFT_PB_VOL:
-		sc_access[0].value = -value;
-		sc_access[0].reg_addr = VOL_CTRL_LT;
-		sc_access[0].mask = (MASK0|MASK1|MASK2|MASK3|MASK4|MASK5);
-		num_reg = 1;
-		break;
-	case PMIC_SND_RIGHT_PB_VOL:
-		sc_access[0].value = -value;
-		sc_access[0].reg_addr = VOL_CTRL_RT;
-		sc_access[0].mask = (MASK0|MASK1|MASK2|MASK3|MASK4|MASK5);
-		if (snd_pmic_ops_mx.num_channel == 1) {
-			sc_access[0].value = 0x40;
-			sc_access[0].mask = MASK6;
-			sc_access[0].reg_addr = VOL_CTRL_RT;
-		}
-		num_reg = 1;
-		break;
-	}
-	return sst_sc_reg_access(sc_access, PMIC_READ_MODIFY, num_reg);
-}
-
-static int mx_get_mute(int dev_id, u8 *value)
-{
-	struct sc_reg_access sc_access[4] = {{0},};
-	int retval = 0, num_reg = 0, mask = 0;
-
-	if (snd_pmic_ops_mx.card_status == SND_CARD_UN_INIT) {
-		retval = mx_init_card();
-		if (retval)
-			return retval;
-	}
-	switch (dev_id) {
-	case PMIC_SND_DMIC_MUTE:
-	case PMIC_SND_AMIC_MUTE:
-	case PMIC_SND_HP_MIC_MUTE:
-		sc_access[0].reg_addr = 0x220;
-		mask = MASK5|MASK6;
-		num_reg = 1;
-		retval = sst_sc_reg_access(sc_access, PMIC_READ, num_reg);
-		if (retval)
-			return retval;
-		*value = sc_access[0].value & mask;
-		if (*value)
-			*value = UNMUTE;
-		else
-			*value = MUTE;
-		return retval;
-	case PMIC_SND_LEFT_HP_MUTE:
-	case PMIC_SND_LEFT_SPEAKER_MUTE:
-		sc_access[0].reg_addr = VOL_CTRL_LT;
-		num_reg = 1;
-		mask = MASK6;
-		break;
-	case PMIC_SND_RIGHT_HP_MUTE:
-	case PMIC_SND_RIGHT_SPEAKER_MUTE:
-		sc_access[0].reg_addr = VOL_CTRL_RT;
-		num_reg = 1;
-		mask = MASK6;
-		break;
-	}
-	retval = sst_sc_reg_access(sc_access, PMIC_READ, num_reg);
-	if (retval)
-		return retval;
-	*value = sc_access[0].value & mask;
-	if (*value)
-		*value = MUTE;
-	else
-		*value = UNMUTE;
-	return retval;
-}
-
-static int mx_get_vol(int dev_id, int *value)
-{
-	struct sc_reg_access sc_access = {0,};
-	int retval = 0, mask = 0, num_reg = 0;
-
-	if (snd_pmic_ops_mx.card_status == SND_CARD_UN_INIT) {
-		retval = mx_init_card();
-		if (retval)
-			return retval;
-	}
-	switch (dev_id) {
-	case PMIC_SND_CAPTURE_VOL:
-		sc_access.reg_addr = 0x220;
-		mask = MASK0|MASK1|MASK2|MASK3|MASK4;
-		num_reg = 1;
-		break;
-	case PMIC_SND_LEFT_PB_VOL:
-		sc_access.reg_addr = VOL_CTRL_LT;
-		mask = MASK0|MASK1|MASK2|MASK3|MASK4|MASK5;
-		num_reg = 1;
-		break;
-	case PMIC_SND_RIGHT_PB_VOL:
-		sc_access.reg_addr = VOL_CTRL_RT;
-		mask = MASK0|MASK1|MASK2|MASK3|MASK4|MASK5;
-		num_reg = 1;
-		break;
-	}
-	retval = sst_sc_reg_access(&sc_access, PMIC_READ, num_reg);
-	if (retval)
-		return retval;
-	*value = -(sc_access.value & mask);
-	pr_debug("get volume value extracted %d\n", *value);
-	return retval;
-}
-
-static u8 mx_get_jack_status(void)
-{
-	struct sc_reg_access sc_access_read = {0,};
-
-	sc_access_read.reg_addr = 0x201;
-	sst_sc_reg_access(&sc_access_read, PMIC_READ, 1);
-	pr_debug("value returned = 0x%x\n", sc_access_read.value);
-	return sc_access_read.value;
-}
-
-static void mx_pmic_irq_enable(void *data)
-{
-	struct snd_intelmad *intelmaddata = data;
-
-	intelmaddata->jack_prev_state = 0xc0;
-	return;
-}
-
-static void mx_pmic_irq_cb(void *cb_data, u8 intsts)
-{
-	u8 jack_cur_status, jack_prev_state = 0;
-	struct mad_jack *mjack = NULL;
-	unsigned int present = 0, jack_event_flag = 0, buttonpressflag = 0;
-	time_t  timediff;
-	struct snd_intelmad *intelmaddata = cb_data;
-
-	mjack = &intelmaddata->jack[0];
-	if (intsts & 0x2) {
-		jack_cur_status = mx_get_jack_status();
-		jack_prev_state = intelmaddata->jack_prev_state;
-		if ((jack_prev_state == 0xc0) && (jack_cur_status == 0x40)) {
-			/*headset insert detected. */
-			pr_debug("MAD headset inserted\n");
-			present = 1;
-			jack_event_flag = 1;
-			mjack->jack_status = 1;
-			mjack->jack.type = SND_JACK_HEADSET;
-		}
-
-		if ((jack_prev_state == 0xc0) && (jack_cur_status == 0x00)) {
-			/* headphone insert detected. */
-			pr_debug("MAD headphone inserted\n");
-			present = 1;
-			jack_event_flag = 1;
-			mjack->jack.type = SND_JACK_HEADPHONE;
-		}
-
-		if ((jack_prev_state == 0x40) && (jack_cur_status == 0xc0)) {
-			/* headset remove detected. */
-			pr_debug("MAD headset removed\n");
-
-			present = 0;
-			jack_event_flag = 1;
-			mjack->jack_status = 0;
-			mjack->jack.type = SND_JACK_HEADSET;
-		}
-
-		if ((jack_prev_state == 0x00) && (jack_cur_status == 0xc0)) {
-			/* headphone remove detected. */
-			pr_debug("MAD headphone removed\n");
-			present = 0;
-			jack_event_flag = 1;
-			mjack->jack.type = SND_JACK_HEADPHONE;
-		}
-
-		if ((jack_prev_state == 0x40) && (jack_cur_status == 0x00)) {
-			/* button pressed */
-			do_gettimeofday(&mjack->buttonpressed);
-			pr_debug("MAD button press detected\n");
-		}
-
-		if ((jack_prev_state == 0x00) && (jack_cur_status == 0x40)) {
-			if (mjack->jack_status) {
-				/*button pressed */
-				do_gettimeofday(
-					&mjack->buttonreleased);
-				/*button pressed */
-				pr_debug("MAD Button Released detected\n");
-				timediff = mjack->buttonreleased.tv_sec -
-					mjack->buttonpressed.tv_sec;
-				buttonpressflag = 1;
-
-				if (timediff > 1) {
-					pr_debug("MAD long press dtd\n");
-					/* send headphone detect/undetect */
-					present = 1;
-					jack_event_flag = 1;
-					mjack->jack.type =
-							MID_JACK_HS_LONG_PRESS;
-				} else {
-					pr_debug("MAD short press dtd\n");
-					/* send headphone detect/undetect */
-					present = 1;
-					jack_event_flag = 1;
-					mjack->jack.type =
-						MID_JACK_HS_SHORT_PRESS;
-				}
-			} else {
-				/***workaround for maxim
-				hw issue,0x00 t 0x40 is not
-				a valid transiton for Headset insertion */
-				/*headset insert detected. */
-				pr_debug("MAD headset inserted\n");
-				present = 1;
-				jack_event_flag = 1;
-				mjack->jack_status = 1;
-				mjack->jack.type = SND_JACK_HEADSET;
-			}
-		}
-		intelmaddata->jack_prev_state  = jack_cur_status;
-		pr_debug("mx_pmic_irq_cb prv_state= 0x%x\n",
-					intelmaddata->jack_prev_state);
-	}
-
-	if (jack_event_flag)
-		sst_mad_send_jack_report(&mjack->jack,
-						buttonpressflag, present);
-}
-static int mx_jack_enable(void)
-{
-	return 0;
-}
-
-struct snd_pmic_ops snd_pmic_ops_mx = {
-	.set_input_dev = mx_set_selected_input_dev,
-	.set_output_dev = mx_set_selected_output_dev,
-	.set_mute = mx_set_mute,
-	.get_mute = mx_get_mute,
-	.set_vol = mx_set_vol,
-	.get_vol = mx_get_vol,
-	.init_card = mx_init_card,
-	.set_pcm_audio_params = mx_set_pcm_audio_params,
-	.set_pcm_voice_params = mx_set_pcm_voice_params,
-	.set_voice_port = mx_set_voice_port,
-	.set_audio_port = mx_set_audio_port,
-	.power_up_pmic_pb =	mx_power_up_pb,
-	.power_up_pmic_cp =	mx_power_up_cp,
-	.power_down_pmic_pb =	mx_power_down_pb,
-	.power_down_pmic_cp =	mx_power_down_cp,
-	.power_down_pmic =	mx_power_down,
-	.pmic_irq_cb	 =	mx_pmic_irq_cb,
-	.pmic_irq_enable =	mx_pmic_irq_enable,
-	.pmic_jack_enable =	mx_jack_enable,
-};
-
diff --git a/drivers/staging/intel_sst/intelmid_v2_control.c b/drivers/staging/intel_sst/intelmid_v2_control.c
deleted file mode 100644
index 46ab55e..0000000
--- a/drivers/staging/intel_sst/intelmid_v2_control.c
+++ /dev/null
@@ -1,1156 +0,0 @@
-/*
- *  intelmid_v2_control.c - Intel Sound card driver for MID
- *
- *  Copyright (C) 2008-10 Intel Corp
- *  Authors:	Vinod Koul <vinod.koul@intel.com>
- *		Harsha Priya <priya.harsha@intel.com>
- *		KP Jeeja <jeeja.kp@intel.com>
- *		Dharageswari R <dharageswari.r@intel.com>
- *  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; version 2 of the License.
- *
- *  This program is distributed in the hope that it will be useful, but
- *  WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *  General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License along
- *  with this program; if not, write to the Free Software Foundation, Inc.,
- *  59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
- *
- * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- *
- *  This file contains the control operations of vendor 3
- */
-
-#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
-
-#include <linux/gpio.h>
-#include <linux/pci.h>
-#include <linux/delay.h>
-#include <linux/file.h>
-#include <sound/control.h>
-#include "intel_sst.h"
-#include "intelmid_snd_control.h"
-#include "intelmid.h"
-
-enum reg_v3 {
-	VAUDIOCNT = 0x51,
-	VOICEPORT1 = 0x100,
-	VOICEPORT2 = 0x101,
-	AUDIOPORT1 = 0x102,
-	AUDIOPORT2 = 0x103,
-	ADCSAMPLERATE = 0x104,
-	DMICCTRL1 = 0x105,
-	DMICCTRL2 = 0x106,
-	MICCTRL = 0x107,
-	MICSELVOL = 0x108,
-	LILSEL = 0x109,
-	LIRSEL = 0x10a,
-	VOICEVOL = 0x10b,
-	AUDIOLVOL = 0x10c,
-	AUDIORVOL = 0x10d,
-	LMUTE = 0x10e,
-	RMUTE = 0x10f,
-	POWERCTRL1 = 0x110,
-	POWERCTRL2 = 0x111,
-	DRVPOWERCTRL = 0x112,
-	VREFPLL = 0x113,
-	PCMBUFCTRL = 0x114,
-	SOFTMUTE = 0x115,
-	DTMFPATH = 0x116,
-	DTMFVOL = 0x117,
-	DTMFFREQ = 0x118,
-	DTMFHFREQ = 0x119,
-	DTMFLFREQ = 0x11a,
-	DTMFCTRL = 0x11b,
-	DTMFASON = 0x11c,
-	DTMFASOFF = 0x11d,
-	DTMFASINUM = 0x11e,
-	CLASSDVOL = 0x11f,
-	VOICEDACAVOL = 0x120,
-	AUDDACAVOL = 0x121,
-	LOMUTEVOL = 0x122,
-	HPLVOL = 0x123,
-	HPRVOL = 0x124,
-	MONOVOL = 0x125,
-	LINEOUTMIXVOL = 0x126,
-	EPMIXVOL = 0x127,
-	LINEOUTLSEL = 0x128,
-	LINEOUTRSEL = 0x129,
-	EPMIXOUTSEL = 0x12a,
-	HPLMIXSEL = 0x12b,
-	HPRMIXSEL = 0x12c,
-	LOANTIPOP = 0x12d,
-	AUXDBNC = 0x12f,
-};
-
-static void nc_set_amp_power(int power)
-{
-	if (snd_pmic_ops_nc.gpio_amp)
-		gpio_set_value(snd_pmic_ops_nc.gpio_amp, power);
-}
-
-/****
- * nc_init_card - initialize the sound card
- *
- * This initializes the audio paths to know values in case of this sound card
- */
-static int nc_init_card(void)
-{
-	struct sc_reg_access sc_access[] = {
-		{VAUDIOCNT, 0x25, 0},
-		{VOICEPORT1, 0x00, 0},
-		{VOICEPORT2, 0x00, 0},
-		{AUDIOPORT1, 0x98, 0},
-		{AUDIOPORT2, 0x09, 0},
-		{AUDIOLVOL, 0x00, 0},
-		{AUDIORVOL, 0x00, 0},
-		{LMUTE, 0x03, 0},
-		{RMUTE, 0x03, 0},
-		{POWERCTRL1, 0x00, 0},
-		{POWERCTRL2, 0x00, 0},
-		{DRVPOWERCTRL, 0x00, 0},
-		{VREFPLL, 0x10, 0},
-		{HPLMIXSEL, 0xee, 0},
-		{HPRMIXSEL, 0xf6, 0},
-		{PCMBUFCTRL, 0x0, 0},
-		{VOICEVOL, 0x0e, 0},
-		{HPLVOL, 0x06, 0},
-		{HPRVOL, 0x06, 0},
-		{MICCTRL, 0x51, 0x00},
-		{ADCSAMPLERATE, 0x8B, 0x00},
-		{MICSELVOL, 0x5B, 0x00},
-		{LILSEL, 0x06, 0},
-		{LIRSEL, 0x46, 0},
-		{LOANTIPOP, 0x00, 0},
-		{DMICCTRL1, 0x40, 0},
-		{AUXDBNC, 0xff, 0},
-	};
-	snd_pmic_ops_nc.card_status = SND_CARD_INIT_DONE;
-	snd_pmic_ops_nc.master_mute = UNMUTE;
-	snd_pmic_ops_nc.mute_status = UNMUTE;
-	sst_sc_reg_access(sc_access, PMIC_WRITE, 27);
-	mutex_init(&snd_pmic_ops_nc.lock);
-	pr_debug("init complete!!\n");
-	return 0;
-}
-
-static int nc_enable_audiodac(int value)
-{
-	struct sc_reg_access sc_access[3];
-	int mute_val = 0;
-
-	if (snd_pmic_ops_nc.mute_status == MUTE)
-		return 0;
-
-	if (((snd_pmic_ops_nc.output_dev_id == MONO_EARPIECE) ||
-		(snd_pmic_ops_nc.output_dev_id == INTERNAL_SPKR)) &&
-		(value == UNMUTE))
-		return 0;
-	if (value == UNMUTE) {
-			/* unmute the system, set the 7th bit to zero */
-			mute_val = 0x00;
-		} else {
-			/* MUTE:Set the seventh bit */
-			mute_val = 0x04;
-
-		}
-		sc_access[0].reg_addr = LMUTE;
-		sc_access[1].reg_addr = RMUTE;
-		sc_access[0].mask = sc_access[1].mask = MASK2;
-		sc_access[0].value = sc_access[1].value = mute_val;
-
-		if (snd_pmic_ops_nc.num_channel == 1)
-			sc_access[1].value = 0x04;
-		return sst_sc_reg_access(sc_access, PMIC_READ_MODIFY, 2);
-
-}
-
-static int nc_power_up_pb(unsigned int port)
-{
-	struct sc_reg_access sc_access[7];
-	int retval = 0;
-
-	if (snd_pmic_ops_nc.card_status == SND_CARD_UN_INIT)
-		retval = nc_init_card();
-	if (retval)
-		return retval;
-	if (port == 0xFF)
-		return 0;
-	mutex_lock(&snd_pmic_ops_nc.lock);
-	nc_enable_audiodac(MUTE);
-	msleep(30);
-
-	pr_debug("powering up pb....\n");
-
-	sc_access[0].reg_addr = VAUDIOCNT;
-	sc_access[0].value = 0x27;
-	sc_access[0].mask = 0x27;
-	sc_access[1].reg_addr = VREFPLL;
-	if (port == 0) {
-		sc_access[1].value = 0x3A;
-		sc_access[1].mask = 0x3A;
-	} else if (port == 1) {
-		sc_access[1].value = 0x35;
-		sc_access[1].mask = 0x35;
-	}
-	retval =  sst_sc_reg_access(sc_access, PMIC_READ_MODIFY, 2);
-
-
-
-	sc_access[0].reg_addr = POWERCTRL1;
-	if (port == 0) {
-		sc_access[0].value = 0x40;
-		sc_access[0].mask = 0x40;
-	} else if (port == 1) {
-		sc_access[0].value = 0x01;
-		sc_access[0].mask = 0x01;
-	}
-	sc_access[1].reg_addr = POWERCTRL2;
-	sc_access[1].value = 0x0C;
-	sc_access[1].mask = 0x0C;
-
-	sc_access[2].reg_addr = DRVPOWERCTRL;
-	sc_access[2].value = 0x86;
-	sc_access[2].mask = 0x86;
-
-	sst_sc_reg_access(sc_access, PMIC_READ_MODIFY, 3);
-
-	msleep(30);
-
-	snd_pmic_ops_nc.pb_on = 1;
-
-	/*
-	 * There is a mismatch between Playback Sources and the enumerated
-	 * values of output sources.  This mismatch causes ALSA upper to send
-	 * Item 1 for Internal Speaker, but the expected enumeration is 2!  For
-	 * now, treat MONO_EARPIECE and INTERNAL_SPKR identically and power up
-	 * the needed resources
-	 */
-	if (snd_pmic_ops_nc.output_dev_id == MONO_EARPIECE ||
-	    snd_pmic_ops_nc.output_dev_id == INTERNAL_SPKR)
-		nc_set_amp_power(1);
-	nc_enable_audiodac(UNMUTE);
-	mutex_unlock(&snd_pmic_ops_nc.lock);
-	return 0;
-}
-
-static int nc_power_up_cp(unsigned int port)
-{
-	struct sc_reg_access sc_access[5];
-	int retval = 0;
-
-
-	if (snd_pmic_ops_nc.card_status == SND_CARD_UN_INIT)
-		retval = nc_init_card();
-	if (retval)
-		return retval;
-
-
-	pr_debug("powering up cp....\n");
-
-	if (port == 0xFF)
-		return 0;
-	sc_access[0].reg_addr = VAUDIOCNT;
-	sc_access[0].value = 0x27;
-	sc_access[0].mask = 0x27;
-	sc_access[1].reg_addr = VREFPLL;
-	if (port == 0) {
-		sc_access[1].value = 0x3E;
-		sc_access[1].mask = 0x3E;
-	} else if (port == 1) {
-		sc_access[1].value = 0x35;
-		sc_access[1].mask = 0x35;
-	}
-
-	retval =  sst_sc_reg_access(sc_access, PMIC_READ_MODIFY, 2);
-
-
-	sc_access[0].reg_addr = POWERCTRL1;
-	if (port == 0) {
-		sc_access[0].value = 0xB4;
-		sc_access[0].mask = 0xB4;
-	} else if (port == 1) {
-		sc_access[0].value = 0xBF;
-		sc_access[0].mask = 0xBF;
-	}
-	sc_access[1].reg_addr = POWERCTRL2;
-	if (port == 0) {
-		sc_access[1].value = 0x0C;
-		sc_access[1].mask = 0x0C;
-	} else if (port == 1) {
-		sc_access[1].value = 0x02;
-		sc_access[1].mask = 0x02;
-	}
-
-	return  sst_sc_reg_access(sc_access, PMIC_READ_MODIFY, 2);
-
-}
-
-static int nc_power_down(void)
-{
-	int retval = 0;
-	struct sc_reg_access sc_access[5];
-
-	if (snd_pmic_ops_nc.card_status == SND_CARD_UN_INIT)
-		retval = nc_init_card();
-	if (retval)
-		return retval;
-	nc_enable_audiodac(MUTE);
-
-
-	pr_debug("powering dn nc_power_down ....\n");
-
-	if (snd_pmic_ops_nc.output_dev_id == MONO_EARPIECE ||
-	    snd_pmic_ops_nc.output_dev_id == INTERNAL_SPKR)
-		nc_set_amp_power(0);
-
-	msleep(30);
-
-	sc_access[0].reg_addr = DRVPOWERCTRL;
-	sc_access[0].value = 0x00;
-	sc_access[0].mask = 0x00;
-
-	sst_sc_reg_access(sc_access, PMIC_WRITE, 1);
-
-	sc_access[0].reg_addr = POWERCTRL1;
-	sc_access[0].value = 0x00;
-	sc_access[0].mask = 0x00;
-
-	sc_access[1].reg_addr = POWERCTRL2;
-	sc_access[1].value = 0x00;
-	sc_access[1].mask = 0x00;
-
-
-
-	sst_sc_reg_access(sc_access, PMIC_WRITE, 2);
-
-	msleep(30);
-	sc_access[0].reg_addr = VREFPLL;
-	sc_access[0].value = 0x10;
-	sc_access[0].mask = 0x10;
-
-	sc_access[1].reg_addr = VAUDIOCNT;
-	sc_access[1].value = 0x25;
-	sc_access[1].mask = 0x25;
-
-
-	retval =  sst_sc_reg_access(sc_access, PMIC_WRITE, 2);
-
-	msleep(30);
-	return nc_enable_audiodac(UNMUTE);
-}
-
-static int nc_power_down_pb(unsigned int device)
-{
-
-	int retval = 0;
-	struct sc_reg_access sc_access[5];
-
-	if (snd_pmic_ops_nc.card_status == SND_CARD_UN_INIT)
-		retval = nc_init_card();
-	if (retval)
-		return retval;
-
-	pr_debug("powering dn pb....\n");
-	mutex_lock(&snd_pmic_ops_nc.lock);
-	nc_enable_audiodac(MUTE);
-
-
-	msleep(30);
-
-
-	sc_access[0].reg_addr = DRVPOWERCTRL;
-	sc_access[0].value = 0x00;
-	sc_access[0].mask = 0x00;
-
-	sst_sc_reg_access(sc_access, PMIC_WRITE, 1);
-
-	msleep(30);
-
-	sc_access[0].reg_addr = POWERCTRL1;
-	sc_access[0].value = 0x00;
-	sc_access[0].mask = 0x41;
-
-	sc_access[1].reg_addr = POWERCTRL2;
-	sc_access[1].value = 0x00;
-	sc_access[1].mask = 0x0C;
-
-	sst_sc_reg_access(sc_access, PMIC_READ_MODIFY, 2);
-
-	msleep(30);
-
-	snd_pmic_ops_nc.pb_on = 0;
-
-	nc_enable_audiodac(UNMUTE);
-	mutex_unlock(&snd_pmic_ops_nc.lock);
-	return 0;
-}
-
-static int nc_power_down_cp(unsigned int device)
-{
-	struct sc_reg_access sc_access[] = {
-		{POWERCTRL1, 0x00, 0xBE},
-		{POWERCTRL2, 0x00, 0x02},
-	};
-	int retval = 0;
-
-	if (snd_pmic_ops_nc.card_status == SND_CARD_UN_INIT)
-		retval = nc_init_card();
-	if (retval)
-		return retval;
-
-	pr_debug("powering dn cp....\n");
-	return sst_sc_reg_access(sc_access, PMIC_READ_MODIFY, 1);
-}
-
-static int nc_set_pcm_voice_params(void)
-{
-	struct sc_reg_access sc_access[] = {
-			{0x100, 0xD5, 0},
-			{0x101, 0x08, 0},
-			{0x104, 0x03, 0},
-			{0x107, 0x10, 0},
-			{0x10B, 0x0E, 0},
-			{0x10E, 0x03, 0},
-			{0x10F, 0x03, 0},
-			{0x114, 0x13, 0},
-			{0x115, 0x00, 0},
-			{0x128, 0xFE, 0},
-			{0x129, 0xFE, 0},
-			{0x12A, 0xFE, 0},
-			{0x12B, 0xDE, 0},
-			{0x12C, 0xDE, 0},
-	};
-	int retval = 0;
-
-	if (snd_pmic_ops_nc.card_status == SND_CARD_UN_INIT)
-		retval = nc_init_card();
-	if (retval)
-		return retval;
-
-	sst_sc_reg_access(sc_access, PMIC_WRITE, 14);
-	pr_debug("Voice parameters set successfully!!\n");
-	return 0;
-}
-
-
-static int nc_set_pcm_audio_params(int sfreq, int word_size, int num_channel)
-{
-	int config2 = 0;
-	struct sc_reg_access sc_access;
-	int retval = 0;
-
-	if (snd_pmic_ops_nc.card_status == SND_CARD_UN_INIT)
-		retval = nc_init_card();
-	if (retval)
-		return retval;
-
-	switch (sfreq) {
-	case 8000:
-		config2 = 0x00;
-		break;
-	case 11025:
-		config2 = 0x01;
-		break;
-	case 12000:
-		config2 = 0x02;
-		break;
-	case 16000:
-		config2 = 0x03;
-		break;
-	case 22050:
-		config2 = 0x04;
-		break;
-	case 24000:
-		config2 = 0x05;
-		break;
-	case 32000:
-		config2 = 0x07;
-		break;
-	case 44100:
-		config2 = 0x08;
-		break;
-	case 48000:
-		config2 = 0x09;
-		break;
-	}
-
-	snd_pmic_ops_nc.num_channel = num_channel;
-	if (snd_pmic_ops_nc.num_channel == 1)	{
-
-		sc_access.value = 0x07;
-		sc_access.reg_addr = RMUTE;
-		pr_debug("RIGHT_HP_MUTE value%d\n", sc_access.value);
-		sc_access.mask = MASK2;
-		sst_sc_reg_access(&sc_access, PMIC_READ_MODIFY, 1);
-	} else {
-		sc_access.value = 0x00;
-		sc_access.reg_addr = RMUTE;
-		pr_debug("RIGHT_HP_MUTE value %d\n", sc_access.value);
-		sc_access.mask = MASK2;
-		sst_sc_reg_access(&sc_access, PMIC_READ_MODIFY, 1);
-
-
-	}
-
-	pr_debug("word_size = %d\n", word_size);
-
-	if (word_size == 24) {
-		sc_access.reg_addr = AUDIOPORT2;
-		sc_access.value = config2 | 0x10;
-		sc_access.mask = 0x1F;
-	} else {
-		sc_access.value = config2;
-		sc_access.mask = 0x1F;
-		sc_access.reg_addr = AUDIOPORT2;
-	}
-	sst_sc_reg_access(&sc_access, PMIC_READ_MODIFY, 1);
-
-	pr_debug("word_size = %d\n", word_size);
-	sc_access.reg_addr = AUDIOPORT1;
-	sc_access.mask = MASK5|MASK4|MASK1|MASK0;
-	if (word_size == 16)
-		sc_access.value = 0x98;
-	else if (word_size == 24)
-		sc_access.value = 0xAB;
-
-	return sst_sc_reg_access(&sc_access, PMIC_READ_MODIFY, 1);
-
-
-
-}
-
-static int nc_set_selected_output_dev(u8 value)
-{
-	struct sc_reg_access sc_access_HP[] = {
-		{LMUTE, 0x02, 0x06},
-		{RMUTE, 0x02, 0x06},
-		{DRVPOWERCTRL, 0x06, 0x06},
-	};
-	struct sc_reg_access sc_access_IS[] = {
-		{LMUTE, 0x04, 0x06},
-		{RMUTE, 0x04, 0x06},
-		{DRVPOWERCTRL, 0x00, 0x06},
-	};
-	int retval = 0;
-
-	snd_pmic_ops_nc.output_dev_id = value;
-	if (snd_pmic_ops_nc.card_status == SND_CARD_UN_INIT)
-		retval = nc_init_card();
-	if (retval)
-		return retval;
-	pr_debug("nc set selected output:%d\n", value);
-	mutex_lock(&snd_pmic_ops_nc.lock);
-	switch (value) {
-	case STEREO_HEADPHONE:
-		if (snd_pmic_ops_nc.pb_on)
-			sst_sc_reg_access(sc_access_HP+2, PMIC_WRITE, 1);
-		retval = sst_sc_reg_access(sc_access_HP, PMIC_WRITE, 2);
-		nc_set_amp_power(0);
-		break;
-	case MONO_EARPIECE:
-	case INTERNAL_SPKR:
-		retval = sst_sc_reg_access(sc_access_IS, PMIC_WRITE, 3);
-		if (snd_pmic_ops_nc.pb_on)
-			nc_set_amp_power(1);
-		break;
-	default:
-		pr_err("rcvd illegal request: %d\n", value);
-		mutex_unlock(&snd_pmic_ops_nc.lock);
-		return -EINVAL;
-	}
-	mutex_unlock(&snd_pmic_ops_nc.lock);
-	return retval;
-}
-
-static int nc_audio_init(void)
-{
-	struct sc_reg_access sc_acces, sc_access[] = {
-			{0x100, 0x00, 0},
-			{0x101, 0x00, 0},
-			{0x104, 0x8B, 0},
-			{0x107, 0x11, 0},
-			{0x10B, 0x0E, 0},
-			{0x114, 0x00, 0},
-			{0x115, 0x00, 0},
-			{0x128, 0x00, 0},
-			{0x129, 0x00, 0},
-			{0x12A, 0x00, 0},
-			{0x12B, 0xee, 0},
-			{0x12C, 0xf6, 0},
-	};
-
-	sst_sc_reg_access(sc_access, PMIC_WRITE, 12);
-	pr_debug("Audio Init successfully!!\n");
-
-	/*set output device */
-	nc_set_selected_output_dev(snd_pmic_ops_nc.output_dev_id);
-
-	if (snd_pmic_ops_nc.num_channel == 1) {
-		sc_acces.value = 0x07;
-		sc_acces.reg_addr = RMUTE;
-		pr_debug("RIGHT_HP_MUTE value%d\n", sc_acces.value);
-		sc_acces.mask = MASK2;
-		sst_sc_reg_access(&sc_acces, PMIC_READ_MODIFY, 1);
-	} else {
-		sc_acces.value = 0x00;
-		sc_acces.reg_addr = RMUTE;
-		pr_debug("RIGHT_HP_MUTE value%d\n", sc_acces.value);
-		sc_acces.mask = MASK2;
-		sst_sc_reg_access(&sc_acces, PMIC_READ_MODIFY, 1);
-	}
-
-	return 0;
-}
-
-static int nc_set_audio_port(int status)
-{
-	struct sc_reg_access sc_access[2] = {{0,},};
-	int retval = 0;
-
-	if (snd_pmic_ops_nc.card_status == SND_CARD_UN_INIT)
-		retval = nc_init_card();
-	if (retval)
-		return retval;
-
-	if (status == DEACTIVATE) {
-		/* Deactivate audio port-tristate and power */
-		sc_access[0].value = 0x00;
-		sc_access[0].mask = MASK4|MASK5;
-		sc_access[0].reg_addr = AUDIOPORT1;
-		return sst_sc_reg_access(sc_access, PMIC_READ_MODIFY, 1);
-	} else if (status == ACTIVATE) {
-		/* activate audio port */
-		nc_audio_init();
-		sc_access[0].value = 0x10;
-		sc_access[0].mask =  MASK4|MASK5 ;
-		sc_access[0].reg_addr = AUDIOPORT1;
-		return sst_sc_reg_access(sc_access, PMIC_READ_MODIFY, 1);
-	} else
-		return -EINVAL;
-
-}
-
-static int nc_set_voice_port(int status)
-{
-	struct sc_reg_access sc_access[2] = {{0,},};
-	int retval = 0;
-
-	if (snd_pmic_ops_nc.card_status == SND_CARD_UN_INIT)
-		retval = nc_init_card();
-	if (retval)
-		return retval;
-
-	if (status == DEACTIVATE) {
-		/* Activate Voice port */
-		sc_access[0].value = 0x00;
-		sc_access[0].mask = MASK4;
-		sc_access[0].reg_addr = VOICEPORT1;
-		return sst_sc_reg_access(sc_access, PMIC_READ_MODIFY, 1);
-	} else if (status == ACTIVATE) {
-		/* Deactivate voice port */
-		nc_set_pcm_voice_params();
-		sc_access[0].value = 0x10;
-		sc_access[0].mask = MASK4;
-		sc_access[0].reg_addr = VOICEPORT1;
-		return sst_sc_reg_access(sc_access, PMIC_READ_MODIFY, 1);
-	} else
-		return -EINVAL;
-}
-
-static int nc_set_mute(int dev_id, u8 value)
-{
-	struct sc_reg_access sc_access[3];
-	u8 mute_val, cap_mute;
-	int retval = 0;
-
-	if (snd_pmic_ops_nc.card_status == SND_CARD_UN_INIT)
-		retval = nc_init_card();
-	if (retval)
-		return retval;
-
-	pr_debug("set device id::%d, value %d\n", dev_id, value);
-
-	switch (dev_id) {
-	case PMIC_SND_MUTE_ALL:
-		pr_debug("PMIC_SND_MUTE_ALL value %d\n", value);
-		snd_pmic_ops_nc.mute_status = value;
-		snd_pmic_ops_nc.master_mute = value;
-		if (value == UNMUTE) {
-			/* unmute the system, set the 7th bit to zero */
-			mute_val = cap_mute = 0x00;
-		} else {
-			/* MUTE:Set the seventh bit */
-			mute_val = 0x80;
-			cap_mute = 0x40;
-		}
-		sc_access[0].reg_addr = AUDIOLVOL;
-		sc_access[1].reg_addr = AUDIORVOL;
-		sc_access[0].mask = sc_access[1].mask = MASK7;
-		sc_access[0].value = sc_access[1].value = mute_val;
-		if (snd_pmic_ops_nc.num_channel == 1)
-				sc_access[1].value = 0x80;
-		if (!sst_sc_reg_access(sc_access, PMIC_READ_MODIFY, 2)) {
-			sc_access[0].reg_addr = 0x109;
-			sc_access[1].reg_addr = 0x10a;
-			sc_access[2].reg_addr = 0x105;
-			sc_access[0].mask = sc_access[1].mask =
-				sc_access[2].mask = MASK6;
-			sc_access[0].value = sc_access[1].value =
-				sc_access[2].value = cap_mute;
-
-			if ((snd_pmic_ops_nc.input_dev_id == AMIC) ||
-				(snd_pmic_ops_nc.input_dev_id == DMIC))
-					sc_access[1].value = 0x40;
-			if (snd_pmic_ops_nc.input_dev_id == HS_MIC)
-					sc_access[0].value = 0x40;
-			retval = sst_sc_reg_access(sc_access,
-					PMIC_READ_MODIFY, 3);
-		}
-		break;
-	case PMIC_SND_HP_MIC_MUTE:
-		pr_debug("PMIC_SND_HPMIC_MUTE value %d\n", value);
-		if (value == UNMUTE) {
-			/* unmute the system, set the 6th bit to one */
-			sc_access[0].value = 0x00;
-		} else {
-			/* mute the system, reset the 6th bit to zero */
-			sc_access[0].value = 0x40;
-		}
-		sc_access[0].reg_addr = LIRSEL;
-		sc_access[0].mask = MASK6;
-		retval = sst_sc_reg_access(sc_access, PMIC_READ_MODIFY, 1);
-		break;
-	case PMIC_SND_AMIC_MUTE:
-		pr_debug("PMIC_SND_AMIC_MUTE value %d\n", value);
-		if (value == UNMUTE) {
-			/* unmute the system, set the 6th bit to one */
-			sc_access[0].value = 0x00;
-		} else {
-			/* mute the system, reset the 6th bit to zero */
-			sc_access[0].value = 0x40;
-		}
-		sc_access[0].reg_addr = LILSEL;
-		sc_access[0].mask = MASK6;
-		retval = sst_sc_reg_access(sc_access, PMIC_READ_MODIFY, 1);
-		break;
-
-	case PMIC_SND_DMIC_MUTE:
-		pr_debug("INPUT_MUTE_DMIC value%d\n", value);
-		if (value == UNMUTE) {
-			/* unmute the system, set the 6th bit to one */
-			sc_access[1].value = 0x00;
-			sc_access[0].value = 0x00;
-		} else {
-			/* mute the system, reset the 6th bit to zero */
-			sc_access[1].value = 0x40;
-			sc_access[0].value = 0x40;
-		}
-		sc_access[0].reg_addr = DMICCTRL1;
-		sc_access[0].mask = MASK6;
-		sc_access[1].reg_addr = LILSEL;
-		sc_access[1].mask = MASK6;
-		retval = sst_sc_reg_access(sc_access,
-					PMIC_READ_MODIFY, 2);
-		break;
-
-	case PMIC_SND_LEFT_HP_MUTE:
-	case PMIC_SND_RIGHT_HP_MUTE:
-		snd_pmic_ops_nc.mute_status = value;
-		if (value == UNMUTE)
-			sc_access[0].value = 0x0;
-		else
-			sc_access[0].value = 0x04;
-
-		if (dev_id == PMIC_SND_LEFT_HP_MUTE) {
-			sc_access[0].reg_addr = LMUTE;
-			pr_debug("LEFT_HP_MUTE value %d\n",
-					sc_access[0].value);
-		} else {
-			if (snd_pmic_ops_nc.num_channel == 1)
-				sc_access[0].value = 0x04;
-			sc_access[0].reg_addr = RMUTE;
-			pr_debug("RIGHT_HP_MUTE value %d\n",
-					sc_access[0].value);
-		}
-		sc_access[0].mask = MASK2;
-		retval = sst_sc_reg_access(sc_access, PMIC_READ_MODIFY, 1);
-		break;
-	case PMIC_SND_LEFT_SPEAKER_MUTE:
-	case PMIC_SND_RIGHT_SPEAKER_MUTE:
-		if (value == UNMUTE)
-			sc_access[0].value = 0x00;
-		else
-			sc_access[0].value = 0x03;
-		sc_access[0].reg_addr = LMUTE;
-		pr_debug("SPEAKER_MUTE %d\n", sc_access[0].value);
-		sc_access[0].mask = MASK1;
-		retval = sst_sc_reg_access(sc_access, PMIC_READ_MODIFY, 1);
-		break;
-	default:
-		return -EINVAL;
-	}
-	return retval ;
-
-}
-
-static int nc_set_vol(int dev_id, int value)
-{
-	struct sc_reg_access sc_access[3];
-	int retval = 0, entries = 0;
-
-	if (snd_pmic_ops_nc.card_status == SND_CARD_UN_INIT)
-		retval = nc_init_card();
-	if (retval)
-		return retval;
-
-	pr_debug("set volume:%d\n", dev_id);
-	switch (dev_id) {
-	case PMIC_SND_CAPTURE_VOL:
-		pr_debug("PMIC_SND_CAPTURE_VOL:value::%d\n", value);
-		sc_access[0].value = sc_access[1].value =
-					sc_access[2].value = -value;
-		sc_access[0].mask = sc_access[1].mask = sc_access[2].mask =
-					(MASK0|MASK1|MASK2|MASK3|MASK4|MASK5);
-		sc_access[0].reg_addr = 0x10a;
-		sc_access[1].reg_addr = 0x109;
-		sc_access[2].reg_addr = 0x105;
-		entries = 3;
-		break;
-
-	case PMIC_SND_LEFT_PB_VOL:
-		pr_debug("PMIC_SND_LEFT_HP_VOL %d\n", value);
-		sc_access[0].value = -value;
-		sc_access[0].reg_addr  = HPLVOL;
-		sc_access[0].mask = (MASK0|MASK1|MASK2|MASK3|MASK4);
-		entries = 1;
-		break;
-
-	case PMIC_SND_RIGHT_PB_VOL:
-		pr_debug("PMIC_SND_RIGHT_HP_VOL value %d\n", value);
-		if (snd_pmic_ops_nc.num_channel == 1) {
-			sc_access[0].value = 0x04;
-			sc_access[0].reg_addr = RMUTE;
-			sc_access[0].mask = MASK2;
-		} else {
-			sc_access[0].value = -value;
-			sc_access[0].reg_addr  = HPRVOL;
-			sc_access[0].mask = (MASK0|MASK1|MASK2|MASK3|MASK4);
-		}
-		entries = 1;
-		break;
-
-	case PMIC_SND_LEFT_MASTER_VOL:
-		pr_debug("PMIC_SND_LEFT_MASTER_VOL value %d\n", value);
-		sc_access[0].value = -value;
-		sc_access[0].reg_addr = AUDIOLVOL;
-		sc_access[0].mask =
-			(MASK0|MASK1|MASK2|MASK3|MASK4|MASK5|MASK6);
-		entries = 1;
-		break;
-
-	case PMIC_SND_RIGHT_MASTER_VOL:
-		pr_debug("PMIC_SND_RIGHT_MASTER_VOL value %d\n", value);
-		sc_access[0].value = -value;
-		sc_access[0].reg_addr = AUDIORVOL;
-		sc_access[0].mask =
-				(MASK0|MASK1|MASK2|MASK3|MASK4|MASK5|MASK6);
-		entries = 1;
-		break;
-
-	default:
-		return -EINVAL;
-
-	}
-	return sst_sc_reg_access(sc_access, PMIC_READ_MODIFY, entries);
-}
-
-static int nc_set_selected_input_dev(u8 value)
-{
-	struct sc_reg_access sc_access[6];
-	u8 num_val;
-	int retval = 0;
-
-	if (snd_pmic_ops_nc.card_status == SND_CARD_UN_INIT)
-		retval = nc_init_card();
-	if (retval)
-		return retval;
-	snd_pmic_ops_nc.input_dev_id = value;
-
-	pr_debug("nc set selected input:%d\n", value);
-
-	switch (value) {
-	case AMIC:
-		pr_debug("Selecting AMIC\n");
-		sc_access[0].reg_addr = 0x107;
-		sc_access[0].value = 0x40;
-		sc_access[0].mask =  MASK6|MASK3|MASK1|MASK0;
-		sc_access[1].reg_addr = 0x10a;
-		sc_access[1].value = 0x40;
-		sc_access[1].mask = MASK6;
-		sc_access[2].reg_addr = 0x109;
-		sc_access[2].value = 0x00;
-		sc_access[2].mask = MASK6;
-		sc_access[3].reg_addr = 0x105;
-		sc_access[3].value = 0x40;
-		sc_access[3].mask = MASK6;
-		num_val = 4;
-		break;
-
-	case HS_MIC:
-		pr_debug("Selecting HS_MIC\n");
-		sc_access[0].reg_addr = MICCTRL;
-		sc_access[0].mask =  MASK6|MASK3|MASK1|MASK0;
-		sc_access[0].value = 0x00;
-		sc_access[1].reg_addr = 0x109;
-		sc_access[1].mask = MASK6;
-		sc_access[1].value = 0x40;
-		sc_access[2].reg_addr = 0x10a;
-		sc_access[2].mask = MASK6;
-		sc_access[2].value = 0x00;
-		sc_access[3].reg_addr = 0x105;
-		sc_access[3].value = 0x40;
-		sc_access[3].mask = MASK6;
-		sc_access[4].reg_addr = ADCSAMPLERATE;
-		sc_access[4].mask = MASK7|MASK6|MASK5|MASK4|MASK3;
-		sc_access[4].value = 0xc8;
-		num_val = 5;
-		break;
-
-	case DMIC:
-		pr_debug("DMIC\n");
-		sc_access[0].reg_addr = MICCTRL;
-		sc_access[0].mask = MASK6|MASK3|MASK1|MASK0;
-		sc_access[0].value = 0x0B;
-		sc_access[1].reg_addr = 0x105;
-		sc_access[1].value = 0x80;
-		sc_access[1].mask = MASK7|MASK6;
-		sc_access[2].reg_addr = 0x10a;
-		sc_access[2].value = 0x40;
-		sc_access[2].mask = MASK6;
-		sc_access[3].reg_addr = LILSEL;
-		sc_access[3].mask = MASK6;
-		sc_access[3].value = 0x00;
-		sc_access[4].reg_addr = ADCSAMPLERATE;
-		sc_access[4].mask =  MASK7|MASK6|MASK5|MASK4|MASK3;
-		sc_access[4].value = 0x33;
-		num_val = 5;
-		break;
-	default:
-		return -EINVAL;
-	}
-	return sst_sc_reg_access(sc_access, PMIC_READ_MODIFY, num_val);
-}
-
-static int nc_get_mute(int dev_id, u8 *value)
-{
-	int retval = 0, mask = 0;
-	struct sc_reg_access sc_access = {0,};
-
-	if (snd_pmic_ops_nc.card_status == SND_CARD_UN_INIT)
-		retval = nc_init_card();
-	if (retval)
-		return retval;
-
-	pr_debug("get mute::%d\n", dev_id);
-
-	switch (dev_id) {
-	case PMIC_SND_AMIC_MUTE:
-		pr_debug("PMIC_SND_INPUT_MUTE_MIC1\n");
-		sc_access.reg_addr = LILSEL;
-		mask = MASK6;
-		break;
-	case PMIC_SND_HP_MIC_MUTE:
-		pr_debug("PMIC_SND_INPUT_MUTE_MIC2\n");
-		sc_access.reg_addr = LIRSEL;
-		mask = MASK6;
-		break;
-	case PMIC_SND_LEFT_HP_MUTE:
-	case PMIC_SND_RIGHT_HP_MUTE:
-		mask = MASK2;
-		pr_debug("PMIC_SN_LEFT/RIGHT_HP_MUTE\n");
-		if (dev_id == PMIC_SND_RIGHT_HP_MUTE)
-			sc_access.reg_addr = RMUTE;
-		else
-			sc_access.reg_addr = LMUTE;
-		break;
-
-	case PMIC_SND_LEFT_SPEAKER_MUTE:
-		pr_debug("PMIC_MONO_EARPIECE_MUTE\n");
-		sc_access.reg_addr = RMUTE;
-		mask = MASK1;
-		break;
-	case PMIC_SND_DMIC_MUTE:
-		pr_debug("PMIC_SND_INPUT_MUTE_DMIC\n");
-		sc_access.reg_addr = 0x105;
-		mask = MASK6;
-		break;
-	default:
-		return -EINVAL;
-
-	}
-	retval = sst_sc_reg_access(&sc_access, PMIC_READ, 1);
-	pr_debug("reg value = %d\n", sc_access.value);
-	if (retval)
-		return retval;
-	*value = (sc_access.value) & mask;
-	pr_debug("masked value = %d\n", *value);
-	if (*value)
-		*value = 0;
-	else
-		*value = 1;
-	pr_debug("value returned = 0x%x\n", *value);
-	return retval;
-}
-
-static int nc_get_vol(int dev_id, int *value)
-{
-	int retval = 0, mask = 0;
-	struct sc_reg_access sc_access = {0,};
-
-	if (snd_pmic_ops_nc.card_status == SND_CARD_UN_INIT)
-		retval = nc_init_card();
-	if (retval)
-		return retval;
-
-	switch (dev_id) {
-	case PMIC_SND_CAPTURE_VOL:
-		pr_debug("PMIC_SND_INPUT_CAPTURE_VOL\n");
-		sc_access.reg_addr =  LILSEL;
-		mask = (MASK0|MASK1|MASK2|MASK3|MASK4|MASK5);
-		break;
-
-	case PMIC_SND_LEFT_MASTER_VOL:
-		pr_debug("GET_VOLUME_PMIC_LEFT_MASTER_VOL\n");
-		sc_access.reg_addr = AUDIOLVOL;
-		mask = (MASK0|MASK1|MASK2|MASK3|MASK4|MASK5|MASK6);
-		break;
-
-	case PMIC_SND_RIGHT_MASTER_VOL:
-		pr_debug("GET_VOLUME_PMIC_RIGHT_MASTER_VOL\n");
-		sc_access.reg_addr = AUDIORVOL;
-		mask = (MASK0|MASK1|MASK2|MASK3|MASK4|MASK5|MASK6);
-		break;
-
-	case PMIC_SND_RIGHT_PB_VOL:
-		pr_debug("GET_VOLUME_PMIC_RIGHT_HP_VOL\n");
-		sc_access.reg_addr = HPRVOL;
-		mask = (MASK0|MASK1|MASK2|MASK3|MASK4);
-		break;
-
-	case PMIC_SND_LEFT_PB_VOL:
-		pr_debug("GET_VOLUME_PMIC_LEFT_HP_VOL\n");
-		sc_access.reg_addr = HPLVOL;
-		mask = (MASK0|MASK1|MASK2|MASK3|MASK4);
-		break;
-
-	default:
-		return -EINVAL;
-
-	}
-	retval = sst_sc_reg_access(&sc_access, PMIC_READ, 1);
-	pr_debug("value read = 0x%x\n", sc_access.value);
-	*value = -((sc_access.value) & mask);
-	pr_debug("get vol value returned = %d\n", *value);
-	return retval;
-}
-
-static void hp_automute(enum snd_jack_types type, int present)
-{
-	u8 in = DMIC;
-	u8 out = INTERNAL_SPKR;
-	if (present) {
-		if (type == SND_JACK_HEADSET)
-			in = HS_MIC;
-		out = STEREO_HEADPHONE;
-	}
-	nc_set_selected_input_dev(in);
-	nc_set_selected_output_dev(out);
-}
-
-static void nc_pmic_irq_cb(void *cb_data, u8 intsts)
-{
-	u8 value = 0;
-	struct mad_jack *mjack = NULL;
-	unsigned int present = 0, jack_event_flag = 0, buttonpressflag = 0;
-	struct snd_intelmad *intelmaddata = cb_data;
-	struct sc_reg_access sc_access_read = {0,};
-
-	sc_access_read.reg_addr = 0x132;
-	sst_sc_reg_access(&sc_access_read, PMIC_READ, 1);
-	value = (sc_access_read.value);
-	pr_debug("value returned = 0x%x\n", value);
-
-	mjack = &intelmaddata->jack[0];
-	if (intsts & 0x1) {
-		pr_debug("SST DBG:MAD headset detected\n");
-		/* send headset detect/undetect */
-		present = (value == 0x1) ? 3 : 0;
-		jack_event_flag = 1;
-		mjack->jack.type = SND_JACK_HEADSET;
-		hp_automute(SND_JACK_HEADSET, present);
-	}
-
-	if (intsts & 0x2) {
-		pr_debug(":MAD headphone detected\n");
-		/* send headphone detect/undetect */
-		present = (value == 0x2) ? 1 : 0;
-		jack_event_flag = 1;
-		mjack->jack.type = SND_JACK_HEADPHONE;
-		hp_automute(SND_JACK_HEADPHONE, present);
-	}
-
-	if (intsts & 0x4) {
-		pr_debug("MAD short push detected\n");
-		/* send short push */
-		present = 1;
-		jack_event_flag = 1;
-		buttonpressflag = 1;
-		mjack->jack.type = MID_JACK_HS_SHORT_PRESS;
-	}
-
-	if (intsts & 0x8) {
-		pr_debug(":MAD long push detected\n");
-		/* send long push */
-		present = 1;
-		jack_event_flag = 1;
-		buttonpressflag = 1;
-		mjack->jack.type = MID_JACK_HS_LONG_PRESS;
-	}
-
-	if (jack_event_flag)
-		sst_mad_send_jack_report(&mjack->jack,
-					buttonpressflag, present);
-}
-static int nc_jack_enable(void)
-{
-	return 0;
-}
-
-struct snd_pmic_ops snd_pmic_ops_nc = {
-	.input_dev_id   =       DMIC,
-	.output_dev_id  =       INTERNAL_SPKR,
-	.set_input_dev	=	nc_set_selected_input_dev,
-	.set_output_dev =	nc_set_selected_output_dev,
-	.set_mute	=	nc_set_mute,
-	.get_mute	=	nc_get_mute,
-	.set_vol	=	nc_set_vol,
-	.get_vol	=	nc_get_vol,
-	.init_card	=	nc_init_card,
-	.set_pcm_audio_params	= nc_set_pcm_audio_params,
-	.set_pcm_voice_params	= nc_set_pcm_voice_params,
-	.set_voice_port = nc_set_voice_port,
-	.set_audio_port = nc_set_audio_port,
-	.power_up_pmic_pb =	nc_power_up_pb,
-	.power_up_pmic_cp =	nc_power_up_cp,
-	.power_down_pmic_pb =	nc_power_down_pb,
-	.power_down_pmic_cp =	nc_power_down_cp,
-	.power_down_pmic	=	nc_power_down,
-	.pmic_irq_cb	=	nc_pmic_irq_cb,
-	.pmic_jack_enable =	nc_jack_enable,
-};
diff --git a/drivers/staging/line6/Makefile b/drivers/staging/line6/Makefile
index de6bd12..34a2dda 100644
--- a/drivers/staging/line6/Makefile
+++ b/drivers/staging/line6/Makefile
@@ -12,4 +12,5 @@
 		playback.o	\
 		pod.o		\
 		toneport.o	\
-		variax.o
+		variax.o	\
+		podhd.o
diff --git a/drivers/staging/line6/capture.c b/drivers/staging/line6/capture.c
index 9647154..127f952 100644
--- a/drivers/staging/line6/capture.c
+++ b/drivers/staging/line6/capture.c
@@ -9,6 +9,7 @@
  *
  */
 
+#include <linux/slab.h>
 #include <sound/core.h>
 #include <sound/pcm.h>
 #include <sound/pcm_params.h>
@@ -192,6 +193,31 @@
 	}
 }
 
+int line6_alloc_capture_buffer(struct snd_line6_pcm *line6pcm)
+{
+	/* We may be invoked multiple times in a row so allocate once only */
+	if (line6pcm->buffer_in)
+		return 0;
+
+	line6pcm->buffer_in =
+		kmalloc(LINE6_ISO_BUFFERS * LINE6_ISO_PACKETS *
+			line6pcm->max_packet_size, GFP_KERNEL);
+
+	if (!line6pcm->buffer_in) {
+		dev_err(line6pcm->line6->ifcdev,
+			"cannot malloc capture buffer\n");
+		return -ENOMEM;
+	}
+
+	return 0;
+}
+
+void line6_free_capture_buffer(struct snd_line6_pcm *line6pcm)
+{
+	kfree(line6pcm->buffer_in);
+	line6pcm->buffer_in = NULL;
+}
+
 /*
  * Callback for completed capture URB.
  */
@@ -243,11 +269,7 @@
 		length += fsize;
 
 		/* the following assumes LINE6_ISO_PACKETS == 1: */
-#if LINE6_BACKUP_MONITOR_SIGNAL
-		memcpy(line6pcm->prev_fbuf, fbuf, fsize);
-#else
 		line6pcm->prev_fbuf = fbuf;
-#endif
 		line6pcm->prev_fsize = fsize;
 
 #ifdef CONFIG_LINE6_USB_IMPULSE_RESPONSE
@@ -319,6 +341,13 @@
 	}
 	/* -- [FD] end */
 
+	if ((line6pcm->flags & MASK_CAPTURE) == 0) {
+		ret = line6_alloc_capture_buffer(line6pcm);
+
+		if (ret < 0)
+			return ret;
+	}
+
 	ret = snd_pcm_lib_malloc_pages(substream,
 				       params_buffer_bytes(hw_params));
 	if (ret < 0)
@@ -331,6 +360,13 @@
 /* hw_free capture callback */
 static int snd_line6_capture_hw_free(struct snd_pcm_substream *substream)
 {
+	struct snd_line6_pcm *line6pcm = snd_pcm_substream_chip(substream);
+
+	if ((line6pcm->flags & MASK_CAPTURE) == 0) {
+		line6_unlink_wait_clear_audio_in_urbs(line6pcm);
+		line6_free_capture_buffer(line6pcm);
+	}
+
 	return snd_pcm_lib_free_pages(substream);
 }
 
diff --git a/drivers/staging/line6/capture.h b/drivers/staging/line6/capture.h
index a7509fb..366cbaa 100644
--- a/drivers/staging/line6/capture.h
+++ b/drivers/staging/line6/capture.h
@@ -19,11 +19,13 @@
 
 extern struct snd_pcm_ops snd_line6_capture_ops;
 
+extern int line6_alloc_capture_buffer(struct snd_line6_pcm *line6pcm);
 extern void line6_capture_copy(struct snd_line6_pcm *line6pcm, char *fbuf,
 			       int fsize);
 extern void line6_capture_check_period(struct snd_line6_pcm *line6pcm,
 				       int length);
 extern int line6_create_audio_in_urbs(struct snd_line6_pcm *line6pcm);
+extern void line6_free_capture_buffer(struct snd_line6_pcm *line6pcm);
 extern int line6_submit_audio_in_all_urbs(struct snd_line6_pcm *line6pcm);
 extern void line6_unlink_audio_in_urbs(struct snd_line6_pcm *line6pcm);
 extern void line6_unlink_wait_clear_audio_in_urbs(struct snd_line6_pcm
diff --git a/drivers/staging/line6/driver.c b/drivers/staging/line6/driver.c
index 851b762..6a1959e 100644
--- a/drivers/staging/line6/driver.c
+++ b/drivers/staging/line6/driver.c
@@ -21,6 +21,7 @@
 #include "midi.h"
 #include "playback.h"
 #include "pod.h"
+#include "podhd.h"
 #include "revision.h"
 #include "toneport.h"
 #include "usbdefs.h"
@@ -37,6 +38,8 @@
 	{USB_DEVICE(LINE6_VENDOR_ID, LINE6_DEVID_BASSPODXTPRO)},
 	{USB_DEVICE(LINE6_VENDOR_ID, LINE6_DEVID_GUITARPORT)},
 	{USB_DEVICE(LINE6_VENDOR_ID, LINE6_DEVID_POCKETPOD)},
+	{USB_DEVICE(LINE6_VENDOR_ID, LINE6_DEVID_PODHD300)},
+	{USB_DEVICE(LINE6_VENDOR_ID, LINE6_DEVID_PODHD500)},
 	{USB_DEVICE(LINE6_VENDOR_ID, LINE6_DEVID_PODSTUDIO_GX)},
 	{USB_DEVICE(LINE6_VENDOR_ID, LINE6_DEVID_PODSTUDIO_UX1)},
 	{USB_DEVICE(LINE6_VENDOR_ID, LINE6_DEVID_PODSTUDIO_UX2)},
@@ -56,23 +59,25 @@
 
 /* *INDENT-OFF* */
 static struct line6_properties line6_properties_table[] = {
-	{ "BassPODxt",     "BassPODxt",        LINE6_BIT_BASSPODXT,     LINE6_BIT_CONTROL_PCM_HWMON },
-	{ "BassPODxtLive", "BassPODxt Live",   LINE6_BIT_BASSPODXTLIVE, LINE6_BIT_CONTROL_PCM_HWMON },
-	{ "BassPODxtPro",  "BassPODxt Pro",    LINE6_BIT_BASSPODXTPRO,  LINE6_BIT_CONTROL_PCM_HWMON },
-	{ "GuitarPort",    "GuitarPort",       LINE6_BIT_GUITARPORT,    LINE6_BIT_PCM               },
-	{ "PocketPOD",     "Pocket POD",       LINE6_BIT_POCKETPOD,     LINE6_BIT_CONTROL           },
-	{ "PODStudioGX",   "POD Studio GX",    LINE6_BIT_PODSTUDIO_GX,  LINE6_BIT_PCM               },
-	{ "PODStudioUX1",  "POD Studio UX1",   LINE6_BIT_PODSTUDIO_UX1, LINE6_BIT_PCM               },
-	{ "PODStudioUX2",  "POD Studio UX2",   LINE6_BIT_PODSTUDIO_UX2, LINE6_BIT_PCM               },
-	{ "PODX3",         "POD X3",           LINE6_BIT_PODX3,         LINE6_BIT_PCM               },
-	{ "PODX3Live",     "POD X3 Live",      LINE6_BIT_PODX3LIVE,     LINE6_BIT_PCM               },
-	{ "PODxt",         "PODxt",            LINE6_BIT_PODXT,         LINE6_BIT_CONTROL_PCM_HWMON },
-	{ "PODxtLive",     "PODxt Live",       LINE6_BIT_PODXTLIVE,     LINE6_BIT_CONTROL_PCM_HWMON },
-	{ "PODxtPro",      "PODxt Pro",        LINE6_BIT_PODXTPRO,      LINE6_BIT_CONTROL_PCM_HWMON },
-	{ "TonePortGX",    "TonePort GX",      LINE6_BIT_TONEPORT_GX,   LINE6_BIT_PCM               },
-	{ "TonePortUX1",   "TonePort UX1",     LINE6_BIT_TONEPORT_UX1,  LINE6_BIT_PCM               },
-	{ "TonePortUX2",   "TonePort UX2",     LINE6_BIT_TONEPORT_UX2,  LINE6_BIT_PCM               },
-	{ "Variax",        "Variax Workbench", LINE6_BIT_VARIAX,        LINE6_BIT_CONTROL           }
+	{ LINE6_BIT_BASSPODXT,     "BassPODxt",     "BassPODxt",        LINE6_BIT_CONTROL_PCM_HWMON },
+	{ LINE6_BIT_BASSPODXTLIVE, "BassPODxtLive", "BassPODxt Live",   LINE6_BIT_CONTROL_PCM_HWMON },
+	{ LINE6_BIT_BASSPODXTPRO,  "BassPODxtPro",  "BassPODxt Pro",    LINE6_BIT_CONTROL_PCM_HWMON },
+	{ LINE6_BIT_GUITARPORT,    "GuitarPort",    "GuitarPort",       LINE6_BIT_PCM               },
+	{ LINE6_BIT_POCKETPOD,     "PocketPOD",     "Pocket POD",       LINE6_BIT_CONTROL           },
+	{ LINE6_BIT_PODHD300,      "PODHD300",      "POD HD300",        LINE6_BIT_CONTROL_PCM_HWMON },
+	{ LINE6_BIT_PODHD500,      "PODHD500",      "POD HD500",        LINE6_BIT_CONTROL_PCM_HWMON },
+	{ LINE6_BIT_PODSTUDIO_GX,  "PODStudioGX",   "POD Studio GX",    LINE6_BIT_PCM               },
+	{ LINE6_BIT_PODSTUDIO_UX1, "PODStudioUX1",  "POD Studio UX1",   LINE6_BIT_PCM               },
+	{ LINE6_BIT_PODSTUDIO_UX2, "PODStudioUX2",  "POD Studio UX2",   LINE6_BIT_PCM               },
+	{ LINE6_BIT_PODX3,         "PODX3",         "POD X3",           LINE6_BIT_PCM               },
+	{ LINE6_BIT_PODX3LIVE,     "PODX3Live",     "POD X3 Live",      LINE6_BIT_PCM               },
+	{ LINE6_BIT_PODXT,         "PODxt",         "PODxt",            LINE6_BIT_CONTROL_PCM_HWMON },
+	{ LINE6_BIT_PODXTLIVE,     "PODxtLive",     "PODxt Live",       LINE6_BIT_CONTROL_PCM_HWMON },
+	{ LINE6_BIT_PODXTPRO,      "PODxtPro",      "PODxt Pro",        LINE6_BIT_CONTROL_PCM_HWMON },
+	{ LINE6_BIT_TONEPORT_GX,   "TonePortGX",    "TonePort GX",      LINE6_BIT_PCM               },
+	{ LINE6_BIT_TONEPORT_UX1,  "TonePortUX1",   "TonePort UX1",     LINE6_BIT_PCM               },
+	{ LINE6_BIT_TONEPORT_UX2,  "TonePortUX2",   "TonePort UX2",     LINE6_BIT_PCM               },
+	{ LINE6_BIT_VARIAX,        "Variax",        "Variax Workbench", LINE6_BIT_CONTROL           },
 };
 /* *INDENT-ON* */
 
@@ -437,6 +442,10 @@
 						  line6);
 			break;
 
+		case LINE6_DEVID_PODHD300:
+		case LINE6_DEVID_PODHD500:
+			break; /* let userspace handle MIDI */
+
 		case LINE6_DEVID_PODXTLIVE:
 			switch (line6->interface_number) {
 			case PODXTLIVE_INTERFACE_POD:
@@ -720,8 +729,8 @@
 		       const struct usb_device_id *id)
 {
 	int devtype;
-	struct usb_device *usbdev = NULL;
-	struct usb_line6 *line6 = NULL;
+	struct usb_device *usbdev;
+	struct usb_line6 *line6;
 	const struct line6_properties *properties;
 	int devnum;
 	int interface_number, alternate = 0;
@@ -794,6 +803,7 @@
 		}
 		break;
 
+	case LINE6_DEVID_PODHD500:
 	case LINE6_DEVID_PODX3:
 	case LINE6_DEVID_PODX3LIVE:
 		switch (interface_number) {
@@ -812,6 +822,7 @@
 	case LINE6_DEVID_BASSPODXTPRO:
 	case LINE6_DEVID_PODXT:
 	case LINE6_DEVID_PODXTPRO:
+	case LINE6_DEVID_PODHD300:
 		alternate = 5;
 		break;
 
@@ -865,6 +876,18 @@
 		ep_write = 0x03;
 		break;
 
+	case LINE6_DEVID_PODHD300:
+		size = sizeof(struct usb_line6_podhd);
+		ep_read = 0x84;
+		ep_write = 0x03;
+		break;
+
+	case LINE6_DEVID_PODHD500:
+		size = sizeof(struct usb_line6_podhd);
+		ep_read = 0x81;
+		ep_write = 0x01;
+		break;
+
 	case LINE6_DEVID_POCKETPOD:
 		size = sizeof(struct usb_line6_pod);
 		ep_read = 0x82;
@@ -923,7 +946,7 @@
 	}
 
 	if (size == 0) {
-		dev_err(line6->ifcdev,
+		dev_err(&interface->dev,
 			"driver bug: interface data size not set\n");
 		ret = -ENODEV;
 		goto err_put;
@@ -1017,6 +1040,12 @@
 		ret = line6_pod_init(interface, (struct usb_line6_pod *)line6);
 		break;
 
+	case LINE6_DEVID_PODHD300:
+	case LINE6_DEVID_PODHD500:
+		ret = line6_podhd_init(interface,
+				       (struct usb_line6_podhd *)line6);
+		break;
+
 	case LINE6_DEVID_PODXTLIVE:
 		switch (interface_number) {
 		case PODXTLIVE_INTERFACE_POD:
@@ -1139,6 +1168,11 @@
 			line6_pod_disconnect(interface);
 			break;
 
+		case LINE6_DEVID_PODHD300:
+		case LINE6_DEVID_PODHD500:
+			line6_podhd_disconnect(interface);
+			break;
+
 		case LINE6_DEVID_PODXTLIVE:
 			switch (interface_number) {
 			case PODXTLIVE_INTERFACE_POD:
diff --git a/drivers/staging/line6/driver.h b/drivers/staging/line6/driver.h
index 553192f..117bf99 100644
--- a/drivers/staging/line6/driver.h
+++ b/drivers/staging/line6/driver.h
@@ -88,6 +88,11 @@
 */
 struct line6_properties {
 	/**
+		 Bit identifying this device in the line6usb driver.
+	*/
+	int device_bit;
+
+	/**
 		 Card id string (maximum 16 characters).
 		 This can be used to address the device in ALSA programs as
 		 "default:CARD=<id>"
@@ -100,11 +105,6 @@
 	const char *name;
 
 	/**
-		 Bit identifying this device in the line6usb driver.
-	*/
-	int device_bit;
-
-	/**
 		 Bit vector defining this device's capabilities in the
 		 line6usb driver.
 	*/
diff --git a/drivers/staging/line6/midi.c b/drivers/staging/line6/midi.c
index e554a2d..13d0293 100644
--- a/drivers/staging/line6/midi.c
+++ b/drivers/staging/line6/midi.c
@@ -135,7 +135,7 @@
 	line6_write_hexdump(line6, 'S', data, length);
 #endif
 
-	transfer_buffer = kmalloc(length, GFP_ATOMIC);
+	transfer_buffer = kmemdup(data, length, GFP_ATOMIC);
 
 	if (transfer_buffer == NULL) {
 		usb_free_urb(urb);
@@ -143,7 +143,6 @@
 		return -ENOMEM;
 	}
 
-	memcpy(transfer_buffer, data, length);
 	usb_fill_int_urb(urb, line6->usbdev,
 			 usb_sndbulkpipe(line6->usbdev,
 					 line6->ep_control_write),
@@ -173,6 +172,8 @@
 		break;
 
 	case LINE6_DEVID_VARIAX:
+	case LINE6_DEVID_PODHD300:
+	case LINE6_DEVID_PODHD500:
 		break;
 
 	default:
@@ -307,10 +308,10 @@
 {
 	struct usb_interface *interface = to_usb_interface(dev);
 	struct usb_line6 *line6 = usb_get_intfdata(interface);
-	unsigned long value;
+	unsigned short value;
 	int ret;
 
-	ret = strict_strtoul(buf, 10, &value);
+	ret = kstrtou16(buf, 10, &value);
 	if (ret)
 		return ret;
 
@@ -339,10 +340,10 @@
 {
 	struct usb_interface *interface = to_usb_interface(dev);
 	struct usb_line6 *line6 = usb_get_intfdata(interface);
-	unsigned long value;
+	unsigned short value;
 	int ret;
 
-	ret = strict_strtoul(buf, 10, &value);
+	ret = kstrtou16(buf, 10, &value);
 	if (ret)
 		return ret;
 
@@ -391,16 +392,32 @@
 		return -ENOMEM;
 
 	err = line6_midibuf_init(&line6midi->midibuf_in, MIDI_BUFFER_SIZE, 0);
-	if (err < 0)
+	if (err < 0) {
+		kfree(line6midi);
 		return err;
+	}
 
 	err = line6_midibuf_init(&line6midi->midibuf_out, MIDI_BUFFER_SIZE, 1);
-	if (err < 0)
+	if (err < 0) {
+		kfree(line6midi->midibuf_in.buf);
+		kfree(line6midi);
 		return err;
+	}
 
 	line6midi->line6 = line6;
-	line6midi->midi_mask_transmit = 1;
-	line6midi->midi_mask_receive = 4;
+
+	switch(line6->product) {
+	case LINE6_DEVID_PODHD300:
+	case LINE6_DEVID_PODHD500:
+		line6midi->midi_mask_transmit = 1;
+		line6midi->midi_mask_receive = 1;
+		break;
+
+	default:
+		line6midi->midi_mask_transmit = 1;
+		line6midi->midi_mask_receive = 4;
+	}
+
 	line6->line6midi = line6midi;
 
 	err = snd_device_new(line6->card, SNDRV_DEV_RAWMIDI, line6midi,
diff --git a/drivers/staging/line6/midi.h b/drivers/staging/line6/midi.h
index b73a025..4a9e9f9 100644
--- a/drivers/staging/line6/midi.h
+++ b/drivers/staging/line6/midi.h
@@ -57,12 +57,12 @@
 	/**
 		 Bit mask for output MIDI channels.
 	*/
-	int midi_mask_transmit;
+	unsigned short midi_mask_transmit;
 
 	/**
 		 Bit mask for input MIDI channels.
 	*/
-	int midi_mask_receive;
+	unsigned short midi_mask_receive;
 
 	/**
 		 Buffer for incoming MIDI stream.
diff --git a/drivers/staging/line6/pcm.c b/drivers/staging/line6/pcm.c
index 9d4c8a6..37675e6 100644
--- a/drivers/staging/line6/pcm.c
+++ b/drivers/staging/line6/pcm.c
@@ -86,31 +86,22 @@
 
 #endif
 
+static bool test_flags(unsigned long flags0, unsigned long flags1,
+		       unsigned long mask)
+{
+	return ((flags0 & mask) == 0) && ((flags1 & mask) != 0);
+}
+
 int line6_pcm_start(struct snd_line6_pcm *line6pcm, int channels)
 {
 	unsigned long flags_old =
 	    __sync_fetch_and_or(&line6pcm->flags, channels);
 	unsigned long flags_new = flags_old | channels;
 	int err = 0;
-
-#if LINE6_BACKUP_MONITOR_SIGNAL
-	if (!(line6pcm->line6->properties->capabilities & LINE6_BIT_HWMON)) {
-		line6pcm->prev_fbuf =
-		    kmalloc(LINE6_ISO_PACKETS * line6pcm->max_packet_size,
-			    GFP_KERNEL);
-
-		if (!line6pcm->prev_fbuf) {
-			dev_err(line6pcm->line6->ifcdev,
-				"cannot malloc monitor buffer\n");
-			return -ENOMEM;
-		}
-	}
-#else
+	
 	line6pcm->prev_fbuf = NULL;
-#endif
 
-	if (((flags_old & MASK_CAPTURE) == 0) &&
-	    ((flags_new & MASK_CAPTURE) != 0)) {
+	if (test_flags(flags_old, flags_new, MASK_CAPTURE)) {
 		/*
 		   Waiting for completion of active URBs in the stop handler is
 		   a bug, we therefore report an error if capturing is restarted
@@ -119,54 +110,47 @@
 		if (line6pcm->active_urb_in | line6pcm->unlink_urb_in)
 			return -EBUSY;
 
-		line6pcm->buffer_in =
-		    kmalloc(LINE6_ISO_BUFFERS * LINE6_ISO_PACKETS *
-			    line6pcm->max_packet_size, GFP_KERNEL);
+		if (!(flags_new & MASK_PCM_ALSA_CAPTURE)) {
+			err = line6_alloc_capture_buffer(line6pcm);
 
-		if (!line6pcm->buffer_in) {
-			dev_err(line6pcm->line6->ifcdev,
-				"cannot malloc capture buffer\n");
-			return -ENOMEM;
+			if (err < 0)
+				goto pcm_start_error;
 		}
 
 		line6pcm->count_in = 0;
 		line6pcm->prev_fsize = 0;
 		err = line6_submit_audio_in_all_urbs(line6pcm);
 
-		if (err < 0) {
-			__sync_fetch_and_and(&line6pcm->flags, ~channels);
-			return err;
-		}
+		if (err < 0)
+			goto pcm_start_error;
 	}
 
-	if (((flags_old & MASK_PLAYBACK) == 0) &&
-	    ((flags_new & MASK_PLAYBACK) != 0)) {
+	if (test_flags(flags_old, flags_new, MASK_PLAYBACK)) {
 		/*
 		   See comment above regarding PCM restart.
 		 */
 		if (line6pcm->active_urb_out | line6pcm->unlink_urb_out)
 			return -EBUSY;
 
-		line6pcm->buffer_out =
-		    kmalloc(LINE6_ISO_BUFFERS * LINE6_ISO_PACKETS *
-			    line6pcm->max_packet_size, GFP_KERNEL);
+		if (!(flags_new & MASK_PCM_ALSA_PLAYBACK)) {
+			err = line6_alloc_playback_buffer(line6pcm);
 
-		if (!line6pcm->buffer_out) {
-			dev_err(line6pcm->line6->ifcdev,
-				"cannot malloc playback buffer\n");
-			return -ENOMEM;
+			if (err < 0)
+				goto pcm_start_error;
 		}
 
 		line6pcm->count_out = 0;
 		err = line6_submit_audio_out_all_urbs(line6pcm);
 
-		if (err < 0) {
-			__sync_fetch_and_and(&line6pcm->flags, ~channels);
-			return err;
-		}
+		if (err < 0)
+			goto pcm_start_error;
 	}
 
 	return 0;
+
+pcm_start_error:
+	__sync_fetch_and_and(&line6pcm->flags, ~channels);
+	return err;
 }
 
 int line6_pcm_stop(struct snd_line6_pcm *line6pcm, int channels)
@@ -175,22 +159,19 @@
 	    __sync_fetch_and_and(&line6pcm->flags, ~channels);
 	unsigned long flags_new = flags_old & ~channels;
 
-	if (((flags_old & MASK_CAPTURE) != 0) &&
-	    ((flags_new & MASK_CAPTURE) == 0)) {
+	if (test_flags(flags_new, flags_old, MASK_CAPTURE)) {
 		line6_unlink_audio_in_urbs(line6pcm);
-		kfree(line6pcm->buffer_in);
-		line6pcm->buffer_in = NULL;
+
+		if (!(flags_old & MASK_PCM_ALSA_CAPTURE))
+			line6_free_capture_buffer(line6pcm);
 	}
 
-	if (((flags_old & MASK_PLAYBACK) != 0) &&
-	    ((flags_new & MASK_PLAYBACK) == 0)) {
+	if (test_flags(flags_new, flags_old, MASK_PLAYBACK)) {
 		line6_unlink_audio_out_urbs(line6pcm);
-		kfree(line6pcm->buffer_out);
-		line6pcm->buffer_out = NULL;
+
+		if (!(flags_old & MASK_PCM_ALSA_PLAYBACK))
+			line6_free_playback_buffer(line6pcm);
 	}
-#if LINE6_BACKUP_MONITOR_SIGNAL
-	kfree(line6pcm->prev_fbuf);
-#endif
 
 	return 0;
 }
@@ -403,10 +384,12 @@
 	case LINE6_DEVID_PODXT:
 	case LINE6_DEVID_PODXTLIVE:
 	case LINE6_DEVID_PODXTPRO:
+	case LINE6_DEVID_PODHD300:
 		ep_read = 0x82;
 		ep_write = 0x01;
 		break;
 
+	case LINE6_DEVID_PODHD500:
 	case LINE6_DEVID_PODX3:
 	case LINE6_DEVID_PODX3LIVE:
 		ep_read = 0x86;
@@ -451,9 +434,14 @@
 	line6pcm->line6 = line6;
 	line6pcm->ep_audio_read = ep_read;
 	line6pcm->ep_audio_write = ep_write;
-	line6pcm->max_packet_size = usb_maxpacket(line6->usbdev,
-						  usb_rcvintpipe(line6->usbdev,
-								 ep_read), 0);
+
+	/* Read and write buffers are sized identically, so choose minimum */
+	line6pcm->max_packet_size = min(
+			usb_maxpacket(line6->usbdev,
+				usb_rcvisocpipe(line6->usbdev, ep_read), 0),
+			usb_maxpacket(line6->usbdev,
+				usb_sndisocpipe(line6->usbdev, ep_write), 1));
+
 	line6pcm->properties = properties;
 	line6->line6pcm = line6pcm;
 
@@ -508,6 +496,23 @@
 {
 	struct snd_line6_pcm *line6pcm = snd_pcm_substream_chip(substream);
 
+	switch (substream->stream) {
+	case SNDRV_PCM_STREAM_PLAYBACK:
+		if ((line6pcm->flags & MASK_PLAYBACK) == 0)
+			line6_unlink_wait_clear_audio_out_urbs(line6pcm);
+
+		break;
+
+	case SNDRV_PCM_STREAM_CAPTURE:
+		if ((line6pcm->flags & MASK_CAPTURE) == 0)
+			line6_unlink_wait_clear_audio_in_urbs(line6pcm);
+
+		break;
+
+	default:
+		MISSING_CASE;
+	}
+
 	if (!test_and_set_bit(BIT_PREPARED, &line6pcm->flags)) {
 		line6pcm->count_out = 0;
 		line6pcm->pos_out = 0;
diff --git a/drivers/staging/line6/pcm.h b/drivers/staging/line6/pcm.h
index 77055b3..55d8297 100644
--- a/drivers/staging/line6/pcm.h
+++ b/drivers/staging/line6/pcm.h
@@ -39,9 +39,6 @@
 #define LINE6_IMPULSE_DEFAULT_PERIOD 100
 #endif
 
-#define LINE6_BACKUP_MONITOR_SIGNAL 0
-#define LINE6_REUSE_DMA_AREA_FOR_PLAYBACK 0
-
 /*
 	Get substream from Line6 PCM data structure
 */
@@ -149,11 +146,6 @@
 	unsigned char *buffer_in;
 
 	/**
-		 Temporary buffer index for playback.
-	*/
-	int index_out;
-
-	/**
 		 Previously captured frame (for software monitoring).
 	*/
 	unsigned char *prev_fbuf;
diff --git a/drivers/staging/line6/playback.c b/drivers/staging/line6/playback.c
index 10c5438..4152db2 100644
--- a/drivers/staging/line6/playback.c
+++ b/drivers/staging/line6/playback.c
@@ -9,6 +9,7 @@
  *
  */
 
+#include <linux/slab.h>
 #include <sound/core.h>
 #include <sound/pcm.h>
 #include <sound/pcm_params.h>
@@ -191,13 +192,10 @@
 	urb_frames = urb_size / bytes_per_frame;
 	urb_out->transfer_buffer =
 	    line6pcm->buffer_out +
-	    line6pcm->max_packet_size * line6pcm->index_out;
+	    index * LINE6_ISO_PACKETS * line6pcm->max_packet_size;
 	urb_out->transfer_buffer_length = urb_size;
 	urb_out->context = line6pcm;
 
-	if (++line6pcm->index_out == LINE6_ISO_BUFFERS)
-		line6pcm->index_out = 0;
-
 	if (test_bit(BIT_PCM_ALSA_PLAYBACK, &line6pcm->flags) &&
 	    !test_bit(BIT_PAUSE_PLAYBACK, &line6pcm->flags)) {
 		struct snd_pcm_runtime *runtime =
@@ -222,18 +220,10 @@
 			} else
 				dev_err(line6pcm->line6->ifcdev, "driver bug: len = %d\n", len);	/* this is somewhat paranoid */
 		} else {
-#if LINE6_REUSE_DMA_AREA_FOR_PLAYBACK
-			/* set the buffer pointer */
-			urb_out->transfer_buffer =
-			    runtime->dma_area +
-			    line6pcm->pos_out * bytes_per_frame;
-#else
-			/* copy data */
 			memcpy(urb_out->transfer_buffer,
 			       runtime->dma_area +
 			       line6pcm->pos_out * bytes_per_frame,
 			       urb_out->transfer_buffer_length);
-#endif
 		}
 
 		line6pcm->pos_out += urb_frames;
@@ -361,6 +351,31 @@
 	wait_clear_audio_out_urbs(line6pcm);
 }
 
+int line6_alloc_playback_buffer(struct snd_line6_pcm *line6pcm)
+{
+	/* We may be invoked multiple times in a row so allocate once only */
+	if (line6pcm->buffer_out)
+		return 0;
+
+	line6pcm->buffer_out =
+		kmalloc(LINE6_ISO_BUFFERS * LINE6_ISO_PACKETS *
+			line6pcm->max_packet_size, GFP_KERNEL);
+
+	if (!line6pcm->buffer_out) {
+		dev_err(line6pcm->line6->ifcdev,
+			"cannot malloc playback buffer\n");
+		return -ENOMEM;
+	}
+
+	return 0;
+}
+
+void line6_free_playback_buffer(struct snd_line6_pcm *line6pcm)
+{
+	kfree(line6pcm->buffer_out);
+	line6pcm->buffer_out = NULL;
+}
+
 /*
 	Callback for completed playback URB.
 */
@@ -469,6 +484,13 @@
 	}
 	/* -- [FD] end */
 
+	if ((line6pcm->flags & MASK_PLAYBACK) == 0) {
+		ret = line6_alloc_playback_buffer(line6pcm);
+
+		if (ret < 0)
+			return ret;
+	}
+
 	ret = snd_pcm_lib_malloc_pages(substream,
 				       params_buffer_bytes(hw_params));
 	if (ret < 0)
@@ -481,6 +503,13 @@
 /* hw_free playback callback */
 static int snd_line6_playback_hw_free(struct snd_pcm_substream *substream)
 {
+	struct snd_line6_pcm *line6pcm = snd_pcm_substream_chip(substream);
+
+	if ((line6pcm->flags & MASK_PLAYBACK) == 0) {
+		line6_unlink_wait_clear_audio_out_urbs(line6pcm);
+		line6_free_playback_buffer(line6pcm);
+	}
+
 	return snd_pcm_lib_free_pages(substream);
 }
 
diff --git a/drivers/staging/line6/playback.h b/drivers/staging/line6/playback.h
index f2fc8c0..02487ff 100644
--- a/drivers/staging/line6/playback.h
+++ b/drivers/staging/line6/playback.h
@@ -29,7 +29,9 @@
 
 extern struct snd_pcm_ops snd_line6_playback_ops;
 
+extern int line6_alloc_playback_buffer(struct snd_line6_pcm *line6pcm);
 extern int line6_create_audio_out_urbs(struct snd_line6_pcm *line6pcm);
+extern void line6_free_playback_buffer(struct snd_line6_pcm *line6pcm);
 extern int line6_submit_audio_out_all_urbs(struct snd_line6_pcm *line6pcm);
 extern void line6_unlink_audio_out_urbs(struct snd_line6_pcm *line6pcm);
 extern void line6_unlink_wait_clear_audio_out_urbs(struct snd_line6_pcm
diff --git a/drivers/staging/line6/pod.c b/drivers/staging/line6/pod.c
index d9b3021..4dadc57 100644
--- a/drivers/staging/line6/pod.c
+++ b/drivers/staging/line6/pod.c
@@ -1149,14 +1149,10 @@
 static void pod_destruct(struct usb_interface *interface)
 {
 	struct usb_line6_pod *pod = usb_get_intfdata(interface);
-	struct usb_line6 *line6;
 
 	if (pod == NULL)
 		return;
-	line6 = &pod->line6;
-	if (line6 == NULL)
-		return;
-	line6_cleanup_audio(line6);
+	line6_cleanup_audio(&pod->line6);
 
 	del_timer(&pod->startup_timer);
 	cancel_work_sync(&pod->startup_work);
diff --git a/drivers/staging/line6/podhd.c b/drivers/staging/line6/podhd.c
new file mode 100644
index 0000000..7ef4543
--- /dev/null
+++ b/drivers/staging/line6/podhd.c
@@ -0,0 +1,154 @@
+/*
+ * Line6 Pod HD
+ *
+ * Copyright (C) 2011 Stefan Hajnoczi <stefanha@gmail.com>
+ *
+ *	This program is free software; you can redistribute it and/or
+ *	modify it under the terms of the GNU General Public License as
+ *	published by the Free Software Foundation, version 2.
+ *
+ */
+
+#include <sound/core.h>
+#include <sound/pcm.h>
+
+#include "audio.h"
+#include "driver.h"
+#include "pcm.h"
+#include "podhd.h"
+
+#define PODHD_BYTES_PER_FRAME 6	/* 24bit audio (stereo) */
+
+static struct snd_ratden podhd_ratden = {
+	.num_min = 48000,
+	.num_max = 48000,
+	.num_step = 1,
+	.den = 1,
+};
+
+static struct line6_pcm_properties podhd_pcm_properties = {
+	.snd_line6_playback_hw = {
+				  .info = (SNDRV_PCM_INFO_MMAP |
+					   SNDRV_PCM_INFO_INTERLEAVED |
+					   SNDRV_PCM_INFO_BLOCK_TRANSFER |
+					   SNDRV_PCM_INFO_MMAP_VALID |
+					   SNDRV_PCM_INFO_PAUSE |
+#ifdef CONFIG_PM
+					   SNDRV_PCM_INFO_RESUME |
+#endif
+					   SNDRV_PCM_INFO_SYNC_START),
+				  .formats = SNDRV_PCM_FMTBIT_S24_3LE,
+				  .rates = SNDRV_PCM_RATE_48000,
+				  .rate_min = 48000,
+				  .rate_max = 48000,
+				  .channels_min = 2,
+				  .channels_max = 2,
+				  .buffer_bytes_max = 60000,
+				  .period_bytes_min = 64,
+				  .period_bytes_max = 8192,
+				  .periods_min = 1,
+				  .periods_max = 1024},
+	.snd_line6_capture_hw = {
+				 .info = (SNDRV_PCM_INFO_MMAP |
+					  SNDRV_PCM_INFO_INTERLEAVED |
+					  SNDRV_PCM_INFO_BLOCK_TRANSFER |
+					  SNDRV_PCM_INFO_MMAP_VALID |
+#ifdef CONFIG_PM
+					  SNDRV_PCM_INFO_RESUME |
+#endif
+					  SNDRV_PCM_INFO_SYNC_START),
+				 .formats = SNDRV_PCM_FMTBIT_S24_3LE,
+				 .rates = SNDRV_PCM_RATE_48000,
+				 .rate_min = 48000,
+				 .rate_max = 48000,
+				 .channels_min = 2,
+				 .channels_max = 2,
+				 .buffer_bytes_max = 60000,
+				 .period_bytes_min = 64,
+				 .period_bytes_max = 8192,
+				 .periods_min = 1,
+				 .periods_max = 1024},
+	.snd_line6_rates = {
+			    .nrats = 1,
+			    .rats = &podhd_ratden},
+	.bytes_per_frame = PODHD_BYTES_PER_FRAME
+};
+
+/*
+	POD HD destructor.
+*/
+static void podhd_destruct(struct usb_interface *interface)
+{
+	struct usb_line6_podhd *podhd = usb_get_intfdata(interface);
+
+	if (podhd == NULL)
+		return;
+	line6_cleanup_audio(&podhd->line6);
+}
+
+/*
+	Try to init POD HD device.
+*/
+static int podhd_try_init(struct usb_interface *interface,
+			  struct usb_line6_podhd *podhd)
+{
+	int err;
+	struct usb_line6 *line6 = &podhd->line6;
+
+	if ((interface == NULL) || (podhd == NULL))
+		return -ENODEV;
+
+	/* initialize audio system: */
+	err = line6_init_audio(line6);
+	if (err < 0)
+		return err;
+
+	/* initialize MIDI subsystem: */
+	err = line6_init_midi(line6);
+	if (err < 0)
+		return err;
+
+	/* initialize PCM subsystem: */
+	err = line6_init_pcm(line6, &podhd_pcm_properties);
+	if (err < 0)
+		return err;
+
+	/* register USB audio system: */
+	err = line6_register_audio(line6);
+	return err;
+}
+
+/*
+	Init POD HD device (and clean up in case of failure).
+*/
+int line6_podhd_init(struct usb_interface *interface,
+		     struct usb_line6_podhd *podhd)
+{
+	int err = podhd_try_init(interface, podhd);
+
+	if (err < 0)
+		podhd_destruct(interface);
+
+	return err;
+}
+
+/*
+	POD HD device disconnected.
+*/
+void line6_podhd_disconnect(struct usb_interface *interface)
+{
+	struct usb_line6_podhd *podhd;
+
+	if (interface == NULL)
+		return;
+	podhd = usb_get_intfdata(interface);
+
+	if (podhd != NULL) {
+		struct snd_line6_pcm *line6pcm = podhd->line6.line6pcm;
+
+		if (line6pcm != NULL)
+			line6_pcm_disconnect(line6pcm);
+	}
+
+	podhd_destruct(interface);
+}
diff --git a/drivers/staging/line6/podhd.h b/drivers/staging/line6/podhd.h
new file mode 100644
index 0000000..652f740
--- /dev/null
+++ b/drivers/staging/line6/podhd.h
@@ -0,0 +1,30 @@
+/*
+ * Line6 Pod HD
+ *
+ * Copyright (C) 2011 Stefan Hajnoczi <stefanha@gmail.com>
+ *
+ *	This program is free software; you can redistribute it and/or
+ *	modify it under the terms of the GNU General Public License as
+ *	published by the Free Software Foundation, version 2.
+ *
+ */
+
+#ifndef PODHD_H
+#define PODHD_H
+
+#include <linux/usb.h>
+
+#include "driver.h"
+
+struct usb_line6_podhd {
+	/**
+		Generic Line6 USB data.
+	*/
+	struct usb_line6 line6;
+};
+
+extern void line6_podhd_disconnect(struct usb_interface *interface);
+extern int line6_podhd_init(struct usb_interface *interface,
+			    struct usb_line6_podhd *podhd);
+
+#endif /* PODHD_H */
diff --git a/drivers/staging/line6/revision.h b/drivers/staging/line6/revision.h
index 350d0df..b4eee2b 100644
--- a/drivers/staging/line6/revision.h
+++ b/drivers/staging/line6/revision.h
@@ -1,4 +1,4 @@
 #ifndef DRIVER_REVISION
 /* current subversion revision */
-#define DRIVER_REVISION " (revision 690)"
+#define DRIVER_REVISION " (904)"
 #endif
diff --git a/drivers/staging/line6/toneport.c b/drivers/staging/line6/toneport.c
index 879e699..f310578 100644
--- a/drivers/staging/line6/toneport.c
+++ b/drivers/staging/line6/toneport.c
@@ -295,14 +295,10 @@
 static void toneport_destruct(struct usb_interface *interface)
 {
 	struct usb_line6_toneport *toneport = usb_get_intfdata(interface);
-	struct usb_line6 *line6;
 
 	if (toneport == NULL)
 		return;
-	line6 = &toneport->line6;
-	if (line6 == NULL)
-		return;
-	line6_cleanup_audio(line6);
+	line6_cleanup_audio(&toneport->line6);
 }
 
 /*
diff --git a/drivers/staging/line6/usbdefs.h b/drivers/staging/line6/usbdefs.h
index c6dffe6..aff9e5c 100644
--- a/drivers/staging/line6/usbdefs.h
+++ b/drivers/staging/line6/usbdefs.h
@@ -24,6 +24,8 @@
 #define LINE6_DEVID_BASSPODXTPRO  0x4252
 #define LINE6_DEVID_GUITARPORT    0x4750
 #define LINE6_DEVID_POCKETPOD     0x5051
+#define LINE6_DEVID_PODHD300      0x5057
+#define LINE6_DEVID_PODHD500      0x414D
 #define LINE6_DEVID_PODSTUDIO_GX  0x4153
 #define LINE6_DEVID_PODSTUDIO_UX1 0x4150
 #define LINE6_DEVID_PODSTUDIO_UX2 0x4151
@@ -37,48 +39,71 @@
 #define LINE6_DEVID_TONEPORT_UX2  0x4142
 #define LINE6_DEVID_VARIAX        0x534d
 
-#define LINE6_BIT_BASSPODXT       (1 <<  0)
-#define LINE6_BIT_BASSPODXTLIVE   (1 <<  1)
-#define LINE6_BIT_BASSPODXTPRO    (1 <<  2)
-#define LINE6_BIT_GUITARPORT      (1 <<  3)
-#define LINE6_BIT_POCKETPOD       (1 <<  4)
-#define LINE6_BIT_PODSTUDIO_GX    (1 <<  5)
-#define LINE6_BIT_PODSTUDIO_UX1   (1 <<  6)
-#define LINE6_BIT_PODSTUDIO_UX2   (1 <<  7)
-#define LINE6_BIT_PODX3           (1 <<  8)
-#define LINE6_BIT_PODX3LIVE       (1 <<  9)
-#define LINE6_BIT_PODXT           (1 << 10)
-#define LINE6_BIT_PODXTLIVE       (1 << 11)
-#define LINE6_BIT_PODXTPRO        (1 << 12)
-#define LINE6_BIT_TONEPORT_GX     (1 << 13)
-#define LINE6_BIT_TONEPORT_UX1    (1 << 14)
-#define LINE6_BIT_TONEPORT_UX2    (1 << 15)
-#define LINE6_BIT_VARIAX          (1 << 16)
+enum {
+	LINE6_ID_BASSPODXT,
+	LINE6_ID_BASSPODXTLIVE,
+	LINE6_ID_BASSPODXTPRO,
+	LINE6_ID_GUITARPORT,
+	LINE6_ID_POCKETPOD,
+	LINE6_ID_PODHD300,
+	LINE6_ID_PODHD500,
+	LINE6_ID_PODSTUDIO_GX,
+	LINE6_ID_PODSTUDIO_UX1,
+	LINE6_ID_PODSTUDIO_UX2,
+	LINE6_ID_PODX3,
+	LINE6_ID_PODX3LIVE,
+	LINE6_ID_PODXT,
+	LINE6_ID_PODXTLIVE,
+	LINE6_ID_PODXTPRO,
+	LINE6_ID_TONEPORT_GX,
+	LINE6_ID_TONEPORT_UX1,
+	LINE6_ID_TONEPORT_UX2,
+	LINE6_ID_VARIAX
+};
 
-#define LINE6_BITS_PRO		(LINE6_BIT_BASSPODXTPRO | \
-				 LINE6_BIT_PODXTPRO)
-#define LINE6_BITS_LIVE		(LINE6_BIT_BASSPODXTLIVE | \
-				 LINE6_BIT_PODXTLIVE | \
-				 LINE6_BIT_PODX3LIVE)
-#define LINE6_BITS_PODXTALL	(LINE6_BIT_PODXT | \
-				 LINE6_BIT_PODXTLIVE | \
-				 LINE6_BIT_PODXTPRO)
-#define LINE6_BITS_BASSPODXTALL	(LINE6_BIT_BASSPODXT | \
-				 LINE6_BIT_BASSPODXTLIVE | \
-				 LINE6_BIT_BASSPODXTPRO)
+#define LINE6_BIT(x) LINE6_BIT_ ## x = 1 << LINE6_ID_ ## x
+
+enum {
+	LINE6_BIT(BASSPODXT),
+	LINE6_BIT(BASSPODXTLIVE),
+	LINE6_BIT(BASSPODXTPRO),
+	LINE6_BIT(GUITARPORT),
+	LINE6_BIT(POCKETPOD),
+	LINE6_BIT(PODHD300),
+	LINE6_BIT(PODHD500),
+	LINE6_BIT(PODSTUDIO_GX),
+	LINE6_BIT(PODSTUDIO_UX1),
+	LINE6_BIT(PODSTUDIO_UX2),
+	LINE6_BIT(PODX3),
+	LINE6_BIT(PODX3LIVE),
+	LINE6_BIT(PODXT),
+	LINE6_BIT(PODXTLIVE),
+	LINE6_BIT(PODXTPRO),
+	LINE6_BIT(TONEPORT_GX),
+	LINE6_BIT(TONEPORT_UX1),
+	LINE6_BIT(TONEPORT_UX2),
+	LINE6_BIT(VARIAX),
+
+	LINE6_BITS_PRO = LINE6_BIT_BASSPODXTPRO | LINE6_BIT_PODXTPRO,
+	LINE6_BITS_LIVE = LINE6_BIT_BASSPODXTLIVE | LINE6_BIT_PODXTLIVE | LINE6_BIT_PODX3LIVE,
+	LINE6_BITS_PODXTALL = LINE6_BIT_PODXT | LINE6_BIT_PODXTLIVE | LINE6_BIT_PODXTPRO,
+	LINE6_BITS_PODX3ALL = LINE6_BIT_PODX3 | LINE6_BIT_PODX3LIVE,
+	LINE6_BITS_PODHDALL = LINE6_BIT_PODHD300 | LINE6_BIT_PODHD500,
+	LINE6_BITS_BASSPODXTALL	= LINE6_BIT_BASSPODXT |	LINE6_BIT_BASSPODXTLIVE | LINE6_BIT_BASSPODXTPRO
+};
 
 /* device supports settings parameter via USB */
-#define LINE6_BIT_CONTROL	(1 << 0)
+#define LINE6_BIT_CONTROL (1 << 0)
 /* device supports PCM input/output via USB */
-#define LINE6_BIT_PCM		(1 << 1)
+#define LINE6_BIT_PCM (1 << 1)
 /* device support hardware monitoring */
-#define LINE6_BIT_HWMON		(1 << 2)
+#define LINE6_BIT_HWMON (1 << 2)
 
 #define LINE6_BIT_CONTROL_PCM_HWMON	(LINE6_BIT_CONTROL |	\
 					 LINE6_BIT_PCM |	\
 					 LINE6_BIT_HWMON)
 
-#define LINE6_FALLBACK_INTERVAL		10
-#define LINE6_FALLBACK_MAXPACKETSIZE	16
+#define LINE6_FALLBACK_INTERVAL 10
+#define LINE6_FALLBACK_MAXPACKETSIZE 16
 
 #endif
diff --git a/drivers/staging/line6/variax.c b/drivers/staging/line6/variax.c
index 81241cd..d366222 100644
--- a/drivers/staging/line6/variax.c
+++ b/drivers/staging/line6/variax.c
@@ -572,14 +572,10 @@
 static void variax_destruct(struct usb_interface *interface)
 {
 	struct usb_line6_variax *variax = usb_get_intfdata(interface);
-	struct usb_line6 *line6;
 
 	if (variax == NULL)
 		return;
-	line6 = &variax->line6;
-	if (line6 == NULL)
-		return;
-	line6_cleanup_audio(line6);
+	line6_cleanup_audio(&variax->line6);
 
 	del_timer(&variax->startup_timer1);
 	del_timer(&variax->startup_timer2);
diff --git a/drivers/staging/mei/init.c b/drivers/staging/mei/init.c
index 8bf3479..4ac3696 100644
--- a/drivers/staging/mei/init.c
+++ b/drivers/staging/mei/init.c
@@ -38,7 +38,6 @@
 {
 	/* initialize our queue list */
 	INIT_LIST_HEAD(&list->mei_cb.cb_list);
-	list->status = 0;
 }
 
 /**
@@ -49,22 +48,15 @@
  */
 void mei_io_list_flush(struct mei_io_list *list, struct mei_cl *cl)
 {
-	struct mei_cl_cb *cb_pos = NULL;
-	struct mei_cl_cb *cb_next = NULL;
+	struct mei_cl_cb *pos;
+	struct mei_cl_cb *next;
 
-	if (list->status != 0)
-		return;
-
-	if (list_empty(&list->mei_cb.cb_list))
-		return;
-
-	list_for_each_entry_safe(cb_pos, cb_next,
-				 &list->mei_cb.cb_list, cb_list) {
-		if (cb_pos) {
+	list_for_each_entry_safe(pos, next, &list->mei_cb.cb_list, cb_list) {
+		if (pos->file_private) {
 			struct mei_cl *cl_tmp;
-			cl_tmp = (struct mei_cl *)cb_pos->file_private;
+			cl_tmp = (struct mei_cl *)pos->file_private;
 			if (mei_cl_cmp_id(cl, cl_tmp))
-				list_del(&cb_pos->cb_list);
+				list_del(&pos->cb_list);
 		}
 	}
 }
@@ -338,16 +330,10 @@
 		}
 	}
 	/* remove all waiting requests */
-	if (dev->write_list.status == 0 &&
-		!list_empty(&dev->write_list.mei_cb.cb_list)) {
-		list_for_each_entry_safe(cb_pos, cb_next,
-				&dev->write_list.mei_cb.cb_list, cb_list) {
-			if (cb_pos) {
-				list_del(&cb_pos->cb_list);
-				mei_free_cb_private(cb_pos);
-				cb_pos = NULL;
-			}
-		}
+	list_for_each_entry_safe(cb_pos, cb_next,
+			&dev->write_list.mei_cb.cb_list, cb_list) {
+		list_del(&cb_pos->cb_list);
+		mei_free_cb_private(cb_pos);
 	}
 }
 
@@ -380,8 +366,7 @@
 	host_start_req->host_version.major_version = HBM_MAJOR_VERSION;
 	host_start_req->host_version.minor_version = HBM_MINOR_VERSION;
 	dev->recvd_msg = false;
-	if (!mei_write_message(dev, mei_hdr,
-				       (unsigned char *) (host_start_req),
+	if (!mei_write_message(dev, mei_hdr, (unsigned char *)host_start_req,
 				       mei_hdr->length)) {
 		dev_dbg(&dev->pdev->dev, "write send version message to FW fail.\n");
 		dev->mei_state = MEI_RESETING;
@@ -414,8 +399,7 @@
 	host_enum_req = (struct hbm_host_enum_request *) &dev->wr_msg_buf[1];
 	memset(host_enum_req, 0, sizeof(struct hbm_host_enum_request));
 	host_enum_req->cmd.cmd = HOST_ENUM_REQ_CMD;
-	if (!mei_write_message(dev, mei_hdr,
-			       (unsigned char *) (host_enum_req),
+	if (!mei_write_message(dev, mei_hdr, (unsigned char *)host_enum_req,
 				mei_hdr->length)) {
 		dev->mei_state = MEI_RESETING;
 		dev_dbg(&dev->pdev->dev, "write send enumeration request message to FW fail.\n");
@@ -605,15 +589,10 @@
 		return;
 	}
 
-	/* Do not render the system unusable when iamthif_mtu is not equal to
-	the value received from ME.
-	Assign iamthif_mtu to the value received from ME in order to solve the
-	hardware macro incompatibility. */
+	/* Assign iamthif_mtu to the value received from ME  */
 
-	dev_dbg(&dev->pdev->dev, "[DEFAULT] IAMTHIF = %d\n", dev->iamthif_mtu);
 	dev->iamthif_mtu = dev->me_clients[i].props.max_msg_length;
-	dev_dbg(&dev->pdev->dev,
-			"IAMTHIF = %d\n",
+	dev_dbg(&dev->pdev->dev, "IAMTHIF_MTU = %d\n",
 			dev->me_clients[i].props.max_msg_length);
 
 	kfree(dev->iamthif_msg_buf);
diff --git a/drivers/staging/mei/interface.c b/drivers/staging/mei/interface.c
index a65dacf..eb5df7f 100644
--- a/drivers/staging/mei/interface.c
+++ b/drivers/staging/mei/interface.c
@@ -128,9 +128,9 @@
  * returns 1 if success, 0 - otherwise.
  */
 int mei_write_message(struct mei_device *dev,
-			     struct mei_msg_hdr *header,
-			     unsigned char *write_buffer,
-			     unsigned long write_length)
+		      struct mei_msg_hdr *header,
+		      unsigned char *write_buffer,
+		      unsigned long write_length)
 {
 	u32 temp_msg = 0;
 	unsigned long bytes_written = 0;
@@ -216,7 +216,7 @@
  * @buffer_length: message size will be read
  */
 void mei_read_slots(struct mei_device *dev,
-		     unsigned char *buffer, unsigned long buffer_length)
+		    unsigned char *buffer, unsigned long buffer_length)
 {
 	u32 i = 0;
 	unsigned char temp_buf[sizeof(u32)];
diff --git a/drivers/staging/mei/interface.h b/drivers/staging/mei/interface.h
index 7bd38ae..aeae511 100644
--- a/drivers/staging/mei/interface.h
+++ b/drivers/staging/mei/interface.h
@@ -52,6 +52,17 @@
 int mei_wd_stop(struct mei_device *dev, bool preserve);
 bool mei_wd_host_init(struct mei_device *dev);
 void mei_wd_set_start_timeout(struct mei_device *dev, u16 timeout);
+/*
+ * mei_watchdog_register  - Registering watchdog interface
+ *   once we got connection to the WD Client
+ * @dev - mei device
+ */
+void mei_watchdog_register(struct mei_device *dev);
+/*
+ * mei_watchdog_unregister  - Uegistering watchdog interface
+ * @dev - mei device
+ */
+void mei_watchdog_unregister(struct mei_device *dev);
 
 int mei_flow_ctrl_reduce(struct mei_device *dev, struct mei_cl *cl);
 
diff --git a/drivers/staging/mei/interrupt.c b/drivers/staging/mei/interrupt.c
index 882d106..3544fee 100644
--- a/drivers/staging/mei/interrupt.c
+++ b/drivers/staging/mei/interrupt.c
@@ -198,8 +198,7 @@
 	unsigned char *buffer = NULL;
 
 	dev_dbg(&dev->pdev->dev, "start client msg\n");
-	if (!(dev->read_list.status == 0 &&
-	      !list_empty(&dev->read_list.mei_cb.cb_list)))
+	if (list_empty(&dev->read_list.mei_cb.cb_list))
 		goto quit;
 
 	list_for_each_entry_safe(cb_pos, cb_next,
@@ -210,9 +209,6 @@
 			buffer = (unsigned char *)
 				(cb_pos->response_buffer.data +
 				cb_pos->information);
-			BUG_ON(cb_pos->response_buffer.size <
-					mei_hdr->length +
-					cb_pos->information);
 
 			if (cb_pos->response_buffer.size <
 					mei_hdr->length + cb_pos->information) {
@@ -390,24 +386,10 @@
 	/* if WD or iamthif client treat specially */
 
 	if (is_treat_specially_client(&(dev->wd_cl), rs)) {
-		dev_dbg(&dev->pdev->dev, "dev->wd_timeout =%d.\n",
-				dev->wd_timeout);
-
-		dev->wd_due_counter = (dev->wd_timeout) ? 1 : 0;
-
 		dev_dbg(&dev->pdev->dev, "successfully connected to WD client.\n");
+		mei_watchdog_register(dev);
 
-		/* Registering watchdog interface device once we got connection
-		   to the WD Client
-		*/
-		if (watchdog_register_device(&amt_wd_dev)) {
-			printk(KERN_ERR "mei: unable to register watchdog device.\n");
-			dev->wd_interface_reg = false;
-		} else {
-			dev_dbg(&dev->pdev->dev, "successfully register watchdog interface.\n");
-			dev->wd_interface_reg = true;
-		}
-
+		/* next step in the state maching */
 		mei_host_init_iamthif(dev);
 		return;
 	}
@@ -416,22 +398,20 @@
 		dev->iamthif_state = MEI_IAMTHIF_IDLE;
 		return;
 	}
-	if (!dev->ctrl_rd_list.status &&
-	    !list_empty(&dev->ctrl_rd_list.mei_cb.cb_list)) {
-		list_for_each_entry_safe(cb_pos, cb_next,
-			&dev->ctrl_rd_list.mei_cb.cb_list, cb_list) {
-			cl = (struct mei_cl *)cb_pos->file_private;
-			if (!cl) {
+	list_for_each_entry_safe(cb_pos, cb_next,
+				&dev->ctrl_rd_list.mei_cb.cb_list, cb_list) {
+
+		cl = (struct mei_cl *)cb_pos->file_private;
+		if (!cl) {
+			list_del(&cb_pos->cb_list);
+			return;
+		}
+		if (MEI_IOCTL == cb_pos->major_file_operations) {
+			if (is_treat_specially_client(cl, rs)) {
 				list_del(&cb_pos->cb_list);
-				return;
-			}
-			if (MEI_IOCTL == cb_pos->major_file_operations) {
-				if (is_treat_specially_client(cl, rs)) {
-					list_del(&cb_pos->cb_list);
-					cl->status = 0;
-					cl->timer_count = 0;
-					break;
-				}
+				cl->status = 0;
+				cl->timer_count = 0;
+				break;
 			}
 		}
 	}
@@ -458,29 +438,26 @@
 			rs->host_addr,
 			rs->status);
 
-	if (!dev->ctrl_rd_list.status &&
-	    !list_empty(&dev->ctrl_rd_list.mei_cb.cb_list)) {
-		list_for_each_entry_safe(cb_pos, cb_next,
-				&dev->ctrl_rd_list.mei_cb.cb_list, cb_list) {
-			cl = (struct mei_cl *)cb_pos->file_private;
+	list_for_each_entry_safe(cb_pos, cb_next,
+			&dev->ctrl_rd_list.mei_cb.cb_list, cb_list) {
+		cl = (struct mei_cl *)cb_pos->file_private;
 
-			if (!cl) {
-				list_del(&cb_pos->cb_list);
-				return;
-			}
+		if (!cl) {
+			list_del(&cb_pos->cb_list);
+			return;
+		}
 
-			dev_dbg(&dev->pdev->dev, "list_for_each_entry_safe in ctrl_rd_list.\n");
-			if (cl->host_client_id == rs->host_addr &&
-			    cl->me_client_id == rs->me_addr) {
+		dev_dbg(&dev->pdev->dev, "list_for_each_entry_safe in ctrl_rd_list.\n");
+		if (cl->host_client_id == rs->host_addr &&
+		    cl->me_client_id == rs->me_addr) {
 
-				list_del(&cb_pos->cb_list);
-				if (!rs->status)
-					cl->state = MEI_FILE_DISCONNECTED;
+			list_del(&cb_pos->cb_list);
+			if (!rs->status)
+				cl->state = MEI_FILE_DISCONNECTED;
 
-				cl->status = 0;
-				cl->timer_count = 0;
-				break;
-			}
+			cl->status = 0;
+			cl->timer_count = 0;
+			break;
 		}
 	}
 }
@@ -718,7 +695,7 @@
 	case CLIENT_DISCONNECT_RES_CMD:
 		disconnect_res =
 			(struct hbm_client_connect_response *) mei_msg;
-		mei_client_disconnect_response(dev,	 disconnect_res);
+		mei_client_disconnect_response(dev, disconnect_res);
 		dev_dbg(&dev->pdev->dev, "client disconnect response message received.\n");
 		wake_up(&dev->wait_recvd_msg);
 		break;
@@ -736,7 +713,7 @@
 			mei_reset(dev, 1);
 			return;
 		}
-	       if (dev->me_clients[dev->me_client_presentation_num]
+		if (dev->me_clients[dev->me_client_presentation_num]
 					.client_id == props_res->address) {
 
 			dev->me_clients[dev->me_client_presentation_num].props
@@ -1228,7 +1205,7 @@
 {
 
 	struct mei_cl *cl;
-	struct mei_cl_cb *cb_pos = NULL, *cb_next = NULL;
+	struct mei_cl_cb *pos = NULL, *next = NULL;
 	struct mei_io_list *list;
 	int ret;
 
@@ -1241,36 +1218,31 @@
 	dev_dbg(&dev->pdev->dev, "complete all waiting for write cb.\n");
 
 	list = &dev->write_waiting_list;
-	if (!list->status && !list_empty(&list->mei_cb.cb_list)) {
-		list_for_each_entry_safe(cb_pos, cb_next,
-				&list->mei_cb.cb_list, cb_list) {
-			cl = (struct mei_cl *)cb_pos->file_private;
-			if (cl) {
-				cl->status = 0;
-				list_del(&cb_pos->cb_list);
-				if (MEI_WRITING == cl->writing_state &&
-				   (cb_pos->major_file_operations ==
-						MEI_WRITE) &&
-				   (cl != &dev->iamthif_cl)) {
-					dev_dbg(&dev->pdev->dev,
-						"MEI WRITE COMPLETE\n");
-					cl->writing_state =
-							MEI_WRITE_COMPLETE;
-					list_add_tail(&cb_pos->cb_list,
-						&cmpl_list->mei_cb.cb_list);
-				}
-				if (cl == &dev->iamthif_cl) {
-					dev_dbg(&dev->pdev->dev, "check iamthif flow control.\n");
-					if (dev->iamthif_flow_control_pending) {
-						ret =
-						_mei_irq_thread_iamthif_read(
-								dev, slots);
-						if (ret)
-							return ret;
-					}
-				}
-			}
+	list_for_each_entry_safe(pos, next,
+			&list->mei_cb.cb_list, cb_list) {
+		cl = (struct mei_cl *)pos->file_private;
+		if (cl == NULL)
+			continue;
 
+		cl->status = 0;
+		list_del(&pos->cb_list);
+		if (MEI_WRITING == cl->writing_state &&
+		   (pos->major_file_operations == MEI_WRITE) &&
+		   (cl != &dev->iamthif_cl)) {
+			dev_dbg(&dev->pdev->dev,
+				"MEI WRITE COMPLETE\n");
+			cl->writing_state = MEI_WRITE_COMPLETE;
+			list_add_tail(&pos->cb_list,
+				&cmpl_list->mei_cb.cb_list);
+		}
+		if (cl == &dev->iamthif_cl) {
+			dev_dbg(&dev->pdev->dev, "check iamthif flow control.\n");
+			if (dev->iamthif_flow_control_pending) {
+				ret = _mei_irq_thread_iamthif_read(
+						dev, slots);
+				if (ret)
+					return ret;
+			}
 		}
 	}
 
@@ -1317,101 +1289,88 @@
 		return ~ENODEV;
 
 	/* complete control write list CB */
-	if (!dev->ctrl_wr_list.status) {
-		/* complete control write list CB */
-		dev_dbg(&dev->pdev->dev, "complete control write list cb.\n");
-		list_for_each_entry_safe(cb_pos, cb_next,
+	dev_dbg(&dev->pdev->dev, "complete control write list cb.\n");
+	list_for_each_entry_safe(pos, next,
 				&dev->ctrl_wr_list.mei_cb.cb_list, cb_list) {
-			cl = (struct mei_cl *)
-				cb_pos->file_private;
-			if (!cl) {
-				list_del(&cb_pos->cb_list);
-				return -ENODEV;
-			}
-			switch (cb_pos->major_file_operations) {
-			case MEI_CLOSE:
-				/* send disconnect message */
-				ret = _mei_irq_thread_close(dev, slots,
-						     cb_pos, cl, cmpl_list);
-				if (ret)
-					return ret;
-
-				break;
-			case MEI_READ:
-				/* send flow control message */
-				ret = _mei_irq_thread_read(dev, slots,
-						    cb_pos, cl, cmpl_list);
-				if (ret)
-					return ret;
-
-				break;
-			case MEI_IOCTL:
-				/* connect message */
-				if (!mei_other_client_is_connecting(dev,
-						cl))
-					continue;
-				ret = _mei_irq_thread_ioctl(dev, slots,
-						     cb_pos, cl, cmpl_list);
-				if (ret)
-					return ret;
-
-				break;
-
-			default:
-				BUG();
-			}
-
+		cl = (struct mei_cl *) pos->file_private;
+		if (!cl) {
+			list_del(&pos->cb_list);
+			return -ENODEV;
 		}
+		switch (pos->major_file_operations) {
+		case MEI_CLOSE:
+			/* send disconnect message */
+			ret = _mei_irq_thread_close(dev, slots, pos, cl, cmpl_list);
+			if (ret)
+				return ret;
+
+			break;
+		case MEI_READ:
+			/* send flow control message */
+			ret = _mei_irq_thread_read(dev, slots, pos, cl, cmpl_list);
+			if (ret)
+				return ret;
+
+			break;
+		case MEI_IOCTL:
+			/* connect message */
+			if (mei_other_client_is_connecting(dev, cl))
+				continue;
+			ret = _mei_irq_thread_ioctl(dev, slots, pos, cl, cmpl_list);
+			if (ret)
+				return ret;
+
+			break;
+
+		default:
+			BUG();
+		}
+
 	}
 	/* complete  write list CB */
-	if (!dev->write_list.status &&
-	    !list_empty(&dev->write_list.mei_cb.cb_list)) {
-		dev_dbg(&dev->pdev->dev, "complete write list cb.\n");
-		list_for_each_entry_safe(cb_pos, cb_next,
-				&dev->write_list.mei_cb.cb_list, cb_list) {
-			cl = (struct mei_cl *)cb_pos->file_private;
+	dev_dbg(&dev->pdev->dev, "complete write list cb.\n");
+	list_for_each_entry_safe(pos, next,
+			&dev->write_list.mei_cb.cb_list, cb_list) {
+		cl = (struct mei_cl *)pos->file_private;
+		if (cl == NULL)
+			continue;
 
-			if (cl) {
-				if (cl != &dev->iamthif_cl) {
-					if (!mei_flow_ctrl_creds(dev,
-						cl)) {
-						dev_dbg(&dev->pdev->dev,
-							"No flow control"
-						    " credentials for client"
-						    " %d, not sending.\n",
-						    cl->host_client_id);
-						continue;
-					}
-					ret = _mei_irq_thread_cmpl(dev, slots,
-							    cb_pos,
-							    cl, cmpl_list);
-					if (ret)
-						return ret;
-
-				} else if (cl == &dev->iamthif_cl) {
-					/* IAMTHIF IOCTL */
-					dev_dbg(&dev->pdev->dev, "complete amthi write cb.\n");
-					if (!mei_flow_ctrl_creds(dev,
-							cl)) {
-						dev_dbg(&dev->pdev->dev,
-							"No flow control"
-						    " credentials for amthi"
-						    " client %d.\n",
-						    cl->host_client_id);
-						continue;
-					}
-					ret = _mei_irq_thread_cmpl_iamthif(dev,
-								slots,
-								cb_pos,
-								cl,
-								cmpl_list);
-					if (ret)
-						return ret;
-
-				}
+		if (cl != &dev->iamthif_cl) {
+			if (!mei_flow_ctrl_creds(dev, cl)) {
+				dev_dbg(&dev->pdev->dev,
+					"No flow control"
+				    " credentials for client"
+				    " %d, not sending.\n",
+				    cl->host_client_id);
+				continue;
 			}
+			ret = _mei_irq_thread_cmpl(dev, slots,
+					    pos,
+					    cl, cmpl_list);
+			if (ret)
+				return ret;
+
+		} else if (cl == &dev->iamthif_cl) {
+			/* IAMTHIF IOCTL */
+			dev_dbg(&dev->pdev->dev, "complete amthi write cb.\n");
+			if (!mei_flow_ctrl_creds(dev, cl)) {
+				dev_dbg(&dev->pdev->dev,
+					"No flow control"
+				    " credentials for amthi"
+				    " client %d.\n",
+				    cl->host_client_id);
+				continue;
+			}
+			ret = _mei_irq_thread_cmpl_iamthif(dev,
+						slots,
+						pos,
+						cl,
+						cmpl_list);
+			if (ret)
+				return ret;
 
 		}
+
 	}
 	return 0;
 }
@@ -1502,18 +1461,13 @@
 			amthi_complete_list = &dev->amthi_read_complete_list.
 					mei_cb.cb_list;
 
-			if (!list_empty(amthi_complete_list)) {
+			list_for_each_entry_safe(cb_pos, cb_next, amthi_complete_list, cb_list) {
 
-				list_for_each_entry_safe(cb_pos, cb_next,
-							amthi_complete_list,
-							cb_list) {
+				cl_pos = cb_pos->file_object->private_data;
 
-					cl_pos = cb_pos->file_object->private_data;
-
-					/* Finding the AMTHI entry. */
-					if (cl_pos ==	&dev->iamthif_cl)
-						list_del(&cb_pos->cb_list);
-				}
+				/* Finding the AMTHI entry. */
+				if (cl_pos == &dev->iamthif_cl)
+					list_del(&cb_pos->cb_list);
 			}
 			if (dev->iamthif_current_cb)
 				mei_free_cb_private(dev->iamthif_current_cb);
@@ -1527,8 +1481,8 @@
 		}
 	}
 out:
-	 schedule_delayed_work(&dev->timer_work, 2 * HZ);
-	 mutex_unlock(&dev->device_lock);
+	schedule_delayed_work(&dev->timer_work, 2 * HZ);
+	mutex_unlock(&dev->device_lock);
 }
 
 /**
@@ -1624,7 +1578,7 @@
 		wake_up_interruptible(&dev->wait_recvd_msg);
 		bus_message_received = false;
 	}
-	if (complete_list.status || list_empty(&complete_list.mei_cb.cb_list))
+	if (list_empty(&complete_list.mei_cb.cb_list))
 		return IRQ_HANDLED;
 
 
diff --git a/drivers/staging/mei/iorw.c b/drivers/staging/mei/iorw.c
index 8a61d12..0752ead 100644
--- a/drivers/staging/mei/iorw.c
+++ b/drivers/staging/mei/iorw.c
@@ -228,18 +228,15 @@
 		struct file *file)
 {
 	struct mei_cl *cl_temp;
-	struct mei_cl_cb *cb_pos = NULL;
-	struct mei_cl_cb *cb_next = NULL;
+	struct mei_cl_cb *pos = NULL;
+	struct mei_cl_cb *next = NULL;
 
-	if (!dev->amthi_read_complete_list.status &&
-	    !list_empty(&dev->amthi_read_complete_list.mei_cb.cb_list)) {
-		list_for_each_entry_safe(cb_pos, cb_next,
-		    &dev->amthi_read_complete_list.mei_cb.cb_list, cb_list) {
-			cl_temp = (struct mei_cl *)cb_pos->file_private;
-			if (cl_temp && cl_temp == &dev->iamthif_cl &&
-				cb_pos->file_object == file)
-				return cb_pos;
-		}
+	list_for_each_entry_safe(pos, next,
+	    &dev->amthi_read_complete_list.mei_cb.cb_list, cb_list) {
+		cl_temp = (struct mei_cl *)pos->file_private;
+		if (cl_temp && cl_temp == &dev->iamthif_cl &&
+			pos->file_object == file)
+			return pos;
 	}
 	return NULL;
 }
@@ -262,7 +259,7 @@
  *  negative on failure.
  */
 int amthi_read(struct mei_device *dev, struct file *file,
-	      char __user *ubuf, size_t length, loff_t *offset)
+	       char __user *ubuf, size_t length, loff_t *offset)
 {
 	int rets;
 	int wait_ret;
@@ -334,8 +331,7 @@
 		}
 	}
 	/* if the whole message will fit remove it from the list */
-	if (cb->information >= *offset &&
-	    length >= (cb->information - *offset))
+	if (cb->information >= *offset && length >= (cb->information - *offset))
 		list_del(&cb->cb_list);
 	else if (cb->information > 0 && cb->information <= *offset) {
 		/* end of the message has been reached */
@@ -356,9 +352,7 @@
 	 * the information may be longer */
 	length = min_t(size_t, length, (cb->information - *offset));
 
-	if (copy_to_user(ubuf,
-			 cb->response_buffer.data + *offset,
-			 length))
+	if (copy_to_user(ubuf, cb->response_buffer.data + *offset, length))
 		rets = -EFAULT;
 	else {
 		rets = length;
@@ -427,7 +421,7 @@
 
 	cb->response_buffer.size = dev->me_clients[i].props.max_msg_length;
 	cb->response_buffer.data =
-	    kmalloc(cb->response_buffer.size, GFP_KERNEL);
+			kmalloc(cb->response_buffer.size, GFP_KERNEL);
 	if (!cb->response_buffer.data) {
 		rets = -ENOMEM;
 		goto unlock;
@@ -448,8 +442,7 @@
 				      &dev->read_list.mei_cb.cb_list);
 		}
 	} else {
-		list_add_tail(&cb->cb_list,
-			      &dev->ctrl_wr_list.mei_cb.cb_list);
+		list_add_tail(&cb->cb_list, &dev->ctrl_wr_list.mei_cb.cb_list);
 	}
 	return rets;
 unlock:
@@ -482,7 +475,7 @@
 	dev->iamthif_ioctl = true;
 	dev->iamthif_msg_buf_size = cb->request_buffer.size;
 	memcpy(dev->iamthif_msg_buf, cb->request_buffer.data,
-	    cb->request_buffer.size);
+	       cb->request_buffer.size);
 
 	ret = mei_flow_ctrl_creds(dev, &dev->iamthif_cl);
 	if (ret < 0)
@@ -534,8 +527,7 @@
 
 		dev_dbg(&dev->pdev->dev, "No flow control credentials, "
 				"so add iamthif cb to write list.\n");
-		list_add_tail(&cb->cb_list,
-			      &dev->write_list.mei_cb.cb_list);
+		list_add_tail(&cb->cb_list, &dev->write_list.mei_cb.cb_list);
 	}
 	return 0;
 }
@@ -550,8 +542,8 @@
 void mei_run_next_iamthif_cmd(struct mei_device *dev)
 {
 	struct mei_cl *cl_tmp;
-	struct mei_cl_cb *cb_pos = NULL;
-	struct mei_cl_cb *cb_next = NULL;
+	struct mei_cl_cb *pos = NULL;
+	struct mei_cl_cb *next = NULL;
 	int status;
 
 	if (!dev)
@@ -565,25 +557,22 @@
 	dev->iamthif_timer = 0;
 	dev->iamthif_file_object = NULL;
 
-	if (dev->amthi_cmd_list.status == 0 &&
-	    !list_empty(&dev->amthi_cmd_list.mei_cb.cb_list)) {
-		dev_dbg(&dev->pdev->dev, "complete amthi cmd_list cb.\n");
+	dev_dbg(&dev->pdev->dev, "complete amthi cmd_list cb.\n");
 
-		list_for_each_entry_safe(cb_pos, cb_next,
-		    &dev->amthi_cmd_list.mei_cb.cb_list, cb_list) {
-			list_del(&cb_pos->cb_list);
-			cl_tmp = (struct mei_cl *)cb_pos->file_private;
+	list_for_each_entry_safe(pos, next,
+			&dev->amthi_cmd_list.mei_cb.cb_list, cb_list) {
+		list_del(&pos->cb_list);
+		cl_tmp = (struct mei_cl *)pos->file_private;
 
-			if (cl_tmp && cl_tmp == &dev->iamthif_cl) {
-				status = amthi_write(dev, cb_pos);
-				if (status) {
-					dev_dbg(&dev->pdev->dev,
-						"amthi write failed status = %d\n",
-							status);
-					return;
-				}
-				break;
+		if (cl_tmp && cl_tmp == &dev->iamthif_cl) {
+			status = amthi_write(dev, pos);
+			if (status) {
+				dev_dbg(&dev->pdev->dev,
+					"amthi write failed status = %d\n",
+						status);
+				return;
 			}
+			break;
 		}
 	}
 }
diff --git a/drivers/staging/mei/main.c b/drivers/staging/mei/main.c
index eb05c36..1e1a9f9 100644
--- a/drivers/staging/mei/main.c
+++ b/drivers/staging/mei/main.c
@@ -33,6 +33,7 @@
 #include <linux/compat.h>
 #include <linux/jiffies.h>
 #include <linux/interrupt.h>
+#include <linux/miscdevice.h>
 
 #include "mei_dev.h"
 #include "mei.h"
@@ -51,18 +52,10 @@
 static const char mei_driver_string[] = "Intel(R) Management Engine Interface";
 static const char mei_driver_version[] = MEI_DRIVER_VERSION;
 
-/* mei char device for registration */
-static struct cdev mei_cdev;
-
-/* major number for device */
-static int mei_major;
 /* The device pointer */
 /* Currently this driver works as long as there is only a single AMT device. */
 struct pci_dev *mei_device;
 
-static struct class *mei_class;
-
-
 /* mei_pci_tbl - PCI Device ID Table */
 static DEFINE_PCI_DEVICE_TABLE(mei_pci_tbl) = {
 	{PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_82946GZ)},
@@ -105,173 +98,6 @@
 
 static DEFINE_MUTEX(mei_mutex);
 
-/**
- * mei_probe - Device Initialization Routine
- *
- * @pdev: PCI device structure
- * @ent: entry in kcs_pci_tbl
- *
- * returns 0 on success, <0 on failure.
- */
-static int __devinit mei_probe(struct pci_dev *pdev,
-				const struct pci_device_id *ent)
-{
-	struct mei_device *dev;
-	int err;
-
-	mutex_lock(&mei_mutex);
-	if (mei_device) {
-		err = -EEXIST;
-		goto end;
-	}
-	/* enable pci dev */
-	err = pci_enable_device(pdev);
-	if (err) {
-		printk(KERN_ERR "mei: Failed to enable pci device.\n");
-		goto end;
-	}
-	/* set PCI host mastering  */
-	pci_set_master(pdev);
-	/* pci request regions for mei driver */
-	err = pci_request_regions(pdev, mei_driver_name);
-	if (err) {
-		printk(KERN_ERR "mei: Failed to get pci regions.\n");
-		goto disable_device;
-	}
-	/* allocates and initializes the mei dev structure */
-	dev = mei_device_init(pdev);
-	if (!dev) {
-		err = -ENOMEM;
-		goto release_regions;
-	}
-	/* mapping  IO device memory */
-	dev->mem_addr = pci_iomap(pdev, 0, 0);
-	if (!dev->mem_addr) {
-		printk(KERN_ERR "mei: mapping I/O device memory failure.\n");
-		err = -ENOMEM;
-		goto free_device;
-	}
-	pci_enable_msi(pdev);
-
-	 /* request and enable interrupt */
-	if (pci_dev_msi_enabled(pdev))
-		err = request_threaded_irq(pdev->irq,
-			NULL,
-			mei_interrupt_thread_handler,
-			0, mei_driver_name, dev);
-	else
-		err = request_threaded_irq(pdev->irq,
-			mei_interrupt_quick_handler,
-			mei_interrupt_thread_handler,
-			IRQF_SHARED, mei_driver_name, dev);
-
-	if (err) {
-		printk(KERN_ERR "mei: request_threaded_irq failure. irq = %d\n",
-		       pdev->irq);
-		goto unmap_memory;
-	}
-	INIT_DELAYED_WORK(&dev->timer_work, mei_timer);
-	if (mei_hw_init(dev)) {
-		printk(KERN_ERR "mei: Init hw failure.\n");
-		err = -ENODEV;
-		goto release_irq;
-	}
-	mei_device = pdev;
-	pci_set_drvdata(pdev, dev);
-	schedule_delayed_work(&dev->timer_work, HZ);
-
-	mutex_unlock(&mei_mutex);
-
-	pr_debug("mei: Driver initialization successful.\n");
-
-	return 0;
-
-release_irq:
-	/* disable interrupts */
-	dev->host_hw_state = mei_hcsr_read(dev);
-	mei_disable_interrupts(dev);
-	flush_scheduled_work();
-	free_irq(pdev->irq, dev);
-	pci_disable_msi(pdev);
-unmap_memory:
-	pci_iounmap(pdev, dev->mem_addr);
-free_device:
-	kfree(dev);
-release_regions:
-	pci_release_regions(pdev);
-disable_device:
-	pci_disable_device(pdev);
-end:
-	mutex_unlock(&mei_mutex);
-	printk(KERN_ERR "mei: Driver initialization failed.\n");
-	return err;
-}
-
-/**
- * mei_remove - Device Removal Routine
- *
- * @pdev: PCI device structure
- *
- * mei_remove is called by the PCI subsystem to alert the driver
- * that it should release a PCI device.
- */
-static void __devexit mei_remove(struct pci_dev *pdev)
-{
-	struct mei_device *dev;
-
-	if (mei_device != pdev)
-		return;
-
-	dev = pci_get_drvdata(pdev);
-	if (!dev)
-		return;
-
-	mutex_lock(&dev->device_lock);
-
-	mei_wd_stop(dev, false);
-
-	mei_device = NULL;
-
-	if (dev->iamthif_cl.state == MEI_FILE_CONNECTED) {
-		dev->iamthif_cl.state = MEI_FILE_DISCONNECTING;
-		mei_disconnect_host_client(dev, &dev->iamthif_cl);
-	}
-	if (dev->wd_cl.state == MEI_FILE_CONNECTED) {
-		dev->wd_cl.state = MEI_FILE_DISCONNECTING;
-		mei_disconnect_host_client(dev, &dev->wd_cl);
-	}
-
-	/* Unregistering watchdog device */
-	if (dev->wd_interface_reg)
-		watchdog_unregister_device(&amt_wd_dev);
-
-	/* remove entry if already in list */
-	dev_dbg(&pdev->dev, "list del iamthif and wd file list.\n");
-	mei_remove_client_from_file_list(dev, dev->wd_cl.host_client_id);
-	mei_remove_client_from_file_list(dev, dev->iamthif_cl.host_client_id);
-
-	dev->iamthif_current_cb = NULL;
-	dev->me_clients_num = 0;
-
-	mutex_unlock(&dev->device_lock);
-
-	flush_scheduled_work();
-
-	/* disable interrupts */
-	mei_disable_interrupts(dev);
-
-	free_irq(pdev->irq, dev);
-	pci_disable_msi(pdev);
-	pci_set_drvdata(pdev, NULL);
-
-	if (dev->mem_addr)
-		pci_iounmap(pdev, dev->mem_addr);
-
-	kfree(dev);
-
-	pci_release_regions(pdev);
-	pci_disable_device(pdev);
-}
 
 /**
  * mei_clear_list - removes all callbacks associated with file
@@ -372,21 +198,17 @@
 		struct mei_device *dev,
 		struct mei_cl *cl)
 {
-	struct mei_cl_cb *cb_pos = NULL;
-	struct mei_cl_cb *cb_next = NULL;
+	struct mei_cl_cb *pos = NULL;
+	struct mei_cl_cb *next = NULL;
 
-	if (!dev->read_list.status &&
-	    !list_empty(&dev->read_list.mei_cb.cb_list)) {
+	dev_dbg(&dev->pdev->dev, "remove read_list CB\n");
+	list_for_each_entry_safe(pos, next,
+			&dev->read_list.mei_cb.cb_list, cb_list) {
+		struct mei_cl *cl_temp;
+		cl_temp = (struct mei_cl *)pos->file_private;
 
-		dev_dbg(&dev->pdev->dev, "remove read_list CB\n");
-		list_for_each_entry_safe(cb_pos, cb_next,
-				&dev->read_list.mei_cb.cb_list, cb_list) {
-			struct mei_cl *cl_temp;
-			cl_temp = (struct mei_cl *)cb_pos->file_private;
-
-			if (mei_cl_cmp_id(cl, cl_temp))
-				return cb_pos;
-		}
+		if (mei_cl_cmp_id(cl, cl_temp))
+			return pos;
 	}
 	return NULL;
 }
@@ -402,15 +224,16 @@
 static int mei_open(struct inode *inode, struct file *file)
 {
 	struct mei_cl *cl;
-	int if_num = iminor(inode), err;
 	struct mei_device *dev;
+	unsigned long cl_id;
+	int err;
 
 	err = -ENODEV;
 	if (!mei_device)
 		goto out;
 
 	dev = pci_get_drvdata(mei_device);
-	if (if_num != MEI_MINOR_NUMBER || !dev)
+	if (!dev)
 		goto out;
 
 	mutex_lock(&dev->device_lock);
@@ -429,14 +252,16 @@
 	if (dev->open_handle_count >= MEI_MAX_OPEN_HANDLE_COUNT)
 		goto out_unlock;
 
-	cl->host_client_id = find_first_zero_bit(dev->host_clients_map,
-							MEI_CLIENTS_MAX);
-	if (cl->host_client_id > MEI_CLIENTS_MAX)
+	cl_id = find_first_zero_bit(dev->host_clients_map, MEI_CLIENTS_MAX);
+	if (cl_id >= MEI_CLIENTS_MAX)
 		goto out_unlock;
 
+	cl->host_client_id  = cl_id;
+
 	dev_dbg(&dev->pdev->dev, "client_id = %d\n", cl->host_client_id);
 
 	dev->open_handle_count++;
+
 	list_add_tail(&cl->link, &dev->file_list);
 
 	set_bit(cl->host_client_id, dev->host_clients_map);
@@ -446,7 +271,7 @@
 	file->private_data = cl;
 	mutex_unlock(&dev->device_lock);
 
-	return 0;
+	return nonseekable_open(inode, file);
 
 out_unlock:
 	mutex_unlock(&dev->device_lock);
@@ -492,8 +317,7 @@
 		    cl->me_client_id);
 
 		if (dev->open_handle_count > 0) {
-			clear_bit(cl->host_client_id,
-				  dev->host_clients_map);
+			clear_bit(cl->host_client_id, dev->host_clients_map);
 			dev->open_handle_count--;
 		}
 		mei_remove_client_from_file_list(dev, cl->host_client_id);
@@ -554,7 +378,7 @@
  * returns >=0 data length on success , <0 on error
  */
 static ssize_t mei_read(struct file *file, char __user *ubuf,
-			 size_t length, loff_t *offset)
+			size_t length, loff_t *offset)
 {
 	struct mei_cl *cl = file->private_data;
 	struct mei_cl_cb *cb_pos = NULL;
@@ -673,9 +497,7 @@
 	/* information size may be longer */
 	length = min_t(size_t, length, (cb->information - *offset));
 
-	if (copy_to_user(ubuf,
-			 cb->response_buffer.data + *offset,
-			 length)) {
+	if (copy_to_user(ubuf, cb->response_buffer.data + *offset, length)) {
 		rets = -EFAULT;
 		goto free;
 	}
@@ -711,7 +533,7 @@
  * returns >=0 data length on success , <0 on error
  */
 static ssize_t mei_write(struct file *file, const char __user *ubuf,
-			  size_t length, loff_t *offset)
+			 size_t length, loff_t *offset)
 {
 	struct mei_cl *cl = file->private_data;
 	struct mei_cl_cb *write_cb = NULL;
@@ -762,8 +584,7 @@
 			cl->read_cb = NULL;
 			cl->read_pending = 0;
 		}
-	} else if (cl->reading_state == MEI_IDLE &&
-		   !cl->read_pending)
+	} else if (cl->reading_state == MEI_IDLE && !cl->read_pending)
 		*offset = 0;
 
 
@@ -1034,7 +855,7 @@
  */
 #ifdef CONFIG_COMPAT
 static long mei_compat_ioctl(struct file *file,
-		      unsigned int cmd, unsigned long data)
+			unsigned int cmd, unsigned long data)
 {
 	return mei_ioctl(file, cmd, (unsigned long)compat_ptr(data));
 }
@@ -1090,6 +911,206 @@
 	return mask;
 }
 
+/*
+ * file operations structure will be used for mei char device.
+ */
+static const struct file_operations mei_fops = {
+	.owner = THIS_MODULE,
+	.read = mei_read,
+	.unlocked_ioctl = mei_ioctl,
+#ifdef CONFIG_COMPAT
+	.compat_ioctl = mei_compat_ioctl,
+#endif
+	.open = mei_open,
+	.release = mei_release,
+	.write = mei_write,
+	.poll = mei_poll,
+	.llseek = no_llseek
+};
+
+
+/*
+ * Misc Device Struct
+ */
+static struct miscdevice  mei_misc_device = {
+		.name = MEI_DRIVER_NAME,
+		.fops = &mei_fops,
+		.minor = MISC_DYNAMIC_MINOR,
+};
+
+/**
+ * mei_probe - Device Initialization Routine
+ *
+ * @pdev: PCI device structure
+ * @ent: entry in kcs_pci_tbl
+ *
+ * returns 0 on success, <0 on failure.
+ */
+static int __devinit mei_probe(struct pci_dev *pdev,
+				const struct pci_device_id *ent)
+{
+	struct mei_device *dev;
+	int err;
+
+	mutex_lock(&mei_mutex);
+	if (mei_device) {
+		err = -EEXIST;
+		goto end;
+	}
+	/* enable pci dev */
+	err = pci_enable_device(pdev);
+	if (err) {
+		printk(KERN_ERR "mei: Failed to enable pci device.\n");
+		goto end;
+	}
+	/* set PCI host mastering  */
+	pci_set_master(pdev);
+	/* pci request regions for mei driver */
+	err = pci_request_regions(pdev, mei_driver_name);
+	if (err) {
+		printk(KERN_ERR "mei: Failed to get pci regions.\n");
+		goto disable_device;
+	}
+	/* allocates and initializes the mei dev structure */
+	dev = mei_device_init(pdev);
+	if (!dev) {
+		err = -ENOMEM;
+		goto release_regions;
+	}
+	/* mapping  IO device memory */
+	dev->mem_addr = pci_iomap(pdev, 0, 0);
+	if (!dev->mem_addr) {
+		printk(KERN_ERR "mei: mapping I/O device memory failure.\n");
+		err = -ENOMEM;
+		goto free_device;
+	}
+	pci_enable_msi(pdev);
+
+	 /* request and enable interrupt */
+	if (pci_dev_msi_enabled(pdev))
+		err = request_threaded_irq(pdev->irq,
+			NULL,
+			mei_interrupt_thread_handler,
+			0, mei_driver_name, dev);
+	else
+		err = request_threaded_irq(pdev->irq,
+			mei_interrupt_quick_handler,
+			mei_interrupt_thread_handler,
+			IRQF_SHARED, mei_driver_name, dev);
+
+	if (err) {
+		printk(KERN_ERR "mei: request_threaded_irq failure. irq = %d\n",
+		       pdev->irq);
+		goto unmap_memory;
+	}
+	INIT_DELAYED_WORK(&dev->timer_work, mei_timer);
+	if (mei_hw_init(dev)) {
+		printk(KERN_ERR "mei: Init hw failure.\n");
+		err = -ENODEV;
+		goto release_irq;
+	}
+
+	err = misc_register(&mei_misc_device);
+	if (err)
+		goto release_irq;
+
+	mei_device = pdev;
+	pci_set_drvdata(pdev, dev);
+
+
+	schedule_delayed_work(&dev->timer_work, HZ);
+
+	mutex_unlock(&mei_mutex);
+
+	pr_debug("mei: Driver initialization successful.\n");
+
+	return 0;
+
+release_irq:
+	/* disable interrupts */
+	dev->host_hw_state = mei_hcsr_read(dev);
+	mei_disable_interrupts(dev);
+	flush_scheduled_work();
+	free_irq(pdev->irq, dev);
+	pci_disable_msi(pdev);
+unmap_memory:
+	pci_iounmap(pdev, dev->mem_addr);
+free_device:
+	kfree(dev);
+release_regions:
+	pci_release_regions(pdev);
+disable_device:
+	pci_disable_device(pdev);
+end:
+	mutex_unlock(&mei_mutex);
+	printk(KERN_ERR "mei: Driver initialization failed.\n");
+	return err;
+}
+
+/**
+ * mei_remove - Device Removal Routine
+ *
+ * @pdev: PCI device structure
+ *
+ * mei_remove is called by the PCI subsystem to alert the driver
+ * that it should release a PCI device.
+ */
+static void __devexit mei_remove(struct pci_dev *pdev)
+{
+	struct mei_device *dev;
+
+	if (mei_device != pdev)
+		return;
+
+	dev = pci_get_drvdata(pdev);
+	if (!dev)
+		return;
+
+	mutex_lock(&dev->device_lock);
+
+	mei_wd_stop(dev, false);
+
+	mei_device = NULL;
+
+	if (dev->iamthif_cl.state == MEI_FILE_CONNECTED) {
+		dev->iamthif_cl.state = MEI_FILE_DISCONNECTING;
+		mei_disconnect_host_client(dev, &dev->iamthif_cl);
+	}
+	if (dev->wd_cl.state == MEI_FILE_CONNECTED) {
+		dev->wd_cl.state = MEI_FILE_DISCONNECTING;
+		mei_disconnect_host_client(dev, &dev->wd_cl);
+	}
+
+	/* Unregistering watchdog device */
+	mei_watchdog_unregister(dev);
+
+	/* remove entry if already in list */
+	dev_dbg(&pdev->dev, "list del iamthif and wd file list.\n");
+	mei_remove_client_from_file_list(dev, dev->wd_cl.host_client_id);
+	mei_remove_client_from_file_list(dev, dev->iamthif_cl.host_client_id);
+
+	dev->iamthif_current_cb = NULL;
+	dev->me_clients_num = 0;
+
+	mutex_unlock(&dev->device_lock);
+
+	flush_scheduled_work();
+
+	/* disable interrupts */
+	mei_disable_interrupts(dev);
+
+	free_irq(pdev->irq, dev);
+	pci_disable_msi(pdev);
+	pci_set_drvdata(pdev, NULL);
+
+	if (dev->mem_addr)
+		pci_iounmap(pdev, dev->mem_addr);
+
+	kfree(dev);
+
+	pci_release_regions(pdev);
+	pci_disable_device(pdev);
+}
 #ifdef CONFIG_PM
 static int mei_pci_suspend(struct device *device)
 {
@@ -1173,131 +1194,6 @@
 	.driver.pm = MEI_PM_OPS,
 };
 
-/*
- * file operations structure will be used for mei char device.
- */
-static const struct file_operations mei_fops = {
-	.owner = THIS_MODULE,
-	.read = mei_read,
-	.unlocked_ioctl = mei_ioctl,
-#ifdef CONFIG_COMPAT
-	.compat_ioctl = mei_compat_ioctl,
-#endif
-	.open = mei_open,
-	.release = mei_release,
-	.write = mei_write,
-	.poll = mei_poll,
-};
-
-/**
- * mei_registration_cdev - sets up the cdev structure for mei device.
- *
- * @dev: char device struct
- * @hminor: minor number for registration char device
- * @fops: file operations structure
- *
- * returns 0 on success, <0 on failure.
- */
-static int mei_registration_cdev(struct cdev *dev, int hminor,
-				  const struct file_operations *fops)
-{
-	int ret, devno = MKDEV(mei_major, hminor);
-
-	cdev_init(dev, fops);
-	dev->owner = THIS_MODULE;
-	ret = cdev_add(dev, devno, 1);
-	/* Fail gracefully if need be */
-	if (ret)
-		printk(KERN_ERR "mei: Error %d registering mei device %d\n",
-		       ret, hminor);
-	return ret;
-}
-
-/**
- * mei_register_cdev - registers mei char device
- *
- * returns 0 on success, <0 on failure.
- */
-static int mei_register_cdev(void)
-{
-	int ret;
-	dev_t dev;
-
-	/* registration of char devices */
-	ret = alloc_chrdev_region(&dev, MEI_MINORS_BASE, MEI_MINORS_COUNT,
-				  MEI_DRIVER_NAME);
-	if (ret) {
-		printk(KERN_ERR "mei: Error allocating char device region.\n");
-		return ret;
-	}
-
-	mei_major = MAJOR(dev);
-
-	ret = mei_registration_cdev(&mei_cdev, MEI_MINOR_NUMBER,
-				     &mei_fops);
-	if (ret)
-		unregister_chrdev_region(MKDEV(mei_major, MEI_MINORS_BASE),
-					 MEI_MINORS_COUNT);
-
-	return ret;
-}
-
-/**
- * mei_unregister_cdev - unregisters mei char device
- */
-static void mei_unregister_cdev(void)
-{
-	cdev_del(&mei_cdev);
-	unregister_chrdev_region(MKDEV(mei_major, MEI_MINORS_BASE),
-				 MEI_MINORS_COUNT);
-}
-
-/**
- * mei_sysfs_device_create - adds device entry to sysfs
- *
- * returns 0 on success, <0 on failure.
- */
-static int mei_sysfs_device_create(void)
-{
-	struct class *class;
-	void *tmphdev;
-	int err;
-
-	class = class_create(THIS_MODULE, MEI_DRIVER_NAME);
-	if (IS_ERR(class)) {
-		err = PTR_ERR(class);
-		printk(KERN_ERR "mei: Error creating mei class.\n");
-		goto err_out;
-	}
-
-	tmphdev = device_create(class, NULL, mei_cdev.dev, NULL,
-					MEI_DEV_NAME);
-	if (IS_ERR(tmphdev)) {
-		err = PTR_ERR(tmphdev);
-		goto err_destroy;
-	}
-
-	mei_class = class;
-	return 0;
-
-err_destroy:
-	class_destroy(class);
-err_out:
-	return err;
-}
-
-/**
- * mei_sysfs_device_remove - unregisters the device entry on sysfs
- */
-static void mei_sysfs_device_remove(void)
-{
-	if (IS_ERR_OR_NULL(mei_class))
-		return;
-
-	device_destroy(mei_class, mei_cdev.dev);
-	class_destroy(mei_class);
-}
-
 /**
  * mei_init_module - Driver Registration Routine
  *
@@ -1314,26 +1210,9 @@
 		mei_driver_string, mei_driver_version);
 	/* init pci module */
 	ret = pci_register_driver(&mei_driver);
-	if (ret < 0) {
+	if (ret < 0)
 		printk(KERN_ERR "mei: Error registering driver.\n");
-		goto end;
-	}
 
-	ret = mei_register_cdev();
-	if (ret)
-		goto unregister_pci;
-
-	ret = mei_sysfs_device_create();
-	if (ret)
-		goto unregister_cdev;
-
-	return ret;
-
-unregister_cdev:
-	mei_unregister_cdev();
-unregister_pci:
-	pci_unregister_driver(&mei_driver);
-end:
 	return ret;
 }
 
@@ -1347,8 +1226,7 @@
  */
 static void __exit mei_exit_module(void)
 {
-	mei_sysfs_device_remove();
-	mei_unregister_cdev();
+	misc_deregister(&mei_misc_device);
 	pci_unregister_driver(&mei_driver);
 
 	pr_debug("mei: Driver unloaded successfully.\n");
diff --git a/drivers/staging/mei/mei.txt b/drivers/staging/mei/mei.txt
index 17302ad..516bfe7 100644
--- a/drivers/staging/mei/mei.txt
+++ b/drivers/staging/mei/mei.txt
@@ -1,78 +1,74 @@
-Intel MEI
+Intel(R) Management Engine Interface (Intel(R) MEI)
 =======================
 
 Introduction
 =======================
 
-The Intel Management Engine (Intel ME) is an isolated and
-protected computing resource (Coprocessor) residing inside
-Intel chipsets. The Intel ME provides support for computer/IT
-management features.
-The Feature set depends on the Intel chipset SKU.
+The Intel Management Engine (Intel ME) is an isolated andprotected computing
+resource (Co-processor) residing inside certain Intel chipsets. The Intel ME
+provides support for computer/IT management features. The feature set
+depends on the Intel chipset SKU.
 
-The Intel Management Engine Interface (Intel MEI, previously known
-as HECI) is the interface between the Host and Intel ME.
-This interface is exposed to the host as a PCI device.
-The Intel MEI Driver is in charge of the communication channel
-between a host application and the ME feature.
+The Intel Management Engine Interface (Intel MEI, previously known as HECI)
+is the interface between the Host and Intel ME. This interface is exposed
+to the host as a PCI device. The Intel MEI Driver is in charge of the
+communication channel between a host application and the Intel ME feature.
 
-Each Intel ME feature (Intel ME Client) is addressed by
-GUID/UUID and each feature defines its own protocol.
-The protocol is message-based with a header and payload up to
-512 bytes.
+Each Intel ME feature (Intel ME Client) is addressed by a GUID/UUID and
+each client has its own protocol. The protocol is message-based with a
+header and payload up to 512 bytes.
 
-[place holder to URL to protocol definitions]
-
-Prominent usage of the Interface is to communicate with
-Intel Active Management Technology (Intel AMT)
-implemented in firmware running on the Intel ME.
+Prominent usage of the Intel ME Interface is to communicate with Intel(R)
+Active Management Technology (Intel AMT)implemented in firmware running on
+the Intel ME.
 
 Intel AMT provides the ability to manage a host remotely out-of-band (OOB)
-even when the host processor has crashed or is in a sleep state.
+even when the operating system running on the host processor has crashed or
+is in a sleep state.
 
 Some examples of Intel AMT usage are:
    - Monitoring hardware state and platform components
-   - Remote power off/on (useful for green computing or overnight IT maintenance)
+   - Remote power off/on (useful for green computing or overnight IT
+     maintenance)
    - OS updates
    - Storage of useful platform information such as software assets
-   - built-in hardware KVM
-   - selective network isolation of Ethernet and IP protocol flows based on
-     policies set by a remote management console
+   - Built-in hardware KVM
+   - Selective network isolation of Ethernet and IP protocol flows based
+     on policies set by a remote management console
    - IDE device redirection from remote management console
 
 Intel AMT (OOB) communication is based on SOAP (deprecated
-starting with Release 6.0) over HTTP/HTTPS or WS-Management protocol
-over HTTP and HTTPS that are received from a remote
-management console application.
+starting with Release 6.0) over HTTP/S or WS-Management protocol over
+HTTP/S that are received from a remote management console application.
 
 For more information about Intel AMT:
-http://software.intel.com/sites/manageability/AMT_Implementation_and_Reference_Guide/WordDocuments/aboutintelamt.htm
+http://software.intel.com/sites/manageability/AMT_Implementation_and_Reference_Guide
 
-
-MEI Driver
+Intel MEI Driver
 =======================
 
-The driver exposes a character device called /dev/mei.
+The driver exposes a misc device called /dev/mei.
 
-An application maintains communication with an ME feature while
-/dev/mei is open. The binding to a specific features is performed
-by calling MEI_CONNECT_CLIENT_IOCTL, which passes the desired UUID.
-The number of instances of an ME feature that can be opened
-at the same time depends on the ME feature, but most of the
+An application maintains communication with an Intel ME feature while
+/dev/mei is open. The binding to a specific features is performed by calling
+MEI_CONNECT_CLIENT_IOCTL, which passes the desired UUID.
+The number of instances of an Intel ME feature that can be opened
+at the same time depends on the Intel ME feature, but most of the
 features allow only a single instance.
 
-
-The Intel AMT Host Interface (AMTHI) feature requires multiple
-simultaneous user applications, therefore the MEI driver handles
+The Intel AMT Host Interface (Intel AMTHI) feature supports multiple
+simultaneous user applications. Therefore, the Intel MEI driver handles
 this internally by maintaining request queues for the applications.
 
-The driver is oblivious to data that are passed between
+The driver is oblivious to data that is passed between firmware feature
+and host application.
 
-Because some of the ME features can change the system
-configuration, the driver by default allows only privileged
+Because some of the Intel ME features can change the system
+configuration, the driver by default allows only a privileged
 user to access it.
 
-A Code snippet for application communicating with AMTHI client:
+A code snippet for an application communicating with
+Intel AMTHI client:
 	struct mei_connect_client_data data;
 	fd = open(MEI_DEVICE);
 
@@ -80,7 +76,7 @@
 
 	ioctl(fd, IOCTL_MEI_CONNECT_CLIENT, &data);
 
-	printf(“Ver=%d, MaxLen=%ld\n”,
+	printf("Ver=%d, MaxLen=%ld\n",
 			data.d.in_client_uuid.protocol_version,
 			data.d.in_client_uuid.max_msg_length);
 
@@ -95,76 +91,106 @@
 	[...]
 	close(fd);
 
-ME Applications:
+IOCTL:
+======
+The Intel MEI Driver supports the following IOCTL command:
+	IOCTL_MEI_CONNECT_CLIENT	Connect to firmware Feature (client).
+
+	usage:
+		struct mei_connect_client_data clientData;
+		ioctl(fd, IOCTL_MEI_CONNECT_CLIENT, &clientData);
+
+	inputs:
+		mei_connect_client_data struct contain the following
+		input field:
+
+		in_client_uuid -	UUID of the FW Feature that needs
+					to connect to.
+	outputs:
+		out_client_properties - Client Properties: MTU and Protocol Version.
+
+	error returns:
+		EINVAL	Wrong IOCTL Number
+		ENODEV	Device or Connection is not initialized or ready.
+			(e.g. Wrong UUID)
+		ENOMEM	Unable to allocate memory to client internal data.
+		EFAULT	Fatal Error (e.g. Unable to access user input data)
+		EBUSY	Connection Already Open
+
+	Notes:
+        max_msg_length (MTU) in client properties describes the maximum
+        data that can be sent or received. (e.g. if MTU=2K, can send
+        requests up to bytes 2k and received responses upto 2k bytes).
+
+Intel ME Applications:
 ==============
 
 1) Intel Local Management Service (Intel LMS)
-	Applications running locally on the platform communicate with
-	Intel AMT Release 2.0 and later releases in the same way
-	that network applications do via SOAP over HTTP (deprecated
-	starting with Release 6.0) or with WS-Management over SOAP over
-	HTTP. which means that some Intel AMT feature can be access
-	from a local application using same Network interface as for
-	remote application.
 
-	When a local application sends a message addressed to the local
-	Intel AMT host name, the Local Manageability Service (LMS),
-	which listens for traffic directed to the host name, intercepts
-	the message and routes it to the Intel Management Engine Interface.
+	Applications running locally on the platform communicate with Intel AMT Release
+	2.0 and later releases in the same way that network applications do via SOAP
+	over HTTP (deprecated starting with Release 6.0) or with WS-Management over
+	SOAP over HTTP. This means that some Intel AMT features can be accessed from a
+	local application using the same network interface as a remote application
+	communicating with Intel AMT over the network.
+
+	When a local application sends a message addressed to the local Intel AMT host
+	name, the Intel LMS, which listens for traffic directed to the host name,
+	intercepts the message and routes it to the Intel MEI.
 	For more information:
-	http://software.intel.com/sites/manageability/AMT_Implementation_and_
-	Reference_Guide/WordDocuments/localaccess1.htm
+	http://software.intel.com/sites/manageability/AMT_Implementation_and_Reference_Guide
+	Under "About Intel AMT" => "Local Access"
 
-	The LMS opens a connection using the MEI driver to the LMS
-	FW feature using a defined UUID and then communicates with the
-	feature using a protocol
-	called Intel(R) AMT Port Forwarding Protocol (APF protocol).
-	The protocol is used to maintain multiple sessions with
-	Intel AMT from a single application.
-	See the protocol specification in
-	the Intel(R) AMT Implementation and Reference Guide
-	http://software.intel.com/sites/manageability/AMT_Implementation_and_Reference_Guide/HTMLDocuments/MPSDocuments/Intel%20AMT%20Port%20Forwarding%20Protocol%20Reference%20Manual.pdf
+	For downloading Intel LMS:
+	http://software.intel.com/en-us/articles/download-the-latest-intel-amt-open-source-drivers/
 
-  2) Intel AMT Remote configuration using a Local Agent:
+	The Intel LMS opens a connection using the Intel MEI driver to the Intel LMS
+	firmware feature using a defined UUID and then communicates with the feature
+	using a protocol called Intel AMT Port Forwarding Protocol(Intel APF protocol).
+	The protocol is used to maintain multiple sessions with Intel AMT from a
+	single application.
+
+	See the protocol specification in the Intel AMT Software Development Kit(SDK)
+	http://software.intel.com/sites/manageability/AMT_Implementation_and_Reference_Guide
+	Under "SDK Resources" => "Intel(R) vPro(TM) Gateway(MPS)"
+	=> "Information for Intel(R) vPro(TM) Gateway Developers"
+	=> "Description of the Intel AMT Port Forwarding (APF)Protocol"
+
+  2) Intel AMT Remote configuration using a Local Agent
 	A Local Agent enables IT personnel to configure Intel AMT out-of-the-box
-	without requiring installing additional data to enable setup.
-	The remote configuration process may involve an ISV-developed remote
-	configuration agent that runs on the host.
+	without requiring installing additional data to enable setup. The remote
+	configuration process may involve an ISV-developed remote configuration
+	agent that runs on the host.
 	For more information:
-	http://software.intel.com/sites/manageability/AMT_Implementation_and_Reference_Guide/WordDocuments/remoteconfigurationwithalocalagent.htm
+	http://software.intel.com/sites/manageability/AMT_Implementation_and_Reference_Guide
+	Under "Setup and Configuration of Intel AMT" =>
+	"SDK Tools Supporting Setup and Configuration" =>
+	"Using the Local Agent Sample"
 
-	How the Local Agent Works (including Command structs):
-	http://software.intel.com/sites/manageability/AMT_Implementation_and_Reference_Guide/WordDocuments/howthelocalagentsampleworks.htm
+	An open source Intel AMT configuration utility,	implementing a local agent
+	that accesses the Intel MEI driver, can be found here:
+	http://software.intel.com/en-us/articles/download-the-latest-intel-amt-open-source-drivers/
+
 
 Intel AMT OS Health Watchdog:
 =============================
 The Intel AMT Watchdog is an OS Health (Hang/Crash) watchdog.
 Whenever the OS hangs or crashes, Intel AMT will send an event
-to whoever subscribed to this event. This mechanism means that
-IT knows when a platform crashes even when there is a hard failure
-on the host.
-The AMT Watchdog is composed of two parts:
-	1) FW Feature - that receives the heartbeats
+to any subsciber to this event. This mechanism means that
+IT knows when a platform crashes even when there is a hard failureon the host.
+
+The Intel AMT Watchdog is composed of two parts:
+	1) Firmware feature - receives the heartbeats
 	   and sends an event when the heartbeats stop.
-	2) MEI driver – connects to the watchdog (WD) feature,
-	   configures the watchdog and sends the heartbeats.
+	2) Intel MEI driver - connects to the watchdog feature, configures the
+	   watchdog and sends the heartbeats.
 
-The MEI driver configures the Watchdog to expire by default
-every 120sec unless set by the user using module parameters.
-The Driver then sends heartbeats every 2sec.
+The Intel MEI driver uses the kernel watchdog to configure the Intel AMT
+Watchdog and to send heartbeats to it. The default timeout of the
+watchdog is 120 seconds.
 
-If WD feature does not exist (i.e. the connection failed),
-the MEI driver will disable the sending of heartbeats.
-
-Module Parameters
-=================
-watchdog_timeout - the user can use this module parameter
-to change the watchdog timeout setting.
-
-This value sets the Intel AMT watchdog timeout interval in seconds;
-the default value is 120sec.
-in order to disable the watchdog activites set the value to 0.
-Normal values should be between 120 and 65535
+If the Intel AMT Watchdog feature does not exist (i.e. the connection failed),
+the Intel MEI driver will disable the sending of heartbeats.
 
 Supported Chipsets:
 ==================
diff --git a/drivers/staging/mei/mei_dev.h b/drivers/staging/mei/mei_dev.h
index af4b1af..82bacfc 100644
--- a/drivers/staging/mei/mei_dev.h
+++ b/drivers/staging/mei/mei_dev.h
@@ -23,13 +23,6 @@
 #include "hw.h"
 
 /*
- * MEI Char Driver Minors
- */
-#define MEI_MINORS_BASE	1
-#define MEI_MINORS_COUNT	1
-#define MEI_MINOR_NUMBER	1
-
-/*
  * watch dog definition
  */
 #define MEI_WATCHDOG_DATA_SIZE         16
@@ -42,11 +35,6 @@
  */
 extern struct pci_dev *mei_device;
 
-/*
- * AMT Watchdog Device
- */
-#define INTEL_AMT_WATCHDOG_ID "INTCAMT"
-extern struct watchdog_device amt_wd_dev;
 
 /*
  * AMTHI Client UUID
@@ -175,7 +163,6 @@
 
 struct mei_io_list {
 	struct mei_cl_cb mei_cb;
-	int status;
 };
 
 /* MEI private device struct */
diff --git a/drivers/staging/mei/wd.c b/drivers/staging/mei/wd.c
index ffca7ca..8094941 100644
--- a/drivers/staging/mei/wd.c
+++ b/drivers/staging/mei/wd.c
@@ -35,12 +35,16 @@
 	{0x07, 0x02, 0x01, 0x10}
 };
 
+/*
+ * AMT Watchdog Device
+ */
+#define INTEL_AMT_WATCHDOG_ID "INTCAMT"
+
 /* UUIDs for AMT F/W clients */
 const uuid_le mei_wd_guid = UUID_LE(0x05B79A6F, 0x4628, 0x4D7F, 0x89,
 						0x9D, 0xA9, 0x15, 0x14, 0xCB,
 						0x32, 0xAB);
 
-
 void mei_wd_set_start_timeout(struct mei_device *dev, u16 timeout)
 {
 	dev_dbg(&dev->pdev->dev, "timeout=%d.\n", timeout);
@@ -331,14 +335,14 @@
 /*
  * Watchdog Device structs
  */
-const struct watchdog_ops wd_ops = {
+static const struct watchdog_ops wd_ops = {
 		.owner = THIS_MODULE,
 		.start = mei_wd_ops_start,
 		.stop = mei_wd_ops_stop,
 		.ping = mei_wd_ops_ping,
 		.set_timeout = mei_wd_ops_set_timeout,
 };
-const struct watchdog_info wd_info = {
+static const struct watchdog_info wd_info = {
 		.identity = INTEL_AMT_WATCHDOG_ID,
 		.options = WDIOF_KEEPALIVEPING,
 };
@@ -352,3 +356,25 @@
 };
 
 
+void  mei_watchdog_register(struct mei_device *dev)
+{
+	dev_dbg(&dev->pdev->dev, "dev->wd_timeout =%d.\n", dev->wd_timeout);
+
+	dev->wd_due_counter = !!dev->wd_timeout;
+
+	if (watchdog_register_device(&amt_wd_dev)) {
+		dev_err(&dev->pdev->dev, "unable to register watchdog device.\n");
+		dev->wd_interface_reg = false;
+	} else {
+		dev_dbg(&dev->pdev->dev, "successfully register watchdog interface.\n");
+		dev->wd_interface_reg = true;
+	}
+}
+
+void mei_watchdog_unregister(struct mei_device *dev)
+{
+	if (dev->wd_interface_reg)
+		watchdog_unregister_device(&amt_wd_dev);
+	dev->wd_interface_reg = false;
+}
+
diff --git a/drivers/staging/nvec/nvec.c b/drivers/staging/nvec/nvec.c
index e06b867..fafdfa2 100644
--- a/drivers/staging/nvec/nvec.c
+++ b/drivers/staging/nvec/nvec.c
@@ -27,6 +27,8 @@
 #include <linux/interrupt.h>
 #include <linux/io.h>
 #include <linux/irq.h>
+#include <linux/of.h>
+#include <linux/of_gpio.h>
 #include <linux/list.h>
 #include <linux/mfd/core.h>
 #include <linux/mutex.h>
@@ -727,8 +729,24 @@
 	}
 	platform_set_drvdata(pdev, nvec);
 	nvec->dev = &pdev->dev;
-	nvec->gpio = pdata->gpio;
-	nvec->i2c_addr = pdata->i2c_addr;
+
+	if (pdata) {
+		nvec->gpio = pdata->gpio;
+		nvec->i2c_addr = pdata->i2c_addr;
+	} else if (nvec->dev->of_node) {
+		nvec->gpio = of_get_named_gpio(nvec->dev->of_node, "request-gpios", 0);
+		if (nvec->gpio < 0) {
+			dev_err(&pdev->dev, "no gpio specified");
+			goto failed;
+		}
+		if (of_property_read_u32(nvec->dev->of_node, "slave-addr", &nvec->i2c_addr)) {
+			dev_err(&pdev->dev, "no i2c address specified");
+			goto failed;
+		}
+	} else {
+		dev_err(&pdev->dev, "no platform data\n");
+		goto failed;
+	}
 
 	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 	if (!res) {
@@ -893,6 +911,13 @@
 #define tegra_nvec_resume NULL
 #endif
 
+/* Match table for of_platform binding */
+static const struct of_device_id nvidia_nvec_of_match[] __devinitconst = {
+	{ .compatible = "nvidia,nvec", },
+	{},
+};
+MODULE_DEVICE_TABLE(of, nvidia_nvec_of_match);
+
 static struct platform_driver nvec_device_driver = {
 	.probe   = tegra_nvec_probe,
 	.remove  = __devexit_p(tegra_nvec_remove),
@@ -901,6 +926,7 @@
 	.driver  = {
 		.name = "nvec",
 		.owner = THIS_MODULE,
+		.of_match_table = nvidia_nvec_of_match,
 	}
 };
 
diff --git a/drivers/staging/olpc_dcon/olpc_dcon.c b/drivers/staging/olpc_dcon/olpc_dcon.c
index af24ddf..3d91993 100644
--- a/drivers/staging/olpc_dcon/olpc_dcon.c
+++ b/drivers/staging/olpc_dcon/olpc_dcon.c
@@ -34,8 +34,8 @@
 
 /* Module definitions */
 
-static int resumeline = 898;
-module_param(resumeline, int, 0444);
+static ushort resumeline = 898;
+module_param(resumeline, ushort, 0444);
 
 /* Default off since it doesn't work on DCON ASIC in B-test OLPC board */
 static int useaa = 1;
@@ -456,7 +456,7 @@
 	unsigned long enable_mono;
 	int rc;
 
-	rc = strict_strtoul(buf, 10, &enable_mono);
+	rc = kstrtoul(buf, 10, &enable_mono);
 	if (rc)
 		return rc;
 
@@ -472,7 +472,7 @@
 	unsigned long output;
 	int ret;
 
-	ret = strict_strtoul(buf, 10, &output);
+	ret = kstrtoul(buf, 10, &output);
 	if (ret)
 		return ret;
 
@@ -498,10 +498,10 @@
 static ssize_t dcon_resumeline_store(struct device *dev,
 	struct device_attribute *attr, const char *buf, size_t count)
 {
-	unsigned long rl;
+	unsigned short rl;
 	int rc;
 
-	rc = strict_strtoul(buf, 10, &rl);
+	rc = kstrtou16(buf, 10, &rl);
 	if (rc)
 		return rc;
 
@@ -517,7 +517,7 @@
 	unsigned long output;
 	int ret;
 
-	ret = strict_strtoul(buf, 10, &output);
+	ret = kstrtoul(buf, 10, &output);
 	if (ret)
 		return ret;
 
@@ -755,9 +755,9 @@
 irqreturn_t dcon_interrupt(int irq, void *id)
 {
 	struct dcon_priv *dcon = id;
-	int status = pdata->read_status();
+	u8 status;
 
-	if (status == -1)
+	if (pdata->read_status(&status))
 		return IRQ_NONE;
 
 	switch (status & 3) {
diff --git a/drivers/staging/olpc_dcon/olpc_dcon.h b/drivers/staging/olpc_dcon/olpc_dcon.h
index 0264c94..167a417 100644
--- a/drivers/staging/olpc_dcon/olpc_dcon.h
+++ b/drivers/staging/olpc_dcon/olpc_dcon.h
@@ -84,7 +84,7 @@
 	int (*init)(struct dcon_priv *);
 	void (*bus_stabilize_wiggle)(void);
 	void (*set_dconload)(int);
-	u8 (*read_status)(void);
+	int (*read_status)(u8 *);
 };
 
 #include <linux/interrupt.h>
diff --git a/drivers/staging/olpc_dcon/olpc_dcon_xo_1.c b/drivers/staging/olpc_dcon/olpc_dcon_xo_1.c
index 2245213..cb6ce0c 100644
--- a/drivers/staging/olpc_dcon/olpc_dcon_xo_1.c
+++ b/drivers/staging/olpc_dcon/olpc_dcon_xo_1.c
@@ -183,17 +183,15 @@
 	gpio_set_value(OLPC_GPIO_DCON_LOAD, val);
 }
 
-static u8 dcon_read_status_xo_1(void)
+static int dcon_read_status_xo_1(u8 *status)
 {
-	u8 status;
-
-	status = gpio_get_value(OLPC_GPIO_DCON_STAT0);
-	status |= gpio_get_value(OLPC_GPIO_DCON_STAT1) << 1;
+	*status = gpio_get_value(OLPC_GPIO_DCON_STAT0);
+	*status |= gpio_get_value(OLPC_GPIO_DCON_STAT1) << 1;
 
 	/* Clear the negative edge status for GPIO7 */
 	cs5535_gpio_set(OLPC_GPIO_DCON_IRQ, GPIO_NEGATIVE_EDGE_STS);
 
-	return status;
+	return 0;
 }
 
 struct dcon_platform_data dcon_pdata_xo_1 = {
diff --git a/drivers/staging/olpc_dcon/olpc_dcon_xo_1_5.c b/drivers/staging/olpc_dcon/olpc_dcon_xo_1_5.c
index a6a6cf2..69415ee 100644
--- a/drivers/staging/olpc_dcon/olpc_dcon_xo_1_5.c
+++ b/drivers/staging/olpc_dcon/olpc_dcon_xo_1_5.c
@@ -167,20 +167,18 @@
 	gpio_set_value(VX855_GPIO(1), val);
 }
 
-static u8 dcon_read_status_xo_1_5(void)
+static int dcon_read_status_xo_1_5(u8 *status)
 {
-	u8 status;
-
 	if (!dcon_was_irq())
 		return -1;
 
 	/* i believe this is the same as "inb(0x44b) & 3" */
-	status = gpio_get_value(VX855_GPI(10));
-	status |= gpio_get_value(VX855_GPI(11)) << 1;
+	*status = gpio_get_value(VX855_GPI(10));
+	*status |= gpio_get_value(VX855_GPI(11)) << 1;
 
 	dcon_clear_irq();
 
-	return status;
+	return 0;
 }
 
 struct dcon_platform_data dcon_pdata_xo_1_5 = {
diff --git a/drivers/staging/omapdrm/Kconfig b/drivers/staging/omapdrm/Kconfig
new file mode 100644
index 0000000..81a7cba
--- /dev/null
+++ b/drivers/staging/omapdrm/Kconfig
@@ -0,0 +1,25 @@
+
+config DRM_OMAP
+	tristate "OMAP DRM"
+	depends on DRM && !CONFIG_FB_OMAP2
+	depends on ARCH_OMAP2PLUS
+	select DRM_KMS_HELPER
+	select OMAP2_DSS
+	select FB_SYS_FILLRECT
+	select FB_SYS_COPYAREA
+	select FB_SYS_IMAGEBLIT
+	select FB_SYS_FOPS
+	default n
+	help
+	  DRM display driver for OMAP2/3/4 based boards.
+
+config DRM_OMAP_NUM_CRTCS
+	int "Number of CRTCs"
+	range 1 10
+	default 1  if ARCH_OMAP2 || ARCH_OMAP3
+	default 2  if ARCH_OMAP4
+	depends on DRM_OMAP
+	help
+	  Select the number of video overlays which can be used as framebuffers.
+	  The remaining overlays are reserved for video.
+
diff --git a/drivers/staging/omapdrm/Makefile b/drivers/staging/omapdrm/Makefile
new file mode 100644
index 0000000..592cf69
--- /dev/null
+++ b/drivers/staging/omapdrm/Makefile
@@ -0,0 +1,21 @@
+#
+# Makefile for the drm device driver.  This driver provides support for the
+# Direct Rendering Infrastructure (DRI)
+#
+
+ccflags-y := -Iinclude/drm -Werror
+omapdrm-y := omap_drv.o \
+	omap_debugfs.o \
+	omap_crtc.o \
+	omap_encoder.o \
+	omap_connector.o \
+	omap_fb.o \
+	omap_fbdev.o \
+	omap_gem.o \
+	omap_dmm_tiler.o \
+	tcm-sita.o
+
+# temporary:
+omapdrm-y += omap_gem_helpers.o
+
+obj-$(CONFIG_DRM_OMAP)	+= omapdrm.o
diff --git a/drivers/staging/omapdrm/TODO b/drivers/staging/omapdrm/TODO
new file mode 100644
index 0000000..55b1837
--- /dev/null
+++ b/drivers/staging/omapdrm/TODO
@@ -0,0 +1,38 @@
+TODO
+. check error handling/cleanup paths
+. add drm_plane / overlay support
+. add video decode/encode support (via syslink3 + codec-engine)
+. still some rough edges with flipping.. event back to userspace should
+  really come after VSYNC interrupt
+. where should we do eviction (detatch_pages())?  We aren't necessarily
+  accessing the pages via a GART, so maybe we need some other threshold
+  to put a cap on the # of pages that can be pin'd.  (It is mostly only
+  of interest in case you have a swap partition/file.. which a lot of
+  these devices do not.. but it doesn't hurt for the driver to do the
+  right thing anyways.)
+  . Use mm_shrinker to trigger unpinning pages.  Need to figure out how
+    to handle next issue first (I think?)
+  . Note TTM already has some mm_shrinker stuff..  maybe an argument to
+    move to TTM?  Or maybe something that could be factored out in common?
+. GEM/shmem backed pages can have existing mappings (kernel linear map,
+  etc..), which isn't really ideal.
+. Revisit GEM sync object infrastructure.. TTM has some framework for this
+  already.  Possibly this could be refactored out and made more common?
+  There should be some way to do this with less wheel-reinvention.
+. Review DSS vs KMS mismatches.  The omap_dss_device is sort of part encoder,
+  part connector.  Which results in a bit of duct tape to fwd calls from
+  encoder to connector.  Possibly this could be done a bit better.
+. Solve PM sequencing on resume.  DMM/TILER must be reloaded before any
+  access is made from any component in the system.  Which means on suspend
+  CRTC's should be disabled, and on resume the LUT should be reprogrammed
+  before CRTC's are re-enabled, to prevent DSS from trying to DMA from a
+  buffer mapped in DMM/TILER before LUT is reloaded.
+. Add debugfs information for DMM/TILER
+
+Userspace:
+. git://github.com/robclark/xf86-video-omap.git
+
+Currently tested on
+. OMAP3530 beagleboard
+. OMAP4430 pandaboard
+. OMAP4460 pandaboard
diff --git a/drivers/staging/omapdrm/omap_connector.c b/drivers/staging/omapdrm/omap_connector.c
new file mode 100644
index 0000000..5e2856c
--- /dev/null
+++ b/drivers/staging/omapdrm/omap_connector.c
@@ -0,0 +1,371 @@
+/*
+ * drivers/staging/omapdrm/omap_connector.c
+ *
+ * Copyright (C) 2011 Texas Instruments
+ * Author: Rob Clark <rob@ti.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "omap_drv.h"
+
+#include "drm_crtc.h"
+#include "drm_crtc_helper.h"
+
+/*
+ * connector funcs
+ */
+
+#define to_omap_connector(x) container_of(x, struct omap_connector, base)
+
+struct omap_connector {
+	struct drm_connector base;
+	struct omap_dss_device *dssdev;
+};
+
+static inline void copy_timings_omap_to_drm(struct drm_display_mode *mode,
+		struct omap_video_timings *timings)
+{
+	mode->clock = timings->pixel_clock;
+
+	mode->hdisplay = timings->x_res;
+	mode->hsync_start = mode->hdisplay + timings->hfp;
+	mode->hsync_end = mode->hsync_start + timings->hsw;
+	mode->htotal = mode->hsync_end + timings->hbp;
+
+	mode->vdisplay = timings->y_res;
+	mode->vsync_start = mode->vdisplay + timings->vfp;
+	mode->vsync_end = mode->vsync_start + timings->vsw;
+	mode->vtotal = mode->vsync_end + timings->vbp;
+
+	/* note: whether or not it is interlaced, +/- h/vsync, etc,
+	 * which should be set in the mode flags, is not exposed in
+	 * the omap_video_timings struct.. but hdmi driver tracks
+	 * those separately so all we have to have to set the mode
+	 * is the way to recover these timings values, and the
+	 * omap_dss_driver would do the rest.
+	 */
+}
+
+static inline void copy_timings_drm_to_omap(struct omap_video_timings *timings,
+		struct drm_display_mode *mode)
+{
+	timings->pixel_clock = mode->clock;
+
+	timings->x_res = mode->hdisplay;
+	timings->hfp = mode->hsync_start - mode->hdisplay;
+	timings->hsw = mode->hsync_end - mode->hsync_start;
+	timings->hbp = mode->htotal - mode->hsync_end;
+
+	timings->y_res = mode->vdisplay;
+	timings->vfp = mode->vsync_start - mode->vdisplay;
+	timings->vsw = mode->vsync_end - mode->vsync_start;
+	timings->vbp = mode->vtotal - mode->vsync_end;
+}
+
+static void omap_connector_dpms(struct drm_connector *connector, int mode)
+{
+	struct omap_connector *omap_connector = to_omap_connector(connector);
+	struct omap_dss_device *dssdev = omap_connector->dssdev;
+	int old_dpms;
+
+	DBG("%s: %d", dssdev->name, mode);
+
+	old_dpms = connector->dpms;
+
+	/* from off to on, do from crtc to connector */
+	if (mode < old_dpms)
+		drm_helper_connector_dpms(connector, mode);
+
+	if (mode == DRM_MODE_DPMS_ON) {
+		/* store resume info for suspended displays */
+		switch (dssdev->state) {
+		case OMAP_DSS_DISPLAY_SUSPENDED:
+			dssdev->activate_after_resume = true;
+			break;
+		case OMAP_DSS_DISPLAY_DISABLED: {
+			int ret = dssdev->driver->enable(dssdev);
+			if (ret) {
+				DBG("%s: failed to enable: %d",
+						dssdev->name, ret);
+				dssdev->driver->disable(dssdev);
+			}
+			break;
+		}
+		default:
+			break;
+		}
+	} else {
+		/* TODO */
+	}
+
+	/* from on to off, do from connector to crtc */
+	if (mode > old_dpms)
+		drm_helper_connector_dpms(connector, mode);
+}
+
+enum drm_connector_status omap_connector_detect(
+		struct drm_connector *connector, bool force)
+{
+	struct omap_connector *omap_connector = to_omap_connector(connector);
+	struct omap_dss_device *dssdev = omap_connector->dssdev;
+	struct omap_dss_driver *dssdrv = dssdev->driver;
+	enum drm_connector_status ret;
+
+	if (dssdrv->detect) {
+		if (dssdrv->detect(dssdev)) {
+			ret = connector_status_connected;
+		} else {
+			ret = connector_status_disconnected;
+		}
+	} else {
+		ret = connector_status_unknown;
+	}
+
+	VERB("%s: %d (force=%d)", omap_connector->dssdev->name, ret, force);
+
+	return ret;
+}
+
+static void omap_connector_destroy(struct drm_connector *connector)
+{
+	struct omap_connector *omap_connector = to_omap_connector(connector);
+	struct omap_dss_device *dssdev = omap_connector->dssdev;
+
+	dssdev->driver->disable(dssdev);
+
+	DBG("%s", omap_connector->dssdev->name);
+	drm_sysfs_connector_remove(connector);
+	drm_connector_cleanup(connector);
+	kfree(omap_connector);
+
+	omap_dss_put_device(dssdev);
+}
+
+#define MAX_EDID  512
+
+static int omap_connector_get_modes(struct drm_connector *connector)
+{
+	struct omap_connector *omap_connector = to_omap_connector(connector);
+	struct omap_dss_device *dssdev = omap_connector->dssdev;
+	struct omap_dss_driver *dssdrv = dssdev->driver;
+	struct drm_device *dev = connector->dev;
+	int n = 0;
+
+	DBG("%s", omap_connector->dssdev->name);
+
+	/* if display exposes EDID, then we parse that in the normal way to
+	 * build table of supported modes.. otherwise (ie. fixed resolution
+	 * LCD panels) we just return a single mode corresponding to the
+	 * currently configured timings:
+	 */
+	if (dssdrv->read_edid) {
+		void *edid = kzalloc(MAX_EDID, GFP_KERNEL);
+
+		if ((dssdrv->read_edid(dssdev, edid, MAX_EDID) > 0) &&
+				drm_edid_is_valid(edid)) {
+			drm_mode_connector_update_edid_property(
+					connector, edid);
+			n = drm_add_edid_modes(connector, edid);
+			kfree(connector->display_info.raw_edid);
+			connector->display_info.raw_edid = edid;
+		} else {
+			drm_mode_connector_update_edid_property(
+					connector, NULL);
+			connector->display_info.raw_edid = NULL;
+			kfree(edid);
+		}
+	} else {
+		struct drm_display_mode *mode = drm_mode_create(dev);
+		struct omap_video_timings timings;
+
+		dssdrv->get_timings(dssdev, &timings);
+
+		copy_timings_omap_to_drm(mode, &timings);
+
+		mode->type = DRM_MODE_TYPE_DRIVER | DRM_MODE_TYPE_PREFERRED;
+		drm_mode_set_name(mode);
+		drm_mode_probed_add(connector, mode);
+
+		n = 1;
+	}
+
+	return n;
+}
+
+static int omap_connector_mode_valid(struct drm_connector *connector,
+				 struct drm_display_mode *mode)
+{
+	struct omap_connector *omap_connector = to_omap_connector(connector);
+	struct omap_dss_device *dssdev = omap_connector->dssdev;
+	struct omap_dss_driver *dssdrv = dssdev->driver;
+	struct omap_video_timings timings = {0};
+	struct drm_device *dev = connector->dev;
+	struct drm_display_mode *new_mode;
+	int ret = MODE_BAD;
+
+	copy_timings_drm_to_omap(&timings, mode);
+	mode->vrefresh = drm_mode_vrefresh(mode);
+
+	if (!dssdrv->check_timings(dssdev, &timings)) {
+		/* check if vrefresh is still valid */
+		new_mode = drm_mode_duplicate(dev, mode);
+		new_mode->clock = timings.pixel_clock;
+		new_mode->vrefresh = 0;
+		if (mode->vrefresh == drm_mode_vrefresh(new_mode))
+			ret = MODE_OK;
+		drm_mode_destroy(dev, new_mode);
+	}
+
+	DBG("connector: mode %s: "
+			"%d:\"%s\" %d %d %d %d %d %d %d %d %d %d 0x%x 0x%x",
+			(ret == MODE_OK) ? "valid" : "invalid",
+			mode->base.id, mode->name, mode->vrefresh, mode->clock,
+			mode->hdisplay, mode->hsync_start,
+			mode->hsync_end, mode->htotal,
+			mode->vdisplay, mode->vsync_start,
+			mode->vsync_end, mode->vtotal, mode->type, mode->flags);
+
+	return ret;
+}
+
+struct drm_encoder *omap_connector_attached_encoder(
+		struct drm_connector *connector)
+{
+	int i;
+	struct omap_connector *omap_connector = to_omap_connector(connector);
+
+	for (i = 0; i < DRM_CONNECTOR_MAX_ENCODER; i++) {
+		struct drm_mode_object *obj;
+
+		if (connector->encoder_ids[i] == 0)
+			break;
+
+		obj = drm_mode_object_find(connector->dev,
+				connector->encoder_ids[i],
+				DRM_MODE_OBJECT_ENCODER);
+
+		if (obj) {
+			struct drm_encoder *encoder = obj_to_encoder(obj);
+			struct omap_overlay_manager *mgr =
+					omap_encoder_get_manager(encoder);
+			DBG("%s: found %s", omap_connector->dssdev->name,
+					mgr->name);
+			return encoder;
+		}
+	}
+
+	DBG("%s: no encoder", omap_connector->dssdev->name);
+
+	return NULL;
+}
+
+static const struct drm_connector_funcs omap_connector_funcs = {
+	.dpms = omap_connector_dpms,
+	.detect = omap_connector_detect,
+	.fill_modes = drm_helper_probe_single_connector_modes,
+	.destroy = omap_connector_destroy,
+};
+
+static const struct drm_connector_helper_funcs omap_connector_helper_funcs = {
+	.get_modes = omap_connector_get_modes,
+	.mode_valid = omap_connector_mode_valid,
+	.best_encoder = omap_connector_attached_encoder,
+};
+
+/* called from encoder when mode is set, to propagate settings to the dssdev */
+void omap_connector_mode_set(struct drm_connector *connector,
+		struct drm_display_mode *mode)
+{
+	struct drm_device *dev = connector->dev;
+	struct omap_connector *omap_connector = to_omap_connector(connector);
+	struct omap_dss_device *dssdev = omap_connector->dssdev;
+	struct omap_dss_driver *dssdrv = dssdev->driver;
+	struct omap_video_timings timings;
+
+	copy_timings_drm_to_omap(&timings, mode);
+
+	DBG("%s: set mode: %d:\"%s\" %d %d %d %d %d %d %d %d %d %d 0x%x 0x%x",
+			omap_connector->dssdev->name,
+			mode->base.id, mode->name, mode->vrefresh, mode->clock,
+			mode->hdisplay, mode->hsync_start,
+			mode->hsync_end, mode->htotal,
+			mode->vdisplay, mode->vsync_start,
+			mode->vsync_end, mode->vtotal, mode->type, mode->flags);
+
+	if (dssdrv->check_timings(dssdev, &timings)) {
+		dev_err(dev->dev, "could not set timings\n");
+		return;
+	}
+
+	dssdrv->set_timings(dssdev, &timings);
+}
+
+/* flush an area of the framebuffer (in case of manual update display that
+ * is not automatically flushed)
+ */
+void omap_connector_flush(struct drm_connector *connector,
+		int x, int y, int w, int h)
+{
+	struct omap_connector *omap_connector = to_omap_connector(connector);
+
+	/* TODO: enable when supported in dss */
+	VERB("%s: %d,%d, %dx%d", omap_connector->dssdev->name, x, y, w, h);
+}
+
+/* initialize connector */
+struct drm_connector *omap_connector_init(struct drm_device *dev,
+		int connector_type, struct omap_dss_device *dssdev)
+{
+	struct drm_connector *connector = NULL;
+	struct omap_connector *omap_connector;
+
+	DBG("%s", dssdev->name);
+
+	omap_dss_get_device(dssdev);
+
+	omap_connector = kzalloc(sizeof(struct omap_connector), GFP_KERNEL);
+	if (!omap_connector) {
+		dev_err(dev->dev, "could not allocate connector\n");
+		goto fail;
+	}
+
+	omap_connector->dssdev = dssdev;
+	connector = &omap_connector->base;
+
+	drm_connector_init(dev, connector, &omap_connector_funcs,
+				connector_type);
+	drm_connector_helper_add(connector, &omap_connector_helper_funcs);
+
+#if 0 /* enable when dss2 supports hotplug */
+	if (dssdev->caps & OMAP_DSS_DISPLAY_CAP_HPD)
+		connector->polled = 0;
+	else
+#endif
+		connector->polled = DRM_CONNECTOR_POLL_CONNECT |
+				DRM_CONNECTOR_POLL_DISCONNECT;
+
+	connector->interlace_allowed = 1;
+	connector->doublescan_allowed = 0;
+
+	drm_sysfs_connector_add(connector);
+
+	return connector;
+
+fail:
+	if (connector) {
+		omap_connector_destroy(connector);
+	}
+
+	return NULL;
+}
diff --git a/drivers/staging/omapdrm/omap_crtc.c b/drivers/staging/omapdrm/omap_crtc.c
new file mode 100644
index 0000000..cffdf5e
--- /dev/null
+++ b/drivers/staging/omapdrm/omap_crtc.c
@@ -0,0 +1,326 @@
+/*
+ * drivers/staging/omapdrm/omap_crtc.c
+ *
+ * Copyright (C) 2011 Texas Instruments
+ * Author: Rob Clark <rob@ti.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "omap_drv.h"
+
+#include "drm_mode.h"
+#include "drm_crtc.h"
+#include "drm_crtc_helper.h"
+
+#define to_omap_crtc(x) container_of(x, struct omap_crtc, base)
+
+struct omap_crtc {
+	struct drm_crtc base;
+	struct omap_overlay *ovl;
+	struct omap_overlay_info info;
+	int id;
+
+	/* if there is a pending flip, this will be non-null: */
+	struct drm_pending_vblank_event *event;
+};
+
+/* push changes down to dss2 */
+static int commit(struct drm_crtc *crtc)
+{
+	struct drm_device *dev = crtc->dev;
+	struct omap_crtc *omap_crtc = to_omap_crtc(crtc);
+	struct omap_overlay *ovl = omap_crtc->ovl;
+	struct omap_overlay_info *info = &omap_crtc->info;
+	int ret;
+
+	DBG("%s", omap_crtc->ovl->name);
+	DBG("%dx%d -> %dx%d (%d)", info->width, info->height, info->out_width,
+			info->out_height, info->screen_width);
+	DBG("%d,%d %08x", info->pos_x, info->pos_y, info->paddr);
+
+	/* NOTE: do we want to do this at all here, or just wait
+	 * for dpms(ON) since other CRTC's may not have their mode
+	 * set yet, so fb dimensions may still change..
+	 */
+	ret = ovl->set_overlay_info(ovl, info);
+	if (ret) {
+		dev_err(dev->dev, "could not set overlay info\n");
+		return ret;
+	}
+
+	/* our encoder doesn't necessarily get a commit() after this, in
+	 * particular in the dpms() and mode_set_base() cases, so force the
+	 * manager to update:
+	 *
+	 * could this be in the encoder somehow?
+	 */
+	if (ovl->manager) {
+		ret = ovl->manager->apply(ovl->manager);
+		if (ret) {
+			dev_err(dev->dev, "could not apply settings\n");
+			return ret;
+		}
+	}
+
+	if (info->enabled) {
+		omap_framebuffer_flush(crtc->fb, crtc->x, crtc->y,
+				crtc->fb->width, crtc->fb->height);
+	}
+
+	return 0;
+}
+
+/* update parameters that are dependent on the framebuffer dimensions and
+ * position within the fb that this crtc scans out from. This is called
+ * when framebuffer dimensions or x,y base may have changed, either due
+ * to our mode, or a change in another crtc that is scanning out of the
+ * same fb.
+ */
+static void update_scanout(struct drm_crtc *crtc)
+{
+	struct omap_crtc *omap_crtc = to_omap_crtc(crtc);
+	dma_addr_t paddr;
+	unsigned int screen_width;
+
+	omap_framebuffer_get_buffer(crtc->fb, crtc->x, crtc->y,
+			NULL, &paddr, &screen_width);
+
+	DBG("%s: %d,%d: %08x (%d)", omap_crtc->ovl->name,
+			crtc->x, crtc->y, (u32)paddr, screen_width);
+
+	omap_crtc->info.paddr = paddr;
+	omap_crtc->info.screen_width = screen_width;
+}
+
+static void omap_crtc_gamma_set(struct drm_crtc *crtc,
+		u16 *red, u16 *green, u16 *blue, uint32_t start, uint32_t size)
+{
+	struct omap_crtc *omap_crtc = to_omap_crtc(crtc);
+	DBG("%s", omap_crtc->ovl->name);
+}
+
+static void omap_crtc_destroy(struct drm_crtc *crtc)
+{
+	struct omap_crtc *omap_crtc = to_omap_crtc(crtc);
+	DBG("%s", omap_crtc->ovl->name);
+	drm_crtc_cleanup(crtc);
+	kfree(omap_crtc);
+}
+
+static void omap_crtc_dpms(struct drm_crtc *crtc, int mode)
+{
+	struct omap_crtc *omap_crtc = to_omap_crtc(crtc);
+
+	DBG("%s: %d", omap_crtc->ovl->name, mode);
+
+	if (mode == DRM_MODE_DPMS_ON) {
+		update_scanout(crtc);
+		omap_crtc->info.enabled = true;
+	} else {
+		omap_crtc->info.enabled = false;
+	}
+
+	WARN_ON(commit(crtc));
+}
+
+static bool omap_crtc_mode_fixup(struct drm_crtc *crtc,
+				  struct drm_display_mode *mode,
+				  struct drm_display_mode *adjusted_mode)
+{
+	struct omap_crtc *omap_crtc = to_omap_crtc(crtc);
+	DBG("%s", omap_crtc->ovl->name);
+	return true;
+}
+
+static int omap_crtc_mode_set(struct drm_crtc *crtc,
+			       struct drm_display_mode *mode,
+			       struct drm_display_mode *adjusted_mode,
+			       int x, int y,
+			       struct drm_framebuffer *old_fb)
+{
+	struct omap_crtc *omap_crtc = to_omap_crtc(crtc);
+
+	DBG("%s: %d,%d: %dx%d", omap_crtc->ovl->name, x, y,
+			mode->hdisplay, mode->vdisplay);
+
+	/* just use adjusted mode */
+	mode = adjusted_mode;
+
+	omap_crtc->info.width = mode->hdisplay;
+	omap_crtc->info.height = mode->vdisplay;
+	omap_crtc->info.out_width = mode->hdisplay;
+	omap_crtc->info.out_height = mode->vdisplay;
+	omap_crtc->info.color_mode = OMAP_DSS_COLOR_RGB24U;
+	omap_crtc->info.rotation_type = OMAP_DSS_ROT_DMA;
+	omap_crtc->info.rotation = OMAP_DSS_ROT_0;
+	omap_crtc->info.global_alpha = 0xff;
+	omap_crtc->info.mirror = 0;
+	omap_crtc->info.mirror = 0;
+	omap_crtc->info.pos_x = 0;
+	omap_crtc->info.pos_y = 0;
+#if 0 /* re-enable when these are available in DSS2 driver */
+	omap_crtc->info.zorder = 3;        /* GUI in the front, video behind */
+	omap_crtc->info.min_x_decim = 1;
+	omap_crtc->info.max_x_decim = 1;
+	omap_crtc->info.min_y_decim = 1;
+	omap_crtc->info.max_y_decim = 1;
+#endif
+
+	update_scanout(crtc);
+
+	return 0;
+}
+
+static void omap_crtc_prepare(struct drm_crtc *crtc)
+{
+	struct omap_crtc *omap_crtc = to_omap_crtc(crtc);
+	struct omap_overlay *ovl = omap_crtc->ovl;
+
+	DBG("%s", omap_crtc->ovl->name);
+
+	ovl->get_overlay_info(ovl, &omap_crtc->info);
+
+	omap_crtc_dpms(crtc, DRM_MODE_DPMS_OFF);
+}
+
+static void omap_crtc_commit(struct drm_crtc *crtc)
+{
+	struct omap_crtc *omap_crtc = to_omap_crtc(crtc);
+	DBG("%s", omap_crtc->ovl->name);
+	omap_crtc_dpms(crtc, DRM_MODE_DPMS_ON);
+}
+
+static int omap_crtc_mode_set_base(struct drm_crtc *crtc, int x, int y,
+		    struct drm_framebuffer *old_fb)
+{
+	struct omap_crtc *omap_crtc = to_omap_crtc(crtc);
+
+	DBG("%s %d,%d: fb=%p", omap_crtc->ovl->name, x, y, old_fb);
+
+	update_scanout(crtc);
+
+	return commit(crtc);
+}
+
+static void omap_crtc_load_lut(struct drm_crtc *crtc)
+{
+	struct omap_crtc *omap_crtc = to_omap_crtc(crtc);
+	DBG("%s", omap_crtc->ovl->name);
+}
+
+static void page_flip_cb(void *arg)
+{
+	struct drm_crtc *crtc = arg;
+	struct drm_device *dev = crtc->dev;
+	struct omap_crtc *omap_crtc = to_omap_crtc(crtc);
+	struct drm_pending_vblank_event *event = omap_crtc->event;
+	struct timeval now;
+	unsigned long flags;
+
+	WARN_ON(!event);
+
+	omap_crtc->event = NULL;
+
+	update_scanout(crtc);
+	WARN_ON(commit(crtc));
+
+	/* wakeup userspace */
+	/* TODO: this should happen *after* flip in vsync IRQ handler */
+	if (event) {
+		spin_lock_irqsave(&dev->event_lock, flags);
+		event->event.sequence = drm_vblank_count_and_time(
+				dev, omap_crtc->id, &now);
+		event->event.tv_sec = now.tv_sec;
+		event->event.tv_usec = now.tv_usec;
+		list_add_tail(&event->base.link,
+				&event->base.file_priv->event_list);
+		wake_up_interruptible(&event->base.file_priv->event_wait);
+		spin_unlock_irqrestore(&dev->event_lock, flags);
+	}
+}
+
+static int omap_crtc_page_flip_locked(struct drm_crtc *crtc,
+		 struct drm_framebuffer *fb,
+		 struct drm_pending_vblank_event *event)
+{
+	struct drm_device *dev = crtc->dev;
+	struct omap_crtc *omap_crtc = to_omap_crtc(crtc);
+
+	DBG("%d -> %d", crtc->fb ? crtc->fb->base.id : -1, fb->base.id);
+
+	if (omap_crtc->event) {
+		dev_err(dev->dev, "already a pending flip\n");
+		return -EINVAL;
+	}
+
+	crtc->fb = fb;
+	omap_crtc->event = event;
+
+	omap_gem_op_async(omap_framebuffer_bo(fb), OMAP_GEM_READ,
+			page_flip_cb, crtc);
+
+	return 0;
+}
+
+static const struct drm_crtc_funcs omap_crtc_funcs = {
+	.gamma_set = omap_crtc_gamma_set,
+	.set_config = drm_crtc_helper_set_config,
+	.destroy = omap_crtc_destroy,
+	.page_flip = omap_crtc_page_flip_locked,
+};
+
+static const struct drm_crtc_helper_funcs omap_crtc_helper_funcs = {
+	.dpms = omap_crtc_dpms,
+	.mode_fixup = omap_crtc_mode_fixup,
+	.mode_set = omap_crtc_mode_set,
+	.prepare = omap_crtc_prepare,
+	.commit = omap_crtc_commit,
+	.mode_set_base = omap_crtc_mode_set_base,
+	.load_lut = omap_crtc_load_lut,
+};
+
+struct omap_overlay *omap_crtc_get_overlay(struct drm_crtc *crtc)
+{
+	struct omap_crtc *omap_crtc = to_omap_crtc(crtc);
+	return omap_crtc->ovl;
+}
+
+/* initialize crtc */
+struct drm_crtc *omap_crtc_init(struct drm_device *dev,
+		struct omap_overlay *ovl, int id)
+{
+	struct drm_crtc *crtc = NULL;
+	struct omap_crtc *omap_crtc = kzalloc(sizeof(*omap_crtc), GFP_KERNEL);
+
+	DBG("%s", ovl->name);
+
+	if (!omap_crtc) {
+		dev_err(dev->dev, "could not allocate CRTC\n");
+		goto fail;
+	}
+
+	omap_crtc->ovl = ovl;
+	omap_crtc->id = id;
+	crtc = &omap_crtc->base;
+	drm_crtc_init(dev, crtc, &omap_crtc_funcs);
+	drm_crtc_helper_add(crtc, &omap_crtc_helper_funcs);
+
+	return crtc;
+
+fail:
+	if (crtc) {
+		omap_crtc_destroy(crtc);
+	}
+	return NULL;
+}
diff --git a/drivers/staging/omapdrm/omap_debugfs.c b/drivers/staging/omapdrm/omap_debugfs.c
new file mode 100644
index 0000000..da920df
--- /dev/null
+++ b/drivers/staging/omapdrm/omap_debugfs.c
@@ -0,0 +1,42 @@
+/*
+ * drivers/staging/omapdrm/omap_debugfs.c
+ *
+ * Copyright (C) 2011 Texas Instruments
+ * Author: Rob Clark <rob.clark@linaro.org>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "omap_drv.h"
+#include "omap_dmm_tiler.h"
+
+#ifdef CONFIG_DEBUG_FS
+
+static struct drm_info_list omap_debugfs_list[] = {
+	{"tiler_map", tiler_map_show, 0},
+};
+
+int omap_debugfs_init(struct drm_minor *minor)
+{
+	return drm_debugfs_create_files(omap_debugfs_list,
+			ARRAY_SIZE(omap_debugfs_list),
+			minor->debugfs_root, minor);
+}
+
+void omap_debugfs_cleanup(struct drm_minor *minor)
+{
+	drm_debugfs_remove_files(omap_debugfs_list,
+			ARRAY_SIZE(omap_debugfs_list), minor);
+}
+
+#endif
diff --git a/drivers/staging/omapdrm/omap_dmm_priv.h b/drivers/staging/omapdrm/omap_dmm_priv.h
new file mode 100644
index 0000000..2f529ab
--- /dev/null
+++ b/drivers/staging/omapdrm/omap_dmm_priv.h
@@ -0,0 +1,187 @@
+/*
+ *
+ * Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/
+ * Author: Rob Clark <rob@ti.com>
+ *         Andy Gross <andy.gross@ti.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation version 2.
+ *
+ * This program is distributed "as is" WITHOUT ANY WARRANTY of any
+ * kind, whether express or implied; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+#ifndef OMAP_DMM_PRIV_H
+#define OMAP_DMM_PRIV_H
+
+#define DMM_REVISION          0x000
+#define DMM_HWINFO            0x004
+#define DMM_LISA_HWINFO       0x008
+#define DMM_DMM_SYSCONFIG     0x010
+#define DMM_LISA_LOCK         0x01C
+#define DMM_LISA_MAP__0       0x040
+#define DMM_LISA_MAP__1       0x044
+#define DMM_TILER_HWINFO      0x208
+#define DMM_TILER_OR__0       0x220
+#define DMM_TILER_OR__1       0x224
+#define DMM_PAT_HWINFO        0x408
+#define DMM_PAT_GEOMETRY      0x40C
+#define DMM_PAT_CONFIG        0x410
+#define DMM_PAT_VIEW__0       0x420
+#define DMM_PAT_VIEW__1       0x424
+#define DMM_PAT_VIEW_MAP__0   0x440
+#define DMM_PAT_VIEW_MAP_BASE 0x460
+#define DMM_PAT_IRQ_EOI       0x478
+#define DMM_PAT_IRQSTATUS_RAW 0x480
+#define DMM_PAT_IRQSTATUS     0x490
+#define DMM_PAT_IRQENABLE_SET 0x4A0
+#define DMM_PAT_IRQENABLE_CLR 0x4B0
+#define DMM_PAT_STATUS__0     0x4C0
+#define DMM_PAT_STATUS__1     0x4C4
+#define DMM_PAT_STATUS__2     0x4C8
+#define DMM_PAT_STATUS__3     0x4CC
+#define DMM_PAT_DESCR__0      0x500
+#define DMM_PAT_DESCR__1      0x510
+#define DMM_PAT_DESCR__2      0x520
+#define DMM_PAT_DESCR__3      0x530
+#define DMM_PEG_HWINFO        0x608
+#define DMM_PEG_PRIO          0x620
+#define DMM_PEG_PRIO_PAT      0x640
+
+#define DMM_IRQSTAT_DST			(1<<0)
+#define DMM_IRQSTAT_LST			(1<<1)
+#define DMM_IRQSTAT_ERR_INV_DSC		(1<<2)
+#define DMM_IRQSTAT_ERR_INV_DATA	(1<<3)
+#define DMM_IRQSTAT_ERR_UPD_AREA	(1<<4)
+#define DMM_IRQSTAT_ERR_UPD_CTRL	(1<<5)
+#define DMM_IRQSTAT_ERR_UPD_DATA	(1<<6)
+#define DMM_IRQSTAT_ERR_LUT_MISS	(1<<7)
+
+#define DMM_IRQSTAT_ERR_MASK	(DMM_IRQ_STAT_ERR_INV_DSC | \
+				DMM_IRQ_STAT_ERR_INV_DATA | \
+				DMM_IRQ_STAT_ERR_UPD_AREA | \
+				DMM_IRQ_STAT_ERR_UPD_CTRL | \
+				DMM_IRQ_STAT_ERR_UPD_DATA | \
+				DMM_IRQ_STAT_ERR_LUT_MISS)
+
+#define DMM_PATSTATUS_READY		(1<<0)
+#define DMM_PATSTATUS_VALID		(1<<1)
+#define DMM_PATSTATUS_RUN		(1<<2)
+#define DMM_PATSTATUS_DONE		(1<<3)
+#define DMM_PATSTATUS_LINKED		(1<<4)
+#define DMM_PATSTATUS_BYPASSED		(1<<7)
+#define DMM_PATSTATUS_ERR_INV_DESCR	(1<<10)
+#define DMM_PATSTATUS_ERR_INV_DATA	(1<<11)
+#define DMM_PATSTATUS_ERR_UPD_AREA	(1<<12)
+#define DMM_PATSTATUS_ERR_UPD_CTRL	(1<<13)
+#define DMM_PATSTATUS_ERR_UPD_DATA	(1<<14)
+#define DMM_PATSTATUS_ERR_ACCESS	(1<<15)
+
+/* note: don't treat DMM_PATSTATUS_ERR_ACCESS as an error */
+#define DMM_PATSTATUS_ERR	(DMM_PATSTATUS_ERR_INV_DESCR | \
+				DMM_PATSTATUS_ERR_INV_DATA | \
+				DMM_PATSTATUS_ERR_UPD_AREA | \
+				DMM_PATSTATUS_ERR_UPD_CTRL | \
+				DMM_PATSTATUS_ERR_UPD_DATA)
+
+
+
+enum {
+	PAT_STATUS,
+	PAT_DESCR
+};
+
+struct pat_ctrl {
+	u32 start:4;
+	u32 dir:4;
+	u32 lut_id:8;
+	u32 sync:12;
+	u32 ini:4;
+};
+
+struct pat {
+	uint32_t next_pa;
+	struct pat_area area;
+	struct pat_ctrl ctrl;
+	uint32_t data_pa;
+};
+
+#define DMM_FIXED_RETRY_COUNT 1000
+
+/* create refill buffer big enough to refill all slots, plus 3 descriptors..
+ * 3 descriptors is probably the worst-case for # of 2d-slices in a 1d area,
+ * but I guess you don't hit that worst case at the same time as full area
+ * refill
+ */
+#define DESCR_SIZE 128
+#define REFILL_BUFFER_SIZE ((4 * 128 * 256) + (3 * DESCR_SIZE))
+
+struct dmm;
+
+struct dmm_txn {
+	void *engine_handle;
+	struct tcm *tcm;
+
+	uint8_t *current_va;
+	dma_addr_t current_pa;
+
+	struct pat *last_pat;
+};
+
+struct refill_engine {
+	int id;
+	struct dmm *dmm;
+	struct tcm *tcm;
+
+	uint8_t *refill_va;
+	dma_addr_t refill_pa;
+
+	/* only one trans per engine for now */
+	struct dmm_txn txn;
+
+	/* offset to lut associated with container */
+	u32 *lut_offset;
+
+	wait_queue_head_t wait_for_refill;
+
+	struct list_head idle_node;
+};
+
+struct dmm {
+	struct device *dev;
+	void __iomem *base;
+	int irq;
+
+	struct page *dummy_page;
+	dma_addr_t dummy_pa;
+
+	void *refill_va;
+	dma_addr_t refill_pa;
+
+	/* refill engines */
+	struct semaphore engine_sem;
+	struct list_head idle_head;
+	struct refill_engine *engines;
+	int num_engines;
+
+	/* container information */
+	int container_width;
+	int container_height;
+	int lut_width;
+	int lut_height;
+	int num_lut;
+
+	/* array of LUT - TCM containers */
+	struct tcm **tcm;
+
+	/* LUT table storage */
+	u32 *lut;
+
+	/* allocation list and lock */
+	struct list_head alloc_head;
+	spinlock_t list_lock;
+};
+
+#endif
diff --git a/drivers/staging/omapdrm/omap_dmm_tiler.c b/drivers/staging/omapdrm/omap_dmm_tiler.c
new file mode 100644
index 0000000..852d944
--- /dev/null
+++ b/drivers/staging/omapdrm/omap_dmm_tiler.c
@@ -0,0 +1,830 @@
+/*
+ * DMM IOMMU driver support functions for TI OMAP processors.
+ *
+ * Author: Rob Clark <rob@ti.com>
+ *         Andy Gross <andy.gross@ti.com>
+ *
+ * Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation version 2.
+ *
+ * This program is distributed "as is" WITHOUT ANY WARRANTY of any
+ * kind, whether express or implied; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/platform_device.h> /* platform_device() */
+#include <linux/errno.h>
+#include <linux/sched.h>
+#include <linux/wait.h>
+#include <linux/interrupt.h>
+#include <linux/dma-mapping.h>
+#include <linux/slab.h>
+#include <linux/vmalloc.h>
+#include <linux/delay.h>
+#include <linux/mm.h>
+#include <linux/time.h>
+#include <linux/list.h>
+#include <linux/semaphore.h>
+
+#include "omap_dmm_tiler.h"
+#include "omap_dmm_priv.h"
+
+/* mappings for associating views to luts */
+static struct tcm *containers[TILFMT_NFORMATS];
+static struct dmm *omap_dmm;
+
+/* Geometry table */
+#define GEOM(xshift, yshift, bytes_per_pixel) { \
+		.x_shft = (xshift), \
+		.y_shft = (yshift), \
+		.cpp    = (bytes_per_pixel), \
+		.slot_w = 1 << (SLOT_WIDTH_BITS - (xshift)), \
+		.slot_h = 1 << (SLOT_HEIGHT_BITS - (yshift)), \
+	}
+
+static const struct {
+	uint32_t x_shft;	/* unused X-bits (as part of bpp) */
+	uint32_t y_shft;	/* unused Y-bits (as part of bpp) */
+	uint32_t cpp;		/* bytes/chars per pixel */
+	uint32_t slot_w;	/* width of each slot (in pixels) */
+	uint32_t slot_h;	/* height of each slot (in pixels) */
+} geom[TILFMT_NFORMATS] = {
+		[TILFMT_8BIT]  = GEOM(0, 0, 1),
+		[TILFMT_16BIT] = GEOM(0, 1, 2),
+		[TILFMT_32BIT] = GEOM(1, 1, 4),
+		[TILFMT_PAGE]  = GEOM(SLOT_WIDTH_BITS, SLOT_HEIGHT_BITS, 1),
+};
+
+
+/* lookup table for registers w/ per-engine instances */
+static const uint32_t reg[][4] = {
+		[PAT_STATUS] = {DMM_PAT_STATUS__0, DMM_PAT_STATUS__1,
+				DMM_PAT_STATUS__2, DMM_PAT_STATUS__3},
+		[PAT_DESCR]  = {DMM_PAT_DESCR__0, DMM_PAT_DESCR__1,
+				DMM_PAT_DESCR__2, DMM_PAT_DESCR__3},
+};
+
+/* simple allocator to grab next 16 byte aligned memory from txn */
+static void *alloc_dma(struct dmm_txn *txn, size_t sz, dma_addr_t *pa)
+{
+	void *ptr;
+	struct refill_engine *engine = txn->engine_handle;
+
+	/* dmm programming requires 16 byte aligned addresses */
+	txn->current_pa = round_up(txn->current_pa, 16);
+	txn->current_va = (void *)round_up((long)txn->current_va, 16);
+
+	ptr = txn->current_va;
+	*pa = txn->current_pa;
+
+	txn->current_pa += sz;
+	txn->current_va += sz;
+
+	BUG_ON((txn->current_va - engine->refill_va) > REFILL_BUFFER_SIZE);
+
+	return ptr;
+}
+
+/* check status and spin until wait_mask comes true */
+static int wait_status(struct refill_engine *engine, uint32_t wait_mask)
+{
+	struct dmm *dmm = engine->dmm;
+	uint32_t r = 0, err, i;
+
+	i = DMM_FIXED_RETRY_COUNT;
+	while (true) {
+		r = readl(dmm->base + reg[PAT_STATUS][engine->id]);
+		err = r & DMM_PATSTATUS_ERR;
+		if (err)
+			return -EFAULT;
+
+		if ((r & wait_mask) == wait_mask)
+			break;
+
+		if (--i == 0)
+			return -ETIMEDOUT;
+
+		udelay(1);
+	}
+
+	return 0;
+}
+
+irqreturn_t omap_dmm_irq_handler(int irq, void *arg)
+{
+	struct dmm *dmm = arg;
+	uint32_t status = readl(dmm->base + DMM_PAT_IRQSTATUS);
+	int i;
+
+	/* ack IRQ */
+	writel(status, dmm->base + DMM_PAT_IRQSTATUS);
+
+	for (i = 0; i < dmm->num_engines; i++) {
+		if (status & DMM_IRQSTAT_LST)
+			wake_up_interruptible(&dmm->engines[i].wait_for_refill);
+
+		status >>= 8;
+	}
+
+	return IRQ_HANDLED;
+}
+
+/**
+ * Get a handle for a DMM transaction
+ */
+static struct dmm_txn *dmm_txn_init(struct dmm *dmm, struct tcm *tcm)
+{
+	struct dmm_txn *txn = NULL;
+	struct refill_engine *engine = NULL;
+
+	down(&dmm->engine_sem);
+
+	/* grab an idle engine */
+	spin_lock(&dmm->list_lock);
+	if (!list_empty(&dmm->idle_head)) {
+		engine = list_entry(dmm->idle_head.next, struct refill_engine,
+					idle_node);
+		list_del(&engine->idle_node);
+	}
+	spin_unlock(&dmm->list_lock);
+
+	BUG_ON(!engine);
+
+	txn = &engine->txn;
+	engine->tcm = tcm;
+	txn->engine_handle = engine;
+	txn->last_pat = NULL;
+	txn->current_va = engine->refill_va;
+	txn->current_pa = engine->refill_pa;
+
+	return txn;
+}
+
+/**
+ * Add region to DMM transaction.  If pages or pages[i] is NULL, then the
+ * corresponding slot is cleared (ie. dummy_pa is programmed)
+ */
+static int dmm_txn_append(struct dmm_txn *txn, struct pat_area *area,
+		struct page **pages, uint32_t npages, uint32_t roll)
+{
+	dma_addr_t pat_pa = 0;
+	uint32_t *data;
+	struct pat *pat;
+	struct refill_engine *engine = txn->engine_handle;
+	int columns = (1 + area->x1 - area->x0);
+	int rows = (1 + area->y1 - area->y0);
+	int i = columns*rows;
+	u32 *lut = omap_dmm->lut + (engine->tcm->lut_id * omap_dmm->lut_width *
+			omap_dmm->lut_height) +
+			(area->y0 * omap_dmm->lut_width) + area->x0;
+
+	pat = alloc_dma(txn, sizeof(struct pat), &pat_pa);
+
+	if (txn->last_pat)
+		txn->last_pat->next_pa = (uint32_t)pat_pa;
+
+	pat->area = *area;
+	pat->ctrl = (struct pat_ctrl){
+			.start = 1,
+			.lut_id = engine->tcm->lut_id,
+		};
+
+	data = alloc_dma(txn, 4*i, &pat->data_pa);
+
+	while (i--) {
+		int n = i + roll;
+		if (n >= npages)
+			n -= npages;
+		data[i] = (pages && pages[n]) ?
+			page_to_phys(pages[n]) : engine->dmm->dummy_pa;
+	}
+
+	/* fill in lut with new addresses */
+	for (i = 0; i < rows; i++, lut += omap_dmm->lut_width)
+		memcpy(lut, &data[i*columns], columns * sizeof(u32));
+
+	txn->last_pat = pat;
+
+	return 0;
+}
+
+/**
+ * Commit the DMM transaction.
+ */
+static int dmm_txn_commit(struct dmm_txn *txn, bool wait)
+{
+	int ret = 0;
+	struct refill_engine *engine = txn->engine_handle;
+	struct dmm *dmm = engine->dmm;
+
+	if (!txn->last_pat) {
+		dev_err(engine->dmm->dev, "need at least one txn\n");
+		ret = -EINVAL;
+		goto cleanup;
+	}
+
+	txn->last_pat->next_pa = 0;
+
+	/* write to PAT_DESCR to clear out any pending transaction */
+	writel(0x0, dmm->base + reg[PAT_DESCR][engine->id]);
+
+	/* wait for engine ready: */
+	ret = wait_status(engine, DMM_PATSTATUS_READY);
+	if (ret) {
+		ret = -EFAULT;
+		goto cleanup;
+	}
+
+	/* kick reload */
+	writel(engine->refill_pa,
+		dmm->base + reg[PAT_DESCR][engine->id]);
+
+	if (wait) {
+		if (wait_event_interruptible_timeout(engine->wait_for_refill,
+				wait_status(engine, DMM_PATSTATUS_READY) == 0,
+				msecs_to_jiffies(1)) <= 0) {
+			dev_err(dmm->dev, "timed out waiting for done\n");
+			ret = -ETIMEDOUT;
+		}
+	}
+
+cleanup:
+	spin_lock(&dmm->list_lock);
+	list_add(&engine->idle_node, &dmm->idle_head);
+	spin_unlock(&dmm->list_lock);
+
+	up(&omap_dmm->engine_sem);
+	return ret;
+}
+
+/*
+ * DMM programming
+ */
+static int fill(struct tcm_area *area, struct page **pages,
+		uint32_t npages, uint32_t roll, bool wait)
+{
+	int ret = 0;
+	struct tcm_area slice, area_s;
+	struct dmm_txn *txn;
+
+	txn = dmm_txn_init(omap_dmm, area->tcm);
+	if (IS_ERR_OR_NULL(txn))
+		return PTR_ERR(txn);
+
+	tcm_for_each_slice(slice, *area, area_s) {
+		struct pat_area p_area = {
+				.x0 = slice.p0.x,  .y0 = slice.p0.y,
+				.x1 = slice.p1.x,  .y1 = slice.p1.y,
+		};
+
+		ret = dmm_txn_append(txn, &p_area, pages, npages, roll);
+		if (ret)
+			goto fail;
+
+		roll += tcm_sizeof(slice);
+	}
+
+	ret = dmm_txn_commit(txn, wait);
+
+fail:
+	return ret;
+}
+
+/*
+ * Pin/unpin
+ */
+
+/* note: slots for which pages[i] == NULL are filled w/ dummy page
+ */
+int tiler_pin(struct tiler_block *block, struct page **pages,
+		uint32_t npages, uint32_t roll, bool wait)
+{
+	int ret;
+
+	ret = fill(&block->area, pages, npages, roll, wait);
+
+	if (ret)
+		tiler_unpin(block);
+
+	return ret;
+}
+
+int tiler_unpin(struct tiler_block *block)
+{
+	return fill(&block->area, NULL, 0, 0, false);
+}
+
+/*
+ * Reserve/release
+ */
+struct tiler_block *tiler_reserve_2d(enum tiler_fmt fmt, uint16_t w,
+		uint16_t h, uint16_t align)
+{
+	struct tiler_block *block = kzalloc(sizeof(*block), GFP_KERNEL);
+	u32 min_align = 128;
+	int ret;
+
+	BUG_ON(!validfmt(fmt));
+
+	/* convert width/height to slots */
+	w = DIV_ROUND_UP(w, geom[fmt].slot_w);
+	h = DIV_ROUND_UP(h, geom[fmt].slot_h);
+
+	/* convert alignment to slots */
+	min_align = max(min_align, (geom[fmt].slot_w * geom[fmt].cpp));
+	align = ALIGN(align, min_align);
+	align /= geom[fmt].slot_w * geom[fmt].cpp;
+
+	block->fmt = fmt;
+
+	ret = tcm_reserve_2d(containers[fmt], w, h, align, &block->area);
+	if (ret) {
+		kfree(block);
+		return 0;
+	}
+
+	/* add to allocation list */
+	spin_lock(&omap_dmm->list_lock);
+	list_add(&block->alloc_node, &omap_dmm->alloc_head);
+	spin_unlock(&omap_dmm->list_lock);
+
+	return block;
+}
+
+struct tiler_block *tiler_reserve_1d(size_t size)
+{
+	struct tiler_block *block = kzalloc(sizeof(*block), GFP_KERNEL);
+	int num_pages = (size + PAGE_SIZE - 1) >> PAGE_SHIFT;
+
+	if (!block)
+		return 0;
+
+	block->fmt = TILFMT_PAGE;
+
+	if (tcm_reserve_1d(containers[TILFMT_PAGE], num_pages,
+				&block->area)) {
+		kfree(block);
+		return 0;
+	}
+
+	spin_lock(&omap_dmm->list_lock);
+	list_add(&block->alloc_node, &omap_dmm->alloc_head);
+	spin_unlock(&omap_dmm->list_lock);
+
+	return block;
+}
+
+/* note: if you have pin'd pages, you should have already unpin'd first! */
+int tiler_release(struct tiler_block *block)
+{
+	int ret = tcm_free(&block->area);
+
+	if (block->area.tcm)
+		dev_err(omap_dmm->dev, "failed to release block\n");
+
+	spin_lock(&omap_dmm->list_lock);
+	list_del(&block->alloc_node);
+	spin_unlock(&omap_dmm->list_lock);
+
+	kfree(block);
+	return ret;
+}
+
+/*
+ * Utils
+ */
+
+/* calculate the tiler space address of a pixel in a view orientation */
+static u32 tiler_get_address(u32 orient, enum tiler_fmt fmt, u32 x, u32 y)
+{
+	u32 x_bits, y_bits, tmp, x_mask, y_mask, alignment;
+
+	x_bits = CONT_WIDTH_BITS - geom[fmt].x_shft;
+	y_bits = CONT_HEIGHT_BITS - geom[fmt].y_shft;
+	alignment = geom[fmt].x_shft + geom[fmt].y_shft;
+
+	/* validate coordinate */
+	x_mask = MASK(x_bits);
+	y_mask = MASK(y_bits);
+
+	if (x < 0 || x > x_mask || y < 0 || y > y_mask)
+		return 0;
+
+	/* account for mirroring */
+	if (orient & MASK_X_INVERT)
+		x ^= x_mask;
+	if (orient & MASK_Y_INVERT)
+		y ^= y_mask;
+
+	/* get coordinate address */
+	if (orient & MASK_XY_FLIP)
+		tmp = ((x << y_bits) + y);
+	else
+		tmp = ((y << x_bits) + x);
+
+	return TIL_ADDR((tmp << alignment), orient, fmt);
+}
+
+dma_addr_t tiler_ssptr(struct tiler_block *block)
+{
+	BUG_ON(!validfmt(block->fmt));
+
+	return TILVIEW_8BIT + tiler_get_address(0, block->fmt,
+			block->area.p0.x * geom[block->fmt].slot_w,
+			block->area.p0.y * geom[block->fmt].slot_h);
+}
+
+void tiler_align(enum tiler_fmt fmt, uint16_t *w, uint16_t *h)
+{
+	BUG_ON(!validfmt(fmt));
+	*w = round_up(*w, geom[fmt].slot_w);
+	*h = round_up(*h, geom[fmt].slot_h);
+}
+
+uint32_t tiler_stride(enum tiler_fmt fmt)
+{
+	BUG_ON(!validfmt(fmt));
+
+	return 1 << (CONT_WIDTH_BITS + geom[fmt].y_shft);
+}
+
+size_t tiler_size(enum tiler_fmt fmt, uint16_t w, uint16_t h)
+{
+	tiler_align(fmt, &w, &h);
+	return geom[fmt].cpp * w * h;
+}
+
+size_t tiler_vsize(enum tiler_fmt fmt, uint16_t w, uint16_t h)
+{
+	BUG_ON(!validfmt(fmt));
+	return round_up(geom[fmt].cpp * w, PAGE_SIZE) * h;
+}
+
+int omap_dmm_remove(void)
+{
+	struct tiler_block *block, *_block;
+	int i;
+
+	if (omap_dmm) {
+		/* free all area regions */
+		spin_lock(&omap_dmm->list_lock);
+		list_for_each_entry_safe(block, _block, &omap_dmm->alloc_head,
+					alloc_node) {
+			list_del(&block->alloc_node);
+			kfree(block);
+		}
+		spin_unlock(&omap_dmm->list_lock);
+
+		for (i = 0; i < omap_dmm->num_lut; i++)
+			if (omap_dmm->tcm && omap_dmm->tcm[i])
+				omap_dmm->tcm[i]->deinit(omap_dmm->tcm[i]);
+		kfree(omap_dmm->tcm);
+
+		kfree(omap_dmm->engines);
+		if (omap_dmm->refill_va)
+			dma_free_coherent(omap_dmm->dev,
+				REFILL_BUFFER_SIZE * omap_dmm->num_engines,
+				omap_dmm->refill_va,
+				omap_dmm->refill_pa);
+		if (omap_dmm->dummy_page)
+			__free_page(omap_dmm->dummy_page);
+
+		vfree(omap_dmm->lut);
+
+		if (omap_dmm->irq != -1)
+			free_irq(omap_dmm->irq, omap_dmm);
+
+		kfree(omap_dmm);
+	}
+
+	return 0;
+}
+
+int omap_dmm_init(struct drm_device *dev)
+{
+	int ret = -EFAULT, i;
+	struct tcm_area area = {0};
+	u32 hwinfo, pat_geom, lut_table_size;
+	struct omap_drm_platform_data *pdata = dev->dev->platform_data;
+
+	if (!pdata || !pdata->dmm_pdata) {
+		dev_err(dev->dev, "dmm platform data not present, skipping\n");
+		return ret;
+	}
+
+	omap_dmm = kzalloc(sizeof(*omap_dmm), GFP_KERNEL);
+	if (!omap_dmm) {
+		dev_err(dev->dev, "failed to allocate driver data section\n");
+		goto fail;
+	}
+
+	/* lookup hwmod data - base address and irq */
+	omap_dmm->base = pdata->dmm_pdata->base;
+	omap_dmm->irq = pdata->dmm_pdata->irq;
+	omap_dmm->dev = dev->dev;
+
+	if (!omap_dmm->base) {
+		dev_err(dev->dev, "failed to get dmm base address\n");
+		goto fail;
+	}
+
+	hwinfo = readl(omap_dmm->base + DMM_PAT_HWINFO);
+	omap_dmm->num_engines = (hwinfo >> 24) & 0x1F;
+	omap_dmm->num_lut = (hwinfo >> 16) & 0x1F;
+	omap_dmm->container_width = 256;
+	omap_dmm->container_height = 128;
+
+	/* read out actual LUT width and height */
+	pat_geom = readl(omap_dmm->base + DMM_PAT_GEOMETRY);
+	omap_dmm->lut_width = ((pat_geom >> 16) & 0xF) << 5;
+	omap_dmm->lut_height = ((pat_geom >> 24) & 0xF) << 5;
+
+	/* initialize DMM registers */
+	writel(0x88888888, omap_dmm->base + DMM_PAT_VIEW__0);
+	writel(0x88888888, omap_dmm->base + DMM_PAT_VIEW__1);
+	writel(0x80808080, omap_dmm->base + DMM_PAT_VIEW_MAP__0);
+	writel(0x80000000, omap_dmm->base + DMM_PAT_VIEW_MAP_BASE);
+	writel(0x88888888, omap_dmm->base + DMM_TILER_OR__0);
+	writel(0x88888888, omap_dmm->base + DMM_TILER_OR__1);
+
+	ret = request_irq(omap_dmm->irq, omap_dmm_irq_handler, IRQF_SHARED,
+				"omap_dmm_irq_handler", omap_dmm);
+
+	if (ret) {
+		dev_err(dev->dev, "couldn't register IRQ %d, error %d\n",
+			omap_dmm->irq, ret);
+		omap_dmm->irq = -1;
+		goto fail;
+	}
+
+	/* Enable all interrupts for each refill engine except
+	 * ERR_LUT_MISS<n> (which is just advisory, and we don't care
+	 * about because we want to be able to refill live scanout
+	 * buffers for accelerated pan/scroll) and FILL_DSC<n> which
+	 * we just generally don't care about.
+	 */
+	writel(0x7e7e7e7e, omap_dmm->base + DMM_PAT_IRQENABLE_SET);
+
+	lut_table_size = omap_dmm->lut_width * omap_dmm->lut_height *
+			omap_dmm->num_lut;
+
+	omap_dmm->lut = vmalloc(lut_table_size * sizeof(*omap_dmm->lut));
+	if (!omap_dmm->lut) {
+		dev_err(dev->dev, "could not allocate lut table\n");
+		ret = -ENOMEM;
+		goto fail;
+	}
+
+	omap_dmm->dummy_page = alloc_page(GFP_KERNEL | __GFP_DMA32);
+	if (!omap_dmm->dummy_page) {
+		dev_err(dev->dev, "could not allocate dummy page\n");
+		ret = -ENOMEM;
+		goto fail;
+	}
+	omap_dmm->dummy_pa = page_to_phys(omap_dmm->dummy_page);
+
+	/* alloc refill memory */
+	omap_dmm->refill_va = dma_alloc_coherent(dev->dev,
+				REFILL_BUFFER_SIZE * omap_dmm->num_engines,
+				&omap_dmm->refill_pa, GFP_KERNEL);
+	if (!omap_dmm->refill_va) {
+		dev_err(dev->dev, "could not allocate refill memory\n");
+		goto fail;
+	}
+
+	/* alloc engines */
+	omap_dmm->engines = kzalloc(
+			omap_dmm->num_engines * sizeof(struct refill_engine),
+			GFP_KERNEL);
+	if (!omap_dmm->engines) {
+		dev_err(dev->dev, "could not allocate engines\n");
+		ret = -ENOMEM;
+		goto fail;
+	}
+
+	sema_init(&omap_dmm->engine_sem, omap_dmm->num_engines);
+	INIT_LIST_HEAD(&omap_dmm->idle_head);
+	for (i = 0; i < omap_dmm->num_engines; i++) {
+		omap_dmm->engines[i].id = i;
+		omap_dmm->engines[i].dmm = omap_dmm;
+		omap_dmm->engines[i].refill_va = omap_dmm->refill_va +
+						(REFILL_BUFFER_SIZE * i);
+		omap_dmm->engines[i].refill_pa = omap_dmm->refill_pa +
+						(REFILL_BUFFER_SIZE * i);
+		init_waitqueue_head(&omap_dmm->engines[i].wait_for_refill);
+
+		list_add(&omap_dmm->engines[i].idle_node, &omap_dmm->idle_head);
+	}
+
+	omap_dmm->tcm = kzalloc(omap_dmm->num_lut * sizeof(*omap_dmm->tcm),
+				GFP_KERNEL);
+	if (!omap_dmm->tcm) {
+		dev_err(dev->dev, "failed to allocate lut ptrs\n");
+		ret = -ENOMEM;
+		goto fail;
+	}
+
+	/* init containers */
+	for (i = 0; i < omap_dmm->num_lut; i++) {
+		omap_dmm->tcm[i] = sita_init(omap_dmm->container_width,
+						omap_dmm->container_height,
+						NULL);
+
+		if (!omap_dmm->tcm[i]) {
+			dev_err(dev->dev, "failed to allocate container\n");
+			ret = -ENOMEM;
+			goto fail;
+		}
+
+		omap_dmm->tcm[i]->lut_id = i;
+	}
+
+	/* assign access mode containers to applicable tcm container */
+	/* OMAP 4 has 1 container for all 4 views */
+	containers[TILFMT_8BIT] = omap_dmm->tcm[0];
+	containers[TILFMT_16BIT] = omap_dmm->tcm[0];
+	containers[TILFMT_32BIT] = omap_dmm->tcm[0];
+	containers[TILFMT_PAGE] = omap_dmm->tcm[0];
+
+	INIT_LIST_HEAD(&omap_dmm->alloc_head);
+	spin_lock_init(&omap_dmm->list_lock);
+
+	area = (struct tcm_area) {
+		.is2d = true,
+		.tcm = NULL,
+		.p1.x = omap_dmm->container_width - 1,
+		.p1.y = omap_dmm->container_height - 1,
+	};
+
+	for (i = 0; i < lut_table_size; i++)
+		omap_dmm->lut[i] = omap_dmm->dummy_pa;
+
+	/* initialize all LUTs to dummy page entries */
+	for (i = 0; i < omap_dmm->num_lut; i++) {
+		area.tcm = omap_dmm->tcm[i];
+		if (fill(&area, NULL, 0, 0, true))
+			dev_err(omap_dmm->dev, "refill failed");
+	}
+
+	dev_info(omap_dmm->dev, "initialized all PAT entries\n");
+
+	return 0;
+
+fail:
+	omap_dmm_remove();
+	return ret;
+}
+
+/*
+ * debugfs support
+ */
+
+#ifdef CONFIG_DEBUG_FS
+
+static const char *alphabet = "abcdefghijklmnopqrstuvwxyz"
+				"ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
+static const char *special = ".,:;'\"`~!^-+";
+
+static void fill_map(char **map, int xdiv, int ydiv, struct tcm_area *a,
+							char c, bool ovw)
+{
+	int x, y;
+	for (y = a->p0.y / ydiv; y <= a->p1.y / ydiv; y++)
+		for (x = a->p0.x / xdiv; x <= a->p1.x / xdiv; x++)
+			if (map[y][x] == ' ' || ovw)
+				map[y][x] = c;
+}
+
+static void fill_map_pt(char **map, int xdiv, int ydiv, struct tcm_pt *p,
+									char c)
+{
+	map[p->y / ydiv][p->x / xdiv] = c;
+}
+
+static char read_map_pt(char **map, int xdiv, int ydiv, struct tcm_pt *p)
+{
+	return map[p->y / ydiv][p->x / xdiv];
+}
+
+static int map_width(int xdiv, int x0, int x1)
+{
+	return (x1 / xdiv) - (x0 / xdiv) + 1;
+}
+
+static void text_map(char **map, int xdiv, char *nice, int yd, int x0, int x1)
+{
+	char *p = map[yd] + (x0 / xdiv);
+	int w = (map_width(xdiv, x0, x1) - strlen(nice)) / 2;
+	if (w >= 0) {
+		p += w;
+		while (*nice)
+			*p++ = *nice++;
+	}
+}
+
+static void map_1d_info(char **map, int xdiv, int ydiv, char *nice,
+							struct tcm_area *a)
+{
+	sprintf(nice, "%dK", tcm_sizeof(*a) * 4);
+	if (a->p0.y + 1 < a->p1.y) {
+		text_map(map, xdiv, nice, (a->p0.y + a->p1.y) / 2 / ydiv, 0,
+							256 - 1);
+	} else if (a->p0.y < a->p1.y) {
+		if (strlen(nice) < map_width(xdiv, a->p0.x, 256 - 1))
+			text_map(map, xdiv, nice, a->p0.y / ydiv,
+					a->p0.x + xdiv,	256 - 1);
+		else if (strlen(nice) < map_width(xdiv, 0, a->p1.x))
+			text_map(map, xdiv, nice, a->p1.y / ydiv,
+					0, a->p1.y - xdiv);
+	} else if (strlen(nice) + 1 < map_width(xdiv, a->p0.x, a->p1.x)) {
+		text_map(map, xdiv, nice, a->p0.y / ydiv, a->p0.x, a->p1.x);
+	}
+}
+
+static void map_2d_info(char **map, int xdiv, int ydiv, char *nice,
+							struct tcm_area *a)
+{
+	sprintf(nice, "(%d*%d)", tcm_awidth(*a), tcm_aheight(*a));
+	if (strlen(nice) + 1 < map_width(xdiv, a->p0.x, a->p1.x))
+		text_map(map, xdiv, nice, (a->p0.y + a->p1.y) / 2 / ydiv,
+							a->p0.x, a->p1.x);
+}
+
+int tiler_map_show(struct seq_file *s, void *arg)
+{
+	int xdiv = 2, ydiv = 1;
+	char **map = NULL, *global_map;
+	struct tiler_block *block;
+	struct tcm_area a, p;
+	int i;
+	const char *m2d = alphabet;
+	const char *a2d = special;
+	const char *m2dp = m2d, *a2dp = a2d;
+	char nice[128];
+	int h_adj = omap_dmm->lut_height / ydiv;
+	int w_adj = omap_dmm->lut_width / xdiv;
+	unsigned long flags;
+
+	map = kzalloc(h_adj * sizeof(*map), GFP_KERNEL);
+	global_map = kzalloc((w_adj + 1) * h_adj, GFP_KERNEL);
+
+	if (!map || !global_map)
+		goto error;
+
+	memset(global_map, ' ', (w_adj + 1) * h_adj);
+	for (i = 0; i < omap_dmm->lut_height; i++) {
+		map[i] = global_map + i * (w_adj + 1);
+		map[i][w_adj] = 0;
+	}
+	spin_lock_irqsave(&omap_dmm->list_lock, flags);
+
+	list_for_each_entry(block, &omap_dmm->alloc_head, alloc_node) {
+		if (block->fmt != TILFMT_PAGE) {
+			fill_map(map, xdiv, ydiv, &block->area, *m2dp, true);
+			if (!*++a2dp)
+				a2dp = a2d;
+			if (!*++m2dp)
+				m2dp = m2d;
+			map_2d_info(map, xdiv, ydiv, nice, &block->area);
+		} else {
+			bool start = read_map_pt(map, xdiv, ydiv,
+							&block->area.p0)
+									== ' ';
+			bool end = read_map_pt(map, xdiv, ydiv, &block->area.p1)
+									== ' ';
+			tcm_for_each_slice(a, block->area, p)
+				fill_map(map, xdiv, ydiv, &a, '=', true);
+			fill_map_pt(map, xdiv, ydiv, &block->area.p0,
+							start ? '<' : 'X');
+			fill_map_pt(map, xdiv, ydiv, &block->area.p1,
+							end ? '>' : 'X');
+			map_1d_info(map, xdiv, ydiv, nice, &block->area);
+		}
+	}
+
+	spin_unlock_irqrestore(&omap_dmm->list_lock, flags);
+
+	if (s) {
+		seq_printf(s, "BEGIN DMM TILER MAP\n");
+		for (i = 0; i < 128; i++)
+			seq_printf(s, "%03d:%s\n", i, map[i]);
+		seq_printf(s, "END TILER MAP\n");
+	} else {
+		dev_dbg(omap_dmm->dev, "BEGIN DMM TILER MAP\n");
+		for (i = 0; i < 128; i++)
+			dev_dbg(omap_dmm->dev, "%03d:%s\n", i, map[i]);
+		dev_dbg(omap_dmm->dev, "END TILER MAP\n");
+	}
+
+error:
+	kfree(map);
+	kfree(global_map);
+
+	return 0;
+}
+#endif
diff --git a/drivers/staging/omapdrm/omap_dmm_tiler.h b/drivers/staging/omapdrm/omap_dmm_tiler.h
new file mode 100644
index 0000000..f87cb65
--- /dev/null
+++ b/drivers/staging/omapdrm/omap_dmm_tiler.h
@@ -0,0 +1,135 @@
+/*
+ *
+ * Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/
+ * Author: Rob Clark <rob@ti.com>
+ *         Andy Gross <andy.gross@ti.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation version 2.
+ *
+ * This program is distributed "as is" WITHOUT ANY WARRANTY of any
+ * kind, whether express or implied; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+#ifndef OMAP_DMM_TILER_H
+#define OMAP_DMM_TILER_H
+
+#include "omap_drv.h"
+#include "tcm.h"
+
+enum tiler_fmt {
+	TILFMT_8BIT = 0,
+	TILFMT_16BIT,
+	TILFMT_32BIT,
+	TILFMT_PAGE,
+	TILFMT_NFORMATS
+};
+
+struct pat_area {
+	u32 x0:8;
+	u32 y0:8;
+	u32 x1:8;
+	u32 y1:8;
+};
+
+struct tiler_block {
+	struct list_head alloc_node;	/* node for global block list */
+	struct tcm_area area;		/* area */
+	enum tiler_fmt fmt;		/* format */
+};
+
+/* bits representing the same slot in DMM-TILER hw-block */
+#define SLOT_WIDTH_BITS         6
+#define SLOT_HEIGHT_BITS        6
+
+/* bits reserved to describe coordinates in DMM-TILER hw-block */
+#define CONT_WIDTH_BITS         14
+#define CONT_HEIGHT_BITS        13
+
+/* calculated constants */
+#define TILER_PAGE              (1 << (SLOT_WIDTH_BITS + SLOT_HEIGHT_BITS))
+#define TILER_WIDTH             (1 << (CONT_WIDTH_BITS - SLOT_WIDTH_BITS))
+#define TILER_HEIGHT            (1 << (CONT_HEIGHT_BITS - SLOT_HEIGHT_BITS))
+
+/* tiler space addressing bitfields */
+#define MASK_XY_FLIP		(1 << 31)
+#define MASK_Y_INVERT		(1 << 30)
+#define MASK_X_INVERT		(1 << 29)
+#define SHIFT_ACC_MODE		27
+#define MASK_ACC_MODE		3
+
+#define MASK(bits) ((1 << (bits)) - 1)
+
+#define TILVIEW_8BIT    0x60000000u
+#define TILVIEW_16BIT   (TILVIEW_8BIT  + VIEW_SIZE)
+#define TILVIEW_32BIT   (TILVIEW_16BIT + VIEW_SIZE)
+#define TILVIEW_PAGE    (TILVIEW_32BIT + VIEW_SIZE)
+#define TILVIEW_END     (TILVIEW_PAGE  + VIEW_SIZE)
+
+/* create tsptr by adding view orientation and access mode */
+#define TIL_ADDR(x, orient, a)\
+	((u32) (x) | (orient) | ((a) << SHIFT_ACC_MODE))
+
+/* externally accessible functions */
+int omap_dmm_init(struct drm_device *dev);
+int omap_dmm_remove(void);
+
+#ifdef CONFIG_DEBUG_FS
+int tiler_map_show(struct seq_file *s, void *arg);
+#endif
+
+/* pin/unpin */
+int tiler_pin(struct tiler_block *block, struct page **pages,
+		uint32_t npages, uint32_t roll, bool wait);
+int tiler_unpin(struct tiler_block *block);
+
+/* reserve/release */
+struct tiler_block *tiler_reserve_2d(enum tiler_fmt fmt, uint16_t w, uint16_t h,
+				uint16_t align);
+struct tiler_block *tiler_reserve_1d(size_t size);
+int tiler_release(struct tiler_block *block);
+
+/* utilities */
+dma_addr_t tiler_ssptr(struct tiler_block *block);
+uint32_t tiler_stride(enum tiler_fmt fmt);
+size_t tiler_size(enum tiler_fmt fmt, uint16_t w, uint16_t h);
+size_t tiler_vsize(enum tiler_fmt fmt, uint16_t w, uint16_t h);
+void tiler_align(enum tiler_fmt fmt, uint16_t *w, uint16_t *h);
+
+
+/* GEM bo flags -> tiler fmt */
+static inline enum tiler_fmt gem2fmt(uint32_t flags)
+{
+	switch (flags & OMAP_BO_TILED) {
+	case OMAP_BO_TILED_8:
+		return TILFMT_8BIT;
+	case OMAP_BO_TILED_16:
+		return TILFMT_16BIT;
+	case OMAP_BO_TILED_32:
+		return TILFMT_32BIT;
+	default:
+		return TILFMT_PAGE;
+	}
+}
+
+static inline bool validfmt(enum tiler_fmt fmt)
+{
+	switch (fmt) {
+	case TILFMT_8BIT:
+	case TILFMT_16BIT:
+	case TILFMT_32BIT:
+	case TILFMT_PAGE:
+		return true;
+	default:
+		return false;
+	}
+}
+
+struct omap_dmm_platform_data {
+	void __iomem *base;
+	int irq;
+};
+
+#endif
diff --git a/drivers/staging/omapdrm/omap_drm.h b/drivers/staging/omapdrm/omap_drm.h
new file mode 100644
index 0000000..f0ac34a
--- /dev/null
+++ b/drivers/staging/omapdrm/omap_drm.h
@@ -0,0 +1,123 @@
+/*
+ * include/drm/omap_drm.h
+ *
+ * Copyright (C) 2011 Texas Instruments
+ * Author: Rob Clark <rob@ti.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef __OMAP_DRM_H__
+#define __OMAP_DRM_H__
+
+#include <drm/drm.h>
+
+/* Please note that modifications to all structs defined here are
+ * subject to backwards-compatibility constraints.
+ */
+
+#define OMAP_PARAM_CHIPSET_ID	1	/* ie. 0x3430, 0x4430, etc */
+
+struct drm_omap_param {
+	uint64_t param;			/* in */
+	uint64_t value;			/* in (set_param), out (get_param) */
+};
+
+#define OMAP_BO_SCANOUT		0x00000001	/* scanout capable (phys contiguous) */
+#define OMAP_BO_CACHE_MASK	0x00000006	/* cache type mask, see cache modes */
+#define OMAP_BO_TILED_MASK	0x00000f00	/* tiled mapping mask, see tiled modes */
+
+/* cache modes */
+#define OMAP_BO_CACHED		0x00000000	/* default */
+#define OMAP_BO_WC		0x00000002	/* write-combine */
+#define OMAP_BO_UNCACHED	0x00000004	/* strongly-ordered (uncached) */
+
+/* tiled modes */
+#define OMAP_BO_TILED_8		0x00000100
+#define OMAP_BO_TILED_16	0x00000200
+#define OMAP_BO_TILED_32	0x00000300
+#define OMAP_BO_TILED		(OMAP_BO_TILED_8 | OMAP_BO_TILED_16 | OMAP_BO_TILED_32)
+
+union omap_gem_size {
+	uint32_t bytes;		/* (for non-tiled formats) */
+	struct {
+		uint16_t width;
+		uint16_t height;
+	} tiled;		/* (for tiled formats) */
+};
+
+struct drm_omap_gem_new {
+	union omap_gem_size size;	/* in */
+	uint32_t flags;			/* in */
+	uint32_t handle;		/* out */
+	uint32_t __pad;
+};
+
+/* mask of operations: */
+enum omap_gem_op {
+	OMAP_GEM_READ = 0x01,
+	OMAP_GEM_WRITE = 0x02,
+};
+
+struct drm_omap_gem_cpu_prep {
+	uint32_t handle;		/* buffer handle (in) */
+	uint32_t op;			/* mask of omap_gem_op (in) */
+};
+
+struct drm_omap_gem_cpu_fini {
+	uint32_t handle;		/* buffer handle (in) */
+	uint32_t op;			/* mask of omap_gem_op (in) */
+	/* TODO maybe here we pass down info about what regions are touched
+	 * by sw so we can be clever about cache ops?  For now a placeholder,
+	 * set to zero and we just do full buffer flush..
+	 */
+	uint32_t nregions;
+	uint32_t __pad;
+};
+
+struct drm_omap_gem_info {
+	uint32_t handle;		/* buffer handle (in) */
+	uint32_t pad;
+	uint64_t offset;		/* mmap offset (out) */
+	/* note: in case of tiled buffers, the user virtual size can be
+	 * different from the physical size (ie. how many pages are needed
+	 * to back the object) which is returned in DRM_IOCTL_GEM_OPEN..
+	 * This size here is the one that should be used if you want to
+	 * mmap() the buffer:
+	 */
+	uint32_t size;			/* virtual size for mmap'ing (out) */
+	uint32_t __pad;
+};
+
+#define DRM_OMAP_GET_PARAM		0x00
+#define DRM_OMAP_SET_PARAM		0x01
+/* placeholder for plugin-api
+#define DRM_OMAP_GET_BASE		0x02
+*/
+#define DRM_OMAP_GEM_NEW		0x03
+#define DRM_OMAP_GEM_CPU_PREP		0x04
+#define DRM_OMAP_GEM_CPU_FINI		0x05
+#define DRM_OMAP_GEM_INFO		0x06
+#define DRM_OMAP_NUM_IOCTLS		0x07
+
+#define DRM_IOCTL_OMAP_GET_PARAM	DRM_IOWR(DRM_COMMAND_BASE + DRM_OMAP_GET_PARAM, struct drm_omap_param)
+#define DRM_IOCTL_OMAP_SET_PARAM	DRM_IOW (DRM_COMMAND_BASE + DRM_OMAP_SET_PARAM, struct drm_omap_param)
+/* placeholder for plugin-api
+#define DRM_IOCTL_OMAP_GET_BASE		DRM_IOWR(DRM_COMMAND_BASE + DRM_OMAP_GET_BASE, struct drm_omap_get_base)
+*/
+#define DRM_IOCTL_OMAP_GEM_NEW		DRM_IOWR(DRM_COMMAND_BASE + DRM_OMAP_GEM_NEW, struct drm_omap_gem_new)
+#define DRM_IOCTL_OMAP_GEM_CPU_PREP	DRM_IOW (DRM_COMMAND_BASE + DRM_OMAP_GEM_CPU_PREP, struct drm_omap_gem_cpu_prep)
+#define DRM_IOCTL_OMAP_GEM_CPU_FINI	DRM_IOW (DRM_COMMAND_BASE + DRM_OMAP_GEM_CPU_FINI, struct drm_omap_gem_cpu_fini)
+#define DRM_IOCTL_OMAP_GEM_INFO		DRM_IOWR(DRM_COMMAND_BASE + DRM_OMAP_GEM_INFO, struct drm_omap_gem_info)
+
+#endif /* __OMAP_DRM_H__ */
diff --git a/drivers/staging/omapdrm/omap_drv.c b/drivers/staging/omapdrm/omap_drv.c
new file mode 100644
index 0000000..602aa2d
--- /dev/null
+++ b/drivers/staging/omapdrm/omap_drv.c
@@ -0,0 +1,821 @@
+/*
+ * drivers/staging/omapdrm/omap_drv.c
+ *
+ * Copyright (C) 2011 Texas Instruments
+ * Author: Rob Clark <rob@ti.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "omap_drv.h"
+
+#include "drm_crtc_helper.h"
+#include "drm_fb_helper.h"
+
+#define DRIVER_NAME		MODULE_NAME
+#define DRIVER_DESC		"OMAP DRM"
+#define DRIVER_DATE		"20110917"
+#define DRIVER_MAJOR		1
+#define DRIVER_MINOR		0
+#define DRIVER_PATCHLEVEL	0
+
+struct drm_device *drm_device;
+
+static int num_crtc = CONFIG_DRM_OMAP_NUM_CRTCS;
+
+MODULE_PARM_DESC(num_crtc, "Number of overlays to use as CRTCs");
+module_param(num_crtc, int, 0600);
+
+/*
+ * mode config funcs
+ */
+
+/* Notes about mapping DSS and DRM entities:
+ *    CRTC:        overlay
+ *    encoder:     manager.. with some extension to allow one primary CRTC
+ *                 and zero or more video CRTC's to be mapped to one encoder?
+ *    connector:   dssdev.. manager can be attached/detached from different
+ *                 devices
+ */
+
+static void omap_fb_output_poll_changed(struct drm_device *dev)
+{
+	struct omap_drm_private *priv = dev->dev_private;
+	DBG("dev=%p", dev);
+	if (priv->fbdev) {
+		drm_fb_helper_hotplug_event(priv->fbdev);
+	}
+}
+
+static struct drm_mode_config_funcs omap_mode_config_funcs = {
+	.fb_create = omap_framebuffer_create,
+	.output_poll_changed = omap_fb_output_poll_changed,
+};
+
+static int get_connector_type(struct omap_dss_device *dssdev)
+{
+	switch (dssdev->type) {
+	case OMAP_DISPLAY_TYPE_HDMI:
+		return DRM_MODE_CONNECTOR_HDMIA;
+	case OMAP_DISPLAY_TYPE_DPI:
+		if (!strcmp(dssdev->name, "dvi"))
+			return DRM_MODE_CONNECTOR_DVID;
+		/* fallthrough */
+	default:
+		return DRM_MODE_CONNECTOR_Unknown;
+	}
+}
+
+#if 0 /* enable when dss2 supports hotplug */
+static int omap_drm_notifier(struct notifier_block *nb,
+		unsigned long evt, void *arg)
+{
+	switch (evt) {
+	case OMAP_DSS_SIZE_CHANGE:
+	case OMAP_DSS_HOTPLUG_CONNECT:
+	case OMAP_DSS_HOTPLUG_DISCONNECT: {
+		struct drm_device *dev = drm_device;
+		DBG("hotplug event: evt=%d, dev=%p", evt, dev);
+		if (dev) {
+			drm_sysfs_hotplug_event(dev);
+		}
+		return NOTIFY_OK;
+	}
+	default:  /* don't care about other events for now */
+		return NOTIFY_DONE;
+	}
+}
+#endif
+
+static void dump_video_chains(void)
+{
+	int i;
+
+	DBG("dumping video chains: ");
+	for (i = 0; i < omap_dss_get_num_overlays(); i++) {
+		struct omap_overlay *ovl = omap_dss_get_overlay(i);
+		struct omap_overlay_manager *mgr = ovl->manager;
+		struct omap_dss_device *dssdev = mgr ? mgr->device : NULL;
+		if (dssdev) {
+			DBG("%d: %s -> %s -> %s", i, ovl->name, mgr->name,
+						dssdev->name);
+		} else if (mgr) {
+			DBG("%d: %s -> %s", i, ovl->name, mgr->name);
+		} else {
+			DBG("%d: %s", i, ovl->name);
+		}
+	}
+}
+
+/* create encoders for each manager */
+static int create_encoder(struct drm_device *dev,
+		struct omap_overlay_manager *mgr)
+{
+	struct omap_drm_private *priv = dev->dev_private;
+	struct drm_encoder *encoder = omap_encoder_init(dev, mgr);
+
+	if (!encoder) {
+		dev_err(dev->dev, "could not create encoder: %s\n",
+				mgr->name);
+		return -ENOMEM;
+	}
+
+	BUG_ON(priv->num_encoders >= ARRAY_SIZE(priv->encoders));
+
+	priv->encoders[priv->num_encoders++] = encoder;
+
+	return 0;
+}
+
+/* create connectors for each display device */
+static int create_connector(struct drm_device *dev,
+		struct omap_dss_device *dssdev)
+{
+	struct omap_drm_private *priv = dev->dev_private;
+	static struct notifier_block *notifier;
+	struct drm_connector *connector;
+	int j;
+
+	if (!dssdev->driver) {
+		dev_warn(dev->dev, "%s has no driver.. skipping it\n",
+				dssdev->name);
+		return 0;
+	}
+
+	if (!(dssdev->driver->get_timings ||
+				dssdev->driver->read_edid)) {
+		dev_warn(dev->dev, "%s driver does not support "
+			"get_timings or read_edid.. skipping it!\n",
+			dssdev->name);
+		return 0;
+	}
+
+	connector = omap_connector_init(dev,
+			get_connector_type(dssdev), dssdev);
+
+	if (!connector) {
+		dev_err(dev->dev, "could not create connector: %s\n",
+				dssdev->name);
+		return -ENOMEM;
+	}
+
+	BUG_ON(priv->num_connectors >= ARRAY_SIZE(priv->connectors));
+
+	priv->connectors[priv->num_connectors++] = connector;
+
+#if 0 /* enable when dss2 supports hotplug */
+	notifier = kzalloc(sizeof(struct notifier_block), GFP_KERNEL);
+	notifier->notifier_call = omap_drm_notifier;
+	omap_dss_add_notify(dssdev, notifier);
+#else
+	notifier = NULL;
+#endif
+
+	for (j = 0; j < priv->num_encoders; j++) {
+		struct omap_overlay_manager *mgr =
+			omap_encoder_get_manager(priv->encoders[j]);
+		if (mgr->device == dssdev) {
+			drm_mode_connector_attach_encoder(connector,
+					priv->encoders[j]);
+		}
+	}
+
+	return 0;
+}
+
+/* create up to max_overlays CRTCs mapping to overlays.. by default,
+ * connect the overlays to different managers/encoders, giving priority
+ * to encoders connected to connectors with a detected connection
+ */
+static int create_crtc(struct drm_device *dev, struct omap_overlay *ovl,
+		int *j, unsigned int connected_connectors)
+{
+	struct omap_drm_private *priv = dev->dev_private;
+	struct omap_overlay_manager *mgr = NULL;
+	struct drm_crtc *crtc;
+
+	if (ovl->manager) {
+		DBG("disconnecting %s from %s", ovl->name,
+					ovl->manager->name);
+		ovl->unset_manager(ovl);
+	}
+
+	/* find next best connector, ones with detected connection first
+	 */
+	while (*j < priv->num_connectors && !mgr) {
+		if (connected_connectors & (1 << *j)) {
+			struct drm_encoder *encoder =
+				omap_connector_attached_encoder(
+						priv->connectors[*j]);
+			if (encoder) {
+				mgr = omap_encoder_get_manager(encoder);
+			}
+		}
+		(*j)++;
+	}
+
+	/* if we couldn't find another connected connector, lets start
+	 * looking at the unconnected connectors:
+	 *
+	 * note: it might not be immediately apparent, but thanks to
+	 * the !mgr check in both this loop and the one above, the only
+	 * way to enter this loop is with *j == priv->num_connectors,
+	 * so idx can never go negative.
+	 */
+	while (*j < 2 * priv->num_connectors && !mgr) {
+		int idx = *j - priv->num_connectors;
+		if (!(connected_connectors & (1 << idx))) {
+			struct drm_encoder *encoder =
+				omap_connector_attached_encoder(
+						priv->connectors[idx]);
+			if (encoder) {
+				mgr = omap_encoder_get_manager(encoder);
+			}
+		}
+		(*j)++;
+	}
+
+	if (mgr) {
+		DBG("connecting %s to %s", ovl->name, mgr->name);
+		ovl->set_manager(ovl, mgr);
+	}
+
+	crtc = omap_crtc_init(dev, ovl, priv->num_crtcs);
+
+	if (!crtc) {
+		dev_err(dev->dev, "could not create CRTC: %s\n",
+				ovl->name);
+		return -ENOMEM;
+	}
+
+	BUG_ON(priv->num_crtcs >= ARRAY_SIZE(priv->crtcs));
+
+	priv->crtcs[priv->num_crtcs++] = crtc;
+
+	return 0;
+}
+
+static int match_dev_name(struct omap_dss_device *dssdev, void *data)
+{
+	return !strcmp(dssdev->name, data);
+}
+
+static unsigned int detect_connectors(struct drm_device *dev)
+{
+	struct omap_drm_private *priv = dev->dev_private;
+	unsigned int connected_connectors = 0;
+	int i;
+
+	for (i = 0; i < priv->num_connectors; i++) {
+		struct drm_connector *connector = priv->connectors[i];
+		if (omap_connector_detect(connector, true) ==
+				connector_status_connected) {
+			connected_connectors |= (1 << i);
+		}
+	}
+
+	return connected_connectors;
+}
+
+static int omap_modeset_init(struct drm_device *dev)
+{
+	const struct omap_drm_platform_data *pdata = dev->dev->platform_data;
+	struct omap_kms_platform_data *kms_pdata = NULL;
+	struct omap_drm_private *priv = dev->dev_private;
+	struct omap_dss_device *dssdev = NULL;
+	int i, j;
+	unsigned int connected_connectors = 0;
+
+	drm_mode_config_init(dev);
+
+	if (pdata && pdata->kms_pdata) {
+		kms_pdata = pdata->kms_pdata;
+
+		/* if platform data is provided by the board file, use it to
+		 * control which overlays, managers, and devices we own.
+		 */
+		for (i = 0; i < kms_pdata->mgr_cnt; i++) {
+			struct omap_overlay_manager *mgr =
+				omap_dss_get_overlay_manager(
+						kms_pdata->mgr_ids[i]);
+			create_encoder(dev, mgr);
+		}
+
+		for (i = 0; i < kms_pdata->dev_cnt; i++) {
+			struct omap_dss_device *dssdev =
+				omap_dss_find_device(
+					(void *)kms_pdata->dev_names[i],
+					match_dev_name);
+			if (!dssdev) {
+				dev_warn(dev->dev, "no such dssdev: %s\n",
+						kms_pdata->dev_names[i]);
+				continue;
+			}
+			create_connector(dev, dssdev);
+		}
+
+		connected_connectors = detect_connectors(dev);
+
+		j = 0;
+		for (i = 0; i < kms_pdata->ovl_cnt; i++) {
+			struct omap_overlay *ovl =
+				omap_dss_get_overlay(kms_pdata->ovl_ids[i]);
+			create_crtc(dev, ovl, &j, connected_connectors);
+		}
+	} else {
+		/* otherwise just grab up to CONFIG_DRM_OMAP_NUM_CRTCS and try
+		 * to make educated guesses about everything else
+		 */
+		int max_overlays = min(omap_dss_get_num_overlays(), num_crtc);
+
+		for (i = 0; i < omap_dss_get_num_overlay_managers(); i++) {
+			create_encoder(dev, omap_dss_get_overlay_manager(i));
+		}
+
+		for_each_dss_dev(dssdev) {
+			create_connector(dev, dssdev);
+		}
+
+		connected_connectors = detect_connectors(dev);
+
+		j = 0;
+		for (i = 0; i < max_overlays; i++) {
+			create_crtc(dev, omap_dss_get_overlay(i),
+					&j, connected_connectors);
+		}
+	}
+
+	/* for now keep the mapping of CRTCs and encoders static.. */
+	for (i = 0; i < priv->num_encoders; i++) {
+		struct drm_encoder *encoder = priv->encoders[i];
+		struct omap_overlay_manager *mgr =
+				omap_encoder_get_manager(encoder);
+
+		encoder->possible_crtcs = 0;
+
+		for (j = 0; j < priv->num_crtcs; j++) {
+			struct omap_overlay *ovl =
+					omap_crtc_get_overlay(priv->crtcs[j]);
+			if (ovl->manager == mgr) {
+				encoder->possible_crtcs |= (1 << j);
+			}
+		}
+
+		DBG("%s: possible_crtcs=%08x", mgr->name,
+					encoder->possible_crtcs);
+	}
+
+	dump_video_chains();
+
+	dev->mode_config.min_width = 256;
+	dev->mode_config.min_height = 256;
+
+	/* note: eventually will need some cpu_is_omapXYZ() type stuff here
+	 * to fill in these limits properly on different OMAP generations..
+	 */
+	dev->mode_config.max_width = 2048;
+	dev->mode_config.max_height = 2048;
+
+	dev->mode_config.funcs = &omap_mode_config_funcs;
+
+	return 0;
+}
+
+static void omap_modeset_free(struct drm_device *dev)
+{
+	drm_mode_config_cleanup(dev);
+}
+
+/*
+ * drm ioctl funcs
+ */
+
+
+static int ioctl_get_param(struct drm_device *dev, void *data,
+		struct drm_file *file_priv)
+{
+	struct drm_omap_param *args = data;
+
+	DBG("%p: param=%llu", dev, args->param);
+
+	switch (args->param) {
+	case OMAP_PARAM_CHIPSET_ID:
+		args->value = GET_OMAP_TYPE;
+		break;
+	default:
+		DBG("unknown parameter %lld", args->param);
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static int ioctl_set_param(struct drm_device *dev, void *data,
+		struct drm_file *file_priv)
+{
+	struct drm_omap_param *args = data;
+
+	switch (args->param) {
+	default:
+		DBG("unknown parameter %lld", args->param);
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static int ioctl_gem_new(struct drm_device *dev, void *data,
+		struct drm_file *file_priv)
+{
+	struct drm_omap_gem_new *args = data;
+	DBG("%p:%p: size=0x%08x, flags=%08x", dev, file_priv,
+			args->size.bytes, args->flags);
+	return omap_gem_new_handle(dev, file_priv, args->size,
+			args->flags, &args->handle);
+}
+
+static int ioctl_gem_cpu_prep(struct drm_device *dev, void *data,
+		struct drm_file *file_priv)
+{
+	struct drm_omap_gem_cpu_prep *args = data;
+	struct drm_gem_object *obj;
+	int ret;
+
+	VERB("%p:%p: handle=%d, op=%x", dev, file_priv, args->handle, args->op);
+
+	obj = drm_gem_object_lookup(dev, file_priv, args->handle);
+	if (!obj) {
+		return -ENOENT;
+	}
+
+	ret = omap_gem_op_sync(obj, args->op);
+
+	if (!ret) {
+		ret = omap_gem_op_start(obj, args->op);
+	}
+
+	drm_gem_object_unreference_unlocked(obj);
+
+	return ret;
+}
+
+static int ioctl_gem_cpu_fini(struct drm_device *dev, void *data,
+		struct drm_file *file_priv)
+{
+	struct drm_omap_gem_cpu_fini *args = data;
+	struct drm_gem_object *obj;
+	int ret;
+
+	VERB("%p:%p: handle=%d", dev, file_priv, args->handle);
+
+	obj = drm_gem_object_lookup(dev, file_priv, args->handle);
+	if (!obj) {
+		return -ENOENT;
+	}
+
+	/* XXX flushy, flushy */
+	ret = 0;
+
+	if (!ret) {
+		ret = omap_gem_op_finish(obj, args->op);
+	}
+
+	drm_gem_object_unreference_unlocked(obj);
+
+	return ret;
+}
+
+static int ioctl_gem_info(struct drm_device *dev, void *data,
+		struct drm_file *file_priv)
+{
+	struct drm_omap_gem_info *args = data;
+	struct drm_gem_object *obj;
+	int ret = 0;
+
+	DBG("%p:%p: handle=%d", dev, file_priv, args->handle);
+
+	obj = drm_gem_object_lookup(dev, file_priv, args->handle);
+	if (!obj) {
+		return -ENOENT;
+	}
+
+	args->size = omap_gem_mmap_size(obj);
+	args->offset = omap_gem_mmap_offset(obj);
+
+	drm_gem_object_unreference_unlocked(obj);
+
+	return ret;
+}
+
+struct drm_ioctl_desc ioctls[DRM_COMMAND_END - DRM_COMMAND_BASE] = {
+	DRM_IOCTL_DEF_DRV(OMAP_GET_PARAM, ioctl_get_param, DRM_UNLOCKED|DRM_AUTH),
+	DRM_IOCTL_DEF_DRV(OMAP_SET_PARAM, ioctl_set_param, DRM_UNLOCKED|DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
+	DRM_IOCTL_DEF_DRV(OMAP_GEM_NEW, ioctl_gem_new, DRM_UNLOCKED|DRM_AUTH),
+	DRM_IOCTL_DEF_DRV(OMAP_GEM_CPU_PREP, ioctl_gem_cpu_prep, DRM_UNLOCKED|DRM_AUTH),
+	DRM_IOCTL_DEF_DRV(OMAP_GEM_CPU_FINI, ioctl_gem_cpu_fini, DRM_UNLOCKED|DRM_AUTH),
+	DRM_IOCTL_DEF_DRV(OMAP_GEM_INFO, ioctl_gem_info, DRM_UNLOCKED|DRM_AUTH),
+};
+
+/*
+ * drm driver funcs
+ */
+
+/**
+ * load - setup chip and create an initial config
+ * @dev: DRM device
+ * @flags: startup flags
+ *
+ * The driver load routine has to do several things:
+ *   - initialize the memory manager
+ *   - allocate initial config memory
+ *   - setup the DRM framebuffer with the allocated memory
+ */
+static int dev_load(struct drm_device *dev, unsigned long flags)
+{
+	struct omap_drm_private *priv;
+	int ret;
+
+	DBG("load: dev=%p", dev);
+
+	drm_device = dev;
+
+	priv = kzalloc(sizeof(*priv), GFP_KERNEL);
+	if (!priv) {
+		dev_err(dev->dev, "could not allocate priv\n");
+		return -ENOMEM;
+	}
+
+	dev->dev_private = priv;
+
+	omap_gem_init(dev);
+
+	ret = omap_modeset_init(dev);
+	if (ret) {
+		dev_err(dev->dev, "omap_modeset_init failed: ret=%d\n", ret);
+		dev->dev_private = NULL;
+		kfree(priv);
+		return ret;
+	}
+
+	priv->fbdev = omap_fbdev_init(dev);
+	if (!priv->fbdev) {
+		dev_warn(dev->dev, "omap_fbdev_init failed\n");
+		/* well, limp along without an fbdev.. maybe X11 will work? */
+	}
+
+	drm_kms_helper_poll_init(dev);
+
+	ret = drm_vblank_init(dev, priv->num_crtcs);
+	if (ret) {
+		dev_warn(dev->dev, "could not init vblank\n");
+	}
+
+	return 0;
+}
+
+static int dev_unload(struct drm_device *dev)
+{
+	DBG("unload: dev=%p", dev);
+
+	drm_vblank_cleanup(dev);
+	drm_kms_helper_poll_fini(dev);
+
+	omap_fbdev_free(dev);
+	omap_modeset_free(dev);
+	omap_gem_deinit(dev);
+
+	kfree(dev->dev_private);
+	dev->dev_private = NULL;
+
+	return 0;
+}
+
+static int dev_open(struct drm_device *dev, struct drm_file *file)
+{
+	file->driver_priv = NULL;
+
+	DBG("open: dev=%p, file=%p", dev, file);
+
+	return 0;
+}
+
+static int dev_firstopen(struct drm_device *dev)
+{
+	DBG("firstopen: dev=%p", dev);
+	return 0;
+}
+
+/**
+ * lastclose - clean up after all DRM clients have exited
+ * @dev: DRM device
+ *
+ * Take care of cleaning up after all DRM clients have exited.  In the
+ * mode setting case, we want to restore the kernel's initial mode (just
+ * in case the last client left us in a bad state).
+ */
+static void dev_lastclose(struct drm_device *dev)
+{
+	/* we don't support vga-switcheroo.. so just make sure the fbdev
+	 * mode is active
+	 */
+	struct omap_drm_private *priv = dev->dev_private;
+	int ret;
+
+	DBG("lastclose: dev=%p", dev);
+
+	ret = drm_fb_helper_restore_fbdev_mode(priv->fbdev);
+	if (ret)
+		DBG("failed to restore crtc mode");
+}
+
+static void dev_preclose(struct drm_device *dev, struct drm_file *file)
+{
+	DBG("preclose: dev=%p", dev);
+}
+
+static void dev_postclose(struct drm_device *dev, struct drm_file *file)
+{
+	DBG("postclose: dev=%p, file=%p", dev, file);
+}
+
+/**
+ * enable_vblank - enable vblank interrupt events
+ * @dev: DRM device
+ * @crtc: which irq to enable
+ *
+ * Enable vblank interrupts for @crtc.  If the device doesn't have
+ * a hardware vblank counter, this routine should be a no-op, since
+ * interrupts will have to stay on to keep the count accurate.
+ *
+ * RETURNS
+ * Zero on success, appropriate errno if the given @crtc's vblank
+ * interrupt cannot be enabled.
+ */
+static int dev_enable_vblank(struct drm_device *dev, int crtc)
+{
+	DBG("enable_vblank: dev=%p, crtc=%d", dev, crtc);
+	return 0;
+}
+
+/**
+ * disable_vblank - disable vblank interrupt events
+ * @dev: DRM device
+ * @crtc: which irq to enable
+ *
+ * Disable vblank interrupts for @crtc.  If the device doesn't have
+ * a hardware vblank counter, this routine should be a no-op, since
+ * interrupts will have to stay on to keep the count accurate.
+ */
+static void dev_disable_vblank(struct drm_device *dev, int crtc)
+{
+	DBG("disable_vblank: dev=%p, crtc=%d", dev, crtc);
+}
+
+static irqreturn_t dev_irq_handler(DRM_IRQ_ARGS)
+{
+	return IRQ_HANDLED;
+}
+
+static void dev_irq_preinstall(struct drm_device *dev)
+{
+	DBG("irq_preinstall: dev=%p", dev);
+}
+
+static int dev_irq_postinstall(struct drm_device *dev)
+{
+	DBG("irq_postinstall: dev=%p", dev);
+	return 0;
+}
+
+static void dev_irq_uninstall(struct drm_device *dev)
+{
+	DBG("irq_uninstall: dev=%p", dev);
+}
+
+static struct vm_operations_struct omap_gem_vm_ops = {
+	.fault = omap_gem_fault,
+	.open = drm_gem_vm_open,
+	.close = drm_gem_vm_close,
+};
+
+static struct drm_driver omap_drm_driver = {
+		.driver_features =
+				DRIVER_HAVE_IRQ | DRIVER_MODESET | DRIVER_GEM,
+		.load = dev_load,
+		.unload = dev_unload,
+		.open = dev_open,
+		.firstopen = dev_firstopen,
+		.lastclose = dev_lastclose,
+		.preclose = dev_preclose,
+		.postclose = dev_postclose,
+		.get_vblank_counter = drm_vblank_count,
+		.enable_vblank = dev_enable_vblank,
+		.disable_vblank = dev_disable_vblank,
+		.irq_preinstall = dev_irq_preinstall,
+		.irq_postinstall = dev_irq_postinstall,
+		.irq_uninstall = dev_irq_uninstall,
+		.irq_handler = dev_irq_handler,
+		.reclaim_buffers = drm_core_reclaim_buffers,
+#ifdef CONFIG_DEBUG_FS
+		.debugfs_init = omap_debugfs_init,
+		.debugfs_cleanup = omap_debugfs_cleanup,
+#endif
+		.gem_init_object = omap_gem_init_object,
+		.gem_free_object = omap_gem_free_object,
+		.gem_vm_ops = &omap_gem_vm_ops,
+		.dumb_create = omap_gem_dumb_create,
+		.dumb_map_offset = omap_gem_dumb_map_offset,
+		.dumb_destroy = omap_gem_dumb_destroy,
+		.ioctls = ioctls,
+		.num_ioctls = DRM_OMAP_NUM_IOCTLS,
+		.fops = {
+				.owner = THIS_MODULE,
+				.open = drm_open,
+				.unlocked_ioctl = drm_ioctl,
+				.release = drm_release,
+				.mmap = omap_gem_mmap,
+				.poll = drm_poll,
+				.fasync = drm_fasync,
+				.read = drm_read,
+				.llseek = noop_llseek,
+		},
+		.name = DRIVER_NAME,
+		.desc = DRIVER_DESC,
+		.date = DRIVER_DATE,
+		.major = DRIVER_MAJOR,
+		.minor = DRIVER_MINOR,
+		.patchlevel = DRIVER_PATCHLEVEL,
+};
+
+static int pdev_suspend(struct platform_device *pDevice, pm_message_t state)
+{
+	DBG("");
+	return 0;
+}
+
+static int pdev_resume(struct platform_device *device)
+{
+	DBG("");
+	return 0;
+}
+
+static void pdev_shutdown(struct platform_device *device)
+{
+	DBG("");
+}
+
+static int pdev_probe(struct platform_device *device)
+{
+	DBG("%s", device->name);
+	return drm_platform_init(&omap_drm_driver, device);
+}
+
+static int pdev_remove(struct platform_device *device)
+{
+	DBG("");
+	drm_platform_exit(&omap_drm_driver, device);
+	return 0;
+}
+
+struct platform_driver pdev = {
+		.driver = {
+			.name = DRIVER_NAME,
+			.owner = THIS_MODULE,
+		},
+		.probe = pdev_probe,
+		.remove = pdev_remove,
+		.suspend = pdev_suspend,
+		.resume = pdev_resume,
+		.shutdown = pdev_shutdown,
+};
+
+static int __init omap_drm_init(void)
+{
+	DBG("init");
+	return platform_driver_register(&pdev);
+}
+
+static void __exit omap_drm_fini(void)
+{
+	DBG("fini");
+	platform_driver_unregister(&pdev);
+}
+
+/* need late_initcall() so we load after dss_driver's are loaded */
+late_initcall(omap_drm_init);
+module_exit(omap_drm_fini);
+
+MODULE_AUTHOR("Rob Clark <rob@ti.com>");
+MODULE_DESCRIPTION("OMAP DRM Display Driver");
+MODULE_ALIAS("platform:" DRIVER_NAME);
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/staging/omapdrm/omap_drv.h b/drivers/staging/omapdrm/omap_drv.h
new file mode 100644
index 0000000..76c4251
--- /dev/null
+++ b/drivers/staging/omapdrm/omap_drv.h
@@ -0,0 +1,135 @@
+/*
+ * drivers/staging/omapdrm/omap_drv.h
+ *
+ * Copyright (C) 2011 Texas Instruments
+ * Author: Rob Clark <rob@ti.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef __OMAP_DRV_H__
+#define __OMAP_DRV_H__
+
+#include <video/omapdss.h>
+#include <linux/module.h>
+#include <linux/types.h>
+#include <drm/drmP.h>
+#include "omap_drm.h"
+#include "omap_priv.h"
+
+#define DBG(fmt, ...) DRM_DEBUG(fmt"\n", ##__VA_ARGS__)
+#define VERB(fmt, ...) if (0) DRM_DEBUG(fmt, ##__VA_ARGS__) /* verbose debug */
+
+#define MODULE_NAME     "omapdrm"
+
+/* max # of mapper-id's that can be assigned.. todo, come up with a better
+ * (but still inexpensive) way to store/access per-buffer mapper private
+ * data..
+ */
+#define MAX_MAPPERS 2
+
+struct omap_drm_private {
+	unsigned int num_crtcs;
+	struct drm_crtc *crtcs[8];
+	unsigned int num_encoders;
+	struct drm_encoder *encoders[8];
+	unsigned int num_connectors;
+	struct drm_connector *connectors[8];
+
+	struct drm_fb_helper *fbdev;
+
+	bool has_dmm;
+};
+
+#ifdef CONFIG_DEBUG_FS
+int omap_debugfs_init(struct drm_minor *minor);
+void omap_debugfs_cleanup(struct drm_minor *minor);
+#endif
+
+struct drm_fb_helper *omap_fbdev_init(struct drm_device *dev);
+void omap_fbdev_free(struct drm_device *dev);
+
+struct drm_crtc *omap_crtc_init(struct drm_device *dev,
+		struct omap_overlay *ovl, int id);
+struct omap_overlay *omap_crtc_get_overlay(struct drm_crtc *crtc);
+
+struct drm_encoder *omap_encoder_init(struct drm_device *dev,
+		struct omap_overlay_manager *mgr);
+struct omap_overlay_manager *omap_encoder_get_manager(
+		struct drm_encoder *encoder);
+struct drm_encoder *omap_connector_attached_encoder(
+		struct drm_connector *connector);
+enum drm_connector_status omap_connector_detect(
+		struct drm_connector *connector, bool force);
+
+struct drm_connector *omap_connector_init(struct drm_device *dev,
+		int connector_type, struct omap_dss_device *dssdev);
+void omap_connector_mode_set(struct drm_connector *connector,
+		struct drm_display_mode *mode);
+void omap_connector_flush(struct drm_connector *connector,
+		int x, int y, int w, int h);
+
+struct drm_framebuffer *omap_framebuffer_create(struct drm_device *dev,
+		struct drm_file *file, struct drm_mode_fb_cmd *mode_cmd);
+struct drm_framebuffer *omap_framebuffer_init(struct drm_device *dev,
+		struct drm_mode_fb_cmd *mode_cmd, struct drm_gem_object *bo);
+struct drm_gem_object *omap_framebuffer_bo(struct drm_framebuffer *fb);
+int omap_framebuffer_get_buffer(struct drm_framebuffer *fb, int x, int y,
+		void **vaddr, dma_addr_t *paddr, unsigned int *screen_width);
+struct drm_connector *omap_framebuffer_get_next_connector(
+		struct drm_framebuffer *fb, struct drm_connector *from);
+void omap_framebuffer_flush(struct drm_framebuffer *fb,
+		int x, int y, int w, int h);
+
+void omap_gem_init(struct drm_device *dev);
+void omap_gem_deinit(struct drm_device *dev);
+
+struct drm_gem_object *omap_gem_new(struct drm_device *dev,
+		union omap_gem_size gsize, uint32_t flags);
+int omap_gem_new_handle(struct drm_device *dev, struct drm_file *file,
+		union omap_gem_size gsize, uint32_t flags, uint32_t *handle);
+void omap_gem_free_object(struct drm_gem_object *obj);
+int omap_gem_init_object(struct drm_gem_object *obj);
+void *omap_gem_vaddr(struct drm_gem_object *obj);
+int omap_gem_dumb_map_offset(struct drm_file *file, struct drm_device *dev,
+		uint32_t handle, uint64_t *offset);
+int omap_gem_dumb_destroy(struct drm_file *file, struct drm_device *dev,
+		uint32_t handle);
+int omap_gem_dumb_create(struct drm_file *file, struct drm_device *dev,
+		struct drm_mode_create_dumb *args);
+int omap_gem_mmap(struct file *filp, struct vm_area_struct *vma);
+int omap_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf);
+int omap_gem_op_start(struct drm_gem_object *obj, enum omap_gem_op op);
+int omap_gem_op_finish(struct drm_gem_object *obj, enum omap_gem_op op);
+int omap_gem_op_sync(struct drm_gem_object *obj, enum omap_gem_op op);
+int omap_gem_op_async(struct drm_gem_object *obj, enum omap_gem_op op,
+		void (*fxn)(void *arg), void *arg);
+int omap_gem_roll(struct drm_gem_object *obj, uint32_t roll);
+int omap_gem_get_paddr(struct drm_gem_object *obj,
+		dma_addr_t *paddr, bool remap);
+int omap_gem_put_paddr(struct drm_gem_object *obj);
+uint64_t omap_gem_mmap_offset(struct drm_gem_object *obj);
+size_t omap_gem_mmap_size(struct drm_gem_object *obj);
+
+static inline int align_pitch(int pitch, int width, int bpp)
+{
+	int bytespp = (bpp + 7) / 8;
+	/* in case someone tries to feed us a completely bogus stride: */
+	pitch = max(pitch, width * bytespp);
+	/* PVR needs alignment to 8 pixels.. right now that is the most
+	 * restrictive stride requirement..
+	 */
+	return ALIGN(pitch, 8 * bytespp);
+}
+
+#endif /* __OMAP_DRV_H__ */
diff --git a/drivers/staging/omapdrm/omap_encoder.c b/drivers/staging/omapdrm/omap_encoder.c
new file mode 100644
index 0000000..06c52cb
--- /dev/null
+++ b/drivers/staging/omapdrm/omap_encoder.c
@@ -0,0 +1,171 @@
+/*
+ * drivers/staging/omapdrm/omap_encoder.c
+ *
+ * Copyright (C) 2011 Texas Instruments
+ * Author: Rob Clark <rob@ti.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "omap_drv.h"
+
+#include "drm_crtc.h"
+#include "drm_crtc_helper.h"
+
+/*
+ * encoder funcs
+ */
+
+#define to_omap_encoder(x) container_of(x, struct omap_encoder, base)
+
+struct omap_encoder {
+	struct drm_encoder base;
+	struct omap_overlay_manager *mgr;
+};
+
+static void omap_encoder_destroy(struct drm_encoder *encoder)
+{
+	struct omap_encoder *omap_encoder = to_omap_encoder(encoder);
+	DBG("%s", omap_encoder->mgr->name);
+	drm_encoder_cleanup(encoder);
+	kfree(omap_encoder);
+}
+
+static void omap_encoder_dpms(struct drm_encoder *encoder, int mode)
+{
+	struct omap_encoder *omap_encoder = to_omap_encoder(encoder);
+	DBG("%s: %d", omap_encoder->mgr->name, mode);
+}
+
+static bool omap_encoder_mode_fixup(struct drm_encoder *encoder,
+				  struct drm_display_mode *mode,
+				  struct drm_display_mode *adjusted_mode)
+{
+	struct omap_encoder *omap_encoder = to_omap_encoder(encoder);
+	DBG("%s", omap_encoder->mgr->name);
+	return true;
+}
+
+static void omap_encoder_mode_set(struct drm_encoder *encoder,
+				struct drm_display_mode *mode,
+				struct drm_display_mode *adjusted_mode)
+{
+	struct omap_encoder *omap_encoder = to_omap_encoder(encoder);
+	struct drm_device *dev = encoder->dev;
+	struct omap_drm_private *priv = dev->dev_private;
+	int i;
+
+	mode = adjusted_mode;
+
+	DBG("%s: set mode: %dx%d", omap_encoder->mgr->name,
+			mode->hdisplay, mode->vdisplay);
+
+	for (i = 0; i < priv->num_connectors; i++) {
+		struct drm_connector *connector = priv->connectors[i];
+		if (connector->encoder == encoder) {
+			omap_connector_mode_set(connector, mode);
+		}
+	}
+}
+
+static void omap_encoder_prepare(struct drm_encoder *encoder)
+{
+	struct omap_encoder *omap_encoder = to_omap_encoder(encoder);
+	struct drm_encoder_helper_funcs *encoder_funcs =
+				encoder->helper_private;
+	DBG("%s", omap_encoder->mgr->name);
+	encoder_funcs->dpms(encoder, DRM_MODE_DPMS_OFF);
+}
+
+static void omap_encoder_commit(struct drm_encoder *encoder)
+{
+	struct omap_encoder *omap_encoder = to_omap_encoder(encoder);
+	struct drm_encoder_helper_funcs *encoder_funcs =
+				encoder->helper_private;
+	DBG("%s", omap_encoder->mgr->name);
+	omap_encoder->mgr->apply(omap_encoder->mgr);
+	encoder_funcs->dpms(encoder, DRM_MODE_DPMS_ON);
+}
+
+static const struct drm_encoder_funcs omap_encoder_funcs = {
+	.destroy = omap_encoder_destroy,
+};
+
+static const struct drm_encoder_helper_funcs omap_encoder_helper_funcs = {
+	.dpms = omap_encoder_dpms,
+	.mode_fixup = omap_encoder_mode_fixup,
+	.mode_set = omap_encoder_mode_set,
+	.prepare = omap_encoder_prepare,
+	.commit = omap_encoder_commit,
+};
+
+struct omap_overlay_manager *omap_encoder_get_manager(
+		struct drm_encoder *encoder)
+{
+	struct omap_encoder *omap_encoder = to_omap_encoder(encoder);
+	return omap_encoder->mgr;
+}
+
+/* initialize encoder */
+struct drm_encoder *omap_encoder_init(struct drm_device *dev,
+		struct omap_overlay_manager *mgr)
+{
+	struct drm_encoder *encoder = NULL;
+	struct omap_encoder *omap_encoder;
+	struct omap_overlay_manager_info info;
+	int ret;
+
+	DBG("%s", mgr->name);
+
+	omap_encoder = kzalloc(sizeof(*omap_encoder), GFP_KERNEL);
+	if (!omap_encoder) {
+		dev_err(dev->dev, "could not allocate encoder\n");
+		goto fail;
+	}
+
+	omap_encoder->mgr = mgr;
+	encoder = &omap_encoder->base;
+
+	drm_encoder_init(dev, encoder, &omap_encoder_funcs,
+			 DRM_MODE_ENCODER_TMDS);
+	drm_encoder_helper_add(encoder, &omap_encoder_helper_funcs);
+
+	mgr->get_manager_info(mgr, &info);
+
+	/* TODO: fix hard-coded setup.. */
+	info.default_color = 0x00000000;
+	info.trans_key = 0x00000000;
+	info.trans_key_type = OMAP_DSS_COLOR_KEY_GFX_DST;
+	info.trans_enabled = false;
+
+	ret = mgr->set_manager_info(mgr, &info);
+	if (ret) {
+		dev_err(dev->dev, "could not set manager info\n");
+		goto fail;
+	}
+
+	ret = mgr->apply(mgr);
+	if (ret) {
+		dev_err(dev->dev, "could not apply\n");
+		goto fail;
+	}
+
+	return encoder;
+
+fail:
+	if (encoder) {
+		omap_encoder_destroy(encoder);
+	}
+
+	return NULL;
+}
diff --git a/drivers/staging/omapdrm/omap_fb.c b/drivers/staging/omapdrm/omap_fb.c
new file mode 100644
index 0000000..0b50c5b
--- /dev/null
+++ b/drivers/staging/omapdrm/omap_fb.c
@@ -0,0 +1,243 @@
+/*
+ * drivers/staging/omapdrm/omap_fb.c
+ *
+ * Copyright (C) 2011 Texas Instruments
+ * Author: Rob Clark <rob@ti.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "omap_drv.h"
+
+#include "drm_crtc.h"
+#include "drm_crtc_helper.h"
+
+
+/*
+ * framebuffer funcs
+ */
+
+#define to_omap_framebuffer(x) container_of(x, struct omap_framebuffer, base)
+
+struct omap_framebuffer {
+	struct drm_framebuffer base;
+	struct drm_gem_object *bo;
+	int size;
+	dma_addr_t paddr;
+};
+
+static int omap_framebuffer_create_handle(struct drm_framebuffer *fb,
+		struct drm_file *file_priv,
+		unsigned int *handle)
+{
+	struct omap_framebuffer *omap_fb = to_omap_framebuffer(fb);
+    return drm_gem_handle_create(file_priv, omap_fb->bo, handle);
+}
+
+static void omap_framebuffer_destroy(struct drm_framebuffer *fb)
+{
+	struct drm_device *dev = fb->dev;
+	struct omap_framebuffer *omap_fb = to_omap_framebuffer(fb);
+
+	DBG("destroy: FB ID: %d (%p)", fb->base.id, fb);
+
+	drm_framebuffer_cleanup(fb);
+
+	if (omap_fb->bo) {
+		if (omap_fb->paddr && omap_gem_put_paddr(omap_fb->bo))
+			dev_err(dev->dev, "could not unmap!\n");
+		drm_gem_object_unreference_unlocked(omap_fb->bo);
+	}
+
+	kfree(omap_fb);
+}
+
+static int omap_framebuffer_dirty(struct drm_framebuffer *fb,
+		struct drm_file *file_priv, unsigned flags, unsigned color,
+		struct drm_clip_rect *clips, unsigned num_clips)
+{
+	int i;
+
+	for (i = 0; i < num_clips; i++) {
+		omap_framebuffer_flush(fb, clips[i].x1, clips[i].y1,
+					clips[i].x2 - clips[i].x1,
+					clips[i].y2 - clips[i].y1);
+	}
+
+	return 0;
+}
+
+static const struct drm_framebuffer_funcs omap_framebuffer_funcs = {
+	.create_handle = omap_framebuffer_create_handle,
+	.destroy = omap_framebuffer_destroy,
+	.dirty = omap_framebuffer_dirty,
+};
+
+/* returns the buffer size */
+int omap_framebuffer_get_buffer(struct drm_framebuffer *fb, int x, int y,
+		void **vaddr, dma_addr_t *paddr, unsigned int *screen_width)
+{
+	struct omap_framebuffer *omap_fb = to_omap_framebuffer(fb);
+	int bpp = fb->bits_per_pixel / 8;
+	unsigned long offset;
+
+	offset = (x * bpp) + (y * fb->pitch);
+
+	if (vaddr) {
+		void *bo_vaddr = omap_gem_vaddr(omap_fb->bo);
+		/* note: we can only count on having a vaddr for buffers that
+		 * are allocated physically contiguously to begin with (ie.
+		 * dma_alloc_coherent()).  But this should be ok because it
+		 * is only used by legacy fbdev
+		 */
+		BUG_ON(IS_ERR_OR_NULL(bo_vaddr));
+		*vaddr = bo_vaddr + offset;
+	}
+
+	*paddr = omap_fb->paddr + offset;
+	*screen_width = fb->pitch / bpp;
+
+	return omap_fb->size - offset;
+}
+
+struct drm_gem_object *omap_framebuffer_bo(struct drm_framebuffer *fb)
+{
+	struct omap_framebuffer *omap_fb = to_omap_framebuffer(fb);
+	return omap_fb->bo;
+}
+
+/* iterate thru all the connectors, returning ones that are attached
+ * to the same fb..
+ */
+struct drm_connector *omap_framebuffer_get_next_connector(
+		struct drm_framebuffer *fb, struct drm_connector *from)
+{
+	struct drm_device *dev = fb->dev;
+	struct list_head *connector_list = &dev->mode_config.connector_list;
+	struct drm_connector *connector = from;
+
+	if (!from) {
+		return list_first_entry(connector_list, typeof(*from), head);
+	}
+
+	list_for_each_entry_from(connector, connector_list, head) {
+		if (connector != from) {
+			struct drm_encoder *encoder = connector->encoder;
+			struct drm_crtc *crtc = encoder ? encoder->crtc : NULL;
+			if (crtc && crtc->fb == fb) {
+				return connector;
+			}
+		}
+	}
+
+	return NULL;
+}
+
+/* flush an area of the framebuffer (in case of manual update display that
+ * is not automatically flushed)
+ */
+void omap_framebuffer_flush(struct drm_framebuffer *fb,
+		int x, int y, int w, int h)
+{
+	struct drm_connector *connector = NULL;
+
+	VERB("flush: %d,%d %dx%d, fb=%p", x, y, w, h, fb);
+
+	while ((connector = omap_framebuffer_get_next_connector(fb, connector))) {
+		/* only consider connectors that are part of a chain */
+		if (connector->encoder && connector->encoder->crtc) {
+			/* TODO: maybe this should propagate thru the crtc who
+			 * could do the coordinate translation..
+			 */
+			struct drm_crtc *crtc = connector->encoder->crtc;
+			int cx = max(0, x - crtc->x);
+			int cy = max(0, y - crtc->y);
+			int cw = w + (x - crtc->x) - cx;
+			int ch = h + (y - crtc->y) - cy;
+
+			omap_connector_flush(connector, cx, cy, cw, ch);
+		}
+	}
+}
+
+struct drm_framebuffer *omap_framebuffer_create(struct drm_device *dev,
+		struct drm_file *file, struct drm_mode_fb_cmd *mode_cmd)
+{
+	struct drm_gem_object *bo;
+	struct drm_framebuffer *fb;
+	bo = drm_gem_object_lookup(dev, file, mode_cmd->handle);
+	if (!bo) {
+		return ERR_PTR(-ENOENT);
+	}
+	fb = omap_framebuffer_init(dev, mode_cmd, bo);
+	if (!fb) {
+		return ERR_PTR(-ENOMEM);
+	}
+	return fb;
+}
+
+struct drm_framebuffer *omap_framebuffer_init(struct drm_device *dev,
+		struct drm_mode_fb_cmd *mode_cmd, struct drm_gem_object *bo)
+{
+	struct omap_framebuffer *omap_fb;
+	struct drm_framebuffer *fb = NULL;
+	int size, ret;
+
+	DBG("create framebuffer: dev=%p, mode_cmd=%p (%dx%d@%d)",
+			dev, mode_cmd, mode_cmd->width, mode_cmd->height,
+			mode_cmd->bpp);
+
+	/* in case someone tries to feed us a completely bogus stride: */
+	mode_cmd->pitch = align_pitch(mode_cmd->pitch,
+			mode_cmd->width, mode_cmd->bpp);
+
+	omap_fb = kzalloc(sizeof(*omap_fb), GFP_KERNEL);
+	if (!omap_fb) {
+		dev_err(dev->dev, "could not allocate fb\n");
+		goto fail;
+	}
+
+	fb = &omap_fb->base;
+	ret = drm_framebuffer_init(dev, fb, &omap_framebuffer_funcs);
+	if (ret) {
+		dev_err(dev->dev, "framebuffer init failed: %d\n", ret);
+		goto fail;
+	}
+
+	DBG("create: FB ID: %d (%p)", fb->base.id, fb);
+
+	size = PAGE_ALIGN(mode_cmd->pitch * mode_cmd->height);
+
+	if (size > bo->size) {
+		dev_err(dev->dev, "provided buffer object is too small!\n");
+		goto fail;
+	}
+
+	omap_fb->bo = bo;
+	omap_fb->size = size;
+
+	if (omap_gem_get_paddr(bo, &omap_fb->paddr, true)) {
+		dev_err(dev->dev, "could not map (paddr)!\n");
+		goto fail;
+	}
+
+	drm_helper_mode_fill_fb_struct(fb, mode_cmd);
+
+	return fb;
+
+fail:
+	if (fb) {
+		omap_framebuffer_destroy(fb);
+	}
+	return NULL;
+}
diff --git a/drivers/staging/omapdrm/omap_fbdev.c b/drivers/staging/omapdrm/omap_fbdev.c
new file mode 100644
index 0000000..093ae2f
--- /dev/null
+++ b/drivers/staging/omapdrm/omap_fbdev.c
@@ -0,0 +1,372 @@
+/*
+ * drivers/staging/omapdrm/omap_fbdev.c
+ *
+ * Copyright (C) 2011 Texas Instruments
+ * Author: Rob Clark <rob@ti.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "omap_drv.h"
+
+#include "drm_crtc.h"
+#include "drm_fb_helper.h"
+
+MODULE_PARM_DESC(ywrap, "Enable ywrap scrolling (omap44xx and later, default 'y')");
+static bool ywrap_enabled = true;
+module_param_named(ywrap, ywrap_enabled, bool, 0644);
+
+/*
+ * fbdev funcs, to implement legacy fbdev interface on top of drm driver
+ */
+
+#define to_omap_fbdev(x) container_of(x, struct omap_fbdev, base)
+
+struct omap_fbdev {
+	struct drm_fb_helper base;
+	struct drm_framebuffer *fb;
+	struct drm_gem_object *bo;
+	bool ywrap_enabled;
+};
+
+static void omap_fbdev_flush(struct fb_info *fbi, int x, int y, int w, int h);
+static struct drm_fb_helper *get_fb(struct fb_info *fbi);
+
+static ssize_t omap_fbdev_write(struct fb_info *fbi, const char __user *buf,
+		size_t count, loff_t *ppos)
+{
+	ssize_t res;
+
+	res = fb_sys_write(fbi, buf, count, ppos);
+	omap_fbdev_flush(fbi, 0, 0, fbi->var.xres, fbi->var.yres);
+
+	return res;
+}
+
+static void omap_fbdev_fillrect(struct fb_info *fbi,
+		const struct fb_fillrect *rect)
+{
+	sys_fillrect(fbi, rect);
+	omap_fbdev_flush(fbi, rect->dx, rect->dy, rect->width, rect->height);
+}
+
+static void omap_fbdev_copyarea(struct fb_info *fbi,
+		const struct fb_copyarea *area)
+{
+	sys_copyarea(fbi, area);
+	omap_fbdev_flush(fbi, area->dx, area->dy, area->width, area->height);
+}
+
+static void omap_fbdev_imageblit(struct fb_info *fbi,
+		const struct fb_image *image)
+{
+	sys_imageblit(fbi, image);
+	omap_fbdev_flush(fbi, image->dx, image->dy,
+				image->width, image->height);
+}
+
+static int omap_fbdev_pan_display(struct fb_var_screeninfo *var,
+		struct fb_info *fbi)
+{
+	struct drm_fb_helper *helper = get_fb(fbi);
+	struct omap_fbdev *fbdev = to_omap_fbdev(helper);
+	int npages;
+
+	if (!helper)
+		goto fallback;
+
+	if (!fbdev->ywrap_enabled)
+		goto fallback;
+
+	/* DMM roll shifts in 4K pages: */
+	npages = fbi->fix.line_length >> PAGE_SHIFT;
+	omap_gem_roll(fbdev->bo, var->yoffset * npages);
+
+	return 0;
+
+fallback:
+	return drm_fb_helper_pan_display(var, fbi);
+}
+
+static struct fb_ops omap_fb_ops = {
+	.owner = THIS_MODULE,
+
+	/* Note: to properly handle manual update displays, we wrap the
+	 * basic fbdev ops which write to the framebuffer
+	 */
+	.fb_read = fb_sys_read,
+	.fb_write = omap_fbdev_write,
+	.fb_fillrect = omap_fbdev_fillrect,
+	.fb_copyarea = omap_fbdev_copyarea,
+	.fb_imageblit = omap_fbdev_imageblit,
+
+	.fb_check_var = drm_fb_helper_check_var,
+	.fb_set_par = drm_fb_helper_set_par,
+	.fb_pan_display = omap_fbdev_pan_display,
+	.fb_blank = drm_fb_helper_blank,
+	.fb_setcmap = drm_fb_helper_setcmap,
+
+	.fb_debug_enter = drm_fb_helper_debug_enter,
+	.fb_debug_leave = drm_fb_helper_debug_leave,
+};
+
+static int omap_fbdev_create(struct drm_fb_helper *helper,
+		struct drm_fb_helper_surface_size *sizes)
+{
+	struct omap_fbdev *fbdev = to_omap_fbdev(helper);
+	struct drm_device *dev = helper->dev;
+	struct omap_drm_private *priv = dev->dev_private;
+	struct drm_framebuffer *fb = NULL;
+	union omap_gem_size gsize;
+	struct fb_info *fbi = NULL;
+	struct drm_mode_fb_cmd mode_cmd = {0};
+	dma_addr_t paddr;
+	void __iomem *vaddr;
+	int size, screen_width;
+	int ret;
+
+	/* only doing ARGB32 since this is what is needed to alpha-blend
+	 * with video overlays:
+	 */
+	sizes->surface_bpp = 32;
+	sizes->surface_depth = 32;
+
+	DBG("create fbdev: %dx%d@%d (%dx%d)", sizes->surface_width,
+			sizes->surface_height, sizes->surface_bpp,
+			sizes->fb_width, sizes->fb_height);
+
+	mode_cmd.width = sizes->surface_width;
+	mode_cmd.height = sizes->surface_height;
+
+	mode_cmd.bpp = sizes->surface_bpp;
+	mode_cmd.depth = sizes->surface_depth;
+
+	mode_cmd.pitch = align_pitch(
+			mode_cmd.width * ((mode_cmd.bpp + 7) / 8),
+			mode_cmd.width, mode_cmd.bpp);
+
+	fbdev->ywrap_enabled = priv->has_dmm && ywrap_enabled;
+	if (fbdev->ywrap_enabled) {
+		/* need to align pitch to page size if using DMM scrolling */
+		mode_cmd.pitch = ALIGN(mode_cmd.pitch, PAGE_SIZE);
+	}
+
+	/* allocate backing bo */
+	gsize = (union omap_gem_size){
+		.bytes = PAGE_ALIGN(mode_cmd.pitch * mode_cmd.height),
+	};
+	DBG("allocating %d bytes for fb %d", gsize.bytes, dev->primary->index);
+	fbdev->bo = omap_gem_new(dev, gsize, OMAP_BO_SCANOUT | OMAP_BO_WC);
+	if (!fbdev->bo) {
+		dev_err(dev->dev, "failed to allocate buffer object\n");
+		goto fail;
+	}
+
+	fb = omap_framebuffer_init(dev, &mode_cmd, fbdev->bo);
+	if (!fb) {
+		dev_err(dev->dev, "failed to allocate fb\n");
+		ret = -ENOMEM;
+		goto fail;
+	}
+
+	mutex_lock(&dev->struct_mutex);
+
+	fbi = framebuffer_alloc(0, dev->dev);
+	if (!fbi) {
+		dev_err(dev->dev, "failed to allocate fb info\n");
+		ret = -ENOMEM;
+		goto fail_unlock;
+	}
+
+	DBG("fbi=%p, dev=%p", fbi, dev);
+
+	fbdev->fb = fb;
+	helper->fb = fb;
+	helper->fbdev = fbi;
+
+	fbi->par = helper;
+	fbi->flags = FBINFO_DEFAULT;
+	fbi->fbops = &omap_fb_ops;
+
+	strcpy(fbi->fix.id, MODULE_NAME);
+
+	ret = fb_alloc_cmap(&fbi->cmap, 256, 0);
+	if (ret) {
+		ret = -ENOMEM;
+		goto fail_unlock;
+	}
+
+	drm_fb_helper_fill_fix(fbi, fb->pitch, fb->depth);
+	drm_fb_helper_fill_var(fbi, helper, sizes->fb_width, sizes->fb_height);
+
+	size = omap_framebuffer_get_buffer(fb, 0, 0,
+			&vaddr, &paddr, &screen_width);
+
+	dev->mode_config.fb_base = paddr;
+
+	fbi->screen_base = vaddr;
+	fbi->screen_size = size;
+	fbi->fix.smem_start = paddr;
+	fbi->fix.smem_len = size;
+
+	/* if we have DMM, then we can use it for scrolling by just
+	 * shuffling pages around in DMM rather than doing sw blit.
+	 */
+	if (fbdev->ywrap_enabled) {
+		DRM_INFO("Enabling DMM ywrap scrolling\n");
+		fbi->flags |= FBINFO_HWACCEL_YWRAP | FBINFO_READS_FAST;
+		fbi->fix.ywrapstep = 1;
+	}
+
+
+	DBG("par=%p, %dx%d", fbi->par, fbi->var.xres, fbi->var.yres);
+	DBG("allocated %dx%d fb", fbdev->fb->width, fbdev->fb->height);
+
+	mutex_unlock(&dev->struct_mutex);
+
+	return 0;
+
+fail_unlock:
+	mutex_unlock(&dev->struct_mutex);
+fail:
+
+	if (ret) {
+		if (fbi)
+			framebuffer_release(fbi);
+		if (fb)
+			fb->funcs->destroy(fb);
+	}
+
+	return ret;
+}
+
+static void omap_crtc_fb_gamma_set(struct drm_crtc *crtc,
+		u16 red, u16 green, u16 blue, int regno)
+{
+	DBG("fbdev: set gamma");
+}
+
+static void omap_crtc_fb_gamma_get(struct drm_crtc *crtc,
+		u16 *red, u16 *green, u16 *blue, int regno)
+{
+	DBG("fbdev: get gamma");
+}
+
+static int omap_fbdev_probe(struct drm_fb_helper *helper,
+		struct drm_fb_helper_surface_size *sizes)
+{
+	int new_fb = 0;
+	int ret;
+
+	if (!helper->fb) {
+		ret = omap_fbdev_create(helper, sizes);
+		if (ret)
+			return ret;
+		new_fb = 1;
+	}
+	return new_fb;
+}
+
+static struct drm_fb_helper_funcs omap_fb_helper_funcs = {
+	.gamma_set = omap_crtc_fb_gamma_set,
+	.gamma_get = omap_crtc_fb_gamma_get,
+	.fb_probe = omap_fbdev_probe,
+};
+
+static struct drm_fb_helper *get_fb(struct fb_info *fbi)
+{
+	if (!fbi || strcmp(fbi->fix.id, MODULE_NAME)) {
+		/* these are not the fb's you're looking for */
+		return NULL;
+	}
+	return fbi->par;
+}
+
+/* flush an area of the framebuffer (in case of manual update display that
+ * is not automatically flushed)
+ */
+static void omap_fbdev_flush(struct fb_info *fbi, int x, int y, int w, int h)
+{
+	struct drm_fb_helper *helper = get_fb(fbi);
+
+	if (!helper)
+		return;
+
+	VERB("flush fbdev: %d,%d %dx%d, fbi=%p", x, y, w, h, fbi);
+
+	omap_framebuffer_flush(helper->fb, x, y, w, h);
+}
+
+/* initialize fbdev helper */
+struct drm_fb_helper *omap_fbdev_init(struct drm_device *dev)
+{
+	struct omap_drm_private *priv = dev->dev_private;
+	struct omap_fbdev *fbdev = NULL;
+	struct drm_fb_helper *helper;
+	int ret = 0;
+
+	fbdev = kzalloc(sizeof(*fbdev), GFP_KERNEL);
+	if (!fbdev) {
+		dev_err(dev->dev, "could not allocate fbdev\n");
+		goto fail;
+	}
+
+	helper = &fbdev->base;
+
+	helper->funcs = &omap_fb_helper_funcs;
+
+	ret = drm_fb_helper_init(dev, helper,
+			priv->num_crtcs, priv->num_connectors);
+	if (ret) {
+		dev_err(dev->dev, "could not init fbdev: ret=%d\n", ret);
+		goto fail;
+	}
+
+	drm_fb_helper_single_add_all_connectors(helper);
+	drm_fb_helper_initial_config(helper, 32);
+
+	priv->fbdev = helper;
+
+	return helper;
+
+fail:
+	kfree(fbdev);
+	return NULL;
+}
+
+void omap_fbdev_free(struct drm_device *dev)
+{
+	struct omap_drm_private *priv = dev->dev_private;
+	struct drm_fb_helper *helper = priv->fbdev;
+	struct omap_fbdev *fbdev;
+	struct fb_info *fbi;
+
+	DBG();
+
+	fbi = helper->fbdev;
+
+	unregister_framebuffer(fbi);
+	framebuffer_release(fbi);
+
+	drm_fb_helper_fini(helper);
+
+	fbdev = to_omap_fbdev(priv->fbdev);
+
+	kfree(fbdev);
+
+	/* this will free the backing object */
+	if (fbdev->fb)
+		fbdev->fb->funcs->destroy(fbdev->fb);
+
+	priv->fbdev = NULL;
+}
diff --git a/drivers/staging/omapdrm/omap_gem.c b/drivers/staging/omapdrm/omap_gem.c
new file mode 100644
index 0000000..e0ebd1d
--- /dev/null
+++ b/drivers/staging/omapdrm/omap_gem.c
@@ -0,0 +1,1231 @@
+/*
+ * drivers/staging/omapdrm/omap_gem.c
+ *
+ * Copyright (C) 2011 Texas Instruments
+ * Author: Rob Clark <rob.clark@linaro.org>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+#include <linux/spinlock.h>
+#include <linux/shmem_fs.h>
+
+#include "omap_drv.h"
+#include "omap_dmm_tiler.h"
+
+/* remove these once drm core helpers are merged */
+struct page ** _drm_gem_get_pages(struct drm_gem_object *obj, gfp_t gfpmask);
+void _drm_gem_put_pages(struct drm_gem_object *obj, struct page **pages,
+		bool dirty, bool accessed);
+int _drm_gem_create_mmap_offset_size(struct drm_gem_object *obj, size_t size);
+
+/*
+ * GEM buffer object implementation.
+ */
+
+#define to_omap_bo(x) container_of(x, struct omap_gem_object, base)
+
+/* note: we use upper 8 bits of flags for driver-internal flags: */
+#define OMAP_BO_DMA			0x01000000	/* actually is physically contiguous */
+#define OMAP_BO_EXT_SYNC	0x02000000	/* externally allocated sync object */
+#define OMAP_BO_EXT_MEM		0x04000000	/* externally allocated memory */
+
+
+struct omap_gem_object {
+	struct drm_gem_object base;
+
+	uint32_t flags;
+
+	/** width/height for tiled formats (rounded up to slot boundaries) */
+	uint16_t width, height;
+
+	/** roll applied when mapping to DMM */
+	uint32_t roll;
+
+	/**
+	 * If buffer is allocated physically contiguous, the OMAP_BO_DMA flag
+	 * is set and the paddr is valid.  Also if the buffer is remapped in
+	 * TILER and paddr_cnt > 0, then paddr is valid.  But if you are using
+	 * the physical address and OMAP_BO_DMA is not set, then you should
+	 * be going thru omap_gem_{get,put}_paddr() to ensure the mapping is
+	 * not removed from under your feet.
+	 *
+	 * Note that OMAP_BO_SCANOUT is a hint from userspace that DMA capable
+	 * buffer is requested, but doesn't mean that it is.  Use the
+	 * OMAP_BO_DMA flag to determine if the buffer has a DMA capable
+	 * physical address.
+	 */
+	dma_addr_t paddr;
+
+	/**
+	 * # of users of paddr
+	 */
+	uint32_t paddr_cnt;
+
+	/**
+	 * tiler block used when buffer is remapped in DMM/TILER.
+	 */
+	struct tiler_block *block;
+
+	/**
+	 * Array of backing pages, if allocated.  Note that pages are never
+	 * allocated for buffers originally allocated from contiguous memory
+	 */
+	struct page **pages;
+
+	/** addresses corresponding to pages in above array */
+	dma_addr_t *addrs;
+
+	/**
+	 * Virtual address, if mapped.
+	 */
+	void *vaddr;
+
+	/**
+	 * sync-object allocated on demand (if needed)
+	 *
+	 * Per-buffer sync-object for tracking pending and completed hw/dma
+	 * read and write operations.  The layout in memory is dictated by
+	 * the SGX firmware, which uses this information to stall the command
+	 * stream if a surface is not ready yet.
+	 *
+	 * Note that when buffer is used by SGX, the sync-object needs to be
+	 * allocated from a special heap of sync-objects.  This way many sync
+	 * objects can be packed in a page, and not waste GPU virtual address
+	 * space.  Because of this we have to have a omap_gem_set_sync_object()
+	 * API to allow replacement of the syncobj after it has (potentially)
+	 * already been allocated.  A bit ugly but I haven't thought of a
+	 * better alternative.
+	 */
+	struct {
+		uint32_t write_pending;
+		uint32_t write_complete;
+		uint32_t read_pending;
+		uint32_t read_complete;
+	} *sync;
+};
+
+/* To deal with userspace mmap'ings of 2d tiled buffers, which (a) are
+ * not necessarily pinned in TILER all the time, and (b) when they are
+ * they are not necessarily page aligned, we reserve one or more small
+ * regions in each of the 2d containers to use as a user-GART where we
+ * can create a second page-aligned mapping of parts of the buffer
+ * being accessed from userspace.
+ *
+ * Note that we could optimize slightly when we know that multiple
+ * tiler containers are backed by the same PAT.. but I'll leave that
+ * for later..
+ */
+#define NUM_USERGART_ENTRIES 2
+struct usergart_entry {
+	struct tiler_block *block;	/* the reserved tiler block */
+	dma_addr_t paddr;
+	struct drm_gem_object *obj;	/* the current pinned obj */
+	pgoff_t obj_pgoff;		/* page offset of obj currently
+					   mapped in */
+};
+static struct {
+	struct usergart_entry entry[NUM_USERGART_ENTRIES];
+	int height;				/* height in rows */
+	int height_shift;		/* ilog2(height in rows) */
+	int slot_shift;			/* ilog2(width per slot) */
+	int stride_pfn;			/* stride in pages */
+	int last;				/* index of last used entry */
+} *usergart;
+
+static void evict_entry(struct drm_gem_object *obj,
+		enum tiler_fmt fmt, struct usergart_entry *entry)
+{
+	if (obj->dev->dev_mapping) {
+		size_t size = PAGE_SIZE * usergart[fmt].height;
+		loff_t off = omap_gem_mmap_offset(obj) +
+				(entry->obj_pgoff << PAGE_SHIFT);
+		unmap_mapping_range(obj->dev->dev_mapping, off, size, 1);
+	}
+
+	entry->obj = NULL;
+}
+
+/* Evict a buffer from usergart, if it is mapped there */
+static void evict(struct drm_gem_object *obj)
+{
+	struct omap_gem_object *omap_obj = to_omap_bo(obj);
+
+	if (omap_obj->flags & OMAP_BO_TILED) {
+		enum tiler_fmt fmt = gem2fmt(omap_obj->flags);
+		int i;
+
+		if (!usergart)
+			return;
+
+		for (i = 0; i < NUM_USERGART_ENTRIES; i++) {
+			struct usergart_entry *entry = &usergart[fmt].entry[i];
+			if (entry->obj == obj)
+				evict_entry(obj, fmt, entry);
+		}
+	}
+}
+
+/* GEM objects can either be allocated from contiguous memory (in which
+ * case obj->filp==NULL), or w/ shmem backing (obj->filp!=NULL).  But non
+ * contiguous buffers can be remapped in TILER/DMM if they need to be
+ * contiguous... but we don't do this all the time to reduce pressure
+ * on TILER/DMM space when we know at allocation time that the buffer
+ * will need to be scanned out.
+ */
+static inline bool is_shmem(struct drm_gem_object *obj)
+{
+	return obj->filp != NULL;
+}
+
+static int get_pages(struct drm_gem_object *obj, struct page ***pages);
+
+static DEFINE_SPINLOCK(sync_lock);
+
+/** ensure backing pages are allocated */
+static int omap_gem_attach_pages(struct drm_gem_object *obj)
+{
+	struct omap_gem_object *omap_obj = to_omap_bo(obj);
+	struct page **pages;
+
+	WARN_ON(omap_obj->pages);
+
+	/* TODO: __GFP_DMA32 .. but somehow GFP_HIGHMEM is coming from the
+	 * mapping_gfp_mask(mapping) which conflicts w/ GFP_DMA32.. probably
+	 * we actually want CMA memory for it all anyways..
+	 */
+	pages = _drm_gem_get_pages(obj, GFP_KERNEL);
+	if (IS_ERR(pages)) {
+		dev_err(obj->dev->dev, "could not get pages: %ld\n", PTR_ERR(pages));
+		return PTR_ERR(pages);
+	}
+
+	/* for non-cached buffers, ensure the new pages are clean because
+	 * DSS, GPU, etc. are not cache coherent:
+	 */
+	if (omap_obj->flags & (OMAP_BO_WC|OMAP_BO_UNCACHED)) {
+		int i, npages = obj->size >> PAGE_SHIFT;
+		dma_addr_t *addrs = kmalloc(npages * sizeof(addrs), GFP_KERNEL);
+		for (i = 0; i < npages; i++) {
+			addrs[i] = dma_map_page(obj->dev->dev, pages[i],
+					0, PAGE_SIZE, DMA_BIDIRECTIONAL);
+		}
+		omap_obj->addrs = addrs;
+	}
+
+	omap_obj->pages = pages;
+	return 0;
+}
+
+/** release backing pages */
+static void omap_gem_detach_pages(struct drm_gem_object *obj)
+{
+	struct omap_gem_object *omap_obj = to_omap_bo(obj);
+
+	/* for non-cached buffers, ensure the new pages are clean because
+	 * DSS, GPU, etc. are not cache coherent:
+	 */
+	if (omap_obj->flags & (OMAP_BO_WC|OMAP_BO_UNCACHED)) {
+		int i, npages = obj->size >> PAGE_SHIFT;
+		for (i = 0; i < npages; i++) {
+			dma_unmap_page(obj->dev->dev, omap_obj->addrs[i],
+					PAGE_SIZE, DMA_BIDIRECTIONAL);
+		}
+		kfree(omap_obj->addrs);
+		omap_obj->addrs = NULL;
+	}
+
+	_drm_gem_put_pages(obj, omap_obj->pages, true, false);
+	omap_obj->pages = NULL;
+}
+
+/** get mmap offset */
+uint64_t omap_gem_mmap_offset(struct drm_gem_object *obj)
+{
+	if (!obj->map_list.map) {
+		/* Make it mmapable */
+		size_t size = omap_gem_mmap_size(obj);
+		int ret = _drm_gem_create_mmap_offset_size(obj, size);
+
+		if (ret) {
+			dev_err(obj->dev->dev, "could not allocate mmap offset");
+			return 0;
+		}
+	}
+
+	return (uint64_t)obj->map_list.hash.key << PAGE_SHIFT;
+}
+
+/** get mmap size */
+size_t omap_gem_mmap_size(struct drm_gem_object *obj)
+{
+	struct omap_gem_object *omap_obj = to_omap_bo(obj);
+	size_t size = obj->size;
+
+	if (omap_obj->flags & OMAP_BO_TILED) {
+		/* for tiled buffers, the virtual size has stride rounded up
+		 * to 4kb.. (to hide the fact that row n+1 might start 16kb or
+		 * 32kb later!).  But we don't back the entire buffer with
+		 * pages, only the valid picture part.. so need to adjust for
+		 * this in the size used to mmap and generate mmap offset
+		 */
+		size = tiler_vsize(gem2fmt(omap_obj->flags),
+				omap_obj->width, omap_obj->height);
+	}
+
+	return size;
+}
+
+
+/* Normal handling for the case of faulting in non-tiled buffers */
+static int fault_1d(struct drm_gem_object *obj,
+		struct vm_area_struct *vma, struct vm_fault *vmf)
+{
+	struct omap_gem_object *omap_obj = to_omap_bo(obj);
+	unsigned long pfn;
+	pgoff_t pgoff;
+
+	/* We don't use vmf->pgoff since that has the fake offset: */
+	pgoff = ((unsigned long)vmf->virtual_address -
+			vma->vm_start) >> PAGE_SHIFT;
+
+	if (omap_obj->pages) {
+		pfn = page_to_pfn(omap_obj->pages[pgoff]);
+	} else {
+		BUG_ON(!(omap_obj->flags & OMAP_BO_DMA));
+		pfn = (omap_obj->paddr >> PAGE_SHIFT) + pgoff;
+	}
+
+	VERB("Inserting %p pfn %lx, pa %lx", vmf->virtual_address,
+			pfn, pfn << PAGE_SHIFT);
+
+	return vm_insert_mixed(vma, (unsigned long)vmf->virtual_address, pfn);
+}
+
+/* Special handling for the case of faulting in 2d tiled buffers */
+static int fault_2d(struct drm_gem_object *obj,
+		struct vm_area_struct *vma, struct vm_fault *vmf)
+{
+	struct omap_gem_object *omap_obj = to_omap_bo(obj);
+	struct usergart_entry *entry;
+	enum tiler_fmt fmt = gem2fmt(omap_obj->flags);
+	struct page *pages[64];  /* XXX is this too much to have on stack? */
+	unsigned long pfn;
+	pgoff_t pgoff, base_pgoff;
+	void __user *vaddr;
+	int i, ret, slots;
+
+	if (!usergart)
+		return -EFAULT;
+
+	/* TODO: this fxn might need a bit tweaking to deal w/ tiled buffers
+	 * that are wider than 4kb
+	 */
+
+	/* We don't use vmf->pgoff since that has the fake offset: */
+	pgoff = ((unsigned long)vmf->virtual_address -
+			vma->vm_start) >> PAGE_SHIFT;
+
+	/* actual address we start mapping at is rounded down to previous slot
+	 * boundary in the y direction:
+	 */
+	base_pgoff = round_down(pgoff, usergart[fmt].height);
+	vaddr = vmf->virtual_address - ((pgoff - base_pgoff) << PAGE_SHIFT);
+	entry = &usergart[fmt].entry[usergart[fmt].last];
+
+	slots = omap_obj->width >> usergart[fmt].slot_shift;
+
+	/* evict previous buffer using this usergart entry, if any: */
+	if (entry->obj)
+		evict_entry(entry->obj, fmt, entry);
+
+	entry->obj = obj;
+	entry->obj_pgoff = base_pgoff;
+
+	/* now convert base_pgoff to phys offset from virt offset:
+	 */
+	base_pgoff = (base_pgoff >> usergart[fmt].height_shift) * slots;
+
+	/* map in pages.  Note the height of the slot is also equal to the
+	 * number of pages that need to be mapped in to fill 4kb wide CPU page.
+	 * If the height is 64, then 64 pages fill a 4kb wide by 64 row region.
+	 * Beyond the valid pixel part of the buffer, we set pages[i] to NULL to
+	 * get a dummy page mapped in.. if someone reads/writes it they will get
+	 * random/undefined content, but at least it won't be corrupting
+	 * whatever other random page used to be mapped in, or other undefined
+	 * behavior.
+	 */
+	memcpy(pages, &omap_obj->pages[base_pgoff],
+			sizeof(struct page *) * slots);
+	memset(pages + slots, 0,
+			sizeof(struct page *) * (usergart[fmt].height - slots));
+
+	ret = tiler_pin(entry->block, pages, ARRAY_SIZE(pages), 0, true);
+	if (ret) {
+		dev_err(obj->dev->dev, "failed to pin: %d\n", ret);
+		return ret;
+	}
+
+	i = usergart[fmt].height;
+	pfn = entry->paddr >> PAGE_SHIFT;
+
+	VERB("Inserting %p pfn %lx, pa %lx", vmf->virtual_address,
+			pfn, pfn << PAGE_SHIFT);
+
+	while (i--) {
+		vm_insert_mixed(vma, (unsigned long)vaddr, pfn);
+		pfn += usergart[fmt].stride_pfn;
+		vaddr += PAGE_SIZE;
+	}
+
+	/* simple round-robin: */
+	usergart[fmt].last = (usergart[fmt].last + 1) % NUM_USERGART_ENTRIES;
+
+	return 0;
+}
+
+/**
+ * omap_gem_fault		-	pagefault handler for GEM objects
+ * @vma: the VMA of the GEM object
+ * @vmf: fault detail
+ *
+ * Invoked when a fault occurs on an mmap of a GEM managed area. GEM
+ * does most of the work for us including the actual map/unmap calls
+ * but we need to do the actual page work.
+ *
+ * The VMA was set up by GEM. In doing so it also ensured that the
+ * vma->vm_private_data points to the GEM object that is backing this
+ * mapping.
+ */
+int omap_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
+{
+	struct drm_gem_object *obj = vma->vm_private_data;
+	struct omap_gem_object *omap_obj = to_omap_bo(obj);
+	struct drm_device *dev = obj->dev;
+	struct page **pages;
+	int ret;
+
+	/* Make sure we don't parallel update on a fault, nor move or remove
+	 * something from beneath our feet
+	 */
+	mutex_lock(&dev->struct_mutex);
+
+	/* if a shmem backed object, make sure we have pages attached now */
+	ret = get_pages(obj, &pages);
+	if (ret) {
+		goto fail;
+	}
+
+	/* where should we do corresponding put_pages().. we are mapping
+	 * the original page, rather than thru a GART, so we can't rely
+	 * on eviction to trigger this.  But munmap() or all mappings should
+	 * probably trigger put_pages()?
+	 */
+
+	if (omap_obj->flags & OMAP_BO_TILED)
+		ret = fault_2d(obj, vma, vmf);
+	else
+		ret = fault_1d(obj, vma, vmf);
+
+
+fail:
+	mutex_unlock(&dev->struct_mutex);
+	switch (ret) {
+	case 0:
+	case -ERESTARTSYS:
+	case -EINTR:
+		return VM_FAULT_NOPAGE;
+	case -ENOMEM:
+		return VM_FAULT_OOM;
+	default:
+		return VM_FAULT_SIGBUS;
+	}
+}
+
+/** We override mainly to fix up some of the vm mapping flags.. */
+int omap_gem_mmap(struct file *filp, struct vm_area_struct *vma)
+{
+	struct omap_gem_object *omap_obj;
+	int ret;
+
+	ret = drm_gem_mmap(filp, vma);
+	if (ret) {
+		DBG("mmap failed: %d", ret);
+		return ret;
+	}
+
+	/* after drm_gem_mmap(), it is safe to access the obj */
+	omap_obj = to_omap_bo(vma->vm_private_data);
+
+	vma->vm_flags &= ~VM_PFNMAP;
+	vma->vm_flags |= VM_MIXEDMAP;
+
+	if (omap_obj->flags & OMAP_BO_WC) {
+		vma->vm_page_prot = pgprot_writecombine(vm_get_page_prot(vma->vm_flags));
+	} else if (omap_obj->flags & OMAP_BO_UNCACHED) {
+		vma->vm_page_prot = pgprot_noncached(vm_get_page_prot(vma->vm_flags));
+	} else {
+		vma->vm_page_prot = vm_get_page_prot(vma->vm_flags);
+	}
+
+	return ret;
+}
+
+/**
+ * omap_gem_dumb_create	-	create a dumb buffer
+ * @drm_file: our client file
+ * @dev: our device
+ * @args: the requested arguments copied from userspace
+ *
+ * Allocate a buffer suitable for use for a frame buffer of the
+ * form described by user space. Give userspace a handle by which
+ * to reference it.
+ */
+int omap_gem_dumb_create(struct drm_file *file, struct drm_device *dev,
+		struct drm_mode_create_dumb *args)
+{
+	union omap_gem_size gsize;
+
+	/* in case someone tries to feed us a completely bogus stride: */
+	args->pitch = align_pitch(args->pitch, args->width, args->bpp);
+	args->size = PAGE_ALIGN(args->pitch * args->height);
+
+	gsize = (union omap_gem_size){
+		.bytes = args->size,
+	};
+
+	return omap_gem_new_handle(dev, file, gsize,
+			OMAP_BO_SCANOUT | OMAP_BO_WC, &args->handle);
+}
+
+/**
+ * omap_gem_dumb_destroy	-	destroy a dumb buffer
+ * @file: client file
+ * @dev: our DRM device
+ * @handle: the object handle
+ *
+ * Destroy a handle that was created via omap_gem_dumb_create.
+ */
+int omap_gem_dumb_destroy(struct drm_file *file, struct drm_device *dev,
+		uint32_t handle)
+{
+	/* No special work needed, drop the reference and see what falls out */
+	return drm_gem_handle_delete(file, handle);
+}
+
+/**
+ * omap_gem_dumb_map	-	buffer mapping for dumb interface
+ * @file: our drm client file
+ * @dev: drm device
+ * @handle: GEM handle to the object (from dumb_create)
+ *
+ * Do the necessary setup to allow the mapping of the frame buffer
+ * into user memory. We don't have to do much here at the moment.
+ */
+int omap_gem_dumb_map_offset(struct drm_file *file, struct drm_device *dev,
+		uint32_t handle, uint64_t *offset)
+{
+	struct drm_gem_object *obj;
+	int ret = 0;
+
+	/* GEM does all our handle to object mapping */
+	obj = drm_gem_object_lookup(dev, file, handle);
+	if (obj == NULL) {
+		ret = -ENOENT;
+		goto fail;
+	}
+
+	*offset = omap_gem_mmap_offset(obj);
+
+	drm_gem_object_unreference_unlocked(obj);
+
+fail:
+	return ret;
+}
+
+/* Set scrolling position.  This allows us to implement fast scrolling
+ * for console.
+ */
+int omap_gem_roll(struct drm_gem_object *obj, uint32_t roll)
+{
+	struct omap_gem_object *omap_obj = to_omap_bo(obj);
+	uint32_t npages = obj->size >> PAGE_SHIFT;
+	int ret = 0;
+
+	if (roll > npages) {
+		dev_err(obj->dev->dev, "invalid roll: %d\n", roll);
+		return -EINVAL;
+	}
+
+	omap_obj->roll = roll;
+
+	if (in_atomic() || mutex_is_locked(&obj->dev->struct_mutex)) {
+		/* this can get called from fbcon in atomic context.. so
+		 * just ignore it and wait for next time called from
+		 * interruptible context to update the PAT.. the result
+		 * may be that user sees wrap-around instead of scrolling
+		 * momentarily on the screen.  If we wanted to be fancier
+		 * we could perhaps schedule some workqueue work at this
+		 * point.
+		 */
+		return 0;
+	}
+
+	mutex_lock(&obj->dev->struct_mutex);
+
+	/* if we aren't mapped yet, we don't need to do anything */
+	if (omap_obj->block) {
+		struct page **pages;
+		ret = get_pages(obj, &pages);
+		if (ret)
+			goto fail;
+		ret = tiler_pin(omap_obj->block, pages, npages, roll, true);
+		if (ret)
+			dev_err(obj->dev->dev, "could not repin: %d\n", ret);
+	}
+
+fail:
+	mutex_unlock(&obj->dev->struct_mutex);
+
+	return ret;
+}
+
+/* Get physical address for DMA.. if 'remap' is true, and the buffer is not
+ * already contiguous, remap it to pin in physically contiguous memory.. (ie.
+ * map in TILER)
+ */
+int omap_gem_get_paddr(struct drm_gem_object *obj,
+		dma_addr_t *paddr, bool remap)
+{
+	struct omap_drm_private *priv = obj->dev->dev_private;
+	struct omap_gem_object *omap_obj = to_omap_bo(obj);
+	int ret = 0;
+
+	mutex_lock(&obj->dev->struct_mutex);
+
+	if (remap && is_shmem(obj) && priv->has_dmm) {
+		if (omap_obj->paddr_cnt == 0) {
+			struct page **pages;
+			uint32_t npages = obj->size >> PAGE_SHIFT;
+			enum tiler_fmt fmt = gem2fmt(omap_obj->flags);
+			struct tiler_block *block;
+
+			BUG_ON(omap_obj->block);
+
+			ret = get_pages(obj, &pages);
+			if (ret)
+				goto fail;
+
+			if (omap_obj->flags & OMAP_BO_TILED) {
+				block = tiler_reserve_2d(fmt,
+						omap_obj->width,
+						omap_obj->height, 0);
+			} else {
+				block = tiler_reserve_1d(obj->size);
+			}
+
+			if (IS_ERR(block)) {
+				ret = PTR_ERR(block);
+				dev_err(obj->dev->dev,
+					"could not remap: %d (%d)\n", ret, fmt);
+				goto fail;
+			}
+
+			/* TODO: enable async refill.. */
+			ret = tiler_pin(block, pages, npages,
+					omap_obj->roll, true);
+			if (ret) {
+				tiler_release(block);
+				dev_err(obj->dev->dev,
+						"could not pin: %d\n", ret);
+				goto fail;
+			}
+
+			omap_obj->paddr = tiler_ssptr(block);
+			omap_obj->block = block;
+
+			DBG("got paddr: %08x", omap_obj->paddr);
+		}
+
+		omap_obj->paddr_cnt++;
+
+		*paddr = omap_obj->paddr;
+	} else if (omap_obj->flags & OMAP_BO_DMA) {
+		*paddr = omap_obj->paddr;
+	} else {
+		ret = -EINVAL;
+	}
+
+fail:
+	mutex_unlock(&obj->dev->struct_mutex);
+
+	return ret;
+}
+
+/* Release physical address, when DMA is no longer being performed.. this
+ * could potentially unpin and unmap buffers from TILER
+ */
+int omap_gem_put_paddr(struct drm_gem_object *obj)
+{
+	struct omap_gem_object *omap_obj = to_omap_bo(obj);
+	int ret = 0;
+
+	mutex_lock(&obj->dev->struct_mutex);
+	if (omap_obj->paddr_cnt > 0) {
+		omap_obj->paddr_cnt--;
+		if (omap_obj->paddr_cnt == 0) {
+			ret = tiler_unpin(omap_obj->block);
+			if (ret) {
+				dev_err(obj->dev->dev,
+					"could not unpin pages: %d\n", ret);
+				goto fail;
+			}
+			ret = tiler_release(omap_obj->block);
+			if (ret) {
+				dev_err(obj->dev->dev,
+					"could not release unmap: %d\n", ret);
+			}
+			omap_obj->block = NULL;
+		}
+	}
+fail:
+	mutex_unlock(&obj->dev->struct_mutex);
+	return ret;
+}
+
+/* acquire pages when needed (for example, for DMA where physically
+ * contiguous buffer is not required
+ */
+static int get_pages(struct drm_gem_object *obj, struct page ***pages)
+{
+	struct omap_gem_object *omap_obj = to_omap_bo(obj);
+	int ret = 0;
+
+	if (is_shmem(obj) && !omap_obj->pages) {
+		ret = omap_gem_attach_pages(obj);
+		if (ret) {
+			dev_err(obj->dev->dev, "could not attach pages\n");
+			return ret;
+		}
+	}
+
+	/* TODO: even phys-contig.. we should have a list of pages? */
+	*pages = omap_obj->pages;
+
+	return 0;
+}
+
+int omap_gem_get_pages(struct drm_gem_object *obj, struct page ***pages)
+{
+	int ret;
+	mutex_lock(&obj->dev->struct_mutex);
+	ret = get_pages(obj, pages);
+	mutex_unlock(&obj->dev->struct_mutex);
+	return ret;
+}
+
+/* release pages when DMA no longer being performed */
+int omap_gem_put_pages(struct drm_gem_object *obj)
+{
+	/* do something here if we dynamically attach/detach pages.. at
+	 * least they would no longer need to be pinned if everyone has
+	 * released the pages..
+	 */
+	return 0;
+}
+
+/* Get kernel virtual address for CPU access.. this more or less only
+ * exists for omap_fbdev.  This should be called with struct_mutex
+ * held.
+ */
+void *omap_gem_vaddr(struct drm_gem_object *obj)
+{
+	struct omap_gem_object *omap_obj = to_omap_bo(obj);
+	WARN_ON(! mutex_is_locked(&obj->dev->struct_mutex));
+	if (!omap_obj->vaddr) {
+		struct page **pages;
+		int ret = get_pages(obj, &pages);
+		if (ret)
+			return ERR_PTR(ret);
+		omap_obj->vaddr = vmap(pages, obj->size >> PAGE_SHIFT,
+				VM_MAP, pgprot_writecombine(PAGE_KERNEL));
+	}
+	return omap_obj->vaddr;
+}
+
+/* Buffer Synchronization:
+ */
+
+struct omap_gem_sync_waiter {
+	struct list_head list;
+	struct omap_gem_object *omap_obj;
+	enum omap_gem_op op;
+	uint32_t read_target, write_target;
+	/* notify called w/ sync_lock held */
+	void (*notify)(void *arg);
+	void *arg;
+};
+
+/* list of omap_gem_sync_waiter.. the notify fxn gets called back when
+ * the read and/or write target count is achieved which can call a user
+ * callback (ex. to kick 3d and/or 2d), wakeup blocked task (prep for
+ * cpu access), etc.
+ */
+static LIST_HEAD(waiters);
+
+static inline bool is_waiting(struct omap_gem_sync_waiter *waiter)
+{
+	struct omap_gem_object *omap_obj = waiter->omap_obj;
+	if ((waiter->op & OMAP_GEM_READ) &&
+			(omap_obj->sync->read_complete < waiter->read_target))
+		return true;
+	if ((waiter->op & OMAP_GEM_WRITE) &&
+			(omap_obj->sync->write_complete < waiter->write_target))
+		return true;
+	return false;
+}
+
+/* macro for sync debug.. */
+#define SYNCDBG 0
+#define SYNC(fmt, ...) do { if (SYNCDBG) \
+		printk(KERN_ERR "%s:%d: "fmt"\n", \
+				__func__, __LINE__, ##__VA_ARGS__); \
+	} while (0)
+
+
+static void sync_op_update(void)
+{
+	struct omap_gem_sync_waiter *waiter, *n;
+	list_for_each_entry_safe(waiter, n, &waiters, list) {
+		if (!is_waiting(waiter)) {
+			list_del(&waiter->list);
+			SYNC("notify: %p", waiter);
+			waiter->notify(waiter->arg);
+			kfree(waiter);
+		}
+	}
+}
+
+static inline int sync_op(struct drm_gem_object *obj,
+		enum omap_gem_op op, bool start)
+{
+	struct omap_gem_object *omap_obj = to_omap_bo(obj);
+	int ret = 0;
+
+	spin_lock(&sync_lock);
+
+	if (!omap_obj->sync) {
+		omap_obj->sync = kzalloc(sizeof(*omap_obj->sync), GFP_ATOMIC);
+		if (!omap_obj->sync) {
+			ret = -ENOMEM;
+			goto unlock;
+		}
+	}
+
+	if (start) {
+		if (op & OMAP_GEM_READ)
+			omap_obj->sync->read_pending++;
+		if (op & OMAP_GEM_WRITE)
+			omap_obj->sync->write_pending++;
+	} else {
+		if (op & OMAP_GEM_READ)
+			omap_obj->sync->read_complete++;
+		if (op & OMAP_GEM_WRITE)
+			omap_obj->sync->write_complete++;
+		sync_op_update();
+	}
+
+unlock:
+	spin_unlock(&sync_lock);
+
+	return ret;
+}
+
+/* it is a bit lame to handle updates in this sort of polling way, but
+ * in case of PVR, the GPU can directly update read/write complete
+ * values, and not really tell us which ones it updated.. this also
+ * means that sync_lock is not quite sufficient.  So we'll need to
+ * do something a bit better when it comes time to add support for
+ * separate 2d hw..
+ */
+void omap_gem_op_update(void)
+{
+	spin_lock(&sync_lock);
+	sync_op_update();
+	spin_unlock(&sync_lock);
+}
+
+/* mark the start of read and/or write operation */
+int omap_gem_op_start(struct drm_gem_object *obj, enum omap_gem_op op)
+{
+	return sync_op(obj, op, true);
+}
+
+int omap_gem_op_finish(struct drm_gem_object *obj, enum omap_gem_op op)
+{
+	return sync_op(obj, op, false);
+}
+
+static DECLARE_WAIT_QUEUE_HEAD(sync_event);
+
+static void sync_notify(void *arg)
+{
+	struct task_struct **waiter_task = arg;
+	*waiter_task = NULL;
+	wake_up_all(&sync_event);
+}
+
+int omap_gem_op_sync(struct drm_gem_object *obj, enum omap_gem_op op)
+{
+	struct omap_gem_object *omap_obj = to_omap_bo(obj);
+	int ret = 0;
+	if (omap_obj->sync) {
+		struct task_struct *waiter_task = current;
+		struct omap_gem_sync_waiter *waiter =
+				kzalloc(sizeof(*waiter), GFP_KERNEL);
+
+		if (!waiter) {
+			return -ENOMEM;
+		}
+
+		waiter->omap_obj = omap_obj;
+		waiter->op = op;
+		waiter->read_target = omap_obj->sync->read_pending;
+		waiter->write_target = omap_obj->sync->write_pending;
+		waiter->notify = sync_notify;
+		waiter->arg = &waiter_task;
+
+		spin_lock(&sync_lock);
+		if (is_waiting(waiter)) {
+			SYNC("waited: %p", waiter);
+			list_add_tail(&waiter->list, &waiters);
+			spin_unlock(&sync_lock);
+			ret = wait_event_interruptible(sync_event,
+					(waiter_task == NULL));
+			spin_lock(&sync_lock);
+			if (waiter_task) {
+				SYNC("interrupted: %p", waiter);
+				/* we were interrupted */
+				list_del(&waiter->list);
+				waiter_task = NULL;
+			} else {
+				/* freed in sync_op_update() */
+				waiter = NULL;
+			}
+		}
+		spin_unlock(&sync_lock);
+
+		if (waiter) {
+			kfree(waiter);
+		}
+	}
+	return ret;
+}
+
+/* call fxn(arg), either synchronously or asynchronously if the op
+ * is currently blocked..  fxn() can be called from any context
+ *
+ * (TODO for now fxn is called back from whichever context calls
+ * omap_gem_op_update().. but this could be better defined later
+ * if needed)
+ *
+ * TODO more code in common w/ _sync()..
+ */
+int omap_gem_op_async(struct drm_gem_object *obj, enum omap_gem_op op,
+		void (*fxn)(void *arg), void *arg)
+{
+	struct omap_gem_object *omap_obj = to_omap_bo(obj);
+	if (omap_obj->sync) {
+		struct omap_gem_sync_waiter *waiter =
+				kzalloc(sizeof(*waiter), GFP_ATOMIC);
+
+		if (!waiter) {
+			return -ENOMEM;
+		}
+
+		waiter->omap_obj = omap_obj;
+		waiter->op = op;
+		waiter->read_target = omap_obj->sync->read_pending;
+		waiter->write_target = omap_obj->sync->write_pending;
+		waiter->notify = fxn;
+		waiter->arg = arg;
+
+		spin_lock(&sync_lock);
+		if (is_waiting(waiter)) {
+			SYNC("waited: %p", waiter);
+			list_add_tail(&waiter->list, &waiters);
+			spin_unlock(&sync_lock);
+			return 0;
+		}
+
+		spin_unlock(&sync_lock);
+	}
+
+	/* no waiting.. */
+	fxn(arg);
+
+	return 0;
+}
+
+/* special API so PVR can update the buffer to use a sync-object allocated
+ * from it's sync-obj heap.  Only used for a newly allocated (from PVR's
+ * perspective) sync-object, so we overwrite the new syncobj w/ values
+ * from the already allocated syncobj (if there is one)
+ */
+int omap_gem_set_sync_object(struct drm_gem_object *obj, void *syncobj)
+{
+	struct omap_gem_object *omap_obj = to_omap_bo(obj);
+	int ret = 0;
+
+	spin_lock(&sync_lock);
+
+	if ((omap_obj->flags & OMAP_BO_EXT_SYNC) && !syncobj) {
+		/* clearing a previously set syncobj */
+		syncobj = kzalloc(sizeof(*omap_obj->sync), GFP_ATOMIC);
+		if (!syncobj) {
+			ret = -ENOMEM;
+			goto unlock;
+		}
+		memcpy(syncobj, omap_obj->sync, sizeof(*omap_obj->sync));
+		omap_obj->flags &= ~OMAP_BO_EXT_SYNC;
+		omap_obj->sync = syncobj;
+	} else if (syncobj && !(omap_obj->flags & OMAP_BO_EXT_SYNC)) {
+		/* replacing an existing syncobj */
+		if (omap_obj->sync) {
+			memcpy(syncobj, omap_obj->sync, sizeof(*omap_obj->sync));
+			kfree(omap_obj->sync);
+		}
+		omap_obj->flags |= OMAP_BO_EXT_SYNC;
+		omap_obj->sync = syncobj;
+	}
+
+unlock:
+	spin_unlock(&sync_lock);
+	return ret;
+}
+
+int omap_gem_init_object(struct drm_gem_object *obj)
+{
+	return -EINVAL;          /* unused */
+}
+
+/* don't call directly.. called from GEM core when it is time to actually
+ * free the object..
+ */
+void omap_gem_free_object(struct drm_gem_object *obj)
+{
+	struct drm_device *dev = obj->dev;
+	struct omap_gem_object *omap_obj = to_omap_bo(obj);
+
+	evict(obj);
+
+	if (obj->map_list.map) {
+		drm_gem_free_mmap_offset(obj);
+	}
+
+	/* don't free externally allocated backing memory */
+	if (!(omap_obj->flags & OMAP_BO_EXT_MEM)) {
+		if (omap_obj->pages) {
+			omap_gem_detach_pages(obj);
+		}
+		if (!is_shmem(obj)) {
+			dma_free_writecombine(dev->dev, obj->size,
+					omap_obj->vaddr, omap_obj->paddr);
+		} else if (omap_obj->vaddr) {
+			vunmap(omap_obj->vaddr);
+		}
+	}
+
+	/* don't free externally allocated syncobj */
+	if (!(omap_obj->flags & OMAP_BO_EXT_SYNC)) {
+		kfree(omap_obj->sync);
+	}
+
+	drm_gem_object_release(obj);
+
+	kfree(obj);
+}
+
+/* convenience method to construct a GEM buffer object, and userspace handle */
+int omap_gem_new_handle(struct drm_device *dev, struct drm_file *file,
+		union omap_gem_size gsize, uint32_t flags, uint32_t *handle)
+{
+	struct drm_gem_object *obj;
+	int ret;
+
+	obj = omap_gem_new(dev, gsize, flags);
+	if (!obj)
+		return -ENOMEM;
+
+	ret = drm_gem_handle_create(file, obj, handle);
+	if (ret) {
+		drm_gem_object_release(obj);
+		kfree(obj); /* TODO isn't there a dtor to call? just copying i915 */
+		return ret;
+	}
+
+	/* drop reference from allocate - handle holds it now */
+	drm_gem_object_unreference_unlocked(obj);
+
+	return 0;
+}
+
+/* GEM buffer object constructor */
+struct drm_gem_object *omap_gem_new(struct drm_device *dev,
+		union omap_gem_size gsize, uint32_t flags)
+{
+	struct omap_drm_private *priv = dev->dev_private;
+	struct omap_gem_object *omap_obj;
+	struct drm_gem_object *obj = NULL;
+	size_t size;
+	int ret;
+
+	if (flags & OMAP_BO_TILED) {
+		if (!usergart) {
+			dev_err(dev->dev, "Tiled buffers require DMM\n");
+			goto fail;
+		}
+
+		/* tiled buffers are always shmem paged backed.. when they are
+		 * scanned out, they are remapped into DMM/TILER
+		 */
+		flags &= ~OMAP_BO_SCANOUT;
+
+		/* currently don't allow cached buffers.. there is some caching
+		 * stuff that needs to be handled better
+		 */
+		flags &= ~(OMAP_BO_CACHED|OMAP_BO_UNCACHED);
+		flags |= OMAP_BO_WC;
+
+		/* align dimensions to slot boundaries... */
+		tiler_align(gem2fmt(flags),
+				&gsize.tiled.width, &gsize.tiled.height);
+
+		/* ...and calculate size based on aligned dimensions */
+		size = tiler_size(gem2fmt(flags),
+				gsize.tiled.width, gsize.tiled.height);
+	} else {
+		size = PAGE_ALIGN(gsize.bytes);
+	}
+
+	omap_obj = kzalloc(sizeof(*omap_obj), GFP_KERNEL);
+	if (!omap_obj) {
+		dev_err(dev->dev, "could not allocate GEM object\n");
+		goto fail;
+	}
+
+	obj = &omap_obj->base;
+
+	if ((flags & OMAP_BO_SCANOUT) && !priv->has_dmm) {
+		/* attempt to allocate contiguous memory if we don't
+		 * have DMM for remappign discontiguous buffers
+		 */
+		omap_obj->vaddr =  dma_alloc_writecombine(dev->dev, size,
+				&omap_obj->paddr, GFP_KERNEL);
+		if (omap_obj->vaddr) {
+			flags |= OMAP_BO_DMA;
+		}
+	}
+
+	omap_obj->flags = flags;
+
+	if (flags & OMAP_BO_TILED) {
+		omap_obj->width = gsize.tiled.width;
+		omap_obj->height = gsize.tiled.height;
+	}
+
+	if (flags & (OMAP_BO_DMA|OMAP_BO_EXT_MEM)) {
+		ret = drm_gem_private_object_init(dev, obj, size);
+	} else {
+		ret = drm_gem_object_init(dev, obj, size);
+	}
+
+	if (ret) {
+		goto fail;
+	}
+
+	return obj;
+
+fail:
+	if (obj) {
+		omap_gem_free_object(obj);
+	}
+	return NULL;
+}
+
+/* init/cleanup.. if DMM is used, we need to set some stuff up.. */
+void omap_gem_init(struct drm_device *dev)
+{
+	struct omap_drm_private *priv = dev->dev_private;
+	const enum tiler_fmt fmts[] = {
+			TILFMT_8BIT, TILFMT_16BIT, TILFMT_32BIT
+	};
+	int i, j, ret;
+
+	ret = omap_dmm_init(dev);
+	if (ret) {
+		/* DMM only supported on OMAP4 and later, so this isn't fatal */
+		dev_warn(dev->dev, "omap_dmm_init failed, disabling DMM\n");
+		return;
+	}
+
+	usergart = kzalloc(3 * sizeof(*usergart), GFP_KERNEL);
+	if (!usergart) {
+		dev_warn(dev->dev, "could not allocate usergart\n");
+		return;
+	}
+
+	/* reserve 4k aligned/wide regions for userspace mappings: */
+	for (i = 0; i < ARRAY_SIZE(fmts); i++) {
+		uint16_t h = 1, w = PAGE_SIZE >> i;
+		tiler_align(fmts[i], &w, &h);
+		/* note: since each region is 1 4kb page wide, and minimum
+		 * number of rows, the height ends up being the same as the
+		 * # of pages in the region
+		 */
+		usergart[i].height = h;
+		usergart[i].height_shift = ilog2(h);
+		usergart[i].stride_pfn = tiler_stride(fmts[i]) >> PAGE_SHIFT;
+		usergart[i].slot_shift = ilog2((PAGE_SIZE / h) >> i);
+		for (j = 0; j < NUM_USERGART_ENTRIES; j++) {
+			struct usergart_entry *entry = &usergart[i].entry[j];
+			struct tiler_block *block =
+					tiler_reserve_2d(fmts[i], w, h,
+							PAGE_SIZE);
+			if (IS_ERR(block)) {
+				dev_err(dev->dev,
+						"reserve failed: %d, %d, %ld\n",
+						i, j, PTR_ERR(block));
+				return;
+			}
+			entry->paddr = tiler_ssptr(block);
+			entry->block = block;
+
+			DBG("%d:%d: %dx%d: paddr=%08x stride=%d", i, j, w, h,
+					entry->paddr,
+					usergart[i].stride_pfn << PAGE_SHIFT);
+		}
+	}
+
+	priv->has_dmm = true;
+}
+
+void omap_gem_deinit(struct drm_device *dev)
+{
+	/* I believe we can rely on there being no more outstanding GEM
+	 * objects which could depend on usergart/dmm at this point.
+	 */
+	omap_dmm_remove();
+	kfree(usergart);
+}
diff --git a/drivers/staging/omapdrm/omap_gem_helpers.c b/drivers/staging/omapdrm/omap_gem_helpers.c
new file mode 100644
index 0000000..29275c7
--- /dev/null
+++ b/drivers/staging/omapdrm/omap_gem_helpers.c
@@ -0,0 +1,169 @@
+/*
+ * drivers/staging/omapdrm/omap_gem_helpers.c
+ *
+ * Copyright (C) 2011 Texas Instruments
+ * Author: Rob Clark <rob.clark@linaro.org>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/* temporary copy of drm_gem_{get,put}_pages() until the
+ * "drm/gem: add functions to get/put pages" patch is merged..
+ */
+
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/shmem_fs.h>
+
+#include <drm/drmP.h>
+
+/**
+ * drm_gem_get_pages - helper to allocate backing pages for a GEM object
+ * @obj: obj in question
+ * @gfpmask: gfp mask of requested pages
+ */
+struct page ** _drm_gem_get_pages(struct drm_gem_object *obj, gfp_t gfpmask)
+{
+	struct inode *inode;
+	struct address_space *mapping;
+	struct page *p, **pages;
+	int i, npages;
+
+	/* This is the shared memory object that backs the GEM resource */
+	inode = obj->filp->f_path.dentry->d_inode;
+	mapping = inode->i_mapping;
+
+	npages = obj->size >> PAGE_SHIFT;
+
+	pages = drm_malloc_ab(npages, sizeof(struct page *));
+	if (pages == NULL)
+		return ERR_PTR(-ENOMEM);
+
+	gfpmask |= mapping_gfp_mask(mapping);
+
+	for (i = 0; i < npages; i++) {
+		p = shmem_read_mapping_page_gfp(mapping, i, gfpmask);
+		if (IS_ERR(p))
+			goto fail;
+		pages[i] = p;
+
+		/* There is a hypothetical issue w/ drivers that require
+		 * buffer memory in the low 4GB.. if the pages are un-
+		 * pinned, and swapped out, they can end up swapped back
+		 * in above 4GB.  If pages are already in memory, then
+		 * shmem_read_mapping_page_gfp will ignore the gfpmask,
+		 * even if the already in-memory page disobeys the mask.
+		 *
+		 * It is only a theoretical issue today, because none of
+		 * the devices with this limitation can be populated with
+		 * enough memory to trigger the issue.  But this BUG_ON()
+		 * is here as a reminder in case the problem with
+		 * shmem_read_mapping_page_gfp() isn't solved by the time
+		 * it does become a real issue.
+		 *
+		 * See this thread: http://lkml.org/lkml/2011/7/11/238
+		 */
+		BUG_ON((gfpmask & __GFP_DMA32) &&
+				(page_to_pfn(p) >= 0x00100000UL));
+	}
+
+	return pages;
+
+fail:
+	while (i--) {
+		page_cache_release(pages[i]);
+	}
+	drm_free_large(pages);
+	return ERR_PTR(PTR_ERR(p));
+}
+
+/**
+ * drm_gem_put_pages - helper to free backing pages for a GEM object
+ * @obj: obj in question
+ * @pages: pages to free
+ */
+void _drm_gem_put_pages(struct drm_gem_object *obj, struct page **pages,
+		bool dirty, bool accessed)
+{
+	int i, npages;
+
+	npages = obj->size >> PAGE_SHIFT;
+
+	for (i = 0; i < npages; i++) {
+		if (dirty)
+			set_page_dirty(pages[i]);
+
+		if (accessed)
+			mark_page_accessed(pages[i]);
+
+		/* Undo the reference we took when populating the table */
+		page_cache_release(pages[i]);
+	}
+
+	drm_free_large(pages);
+}
+
+int
+_drm_gem_create_mmap_offset_size(struct drm_gem_object *obj, size_t size)
+{
+	struct drm_device *dev = obj->dev;
+	struct drm_gem_mm *mm = dev->mm_private;
+	struct drm_map_list *list;
+	struct drm_local_map *map;
+	int ret = 0;
+
+	/* Set the object up for mmap'ing */
+	list = &obj->map_list;
+	list->map = kzalloc(sizeof(struct drm_map_list), GFP_KERNEL);
+	if (!list->map)
+		return -ENOMEM;
+
+	map = list->map;
+	map->type = _DRM_GEM;
+	map->size = size;
+	map->handle = obj;
+
+	/* Get a DRM GEM mmap offset allocated... */
+	list->file_offset_node = drm_mm_search_free(&mm->offset_manager,
+			size / PAGE_SIZE, 0, 0);
+
+	if (!list->file_offset_node) {
+		DRM_ERROR("failed to allocate offset for bo %d\n", obj->name);
+		ret = -ENOSPC;
+		goto out_free_list;
+	}
+
+	list->file_offset_node = drm_mm_get_block(list->file_offset_node,
+			size / PAGE_SIZE, 0);
+	if (!list->file_offset_node) {
+		ret = -ENOMEM;
+		goto out_free_list;
+	}
+
+	list->hash.key = list->file_offset_node->start;
+	ret = drm_ht_insert_item(&mm->offset_hash, &list->hash);
+	if (ret) {
+		DRM_ERROR("failed to add to map hash\n");
+		goto out_free_mm;
+	}
+
+	return 0;
+
+out_free_mm:
+	drm_mm_put_block(list->file_offset_node);
+out_free_list:
+	kfree(list->map);
+	list->map = NULL;
+
+	return ret;
+}
diff --git a/drivers/staging/omapdrm/omap_priv.h b/drivers/staging/omapdrm/omap_priv.h
new file mode 100644
index 0000000..c324709
--- /dev/null
+++ b/drivers/staging/omapdrm/omap_priv.h
@@ -0,0 +1,47 @@
+/*
+ * include/drm/omap_priv.h
+ *
+ * Copyright (C) 2011 Texas Instruments
+ * Author: Rob Clark <rob@ti.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef __OMAP_PRIV_H__
+#define __OMAP_PRIV_H__
+
+/* Non-userspace facing APIs
+ */
+
+/* optional platform data to configure the default configuration of which
+ * pipes/overlays/CRTCs are used.. if this is not provided, then instead the
+ * first CONFIG_DRM_OMAP_NUM_CRTCS are used, and they are each connected to
+ * one manager, with priority given to managers that are connected to
+ * detected devices.  This should be a good default behavior for most cases,
+ * but yet there still might be times when you wish to do something different.
+ */
+struct omap_kms_platform_data {
+	int ovl_cnt;
+	const int *ovl_ids;
+	int mgr_cnt;
+	const int *mgr_ids;
+	int dev_cnt;
+	const char **dev_names;
+};
+
+struct omap_drm_platform_data {
+	struct omap_kms_platform_data *kms_pdata;
+	struct omap_dmm_platform_data *dmm_pdata;
+};
+
+#endif /* __OMAP_DRM_H__ */
diff --git a/drivers/staging/omapdrm/tcm-sita.c b/drivers/staging/omapdrm/tcm-sita.c
new file mode 100644
index 0000000..10d5ac3
--- /dev/null
+++ b/drivers/staging/omapdrm/tcm-sita.c
@@ -0,0 +1,703 @@
+/*
+ * tcm-sita.c
+ *
+ * SImple Tiler Allocator (SiTA): 2D and 1D allocation(reservation) algorithm
+ *
+ * Authors: Ravi Ramachandra <r.ramachandra@ti.com>,
+ *          Lajos Molnar <molnar@ti.com>
+ *
+ * Copyright (C) 2009-2010 Texas Instruments, Inc.
+ *
+ * This package is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ */
+#include <linux/slab.h>
+#include <linux/spinlock.h>
+
+#include "tcm-sita.h"
+
+#define ALIGN_DOWN(value, align) ((value) & ~((align) - 1))
+
+/* Individual selection criteria for different scan areas */
+static s32 CR_L2R_T2B = CR_BIAS_HORIZONTAL;
+static s32 CR_R2L_T2B = CR_DIAGONAL_BALANCE;
+
+/*********************************************
+ *	TCM API - Sita Implementation
+ *********************************************/
+static s32 sita_reserve_2d(struct tcm *tcm, u16 h, u16 w, u8 align,
+			   struct tcm_area *area);
+static s32 sita_reserve_1d(struct tcm *tcm, u32 slots, struct tcm_area *area);
+static s32 sita_free(struct tcm *tcm, struct tcm_area *area);
+static void sita_deinit(struct tcm *tcm);
+
+/*********************************************
+ *	Main Scanner functions
+ *********************************************/
+static s32 scan_areas_and_find_fit(struct tcm *tcm, u16 w, u16 h, u16 align,
+				   struct tcm_area *area);
+
+static s32 scan_l2r_t2b(struct tcm *tcm, u16 w, u16 h, u16 align,
+			struct tcm_area *field, struct tcm_area *area);
+
+static s32 scan_r2l_t2b(struct tcm *tcm, u16 w, u16 h, u16 align,
+			struct tcm_area *field, struct tcm_area *area);
+
+static s32 scan_r2l_b2t_one_dim(struct tcm *tcm, u32 num_slots,
+			struct tcm_area *field, struct tcm_area *area);
+
+/*********************************************
+ *	Support Infrastructure Methods
+ *********************************************/
+static s32 is_area_free(struct tcm_area ***map, u16 x0, u16 y0, u16 w, u16 h);
+
+static s32 update_candidate(struct tcm *tcm, u16 x0, u16 y0, u16 w, u16 h,
+			    struct tcm_area *field, s32 criteria,
+			    struct score *best);
+
+static void get_nearness_factor(struct tcm_area *field,
+				struct tcm_area *candidate,
+				struct nearness_factor *nf);
+
+static void get_neighbor_stats(struct tcm *tcm, struct tcm_area *area,
+			       struct neighbor_stats *stat);
+
+static void fill_area(struct tcm *tcm,
+				struct tcm_area *area, struct tcm_area *parent);
+
+
+/*********************************************/
+
+/*********************************************
+ *	Utility Methods
+ *********************************************/
+struct tcm *sita_init(u16 width, u16 height, struct tcm_pt *attr)
+{
+	struct tcm *tcm;
+	struct sita_pvt *pvt;
+	struct tcm_area area = {0};
+	s32 i;
+
+	if (width == 0 || height == 0)
+		return NULL;
+
+	tcm = kmalloc(sizeof(*tcm), GFP_KERNEL);
+	pvt = kmalloc(sizeof(*pvt), GFP_KERNEL);
+	if (!tcm || !pvt)
+		goto error;
+
+	memset(tcm, 0, sizeof(*tcm));
+	memset(pvt, 0, sizeof(*pvt));
+
+	/* Updating the pointers to SiTA implementation APIs */
+	tcm->height = height;
+	tcm->width = width;
+	tcm->reserve_2d = sita_reserve_2d;
+	tcm->reserve_1d = sita_reserve_1d;
+	tcm->free = sita_free;
+	tcm->deinit = sita_deinit;
+	tcm->pvt = (void *)pvt;
+
+	spin_lock_init(&(pvt->lock));
+
+	/* Creating tam map */
+	pvt->map = kmalloc(sizeof(*pvt->map) * tcm->width, GFP_KERNEL);
+	if (!pvt->map)
+		goto error;
+
+	for (i = 0; i < tcm->width; i++) {
+		pvt->map[i] =
+			kmalloc(sizeof(**pvt->map) * tcm->height,
+								GFP_KERNEL);
+		if (pvt->map[i] == NULL) {
+			while (i--)
+				kfree(pvt->map[i]);
+			kfree(pvt->map);
+			goto error;
+		}
+	}
+
+	if (attr && attr->x <= tcm->width && attr->y <= tcm->height) {
+		pvt->div_pt.x = attr->x;
+		pvt->div_pt.y = attr->y;
+
+	} else {
+		/* Defaulting to 3:1 ratio on width for 2D area split */
+		/* Defaulting to 3:1 ratio on height for 2D and 1D split */
+		pvt->div_pt.x = (tcm->width * 3) / 4;
+		pvt->div_pt.y = (tcm->height * 3) / 4;
+	}
+
+	spin_lock(&(pvt->lock));
+	assign(&area, 0, 0, width - 1, height - 1);
+	fill_area(tcm, &area, NULL);
+	spin_unlock(&(pvt->lock));
+	return tcm;
+
+error:
+	kfree(tcm);
+	kfree(pvt);
+	return NULL;
+}
+
+static void sita_deinit(struct tcm *tcm)
+{
+	struct sita_pvt *pvt = (struct sita_pvt *)tcm->pvt;
+	struct tcm_area area = {0};
+	s32 i;
+
+	area.p1.x = tcm->width - 1;
+	area.p1.y = tcm->height - 1;
+
+	spin_lock(&(pvt->lock));
+	fill_area(tcm, &area, NULL);
+	spin_unlock(&(pvt->lock));
+
+	for (i = 0; i < tcm->height; i++)
+		kfree(pvt->map[i]);
+	kfree(pvt->map);
+	kfree(pvt);
+}
+
+/**
+ * Reserve a 1D area in the container
+ *
+ * @param num_slots	size of 1D area
+ * @param area		pointer to the area that will be populated with the
+ *			reserved area
+ *
+ * @return 0 on success, non-0 error value on failure.
+ */
+static s32 sita_reserve_1d(struct tcm *tcm, u32 num_slots,
+			   struct tcm_area *area)
+{
+	s32 ret;
+	struct tcm_area field = {0};
+	struct sita_pvt *pvt = (struct sita_pvt *)tcm->pvt;
+
+	spin_lock(&(pvt->lock));
+
+	/* Scanning entire container */
+	assign(&field, tcm->width - 1, tcm->height - 1, 0, 0);
+
+	ret = scan_r2l_b2t_one_dim(tcm, num_slots, &field, area);
+	if (!ret)
+		/* update map */
+		fill_area(tcm, area, area);
+
+	spin_unlock(&(pvt->lock));
+	return ret;
+}
+
+/**
+ * Reserve a 2D area in the container
+ *
+ * @param w	width
+ * @param h	height
+ * @param area	pointer to the area that will be populated with the reesrved
+ *		area
+ *
+ * @return 0 on success, non-0 error value on failure.
+ */
+static s32 sita_reserve_2d(struct tcm *tcm, u16 h, u16 w, u8 align,
+			   struct tcm_area *area)
+{
+	s32 ret;
+	struct sita_pvt *pvt = (struct sita_pvt *)tcm->pvt;
+
+	/* not supporting more than 64 as alignment */
+	if (align > 64)
+		return -EINVAL;
+
+	/* we prefer 1, 32 and 64 as alignment */
+	align = align <= 1 ? 1 : align <= 32 ? 32 : 64;
+
+	spin_lock(&(pvt->lock));
+	ret = scan_areas_and_find_fit(tcm, w, h, align, area);
+	if (!ret)
+		/* update map */
+		fill_area(tcm, area, area);
+
+	spin_unlock(&(pvt->lock));
+	return ret;
+}
+
+/**
+ * Unreserve a previously allocated 2D or 1D area
+ * @param area	area to be freed
+ * @return 0 - success
+ */
+static s32 sita_free(struct tcm *tcm, struct tcm_area *area)
+{
+	struct sita_pvt *pvt = (struct sita_pvt *)tcm->pvt;
+
+	spin_lock(&(pvt->lock));
+
+	/* check that this is in fact an existing area */
+	WARN_ON(pvt->map[area->p0.x][area->p0.y] != area ||
+		pvt->map[area->p1.x][area->p1.y] != area);
+
+	/* Clear the contents of the associated tiles in the map */
+	fill_area(tcm, area, NULL);
+
+	spin_unlock(&(pvt->lock));
+
+	return 0;
+}
+
+/**
+ * Note: In general the cordinates in the scan field area relevant to the can
+ * sweep directions. The scan origin (e.g. top-left corner) will always be
+ * the p0 member of the field.  Therfore, for a scan from top-left p0.x <= p1.x
+ * and p0.y <= p1.y; whereas, for a scan from bottom-right p1.x <= p0.x and p1.y
+ * <= p0.y
+ */
+
+/**
+ * Raster scan horizontally right to left from top to bottom to find a place for
+ * a 2D area of given size inside a scan field.
+ *
+ * @param w	width of desired area
+ * @param h	height of desired area
+ * @param align	desired area alignment
+ * @param area	pointer to the area that will be set to the best position
+ * @param field	area to scan (inclusive)
+ *
+ * @return 0 on success, non-0 error value on failure.
+ */
+static s32 scan_r2l_t2b(struct tcm *tcm, u16 w, u16 h, u16 align,
+			struct tcm_area *field, struct tcm_area *area)
+{
+	s32 x, y;
+	s16 start_x, end_x, start_y, end_y, found_x = -1;
+	struct tcm_area ***map = ((struct sita_pvt *)tcm->pvt)->map;
+	struct score best = {{0}, {0}, {0}, 0};
+
+	start_x = field->p0.x;
+	end_x = field->p1.x;
+	start_y = field->p0.y;
+	end_y = field->p1.y;
+
+	/* check scan area co-ordinates */
+	if (field->p0.x < field->p1.x ||
+	    field->p1.y < field->p0.y)
+		return -EINVAL;
+
+	/* check if allocation would fit in scan area */
+	if (w > LEN(start_x, end_x) || h > LEN(end_y, start_y))
+		return -ENOSPC;
+
+	/* adjust start_x and end_y, as allocation would not fit beyond */
+	start_x = ALIGN_DOWN(start_x - w + 1, align); /* - 1 to be inclusive */
+	end_y = end_y - h + 1;
+
+	/* check if allocation would still fit in scan area */
+	if (start_x < end_x)
+		return -ENOSPC;
+
+	/* scan field top-to-bottom, right-to-left */
+	for (y = start_y; y <= end_y; y++) {
+		for (x = start_x; x >= end_x; x -= align) {
+			if (is_area_free(map, x, y, w, h)) {
+				found_x = x;
+
+				/* update best candidate */
+				if (update_candidate(tcm, x, y, w, h, field,
+							CR_R2L_T2B, &best))
+					goto done;
+
+				/* change upper x bound */
+				end_x = x + 1;
+				break;
+			} else if (map[x][y] && map[x][y]->is2d) {
+				/* step over 2D areas */
+				x = ALIGN(map[x][y]->p0.x - w + 1, align);
+			}
+		}
+
+		/* break if you find a free area shouldering the scan field */
+		if (found_x == start_x)
+			break;
+	}
+
+	if (!best.a.tcm)
+		return -ENOSPC;
+done:
+	assign(area, best.a.p0.x, best.a.p0.y, best.a.p1.x, best.a.p1.y);
+	return 0;
+}
+
+/**
+ * Raster scan horizontally left to right from top to bottom to find a place for
+ * a 2D area of given size inside a scan field.
+ *
+ * @param w	width of desired area
+ * @param h	height of desired area
+ * @param align	desired area alignment
+ * @param area	pointer to the area that will be set to the best position
+ * @param field	area to scan (inclusive)
+ *
+ * @return 0 on success, non-0 error value on failure.
+ */
+static s32 scan_l2r_t2b(struct tcm *tcm, u16 w, u16 h, u16 align,
+			struct tcm_area *field, struct tcm_area *area)
+{
+	s32 x, y;
+	s16 start_x, end_x, start_y, end_y, found_x = -1;
+	struct tcm_area ***map = ((struct sita_pvt *)tcm->pvt)->map;
+	struct score best = {{0}, {0}, {0}, 0};
+
+	start_x = field->p0.x;
+	end_x = field->p1.x;
+	start_y = field->p0.y;
+	end_y = field->p1.y;
+
+	/* check scan area co-ordinates */
+	if (field->p1.x < field->p0.x ||
+	    field->p1.y < field->p0.y)
+		return -EINVAL;
+
+	/* check if allocation would fit in scan area */
+	if (w > LEN(end_x, start_x) || h > LEN(end_y, start_y))
+		return -ENOSPC;
+
+	start_x = ALIGN(start_x, align);
+
+	/* check if allocation would still fit in scan area */
+	if (w > LEN(end_x, start_x))
+		return -ENOSPC;
+
+	/* adjust end_x and end_y, as allocation would not fit beyond */
+	end_x = end_x - w + 1; /* + 1 to be inclusive */
+	end_y = end_y - h + 1;
+
+	/* scan field top-to-bottom, left-to-right */
+	for (y = start_y; y <= end_y; y++) {
+		for (x = start_x; x <= end_x; x += align) {
+			if (is_area_free(map, x, y, w, h)) {
+				found_x = x;
+
+				/* update best candidate */
+				if (update_candidate(tcm, x, y, w, h, field,
+							CR_L2R_T2B, &best))
+					goto done;
+				/* change upper x bound */
+				end_x = x - 1;
+
+				break;
+			} else if (map[x][y] && map[x][y]->is2d) {
+				/* step over 2D areas */
+				x = ALIGN_DOWN(map[x][y]->p1.x, align);
+			}
+		}
+
+		/* break if you find a free area shouldering the scan field */
+		if (found_x == start_x)
+			break;
+	}
+
+	if (!best.a.tcm)
+		return -ENOSPC;
+done:
+	assign(area, best.a.p0.x, best.a.p0.y, best.a.p1.x, best.a.p1.y);
+	return 0;
+}
+
+/**
+ * Raster scan horizontally right to left from bottom to top to find a place
+ * for a 1D area of given size inside a scan field.
+ *
+ * @param num_slots	size of desired area
+ * @param align		desired area alignment
+ * @param area		pointer to the area that will be set to the best
+ *			position
+ * @param field		area to scan (inclusive)
+ *
+ * @return 0 on success, non-0 error value on failure.
+ */
+static s32 scan_r2l_b2t_one_dim(struct tcm *tcm, u32 num_slots,
+				struct tcm_area *field, struct tcm_area *area)
+{
+	s32 found = 0;
+	s16 x, y;
+	struct sita_pvt *pvt = (struct sita_pvt *)tcm->pvt;
+	struct tcm_area *p;
+
+	/* check scan area co-ordinates */
+	if (field->p0.y < field->p1.y)
+		return -EINVAL;
+
+	/**
+	 * Currently we only support full width 1D scan field, which makes sense
+	 * since 1D slot-ordering spans the full container width.
+	 */
+	if (tcm->width != field->p0.x - field->p1.x + 1)
+		return -EINVAL;
+
+	/* check if allocation would fit in scan area */
+	if (num_slots > tcm->width * LEN(field->p0.y, field->p1.y))
+		return -ENOSPC;
+
+	x = field->p0.x;
+	y = field->p0.y;
+
+	/* find num_slots consecutive free slots to the left */
+	while (found < num_slots) {
+		if (y < 0)
+			return -ENOSPC;
+
+		/* remember bottom-right corner */
+		if (found == 0) {
+			area->p1.x = x;
+			area->p1.y = y;
+		}
+
+		/* skip busy regions */
+		p = pvt->map[x][y];
+		if (p) {
+			/* move to left of 2D areas, top left of 1D */
+			x = p->p0.x;
+			if (!p->is2d)
+				y = p->p0.y;
+
+			/* start over */
+			found = 0;
+		} else {
+			/* count consecutive free slots */
+			found++;
+			if (found == num_slots)
+				break;
+		}
+
+		/* move to the left */
+		if (x == 0)
+			y--;
+		x = (x ? : tcm->width) - 1;
+
+	}
+
+	/* set top-left corner */
+	area->p0.x = x;
+	area->p0.y = y;
+	return 0;
+}
+
+/**
+ * Find a place for a 2D area of given size inside a scan field based on its
+ * alignment needs.
+ *
+ * @param w	width of desired area
+ * @param h	height of desired area
+ * @param align	desired area alignment
+ * @param area	pointer to the area that will be set to the best position
+ *
+ * @return 0 on success, non-0 error value on failure.
+ */
+static s32 scan_areas_and_find_fit(struct tcm *tcm, u16 w, u16 h, u16 align,
+				   struct tcm_area *area)
+{
+	s32 ret = 0;
+	struct tcm_area field = {0};
+	u16 boundary_x, boundary_y;
+	struct sita_pvt *pvt = (struct sita_pvt *)tcm->pvt;
+
+	if (align > 1) {
+		/* prefer top-left corner */
+		boundary_x = pvt->div_pt.x - 1;
+		boundary_y = pvt->div_pt.y - 1;
+
+		/* expand width and height if needed */
+		if (w > pvt->div_pt.x)
+			boundary_x = tcm->width - 1;
+		if (h > pvt->div_pt.y)
+			boundary_y = tcm->height - 1;
+
+		assign(&field, 0, 0, boundary_x, boundary_y);
+		ret = scan_l2r_t2b(tcm, w, h, align, &field, area);
+
+		/* scan whole container if failed, but do not scan 2x */
+		if (ret != 0 && (boundary_x != tcm->width - 1 ||
+				 boundary_y != tcm->height - 1)) {
+			/* scan the entire container if nothing found */
+			assign(&field, 0, 0, tcm->width - 1, tcm->height - 1);
+			ret = scan_l2r_t2b(tcm, w, h, align, &field, area);
+		}
+	} else if (align == 1) {
+		/* prefer top-right corner */
+		boundary_x = pvt->div_pt.x;
+		boundary_y = pvt->div_pt.y - 1;
+
+		/* expand width and height if needed */
+		if (w > (tcm->width - pvt->div_pt.x))
+			boundary_x = 0;
+		if (h > pvt->div_pt.y)
+			boundary_y = tcm->height - 1;
+
+		assign(&field, tcm->width - 1, 0, boundary_x, boundary_y);
+		ret = scan_r2l_t2b(tcm, w, h, align, &field, area);
+
+		/* scan whole container if failed, but do not scan 2x */
+		if (ret != 0 && (boundary_x != 0 ||
+				 boundary_y != tcm->height - 1)) {
+			/* scan the entire container if nothing found */
+			assign(&field, tcm->width - 1, 0, 0, tcm->height - 1);
+			ret = scan_r2l_t2b(tcm, w, h, align, &field,
+					   area);
+		}
+	}
+
+	return ret;
+}
+
+/* check if an entire area is free */
+static s32 is_area_free(struct tcm_area ***map, u16 x0, u16 y0, u16 w, u16 h)
+{
+	u16 x = 0, y = 0;
+	for (y = y0; y < y0 + h; y++) {
+		for (x = x0; x < x0 + w; x++) {
+			if (map[x][y])
+				return false;
+		}
+	}
+	return true;
+}
+
+/* fills an area with a parent tcm_area */
+static void fill_area(struct tcm *tcm, struct tcm_area *area,
+			struct tcm_area *parent)
+{
+	s32 x, y;
+	struct sita_pvt *pvt = (struct sita_pvt *)tcm->pvt;
+	struct tcm_area a, a_;
+
+	/* set area's tcm; otherwise, enumerator considers it invalid */
+	area->tcm = tcm;
+
+	tcm_for_each_slice(a, *area, a_) {
+		for (x = a.p0.x; x <= a.p1.x; ++x)
+			for (y = a.p0.y; y <= a.p1.y; ++y)
+				pvt->map[x][y] = parent;
+
+	}
+}
+
+/**
+ * Compares a candidate area to the current best area, and if it is a better
+ * fit, it updates the best to this one.
+ *
+ * @param x0, y0, w, h		top, left, width, height of candidate area
+ * @param field			scan field
+ * @param criteria		scan criteria
+ * @param best			best candidate and its scores
+ *
+ * @return 1 (true) if the candidate area is known to be the final best, so no
+ * more searching should be performed
+ */
+static s32 update_candidate(struct tcm *tcm, u16 x0, u16 y0, u16 w, u16 h,
+			    struct tcm_area *field, s32 criteria,
+			    struct score *best)
+{
+	struct score me;	/* score for area */
+
+	/*
+	 * NOTE: For horizontal bias we always give the first found, because our
+	 * scan is horizontal-raster-based and the first candidate will always
+	 * have the horizontal bias.
+	 */
+	bool first = criteria & CR_BIAS_HORIZONTAL;
+
+	assign(&me.a, x0, y0, x0 + w - 1, y0 + h - 1);
+
+	/* calculate score for current candidate */
+	if (!first) {
+		get_neighbor_stats(tcm, &me.a, &me.n);
+		me.neighs = me.n.edge + me.n.busy;
+		get_nearness_factor(field, &me.a, &me.f);
+	}
+
+	/* the 1st candidate is always the best */
+	if (!best->a.tcm)
+		goto better;
+
+	BUG_ON(first);
+
+	/* diagonal balance check */
+	if ((criteria & CR_DIAGONAL_BALANCE) &&
+		best->neighs <= me.neighs &&
+		(best->neighs < me.neighs ||
+		 /* this implies that neighs and occupied match */
+		 best->n.busy < me.n.busy ||
+		 (best->n.busy == me.n.busy &&
+		  /* check the nearness factor */
+		  best->f.x + best->f.y > me.f.x + me.f.y)))
+		goto better;
+
+	/* not better, keep going */
+	return 0;
+
+better:
+	/* save current area as best */
+	memcpy(best, &me, sizeof(me));
+	best->a.tcm = tcm;
+	return first;
+}
+
+/**
+ * Calculate the nearness factor of an area in a search field.  The nearness
+ * factor is smaller if the area is closer to the search origin.
+ */
+static void get_nearness_factor(struct tcm_area *field, struct tcm_area *area,
+				struct nearness_factor *nf)
+{
+	/**
+	 * Using signed math as field coordinates may be reversed if
+	 * search direction is right-to-left or bottom-to-top.
+	 */
+	nf->x = (s32)(area->p0.x - field->p0.x) * 1000 /
+		(field->p1.x - field->p0.x);
+	nf->y = (s32)(area->p0.y - field->p0.y) * 1000 /
+		(field->p1.y - field->p0.y);
+}
+
+/* get neighbor statistics */
+static void get_neighbor_stats(struct tcm *tcm, struct tcm_area *area,
+			 struct neighbor_stats *stat)
+{
+	s16 x = 0, y = 0;
+	struct sita_pvt *pvt = (struct sita_pvt *)tcm->pvt;
+
+	/* Clearing any exisiting values */
+	memset(stat, 0, sizeof(*stat));
+
+	/* process top & bottom edges */
+	for (x = area->p0.x; x <= area->p1.x; x++) {
+		if (area->p0.y == 0)
+			stat->edge++;
+		else if (pvt->map[x][area->p0.y - 1])
+			stat->busy++;
+
+		if (area->p1.y == tcm->height - 1)
+			stat->edge++;
+		else if (pvt->map[x][area->p1.y + 1])
+			stat->busy++;
+	}
+
+	/* process left & right edges */
+	for (y = area->p0.y; y <= area->p1.y; ++y) {
+		if (area->p0.x == 0)
+			stat->edge++;
+		else if (pvt->map[area->p0.x - 1][y])
+			stat->busy++;
+
+		if (area->p1.x == tcm->width - 1)
+			stat->edge++;
+		else if (pvt->map[area->p1.x + 1][y])
+			stat->busy++;
+	}
+}
diff --git a/drivers/staging/omapdrm/tcm-sita.h b/drivers/staging/omapdrm/tcm-sita.h
new file mode 100644
index 0000000..0444f86
--- /dev/null
+++ b/drivers/staging/omapdrm/tcm-sita.h
@@ -0,0 +1,95 @@
+/*
+ * tcm_sita.h
+ *
+ * SImple Tiler Allocator (SiTA) private structures.
+ *
+ * Author: Ravi Ramachandra <r.ramachandra@ti.com>
+ *
+ * Copyright (C) 2009-2011 Texas Instruments, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ *
+ * * Neither the name of Texas Instruments Incorporated nor the names of
+ *   its contributors may be used to endorse or promote products derived
+ *   from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _TCM_SITA_H
+#define _TCM_SITA_H
+
+#include "tcm.h"
+
+/* length between two coordinates */
+#define LEN(a, b) ((a) > (b) ? (a) - (b) + 1 : (b) - (a) + 1)
+
+enum criteria {
+	CR_MAX_NEIGHS		= 0x01,
+	CR_FIRST_FOUND		= 0x10,
+	CR_BIAS_HORIZONTAL	= 0x20,
+	CR_BIAS_VERTICAL	= 0x40,
+	CR_DIAGONAL_BALANCE	= 0x80
+};
+
+/* nearness to the beginning of the search field from 0 to 1000 */
+struct nearness_factor {
+	s32 x;
+	s32 y;
+};
+
+/*
+ * Statistics on immediately neighboring slots.  Edge is the number of
+ * border segments that are also border segments of the scan field.  Busy
+ * refers to the number of neighbors that are occupied.
+ */
+struct neighbor_stats {
+	u16 edge;
+	u16 busy;
+};
+
+/* structure to keep the score of a potential allocation */
+struct score {
+	struct nearness_factor	f;
+	struct neighbor_stats	n;
+	struct tcm_area		a;
+	u16    neighs;		/* number of busy neighbors */
+};
+
+struct sita_pvt {
+	spinlock_t lock;	/* spinlock to protect access */
+	struct tcm_pt div_pt;	/* divider point splitting container */
+	struct tcm_area ***map;	/* pointers to the parent area for each slot */
+};
+
+/* assign coordinates to area */
+static inline
+void assign(struct tcm_area *a, u16 x0, u16 y0, u16 x1, u16 y1)
+{
+	a->p0.x = x0;
+	a->p0.y = y0;
+	a->p1.x = x1;
+	a->p1.y = y1;
+}
+
+#endif
diff --git a/drivers/staging/omapdrm/tcm.h b/drivers/staging/omapdrm/tcm.h
new file mode 100644
index 0000000..d273e3e
--- /dev/null
+++ b/drivers/staging/omapdrm/tcm.h
@@ -0,0 +1,326 @@
+/*
+ * tcm.h
+ *
+ * TILER container manager specification and support functions for TI
+ * TILER driver.
+ *
+ * Author: Lajos Molnar <molnar@ti.com>
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ *
+ * * Neither the name of Texas Instruments Incorporated nor the names of
+ *   its contributors may be used to endorse or promote products derived
+ *   from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef TCM_H
+#define TCM_H
+
+struct tcm;
+
+/* point */
+struct tcm_pt {
+	u16 x;
+	u16 y;
+};
+
+/* 1d or 2d area */
+struct tcm_area {
+	bool is2d;		/* whether area is 1d or 2d */
+	struct tcm    *tcm;	/* parent */
+	struct tcm_pt  p0;
+	struct tcm_pt  p1;
+};
+
+struct tcm {
+	u16 width, height;	/* container dimensions */
+	int lut_id;		/* Lookup table identifier */
+
+	/* 'pvt' structure shall contain any tcm details (attr) along with
+	linked list of allocated areas and mutex for mutually exclusive access
+	to the list.  It may also contain copies of width and height to notice
+	any changes to the publicly available width and height fields. */
+	void *pvt;
+
+	/* function table */
+	s32 (*reserve_2d)(struct tcm *tcm, u16 height, u16 width, u8 align,
+			  struct tcm_area *area);
+	s32 (*reserve_1d)(struct tcm *tcm, u32 slots, struct tcm_area *area);
+	s32 (*free)      (struct tcm *tcm, struct tcm_area *area);
+	void (*deinit)   (struct tcm *tcm);
+};
+
+/*=============================================================================
+    BASIC TILER CONTAINER MANAGER INTERFACE
+=============================================================================*/
+
+/*
+ * NOTE:
+ *
+ * Since some basic parameter checking is done outside the TCM algorithms,
+ * TCM implementation do NOT have to check the following:
+ *
+ *   area pointer is NULL
+ *   width and height fits within container
+ *   number of pages is more than the size of the container
+ *
+ */
+
+struct tcm *sita_init(u16 width, u16 height, struct tcm_pt *attr);
+
+
+/**
+ * Deinitialize tiler container manager.
+ *
+ * @param tcm	Pointer to container manager.
+ *
+ * @return 0 on success, non-0 error value on error.  The call
+ *	   should free as much memory as possible and meaningful
+ *	   even on failure.  Some error codes: -ENODEV: invalid
+ *	   manager.
+ */
+static inline void tcm_deinit(struct tcm *tcm)
+{
+	if (tcm)
+		tcm->deinit(tcm);
+}
+
+/**
+ * Reserves a 2D area in the container.
+ *
+ * @param tcm		Pointer to container manager.
+ * @param height	Height(in pages) of area to be reserved.
+ * @param width		Width(in pages) of area to be reserved.
+ * @param align		Alignment requirement for top-left corner of area. Not
+ *			all values may be supported by the container manager,
+ *			but it must support 0 (1), 32 and 64.
+ *			0 value is equivalent to 1.
+ * @param area		Pointer to where the reserved area should be stored.
+ *
+ * @return 0 on success.  Non-0 error code on failure.  Also,
+ *	   the tcm field of the area will be set to NULL on
+ *	   failure.  Some error codes: -ENODEV: invalid manager,
+ *	   -EINVAL: invalid area, -ENOMEM: not enough space for
+ *	    allocation.
+ */
+static inline s32 tcm_reserve_2d(struct tcm *tcm, u16 width, u16 height,
+				 u16 align, struct tcm_area *area)
+{
+	/* perform rudimentary error checking */
+	s32 res = tcm  == NULL ? -ENODEV :
+		(area == NULL || width == 0 || height == 0 ||
+		 /* align must be a 2 power */
+		 (align & (align - 1))) ? -EINVAL :
+		(height > tcm->height || width > tcm->width) ? -ENOMEM : 0;
+
+	if (!res) {
+		area->is2d = true;
+		res = tcm->reserve_2d(tcm, height, width, align, area);
+		area->tcm = res ? NULL : tcm;
+	}
+
+	return res;
+}
+
+/**
+ * Reserves a 1D area in the container.
+ *
+ * @param tcm		Pointer to container manager.
+ * @param slots		Number of (contiguous) slots to reserve.
+ * @param area		Pointer to where the reserved area should be stored.
+ *
+ * @return 0 on success.  Non-0 error code on failure.  Also,
+ *	   the tcm field of the area will be set to NULL on
+ *	   failure.  Some error codes: -ENODEV: invalid manager,
+ *	   -EINVAL: invalid area, -ENOMEM: not enough space for
+ *	    allocation.
+ */
+static inline s32 tcm_reserve_1d(struct tcm *tcm, u32 slots,
+				 struct tcm_area *area)
+{
+	/* perform rudimentary error checking */
+	s32 res = tcm  == NULL ? -ENODEV :
+		(area == NULL || slots == 0) ? -EINVAL :
+		slots > (tcm->width * (u32) tcm->height) ? -ENOMEM : 0;
+
+	if (!res) {
+		area->is2d = false;
+		res = tcm->reserve_1d(tcm, slots, area);
+		area->tcm = res ? NULL : tcm;
+	}
+
+	return res;
+}
+
+/**
+ * Free a previously reserved area from the container.
+ *
+ * @param area	Pointer to area reserved by a prior call to
+ *		tcm_reserve_1d or tcm_reserve_2d call, whether
+ *		it was successful or not. (Note: all fields of
+ *		the structure must match.)
+ *
+ * @return 0 on success.  Non-0 error code on failure.  Also, the tcm
+ *	   field of the area is set to NULL on success to avoid subsequent
+ *	   freeing.  This call will succeed even if supplying
+ *	   the area from a failed reserved call.
+ */
+static inline s32 tcm_free(struct tcm_area *area)
+{
+	s32 res = 0; /* free succeeds by default */
+
+	if (area && area->tcm) {
+		res = area->tcm->free(area->tcm, area);
+		if (res == 0)
+			area->tcm = NULL;
+	}
+
+	return res;
+}
+
+/*=============================================================================
+    HELPER FUNCTION FOR ANY TILER CONTAINER MANAGER
+=============================================================================*/
+
+/**
+ * This method slices off the topmost 2D slice from the parent area, and stores
+ * it in the 'slice' parameter.  The 'parent' parameter will get modified to
+ * contain the remaining portion of the area.  If the whole parent area can
+ * fit in a 2D slice, its tcm pointer is set to NULL to mark that it is no
+ * longer a valid area.
+ *
+ * @param parent	Pointer to a VALID parent area that will get modified
+ * @param slice		Pointer to the slice area that will get modified
+ */
+static inline void tcm_slice(struct tcm_area *parent, struct tcm_area *slice)
+{
+	*slice = *parent;
+
+	/* check if we need to slice */
+	if (slice->tcm && !slice->is2d &&
+		slice->p0.y != slice->p1.y &&
+		(slice->p0.x || (slice->p1.x != slice->tcm->width - 1))) {
+		/* set end point of slice (start always remains) */
+		slice->p1.x = slice->tcm->width - 1;
+		slice->p1.y = (slice->p0.x) ? slice->p0.y : slice->p1.y - 1;
+		/* adjust remaining area */
+		parent->p0.x = 0;
+		parent->p0.y = slice->p1.y + 1;
+	} else {
+		/* mark this as the last slice */
+		parent->tcm = NULL;
+	}
+}
+
+/* Verify if a tcm area is logically valid */
+static inline bool tcm_area_is_valid(struct tcm_area *area)
+{
+	return area && area->tcm &&
+		/* coordinate bounds */
+		area->p1.x < area->tcm->width &&
+		area->p1.y < area->tcm->height &&
+		area->p0.y <= area->p1.y &&
+		/* 1D coordinate relationship + p0.x check */
+		((!area->is2d &&
+		  area->p0.x < area->tcm->width &&
+		  area->p0.x + area->p0.y * area->tcm->width <=
+		  area->p1.x + area->p1.y * area->tcm->width) ||
+		 /* 2D coordinate relationship */
+		 (area->is2d &&
+		  area->p0.x <= area->p1.x));
+}
+
+/* see if a coordinate is within an area */
+static inline bool __tcm_is_in(struct tcm_pt *p, struct tcm_area *a)
+{
+	u16 i;
+
+	if (a->is2d) {
+		return p->x >= a->p0.x && p->x <= a->p1.x &&
+		       p->y >= a->p0.y && p->y <= a->p1.y;
+	} else {
+		i = p->x + p->y * a->tcm->width;
+		return i >= a->p0.x + a->p0.y * a->tcm->width &&
+		       i <= a->p1.x + a->p1.y * a->tcm->width;
+	}
+}
+
+/* calculate area width */
+static inline u16 __tcm_area_width(struct tcm_area *area)
+{
+	return area->p1.x - area->p0.x + 1;
+}
+
+/* calculate area height */
+static inline u16 __tcm_area_height(struct tcm_area *area)
+{
+	return area->p1.y - area->p0.y + 1;
+}
+
+/* calculate number of slots in an area */
+static inline u16 __tcm_sizeof(struct tcm_area *area)
+{
+	return area->is2d ?
+		__tcm_area_width(area) * __tcm_area_height(area) :
+		(area->p1.x - area->p0.x + 1) + (area->p1.y - area->p0.y) *
+							area->tcm->width;
+}
+#define tcm_sizeof(area) __tcm_sizeof(&(area))
+#define tcm_awidth(area) __tcm_area_width(&(area))
+#define tcm_aheight(area) __tcm_area_height(&(area))
+#define tcm_is_in(pt, area) __tcm_is_in(&(pt), &(area))
+
+/* limit a 1D area to the first N pages */
+static inline s32 tcm_1d_limit(struct tcm_area *a, u32 num_pg)
+{
+	if (__tcm_sizeof(a) < num_pg)
+		return -ENOMEM;
+	if (!num_pg)
+		return -EINVAL;
+
+	a->p1.x = (a->p0.x + num_pg - 1) % a->tcm->width;
+	a->p1.y = a->p0.y + ((a->p0.x + num_pg - 1) / a->tcm->width);
+	return 0;
+}
+
+/**
+ * Iterate through 2D slices of a valid area. Behaves
+ * syntactically as a for(;;) statement.
+ *
+ * @param var		Name of a local variable of type 'struct
+ *			tcm_area *' that will get modified to
+ *			contain each slice.
+ * @param area		Pointer to the VALID parent area. This
+ *			structure will not get modified
+ *			throughout the loop.
+ *
+ */
+#define tcm_for_each_slice(var, area, safe) \
+	for (safe = area, \
+	     tcm_slice(&safe, &var); \
+	     var.tcm; tcm_slice(&safe, &var))
+
+#endif
diff --git a/drivers/staging/phison/phison.c b/drivers/staging/phison/phison.c
index 683657c..d77b21f 100644
--- a/drivers/staging/phison/phison.c
+++ b/drivers/staging/phison/phison.c
@@ -70,7 +70,7 @@
 }
 
 static DEFINE_PCI_DEVICE_TABLE(phison_pci_tbl) = {
-	{ PCI_VENDOR_ID_PHISON, PCI_DEVICE_ID_PS5000, PCI_ANY_ID, PCI_ANY_ID,
+	{ PCI_DEVICE(PCI_VENDOR_ID_PHISON, PCI_DEVICE_ID_PS5000),
 	  PCI_CLASS_STORAGE_IDE << 8, 0xffff00, 0 },
 	{ 0, },
 };
diff --git a/drivers/staging/rtl8192e/Kconfig b/drivers/staging/rtl8192e/Kconfig
index 750c347..f87e211 100644
--- a/drivers/staging/rtl8192e/Kconfig
+++ b/drivers/staging/rtl8192e/Kconfig
@@ -1,9 +1,43 @@
-config RTL8192E
-	tristate "RealTek RTL8192E Wireless LAN NIC driver"
-	depends on PCI && WLAN
-	depends on m
-	select WIRELESS_EXT
-	select WEXT_PRIV
-	select CRYPTO
-	default N
+config RTLLIB
+	tristate "Support for rtllib wireless devices"
+	depends on WLAN && m
+	default n
+	select LIB80211
 	---help---
+	  If you have a wireless card that uses rtllib, say
+	  Y. Currently the only card is the rtl8192e.
+
+	  If unsure, say N.
+
+if RTLLIB
+
+config RTLLIB_CRYPTO_CCMP
+	tristate "Support for rtllib CCMP crypto"
+	depends on RTLLIB
+	default y
+	---help---
+	  CCMP crypto driver for rtllib.
+
+	  If you enabled RTLLIB, you want this.
+
+config RTLLIB_CRYPTO_TKIP
+	tristate "Support for rtllib TKIP crypto"
+	depends on RTLLIB
+	default y
+	---help---
+	  TKIP crypto driver for rtllib.
+
+	  If you enabled RTLLIB, you want this.
+
+config RTLLIB_CRYPTO_WEP
+	tristate "Support for rtllib WEP crypto"
+	depends on RTLLIB
+	default y
+	---help---
+	  TKIP crypto driver for rtllib.
+
+	  If you enabled RTLLIB, you want this.
+
+source "drivers/staging/rtl8192e/rtl8192e/Kconfig"
+
+endif
diff --git a/drivers/staging/rtl8192e/Makefile b/drivers/staging/rtl8192e/Makefile
index a66a9ad..cb18db7 100644
--- a/drivers/staging/rtl8192e/Makefile
+++ b/drivers/staging/rtl8192e/Makefile
@@ -1,41 +1,21 @@
-ccflags-y += -DUSE_FW_SOURCE_IMG_FILE
-ccflags-y += -DCONFIG_PM_RTL
-ccflags-y += -DCONFIG_PM
-ccflags-y += -DHAVE_NET_DEVICE_OPS
-ccflags-y += -DENABLE_DOT11D
-
-r8192e_pci-objs :=		\
-	rtl_core.o		\
-	rtl_eeprom.o		\
-	rtl_ps.o		\
-	rtl_wx.o		\
-	rtl_cam.o		\
-	rtl_dm.o		\
-	rtl_pm.o		\
-	rtl_pci.o		\
-	rtl_debug.o		\
-	rtl_ethtool.o		\
-	r8192E_dev.o		\
-	r8192E_phy.o		\
-	r8192E_firmware.o	\
-	r8192E_cmdpkt.o		\
-	r8192E_hwimg.o		\
-	r8190P_rtl8256.o	\
+rtllib-objs :=			\
+	dot11d.o		\
+	rtllib_module.o		\
 	rtllib_rx.o		\
-	rtllib_softmac.o	\
 	rtllib_tx.o		\
 	rtllib_wx.o		\
-	rtllib_module.o		\
+	rtllib_softmac.o	\
 	rtllib_softmac_wx.o	\
-	rtl819x_HTProc.o	\
-	rtl819x_TSProc.o	\
 	rtl819x_BAProc.o	\
-	dot11d.o		\
-	rtllib_crypt.o		\
-	rtllib_crypt_tkip.o	\
-	rtllib_crypt_ccmp.o	\
-	rtllib_crypt_wep.o
+	rtl819x_HTProc.o	\
+	rtl819x_TSProc.o
 
-obj-$(CONFIG_RTL8192E) += r8192e_pci.o
+obj-$(CONFIG_RTLLIB) += rtllib.o
+
+obj-$(CONFIG_RTLLIB_CRYPTO_CCMP) += rtllib_crypt_ccmp.o
+obj-$(CONFIG_RTLLIB_CRYPTO_TKIP) += rtllib_crypt_tkip.o
+obj-$(CONFIG_RTLLIB_CRYPTO_WEP) += rtllib_crypt_wep.o
+
+obj-$(CONFIG_RTL8192E) += rtl8192e/
 
 ccflags-y += -D__CHECK_ENDIAN__
diff --git a/drivers/staging/rtl8192e/dot11d.c b/drivers/staging/rtl8192e/dot11d.c
index ee0381e..f7b14f8 100644
--- a/drivers/staging/rtl8192e/dot11d.c
+++ b/drivers/staging/rtl8192e/dot11d.c
@@ -46,7 +46,7 @@
 	  56, 60, 64}, 21}
 };
 
-void Dot11d_Init(struct rtllib_device *ieee)
+void dot11d_init(struct rtllib_device *ieee)
 {
 	struct rt_dot11d_info *pDot11dInfo = GET_DOT11D_INFO(ieee);
 	pDot11dInfo->bEnabled = false;
@@ -58,6 +58,7 @@
 	RESET_CIE_WATCHDOG(ieee);
 
 }
+EXPORT_SYMBOL(dot11d_init);
 
 void Dot11d_Channelmap(u8 channel_plan, struct rtllib_device *ieee)
 {
@@ -99,6 +100,7 @@
 		break;
 	}
 }
+EXPORT_SYMBOL(Dot11d_Channelmap);
 
 
 void Dot11d_Reset(struct rtllib_device *ieee)
diff --git a/drivers/staging/rtl8192e/dot11d.h b/drivers/staging/rtl8192e/dot11d.h
index 032f700..71f4549 100644
--- a/drivers/staging/rtl8192e/dot11d.h
+++ b/drivers/staging/rtl8192e/dot11d.h
@@ -93,7 +93,7 @@
 #define IS_DOT11D_STATE_DONE(__pIeeeDev)			\
 	(GET_DOT11D_INFO(__pIeeeDev)->State == DOT11D_STATE_DONE)
 
-void Dot11d_Init(struct rtllib_device *dev);
+void dot11d_init(struct rtllib_device *dev);
 void Dot11d_Channelmap(u8 channel_plan, struct rtllib_device *ieee);
 void Dot11d_Reset(struct rtllib_device *dev);
 void Dot11d_UpdateCountryIe(struct rtllib_device *dev, u8 *pTaddr,
diff --git a/drivers/staging/rtl8192e/rtl8192e/Kconfig b/drivers/staging/rtl8192e/rtl8192e/Kconfig
new file mode 100644
index 0000000..50e0d91
--- /dev/null
+++ b/drivers/staging/rtl8192e/rtl8192e/Kconfig
@@ -0,0 +1,9 @@
+config RTL8192E
+	tristate "RealTek RTL8192E Wireless LAN NIC driver"
+	depends on PCI && WLAN && RTLLIB
+	depends on m
+	select WIRELESS_EXT
+	select WEXT_PRIV
+	select CRYPTO
+	default N
+	---help---
diff --git a/drivers/staging/rtl8192e/rtl8192e/Makefile b/drivers/staging/rtl8192e/rtl8192e/Makefile
new file mode 100644
index 0000000..313a92e
--- /dev/null
+++ b/drivers/staging/rtl8192e/rtl8192e/Makefile
@@ -0,0 +1,21 @@
+r8192e_pci-objs :=		\
+	r8192E_dev.o		\
+	r8192E_phy.o		\
+	r8192E_firmware.o	\
+	r8192E_cmdpkt.o		\
+	r8192E_hwimg.o		\
+	r8190P_rtl8256.o	\
+	rtl_cam.o		\
+	rtl_core.o		\
+	rtl_debug.o		\
+	rtl_dm.o		\
+	rtl_eeprom.o		\
+	rtl_ethtool.o		\
+	rtl_pci.o		\
+	rtl_pm.o		\
+	rtl_ps.o		\
+	rtl_wx.o		\
+
+obj-$(CONFIG_RTL8192E) += r8192e_pci.o
+
+ccflags-y += -D__CHECK_ENDIAN__
diff --git a/drivers/staging/rtl8192e/r8190P_def.h b/drivers/staging/rtl8192e/rtl8192e/r8190P_def.h
similarity index 100%
rename from drivers/staging/rtl8192e/r8190P_def.h
rename to drivers/staging/rtl8192e/rtl8192e/r8190P_def.h
diff --git a/drivers/staging/rtl8192e/r8190P_rtl8256.c b/drivers/staging/rtl8192e/rtl8192e/r8190P_rtl8256.c
similarity index 100%
rename from drivers/staging/rtl8192e/r8190P_rtl8256.c
rename to drivers/staging/rtl8192e/rtl8192e/r8190P_rtl8256.c
diff --git a/drivers/staging/rtl8192e/r8190P_rtl8256.h b/drivers/staging/rtl8192e/rtl8192e/r8190P_rtl8256.h
similarity index 100%
rename from drivers/staging/rtl8192e/r8190P_rtl8256.h
rename to drivers/staging/rtl8192e/rtl8192e/r8190P_rtl8256.h
diff --git a/drivers/staging/rtl8192e/r8192E_cmdpkt.c b/drivers/staging/rtl8192e/rtl8192e/r8192E_cmdpkt.c
similarity index 100%
rename from drivers/staging/rtl8192e/r8192E_cmdpkt.c
rename to drivers/staging/rtl8192e/rtl8192e/r8192E_cmdpkt.c
diff --git a/drivers/staging/rtl8192e/r8192E_cmdpkt.h b/drivers/staging/rtl8192e/rtl8192e/r8192E_cmdpkt.h
similarity index 100%
rename from drivers/staging/rtl8192e/r8192E_cmdpkt.h
rename to drivers/staging/rtl8192e/rtl8192e/r8192E_cmdpkt.h
diff --git a/drivers/staging/rtl8192e/r8192E_dev.c b/drivers/staging/rtl8192e/rtl8192e/r8192E_dev.c
similarity index 100%
rename from drivers/staging/rtl8192e/r8192E_dev.c
rename to drivers/staging/rtl8192e/rtl8192e/r8192E_dev.c
diff --git a/drivers/staging/rtl8192e/r8192E_dev.h b/drivers/staging/rtl8192e/rtl8192e/r8192E_dev.h
similarity index 100%
rename from drivers/staging/rtl8192e/r8192E_dev.h
rename to drivers/staging/rtl8192e/rtl8192e/r8192E_dev.h
diff --git a/drivers/staging/rtl8192e/r8192E_firmware.c b/drivers/staging/rtl8192e/rtl8192e/r8192E_firmware.c
similarity index 100%
rename from drivers/staging/rtl8192e/r8192E_firmware.c
rename to drivers/staging/rtl8192e/rtl8192e/r8192E_firmware.c
diff --git a/drivers/staging/rtl8192e/r8192E_firmware.h b/drivers/staging/rtl8192e/rtl8192e/r8192E_firmware.h
similarity index 100%
rename from drivers/staging/rtl8192e/r8192E_firmware.h
rename to drivers/staging/rtl8192e/rtl8192e/r8192E_firmware.h
diff --git a/drivers/staging/rtl8192e/r8192E_hw.h b/drivers/staging/rtl8192e/rtl8192e/r8192E_hw.h
similarity index 100%
rename from drivers/staging/rtl8192e/r8192E_hw.h
rename to drivers/staging/rtl8192e/rtl8192e/r8192E_hw.h
diff --git a/drivers/staging/rtl8192e/r8192E_hwimg.c b/drivers/staging/rtl8192e/rtl8192e/r8192E_hwimg.c
similarity index 100%
rename from drivers/staging/rtl8192e/r8192E_hwimg.c
rename to drivers/staging/rtl8192e/rtl8192e/r8192E_hwimg.c
diff --git a/drivers/staging/rtl8192e/r8192E_hwimg.h b/drivers/staging/rtl8192e/rtl8192e/r8192E_hwimg.h
similarity index 100%
rename from drivers/staging/rtl8192e/r8192E_hwimg.h
rename to drivers/staging/rtl8192e/rtl8192e/r8192E_hwimg.h
diff --git a/drivers/staging/rtl8192e/r8192E_phy.c b/drivers/staging/rtl8192e/rtl8192e/r8192E_phy.c
similarity index 99%
rename from drivers/staging/rtl8192e/r8192E_phy.c
rename to drivers/staging/rtl8192e/rtl8192e/r8192E_phy.c
index 7fe69a3..3e705ef 100644
--- a/drivers/staging/rtl8192e/r8192E_phy.c
+++ b/drivers/staging/rtl8192e/rtl8192e/r8192E_phy.c
@@ -23,7 +23,6 @@
 #include "r8190P_rtl8256.h"
 #include "r8192E_phy.h"
 #include "rtl_dm.h"
-#include "dot11d.h"
 
 #include "r8192E_hwimg.h"
 
@@ -859,7 +858,7 @@
 	RT_TRACE(COMP_TRACE, "====>%s()====stage:%d, step:%d, channel:%d\n",
 		  __func__, *stage, *step, channel);
 
-	if (!IsLegalChannel(priv->rtllib, channel)) {
+	if (!rtllib_legal_channel(priv->rtllib, channel)) {
 		RT_TRACE(COMP_ERR, "=============>set to illegal channel:%d\n",
 			 channel);
 		return true;
diff --git a/drivers/staging/rtl8192e/r8192E_phy.h b/drivers/staging/rtl8192e/rtl8192e/r8192E_phy.h
similarity index 100%
rename from drivers/staging/rtl8192e/r8192E_phy.h
rename to drivers/staging/rtl8192e/rtl8192e/r8192E_phy.h
diff --git a/drivers/staging/rtl8192e/r8192E_phyreg.h b/drivers/staging/rtl8192e/rtl8192e/r8192E_phyreg.h
similarity index 100%
rename from drivers/staging/rtl8192e/r8192E_phyreg.h
rename to drivers/staging/rtl8192e/rtl8192e/r8192E_phyreg.h
diff --git a/drivers/staging/rtl8192e/r819xE_phyreg.h b/drivers/staging/rtl8192e/rtl8192e/r819xE_phyreg.h
similarity index 100%
rename from drivers/staging/rtl8192e/r819xE_phyreg.h
rename to drivers/staging/rtl8192e/rtl8192e/r819xE_phyreg.h
diff --git a/drivers/staging/rtl8192e/rtl_cam.c b/drivers/staging/rtl8192e/rtl8192e/rtl_cam.c
similarity index 100%
rename from drivers/staging/rtl8192e/rtl_cam.c
rename to drivers/staging/rtl8192e/rtl8192e/rtl_cam.c
diff --git a/drivers/staging/rtl8192e/rtl_cam.h b/drivers/staging/rtl8192e/rtl8192e/rtl_cam.h
similarity index 100%
rename from drivers/staging/rtl8192e/rtl_cam.h
rename to drivers/staging/rtl8192e/rtl8192e/rtl_cam.h
diff --git a/drivers/staging/rtl8192e/rtl_core.c b/drivers/staging/rtl8192e/rtl8192e/rtl_core.c
similarity index 97%
rename from drivers/staging/rtl8192e/rtl_core.c
rename to drivers/staging/rtl8192e/rtl8192e/rtl_core.c
index 5ad9664..71adb6b 100644
--- a/drivers/staging/rtl8192e/rtl_core.c
+++ b/drivers/staging/rtl8192e/rtl8192e/rtl_core.c
@@ -53,9 +53,7 @@
 #include "rtl_wx.h"
 #include "rtl_dm.h"
 
-#ifdef CONFIG_PM_RTL
 #include "rtl_pm.h"
-#endif
 
 int hwwep = 1;
 static int channels = 0x3fff;
@@ -581,7 +579,7 @@
 	struct rtllib_network *net = &ieee->current_network;
 
 	if (ieee->pHTInfo->bCurrentHTSupport)
-		HTUpdateSelfAndPeerSetting(ieee, net);
+		HT_update_self_and_peer_setting(ieee, net);
 	ieee->pHTInfo->bCurrentRT2RTLongSlotTime =
 		 net->bssht.bdRT2RTLongSlotTime;
 	ieee->pHTInfo->RT2RT_HT_Mode = net->bssht.RT2RT_HT_Mode;
@@ -1289,7 +1287,7 @@
 		priv->ChannelPlan = COUNTRY_CODE_FCC;
 	}
 	RT_TRACE(COMP_INIT, "Channel plan is %d\n", priv->ChannelPlan);
-	Dot11d_Init(priv->rtllib);
+	dot11d_init(priv->rtllib);
 	Dot11d_Channelmap(priv->ChannelPlan, priv->rtllib);
 	for (i = 1; i <= 11; i++)
 		(priv->rtllib->active_channel_map)[i] = 1;
@@ -1305,7 +1303,6 @@
 
 	memset(&(priv->stats), 0, sizeof(struct rt_stats));
 
-	rtl8192_dbgp_flag_init(dev);
 	rtl8192_init_priv_handler(dev);
 	rtl8192_init_priv_constant(dev);
 	rtl8192_init_priv_variable(dev);
@@ -2839,7 +2836,6 @@
 /****************************************************************************
 	---------------------------- PCI_STUFF---------------------------
 *****************************************************************************/
-#ifdef HAVE_NET_DEVICE_OPS
 static const struct net_device_ops rtl8192_netdev_ops = {
 	.ndo_open = rtl8192_open,
 	.ndo_stop = rtl8192_close,
@@ -2851,7 +2847,6 @@
 	.ndo_change_mtu = eth_change_mtu,
 	.ndo_start_xmit = rtllib_xmit,
 };
-#endif
 
 static int __devinit rtl8192_pci_probe(struct pci_dev *pdev,
 			const struct pci_device_id *id)
@@ -2938,17 +2933,7 @@
 	dev->irq = pdev->irq;
 	priv->irq = 0;
 
-#ifdef HAVE_NET_DEVICE_OPS
 	dev->netdev_ops = &rtl8192_netdev_ops;
-#else
-	dev->open = rtl8192_open;
-	dev->stop = rtl8192_close;
-	dev->tx_timeout = rtl8192_tx_timeout;
-	dev->do_ioctl = rtl8192_ioctl;
-	dev->set_multicast_list = r8192_set_multicast;
-	dev->set_mac_address = r8192_set_mac_adr;
-	dev->hard_start_xmit = rtllib_xmit;
-#endif
 
 	dev->wireless_handlers = (struct iw_handler_def *)
 				 &r8192_wx_handlers_def;
@@ -2974,10 +2959,7 @@
 
 	register_netdev(dev);
 	RT_TRACE(COMP_INIT, "dev name: %s\n", dev->name);
-	err = rtl_debug_module_init(priv, dev->name);
-	if (err)
-		RT_TRACE(COMP_DBG, "failed to create debugfs files. Ignoring "
-			 "error: %d\n", err);
+
 	rtl8192_proc_init_one(dev);
 
 	if (priv->polling_timer_on == 0)
@@ -3015,7 +2997,6 @@
 		del_timer_sync(&priv->gpio_polling_timer);
 		cancel_delayed_work(&priv->gpio_change_rf_wq);
 		priv->polling_timer_on = 0;
-		rtl_debug_module_remove(priv);
 		rtl8192_proc_remove_one(dev);
 		rtl8192_down(dev, true);
 		deinit_hal_dm(dev);
@@ -3103,43 +3084,9 @@
 
 static int __init rtl8192_pci_module_init(void)
 {
-	int ret;
-	int error;
-
-	ret = rtllib_init();
-	if (ret) {
-		printk(KERN_ERR "rtllib_init() failed %d\n", ret);
-		return ret;
-	}
-	ret = rtllib_crypto_init();
-	if (ret) {
-		printk(KERN_ERR "rtllib_crypto_init() failed %d\n", ret);
-		return ret;
-	}
-	ret = rtllib_crypto_tkip_init();
-	if (ret) {
-		printk(KERN_ERR "rtllib_crypto_tkip_init() failed %d\n", ret);
-		return ret;
-	}
-	ret = rtllib_crypto_ccmp_init();
-	if (ret) {
-		printk(KERN_ERR "rtllib_crypto_ccmp_init() failed %d\n", ret);
-		return ret;
-	}
-	ret = rtllib_crypto_wep_init();
-	if (ret) {
-		printk(KERN_ERR "rtllib_crypto_wep_init() failed %d\n", ret);
-		return ret;
-	}
 	printk(KERN_INFO "\nLinux kernel driver for RTL8192E WLAN cards\n");
 	printk(KERN_INFO "Copyright (c) 2007-2008, Realsil Wlan Driver\n");
 
-	error = rtl_create_debugfs_root();
-	if (error) {
-		RT_TRACE(COMP_DBG, "Create debugfs root fail: %d\n", error);
-		goto err_out;
-	}
-
 	rtl8192_proc_module_init();
 	if (0 != pci_register_driver(&rtl8192_pci_driver)) {
 		DMESG("No device found");
@@ -3147,9 +3094,6 @@
 		return -ENODEV;
 	}
 	return 0;
-err_out:
-	return error;
-
 }
 
 static void __exit rtl8192_pci_module_exit(void)
@@ -3158,12 +3102,6 @@
 
 	RT_TRACE(COMP_DOWN, "Exiting");
 	rtl8192_proc_module_remove();
-	rtl_remove_debugfs_root();
-	rtllib_crypto_tkip_exit();
-	rtllib_crypto_ccmp_exit();
-	rtllib_crypto_wep_exit();
-	rtllib_crypto_deinit();
-	rtllib_exit();
 }
 
 void check_rfctrl_gpio_timer(unsigned long data)
diff --git a/drivers/staging/rtl8192e/rtl_core.h b/drivers/staging/rtl8192e/rtl8192e/rtl_core.h
similarity index 96%
rename from drivers/staging/rtl8192e/rtl_core.h
rename to drivers/staging/rtl8192e/rtl8192e/rtl_core.h
index f9af515..2a2519c 100644
--- a/drivers/staging/rtl8192e/rtl_core.h
+++ b/drivers/staging/rtl8192e/rtl8192e/rtl_core.h
@@ -44,11 +44,14 @@
 #include <linux/proc_fs.h>
 #include <linux/if_arp.h>
 #include <linux/random.h>
-#include <linux/version.h>
 #include <linux/io.h>
-#include "rtllib.h"
 
-#include "dot11d.h"
+/* Need this defined before including local include files */
+#define DRV_NAME "rtl819xE"
+
+#include "../rtllib.h"
+
+#include "../dot11d.h"
 
 #include "r8192E_firmware.h"
 #include "r8192E_hw.h"
@@ -56,7 +59,6 @@
 #include "r8190P_def.h"
 #include "r8192E_dev.h"
 
-#include "rtl_debug.h"
 #include "rtl_eeprom.h"
 #include "rtl_ps.h"
 #include "rtl_pci.h"
@@ -67,8 +69,6 @@
 #define DRV_AUTHOR  "<wlanfae@realtek.com>"
 #define DRV_VERSION  "0014.0401.2010"
 
-#define DRV_NAME "rtl819xE"
-
 #define IS_HARDWARE_TYPE_819xP(_priv)		\
 	((((struct r8192_priv *)rtllib_priv(dev))->card_8192 == NIC_8190P) || \
 	(((struct r8192_priv *)rtllib_priv(dev))->card_8192 == NIC_8192E))
@@ -215,41 +215,6 @@
 	RTL819X_EFUSE_MAP			= 19,
 };
 
-enum RTL_DEBUG {
-	COMP_TRACE		= BIT0,
-	COMP_DBG		= BIT1,
-	COMP_INIT		= BIT2,
-	COMP_RECV		= BIT3,
-	COMP_SEND		= BIT4,
-	COMP_CMD		= BIT5,
-	COMP_POWER		= BIT6,
-	COMP_EPROM		= BIT7,
-	COMP_SWBW		= BIT8,
-	COMP_SEC		= BIT9,
-	COMP_LPS		= BIT10,
-	COMP_QOS		= BIT11,
-	COMP_RATE		= BIT12,
-	COMP_RXDESC		= BIT13,
-	COMP_PHY		= BIT14,
-	COMP_DIG		= BIT15,
-	COMP_TXAGC		= BIT16,
-	COMP_HALDM		= BIT17,
-	COMP_POWER_TRACKING	= BIT18,
-	COMP_CH			= BIT19,
-	COMP_RF			= BIT20,
-	COMP_FIRMWARE		= BIT21,
-	COMP_HT			= BIT22,
-	COMP_RESET		= BIT23,
-	COMP_CMDPKT		= BIT24,
-	COMP_SCAN		= BIT25,
-	COMP_PS			= BIT26,
-	COMP_DOWN		= BIT27,
-	COMP_INTR		= BIT28,
-	COMP_LED		= BIT29,
-	COMP_MLME		= BIT30,
-	COMP_ERR		= BIT31
-};
-
 enum nic_t {
 	NIC_UNKNOWN     = 0,
 	NIC_8192E       = 1,
@@ -1121,4 +1086,10 @@
 			   enum wireless_mode WirelessMode,
 			   struct channel_access_setting *ChnlAccessSetting);
 
+/* proc stuff from rtl_debug.c */
+void rtl8192_proc_init_one(struct net_device *dev);
+void rtl8192_proc_remove_one(struct net_device *dev);
+void rtl8192_proc_module_init(void);
+void rtl8192_proc_module_remove(void);
+
 #endif
diff --git a/drivers/staging/rtl8192e/rtl_crypto.h b/drivers/staging/rtl8192e/rtl8192e/rtl_crypto.h
similarity index 100%
rename from drivers/staging/rtl8192e/rtl_crypto.h
rename to drivers/staging/rtl8192e/rtl8192e/rtl_crypto.h
diff --git a/drivers/staging/rtl8192e/rtl_debug.c b/drivers/staging/rtl8192e/rtl8192e/rtl_debug.c
similarity index 94%
rename from drivers/staging/rtl8192e/rtl_debug.c
rename to drivers/staging/rtl8192e/rtl8192e/rtl_debug.c
index 22bc2dd..c19b14c 100644
--- a/drivers/staging/rtl8192e/rtl_debug.c
+++ b/drivers/staging/rtl8192e/rtl8192e/rtl_debug.c
@@ -22,91 +22,12 @@
  * Contact Information:
  * wlanfae <wlanfae@realtek.com>
 ******************************************************************************/
-#include "rtl_debug.h"
 #include "rtl_core.h"
 #include "r8192E_phy.h"
 #include "r8192E_phyreg.h"
 #include "r8190P_rtl8256.h" /* RTL8225 Radio frontend */
 #include "r8192E_cmdpkt.h"
 
-u32 rt_global_debug_component = \
-				COMP_ERR ;
-
-/*------------------Declare variable-----------------------*/
-u32	DBGP_Type[DBGP_TYPE_MAX];
-
-/*-----------------------------------------------------------------------------
- * Function:    DBGP_Flag_Init
- *
- * Overview:    Refresh all debug print control flag content to zero.
- *
- * Input:       NONE
- *
- * Output:      NONE
- *
- * Return:      NONE
- *
- * Revised History:
- *  When		Who		Remark
- *  10/20/2006	MHC		Create Version 0.
- *
- *---------------------------------------------------------------------------*/
-void	rtl8192_dbgp_flag_init(struct net_device *dev)
-{
-	u8 i;
-
-	for (i = 0; i < DBGP_TYPE_MAX; i++)
-		DBGP_Type[i] = 0;
-
-
-}	/* DBGP_Flag_Init */
-
-/* this is only for debugging */
-void print_buffer(u32 *buffer, int len)
-{
-	int i;
-	u8 *buf = (u8 *)buffer;
-
-	printk(KERN_INFO "ASCII BUFFER DUMP (len: %x):\n", len);
-
-	for (i = 0; i < len; i++)
-		printk(KERN_INFO "%c", buf[i]);
-
-	printk(KERN_INFO "\nBINARY BUFFER DUMP (len: %x):\n", len);
-
-	for (i = 0; i < len; i++)
-		printk(KERN_INFO "%x", buf[i]);
-
-	printk(KERN_INFO "\n");
-}
-
-/* this is only for debug */
-void dump_eprom(struct net_device *dev)
-{
-	int i;
-
-	for (i = 0; i < 0xff; i++)
-		RT_TRACE(COMP_INIT, "EEPROM addr %x : %x", i,
-			 eprom_read(dev, i));
-}
-
-/* this is only for debug */
-void rtl8192_dump_reg(struct net_device *dev)
-{
-	int i;
-	int n;
-	int max = 0x5ff;
-
-	RT_TRACE(COMP_INIT, "Dumping NIC register map");
-
-	for (n = 0; n <= max; ) {
-		printk(KERN_INFO "\nD: %2x> ", n);
-		for (i = 0; i < 16 && n <= max; i++, n++)
-			printk(KERN_INFO "%2x ", read_nic_byte(dev, n));
-	}
-	printk(KERN_INFO "\n");
-}
-
 /****************************************************************************
    -----------------------------PROCFS STUFF-------------------------
 *****************************************************************************/
diff --git a/drivers/staging/rtl8192e/rtl_dm.c b/drivers/staging/rtl8192e/rtl8192e/rtl_dm.c
similarity index 100%
rename from drivers/staging/rtl8192e/rtl_dm.c
rename to drivers/staging/rtl8192e/rtl8192e/rtl_dm.c
diff --git a/drivers/staging/rtl8192e/rtl_dm.h b/drivers/staging/rtl8192e/rtl8192e/rtl_dm.h
similarity index 100%
rename from drivers/staging/rtl8192e/rtl_dm.h
rename to drivers/staging/rtl8192e/rtl8192e/rtl_dm.h
diff --git a/drivers/staging/rtl8192e/rtl_eeprom.c b/drivers/staging/rtl8192e/rtl8192e/rtl_eeprom.c
similarity index 100%
rename from drivers/staging/rtl8192e/rtl_eeprom.c
rename to drivers/staging/rtl8192e/rtl8192e/rtl_eeprom.c
diff --git a/drivers/staging/rtl8192e/rtl_eeprom.h b/drivers/staging/rtl8192e/rtl8192e/rtl_eeprom.h
similarity index 100%
rename from drivers/staging/rtl8192e/rtl_eeprom.h
rename to drivers/staging/rtl8192e/rtl8192e/rtl_eeprom.h
diff --git a/drivers/staging/rtl8192e/rtl_ethtool.c b/drivers/staging/rtl8192e/rtl8192e/rtl_ethtool.c
similarity index 100%
rename from drivers/staging/rtl8192e/rtl_ethtool.c
rename to drivers/staging/rtl8192e/rtl8192e/rtl_ethtool.c
diff --git a/drivers/staging/rtl8192e/rtl_pci.c b/drivers/staging/rtl8192e/rtl8192e/rtl_pci.c
similarity index 100%
rename from drivers/staging/rtl8192e/rtl_pci.c
rename to drivers/staging/rtl8192e/rtl8192e/rtl_pci.c
diff --git a/drivers/staging/rtl8192e/rtl_pci.h b/drivers/staging/rtl8192e/rtl8192e/rtl_pci.h
similarity index 99%
rename from drivers/staging/rtl8192e/rtl_pci.h
rename to drivers/staging/rtl8192e/rtl8192e/rtl_pci.h
index 7ea5a47..28c7da6 100644
--- a/drivers/staging/rtl8192e/rtl_pci.h
+++ b/drivers/staging/rtl8192e/rtl8192e/rtl_pci.h
@@ -27,7 +27,6 @@
 
 #include <linux/types.h>
 #include <linux/pci.h>
-#include "rtllib.h"
 
 static inline void NdisRawWritePortUlong(u32 port,  u32 val)
 {
diff --git a/drivers/staging/rtl8192e/rtl_pm.c b/drivers/staging/rtl8192e/rtl8192e/rtl_pm.c
similarity index 99%
rename from drivers/staging/rtl8192e/rtl_pm.c
rename to drivers/staging/rtl8192e/rtl8192e/rtl_pm.c
index 92e2fde..8e1a5d5 100644
--- a/drivers/staging/rtl8192e/rtl_pm.c
+++ b/drivers/staging/rtl8192e/rtl8192e/rtl_pm.c
@@ -17,7 +17,6 @@
  * wlanfae <wlanfae@realtek.com>
 ******************************************************************************/
 
-#ifdef CONFIG_PM_RTL
 #include "rtl_core.h"
 #include "r8192E_hw.h"
 #include "r8190P_rtl8256.h"
@@ -133,4 +132,3 @@
 	return -EAGAIN;
 }
 
-#endif
diff --git a/drivers/staging/rtl8192e/rtl_pm.h b/drivers/staging/rtl8192e/rtl8192e/rtl_pm.h
similarity index 97%
rename from drivers/staging/rtl8192e/rtl_pm.h
rename to drivers/staging/rtl8192e/rtl8192e/rtl_pm.h
index 4d7f406..e5299fc 100644
--- a/drivers/staging/rtl8192e/rtl_pm.h
+++ b/drivers/staging/rtl8192e/rtl8192e/rtl_pm.h
@@ -17,8 +17,6 @@
  * wlanfae <wlanfae@realtek.com>
 ******************************************************************************/
 
-#ifdef CONFIG_PM_RTL
-
 #ifndef R8192E_PM_H
 #define R8192E_PM_H
 
@@ -31,5 +29,3 @@
 int rtl8192E_enable_wake(struct pci_dev *dev, pm_message_t state, int enable);
 
 #endif
-
-#endif
diff --git a/drivers/staging/rtl8192e/rtl_ps.c b/drivers/staging/rtl8192e/rtl8192e/rtl_ps.c
similarity index 100%
rename from drivers/staging/rtl8192e/rtl_ps.c
rename to drivers/staging/rtl8192e/rtl8192e/rtl_ps.c
diff --git a/drivers/staging/rtl8192e/rtl_ps.h b/drivers/staging/rtl8192e/rtl8192e/rtl_ps.h
similarity index 98%
rename from drivers/staging/rtl8192e/rtl_ps.h
rename to drivers/staging/rtl8192e/rtl8192e/rtl_ps.h
index a9c2d79..df79d6c 100644
--- a/drivers/staging/rtl8192e/rtl_ps.h
+++ b/drivers/staging/rtl8192e/rtl8192e/rtl_ps.h
@@ -26,7 +26,7 @@
 #define _RTL_PS_H
 
 #include <linux/types.h>
-#include "rtllib.h"
+
 struct net_device;
 
 #define RT_CHECK_FOR_HANG_PERIOD 2
diff --git a/drivers/staging/rtl8192e/rtl_wx.c b/drivers/staging/rtl8192e/rtl8192e/rtl_wx.c
similarity index 99%
rename from drivers/staging/rtl8192e/rtl_wx.c
rename to drivers/staging/rtl8192e/rtl8192e/rtl_wx.c
index 93b1edb..4e93669 100644
--- a/drivers/staging/rtl8192e/rtl_wx.c
+++ b/drivers/staging/rtl8192e/rtl8192e/rtl_wx.c
@@ -19,7 +19,6 @@
 
 #include <linux/string.h>
 #include "rtl_core.h"
-#include "dot11d.h"
 
 #define RATE_COUNT 12
 static u32 rtl8192_rates[] = {
@@ -803,7 +802,7 @@
 
 		switch (wrqu->encoding.flags & IW_ENCODE_INDEX) {
 		case 0:
-			key_idx = ieee->tx_keyidx;
+			key_idx = ieee->crypt_info.tx_keyidx;
 			break;
 		case 1:
 			key_idx = 0;
diff --git a/drivers/staging/rtl8192e/rtl_wx.h b/drivers/staging/rtl8192e/rtl8192e/rtl_wx.h
similarity index 100%
rename from drivers/staging/rtl8192e/rtl_wx.h
rename to drivers/staging/rtl8192e/rtl8192e/rtl_wx.h
diff --git a/drivers/staging/rtl8192e/rtl819x_BAProc.c b/drivers/staging/rtl8192e/rtl819x_BAProc.c
index 8b9d85c..32fbbc9 100644
--- a/drivers/staging/rtl8192e/rtl819x_BAProc.c
+++ b/drivers/staging/rtl8192e/rtl819x_BAProc.c
@@ -18,7 +18,6 @@
 ******************************************************************************/
 #include "rtllib.h"
 #include "rtl819x_BA.h"
-#include "rtl_core.h"
 
 static void ActivateBAEntry(struct rtllib_device *ieee, struct ba_record *pBA,
 			    u16 Time)
diff --git a/drivers/staging/rtl8192e/rtl819x_HTProc.c b/drivers/staging/rtl8192e/rtl819x_HTProc.c
index b1c0c56..8b74129 100644
--- a/drivers/staging/rtl8192e/rtl819x_HTProc.c
+++ b/drivers/staging/rtl8192e/rtl819x_HTProc.c
@@ -943,8 +943,8 @@
 	}
 }
 
-void HTUpdateSelfAndPeerSetting(struct rtllib_device *ieee,
-				struct rtllib_network *pNetwork)
+void HT_update_self_and_peer_setting(struct rtllib_device *ieee,
+				     struct rtllib_network *pNetwork)
 {
 	struct rt_hi_throughput *pHTInfo = ieee->pHTInfo;
 	struct ht_info_ele *pPeerHTInfo =
@@ -955,6 +955,7 @@
 			pHTInfo->CurrentOpMode = pPeerHTInfo->OptMode;
 	}
 }
+EXPORT_SYMBOL(HT_update_self_and_peer_setting);
 
 void HTUseDefaultSetting(struct rtllib_device *ieee)
 {
diff --git a/drivers/staging/rtl8192e/rtl819x_TSProc.c b/drivers/staging/rtl8192e/rtl819x_TSProc.c
index 09a602f..711a096 100644
--- a/drivers/staging/rtl8192e/rtl819x_TSProc.c
+++ b/drivers/staging/rtl8192e/rtl819x_TSProc.c
@@ -497,6 +497,7 @@
 		}
 	}
 }
+EXPORT_SYMBOL(RemovePeerTS);
 
 void RemoveAllTS(struct rtllib_device *ieee)
 {
diff --git a/drivers/staging/rtl8192e/rtl_debug.h b/drivers/staging/rtl8192e/rtl_debug.h
deleted file mode 100644
index 50fb9a9..0000000
--- a/drivers/staging/rtl8192e/rtl_debug.h
+++ /dev/null
@@ -1,299 +0,0 @@
-/******************************************************************************
- * Copyright(c) 2008 - 2010 Realtek Corporation. All rights reserved.
- *
- * Based on the r8180 driver, which is:
- * Copyright 2004-2005 Andrea Merello <andreamrl@tiscali.it>, et al.
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
- *
- * The full GNU General Public License is included in this distribution in the
- * file called LICENSE.
- *
- * Contact Information:
- * wlanfae <wlanfae@realtek.com>
-******************************************************************************/
-#ifndef _RTL_DEBUG_H
-#define _RTL_DEBUG_H
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/version.h>
-#include <linux/debugfs.h>
-
-struct r8192_priv;
-struct _tx_desc_8192se;
-struct _TX_DESC_8192CE;
-struct net_device;
-
-#define	DBG_LOUD	4
-
-#define RT_ASSERT(_Exp, Fmt)				\
-		if (!(_Exp)) {				\
-			printk("Rtl819x: ");		\
-			printk Fmt;			\
-		}
-
-enum dbgp_flag {
-	FQoS				= 0,
-	FTX				= 1,
-	FRX				= 2,
-	FSEC				= 3,
-	FMGNT				= 4,
-	FMLME				= 5,
-	FRESOURCE			= 6,
-	FBEACON				= 7,
-	FISR				= 8,
-	FPHY				= 9,
-	FMP				= 10,
-	FEEPROM				= 11,
-	FPWR				= 12,
-	FDM				= 13,
-	FDBGCtrl			= 14,
-	FC2H				= 15,
-	FBT				= 16,
-	FINIT				= 17,
-	FIOCTL				= 18,
-	DBGP_TYPE_MAX
-};
-
-#define		QoS_INIT				BIT0
-#define		QoS_VISTA				BIT1
-
-#define		TX_DESC					BIT0
-#define		TX_DESC_TID				BIT1
-
-#define		RX_DATA					BIT0
-#define		RX_PHY_STS				BIT1
-#define		RX_PHY_SS				BIT2
-#define		RX_PHY_SQ				BIT3
-#define		RX_PHY_ASTS				BIT4
-#define		RX_ERR_LEN				BIT5
-#define		RX_DEFRAG				BIT6
-#define		RX_ERR_RATE				BIT7
-
-
-
-#define		MEDIA_STS				BIT0
-#define		LINK_STS				BIT1
-
-#define		OS_CHK					BIT0
-
-#define		BCN_SHOW				BIT0
-#define		BCN_PEER				BIT1
-
-#define		ISR_CHK					BIT0
-
-#define		PHY_BBR					BIT0
-#define		PHY_BBW					BIT1
-#define		PHY_RFR					BIT2
-#define		PHY_RFW					BIT3
-#define		PHY_MACR				BIT4
-#define		PHY_MACW				BIT5
-#define		PHY_ALLR				BIT6
-#define		PHY_ALLW				BIT7
-#define		PHY_TXPWR				BIT8
-#define		PHY_PWRDIFF				BIT9
-
-#define		MP_RX					BIT0
-#define		MP_SWICH_CH				BIT1
-
-#define		EEPROM_W				BIT0
-#define		EFUSE_PG				BIT1
-#define		EFUSE_READ_ALL				BIT2
-
-#define		LPS					BIT0
-#define		IPS					BIT1
-#define		PWRSW					BIT2
-#define		PWRHW					BIT3
-#define		PWRHAL					BIT4
-
-#define		WA_IOT					BIT0
-#define		DM_PWDB					BIT1
-#define		DM_Monitor				BIT2
-#define		DM_DIG					BIT3
-#define		DM_EDCA_Turbo				BIT4
-
-#define		DbgCtrl_Trace				BIT0
-#define		DbgCtrl_InbandNoise			BIT1
-
-#define		BT_TRACE				BIT0
-#define		BT_RFPoll				BIT1
-
-#define		C2H_Summary				BIT0
-#define		C2H_PacketData				BIT1
-#define		C2H_ContentData				BIT2
-#define		BT_TRACE				BIT0
-#define		BT_RFPoll				BIT1
-
-#define		INIT_EEPROM				BIT0
-#define		INIT_TxPower				BIT1
-#define		INIT_IQK				BIT2
-#define		INIT_RF					BIT3
-
-#define		IOCTL_TRACE				BIT0
-#define		IOCTL_BT_EVENT				BIT1
-#define		IOCTL_BT_EVENT_DETAIL			BIT2
-#define		IOCTL_BT_TX_ACLDATA			BIT3
-#define		IOCTL_BT_TX_ACLDATA_DETAIL		BIT4
-#define		IOCTL_BT_RX_ACLDATA			BIT5
-#define		IOCTL_BT_RX_ACLDATA_DETAIL		BIT6
-#define		IOCTL_BT_HCICMD				BIT7
-#define		IOCTL_BT_HCICMD_DETAIL			BIT8
-#define		IOCTL_IRP				BIT9
-#define		IOCTL_IRP_DETAIL			BIT10
-#define		IOCTL_CALLBACK_FUN			BIT11
-#define		IOCTL_STATE				BIT12
-#define		IOCTL_BT_TP				BIT13
-#define		IOCTL_BT_LOGO				BIT14
-
-/* 2007/07/13 MH  ------For DeBuG Print modeue------*/
-/*------------------------------Define structure----------------------------*/
-
-
-/*------------------------Export Marco Definition---------------------------*/
-#define		DEBUG_PRINT		1
-
-#if (DEBUG_PRINT == 1)
-#define RTPRINT(dbgtype, dbgflag, printstr)			\
-{								\
-	if (DBGP_Type[dbgtype] & dbgflag) {			\
-		printk printstr;				\
-	}							\
-}
-
-#define	RTPRINT_ADDR(dbgtype, dbgflag, printstr, _Ptr)		\
-{								\
-	if (DBGP_Type[dbgtype] & dbgflag) {			\
-		int __i;					\
-		u8 *ptr = (u8 *)_Ptr;				\
-		printk printstr;				\
-		printk(" ");					\
-		for (__i = 0; __i < 6; __i++)			\
-			printk("%02X%s", ptr[__i],		\
-			       (__i == 5) ? "" : "-");		\
-			printk("\n");				\
-	}							\
-}
-
-#define RTPRINT_DATA(dbgtype, dbgflag, _TitleString, _HexData, _HexDataLen)\
-{								\
-	if (DBGP_Type[dbgtype] & dbgflag) {			\
-		int __i;					\
-		u8 *ptr = (u8 *)_HexData;			\
-		printk(_TitleString);				\
-		for (__i = 0; __i < (int)_HexDataLen; __i++) {	\
-			printk("%02X%s", ptr[__i], (((__i + 1)	\
-			       % 4) == 0) ? "  " : " ");	\
-			if (((__i + 1) % 16) == 0)		\
-				printk("\n");			\
-		}						\
-		printk("\n");					\
-	}							\
-}
-#else
-#define	RTPRINT(dbgtype, dbgflag, printstr)
-#define	RTPRINT_ADDR(dbgtype, dbgflag, printstr, _Ptr)
-#define RTPRINT_DATA(dbgtype, dbgflag, _TitleString, _HexData, _HexDataLen)
-#endif
-
-extern u32	DBGP_Type[DBGP_TYPE_MAX];
-
-#define RT_PRINT_DATA(_Comp, _Level, _TitleString, _HexData, _HexDataLen) \
-do {\
-	if (((_Comp) & rt_global_debug_component) &&			\
-	     (_Level <= rt_global_debug_component)) {			\
-		int __i;						\
-		u8*	ptr = (u8 *)_HexData;				\
-		printk(KERN_INFO "Rtl819x: ");				\
-		printk(_TitleString);					\
-		for (__i = 0; __i < (int)_HexDataLen; __i++) {		\
-			printk("%02X%s", ptr[__i], (((__i + 1) %	\
-			       4) == 0) ? "  " : " ");			\
-			if (((__i + 1) % 16) == 0)			\
-				printk("\n");				\
-		}							\
-		printk("\n");						\
-	} \
-} while (0);
-
-#define DMESG(x, a...)
-#define DMESGW(x, a...)
-#define DMESGE(x, a...)
-extern u32 rt_global_debug_component;
-#define RT_TRACE(component, x, args...) \
-do {			\
-	if (rt_global_debug_component & component) \
-		printk(KERN_DEBUG DRV_NAME ":" x "\n" , \
-		       ##args);\
-} while (0);
-
-#define assert(expr) \
-	if (!(expr)) {				  \
-		printk(KERN_INFO "Assertion failed! %s,%s,%s,line=%d\n", \
-		#expr, __FILE__, __func__, __LINE__);	  \
-	}
-#define RT_DEBUG_DATA(level, data, datalen)      \
-	do {								\
-		if ((rt_global_debug_component & (level)) == (level)) {\
-			int _i;				  \
-			u8 *_pdata = (u8 *)data;		 \
-			printk(KERN_DEBUG DRV_NAME ": %s()\n", __func__);   \
-			for (_i = 0; _i < (int)(datalen); _i++) {	\
-				printk(KERN_INFO "%2x ", _pdata[_i]);	\
-				if ((_i+1) % 16 == 0)			\
-					printk("\n");			\
-			}			       \
-			printk(KERN_INFO "\n");	  \
-		}				       \
-	} while (0)
-
-struct rtl_fs_debug {
-	const char *name;
-	struct dentry *dir_drv;
-	struct dentry *debug_register;
-	u32 hw_type;
-	u32 hw_offset;
-	bool hw_holding;
-};
-
-void print_buffer(u32 *buffer, int len);
-void dump_eprom(struct net_device *dev);
-void rtl8192_dump_reg(struct net_device *dev);
-
-/* debugfs stuff */
-static inline int rtl_debug_module_init(struct r8192_priv *priv,
-					const char *name)
-{
-	return 0;
-}
-
-static inline void rtl_debug_module_remove(struct r8192_priv *priv)
-{
-}
-
-static inline int rtl_create_debugfs_root(void)
-{
-	return 0;
-}
-
-static inline void rtl_remove_debugfs_root(void)
-{
-}
-
-/* proc stuff */
-void rtl8192_proc_init_one(struct net_device *dev);
-void rtl8192_proc_remove_one(struct net_device *dev);
-void rtl8192_proc_module_init(void);
-void rtl8192_proc_module_remove(void);
-void rtl8192_dbgp_flag_init(struct net_device *dev);
-
-#endif
diff --git a/drivers/staging/rtl8192e/rtllib.h b/drivers/staging/rtl8192e/rtllib.h
index de25975..e26aec8 100644
--- a/drivers/staging/rtl8192e/rtllib.h
+++ b/drivers/staging/rtl8192e/rtllib.h
@@ -25,7 +25,6 @@
 #define RTLLIB_H
 #include <linux/if_ether.h> /* ETH_ALEN */
 #include <linux/kernel.h>   /* ARRAY_SIZE */
-#include <linux/version.h>
 #include <linux/module.h>
 #include <linux/interrupt.h>
 #include <linux/jiffies.h>
@@ -36,12 +35,14 @@
 #include <linux/delay.h>
 #include <linux/wireless.h>
 
+#include "rtllib_debug.h"
 #include "rtl819x_HT.h"
 #include "rtl819x_BA.h"
 #include "rtl819x_TS.h"
 
 #include <linux/netdevice.h>
 #include <linux/if_arp.h> /* ARPHRD_ETHER */
+#include <net/lib80211.h>
 
 #define MAX_PRECMD_CNT 16
 #define MAX_RFDEPENDCMD_CNT 16
@@ -870,69 +871,6 @@
 #define WLAN_ERP_USE_PROTECTION (1<<1)
 #define WLAN_ERP_BARKER_PREAMBLE (1<<2)
 
-/* Status codes */
-enum rtllib_statuscode {
-	WLAN_STATUS_SUCCESS = 0,
-	WLAN_STATUS_UNSPECIFIED_FAILURE = 1,
-	WLAN_STATUS_CAPS_UNSUPPORTED = 10,
-	WLAN_STATUS_REASSOC_NO_ASSOC = 11,
-	WLAN_STATUS_ASSOC_DENIED_UNSPEC = 12,
-	WLAN_STATUS_NOT_SUPPORTED_AUTH_ALG = 13,
-	WLAN_STATUS_UNKNOWN_AUTH_TRANSACTION = 14,
-	WLAN_STATUS_CHALLENGE_FAIL = 15,
-	WLAN_STATUS_AUTH_TIMEOUT = 16,
-	WLAN_STATUS_AP_UNABLE_TO_HANDLE_NEW_STA = 17,
-	WLAN_STATUS_ASSOC_DENIED_RATES = 18,
-	/* 802.11b */
-	WLAN_STATUS_ASSOC_DENIED_NOSHORTPREAMBLE = 19,
-	WLAN_STATUS_ASSOC_DENIED_NOPBCC = 20,
-	WLAN_STATUS_ASSOC_DENIED_NOAGILITY = 21,
-	/* 802.11h */
-	WLAN_STATUS_ASSOC_DENIED_NOSPECTRUM = 22,
-	WLAN_STATUS_ASSOC_REJECTED_BAD_POWER = 23,
-	WLAN_STATUS_ASSOC_REJECTED_BAD_SUPP_CHAN = 24,
-	/* 802.11g */
-	WLAN_STATUS_ASSOC_DENIED_NOSHORTTIME = 25,
-	WLAN_STATUS_ASSOC_DENIED_NODSSSOFDM = 26,
-	/* 802.11i */
-	WLAN_STATUS_INVALID_IE = 40,
-	WLAN_STATUS_INVALID_GROUP_CIPHER = 41,
-	WLAN_STATUS_INVALID_PAIRWISE_CIPHER = 42,
-	WLAN_STATUS_INVALID_AKMP = 43,
-	WLAN_STATUS_UNSUPP_RSN_VERSION = 44,
-	WLAN_STATUS_INVALID_RSN_IE_CAP = 45,
-	WLAN_STATUS_CIPHER_SUITE_REJECTED = 46,
-};
-
-/* Reason codes */
-enum rtllib_reasoncode {
-	WLAN_REASON_UNSPECIFIED = 1,
-	WLAN_REASON_PREV_AUTH_NOT_VALID = 2,
-	WLAN_REASON_DEAUTH_LEAVING = 3,
-	WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY = 4,
-	WLAN_REASON_DISASSOC_AP_BUSY = 5,
-	WLAN_REASON_CLASS2_FRAME_FROM_NONAUTH_STA = 6,
-	WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA = 7,
-	WLAN_REASON_DISASSOC_STA_HAS_LEFT = 8,
-	WLAN_REASON_STA_REQ_ASSOC_WITHOUT_AUTH = 9,
-	/* 802.11h */
-	WLAN_REASON_DISASSOC_BAD_POWER = 10,
-	WLAN_REASON_DISASSOC_BAD_SUPP_CHAN = 11,
-	/* 802.11i */
-	WLAN_REASON_INVALID_IE = 13,
-	WLAN_REASON_MIC_FAILURE = 14,
-	WLAN_REASON_4WAY_HANDSHAKE_TIMEOUT = 15,
-	WLAN_REASON_GROUP_KEY_HANDSHAKE_TIMEOUT = 16,
-	WLAN_REASON_IE_DIFFERENT = 17,
-	WLAN_REASON_INVALID_GROUP_CIPHER = 18,
-	WLAN_REASON_INVALID_PAIRWISE_CIPHER = 19,
-	WLAN_REASON_INVALID_AKMP = 20,
-	WLAN_REASON_UNSUPP_RSN_VERSION = 21,
-	WLAN_REASON_INVALID_RSN_IE_CAP = 22,
-	WLAN_REASON_IEEE8021X_FAILED = 23,
-	WLAN_REASON_CIPHER_SUITE_REJECTED = 24,
-};
-
 #define RTLLIB_STATMASK_SIGNAL (1<<0)
 #define RTLLIB_STATMASK_RSSI (1<<1)
 #define RTLLIB_STATMASK_NOISE (1<<2)
@@ -1122,8 +1060,6 @@
 
 struct rtllib_device;
 
-#include "rtllib_crypt.h"
-
 #define SEC_KEY_1	 (1<<0)
 #define SEC_KEY_2	 (1<<1)
 #define SEC_KEY_3	 (1<<2)
@@ -1146,7 +1082,6 @@
 #define SEC_ALG_TKIP		2
 #define SEC_ALG_CCMP		4
 
-#define WEP_KEYS		4
 #define WEP_KEY_LEN		13
 #define SCM_KEY_LEN		32
 #define SCM_TEMPORAL_KEY_LENGTH 16
@@ -1158,8 +1093,8 @@
 	    auth_algo:4,
 	    unicast_uses_group:1,
 	    encrypt:1;
-	u8 key_sizes[WEP_KEYS];
-	u8 keys[WEP_KEYS][SCM_KEY_LEN];
+	u8 key_sizes[NUM_WEP_KEYS];
+	u8 keys[NUM_WEP_KEYS][SCM_KEY_LEN];
 	u8 level;
 	u16 flags;
 } __packed;
@@ -2251,14 +2186,10 @@
 	u8 ap_mac_addr[6];
 	u16 pairwise_key_type;
 	u16 group_key_type;
-	struct list_head crypt_deinit_list;
-	struct rtllib_crypt_data *crypt[WEP_KEYS];
 
-	int tx_keyidx; /* default TX key index (crypt[tx_keyidx]) */
+	struct lib80211_crypt_info crypt_info;
+
 	struct sw_cam_table swcamtable[TOTAL_CAM_ENTRY];
-	struct timer_list crypt_deinit_timer;
-	int crypt_quiesced;
-
 	int bcrx_sta_key; /* use individual keys to override default keys even
 			   * with RX of broad/multicast frames */
 
@@ -2774,7 +2705,7 @@
 			     struct rtllib_rx_stats *stats);
 extern void rtllib_rx_probe_rq(struct rtllib_device *ieee,
 			   struct sk_buff *skb);
-extern int IsLegalChannel(struct rtllib_device *rtllib, u8 channel);
+extern int rtllib_legal_channel(struct rtllib_device *rtllib, u8 channel);
 
 /* rtllib_wx.c */
 extern int rtllib_wx_get_scan(struct rtllib_device *ieee,
@@ -2804,7 +2735,7 @@
 
 /* rtllib_softmac.c */
 extern short rtllib_is_54g(struct rtllib_network *net);
-extern short rtllib_is_shortslot(struct rtllib_network net);
+extern short rtllib_is_shortslot(const struct rtllib_network *net);
 extern int rtllib_rx_frame_softmac(struct rtllib_device *ieee,
 				   struct sk_buff *skb,
 				   struct rtllib_rx_stats *rx_stats, u16 type,
@@ -2971,8 +2902,8 @@
 extern void HTInitializeBssDesc(struct bss_ht *pBssHT);
 extern void HTResetSelfAndSavePeerSetting(struct rtllib_device *ieee,
 					  struct rtllib_network *pNetwork);
-extern void HTUpdateSelfAndPeerSetting(struct rtllib_device *ieee,
-				       struct rtllib_network *pNetwork);
+extern void HT_update_self_and_peer_setting(struct rtllib_device *ieee,
+					    struct rtllib_network *pNetwork);
 extern u8 HTGetHighestMCSRate(struct rtllib_device *ieee, u8 *pMCSRateSet,
 			      u8 *pMCSFilter);
 extern u8 MCS_FILTER_ALL[];
@@ -3052,21 +2983,6 @@
 	(HTMcsToDataRate(_ieee, (u8)_MGN_RATE)))
 
 /* fun with the built-in rtllib stack... */
-int rtllib_init(void);
-void rtllib_exit(void);
-int rtllib_crypto_init(void);
-void rtllib_crypto_deinit(void);
-int rtllib_crypto_tkip_init(void);
-void rtllib_crypto_tkip_exit(void);
-int rtllib_crypto_ccmp_init(void);
-void rtllib_crypto_ccmp_exit(void);
-int rtllib_crypto_wep_init(void);
-void rtllib_crypto_wep_exit(void);
-
-void rtllib_MgntDisconnectIBSS(struct rtllib_device *rtllib);
-void rtllib_MlmeDisassociateRequest(struct rtllib_device *rtllib, u8 *asSta,
-				    u8 asRsn);
-void rtllib_MgntDisconnectAP(struct rtllib_device *rtllib, u8 asRsn);
 bool rtllib_MgntDisconnect(struct rtllib_device *rtllib, u8 asRsn);
 
 
@@ -3133,12 +3049,5 @@
 #define MUTEX_LOCK_PRIV(pmutex) mutex_lock(pmutex)
 #define MUTEX_UNLOCK_PRIV(pmutex) mutex_unlock(pmutex)
 #endif
-static inline void dump_buf(u8 *buf, u32 len)
-{
-	u32 i;
-	printk(KERN_INFO "-----------------Len %d----------------\n", len);
-	for (i = 0; i < len; i++)
-		printk("%2.2x-", *(buf+i));
-	printk("\n");
-}
+
 #endif /* RTLLIB_H */
diff --git a/drivers/staging/rtl8192e/rtllib_crypt.c b/drivers/staging/rtl8192e/rtllib_crypt.c
index acda37b..86152d0 100644
--- a/drivers/staging/rtl8192e/rtllib_crypt.c
+++ b/drivers/staging/rtl8192e/rtllib_crypt.c
@@ -11,7 +11,6 @@
  *
  */
 
-#include <linux/version.h>
 #include <linux/module.h>
 #include <linux/init.h>
 #include <linux/slab.h>
@@ -22,7 +21,7 @@
 
 struct rtllib_crypto_alg {
 	struct list_head list;
-	struct rtllib_crypto_ops *ops;
+	struct lib80211_crypto_ops *ops;
 };
 
 
@@ -33,15 +32,15 @@
 
 static struct rtllib_crypto *hcrypt;
 
-void rtllib_crypt_deinit_entries(struct rtllib_device *ieee,
+void rtllib_crypt_deinit_entries(struct lib80211_crypt_info *info,
 					   int force)
 {
 	struct list_head *ptr, *n;
-	struct rtllib_crypt_data *entry;
+	struct lib80211_crypt_data *entry;
 
-	for (ptr = ieee->crypt_deinit_list.next, n = ptr->next;
-	     ptr != &ieee->crypt_deinit_list; ptr = n, n = ptr->next) {
-		entry = list_entry(ptr, struct rtllib_crypt_data, list);
+	for (ptr = info->crypt_deinit_list.next, n = ptr->next;
+	     ptr != &info->crypt_deinit_list; ptr = n, n = ptr->next) {
+		entry = list_entry(ptr, struct lib80211_crypt_data, list);
 
 		if (atomic_read(&entry->refcnt) != 0 && !force)
 			continue;
@@ -53,28 +52,30 @@
 		kfree(entry);
 	}
 }
+EXPORT_SYMBOL(rtllib_crypt_deinit_entries);
 
 void rtllib_crypt_deinit_handler(unsigned long data)
 {
-	struct rtllib_device *ieee = (struct rtllib_device *)data;
+	struct lib80211_crypt_info *info = (struct lib80211_crypt_info *)data;
 	unsigned long flags;
 
-	spin_lock_irqsave(&ieee->lock, flags);
-	rtllib_crypt_deinit_entries(ieee, 0);
-	if (!list_empty(&ieee->crypt_deinit_list)) {
+	spin_lock_irqsave(info->lock, flags);
+	rtllib_crypt_deinit_entries(info, 0);
+	if (!list_empty(&info->crypt_deinit_list)) {
 		printk(KERN_DEBUG "%s: entries remaining in delayed crypt "
-		       "deletion list\n", ieee->dev->name);
-		ieee->crypt_deinit_timer.expires = jiffies + HZ;
-		add_timer(&ieee->crypt_deinit_timer);
+		       "deletion list\n", info->name);
+		info->crypt_deinit_timer.expires = jiffies + HZ;
+		add_timer(&info->crypt_deinit_timer);
 	}
-	spin_unlock_irqrestore(&ieee->lock, flags);
+	spin_unlock_irqrestore(info->lock, flags);
 
 }
+EXPORT_SYMBOL(rtllib_crypt_deinit_handler);
 
-void rtllib_crypt_delayed_deinit(struct rtllib_device *ieee,
-				    struct rtllib_crypt_data **crypt)
+void rtllib_crypt_delayed_deinit(struct lib80211_crypt_info *info,
+				 struct lib80211_crypt_data **crypt)
 {
-	struct rtllib_crypt_data *tmp;
+	struct lib80211_crypt_data *tmp;
 	unsigned long flags;
 
 	if (*crypt == NULL)
@@ -87,16 +88,17 @@
 	 * decrypt operations. Use a list of delayed deinits to avoid needing
 	 * locking. */
 
-	spin_lock_irqsave(&ieee->lock, flags);
-	list_add(&tmp->list, &ieee->crypt_deinit_list);
-	if (!timer_pending(&ieee->crypt_deinit_timer)) {
-		ieee->crypt_deinit_timer.expires = jiffies + HZ;
-		add_timer(&ieee->crypt_deinit_timer);
+	spin_lock_irqsave(info->lock, flags);
+	list_add(&tmp->list, &info->crypt_deinit_list);
+	if (!timer_pending(&info->crypt_deinit_timer)) {
+		info->crypt_deinit_timer.expires = jiffies + HZ;
+		add_timer(&info->crypt_deinit_timer);
 	}
-	spin_unlock_irqrestore(&ieee->lock, flags);
+	spin_unlock_irqrestore(info->lock, flags);
 }
+EXPORT_SYMBOL(rtllib_crypt_delayed_deinit);
 
-int rtllib_register_crypto_ops(struct rtllib_crypto_ops *ops)
+int rtllib_register_crypto_ops(struct lib80211_crypto_ops *ops)
 {
 	unsigned long flags;
 	struct rtllib_crypto_alg *alg;
@@ -104,11 +106,10 @@
 	if (hcrypt == NULL)
 		return -1;
 
-	alg = kmalloc(sizeof(*alg), GFP_KERNEL);
+	alg = kzalloc(sizeof(*alg), GFP_KERNEL);
 	if (alg == NULL)
 		return -ENOMEM;
 
-	memset(alg, 0, sizeof(*alg));
 	alg->ops = ops;
 
 	spin_lock_irqsave(&hcrypt->lock, flags);
@@ -120,8 +121,9 @@
 
 	return 0;
 }
+EXPORT_SYMBOL(rtllib_register_crypto_ops);
 
-int rtllib_unregister_crypto_ops(struct rtllib_crypto_ops *ops)
+int rtllib_unregister_crypto_ops(struct lib80211_crypto_ops *ops)
 {
 	unsigned long flags;
 	struct list_head *ptr;
@@ -150,9 +152,10 @@
 
 	return del_alg ? 0 : -1;
 }
+EXPORT_SYMBOL(rtllib_unregister_crypto_ops);
 
 
-struct rtllib_crypto_ops *rtllib_get_crypto_ops(const char *name)
+struct lib80211_crypto_ops *rtllib_get_crypto_ops(const char *name)
 {
 	unsigned long flags;
 	struct list_head *ptr;
@@ -177,12 +180,13 @@
 	else
 		return NULL;
 }
+EXPORT_SYMBOL(rtllib_get_crypto_ops);
 
 
 static void * rtllib_crypt_null_init(int keyidx) { return (void *) 1; }
 static void rtllib_crypt_null_deinit(void *priv) {}
 
-static struct rtllib_crypto_ops rtllib_crypt_null = {
+static struct lib80211_crypto_ops rtllib_crypt_null = {
 	.name			= "NULL",
 	.init			= rtllib_crypt_null_init,
 	.deinit			= rtllib_crypt_null_deinit,
@@ -192,8 +196,10 @@
 	.decrypt_msdu		= NULL,
 	.set_key		= NULL,
 	.get_key		= NULL,
-	.extra_prefix_len	= 0,
-	.extra_postfix_len	= 0,
+	.extra_mpdu_prefix_len	= 0,
+	.extra_mpdu_postfix_len	= 0,
+	.extra_msdu_prefix_len	= 0,
+	.extra_msdu_postfix_len	= 0,
 	.owner			= THIS_MODULE,
 };
 
@@ -202,15 +208,14 @@
 {
 	int ret = -ENOMEM;
 
-	hcrypt = kmalloc(sizeof(*hcrypt), GFP_KERNEL);
+	hcrypt = kzalloc(sizeof(*hcrypt), GFP_KERNEL);
 	if (!hcrypt)
 		goto out;
 
-	memset(hcrypt, 0, sizeof(*hcrypt));
 	INIT_LIST_HEAD(&hcrypt->algs);
 	spin_lock_init(&hcrypt->lock);
 
-	ret = rtllib_register_crypto_ops(&rtllib_crypt_null);
+	ret = lib80211_register_crypto_ops(&rtllib_crypt_null);
 	if (ret < 0) {
 		kfree(hcrypt);
 		hcrypt = NULL;
@@ -239,3 +244,8 @@
 
 	kfree(hcrypt);
 }
+
+module_init(rtllib_crypto_init);
+module_exit(rtllib_crypto_deinit);
+
+MODULE_LICENSE("GPL");
diff --git a/drivers/staging/rtl8192e/rtllib_crypt.h b/drivers/staging/rtl8192e/rtllib_crypt.h
index 49b90b7..e177c92 100644
--- a/drivers/staging/rtl8192e/rtllib_crypt.h
+++ b/drivers/staging/rtl8192e/rtllib_crypt.h
@@ -25,61 +25,11 @@
 
 #include <linux/skbuff.h>
 
-struct rtllib_crypto_ops {
-	const char *name;
-
-	/* init new crypto context (e.g., allocate private data space,
-	 * select IV, etc.); returns NULL on failure or pointer to allocated
-	 * private data on success */
-	void * (*init)(int keyidx);
-
-	/* deinitialize crypto context and free allocated private data */
-	void (*deinit)(void *priv);
-
-	/* encrypt/decrypt return < 0 on error or >= 0 on success. The return
-	 * value from decrypt_mpdu is passed as the keyidx value for
-	 * decrypt_msdu. skb must have enough head and tail room for the
-	 * encryption; if not, error will be returned; these functions are
-	 * called for all MPDUs (i.e., fragments).
-	 */
-	int (*encrypt_mpdu)(struct sk_buff *skb, int hdr_len, void *priv);
-	int (*decrypt_mpdu)(struct sk_buff *skb, int hdr_len, void *priv);
-
-	/* These functions are called for full MSDUs, i.e. full frames.
-	 * These can be NULL if full MSDU operations are not needed. */
-	int (*encrypt_msdu)(struct sk_buff *skb, int hdr_len, void *priv);
-	int (*decrypt_msdu)(struct sk_buff *skb, int keyidx, int hdr_len,
-			    void *priv, struct rtllib_device* ieee);
-
-	int (*set_key)(void *key, int len, u8 *seq, void *priv);
-	int (*get_key)(void *key, int len, u8 *seq, void *priv);
-
-	/* procfs handler for printing out key information and possible
-	 * statistics */
-	char * (*print_stats)(char *p, void *priv);
-
-	/* maximum number of bytes added by encryption; encrypt buf is
-	 * allocated with extra_prefix_len bytes, copy of in_buf, and
-	 * extra_postfix_len; encrypt need not use all this space, but
-	 * the result must start at the beginning of the struct buffer and
-	 * correct length must be returned */
-	int extra_prefix_len, extra_postfix_len;
-
-	struct module *owner;
-};
-
-struct rtllib_crypt_data {
-	struct list_head list; /* delayed deletion list */
-	struct rtllib_crypto_ops *ops;
-	void *priv;
-	atomic_t refcnt;
-};
-
-int rtllib_register_crypto_ops(struct rtllib_crypto_ops *ops);
-int rtllib_unregister_crypto_ops(struct rtllib_crypto_ops *ops);
-struct rtllib_crypto_ops *rtllib_get_crypto_ops(const char *name);
-void rtllib_crypt_deinit_entries(struct rtllib_device *, int);
-void rtllib_crypt_deinit_handler(unsigned long);
-void rtllib_crypt_delayed_deinit(struct rtllib_device *ieee,
-				 struct rtllib_crypt_data **crypt);
+int rtllib_register_crypto_ops(struct lib80211_crypto_ops *ops);
+int rtllib_unregister_crypto_ops(struct lib80211_crypto_ops *ops);
+struct lib80211_crypto_ops *rtllib_get_crypto_ops(const char *name);
+void rtllib_crypt_deinit_entries(struct lib80211_crypt_info *info, int force);
+void rtllib_crypt_deinit_handler(unsigned long data);
+void rtllib_crypt_delayed_deinit(struct lib80211_crypt_info *info,
+				 struct lib80211_crypt_data **crypt);
 #endif
diff --git a/drivers/staging/rtl8192e/rtllib_crypt_ccmp.c b/drivers/staging/rtl8192e/rtllib_crypt_ccmp.c
index 6196b9a..4217b88 100644
--- a/drivers/staging/rtl8192e/rtllib_crypt_ccmp.c
+++ b/drivers/staging/rtl8192e/rtllib_crypt_ccmp.c
@@ -9,7 +9,6 @@
  * more details.
  */
 
-#include <linux/version.h>
 #include <linux/module.h>
 #include <linux/init.h>
 #include <linux/slab.h>
@@ -63,10 +62,9 @@
 {
 	struct rtllib_ccmp_data *priv;
 
-	priv = kmalloc(sizeof(*priv), GFP_ATOMIC);
+	priv = kzalloc(sizeof(*priv), GFP_ATOMIC);
 	if (priv == NULL)
 		goto fail;
-	memset(priv, 0, sizeof(*priv));
 	priv->key_idx = key_idx;
 
 	priv->tfm = (void *)crypto_alloc_cipher("aes", 0, CRYPTO_ALG_ASYNC);
@@ -429,13 +427,8 @@
 	return p;
 }
 
-void rtllib_ccmp_null(void)
-{
-	return;
-}
-
-static struct rtllib_crypto_ops rtllib_crypt_ccmp = {
-	.name			= "CCMP",
+static struct lib80211_crypto_ops rtllib_crypt_ccmp = {
+	.name			= "R-CCMP",
 	.init			= rtllib_ccmp_init,
 	.deinit			= rtllib_ccmp_deinit,
 	.encrypt_mpdu		= rtllib_ccmp_encrypt,
@@ -445,19 +438,24 @@
 	.set_key		= rtllib_ccmp_set_key,
 	.get_key		= rtllib_ccmp_get_key,
 	.print_stats		= rtllib_ccmp_print_stats,
-	.extra_prefix_len	= CCMP_HDR_LEN,
-	.extra_postfix_len	= CCMP_MIC_LEN,
+	.extra_mpdu_prefix_len = CCMP_HDR_LEN,
+	.extra_mpdu_postfix_len = CCMP_MIC_LEN,
 	.owner			= THIS_MODULE,
 };
 
 
 int __init rtllib_crypto_ccmp_init(void)
 {
-	return rtllib_register_crypto_ops(&rtllib_crypt_ccmp);
+	return lib80211_register_crypto_ops(&rtllib_crypt_ccmp);
 }
 
 
 void __exit rtllib_crypto_ccmp_exit(void)
 {
-	rtllib_unregister_crypto_ops(&rtllib_crypt_ccmp);
+	lib80211_unregister_crypto_ops(&rtllib_crypt_ccmp);
 }
+
+module_init(rtllib_crypto_ccmp_init);
+module_exit(rtllib_crypto_ccmp_exit);
+
+MODULE_LICENSE("GPL");
diff --git a/drivers/staging/rtl8192e/rtllib_crypt_tkip.c b/drivers/staging/rtl8192e/rtllib_crypt_tkip.c
index 6a0c878..8009250 100644
--- a/drivers/staging/rtl8192e/rtllib_crypt_tkip.c
+++ b/drivers/staging/rtl8192e/rtllib_crypt_tkip.c
@@ -9,7 +9,6 @@
  * more details.
  */
 
-#include <linux/version.h>
 #include <linux/module.h>
 #include <linux/init.h>
 #include <linux/slab.h>
@@ -60,10 +59,9 @@
 {
 	struct rtllib_tkip_data *priv;
 
-	priv = kmalloc(sizeof(*priv), GFP_ATOMIC);
+	priv = kzalloc(sizeof(*priv), GFP_ATOMIC);
 	if (priv == NULL)
 		goto fail;
-	memset(priv, 0, sizeof(*priv));
 	priv->key_idx = key_idx;
 	priv->tx_tfm_arc4 = crypto_alloc_blkcipher("ecb(arc4)", 0,
 			CRYPTO_ALG_ASYNC);
@@ -598,8 +596,7 @@
 }
 
 static int rtllib_michael_mic_verify(struct sk_buff *skb, int keyidx,
-				     int hdr_len, void *priv,
-				     struct rtllib_device *ieee)
+				     int hdr_len, void *priv)
 {
 	struct rtllib_tkip_data *tkey = priv;
 	u8 mic[8];
@@ -618,23 +615,20 @@
 			skb->data + hdr_len, skb->len - 8 - hdr_len, mic))
 		return -1;
 
-	if ((memcmp(mic, skb->data + skb->len - 8, 8) != 0) ||
-	   (ieee->force_mic_error)) {
+	if (memcmp(mic, skb->data + skb->len - 8, 8) != 0) {
 		struct rtllib_hdr_4addr *hdr;
 		hdr = (struct rtllib_hdr_4addr *) skb->data;
 		printk(KERN_DEBUG "%s: Michael MIC verification failed for "
 		       "MSDU from %pM keyidx=%d\n",
 		       skb->dev ? skb->dev->name : "N/A", hdr->addr2,
 		       keyidx);
-		printk(KERN_DEBUG "%d, force_mic_error = %d\n",
-		       (memcmp(mic, skb->data + skb->len - 8, 8) != 0),\
-			ieee->force_mic_error);
+		printk(KERN_DEBUG "%d\n",
+		       memcmp(mic, skb->data + skb->len - 8, 8) != 0);
 		if (skb->dev) {
 			printk(KERN_INFO "skb->dev != NULL\n");
 			rtllib_michael_mic_failure(skb->dev, hdr, keyidx);
 		}
 		tkey->dot11RSNAStatsTKIPLocalMICFailures++;
-		ieee->force_mic_error = false;
 		return -1;
 	}
 
@@ -740,9 +734,8 @@
 	return p;
 }
 
-
-static struct rtllib_crypto_ops rtllib_crypt_tkip = {
-	.name			= "TKIP",
+static struct lib80211_crypto_ops rtllib_crypt_tkip = {
+	.name			= "R-TKIP",
 	.init			= rtllib_tkip_init,
 	.deinit			= rtllib_tkip_deinit,
 	.encrypt_mpdu		= rtllib_tkip_encrypt,
@@ -752,24 +745,25 @@
 	.set_key		= rtllib_tkip_set_key,
 	.get_key		= rtllib_tkip_get_key,
 	.print_stats		= rtllib_tkip_print_stats,
-	.extra_prefix_len	= 4 + 4, /* IV + ExtIV */
-	.extra_postfix_len	= 8 + 4, /* MIC + ICV */
+	.extra_mpdu_prefix_len = 4 + 4,	/* IV + ExtIV */
+	.extra_mpdu_postfix_len = 4,	/* ICV */
+	.extra_msdu_postfix_len = 8,	/* MIC */
 	.owner			= THIS_MODULE,
 };
 
 
 int __init rtllib_crypto_tkip_init(void)
 {
-	return rtllib_register_crypto_ops(&rtllib_crypt_tkip);
+	return lib80211_register_crypto_ops(&rtllib_crypt_tkip);
 }
 
 
 void __exit rtllib_crypto_tkip_exit(void)
 {
-	rtllib_unregister_crypto_ops(&rtllib_crypt_tkip);
+	lib80211_unregister_crypto_ops(&rtllib_crypt_tkip);
 }
 
-void rtllib_tkip_null(void)
-{
-	return;
-}
+module_init(rtllib_crypto_tkip_init);
+module_exit(rtllib_crypto_tkip_exit);
+
+MODULE_LICENSE("GPL");
diff --git a/drivers/staging/rtl8192e/rtllib_crypt_wep.c b/drivers/staging/rtl8192e/rtllib_crypt_wep.c
index c59bf10..8cdf389 100644
--- a/drivers/staging/rtl8192e/rtllib_crypt_wep.c
+++ b/drivers/staging/rtl8192e/rtllib_crypt_wep.c
@@ -9,7 +9,6 @@
  * more details.
  */
 
-#include <linux/version.h>
 #include <linux/module.h>
 #include <linux/init.h>
 #include <linux/slab.h>
@@ -38,10 +37,9 @@
 {
 	struct prism2_wep_data *priv;
 
-	priv = kmalloc(sizeof(*priv), GFP_ATOMIC);
+	priv = kzalloc(sizeof(*priv), GFP_ATOMIC);
 	if (priv == NULL)
 		goto fail;
-	memset(priv, 0, sizeof(*priv));
 	priv->key_idx = keyidx;
 
 	priv->tx_tfm = crypto_alloc_blkcipher("ecb(arc4)", 0, CRYPTO_ALG_ASYNC);
@@ -257,9 +255,8 @@
 	return p;
 }
 
-
-static struct rtllib_crypto_ops rtllib_crypt_wep = {
-	.name			= "WEP",
+static struct lib80211_crypto_ops rtllib_crypt_wep = {
+	.name			= "R-WEP",
 	.init			= prism2_wep_init,
 	.deinit			= prism2_wep_deinit,
 	.encrypt_mpdu		= prism2_wep_encrypt,
@@ -269,24 +266,24 @@
 	.set_key		= prism2_wep_set_key,
 	.get_key		= prism2_wep_get_key,
 	.print_stats		= prism2_wep_print_stats,
-	.extra_prefix_len	= 4, /* IV */
-	.extra_postfix_len	= 4, /* ICV */
+	.extra_mpdu_prefix_len  = 4,	/* IV */
+	.extra_mpdu_postfix_len = 4,	/* ICV */
 	.owner			= THIS_MODULE,
 };
 
 
 int __init rtllib_crypto_wep_init(void)
 {
-	return rtllib_register_crypto_ops(&rtllib_crypt_wep);
+	return lib80211_register_crypto_ops(&rtllib_crypt_wep);
 }
 
 
 void __exit rtllib_crypto_wep_exit(void)
 {
-	rtllib_unregister_crypto_ops(&rtllib_crypt_wep);
+	lib80211_unregister_crypto_ops(&rtllib_crypt_wep);
 }
 
-void rtllib_wep_null(void)
-{
-	return;
-}
+module_init(rtllib_crypto_wep_init);
+module_exit(rtllib_crypto_wep_exit);
+
+MODULE_LICENSE("GPL");
diff --git a/drivers/staging/rtl8192e/rtllib_debug.h b/drivers/staging/rtl8192e/rtllib_debug.h
new file mode 100644
index 0000000..2bfc115
--- /dev/null
+++ b/drivers/staging/rtl8192e/rtllib_debug.h
@@ -0,0 +1,86 @@
+/******************************************************************************
+ * Copyright(c) 2008 - 2010 Realtek Corporation. All rights reserved.
+ *
+ * Based on the r8180 driver, which is:
+ * Copyright 2004-2005 Andrea Merello <andreamrl@tiscali.it>, et al.
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
+ *
+ * The full GNU General Public License is included in this distribution in the
+ * file called LICENSE.
+ *
+ * Contact Information:
+ * wlanfae <wlanfae@realtek.com>
+******************************************************************************/
+#ifndef _RTL_DEBUG_H
+#define _RTL_DEBUG_H
+
+/* Allow files to override DRV_NAME */
+#ifndef DRV_NAME
+#define DRV_NAME "rtllib_92e"
+#endif
+
+#define DMESG(x, a...)
+
+extern u32 rt_global_debug_component;
+
+/* These are the defines for rt_global_debug_component */
+enum RTL_DEBUG {
+	COMP_TRACE		= (1 << 0),
+	COMP_DBG		= (1 << 1),
+	COMP_INIT		= (1 << 2),
+	COMP_RECV		= (1 << 3),
+	COMP_SEND		= (1 << 4),
+	COMP_CMD		= (1 << 5),
+	COMP_POWER		= (1 << 6),
+	COMP_EPROM		= (1 << 7),
+	COMP_SWBW		= (1 << 8),
+	COMP_SEC		= (1 << 9),
+	COMP_LPS		= (1 << 10),
+	COMP_QOS		= (1 << 11),
+	COMP_RATE		= (1 << 12),
+	COMP_RXDESC		= (1 << 13),
+	COMP_PHY		= (1 << 14),
+	COMP_DIG		= (1 << 15),
+	COMP_TXAGC		= (1 << 16),
+	COMP_HALDM		= (1 << 17),
+	COMP_POWER_TRACKING	= (1 << 18),
+	COMP_CH			= (1 << 19),
+	COMP_RF			= (1 << 20),
+	COMP_FIRMWARE		= (1 << 21),
+	COMP_HT			= (1 << 22),
+	COMP_RESET		= (1 << 23),
+	COMP_CMDPKT		= (1 << 24),
+	COMP_SCAN		= (1 << 25),
+	COMP_PS			= (1 << 26),
+	COMP_DOWN		= (1 << 27),
+	COMP_INTR		= (1 << 28),
+	COMP_LED		= (1 << 29),
+	COMP_MLME		= (1 << 30),
+	COMP_ERR		= (1 << 31)
+};
+
+#define RT_TRACE(component, x, args...)		\
+do {			\
+	if (rt_global_debug_component & component) \
+		printk(KERN_DEBUG DRV_NAME ":" x "\n" , \
+		       ##args);\
+} while (0);
+
+#define assert(expr) \
+	if (!(expr)) {				  \
+		printk(KERN_INFO "Assertion failed! %s,%s,%s,line=%d\n", \
+		#expr, __FILE__, __func__, __LINE__);	  \
+	}
+
+#endif
diff --git a/drivers/staging/rtl8192e/rtllib_module.c b/drivers/staging/rtl8192e/rtllib_module.c
index c36a140..f9dae95 100644
--- a/drivers/staging/rtl8192e/rtllib_module.c
+++ b/drivers/staging/rtl8192e/rtllib_module.c
@@ -45,7 +45,6 @@
 #include <linux/slab.h>
 #include <linux/tcp.h>
 #include <linux/types.h>
-#include <linux/version.h>
 #include <linux/wireless.h>
 #include <linux/etherdevice.h>
 #include <linux/uaccess.h>
@@ -54,7 +53,9 @@
 #include "rtllib.h"
 
 
-#define DRV_NAME "rtllib_92e"
+u32 rt_global_debug_component = COMP_ERR;
+EXPORT_SYMBOL(rt_global_debug_component);
+
 
 void _setup_timer(struct timer_list *ptimer, void *fun, unsigned long data)
 {
@@ -135,10 +136,6 @@
 	ieee->host_decrypt = 1;
 	ieee->ieee802_1x = 1; /* Default to supporting 802.1x */
 
-	INIT_LIST_HEAD(&ieee->crypt_deinit_list);
-	_setup_timer(&ieee->crypt_deinit_timer,
-		    rtllib_crypt_deinit_handler,
-		    (unsigned long) ieee);
 	ieee->rtllib_ap_sec_type = rtllib_ap_sec_type;
 
 	spin_lock_init(&ieee->lock);
@@ -148,6 +145,9 @@
 	atomic_set(&(ieee->atm_chnlop), 0);
 	atomic_set(&(ieee->atm_swbw), 0);
 
+	/* SAM FIXME */
+	lib80211_crypt_info_init(&ieee->crypt_info, "RTLLIB", &ieee->lock);
+
 	ieee->bHalfNMode = false;
 	ieee->wpa_enabled = 0;
 	ieee->tkip_countermeasures = 0;
@@ -177,10 +177,6 @@
 		ieee->last_packet_time[i] = 0;
 	}
 
-	rtllib_tkip_null();
-	rtllib_wep_null();
-	rtllib_ccmp_null();
-
 	return dev;
 
  failed:
@@ -188,32 +184,23 @@
 		free_netdev(dev);
 	return NULL;
 }
+EXPORT_SYMBOL(alloc_rtllib);
 
 void free_rtllib(struct net_device *dev)
 {
 	struct rtllib_device *ieee = (struct rtllib_device *)
 				      netdev_priv_rsl(dev);
-	int i;
 
 	kfree(ieee->pHTInfo);
 	ieee->pHTInfo = NULL;
 	rtllib_softmac_free(ieee);
-	del_timer_sync(&ieee->crypt_deinit_timer);
-	rtllib_crypt_deinit_entries(ieee, 1);
 
-	for (i = 0; i < WEP_KEYS; i++) {
-		struct rtllib_crypt_data *crypt = ieee->crypt[i];
-		if (crypt) {
-			if (crypt->ops)
-				crypt->ops->deinit(crypt->priv);
-			kfree(crypt);
-			ieee->crypt[i] = NULL;
-		}
-	}
+	lib80211_crypt_info_free(&ieee->crypt_info);
 
 	rtllib_networks_free(ieee);
 	free_netdev(dev);
 }
+EXPORT_SYMBOL(free_rtllib);
 
 u32 rtllib_debug_level;
 static int debug = \
@@ -287,3 +274,8 @@
 		rtllib_proc = NULL;
 	}
 }
+
+module_init(rtllib_init);
+module_exit(rtllib_exit);
+
+MODULE_LICENSE("GPL");
diff --git a/drivers/staging/rtl8192e/rtllib_rx.c b/drivers/staging/rtl8192e/rtllib_rx.c
index 8d0af5e..6c5061f 100644
--- a/drivers/staging/rtl8192e/rtllib_rx.c
+++ b/drivers/staging/rtl8192e/rtllib_rx.c
@@ -36,7 +36,6 @@
 #include <linux/slab.h>
 #include <linux/tcp.h>
 #include <linux/types.h>
-#include <linux/version.h>
 #include <linux/wireless.h>
 #include <linux/etherdevice.h>
 #include <linux/uaccess.h>
@@ -281,7 +280,7 @@
 /* Called only as a tasklet (software IRQ), by rtllib_rx */
 static inline int
 rtllib_rx_frame_decrypt(struct rtllib_device *ieee, struct sk_buff *skb,
-			struct rtllib_crypt_data *crypt)
+			struct lib80211_crypt_data *crypt)
 {
 	struct rtllib_hdr_4addr *hdr;
 	int res, hdrlen;
@@ -322,7 +321,7 @@
 /* Called only as a tasklet (software IRQ), by rtllib_rx */
 static inline int
 rtllib_rx_frame_decrypt_msdu(struct rtllib_device *ieee, struct sk_buff *skb,
-			     int keyidx, struct rtllib_crypt_data *crypt)
+			     int keyidx, struct lib80211_crypt_data *crypt)
 {
 	struct rtllib_hdr_4addr *hdr;
 	int res, hdrlen;
@@ -341,7 +340,7 @@
 	hdrlen = rtllib_get_hdrlen(le16_to_cpu(hdr->frame_ctl));
 
 	atomic_inc(&crypt->refcnt);
-	res = crypt->ops->decrypt_msdu(skb, keyidx, hdrlen, crypt->priv, ieee);
+	res = crypt->ops->decrypt_msdu(skb, keyidx, hdrlen, crypt->priv);
 	atomic_dec(&crypt->refcnt);
 	if (res < 0) {
 		printk(KERN_DEBUG "%s: MSDU decryption/MIC verification failed"
@@ -1010,7 +1009,7 @@
 }
 
 static int rtllib_rx_get_crypt(struct rtllib_device *ieee, struct sk_buff *skb,
-			struct rtllib_crypt_data **crypt, size_t hdrlen)
+			struct lib80211_crypt_data **crypt, size_t hdrlen)
 {
 	struct rtllib_hdr_4addr *hdr = (struct rtllib_hdr_4addr *)skb->data;
 	u16 fc = le16_to_cpu(hdr->frame_ctl);
@@ -1020,7 +1019,7 @@
 		if (skb->len >= hdrlen + 3)
 			idx = skb->data[hdrlen + 3] >> 6;
 
-		*crypt = ieee->crypt[idx];
+		*crypt = ieee->crypt_info.crypt[idx];
 		/* allow NULL decrypt to indicate an station specific override
 		 * for default encryption */
 		if (*crypt && ((*crypt)->ops == NULL ||
@@ -1045,7 +1044,7 @@
 
 static int rtllib_rx_decrypt(struct rtllib_device *ieee, struct sk_buff *skb,
 		      struct rtllib_rx_stats *rx_stats,
-		      struct rtllib_crypt_data *crypt, size_t hdrlen)
+		      struct lib80211_crypt_data *crypt, size_t hdrlen)
 {
 	struct rtllib_hdr_4addr *hdr;
 	int keyidx = 0;
@@ -1253,7 +1252,7 @@
 {
 	struct net_device *dev = ieee->dev;
 	struct rtllib_hdr_4addr *hdr = (struct rtllib_hdr_4addr *)skb->data;
-	struct rtllib_crypt_data *crypt = NULL;
+	struct lib80211_crypt_data *crypt = NULL;
 	struct rtllib_rxb *rxb = NULL;
 	struct rx_ts_record *pTS = NULL;
 	u16 fc, sc, SeqNum = 0;
@@ -1497,6 +1496,7 @@
 	ieee->stats.rx_dropped++;
 	return 0;
 }
+EXPORT_SYMBOL(rtllib_rx);
 
 static u8 qos_oui[QOS_OUI_LEN] = { 0x00, 0x50, 0xF2 };
 
@@ -2492,7 +2492,7 @@
 	return 0;
 }
 
-int IsLegalChannel(struct rtllib_device *rtllib, u8 channel)
+int rtllib_legal_channel(struct rtllib_device *rtllib, u8 channel)
 {
 	if (MAX_CHANNEL_NUMBER < channel) {
 		printk(KERN_INFO "%s(): Invalid Channel\n", __func__);
@@ -2503,6 +2503,7 @@
 
 	return 0;
 }
+EXPORT_SYMBOL(rtllib_legal_channel);
 
 static inline void rtllib_process_probe_response(
 	struct rtllib_device *ieee,
@@ -2553,7 +2554,7 @@
 	}
 
 
-	if (!IsLegalChannel(ieee, network->channel))
+	if (!rtllib_legal_channel(ieee, network->channel))
 		goto free_network;
 
 	if (WLAN_FC_GET_STYPE(beacon->header.frame_ctl) ==
diff --git a/drivers/staging/rtl8192e/rtllib_softmac.c b/drivers/staging/rtl8192e/rtllib_softmac.c
index b508685..1637f11 100644
--- a/drivers/staging/rtl8192e/rtllib_softmac.c
+++ b/drivers/staging/rtl8192e/rtllib_softmac.c
@@ -15,11 +15,9 @@
 
 
 #include "rtllib.h"
-#include "rtl_core.h"
 
 #include <linux/random.h>
 #include <linux/delay.h>
-#include <linux/version.h>
 #include <linux/uaccess.h>
 #include "dot11d.h"
 
@@ -28,9 +26,9 @@
 	return (net->rates_ex_len > 0) || (net->rates_len > 4);
 }
 
-short rtllib_is_shortslot(struct rtllib_network net)
+short rtllib_is_shortslot(const struct rtllib_network *net)
 {
-	return net.capability & WLAN_CAPABILITY_SHORT_SLOT_TIME;
+	return net->capability & WLAN_CAPABILITY_SHORT_SLOT_TIME;
 }
 
 /* returns the total length needed for pleacing the RATE MFIE
@@ -468,6 +466,7 @@
 
 	ieee->bNetPromiscuousMode = true;
 }
+EXPORT_SYMBOL(rtllib_EnableIntelPromiscuousMode);
 
 
 /*
@@ -490,6 +489,7 @@
 
 	ieee->bNetPromiscuousMode = false;
 }
+EXPORT_SYMBOL(rtllib_DisableIntelPromiscuousMode);
 
 static void rtllib_send_probe(struct rtllib_device *ieee, u8 is_mesh)
 {
@@ -685,6 +685,7 @@
 	if (ieee->softmac_features & IEEE_SOFTMAC_BEACONS)
 		rtllib_beacons_stop(ieee);
 }
+EXPORT_SYMBOL(rtllib_stop_send_beacons);
 
 
 void rtllib_start_send_beacons(struct rtllib_device *ieee)
@@ -694,6 +695,7 @@
 	if (ieee->softmac_features & IEEE_SOFTMAC_BEACONS)
 		rtllib_beacons_start(ieee);
 }
+EXPORT_SYMBOL(rtllib_start_send_beacons);
 
 
 static void rtllib_softmac_stop_scan(struct rtllib_device *ieee)
@@ -719,6 +721,7 @@
 			ieee->rtllib_stop_hw_scan(ieee->dev);
 	}
 }
+EXPORT_SYMBOL(rtllib_stop_scan);
 
 void rtllib_stop_scan_syncro(struct rtllib_device *ieee)
 {
@@ -729,6 +732,7 @@
 			ieee->rtllib_stop_hw_scan(ieee->dev);
 	}
 }
+EXPORT_SYMBOL(rtllib_stop_scan_syncro);
 
 bool rtllib_act_scanning(struct rtllib_device *ieee, bool sync_scan)
 {
@@ -741,6 +745,7 @@
 		return test_bit(STATUS_SCANNING, &ieee->status);
 	}
 }
+EXPORT_SYMBOL(rtllib_act_scanning);
 
 /* called with ieee->lock held */
 static void rtllib_start_scan(struct rtllib_device *ieee)
@@ -781,6 +786,7 @@
 			ieee->rtllib_start_hw_scan(ieee->dev);
 	}
 }
+EXPORT_SYMBOL(rtllib_start_scan_syncro);
 
 inline struct sk_buff *rtllib_authentication_req(struct rtllib_network *beacon,
 	struct rtllib_device *ieee, int challengelen, u8 *daddr)
@@ -830,7 +836,7 @@
 	struct sk_buff *skb = NULL;
 	int encrypt;
 	int atim_len, erp_len;
-	struct rtllib_crypt_data *crypt;
+	struct lib80211_crypt_data *crypt;
 
 	char *ssid = ieee->current_network.ssid;
 	int ssid_len = ieee->current_network.ssid_len;
@@ -865,9 +871,9 @@
 	} else
 		erp_len = 0;
 
-	crypt = ieee->crypt[ieee->tx_keyidx];
+	crypt = ieee->crypt_info.crypt[ieee->crypt_info.tx_keyidx];
 	encrypt = ieee->host_encrypt && crypt && crypt->ops &&
-		((0 == strcmp(crypt->ops->name, "WEP") || wpa_ie_len));
+		((0 == strcmp(crypt->ops->name, "R-WEP") || wpa_ie_len));
 	if (ieee->pHTInfo->bCurrentHTSupport) {
 		tmp_ht_cap_buf = (u8 *) &(ieee->pHTInfo->SelfHTCap);
 		tmp_ht_cap_len = sizeof(ieee->pHTInfo->SelfHTCap);
@@ -917,7 +923,7 @@
 		cpu_to_le16((beacon_buf->capability |=
 				 WLAN_CAPABILITY_SHORT_SLOT_TIME));
 
-	crypt = ieee->crypt[ieee->tx_keyidx];
+	crypt = ieee->crypt_info.crypt[ieee->crypt_info.tx_keyidx];
 	if (encrypt)
 		beacon_buf->capability |= cpu_to_le16(WLAN_CAPABILITY_PRIVACY);
 
@@ -976,7 +982,7 @@
 	struct sk_buff *skb;
 	u8 *tag;
 
-	struct rtllib_crypt_data *crypt;
+	struct lib80211_crypt_data *crypt;
 	struct rtllib_assoc_response_frame *assoc;
 	short encrypt;
 
@@ -1007,7 +1013,7 @@
 				 cpu_to_le16(WLAN_CAPABILITY_SHORT_SLOT_TIME);
 
 	if (ieee->host_encrypt)
-		crypt = ieee->crypt[ieee->tx_keyidx];
+		crypt = ieee->crypt_info.crypt[ieee->crypt_info.tx_keyidx];
 	else
 		crypt = NULL;
 
@@ -1172,7 +1178,7 @@
 	unsigned int ckip_ie_len = 0;
 	unsigned int ccxrm_ie_len = 0;
 	unsigned int cxvernum_ie_len = 0;
-	struct rtllib_crypt_data *crypt;
+	struct lib80211_crypt_data *crypt;
 	int encrypt;
 	int	PMKCacheIdx;
 
@@ -1185,10 +1191,10 @@
 	unsigned int turbo_info_len = beacon->Turbo_Enable ? 9 : 0;
 
 	int len = 0;
-	crypt = ieee->crypt[ieee->tx_keyidx];
+	crypt = ieee->crypt_info.crypt[ieee->crypt_info.tx_keyidx];
 	if (crypt != NULL)
 		encrypt = ieee->host_encrypt && crypt && crypt->ops &&
-			  ((0 == strcmp(crypt->ops->name, "WEP") ||
+			  ((0 == strcmp(crypt->ops->name, "R-WEP") ||
 			  wpa_ie_len));
 	else
 		encrypt = 0;
@@ -1956,6 +1962,7 @@
 	if (buf)
 		softmac_ps_mgmt_xmit(buf, ieee);
 }
+EXPORT_SYMBOL(rtllib_sta_ps_send_null_frame);
 
 void rtllib_sta_ps_send_pspoll_frame(struct rtllib_device *ieee)
 {
@@ -2168,6 +2175,7 @@
 	}
 	spin_unlock_irqrestore(&ieee->lock, flags);
 }
+EXPORT_SYMBOL(rtllib_ps_tx_ack);
 
 static void rtllib_process_action(struct rtllib_device *ieee, struct sk_buff *skb)
 {
@@ -2540,6 +2548,7 @@
 	spin_unlock_irqrestore(&ieee->lock, flags);
 
 }
+EXPORT_SYMBOL(rtllib_reset_queue);
 
 void rtllib_wake_queue(struct rtllib_device *ieee)
 {
@@ -2928,6 +2937,7 @@
 
 	return skb;
 }
+EXPORT_SYMBOL(rtllib_get_beacon);
 
 void rtllib_softmac_stop_protocol(struct rtllib_device *ieee, u8 mesh_flag,
 				  u8 shutdown)
@@ -2937,6 +2947,7 @@
 	rtllib_stop_protocol(ieee, shutdown);
 	up(&ieee->wx_sem);
 }
+EXPORT_SYMBOL(rtllib_softmac_stop_protocol);
 
 
 void rtllib_stop_protocol(struct rtllib_device *ieee, u8 shutdown)
@@ -2985,6 +2996,7 @@
 	rtllib_start_protocol(ieee);
 	up(&ieee->wx_sem);
 }
+EXPORT_SYMBOL(rtllib_softmac_start_protocol);
 
 void rtllib_start_protocol(struct rtllib_device *ieee)
 {
@@ -3048,10 +3060,9 @@
 	ieee->state = RTLLIB_NOLINK;
 	for (i = 0; i < 5; i++)
 		ieee->seq_ctrl[i] = 0;
-	ieee->pDot11dInfo = kmalloc(sizeof(struct rt_dot11d_info), GFP_ATOMIC);
+	ieee->pDot11dInfo = kzalloc(sizeof(struct rt_dot11d_info), GFP_ATOMIC);
 	if (!ieee->pDot11dInfo)
 		RTLLIB_DEBUG(RTLLIB_DL_ERR, "can't alloc memory for DOT11D\n");
-	memset(ieee->pDot11dInfo, 0, sizeof(struct rt_dot11d_info));
 	ieee->LinkDetectInfo.SlotIndex = 0;
 	ieee->LinkDetectInfo.SlotNum = 2;
 	ieee->LinkDetectInfo.NumRecvBcnInPeriod = 0;
@@ -3207,11 +3218,11 @@
 		return -EINVAL;
 
 	if (param->u.wpa_ie.len) {
-		buf = kmalloc(param->u.wpa_ie.len, GFP_KERNEL);
+		buf = kmemdup(param->u.wpa_ie.data, param->u.wpa_ie.len,
+			      GFP_KERNEL);
 		if (buf == NULL)
 			return -ENOMEM;
 
-		memcpy(buf, param->u.wpa_ie.data, param->u.wpa_ie.len);
 		kfree(ieee->wpa_ie);
 		ieee->wpa_ie = buf;
 		ieee->wpa_ie_len = param->u.wpa_ie.len;
@@ -3334,8 +3345,8 @@
 				  u8 is_mesh)
 {
 	int ret = 0;
-	struct rtllib_crypto_ops *ops;
-	struct rtllib_crypt_data **crypt;
+	struct lib80211_crypto_ops *ops;
+	struct lib80211_crypt_data **crypt;
 
 	struct rtllib_security sec = {
 		.flags = 0,
@@ -3354,9 +3365,9 @@
 	if (param->sta_addr[0] == 0xff && param->sta_addr[1] == 0xff &&
 	    param->sta_addr[2] == 0xff && param->sta_addr[3] == 0xff &&
 	    param->sta_addr[4] == 0xff && param->sta_addr[5] == 0xff) {
-		if (param->u.crypt.idx >= WEP_KEYS)
+		if (param->u.crypt.idx >= NUM_WEP_KEYS)
 			return -EINVAL;
-		crypt = &ieee->crypt[param->u.crypt.idx];
+		crypt = &ieee->crypt_info.crypt[param->u.crypt.idx];
 	} else {
 		return -EINVAL;
 	}
@@ -3366,7 +3377,7 @@
 			sec.enabled = 0;
 			sec.level = SEC_LEVEL_0;
 			sec.flags |= SEC_ENABLED | SEC_LEVEL;
-			rtllib_crypt_delayed_deinit(ieee, crypt);
+			lib80211_crypt_delayed_deinit(&ieee->crypt_info, crypt);
 		}
 		goto done;
 	}
@@ -3375,19 +3386,19 @@
 
 	/* IPW HW cannot build TKIP MIC, host decryption still needed. */
 	if (!(ieee->host_encrypt || ieee->host_decrypt) &&
-	    strcmp(param->u.crypt.alg, "TKIP"))
+	    strcmp(param->u.crypt.alg, "R-TKIP"))
 		goto skip_host_crypt;
 
-	ops = rtllib_get_crypto_ops(param->u.crypt.alg);
-	if (ops == NULL && strcmp(param->u.crypt.alg, "WEP") == 0) {
+	ops = lib80211_get_crypto_ops(param->u.crypt.alg);
+	if (ops == NULL && strcmp(param->u.crypt.alg, "R-WEP") == 0) {
 		request_module("rtllib_crypt_wep");
-		ops = rtllib_get_crypto_ops(param->u.crypt.alg);
-	} else if (ops == NULL && strcmp(param->u.crypt.alg, "TKIP") == 0) {
+		ops = lib80211_get_crypto_ops(param->u.crypt.alg);
+	} else if (ops == NULL && strcmp(param->u.crypt.alg, "R-TKIP") == 0) {
 		request_module("rtllib_crypt_tkip");
-		ops = rtllib_get_crypto_ops(param->u.crypt.alg);
-	} else if (ops == NULL && strcmp(param->u.crypt.alg, "CCMP") == 0) {
+		ops = lib80211_get_crypto_ops(param->u.crypt.alg);
+	} else if (ops == NULL && strcmp(param->u.crypt.alg, "R-CCMP") == 0) {
 		request_module("rtllib_crypt_ccmp");
-		ops = rtllib_get_crypto_ops(param->u.crypt.alg);
+		ops = lib80211_get_crypto_ops(param->u.crypt.alg);
 	}
 	if (ops == NULL) {
 		printk(KERN_INFO "unknown crypto alg '%s'\n",
@@ -3397,17 +3408,17 @@
 		goto done;
 	}
 	if (*crypt == NULL || (*crypt)->ops != ops) {
-		struct rtllib_crypt_data *new_crypt;
+		struct lib80211_crypt_data *new_crypt;
 
-		rtllib_crypt_delayed_deinit(ieee, crypt);
+		lib80211_crypt_delayed_deinit(&ieee->crypt_info, crypt);
 
-		new_crypt = (struct rtllib_crypt_data *)
+		new_crypt = (struct lib80211_crypt_data *)
 			kmalloc(sizeof(*new_crypt), GFP_KERNEL);
 		if (new_crypt == NULL) {
 			ret = -ENOMEM;
 			goto done;
 		}
-		memset(new_crypt, 0, sizeof(struct rtllib_crypt_data));
+		memset(new_crypt, 0, sizeof(struct lib80211_crypt_data));
 		new_crypt->ops = ops;
 		if (new_crypt->ops)
 			new_crypt->priv =
@@ -3435,7 +3446,7 @@
 
  skip_host_crypt:
 	if (param->u.crypt.set_tx) {
-		ieee->tx_keyidx = param->u.crypt.idx;
+		ieee->crypt_info.tx_keyidx = param->u.crypt.idx;
 		sec.active_key = param->u.crypt.idx;
 		sec.flags |= SEC_ACTIVE_KEY;
 	} else
@@ -3448,13 +3459,13 @@
 		sec.key_sizes[param->u.crypt.idx] = param->u.crypt.key_len;
 		sec.flags |= (1 << param->u.crypt.idx);
 
-		if (strcmp(param->u.crypt.alg, "WEP") == 0) {
+		if (strcmp(param->u.crypt.alg, "R-WEP") == 0) {
 			sec.flags |= SEC_LEVEL;
 			sec.level = SEC_LEVEL_1;
-		} else if (strcmp(param->u.crypt.alg, "TKIP") == 0) {
+		} else if (strcmp(param->u.crypt.alg, "R-TKIP") == 0) {
 			sec.flags |= SEC_LEVEL;
 			sec.level = SEC_LEVEL_2;
-		} else if (strcmp(param->u.crypt.alg, "CCMP") == 0) {
+		} else if (strcmp(param->u.crypt.alg, "R-CCMP") == 0) {
 			sec.flags |= SEC_LEVEL;
 			sec.level = SEC_LEVEL_3;
 		}
@@ -3551,13 +3562,13 @@
 	static u8 ccmp_ie[4] = {0x00, 0x50, 0xf2, 0x04};
 	static u8 ccmp_rsn_ie[4] = {0x00, 0x0f, 0xac, 0x04};
 	int wpa_ie_len = ieee->wpa_ie_len;
-	struct rtllib_crypt_data *crypt;
+	struct lib80211_crypt_data *crypt;
 	int encrypt;
 
-	crypt = ieee->crypt[ieee->tx_keyidx];
+	crypt = ieee->crypt_info.crypt[ieee->crypt_info.tx_keyidx];
 	encrypt = (ieee->current_network.capability & WLAN_CAPABILITY_PRIVACY)
 		  || (ieee->host_encrypt && crypt && crypt->ops &&
-		  (0 == strcmp(crypt->ops->name, "WEP")));
+		  (0 == strcmp(crypt->ops->name, "R-WEP")));
 
 	/* simply judge  */
 	if (encrypt && (wpa_ie_len == 0)) {
@@ -3634,6 +3645,7 @@
 
 	return ret;
 }
+EXPORT_SYMBOL(rtllib_wpa_supplicant_ioctl);
 
 void rtllib_MgntDisconnectIBSS(struct rtllib_device *rtllib)
 {
@@ -3719,6 +3731,7 @@
 
 	return true;
 }
+EXPORT_SYMBOL(rtllib_MgntDisconnect);
 
 void notify_wx_assoc_event(struct rtllib_device *ieee)
 {
@@ -3739,3 +3752,4 @@
 	}
 	wireless_send_event(ieee->dev, SIOCGIWAP, &wrqu, NULL);
 }
+EXPORT_SYMBOL(notify_wx_assoc_event);
diff --git a/drivers/staging/rtl8192e/rtllib_softmac_wx.c b/drivers/staging/rtl8192e/rtllib_softmac_wx.c
index 22988fb..1523bc7 100644
--- a/drivers/staging/rtl8192e/rtllib_softmac_wx.c
+++ b/drivers/staging/rtl8192e/rtllib_softmac_wx.c
@@ -15,7 +15,6 @@
 
 
 #include "rtllib.h"
-#include "rtl_core.h"
 #include "dot11d.h"
 /* FIXME: add A freqs */
 
@@ -25,6 +24,7 @@
 	2452, 2457, 2462, 2467,
 	2472, 2484
 };
+EXPORT_SYMBOL(rtllib_wlan_frequencies);
 
 
 int rtllib_wx_set_freq(struct rtllib_device *ieee, struct iw_request_info *a,
@@ -82,6 +82,7 @@
 	up(&ieee->wx_sem);
 	return ret;
 }
+EXPORT_SYMBOL(rtllib_wx_set_freq);
 
 
 int rtllib_wx_get_freq(struct rtllib_device *ieee,
@@ -97,6 +98,7 @@
 	fwrq->e = 1;
 	return 0;
 }
+EXPORT_SYMBOL(rtllib_wx_get_freq);
 
 int rtllib_wx_get_wap(struct rtllib_device *ieee,
 			    struct iw_request_info *info,
@@ -125,6 +127,7 @@
 
 	return 0;
 }
+EXPORT_SYMBOL(rtllib_wx_get_wap);
 
 
 int rtllib_wx_set_wap(struct rtllib_device *ieee,
@@ -184,6 +187,7 @@
 	up(&ieee->wx_sem);
 	return ret;
 }
+EXPORT_SYMBOL(rtllib_wx_set_wap);
 
 int rtllib_wx_get_essid(struct rtllib_device *ieee, struct iw_request_info *a,
 			 union iwreq_data *wrqu, char *b)
@@ -220,6 +224,7 @@
 	return ret;
 
 }
+EXPORT_SYMBOL(rtllib_wx_get_essid);
 
 int rtllib_wx_set_rate(struct rtllib_device *ieee,
 			     struct iw_request_info *info,
@@ -231,6 +236,7 @@
 	ieee->rate = target_rate/100000;
 	return 0;
 }
+EXPORT_SYMBOL(rtllib_wx_set_rate);
 
 int rtllib_wx_get_rate(struct rtllib_device *ieee,
 			     struct iw_request_info *info,
@@ -243,6 +249,7 @@
 
 	return 0;
 }
+EXPORT_SYMBOL(rtllib_wx_get_rate);
 
 
 int rtllib_wx_set_rts(struct rtllib_device *ieee,
@@ -259,6 +266,7 @@
 	}
 	return 0;
 }
+EXPORT_SYMBOL(rtllib_wx_set_rts);
 
 int rtllib_wx_get_rts(struct rtllib_device *ieee,
 			     struct iw_request_info *info,
@@ -269,6 +277,7 @@
 	wrqu->rts.disabled = (wrqu->rts.value == DEFAULT_RTS_THRESHOLD);
 	return 0;
 }
+EXPORT_SYMBOL(rtllib_wx_get_rts);
 
 int rtllib_wx_set_mode(struct rtllib_device *ieee, struct iw_request_info *a,
 			     union iwreq_data *wrqu, char *b)
@@ -314,6 +323,7 @@
 	up(&ieee->wx_sem);
 	return set_mode_status;
 }
+EXPORT_SYMBOL(rtllib_wx_set_mode);
 
 void rtllib_wx_sync_scan_wq(void *data)
 {
@@ -428,6 +438,7 @@
 	up(&ieee->wx_sem);
 	return ret;
 }
+EXPORT_SYMBOL(rtllib_wx_set_scan);
 
 int rtllib_wx_set_essid(struct rtllib_device *ieee,
 			struct iw_request_info *a,
@@ -490,6 +501,7 @@
 	up(&ieee->wx_sem);
 	return ret;
 }
+EXPORT_SYMBOL(rtllib_wx_set_essid);
 
 int rtllib_wx_get_mode(struct rtllib_device *ieee, struct iw_request_info *a,
 		       union iwreq_data *wrqu, char *b)
@@ -497,6 +509,7 @@
 	wrqu->mode = ieee->iw_mode;
 	return 0;
 }
+EXPORT_SYMBOL(rtllib_wx_get_mode);
 
 int rtllib_wx_set_rawtx(struct rtllib_device *ieee,
 			struct iw_request_info *info,
@@ -533,6 +546,7 @@
 
 	return 0;
 }
+EXPORT_SYMBOL(rtllib_wx_set_rawtx);
 
 int rtllib_wx_get_name(struct rtllib_device *ieee,
 			     struct iw_request_info *info,
@@ -548,6 +562,7 @@
 		strcat(wrqu->name, "n");
 	return 0;
 }
+EXPORT_SYMBOL(rtllib_wx_get_name);
 
 
 /* this is mostly stolen from hostap */
@@ -605,6 +620,7 @@
 	return ret;
 
 }
+EXPORT_SYMBOL(rtllib_wx_set_power);
 
 /* this is stolen from hostap */
 int rtllib_wx_get_power(struct rtllib_device *ieee,
@@ -643,3 +659,4 @@
 	return ret;
 
 }
+EXPORT_SYMBOL(rtllib_wx_get_power);
diff --git a/drivers/staging/rtl8192e/rtllib_tx.c b/drivers/staging/rtl8192e/rtllib_tx.c
index 44e8006..f451bfc 100644
--- a/drivers/staging/rtl8192e/rtllib_tx.c
+++ b/drivers/staging/rtl8192e/rtllib_tx.c
@@ -46,7 +46,6 @@
 #include <linux/slab.h>
 #include <linux/tcp.h>
 #include <linux/types.h>
-#include <linux/version.h>
 #include <linux/wireless.h>
 #include <linux/etherdevice.h>
 #include <linux/uaccess.h>
@@ -180,10 +179,10 @@
 int rtllib_encrypt_fragment(struct rtllib_device *ieee, struct sk_buff *frag,
 			    int hdr_len)
 {
-	struct rtllib_crypt_data *crypt = NULL;
+	struct lib80211_crypt_data *crypt = NULL;
 	int res;
 
-	crypt = ieee->crypt[ieee->tx_keyidx];
+	crypt = ieee->crypt_info.crypt[ieee->crypt_info.tx_keyidx];
 
 	if (!(crypt && crypt->ops)) {
 		printk(KERN_INFO "=========>%s(), crypt is null\n", __func__);
@@ -569,7 +568,7 @@
 	};
 	u8 dest[ETH_ALEN], src[ETH_ALEN];
 	int qos_actived = ieee->current_network.qos_data.active;
-	struct rtllib_crypt_data *crypt = NULL;
+	struct lib80211_crypt_data *crypt = NULL;
 	struct cb_desc *tcb_desc;
 	u8 bIsMulticast = false;
 	u8 IsAmsdu = false;
@@ -646,7 +645,7 @@
 		}
 
 		skb->priority = rtllib_classify(skb, IsAmsdu);
-		crypt = ieee->crypt[ieee->tx_keyidx];
+		crypt = ieee->crypt_info.crypt[ieee->crypt_info.tx_keyidx];
 		encrypt = !(ether_type == ETH_P_PAE && ieee->ieee802_1x) &&
 			ieee->host_encrypt && crypt && crypt->ops;
 		if (!encrypt && ieee->ieee802_1x &&
@@ -742,8 +741,10 @@
 		/* Each fragment may need to have room for encryptiong
 		 * pre/postfix */
 		if (encrypt) {
-			bytes_per_frag -= crypt->ops->extra_prefix_len +
-				crypt->ops->extra_postfix_len;
+			bytes_per_frag -= crypt->ops->extra_mpdu_prefix_len +
+				crypt->ops->extra_mpdu_postfix_len +
+				crypt->ops->extra_msdu_prefix_len +
+				crypt->ops->extra_msdu_postfix_len;
 		}
 		/* Number of fragments is the total bytes_per_frag /
 		* payload_per_fragment */
@@ -791,7 +792,8 @@
 				else
 					tcb_desc->bHwSec = 0;
 				skb_reserve(skb_frag,
-					    crypt->ops->extra_prefix_len);
+					    crypt->ops->extra_mpdu_prefix_len +
+					    crypt->ops->extra_msdu_prefix_len);
 			} else {
 				tcb_desc->bHwSec = 0;
 			}
@@ -965,3 +967,4 @@
 	memset(skb->cb, 0, sizeof(skb->cb));
 	return rtllib_xmit_inter(skb, dev);
 }
+EXPORT_SYMBOL(rtllib_xmit);
diff --git a/drivers/staging/rtl8192e/rtllib_wx.c b/drivers/staging/rtl8192e/rtllib_wx.c
index 8cea4a6..c27ff7e 100644
--- a/drivers/staging/rtl8192e/rtllib_wx.c
+++ b/drivers/staging/rtl8192e/rtllib_wx.c
@@ -30,7 +30,6 @@
 
 ******************************************************************************/
 #include <linux/wireless.h>
-#include <linux/version.h>
 #include <linux/kmod.h>
 #include <linux/module.h>
 
@@ -295,6 +294,7 @@
 
 	return err;
 }
+EXPORT_SYMBOL(rtllib_wx_get_scan);
 
 int rtllib_wx_set_encode(struct rtllib_device *ieee,
 			    struct iw_request_info *info,
@@ -306,44 +306,44 @@
 		.flags = 0
 	};
 	int i, key, key_provided, len;
-	struct rtllib_crypt_data **crypt;
+	struct lib80211_crypt_data **crypt;
 
 	RTLLIB_DEBUG_WX("SET_ENCODE\n");
 
 	key = erq->flags & IW_ENCODE_INDEX;
 	if (key) {
-		if (key > WEP_KEYS)
+		if (key > NUM_WEP_KEYS)
 			return -EINVAL;
 		key--;
 		key_provided = 1;
 	} else {
 		key_provided = 0;
-		key = ieee->tx_keyidx;
+		key = ieee->crypt_info.tx_keyidx;
 	}
 
 	RTLLIB_DEBUG_WX("Key: %d [%s]\n", key, key_provided ?
 			   "provided" : "default");
-	crypt = &ieee->crypt[key];
+	crypt = &ieee->crypt_info.crypt[key];
 	if (erq->flags & IW_ENCODE_DISABLED) {
 		if (key_provided && *crypt) {
 			RTLLIB_DEBUG_WX("Disabling encryption on key %d.\n",
 					   key);
-			rtllib_crypt_delayed_deinit(ieee, crypt);
+			lib80211_crypt_delayed_deinit(&ieee->crypt_info, crypt);
 		} else
 			RTLLIB_DEBUG_WX("Disabling encryption.\n");
 
 		/* Check all the keys to see if any are still configured,
 		 * and if no key index was provided, de-init them all */
-		for (i = 0; i < WEP_KEYS; i++) {
-			if (ieee->crypt[i] != NULL) {
+		for (i = 0; i < NUM_WEP_KEYS; i++) {
+			if (ieee->crypt_info.crypt[i] != NULL) {
 				if (key_provided)
 					break;
-				rtllib_crypt_delayed_deinit(ieee,
-							    &ieee->crypt[i]);
+				lib80211_crypt_delayed_deinit(&ieee->crypt_info,
+							    &ieee->crypt_info.crypt[i]);
 			}
 		}
 
-		if (i == WEP_KEYS) {
+		if (i == NUM_WEP_KEYS) {
 			sec.enabled = 0;
 			sec.level = SEC_LEVEL_0;
 			sec.flags |= SEC_ENABLED | SEC_LEVEL;
@@ -358,25 +358,24 @@
 	sec.flags |= SEC_ENABLED;
 
 	if (*crypt != NULL && (*crypt)->ops != NULL &&
-	    strcmp((*crypt)->ops->name, "WEP") != 0) {
+	    strcmp((*crypt)->ops->name, "R-WEP") != 0) {
 		/* changing to use WEP; deinit previously used algorithm
 		 * on this key */
-		rtllib_crypt_delayed_deinit(ieee, crypt);
+		lib80211_crypt_delayed_deinit(&ieee->crypt_info, crypt);
 	}
 
 	if (*crypt == NULL) {
-		struct rtllib_crypt_data *new_crypt;
+		struct lib80211_crypt_data *new_crypt;
 
 		/* take WEP into use */
-		new_crypt = kmalloc(sizeof(struct rtllib_crypt_data),
+		new_crypt = kzalloc(sizeof(struct lib80211_crypt_data),
 				    GFP_KERNEL);
 		if (new_crypt == NULL)
 			return -ENOMEM;
-		memset(new_crypt, 0, sizeof(struct rtllib_crypt_data));
-		new_crypt->ops = rtllib_get_crypto_ops("WEP");
+		new_crypt->ops = lib80211_get_crypto_ops("R-WEP");
 		if (!new_crypt->ops) {
 			request_module("rtllib_crypt_wep");
-			new_crypt->ops = rtllib_get_crypto_ops("WEP");
+			new_crypt->ops = lib80211_get_crypto_ops("R-WEP");
 		}
 
 		if (new_crypt->ops)
@@ -412,7 +411,7 @@
 		 * explicitely set */
 		if (key == sec.active_key)
 			sec.flags |= SEC_ACTIVE_KEY;
-		ieee->tx_keyidx = key;
+		ieee->crypt_info.tx_keyidx = key;
 
 	} else {
 		len = (*crypt)->ops->get_key(sec.keys[key], WEP_KEY_LEN,
@@ -435,7 +434,7 @@
 		if (key_provided) {
 			RTLLIB_DEBUG_WX(
 				"Setting key %d to default Tx key.\n", key);
-			ieee->tx_keyidx = key;
+			ieee->crypt_info.tx_keyidx = key;
 			sec.active_key = key;
 			sec.flags |= SEC_ACTIVE_KEY;
 		}
@@ -470,6 +469,7 @@
 	}
 	return 0;
 }
+EXPORT_SYMBOL(rtllib_wx_set_encode);
 
 int rtllib_wx_get_encode(struct rtllib_device *ieee,
 			    struct iw_request_info *info,
@@ -477,7 +477,7 @@
 {
 	struct iw_point *erq = &(wrqu->encoding);
 	int len, key;
-	struct rtllib_crypt_data *crypt;
+	struct lib80211_crypt_data *crypt;
 
 	RTLLIB_DEBUG_WX("GET_ENCODE\n");
 
@@ -486,13 +486,13 @@
 
 	key = erq->flags & IW_ENCODE_INDEX;
 	if (key) {
-		if (key > WEP_KEYS)
+		if (key > NUM_WEP_KEYS)
 			return -EINVAL;
 		key--;
 	} else {
-		key = ieee->tx_keyidx;
+		key = ieee->crypt_info.tx_keyidx;
 	}
-	crypt = ieee->crypt[key];
+	crypt = ieee->crypt_info.crypt[key];
 
 	erq->flags = key + 1;
 
@@ -513,6 +513,7 @@
 
 	return 0;
 }
+EXPORT_SYMBOL(rtllib_wx_get_encode);
 
 int rtllib_wx_set_encode_ext(struct rtllib_device *ieee,
 			       struct iw_request_info *info,
@@ -525,29 +526,29 @@
 	int i, idx;
 	int group_key = 0;
 	const char *alg, *module;
-	struct rtllib_crypto_ops *ops;
-	struct rtllib_crypt_data **crypt;
+	struct lib80211_crypto_ops *ops;
+	struct lib80211_crypt_data **crypt;
 
 	struct rtllib_security sec = {
 		.flags = 0,
 	};
 	idx = encoding->flags & IW_ENCODE_INDEX;
 	if (idx) {
-		if (idx < 1 || idx > WEP_KEYS)
+		if (idx < 1 || idx > NUM_WEP_KEYS)
 			return -EINVAL;
 		idx--;
 	} else{
-			idx = ieee->tx_keyidx;
+			idx = ieee->crypt_info.tx_keyidx;
 	}
 	if (ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY) {
-		crypt = &ieee->crypt[idx];
+		crypt = &ieee->crypt_info.crypt[idx];
 		group_key = 1;
 	} else {
 		/* some Cisco APs use idx>0 for unicast in dynamic WEP */
 		if (idx != 0 && ext->alg != IW_ENCODE_ALG_WEP)
 			return -EINVAL;
 		if (ieee->iw_mode == IW_MODE_INFRA)
-			crypt = &ieee->crypt[idx];
+			crypt = &ieee->crypt_info.crypt[idx];
 		else
 			return -EINVAL;
 	}
@@ -556,13 +557,13 @@
 	if ((encoding->flags & IW_ENCODE_DISABLED) ||
 	    ext->alg == IW_ENCODE_ALG_NONE) {
 		if (*crypt)
-			rtllib_crypt_delayed_deinit(ieee, crypt);
+			lib80211_crypt_delayed_deinit(&ieee->crypt_info, crypt);
 
-		for (i = 0; i < WEP_KEYS; i++) {
-			if (ieee->crypt[i] != NULL)
+		for (i = 0; i < NUM_WEP_KEYS; i++) {
+			if (ieee->crypt_info.crypt[i] != NULL)
 				break;
 		}
-		if (i == WEP_KEYS) {
+		if (i == NUM_WEP_KEYS) {
 			sec.enabled = 0;
 			sec.level = SEC_LEVEL_0;
 			sec.flags |= SEC_LEVEL;
@@ -573,15 +574,15 @@
 	sec.enabled = 1;
 	switch (ext->alg) {
 	case IW_ENCODE_ALG_WEP:
-		alg = "WEP";
+		alg = "R-WEP";
 		module = "rtllib_crypt_wep";
 		break;
 	case IW_ENCODE_ALG_TKIP:
-		alg = "TKIP";
+		alg = "R-TKIP";
 		module = "rtllib_crypt_tkip";
 		break;
 	case IW_ENCODE_ALG_CCMP:
-		alg = "CCMP";
+		alg = "R-CCMP";
 		module = "rtllib_crypt_ccmp";
 		break;
 	default:
@@ -592,14 +593,14 @@
 	}
 	printk(KERN_INFO "alg name:%s\n", alg);
 
-	 ops = rtllib_get_crypto_ops(alg);
+	ops = lib80211_get_crypto_ops(alg);
 	if (ops == NULL) {
 		char tempbuf[100];
 
 		memset(tempbuf, 0x00, 100);
 		sprintf(tempbuf, "%s", module);
 		request_module("%s", tempbuf);
-		ops = rtllib_get_crypto_ops(alg);
+		ops = lib80211_get_crypto_ops(alg);
 	}
 	if (ops == NULL) {
 		RTLLIB_DEBUG_WX("%s: unknown crypto alg %d\n",
@@ -610,9 +611,9 @@
 	}
 
 	if (*crypt == NULL || (*crypt)->ops != ops) {
-		struct rtllib_crypt_data *new_crypt;
+		struct lib80211_crypt_data *new_crypt;
 
-		rtllib_crypt_delayed_deinit(ieee, crypt);
+		lib80211_crypt_delayed_deinit(&ieee->crypt_info, crypt);
 
 		new_crypt = kzalloc(sizeof(*new_crypt), GFP_KERNEL);
 		if (new_crypt == NULL) {
@@ -641,7 +642,7 @@
 		goto done;
 	}
 	if (ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY) {
-		ieee->tx_keyidx = idx;
+		ieee->crypt_info.tx_keyidx = idx;
 		sec.active_key = idx;
 		sec.flags |= SEC_ACTIVE_KEY;
 	}
@@ -674,6 +675,7 @@
 	}
 	return ret;
 }
+EXPORT_SYMBOL(rtllib_wx_set_encode_ext);
 
 int rtllib_wx_get_encode_ext(struct rtllib_device *ieee,
 			       struct iw_request_info *info,
@@ -681,7 +683,7 @@
 {
 	struct iw_point *encoding = &wrqu->encoding;
 	struct iw_encode_ext *ext = (struct iw_encode_ext *)extra;
-	struct rtllib_crypt_data *crypt;
+	struct lib80211_crypt_data *crypt;
 	int idx, max_key_len;
 
 	max_key_len = encoding->length - sizeof(*ext);
@@ -690,18 +692,18 @@
 
 	idx = encoding->flags & IW_ENCODE_INDEX;
 	if (idx) {
-		if (idx < 1 || idx > WEP_KEYS)
+		if (idx < 1 || idx > NUM_WEP_KEYS)
 			return -EINVAL;
 		idx--;
 	} else {
-		idx = ieee->tx_keyidx;
+		idx = ieee->crypt_info.tx_keyidx;
 	}
 	if (!(ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY) &&
 	    (ext->alg != IW_ENCODE_ALG_WEP))
 		if (idx != 0 || (ieee->iw_mode != IW_MODE_INFRA))
 			return -EINVAL;
 
-	crypt = ieee->crypt[idx];
+	crypt = ieee->crypt_info.crypt[idx];
 
 	encoding->flags = idx + 1;
 	memset(ext, 0, sizeof(*ext));
@@ -711,11 +713,11 @@
 		ext->key_len = 0;
 		encoding->flags |= IW_ENCODE_DISABLED;
 	} else {
-		if (strcmp(crypt->ops->name, "WEP") == 0)
+		if (strcmp(crypt->ops->name, "R-WEP") == 0)
 			ext->alg = IW_ENCODE_ALG_WEP;
-		else if (strcmp(crypt->ops->name, "TKIP"))
+		else if (strcmp(crypt->ops->name, "R-TKIP"))
 			ext->alg = IW_ENCODE_ALG_TKIP;
-		else if (strcmp(crypt->ops->name, "CCMP"))
+		else if (strcmp(crypt->ops->name, "R-CCMP"))
 			ext->alg = IW_ENCODE_ALG_CCMP;
 		else
 			return -EINVAL;
@@ -778,6 +780,7 @@
 
 	return 0;
 }
+EXPORT_SYMBOL(rtllib_wx_set_mlme);
 
 int rtllib_wx_set_auth(struct rtllib_device *ieee,
 			       struct iw_request_info *info,
@@ -830,6 +833,7 @@
 	}
 	return 0;
 }
+EXPORT_SYMBOL(rtllib_wx_set_auth);
 
 int rtllib_wx_set_gen_ie(struct rtllib_device *ieee, u8 *ie, size_t len)
 {
@@ -846,10 +850,9 @@
 
 			ieee->wps_ie_len = (len < MAX_WZC_IE_LEN) ? (len) :
 					   (MAX_WZC_IE_LEN);
-			buf = kmalloc(ieee->wps_ie_len, GFP_KERNEL);
+			buf = kmemdup(ie, ieee->wps_ie_len, GFP_KERNEL);
 			if (buf == NULL)
 				return -ENOMEM;
-			memcpy(buf, ie, ieee->wps_ie_len);
 			ieee->wps_ie = buf;
 			return 0;
 		}
@@ -860,10 +863,9 @@
 	if (len) {
 		if (len != ie[1]+2)
 			return -EINVAL;
-		buf = kmalloc(len, GFP_KERNEL);
+		buf = kmemdup(ie, len, GFP_KERNEL);
 		if (buf == NULL)
 			return -ENOMEM;
-		memcpy(buf, ie, len);
 		kfree(ieee->wpa_ie);
 		ieee->wpa_ie = buf;
 		ieee->wpa_ie_len = len;
@@ -874,3 +876,4 @@
 	}
 	return 0;
 }
+EXPORT_SYMBOL(rtllib_wx_set_gen_ie);
diff --git a/drivers/staging/rtl8192u/ieee80211/api.c b/drivers/staging/rtl8192u/ieee80211/api.c
deleted file mode 100644
index 5f46e50..0000000
--- a/drivers/staging/rtl8192u/ieee80211/api.c
+++ /dev/null
@@ -1,244 +0,0 @@
-/*
- * Scatterlist Cryptographic API.
- *
- * Copyright (c) 2002 James Morris <jmorris@intercode.com.au>
- * Copyright (c) 2002 David S. Miller (davem@redhat.com)
- *
- * Portions derived from Cryptoapi, by Alexander Kjeldaas <astor@fast.no>
- * and Nettle, by Niels Mé°ˆler.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the Free
- * Software Foundation; either version 2 of the License, or (at your option)
- * any later version.
- *
- */
-#include "kmap_types.h"
-
-#include <linux/init.h>
-#include <linux/module.h>
-//#include <linux/crypto.h>
-#include "rtl_crypto.h"
-#include <linux/errno.h>
-#include <linux/rwsem.h>
-#include <linux/slab.h>
-#include "internal.h"
-
-LIST_HEAD(crypto_alg_list);
-DECLARE_RWSEM(crypto_alg_sem);
-
-static inline int crypto_alg_get(struct crypto_alg *alg)
-{
-	return try_inc_mod_count(alg->cra_module);
-}
-
-static inline void crypto_alg_put(struct crypto_alg *alg)
-{
-	if (alg->cra_module)
-		__MOD_DEC_USE_COUNT(alg->cra_module);
-}
-
-struct crypto_alg *crypto_alg_lookup(const char *name)
-{
-	struct crypto_alg *q, *alg = NULL;
-
-	if (!name)
-		return NULL;
-
-	down_read(&crypto_alg_sem);
-
-	list_for_each_entry(q, &crypto_alg_list, cra_list) {
-		if (!(strcmp(q->cra_name, name))) {
-			if (crypto_alg_get(q))
-				alg = q;
-			break;
-		}
-	}
-
-	up_read(&crypto_alg_sem);
-	return alg;
-}
-
-static int crypto_init_flags(struct crypto_tfm *tfm, u32 flags)
-{
-	tfm->crt_flags = 0;
-
-	switch (crypto_tfm_alg_type(tfm)) {
-	case CRYPTO_ALG_TYPE_CIPHER:
-		return crypto_init_cipher_flags(tfm, flags);
-
-	case CRYPTO_ALG_TYPE_DIGEST:
-		return crypto_init_digest_flags(tfm, flags);
-
-	case CRYPTO_ALG_TYPE_COMPRESS:
-		return crypto_init_compress_flags(tfm, flags);
-
-	default:
-		break;
-	}
-
-	BUG();
-	return -EINVAL;
-}
-
-static int crypto_init_ops(struct crypto_tfm *tfm)
-{
-	switch (crypto_tfm_alg_type(tfm)) {
-	case CRYPTO_ALG_TYPE_CIPHER:
-		return crypto_init_cipher_ops(tfm);
-
-	case CRYPTO_ALG_TYPE_DIGEST:
-		return crypto_init_digest_ops(tfm);
-
-	case CRYPTO_ALG_TYPE_COMPRESS:
-		return crypto_init_compress_ops(tfm);
-
-	default:
-		break;
-	}
-
-	BUG();
-	return -EINVAL;
-}
-
-static void crypto_exit_ops(struct crypto_tfm *tfm)
-{
-	switch (crypto_tfm_alg_type(tfm)) {
-	case CRYPTO_ALG_TYPE_CIPHER:
-		crypto_exit_cipher_ops(tfm);
-		break;
-
-	case CRYPTO_ALG_TYPE_DIGEST:
-		crypto_exit_digest_ops(tfm);
-		break;
-
-	case CRYPTO_ALG_TYPE_COMPRESS:
-		crypto_exit_compress_ops(tfm);
-		break;
-
-	default:
-		BUG();
-
-	}
-}
-
-struct crypto_tfm *crypto_alloc_tfm(const char *name, u32 flags)
-{
-	struct crypto_tfm *tfm = NULL;
-	struct crypto_alg *alg;
-
-	alg = crypto_alg_mod_lookup(name);
-	if (alg == NULL)
-		goto out;
-
-	tfm = kzalloc(sizeof(*tfm) + alg->cra_ctxsize, GFP_KERNEL);
-	if (tfm == NULL)
-		goto out_put;
-
-	tfm->__crt_alg = alg;
-
-	if (crypto_init_flags(tfm, flags))
-		goto out_free_tfm;
-
-	if (crypto_init_ops(tfm)) {
-		crypto_exit_ops(tfm);
-		goto out_free_tfm;
-	}
-
-	goto out;
-
-out_free_tfm:
-	kfree(tfm);
-	tfm = NULL;
-out_put:
-	crypto_alg_put(alg);
-out:
-	return tfm;
-}
-
-void crypto_free_tfm(struct crypto_tfm *tfm)
-{
-	struct crypto_alg *alg = tfm->__crt_alg;
-	int size = sizeof(*tfm) + alg->cra_ctxsize;
-
-	crypto_exit_ops(tfm);
-	crypto_alg_put(alg);
-	memset(tfm, 0, size);
-	kfree(tfm);
-}
-
-int crypto_register_alg(struct crypto_alg *alg)
-{
-	int ret = 0;
-	struct crypto_alg *q;
-
-	down_write(&crypto_alg_sem);
-
-	list_for_each_entry(q, &crypto_alg_list, cra_list) {
-		if (!(strcmp(q->cra_name, alg->cra_name))) {
-			ret = -EEXIST;
-			goto out;
-		}
-	}
-
-	list_add_tail(&alg->cra_list, &crypto_alg_list);
-out:
-	up_write(&crypto_alg_sem);
-	return ret;
-}
-
-int crypto_unregister_alg(struct crypto_alg *alg)
-{
-	int ret = -ENOENT;
-	struct crypto_alg *q;
-
-	BUG_ON(!alg->cra_module);
-
-	down_write(&crypto_alg_sem);
-	list_for_each_entry(q, &crypto_alg_list, cra_list) {
-		if (alg == q) {
-			list_del(&alg->cra_list);
-			ret = 0;
-			goto out;
-		}
-	}
-out:
-	up_write(&crypto_alg_sem);
-	return ret;
-}
-
-int crypto_alg_available(const char *name, u32 flags)
-{
-	int ret = 0;
-	struct crypto_alg *alg = crypto_alg_mod_lookup(name);
-
-	if (alg) {
-		crypto_alg_put(alg);
-		ret = 1;
-	}
-
-	return ret;
-}
-
-static int __init init_crypto(void)
-{
-	printk(KERN_INFO "Initializing Cryptographic API\n");
-	crypto_init_proc();
-	return 0;
-}
-
-__initcall(init_crypto);
-
-/*
-EXPORT_SYMBOL_GPL(crypto_register_alg);
-EXPORT_SYMBOL_GPL(crypto_unregister_alg);
-EXPORT_SYMBOL_GPL(crypto_alloc_tfm);
-EXPORT_SYMBOL_GPL(crypto_free_tfm);
-EXPORT_SYMBOL_GPL(crypto_alg_available);
-*/
-
-EXPORT_SYMBOL_NOVERS(crypto_register_alg);
-EXPORT_SYMBOL_NOVERS(crypto_unregister_alg);
-EXPORT_SYMBOL_NOVERS(crypto_alloc_tfm);
-EXPORT_SYMBOL_NOVERS(crypto_free_tfm);
-EXPORT_SYMBOL_NOVERS(crypto_alg_available);
diff --git a/drivers/staging/rtl8712/rtl871x_mlme.c b/drivers/staging/rtl8712/rtl871x_mlme.c
index ef8eb6c..4277d03 100644
--- a/drivers/staging/rtl8712/rtl871x_mlme.c
+++ b/drivers/staging/rtl8712/rtl871x_mlme.c
@@ -551,7 +551,7 @@
 			ibss_wlan = r8712_find_network(
 						&pmlmepriv->scanned_queue,
 						pnetwork->MacAddress);
-			if (!ibss_wlan) {
+			if (ibss_wlan) {
 				memcpy(ibss_wlan->network.IEs,
 					pnetwork->IEs, 8);
 				goto exit;
diff --git a/drivers/staging/rts5139/rts51x.h b/drivers/staging/rts5139/rts51x.h
index 9415d5c..b2c5839 100644
--- a/drivers/staging/rts5139/rts51x.h
+++ b/drivers/staging/rts5139/rts51x.h
@@ -34,7 +34,6 @@
 #include <linux/mutex.h>
 #include <linux/cdrom.h>
 #include <linux/kernel.h>
-#include <linux/version.h>
 
 #include <scsi/scsi.h>
 #include <scsi/scsi_cmnd.h>
diff --git a/drivers/staging/rts5139/rts51x_transport.h b/drivers/staging/rts5139/rts51x_transport.h
index f7aa87f..8464c48 100644
--- a/drivers/staging/rts5139/rts51x_transport.h
+++ b/drivers/staging/rts5139/rts51x_transport.h
@@ -28,7 +28,6 @@
 #define __RTS51X_TRANSPORT_H
 
 #include <linux/kernel.h>
-#include <linux/version.h>
 
 #include "rts51x.h"
 #include "rts51x_chip.h"
diff --git a/drivers/staging/sep/sep_driver.c b/drivers/staging/sep/sep_driver.c
index f47571e..6b3d156 100644
--- a/drivers/staging/sep/sep_driver.c
+++ b/drivers/staging/sep/sep_driver.c
@@ -2120,6 +2120,8 @@
 			}
 		}
 		if (tail_size) {
+			if (tail_size > sizeof(dcb_table_ptr->tail_data))
+				return -EINVAL;
 			if (is_kva == true) {
 				memcpy(dcb_table_ptr->tail_data,
 					(void *)(app_in_address + data_in_size -
diff --git a/drivers/staging/serial/68360serial.c b/drivers/staging/serial/68360serial.c
index 0a3e878..daf0b1d 100644
--- a/drivers/staging/serial/68360serial.c
+++ b/drivers/staging/serial/68360serial.c
@@ -2771,8 +2771,8 @@
 			*/
 			/* cpm_install_handler(IRQ_MACHSPEC | state->irq, rs_360_interrupt, info);  */
 			/*request_irq(IRQ_MACHSPEC | state->irq, rs_360_interrupt, */
-			request_irq(state->irq, rs_360_interrupt,
-						IRQ_FLG_LOCK, "ttyS", (void *)info);
+			request_irq(state->irq, rs_360_interrupt, 0, "ttyS",
+				    (void *)info);
 
 			/* Set up the baud rate generator.
 			*/
diff --git a/drivers/staging/sm7xx/smtcfb.c b/drivers/staging/sm7xx/smtcfb.c
index 39dbf33..ae0035f 100644
--- a/drivers/staging/sm7xx/smtcfb.c
+++ b/drivers/staging/sm7xx/smtcfb.c
@@ -1024,9 +1024,9 @@
 
 /* Jason (08/11/2009) PCI_DRV wrapper essential structs */
 static DEFINE_PCI_DEVICE_TABLE(smtcfb_pci_table) = {
-	{0x126f, 0x710, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
-	{0x126f, 0x712, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
-	{0x126f, 0x720, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+	{ PCI_DEVICE(0x126f, 0x710), },
+	{ PCI_DEVICE(0x126f, 0x712), },
+	{ PCI_DEVICE(0x126f, 0x720), },
 	{0,}
 };
 
diff --git a/drivers/staging/speakup/kobjects.c b/drivers/staging/speakup/kobjects.c
index 07a7f54..2093896 100644
--- a/drivers/staging/speakup/kobjects.c
+++ b/drivers/staging/speakup/kobjects.c
@@ -265,12 +265,11 @@
 	unsigned long flags;
 
 	spk_lock(flags);
-	in_buff = kmalloc(count + 1, GFP_ATOMIC);
+	in_buff = kmemdup(buf, count + 1, GFP_ATOMIC);
 	if (!in_buff) {
 		spk_unlock(flags);
 		return -ENOMEM;
 	}
-	memcpy(in_buff, buf, count + 1);
 	if (strchr("dDrR", *in_buff)) {
 		set_key_info(key_defaults, key_buf);
 		pr_info("keymap set to default values\n");
diff --git a/drivers/staging/speakup/main.c b/drivers/staging/speakup/main.c
index 8be5604..c7b03f0 100644
--- a/drivers/staging/speakup/main.c
+++ b/drivers/staging/speakup/main.c
@@ -2268,8 +2268,6 @@
 		set_mask_bits(0, i, 2);
 
 	set_key_info(key_defaults, key_buf);
-	if (quiet_boot)
-		spk_shut_up |= 0x01;
 
 	/* From here on out, initializations can fail. */
 	err = speakup_add_virtual_keyboard();
@@ -2292,6 +2290,9 @@
 				goto error_kobjects;
 		}
 
+	if (quiet_boot)
+		spk_shut_up |= 0x01;
+
 	err = speakup_kobj_init();
 	if (err)
 		goto error_kobjects;
diff --git a/drivers/staging/spectra/Kconfig b/drivers/staging/spectra/Kconfig
deleted file mode 100644
index 4fc2064..0000000
--- a/drivers/staging/spectra/Kconfig
+++ /dev/null
@@ -1,41 +0,0 @@
-
-menuconfig SPECTRA
-	tristate "Denali Spectra Flash Translation Layer"
-	depends on BLOCK
-	depends on X86_MRST
-	default n
-	---help---
-	  Enable the FTL pseudo-filesystem used with the NAND Flash
-	  controller on Intel Moorestown Platform to pretend to be a disk.
-
-choice
-	prompt "Compile for"
-	depends on SPECTRA
-	default SPECTRA_MRST_HW
-
-config SPECTRA_MRST_HW
-	bool "Moorestown hardware mode"
-	help
-	  Driver communicates with the Moorestown hardware's register interface.
-	  in DMA mode.
-
-config SPECTRA_MTD
-	bool "Linux MTD mode"
-	depends on MTD
-	help
-	  Driver communicates with the kernel MTD subsystem instead of its own
-	  built-in hardware driver.
-
-config SPECTRA_EMU
-	bool "RAM emulator testing"
-	help
-	  Driver emulates Flash on a RAM buffer and / or disk file.  Useful to test the behavior of FTL layer.
-
-endchoice
-
-config SPECTRA_MRST_HW_DMA
-       bool
-       default n
-       depends on SPECTRA_MRST_HW
-       help
-         Use DMA for native hardware interface.
diff --git a/drivers/staging/spectra/Makefile b/drivers/staging/spectra/Makefile
deleted file mode 100644
index f777dfb..0000000
--- a/drivers/staging/spectra/Makefile
+++ /dev/null
@@ -1,11 +0,0 @@
-#
-# Makefile of Intel Moorestown NAND controller driver
-#
-
-obj-$(CONFIG_SPECTRA) += spectra.o
-spectra-y := ffsport.o flash.o lld.o
-spectra-$(CONFIG_SPECTRA_MRST_HW) += lld_nand.o 
-spectra-$(CONFIG_SPECTRA_MRST_HW_DMA) += lld_cdma.o
-spectra-$(CONFIG_SPECTRA_EMU) += lld_emu.o
-spectra-$(CONFIG_SPECTRA_MTD) += lld_mtd.o
-
diff --git a/drivers/staging/spectra/README b/drivers/staging/spectra/README
deleted file mode 100644
index ecba559..0000000
--- a/drivers/staging/spectra/README
+++ /dev/null
@@ -1,29 +0,0 @@
-This is a driver for NAND controller of Intel Moorestown platform.
-
-This driver is a standalone linux block device driver, it acts as if it's a normal hard disk.
-It includes three layer:
-	block layer interface - file ffsport.c
-	Flash Translation Layer (FTL) - file flash.c (implement the NAND flash Translation Layer, includs address mapping, garbage collection, wear-leveling and so on)
-	Low level layer - file lld_nand.c/lld_cdma.c/lld_emu.c (which implements actual controller hardware registers access)
-
-This driver can be build as modules or build-in.
-
-Dependency:
-This driver has dependency on IA Firmware of Intel Moorestown platform.
-It need the IA Firmware to create the block table for the first time.
-And to validate this driver code without IA Firmware, you can change the
-macro AUTO_FORMAT_FLASH from 0 to 1 in file spectraswconfig.h. Thus the
-driver will erase the whole nand flash and create a new block table.
-
-TODO:
-	- Enable Command DMA feature support
-	- lower the memory footprint
-	- Remove most of the unnecessary global variables
-	- Change all the upcase variable / functions name to lowercase
-	- Some other misc bugs
-
-Please send patches to:
-	Greg Kroah-Hartman <gregkh@suse.de>
-
-And Cc to: Gao Yunpeng <yunpeng.gao@intel.com>
-
diff --git a/drivers/staging/spectra/ffsdefs.h b/drivers/staging/spectra/ffsdefs.h
deleted file mode 100644
index a9e9cd2..0000000
--- a/drivers/staging/spectra/ffsdefs.h
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- * NAND Flash Controller Device Driver
- * Copyright (c) 2009, Intel Corporation and its suppliers.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms and conditions of the GNU General Public License,
- * version 2, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
- *
- */
-
-#ifndef _FFSDEFS_
-#define _FFSDEFS_
-
-#define CLEAR 0			/*use this to clear a field instead of "fail"*/
-#define SET   1			/*use this to set a field instead of "pass"*/
-#define FAIL 1			/*failed flag*/
-#define PASS 0			/*success flag*/
-#define ERR -1			/*error flag*/
-
-#define   ERASE_CMD             10
-#define   WRITE_MAIN_CMD        11
-#define   READ_MAIN_CMD         12
-#define   WRITE_SPARE_CMD       13
-#define   READ_SPARE_CMD        14
-#define   WRITE_MAIN_SPARE_CMD  15
-#define   READ_MAIN_SPARE_CMD   16
-#define   MEMCOPY_CMD           17
-#define   DUMMY_CMD             99
-
-#define     EVENT_PASS                                  0x00
-#define     EVENT_CORRECTABLE_DATA_ERROR_FIXED         0x01
-#define     EVENT_UNCORRECTABLE_DATA_ERROR              0x02
-#define     EVENT_TIME_OUT                              0x03
-#define     EVENT_PROGRAM_FAILURE                       0x04
-#define     EVENT_ERASE_FAILURE                         0x05
-#define     EVENT_MEMCOPY_FAILURE                       0x06
-#define     EVENT_FAIL                                  0x07
-
-#define     EVENT_NONE                                  0x22
-#define     EVENT_DMA_CMD_COMP                          0x77
-#define     EVENT_ECC_TRANSACTION_DONE                  0x88
-#define     EVENT_DMA_CMD_FAIL                          0x99
-
-#define CMD_PASS        0
-#define CMD_FAIL        1
-#define CMD_ABORT       2
-#define CMD_NOT_DONE    3
-
-#endif /* _FFSDEFS_ */
diff --git a/drivers/staging/spectra/ffsport.c b/drivers/staging/spectra/ffsport.c
deleted file mode 100644
index 86d556d..0000000
--- a/drivers/staging/spectra/ffsport.c
+++ /dev/null
@@ -1,834 +0,0 @@
-/*
- * NAND Flash Controller Device Driver
- * Copyright (c) 2009, Intel Corporation and its suppliers.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms and conditions of the GNU General Public License,
- * version 2, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
- *
- */
-
-#include "ffsport.h"
-#include "flash.h"
-#include <linux/interrupt.h>
-#include <linux/delay.h>
-#include <linux/blkdev.h>
-#include <linux/wait.h>
-#include <linux/mutex.h>
-#include <linux/kthread.h>
-#include <linux/log2.h>
-#include <linux/init.h>
-#include <linux/slab.h>
-#include <linux/async.h>
-
-/**** Helper functions used for Div, Remainder operation on u64 ****/
-
-/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
-* Function:     GLOB_Calc_Used_Bits
-* Inputs:       Power of 2 number
-* Outputs:      Number of Used Bits
-*               0, if the argument is 0
-* Description:  Calculate the number of bits used by a given power of 2 number
-*               Number can be up to 32 bit
-*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
-int GLOB_Calc_Used_Bits(u32 n)
-{
-	int tot_bits = 0;
-
-	if (n >= 1 << 16) {
-		n >>= 16;
-		tot_bits += 16;
-	}
-
-	if (n >= 1 << 8) {
-		n >>=  8;
-		tot_bits +=  8;
-	}
-
-	if (n >= 1 << 4) {
-		n >>=  4;
-		tot_bits +=  4;
-	}
-
-	if (n >= 1 << 2) {
-		n >>=  2;
-		tot_bits +=  2;
-	}
-
-	if (n >= 1 << 1)
-		tot_bits +=  1;
-
-	return ((n == 0) ? (0) : tot_bits);
-}
-
-/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
-* Function:     GLOB_u64_Div
-* Inputs:       Number of u64
-*               A power of 2 number as Division
-* Outputs:      Quotient of the Divisor operation
-* Description:  It divides the address by divisor by using bit shift operation
-*               (essentially without explicitely using "/").
-*               Divisor is a power of 2 number and Divided is of u64
-*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
-u64 GLOB_u64_Div(u64 addr, u32 divisor)
-{
-	return  (u64)(addr >> GLOB_Calc_Used_Bits(divisor));
-}
-
-/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
-* Function:     GLOB_u64_Remainder
-* Inputs:       Number of u64
-*               Divisor Type (1 -PageAddress, 2- BlockAddress)
-* Outputs:      Remainder of the Division operation
-* Description:  It calculates the remainder of a number (of u64) by
-*               divisor(power of 2 number ) by using bit shifting and multiply
-*               operation(essentially without explicitely using "/").
-*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
-u64 GLOB_u64_Remainder(u64 addr, u32 divisor_type)
-{
-	u64 result = 0;
-
-	if (divisor_type == 1) { /* Remainder -- Page */
-		result = (addr >> DeviceInfo.nBitsInPageDataSize);
-		result = result * DeviceInfo.wPageDataSize;
-	} else if (divisor_type == 2) { /* Remainder -- Block */
-		result = (addr >> DeviceInfo.nBitsInBlockDataSize);
-		result = result * DeviceInfo.wBlockDataSize;
-	}
-
-	result = addr - result;
-
-	return result;
-}
-
-#define NUM_DEVICES             1
-#define PARTITIONS              8
-
-#define GLOB_SBD_NAME          "nd"
-#define GLOB_SBD_IRQ_NUM       (29)
-
-#define GLOB_SBD_IOCTL_GC                        (0x7701)
-#define GLOB_SBD_IOCTL_WL                        (0x7702)
-#define GLOB_SBD_IOCTL_FORMAT                    (0x7703)
-#define GLOB_SBD_IOCTL_ERASE_FLASH               (0x7704)
-#define GLOB_SBD_IOCTL_FLUSH_CACHE               (0x7705)
-#define GLOB_SBD_IOCTL_COPY_BLK_TABLE            (0x7706)
-#define GLOB_SBD_IOCTL_COPY_WEAR_LEVELING_TABLE  (0x7707)
-#define GLOB_SBD_IOCTL_GET_NAND_INFO             (0x7708)
-#define GLOB_SBD_IOCTL_WRITE_DATA                (0x7709)
-#define GLOB_SBD_IOCTL_READ_DATA                 (0x770A)
-
-static int reserved_mb = 0;
-module_param(reserved_mb, int, 0);
-MODULE_PARM_DESC(reserved_mb, "Reserved space for OS image, in MiB (default 25 MiB)");
-
-int nand_debug_level;
-module_param(nand_debug_level, int, 0644);
-MODULE_PARM_DESC(nand_debug_level, "debug level value: 1-3");
-
-MODULE_LICENSE("GPL");
-
-struct spectra_nand_dev {
-	struct pci_dev *dev;
-	u64 size;
-	u16 users;
-	spinlock_t qlock;
-	void __iomem *ioaddr;  /* Mapped address */
-	struct request_queue *queue;
-	struct task_struct *thread;
-	struct gendisk *gd;
-	u8 *tmp_buf;
-};
-
-
-static int GLOB_SBD_majornum;
-
-static char *GLOB_version = GLOB_VERSION;
-
-static struct spectra_nand_dev nand_device[NUM_DEVICES];
-
-static struct mutex spectra_lock;
-
-static int res_blks_os = 1;
-
-struct spectra_indentfy_dev_tag IdentifyDeviceData;
-
-static int force_flush_cache(void)
-{
-	nand_dbg_print(NAND_DBG_DEBUG, "%s, Line %d, Function: %s\n",
-		__FILE__, __LINE__, __func__);
-
-	if (ERR == GLOB_FTL_Flush_Cache()) {
-		printk(KERN_ERR "Fail to Flush FTL Cache!\n");
-		return -EFAULT;
-	}
-#if CMD_DMA
-		if (glob_ftl_execute_cmds())
-			return -EIO;
-		else
-			return 0;
-#endif
-	return 0;
-}
-
-struct ioctl_rw_page_info {
-	u8 *data;
-	unsigned int page;
-};
-
-static int ioctl_read_page_data(unsigned long arg)
-{
-	u8 *buf;
-	struct ioctl_rw_page_info info;
-	int result = PASS;
-
-	if (copy_from_user(&info, (void __user *)arg, sizeof(info)))
-		return -EFAULT;
-
-	buf = kmalloc(IdentifyDeviceData.PageDataSize, GFP_ATOMIC);
-	if (!buf) {
-		printk(KERN_ERR "ioctl_read_page_data: "
-		       "failed to allocate memory\n");
-		return -ENOMEM;
-	}
-
-	mutex_lock(&spectra_lock);
-	result = GLOB_FTL_Page_Read(buf,
-		(u64)info.page * IdentifyDeviceData.PageDataSize);
-	mutex_unlock(&spectra_lock);
-
-	if (copy_to_user((void __user *)info.data, buf,
-			   IdentifyDeviceData.PageDataSize)) {
-		printk(KERN_ERR "ioctl_read_page_data: "
-		       "failed to copy user data\n");
-		kfree(buf);
-		return -EFAULT;
-	}
-
-	kfree(buf);
-	return result;
-}
-
-static int ioctl_write_page_data(unsigned long arg)
-{
-	u8 *buf;
-	struct ioctl_rw_page_info info;
-	int result = PASS;
-
-	if (copy_from_user(&info, (void __user *)arg, sizeof(info)))
-		return -EFAULT;
-
-	buf = memdup_user((void __user *)info.data,
-			  IdentifyDeviceData.PageDataSize);
-	if (IS_ERR(buf)) {
-		printk(KERN_ERR "ioctl_write_page_data: "
-		       "failed to copy user data\n");
-		return PTR_ERR(buf);
-	}
-
-	mutex_lock(&spectra_lock);
-	result = GLOB_FTL_Page_Write(buf,
-		(u64)info.page * IdentifyDeviceData.PageDataSize);
-	mutex_unlock(&spectra_lock);
-
-	kfree(buf);
-	return result;
-}
-
-/* Return how many blocks should be reserved for bad block replacement */
-static int get_res_blk_num_bad_blk(void)
-{
-	return IdentifyDeviceData.wDataBlockNum / 10;
-}
-
-/* Return how many blocks should be reserved for OS image */
-static int get_res_blk_num_os(void)
-{
-	u32 res_blks, blk_size;
-
-	blk_size = IdentifyDeviceData.PageDataSize *
-		IdentifyDeviceData.PagesPerBlock;
-
-	res_blks = (reserved_mb * 1024 * 1024) / blk_size;
-
-	if ((res_blks < 1) || (res_blks >= IdentifyDeviceData.wDataBlockNum))
-		res_blks = 1; /* Reserved 1 block for block table */
-
-	return res_blks;
-}
-
-/* Transfer a full request. */
-static int do_transfer(struct spectra_nand_dev *tr, struct request *req)
-{
-	u64 start_addr, addr;
-	u32 logical_start_sect, hd_start_sect;
-	u32 nsect, hd_sects;
-	u32 rsect, tsect = 0;
-	char *buf;
-	u32 ratio = IdentifyDeviceData.PageDataSize >> 9;
-
-	start_addr = (u64)(blk_rq_pos(req)) << 9;
-	/* Add a big enough offset to prevent the OS Image from
-	*  being accessed or damaged by file system */
-	start_addr += IdentifyDeviceData.PageDataSize *
-			IdentifyDeviceData.PagesPerBlock *
-			res_blks_os;
-
-	if (req->cmd_type & REQ_FLUSH) {
-		if (force_flush_cache()) /* Fail to flush cache */
-			return -EIO;
-		else
-			return 0;
-	}
-
-	if (req->cmd_type != REQ_TYPE_FS)
-		return -EIO;
-
-	if (blk_rq_pos(req) + blk_rq_cur_sectors(req) > get_capacity(tr->gd)) {
-		printk(KERN_ERR "Spectra error: request over the NAND "
-			"capacity!sector %d, current_nr_sectors %d, "
-			"while capacity is %d\n",
-			(int)blk_rq_pos(req),
-			blk_rq_cur_sectors(req),
-			(int)get_capacity(tr->gd));
-		return -EIO;
-	}
-
-	logical_start_sect = start_addr >> 9;
-	hd_start_sect = logical_start_sect / ratio;
-	rsect = logical_start_sect - hd_start_sect * ratio;
-
-	addr = (u64)hd_start_sect * ratio * 512;
-	buf = req->buffer;
-	nsect = blk_rq_cur_sectors(req);
-
-	if (rsect)
-		tsect =  (ratio - rsect) < nsect ? (ratio - rsect) : nsect;
-
-	switch (rq_data_dir(req)) {
-	case READ:
-		/* Read the first NAND page */
-		if (rsect) {
-			if (GLOB_FTL_Page_Read(tr->tmp_buf, addr)) {
-				printk(KERN_ERR "Error in %s, Line %d\n",
-					__FILE__, __LINE__);
-				return -EIO;
-			}
-			memcpy(buf, tr->tmp_buf + (rsect << 9), tsect << 9);
-			addr += IdentifyDeviceData.PageDataSize;
-			buf += tsect << 9;
-			nsect -= tsect;
-		}
-
-		/* Read the other NAND pages */
-		for (hd_sects = nsect / ratio; hd_sects > 0; hd_sects--) {
-			if (GLOB_FTL_Page_Read(buf, addr)) {
-				printk(KERN_ERR "Error in %s, Line %d\n",
-					__FILE__, __LINE__);
-				return -EIO;
-			}
-			addr += IdentifyDeviceData.PageDataSize;
-			buf += IdentifyDeviceData.PageDataSize;
-		}
-
-		/* Read the last NAND pages */
-		if (nsect % ratio) {
-			if (GLOB_FTL_Page_Read(tr->tmp_buf, addr)) {
-				printk(KERN_ERR "Error in %s, Line %d\n",
-					__FILE__, __LINE__);
-				return -EIO;
-			}
-			memcpy(buf, tr->tmp_buf, (nsect % ratio) << 9);
-		}
-#if CMD_DMA
-		if (glob_ftl_execute_cmds())
-			return -EIO;
-		else
-			return 0;
-#endif
-		return 0;
-
-	case WRITE:
-		/* Write the first NAND page */
-		if (rsect) {
-			if (GLOB_FTL_Page_Read(tr->tmp_buf, addr)) {
-				printk(KERN_ERR "Error in %s, Line %d\n",
-					__FILE__, __LINE__);
-				return -EIO;
-			}
-			memcpy(tr->tmp_buf + (rsect << 9), buf, tsect << 9);
-			if (GLOB_FTL_Page_Write(tr->tmp_buf, addr)) {
-				printk(KERN_ERR "Error in %s, Line %d\n",
-					__FILE__, __LINE__);
-				return -EIO;
-			}
-			addr += IdentifyDeviceData.PageDataSize;
-			buf += tsect << 9;
-			nsect -= tsect;
-		}
-
-		/* Write the other NAND pages */
-		for (hd_sects = nsect / ratio; hd_sects > 0; hd_sects--) {
-			if (GLOB_FTL_Page_Write(buf, addr)) {
-				printk(KERN_ERR "Error in %s, Line %d\n",
-					__FILE__, __LINE__);
-				return -EIO;
-			}
-			addr += IdentifyDeviceData.PageDataSize;
-			buf += IdentifyDeviceData.PageDataSize;
-		}
-
-		/* Write the last NAND pages */
-		if (nsect % ratio) {
-			if (GLOB_FTL_Page_Read(tr->tmp_buf, addr)) {
-				printk(KERN_ERR "Error in %s, Line %d\n",
-					__FILE__, __LINE__);
-				return -EIO;
-			}
-			memcpy(tr->tmp_buf, buf, (nsect % ratio) << 9);
-			if (GLOB_FTL_Page_Write(tr->tmp_buf, addr)) {
-				printk(KERN_ERR "Error in %s, Line %d\n",
-					__FILE__, __LINE__);
-				return -EIO;
-			}
-		}
-#if CMD_DMA
-		if (glob_ftl_execute_cmds())
-			return -EIO;
-		else
-			return 0;
-#endif
-		return 0;
-
-	default:
-		printk(KERN_NOTICE "Unknown request %u\n", rq_data_dir(req));
-		return -EIO;
-	}
-}
-
-/* This function is copied from drivers/mtd/mtd_blkdevs.c */
-static int spectra_trans_thread(void *arg)
-{
-	struct spectra_nand_dev *tr = arg;
-	struct request_queue *rq = tr->queue;
-	struct request *req = NULL;
-
-	/* we might get involved when memory gets low, so use PF_MEMALLOC */
-	current->flags |= PF_MEMALLOC;
-
-	spin_lock_irq(rq->queue_lock);
-	while (!kthread_should_stop()) {
-		int res;
-
-		if (!req) {
-			req = blk_fetch_request(rq);
-			if (!req) {
-				set_current_state(TASK_INTERRUPTIBLE);
-				spin_unlock_irq(rq->queue_lock);
-				schedule();
-				spin_lock_irq(rq->queue_lock);
-				continue;
-			}
-		}
-
-		spin_unlock_irq(rq->queue_lock);
-
-		mutex_lock(&spectra_lock);
-		res = do_transfer(tr, req);
-		mutex_unlock(&spectra_lock);
-
-		spin_lock_irq(rq->queue_lock);
-
-		if (!__blk_end_request_cur(req, res))
-			req = NULL;
-	}
-
-	if (req)
-		__blk_end_request_all(req, -EIO);
-
-	spin_unlock_irq(rq->queue_lock);
-
-	return 0;
-}
-
-
-/* Request function that "handles clustering". */
-static void GLOB_SBD_request(struct request_queue *rq)
-{
-	struct spectra_nand_dev *pdev = rq->queuedata;
-	wake_up_process(pdev->thread);
-}
-
-static int GLOB_SBD_open(struct block_device *bdev, fmode_t mode)
-
-{
-	nand_dbg_print(NAND_DBG_WARN, "%s, Line %d, Function: %s\n",
-		       __FILE__, __LINE__, __func__);
-	return 0;
-}
-
-static int GLOB_SBD_release(struct gendisk *disk, fmode_t mode)
-{
-	int ret;
-
-	nand_dbg_print(NAND_DBG_WARN, "%s, Line %d, Function: %s\n",
-		       __FILE__, __LINE__, __func__);
-
-	mutex_lock(&spectra_lock);
-	ret = force_flush_cache();
-	mutex_unlock(&spectra_lock);
-
-	return 0;
-}
-
-static int GLOB_SBD_getgeo(struct block_device *bdev, struct hd_geometry *geo)
-{
-	geo->heads = 4;
-	geo->sectors = 16;
-	geo->cylinders = get_capacity(bdev->bd_disk) / (4 * 16);
-
-	nand_dbg_print(NAND_DBG_DEBUG,
-		"heads: %d, sectors: %d, cylinders: %d\n",
-		geo->heads, geo->sectors, geo->cylinders);
-
-	return 0;
-}
-
-int GLOB_SBD_ioctl(struct block_device *bdev, fmode_t mode,
-		unsigned int cmd, unsigned long arg)
-{
-	int ret;
-
-	nand_dbg_print(NAND_DBG_TRACE, "%s, Line %d, Function: %s\n",
-		       __FILE__, __LINE__, __func__);
-
-	switch (cmd) {
-	case GLOB_SBD_IOCTL_GC:
-		nand_dbg_print(NAND_DBG_DEBUG,
-			       "Spectra IOCTL: Garbage Collection "
-			       "being performed\n");
-		if (PASS != GLOB_FTL_Garbage_Collection())
-			return -EFAULT;
-		return 0;
-
-	case GLOB_SBD_IOCTL_WL:
-		nand_dbg_print(NAND_DBG_DEBUG,
-			       "Spectra IOCTL: Static Wear Leveling "
-			       "being performed\n");
-		if (PASS != GLOB_FTL_Wear_Leveling())
-			return -EFAULT;
-		return 0;
-
-	case GLOB_SBD_IOCTL_FORMAT:
-		nand_dbg_print(NAND_DBG_DEBUG, "Spectra IOCTL: Flash format "
-			       "being performed\n");
-		if (PASS != GLOB_FTL_Flash_Format())
-			return -EFAULT;
-		return 0;
-
-	case GLOB_SBD_IOCTL_FLUSH_CACHE:
-		nand_dbg_print(NAND_DBG_DEBUG, "Spectra IOCTL: Cache flush "
-			       "being performed\n");
-		mutex_lock(&spectra_lock);
-		ret = force_flush_cache();
-		mutex_unlock(&spectra_lock);
-		return ret;
-
-	case GLOB_SBD_IOCTL_COPY_BLK_TABLE:
-		nand_dbg_print(NAND_DBG_DEBUG, "Spectra IOCTL: "
-			       "Copy block table\n");
-		if (copy_to_user((void __user *)arg,
-			get_blk_table_start_addr(),
-			get_blk_table_len()))
-			return -EFAULT;
-		return 0;
-
-	case GLOB_SBD_IOCTL_COPY_WEAR_LEVELING_TABLE:
-		nand_dbg_print(NAND_DBG_DEBUG, "Spectra IOCTL: "
-			       "Copy wear leveling table\n");
-		if (copy_to_user((void __user *)arg,
-			get_wear_leveling_table_start_addr(),
-			get_wear_leveling_table_len()))
-			return -EFAULT;
-		return 0;
-
-	case GLOB_SBD_IOCTL_GET_NAND_INFO:
-		nand_dbg_print(NAND_DBG_DEBUG, "Spectra IOCTL: "
-			       "Get NAND info\n");
-		if (copy_to_user((void __user *)arg, &IdentifyDeviceData,
-			sizeof(IdentifyDeviceData)))
-			return -EFAULT;
-		return 0;
-
-	case GLOB_SBD_IOCTL_WRITE_DATA:
-		nand_dbg_print(NAND_DBG_DEBUG, "Spectra IOCTL: "
-			       "Write one page data\n");
-		return ioctl_write_page_data(arg);
-
-	case GLOB_SBD_IOCTL_READ_DATA:
-		nand_dbg_print(NAND_DBG_DEBUG, "Spectra IOCTL: "
-			       "Read one page data\n");
-		return ioctl_read_page_data(arg);
-	}
-
-	return -ENOTTY;
-}
-
-static DEFINE_MUTEX(ffsport_mutex);
-
-int GLOB_SBD_unlocked_ioctl(struct block_device *bdev, fmode_t mode,
-		unsigned int cmd, unsigned long arg)
-{
-	int ret;
-
-	mutex_lock(&ffsport_mutex);
-	ret = GLOB_SBD_ioctl(bdev, mode, cmd, arg);
-	mutex_unlock(&ffsport_mutex);
-
-	return ret;
-}
-
-static struct block_device_operations GLOB_SBD_ops = {
-	.owner = THIS_MODULE,
-	.open = GLOB_SBD_open,
-	.release = GLOB_SBD_release,
-	.ioctl = GLOB_SBD_unlocked_ioctl,
-	.getgeo = GLOB_SBD_getgeo,
-};
-
-static int SBD_setup_device(struct spectra_nand_dev *dev, int which)
-{
-	int res_blks;
-	u32 sects;
-
-	nand_dbg_print(NAND_DBG_TRACE, "%s, Line %d, Function: %s\n",
-		       __FILE__, __LINE__, __func__);
-
-	memset(dev, 0, sizeof(struct spectra_nand_dev));
-
-	nand_dbg_print(NAND_DBG_WARN, "Reserved %d blocks "
-		"for OS image, %d blocks for bad block replacement.\n",
-		get_res_blk_num_os(),
-		get_res_blk_num_bad_blk());
-
-	res_blks = get_res_blk_num_bad_blk() + get_res_blk_num_os();
-
-	dev->size = (u64)IdentifyDeviceData.PageDataSize *
-		IdentifyDeviceData.PagesPerBlock *
-		(IdentifyDeviceData.wDataBlockNum - res_blks);
-
-	res_blks_os = get_res_blk_num_os();
-
-	spin_lock_init(&dev->qlock);
-
-	dev->tmp_buf = kmalloc(IdentifyDeviceData.PageDataSize, GFP_ATOMIC);
-	if (!dev->tmp_buf) {
-		printk(KERN_ERR "Failed to kmalloc memory in %s Line %d, exit.\n",
-			__FILE__, __LINE__);
-		goto out_vfree;
-	}
-
-	dev->queue = blk_init_queue(GLOB_SBD_request, &dev->qlock);
-	if (dev->queue == NULL) {
-		printk(KERN_ERR
-		       "Spectra: Request queue could not be initialized."
-			" Aborting\n ");
-		goto out_vfree;
-	}
-	dev->queue->queuedata = dev;
-
-	/* As Linux block layer doesn't support >4KB hardware sector,  */
-	/* Here we force report 512 byte hardware sector size to Kernel */
-	blk_queue_logical_block_size(dev->queue, 512);
-
-	blk_queue_flush(dev->queue, REQ_FLUSH);
-
-	dev->thread = kthread_run(spectra_trans_thread, dev, "nand_thd");
-	if (IS_ERR(dev->thread)) {
-		blk_cleanup_queue(dev->queue);
-		unregister_blkdev(GLOB_SBD_majornum, GLOB_SBD_NAME);
-		return PTR_ERR(dev->thread);
-	}
-
-	dev->gd = alloc_disk(PARTITIONS);
-	if (!dev->gd) {
-		printk(KERN_ERR
-		       "Spectra: Could not allocate disk. Aborting \n ");
-		goto out_vfree;
-	}
-	dev->gd->major = GLOB_SBD_majornum;
-	dev->gd->first_minor = which * PARTITIONS;
-	dev->gd->fops = &GLOB_SBD_ops;
-	dev->gd->queue = dev->queue;
-	dev->gd->private_data = dev;
-	snprintf(dev->gd->disk_name, 32, "%s%c", GLOB_SBD_NAME, which + 'a');
-
-	sects = dev->size >> 9;
-	nand_dbg_print(NAND_DBG_WARN, "Capacity sects: %d\n", sects);
-	set_capacity(dev->gd, sects);
-
-	add_disk(dev->gd);
-
-	return 0;
-out_vfree:
-	return -ENOMEM;
-}
-
-/*
-static ssize_t show_nand_block_num(struct device *dev,
-	struct device_attribute *attr, char *buf)
-{
-	return snprintf(buf, PAGE_SIZE, "%d\n",
-		(int)IdentifyDeviceData.wDataBlockNum);
-}
-
-static ssize_t show_nand_pages_per_block(struct device *dev,
-	struct device_attribute *attr, char *buf)
-{
-	return snprintf(buf, PAGE_SIZE, "%d\n",
-		(int)IdentifyDeviceData.PagesPerBlock);
-}
-
-static ssize_t show_nand_page_size(struct device *dev,
-	struct device_attribute *attr, char *buf)
-{
-	return snprintf(buf, PAGE_SIZE, "%d\n",
-		(int)IdentifyDeviceData.PageDataSize);
-}
-
-static DEVICE_ATTR(nand_block_num, 0444, show_nand_block_num, NULL);
-static DEVICE_ATTR(nand_pages_per_block, 0444, show_nand_pages_per_block, NULL);
-static DEVICE_ATTR(nand_page_size, 0444, show_nand_page_size, NULL);
-
-static void create_sysfs_entry(struct device *dev)
-{
-	if (device_create_file(dev, &dev_attr_nand_block_num))
-		printk(KERN_ERR "Spectra: "
-			"failed to create sysfs entry nand_block_num.\n");
-	if (device_create_file(dev, &dev_attr_nand_pages_per_block))
-		printk(KERN_ERR "Spectra: "
-		"failed to create sysfs entry nand_pages_per_block.\n");
-	if (device_create_file(dev, &dev_attr_nand_page_size))
-		printk(KERN_ERR "Spectra: "
-		"failed to create sysfs entry nand_page_size.\n");
-}
-*/
-
-static void register_spectra_ftl_async(void *unused, async_cookie_t cookie)
-{
-	int i;
-
-	/* create_sysfs_entry(&dev->dev); */
-
-	if (PASS != GLOB_FTL_IdentifyDevice(&IdentifyDeviceData)) {
-		printk(KERN_ERR "Spectra: Unable to Read Flash Device. "
-		       "Aborting\n");
-		return;
-	} else {
-		nand_dbg_print(NAND_DBG_WARN, "In GLOB_SBD_init: "
-			       "Num blocks=%d, pagesperblock=%d, "
-			       "pagedatasize=%d, ECCBytesPerSector=%d\n",
-		       (int)IdentifyDeviceData.NumBlocks,
-		       (int)IdentifyDeviceData.PagesPerBlock,
-		       (int)IdentifyDeviceData.PageDataSize,
-		       (int)IdentifyDeviceData.wECCBytesPerSector);
-	}
-
-	printk(KERN_ALERT "Spectra: searching block table, please wait ...\n");
-	if (GLOB_FTL_Init() != PASS) {
-		printk(KERN_ERR "Spectra: Unable to Initialize FTL Layer. "
-		       "Aborting\n");
-		goto out_ftl_flash_register;
-	}
-	printk(KERN_ALERT "Spectra: block table has been found.\n");
-
-	GLOB_SBD_majornum = register_blkdev(0, GLOB_SBD_NAME);
-	if (GLOB_SBD_majornum <= 0) {
-		printk(KERN_ERR "Unable to get the major %d for Spectra",
-		       GLOB_SBD_majornum);
-		goto out_ftl_flash_register;
-	}
-
-	for (i = 0; i < NUM_DEVICES; i++)
-		if (SBD_setup_device(&nand_device[i], i) == -ENOMEM)
-			goto out_blk_register;
-
-	nand_dbg_print(NAND_DBG_DEBUG,
-		       "Spectra: module loaded with major number %d\n",
-		       GLOB_SBD_majornum);
-
-	return;
-
-out_blk_register:
-	unregister_blkdev(GLOB_SBD_majornum, GLOB_SBD_NAME);
-out_ftl_flash_register:
-	GLOB_FTL_Cache_Release();
-	printk(KERN_ERR "Spectra: Module load failed.\n");
-}
-
-int register_spectra_ftl()
-{
-	async_schedule(register_spectra_ftl_async, NULL);
-	return 0;
-}
-EXPORT_SYMBOL_GPL(register_spectra_ftl);
-
-static int GLOB_SBD_init(void)
-{
-	/* Set debug output level (0~3) here. 3 is most verbose */
-	printk(KERN_ALERT "Spectra: %s\n", GLOB_version);
-
-	mutex_init(&spectra_lock);
-
-	if (PASS != GLOB_FTL_Flash_Init()) {
-		printk(KERN_ERR "Spectra: Unable to Initialize Flash Device. "
-		       "Aborting\n");
-		return -ENODEV;
-	}
-	return 0;
-}
-
-static void __exit GLOB_SBD_exit(void)
-{
-	int i;
-
-	nand_dbg_print(NAND_DBG_TRACE, "%s, Line %d, Function: %s\n",
-		       __FILE__, __LINE__, __func__);
-
-	for (i = 0; i < NUM_DEVICES; i++) {
-		struct spectra_nand_dev *dev = &nand_device[i];
-		if (dev->gd) {
-			del_gendisk(dev->gd);
-			put_disk(dev->gd);
-		}
-		if (dev->queue)
-			blk_cleanup_queue(dev->queue);
-		kfree(dev->tmp_buf);
-	}
-
-	unregister_blkdev(GLOB_SBD_majornum, GLOB_SBD_NAME);
-
-	mutex_lock(&spectra_lock);
-	force_flush_cache();
-	mutex_unlock(&spectra_lock);
-
-	GLOB_FTL_Cache_Release();
-
-	GLOB_FTL_Flash_Release();
-
-	nand_dbg_print(NAND_DBG_DEBUG,
-		       "Spectra FTL module (major number %d) unloaded.\n",
-		       GLOB_SBD_majornum);
-}
-
-module_init(GLOB_SBD_init);
-module_exit(GLOB_SBD_exit);
diff --git a/drivers/staging/spectra/ffsport.h b/drivers/staging/spectra/ffsport.h
deleted file mode 100644
index 85c0750..0000000
--- a/drivers/staging/spectra/ffsport.h
+++ /dev/null
@@ -1,85 +0,0 @@
-/*
- * NAND Flash Controller Device Driver
- * Copyright (c) 2009, Intel Corporation and its suppliers.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms and conditions of the GNU General Public License,
- * version 2, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
- *
- */
-
-#ifndef _FFSPORT_
-#define _FFSPORT_
-
-#include "ffsdefs.h"
-
-#if defined __GNUC__
-#define PACKED
-#define PACKED_GNU __attribute__ ((packed))
-#define UNALIGNED
-#endif
-
-#include <linux/semaphore.h>
-#include <linux/string.h>	/* for strcpy(), stricmp(), etc */
-#include <linux/mm.h>		/* for kmalloc(), kfree() */
-#include <linux/vmalloc.h>
-#include <linux/module.h>
-#include <linux/moduleparam.h>
-#include <linux/init.h>
-
-#include <linux/kernel.h>	/* printk() */
-#include <linux/fs.h>		/* everything... */
-#include <linux/errno.h>	/* error codes */
-#include <linux/types.h>	/* size_t */
-#include <linux/genhd.h>
-#include <linux/blkdev.h>
-#include <linux/hdreg.h>
-#include <linux/pci.h>
-#include "flash.h"
-
-#define VERBOSE    1
-
-#define NAND_DBG_WARN  1
-#define NAND_DBG_DEBUG 2
-#define NAND_DBG_TRACE 3
-
-extern int nand_debug_level;
-
-#ifdef VERBOSE
-#define nand_dbg_print(level, args...)			\
-	do {						\
-		if (level <= nand_debug_level)		\
-			printk(KERN_ALERT args);	\
-	} while (0)
-#else
-#define nand_dbg_print(level, args...)
-#endif
-
-#ifdef SUPPORT_BIG_ENDIAN
-#define INVERTUINT16(w)   ((u16)(((u16)(w)) << 8) | \
-			   (u16)((u16)(w) >> 8))
-
-#define INVERTUINT32(dw)  (((u32)(dw) << 24) | \
-			   (((u32)(dw) << 8) & 0x00ff0000) | \
-			   (((u32)(dw) >> 8) & 0x0000ff00) | \
-			   ((u32)(dw) >> 24))
-#else
-#define INVERTUINT16(w)   w
-#define INVERTUINT32(dw)  dw
-#endif
-
-extern int GLOB_Calc_Used_Bits(u32 n);
-extern u64 GLOB_u64_Div(u64 addr, u32 divisor);
-extern u64 GLOB_u64_Remainder(u64 addr, u32 divisor_type);
-extern int register_spectra_ftl(void);
-
-#endif /* _FFSPORT_ */
diff --git a/drivers/staging/spectra/flash.c b/drivers/staging/spectra/flash.c
deleted file mode 100644
index aead358..0000000
--- a/drivers/staging/spectra/flash.c
+++ /dev/null
@@ -1,4305 +0,0 @@
-/*
- * NAND Flash Controller Device Driver
- * Copyright (c) 2009, Intel Corporation and its suppliers.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms and conditions of the GNU General Public License,
- * version 2, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
- *
- */
-
-#include <linux/fs.h>
-#include <linux/slab.h>
-
-#include "flash.h"
-#include "ffsdefs.h"
-#include "lld.h"
-#include "lld_nand.h"
-#if CMD_DMA
-#include "lld_cdma.h"
-#endif
-
-#define BLK_FROM_ADDR(addr)  ((u32)(addr >> DeviceInfo.nBitsInBlockDataSize))
-#define PAGE_FROM_ADDR(addr, Block)  ((u16)((addr - (u64)Block * \
-	DeviceInfo.wBlockDataSize) >> DeviceInfo.nBitsInPageDataSize))
-
-#define IS_SPARE_BLOCK(blk)     (BAD_BLOCK != (pbt[blk] &\
-	BAD_BLOCK) && SPARE_BLOCK == (pbt[blk] & SPARE_BLOCK))
-
-#define IS_DATA_BLOCK(blk)      (0 == (pbt[blk] & BAD_BLOCK))
-
-#define IS_DISCARDED_BLOCK(blk) (BAD_BLOCK != (pbt[blk] &\
-	BAD_BLOCK) && DISCARD_BLOCK == (pbt[blk] & DISCARD_BLOCK))
-
-#define IS_BAD_BLOCK(blk)       (BAD_BLOCK == (pbt[blk] & BAD_BLOCK))
-
-#if DEBUG_BNDRY
-void debug_boundary_lineno_error(int chnl, int limit, int no,
-				int lineno, char *filename)
-{
-	if (chnl >= limit)
-		printk(KERN_ERR "Boundary Check Fail value %d >= limit %d, "
-		"at  %s:%d. Other info:%d. Aborting...\n",
-		chnl, limit, filename, lineno, no);
-}
-/* static int globalmemsize; */
-#endif
-
-static u16 FTL_Cache_If_Hit(u64 dwPageAddr);
-static int FTL_Cache_Read(u64 dwPageAddr);
-static void FTL_Cache_Read_Page(u8 *pData, u64 dwPageAddr,
-				u16 cache_blk);
-static void FTL_Cache_Write_Page(u8 *pData, u64 dwPageAddr,
-				 u8 cache_blk, u16 flag);
-static int FTL_Cache_Write(void);
-static void FTL_Calculate_LRU(void);
-static u32 FTL_Get_Block_Index(u32 wBlockNum);
-
-static int FTL_Search_Block_Table_IN_Block(u32 BT_Block,
-					   u8 BT_Tag, u16 *Page);
-static int FTL_Read_Block_Table(void);
-static int FTL_Write_Block_Table(int wForce);
-static int FTL_Write_Block_Table_Data(void);
-static int FTL_Check_Block_Table(int wOldTable);
-static int FTL_Static_Wear_Leveling(void);
-static u32 FTL_Replace_Block_Table(void);
-static int FTL_Write_IN_Progress_Block_Table_Page(void);
-
-static u32 FTL_Get_Page_Num(u64 length);
-static u64 FTL_Get_Physical_Block_Addr(u64 blk_addr);
-
-static u32 FTL_Replace_OneBlock(u32 wBlockNum,
-				      u32 wReplaceNum);
-static u32 FTL_Replace_LWBlock(u32 wBlockNum,
-				     int *pGarbageCollect);
-static u32 FTL_Replace_MWBlock(void);
-static int FTL_Replace_Block(u64 blk_addr);
-static int FTL_Adjust_Relative_Erase_Count(u32 Index_of_MAX);
-
-struct device_info_tag DeviceInfo;
-struct flash_cache_tag Cache;
-static struct spectra_l2_cache_info cache_l2;
-
-static u8 *cache_l2_page_buf;
-static u8 *cache_l2_blk_buf;
-
-u8 *g_pBlockTable;
-u8 *g_pWearCounter;
-u16 *g_pReadCounter;
-u32 *g_pBTBlocks;
-static u16 g_wBlockTableOffset;
-static u32 g_wBlockTableIndex;
-static u8 g_cBlockTableStatus;
-
-static u8 *g_pTempBuf;
-static u8 *flag_check_blk_table;
-static u8 *tmp_buf_search_bt_in_block;
-static u8 *spare_buf_search_bt_in_block;
-static u8 *spare_buf_bt_search_bt_in_block;
-static u8 *tmp_buf1_read_blk_table;
-static u8 *tmp_buf2_read_blk_table;
-static u8 *flags_static_wear_leveling;
-static u8 *tmp_buf_write_blk_table_data;
-static u8 *tmp_buf_read_disturbance;
-
-u8 *buf_read_page_main_spare;
-u8 *buf_write_page_main_spare;
-u8 *buf_read_page_spare;
-u8 *buf_get_bad_block;
-
-#if (RESTORE_CACHE_ON_CDMA_CHAIN_FAILURE && CMD_DMA)
-struct flash_cache_delta_list_tag int_cache[MAX_CHANS + MAX_DESCS];
-struct flash_cache_tag cache_start_copy;
-#endif
-
-int g_wNumFreeBlocks;
-u8 g_SBDCmdIndex;
-
-static u8 *g_pIPF;
-static u8 bt_flag = FIRST_BT_ID;
-static u8 bt_block_changed;
-
-static u16 cache_block_to_write;
-static u8 last_erased = FIRST_BT_ID;
-
-static u8 GC_Called;
-static u8 BT_GC_Called;
-
-#if CMD_DMA
-#define COPY_BACK_BUF_NUM 10
-
-static u8 ftl_cmd_cnt;  /* Init value is 0 */
-u8 *g_pBTDelta;
-u8 *g_pBTDelta_Free;
-u8 *g_pBTStartingCopy;
-u8 *g_pWearCounterCopy;
-u16 *g_pReadCounterCopy;
-u8 *g_pBlockTableCopies;
-u8 *g_pNextBlockTable;
-static u8 *cp_back_buf_copies[COPY_BACK_BUF_NUM];
-static int cp_back_buf_idx;
-
-static u8 *g_temp_buf;
-
-#pragma pack(push, 1)
-#pragma pack(1)
-struct BTableChangesDelta {
-	u8 ftl_cmd_cnt;
-	u8 ValidFields;
-	u16 g_wBlockTableOffset;
-	u32 g_wBlockTableIndex;
-	u32 BT_Index;
-	u32 BT_Entry_Value;
-	u32 WC_Index;
-	u8 WC_Entry_Value;
-	u32 RC_Index;
-	u16 RC_Entry_Value;
-};
-
-#pragma pack(pop)
-
-struct BTableChangesDelta *p_BTableChangesDelta;
-#endif
-
-
-#define MARK_BLOCK_AS_BAD(blocknode)      (blocknode |= BAD_BLOCK)
-#define MARK_BLK_AS_DISCARD(blk)  (blk = (blk & ~SPARE_BLOCK) | DISCARD_BLOCK)
-
-#define FTL_Get_LBAPBA_Table_Mem_Size_Bytes() (DeviceInfo.wDataBlockNum *\
-						sizeof(u32))
-#define FTL_Get_WearCounter_Table_Mem_Size_Bytes() (DeviceInfo.wDataBlockNum *\
-						sizeof(u8))
-#define FTL_Get_ReadCounter_Table_Mem_Size_Bytes() (DeviceInfo.wDataBlockNum *\
-						sizeof(u16))
-#if SUPPORT_LARGE_BLOCKNUM
-#define FTL_Get_LBAPBA_Table_Flash_Size_Bytes() (DeviceInfo.wDataBlockNum *\
-						sizeof(u8) * 3)
-#else
-#define FTL_Get_LBAPBA_Table_Flash_Size_Bytes() (DeviceInfo.wDataBlockNum *\
-						sizeof(u16))
-#endif
-#define FTL_Get_WearCounter_Table_Flash_Size_Bytes \
-	FTL_Get_WearCounter_Table_Mem_Size_Bytes
-#define FTL_Get_ReadCounter_Table_Flash_Size_Bytes \
-	FTL_Get_ReadCounter_Table_Mem_Size_Bytes
-
-static u32 FTL_Get_Block_Table_Flash_Size_Bytes(void)
-{
-	u32 byte_num;
-
-	if (DeviceInfo.MLCDevice) {
-		byte_num = FTL_Get_LBAPBA_Table_Flash_Size_Bytes() +
-			DeviceInfo.wDataBlockNum * sizeof(u8) +
-			DeviceInfo.wDataBlockNum * sizeof(u16);
-	} else {
-		byte_num = FTL_Get_LBAPBA_Table_Flash_Size_Bytes() +
-			DeviceInfo.wDataBlockNum * sizeof(u8);
-	}
-
-	byte_num += 4 * sizeof(u8);
-
-	return byte_num;
-}
-
-static u16  FTL_Get_Block_Table_Flash_Size_Pages(void)
-{
-	return (u16)FTL_Get_Page_Num(FTL_Get_Block_Table_Flash_Size_Bytes());
-}
-
-static int FTL_Copy_Block_Table_To_Flash(u8 *flashBuf, u32 sizeToTx,
-					u32 sizeTxed)
-{
-	u32 wBytesCopied, blk_tbl_size, wBytes;
-	u32 *pbt = (u32 *)g_pBlockTable;
-
-	blk_tbl_size = FTL_Get_LBAPBA_Table_Flash_Size_Bytes();
-	for (wBytes = 0;
-	(wBytes < sizeToTx) && ((wBytes + sizeTxed) < blk_tbl_size);
-	wBytes++) {
-#if SUPPORT_LARGE_BLOCKNUM
-		flashBuf[wBytes] = (u8)(pbt[(wBytes + sizeTxed) / 3]
-		>> (((wBytes + sizeTxed) % 3) ?
-		((((wBytes + sizeTxed) % 3) == 2) ? 0 : 8) : 16)) & 0xFF;
-#else
-		flashBuf[wBytes] = (u8)(pbt[(wBytes + sizeTxed) / 2]
-		>> (((wBytes + sizeTxed) % 2) ? 0 : 8)) & 0xFF;
-#endif
-	}
-
-	sizeTxed = (sizeTxed > blk_tbl_size) ? (sizeTxed - blk_tbl_size) : 0;
-	blk_tbl_size = FTL_Get_WearCounter_Table_Flash_Size_Bytes();
-	wBytesCopied = wBytes;
-	wBytes = ((blk_tbl_size - sizeTxed) > (sizeToTx - wBytesCopied)) ?
-		(sizeToTx - wBytesCopied) : (blk_tbl_size - sizeTxed);
-	memcpy(flashBuf + wBytesCopied, g_pWearCounter + sizeTxed, wBytes);
-
-	sizeTxed = (sizeTxed > blk_tbl_size) ? (sizeTxed - blk_tbl_size) : 0;
-
-	if (DeviceInfo.MLCDevice) {
-		blk_tbl_size = FTL_Get_ReadCounter_Table_Flash_Size_Bytes();
-		wBytesCopied += wBytes;
-		for (wBytes = 0; ((wBytes + wBytesCopied) < sizeToTx) &&
-			((wBytes + sizeTxed) < blk_tbl_size); wBytes++)
-			flashBuf[wBytes + wBytesCopied] =
-			(g_pReadCounter[(wBytes + sizeTxed) / 2] >>
-			(((wBytes + sizeTxed) % 2) ? 0 : 8)) & 0xFF;
-	}
-
-	return wBytesCopied + wBytes;
-}
-
-static int FTL_Copy_Block_Table_From_Flash(u8 *flashBuf,
-				u32 sizeToTx, u32 sizeTxed)
-{
-	u32 wBytesCopied, blk_tbl_size, wBytes;
-	u32 *pbt = (u32 *)g_pBlockTable;
-
-	blk_tbl_size = FTL_Get_LBAPBA_Table_Flash_Size_Bytes();
-	for (wBytes = 0; (wBytes < sizeToTx) &&
-		((wBytes + sizeTxed) < blk_tbl_size); wBytes++) {
-#if SUPPORT_LARGE_BLOCKNUM
-		if (!((wBytes + sizeTxed) % 3))
-			pbt[(wBytes + sizeTxed) / 3] = 0;
-		pbt[(wBytes + sizeTxed) / 3] |=
-			(flashBuf[wBytes] << (((wBytes + sizeTxed) % 3) ?
-			((((wBytes + sizeTxed) % 3) == 2) ? 0 : 8) : 16));
-#else
-		if (!((wBytes + sizeTxed) % 2))
-			pbt[(wBytes + sizeTxed) / 2] = 0;
-		pbt[(wBytes + sizeTxed) / 2] |=
-			(flashBuf[wBytes] << (((wBytes + sizeTxed) % 2) ?
-			0 : 8));
-#endif
-	}
-
-	sizeTxed = (sizeTxed > blk_tbl_size) ? (sizeTxed - blk_tbl_size) : 0;
-	blk_tbl_size = FTL_Get_WearCounter_Table_Flash_Size_Bytes();
-	wBytesCopied = wBytes;
-	wBytes = ((blk_tbl_size - sizeTxed) > (sizeToTx - wBytesCopied)) ?
-		(sizeToTx - wBytesCopied) : (blk_tbl_size - sizeTxed);
-	memcpy(g_pWearCounter + sizeTxed, flashBuf + wBytesCopied, wBytes);
-	sizeTxed = (sizeTxed > blk_tbl_size) ? (sizeTxed - blk_tbl_size) : 0;
-
-	if (DeviceInfo.MLCDevice) {
-		wBytesCopied += wBytes;
-		blk_tbl_size = FTL_Get_ReadCounter_Table_Flash_Size_Bytes();
-		for (wBytes = 0; ((wBytes + wBytesCopied) < sizeToTx) &&
-			((wBytes + sizeTxed) < blk_tbl_size); wBytes++) {
-			if (((wBytes + sizeTxed) % 2))
-				g_pReadCounter[(wBytes + sizeTxed) / 2] = 0;
-			g_pReadCounter[(wBytes + sizeTxed) / 2] |=
-				(flashBuf[wBytes] <<
-				(((wBytes + sizeTxed) % 2) ? 0 : 8));
-		}
-	}
-
-	return wBytesCopied+wBytes;
-}
-
-static int FTL_Insert_Block_Table_Signature(u8 *buf, u8 tag)
-{
-	int i;
-
-	for (i = 0; i < BTSIG_BYTES; i++)
-		buf[BTSIG_OFFSET + i] =
-		((tag + (i * BTSIG_DELTA) - FIRST_BT_ID) %
-		(1 + LAST_BT_ID-FIRST_BT_ID)) + FIRST_BT_ID;
-
-	return PASS;
-}
-
-static int FTL_Extract_Block_Table_Tag(u8 *buf, u8 **tagarray)
-{
-	static u8 tag[BTSIG_BYTES >> 1];
-	int i, j, k, tagi, tagtemp, status;
-
-	*tagarray = (u8 *)tag;
-	tagi = 0;
-
-	for (i = 0; i < (BTSIG_BYTES - 1); i++) {
-		for (j = i + 1; (j < BTSIG_BYTES) &&
-			(tagi < (BTSIG_BYTES >> 1)); j++) {
-			tagtemp = buf[BTSIG_OFFSET + j] -
-				buf[BTSIG_OFFSET + i];
-			if (tagtemp && !(tagtemp % BTSIG_DELTA)) {
-				tagtemp = (buf[BTSIG_OFFSET + i] +
-					(1 + LAST_BT_ID - FIRST_BT_ID) -
-					(i * BTSIG_DELTA)) %
-					(1 + LAST_BT_ID - FIRST_BT_ID);
-				status = FAIL;
-				for (k = 0; k < tagi; k++) {
-					if (tagtemp == tag[k])
-						status = PASS;
-				}
-
-				if (status == FAIL) {
-					tag[tagi++] = tagtemp;
-					i = (j == (i + 1)) ? i + 1 : i;
-					j = (j == (i + 1)) ? i + 1 : i;
-				}
-			}
-		}
-	}
-
-	return tagi;
-}
-
-
-static int FTL_Execute_SPL_Recovery(void)
-{
-	u32 j, block, blks;
-	u32 *pbt = (u32 *)g_pBlockTable;
-	int ret;
-
-	nand_dbg_print(NAND_DBG_TRACE, "%s, Line %d, Function: %s\n",
-				__FILE__, __LINE__, __func__);
-
-	blks = DeviceInfo.wSpectraEndBlock - DeviceInfo.wSpectraStartBlock;
-	for (j = 0; j <= blks; j++) {
-		block = (pbt[j]);
-		if (((block & BAD_BLOCK) != BAD_BLOCK) &&
-			((block & SPARE_BLOCK) == SPARE_BLOCK)) {
-			ret =  GLOB_LLD_Erase_Block(block & ~BAD_BLOCK);
-			if (FAIL == ret) {
-				nand_dbg_print(NAND_DBG_WARN,
-					"NAND Program fail in %s, Line %d, "
-					"Function: %s, new Bad Block %d "
-					"generated!\n",
-					__FILE__, __LINE__, __func__,
-					(int)(block & ~BAD_BLOCK));
-				MARK_BLOCK_AS_BAD(pbt[j]);
-			}
-		}
-	}
-
-	return PASS;
-}
-
-/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
-* Function:     GLOB_FTL_IdentifyDevice
-* Inputs:       pointer to identify data structure
-* Outputs:      PASS / FAIL
-* Description:  the identify data structure is filled in with
-*                   information for the block driver.
-*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
-int GLOB_FTL_IdentifyDevice(struct spectra_indentfy_dev_tag *dev_data)
-{
-	nand_dbg_print(NAND_DBG_TRACE, "%s, Line %d, Function: %s\n",
-				__FILE__, __LINE__, __func__);
-
-	dev_data->NumBlocks = DeviceInfo.wTotalBlocks;
-	dev_data->PagesPerBlock = DeviceInfo.wPagesPerBlock;
-	dev_data->PageDataSize = DeviceInfo.wPageDataSize;
-	dev_data->wECCBytesPerSector = DeviceInfo.wECCBytesPerSector;
-	dev_data->wDataBlockNum = DeviceInfo.wDataBlockNum;
-
-	return PASS;
-}
-
-/* ..... */
-static int allocate_memory(void)
-{
-	u32 block_table_size, page_size, block_size, mem_size;
-	u32 total_bytes = 0;
-	int i;
-#if CMD_DMA
-	int j;
-#endif
-
-	nand_dbg_print(NAND_DBG_TRACE, "%s, Line %d, Function: %s\n",
-		__FILE__, __LINE__, __func__);
-
-	page_size = DeviceInfo.wPageSize;
-	block_size = DeviceInfo.wPagesPerBlock * DeviceInfo.wPageDataSize;
-
-	block_table_size = DeviceInfo.wDataBlockNum *
-		(sizeof(u32) + sizeof(u8) + sizeof(u16));
-	block_table_size += (DeviceInfo.wPageDataSize -
-		(block_table_size % DeviceInfo.wPageDataSize)) %
-		DeviceInfo.wPageDataSize;
-
-	/* Malloc memory for block tables */
-	g_pBlockTable = kzalloc(block_table_size, GFP_ATOMIC);
-	if (!g_pBlockTable)
-		goto block_table_fail;
-	total_bytes += block_table_size;
-
-	g_pWearCounter = (u8 *)(g_pBlockTable +
-		DeviceInfo.wDataBlockNum * sizeof(u32));
-
-	if (DeviceInfo.MLCDevice)
-		g_pReadCounter = (u16 *)(g_pBlockTable +
-			DeviceInfo.wDataBlockNum *
-			(sizeof(u32) + sizeof(u8)));
-
-	/* Malloc memory and init for cache items */
-	for (i = 0; i < CACHE_ITEM_NUM; i++) {
-		Cache.array[i].address = NAND_CACHE_INIT_ADDR;
-		Cache.array[i].use_cnt = 0;
-		Cache.array[i].changed = CLEAR;
-		Cache.array[i].buf = kzalloc(Cache.cache_item_size,
-					     GFP_ATOMIC);
-		if (!Cache.array[i].buf)
-			goto cache_item_fail;
-		total_bytes += Cache.cache_item_size;
-	}
-
-	/* Malloc memory for IPF */
-	g_pIPF = kzalloc(page_size, GFP_ATOMIC);
-	if (!g_pIPF)
-		goto ipf_fail;
-	total_bytes += page_size;
-
-	/* Malloc memory for data merging during Level2 Cache flush */
-	cache_l2_page_buf = kmalloc(page_size, GFP_ATOMIC);
-	if (!cache_l2_page_buf)
-		goto cache_l2_page_buf_fail;
-	memset(cache_l2_page_buf, 0xff, page_size);
-	total_bytes += page_size;
-
-	cache_l2_blk_buf = kmalloc(block_size, GFP_ATOMIC);
-	if (!cache_l2_blk_buf)
-		goto cache_l2_blk_buf_fail;
-	memset(cache_l2_blk_buf, 0xff, block_size);
-	total_bytes += block_size;
-
-	/* Malloc memory for temp buffer */
-	g_pTempBuf = kzalloc(Cache.cache_item_size, GFP_ATOMIC);
-	if (!g_pTempBuf)
-		goto Temp_buf_fail;
-	total_bytes += Cache.cache_item_size;
-
-	/* Malloc memory for block table blocks */
-	mem_size = (1 + LAST_BT_ID - FIRST_BT_ID) * sizeof(u32);
-	g_pBTBlocks = kmalloc(mem_size, GFP_ATOMIC);
-	if (!g_pBTBlocks)
-		goto bt_blocks_fail;
-	memset(g_pBTBlocks, 0xff, mem_size);
-	total_bytes += mem_size;
-
-	/* Malloc memory for function FTL_Check_Block_Table */
-	flag_check_blk_table = kmalloc(DeviceInfo.wDataBlockNum, GFP_ATOMIC);
-	if (!flag_check_blk_table)
-		goto flag_check_blk_table_fail;
-	total_bytes += DeviceInfo.wDataBlockNum;
-
-	/* Malloc memory for function FTL_Search_Block_Table_IN_Block */
-	tmp_buf_search_bt_in_block = kmalloc(page_size, GFP_ATOMIC);
-	if (!tmp_buf_search_bt_in_block)
-		goto tmp_buf_search_bt_in_block_fail;
-	memset(tmp_buf_search_bt_in_block, 0xff, page_size);
-	total_bytes += page_size;
-
-	mem_size = DeviceInfo.wPageSize - DeviceInfo.wPageDataSize;
-	spare_buf_search_bt_in_block = kmalloc(mem_size, GFP_ATOMIC);
-	if (!spare_buf_search_bt_in_block)
-		goto spare_buf_search_bt_in_block_fail;
-	memset(spare_buf_search_bt_in_block, 0xff, mem_size);
-	total_bytes += mem_size;
-
-	spare_buf_bt_search_bt_in_block = kmalloc(mem_size, GFP_ATOMIC);
-	if (!spare_buf_bt_search_bt_in_block)
-		goto spare_buf_bt_search_bt_in_block_fail;
-	memset(spare_buf_bt_search_bt_in_block, 0xff, mem_size);
-	total_bytes += mem_size;
-
-	/* Malloc memory for function FTL_Read_Block_Table */
-	tmp_buf1_read_blk_table = kmalloc(page_size, GFP_ATOMIC);
-	if (!tmp_buf1_read_blk_table)
-		goto tmp_buf1_read_blk_table_fail;
-	memset(tmp_buf1_read_blk_table, 0xff, page_size);
-	total_bytes += page_size;
-
-	tmp_buf2_read_blk_table = kmalloc(page_size, GFP_ATOMIC);
-	if (!tmp_buf2_read_blk_table)
-		goto tmp_buf2_read_blk_table_fail;
-	memset(tmp_buf2_read_blk_table, 0xff, page_size);
-	total_bytes += page_size;
-
-	/* Malloc memory for function FTL_Static_Wear_Leveling */
-	flags_static_wear_leveling = kmalloc(DeviceInfo.wDataBlockNum,
-					GFP_ATOMIC);
-	if (!flags_static_wear_leveling)
-		goto flags_static_wear_leveling_fail;
-	total_bytes += DeviceInfo.wDataBlockNum;
-
-	/* Malloc memory for function FTL_Write_Block_Table_Data */
-	if (FTL_Get_Block_Table_Flash_Size_Pages() > 3)
-		mem_size = FTL_Get_Block_Table_Flash_Size_Bytes() -
-				2 * DeviceInfo.wPageSize;
-	else
-		mem_size = DeviceInfo.wPageSize;
-	tmp_buf_write_blk_table_data = kmalloc(mem_size, GFP_ATOMIC);
-	if (!tmp_buf_write_blk_table_data)
-		goto tmp_buf_write_blk_table_data_fail;
-	memset(tmp_buf_write_blk_table_data, 0xff, mem_size);
-	total_bytes += mem_size;
-
-	/* Malloc memory for function FTL_Read_Disturbance */
-	tmp_buf_read_disturbance = kmalloc(block_size, GFP_ATOMIC);
-	if (!tmp_buf_read_disturbance)
-		goto tmp_buf_read_disturbance_fail;
-	memset(tmp_buf_read_disturbance, 0xff, block_size);
-	total_bytes += block_size;
-
-	/* Alloc mem for function NAND_Read_Page_Main_Spare of lld_nand.c */
-	buf_read_page_main_spare = kmalloc(DeviceInfo.wPageSize, GFP_ATOMIC);
-	if (!buf_read_page_main_spare)
-		goto buf_read_page_main_spare_fail;
-	total_bytes += DeviceInfo.wPageSize;
-
-	/* Alloc mem for function NAND_Write_Page_Main_Spare of lld_nand.c */
-	buf_write_page_main_spare = kmalloc(DeviceInfo.wPageSize, GFP_ATOMIC);
-	if (!buf_write_page_main_spare)
-		goto buf_write_page_main_spare_fail;
-	total_bytes += DeviceInfo.wPageSize;
-
-	/* Alloc mem for function NAND_Read_Page_Spare of lld_nand.c */
-	buf_read_page_spare = kmalloc(DeviceInfo.wPageSpareSize, GFP_ATOMIC);
-	if (!buf_read_page_spare)
-		goto buf_read_page_spare_fail;
-	memset(buf_read_page_spare, 0xff, DeviceInfo.wPageSpareSize);
-	total_bytes += DeviceInfo.wPageSpareSize;
-
-	/* Alloc mem for function NAND_Get_Bad_Block of lld_nand.c */
-	buf_get_bad_block = kmalloc(DeviceInfo.wPageSpareSize, GFP_ATOMIC);
-	if (!buf_get_bad_block)
-		goto buf_get_bad_block_fail;
-	memset(buf_get_bad_block, 0xff, DeviceInfo.wPageSpareSize);
-	total_bytes += DeviceInfo.wPageSpareSize;
-
-#if CMD_DMA
-	g_temp_buf = kmalloc(block_size, GFP_ATOMIC);
-	if (!g_temp_buf)
-		goto temp_buf_fail;
-	memset(g_temp_buf, 0xff, block_size);
-	total_bytes += block_size;
-
-	/* Malloc memory for copy of block table used in CDMA mode */
-	g_pBTStartingCopy = kzalloc(block_table_size, GFP_ATOMIC);
-	if (!g_pBTStartingCopy)
-		goto bt_starting_copy;
-	total_bytes += block_table_size;
-
-	g_pWearCounterCopy = (u8 *)(g_pBTStartingCopy +
-		DeviceInfo.wDataBlockNum * sizeof(u32));
-
-	if (DeviceInfo.MLCDevice)
-		g_pReadCounterCopy = (u16 *)(g_pBTStartingCopy +
-			DeviceInfo.wDataBlockNum *
-			(sizeof(u32) + sizeof(u8)));
-
-	/* Malloc memory for block table copies */
-	mem_size = 5 * DeviceInfo.wDataBlockNum * sizeof(u32) +
-			5 * DeviceInfo.wDataBlockNum * sizeof(u8);
-	if (DeviceInfo.MLCDevice)
-		mem_size += 5 * DeviceInfo.wDataBlockNum * sizeof(u16);
-	g_pBlockTableCopies = kzalloc(mem_size, GFP_ATOMIC);
-	if (!g_pBlockTableCopies)
-		goto blk_table_copies_fail;
-	total_bytes += mem_size;
-	g_pNextBlockTable = g_pBlockTableCopies;
-
-	/* Malloc memory for Block Table Delta */
-	mem_size = MAX_DESCS * sizeof(struct BTableChangesDelta);
-	g_pBTDelta = kzalloc(mem_size, GFP_ATOMIC);
-	if (!g_pBTDelta)
-		goto bt_delta_fail;
-	total_bytes += mem_size;
-	g_pBTDelta_Free = g_pBTDelta;
-
-	/* Malloc memory for Copy Back Buffers */
-	for (j = 0; j < COPY_BACK_BUF_NUM; j++) {
-		cp_back_buf_copies[j] = kzalloc(block_size, GFP_ATOMIC);
-		if (!cp_back_buf_copies[j])
-			goto cp_back_buf_copies_fail;
-		total_bytes += block_size;
-	}
-	cp_back_buf_idx = 0;
-
-	/* Malloc memory for pending commands list */
-	mem_size = sizeof(struct pending_cmd) * MAX_DESCS;
-	info.pcmds = kzalloc(mem_size, GFP_KERNEL);
-	if (!info.pcmds)
-		goto pending_cmds_buf_fail;
-	total_bytes += mem_size;
-
-	/* Malloc memory for CDMA descripter table */
-	mem_size = sizeof(struct cdma_descriptor) * MAX_DESCS;
-	info.cdma_desc_buf = kzalloc(mem_size, GFP_KERNEL);
-	if (!info.cdma_desc_buf)
-		goto cdma_desc_buf_fail;
-	total_bytes += mem_size;
-
-	/* Malloc memory for Memcpy descripter table */
-	mem_size = sizeof(struct memcpy_descriptor) * MAX_DESCS;
-	info.memcp_desc_buf = kzalloc(mem_size, GFP_KERNEL);
-	if (!info.memcp_desc_buf)
-		goto memcp_desc_buf_fail;
-	total_bytes += mem_size;
-#endif
-
-	nand_dbg_print(NAND_DBG_WARN,
-		"Total memory allocated in FTL layer: %d\n", total_bytes);
-
-	return PASS;
-
-#if CMD_DMA
-memcp_desc_buf_fail:
-	kfree(info.cdma_desc_buf);
-cdma_desc_buf_fail:
-	kfree(info.pcmds);
-pending_cmds_buf_fail:
-cp_back_buf_copies_fail:
-	j--;
-	for (; j >= 0; j--)
-		kfree(cp_back_buf_copies[j]);
-	kfree(g_pBTDelta);
-bt_delta_fail:
-	kfree(g_pBlockTableCopies);
-blk_table_copies_fail:
-	kfree(g_pBTStartingCopy);
-bt_starting_copy:
-	kfree(g_temp_buf);
-temp_buf_fail:
-	kfree(buf_get_bad_block);
-#endif
-
-buf_get_bad_block_fail:
-	kfree(buf_read_page_spare);
-buf_read_page_spare_fail:
-	kfree(buf_write_page_main_spare);
-buf_write_page_main_spare_fail:
-	kfree(buf_read_page_main_spare);
-buf_read_page_main_spare_fail:
-	kfree(tmp_buf_read_disturbance);
-tmp_buf_read_disturbance_fail:
-	kfree(tmp_buf_write_blk_table_data);
-tmp_buf_write_blk_table_data_fail:
-	kfree(flags_static_wear_leveling);
-flags_static_wear_leveling_fail:
-	kfree(tmp_buf2_read_blk_table);
-tmp_buf2_read_blk_table_fail:
-	kfree(tmp_buf1_read_blk_table);
-tmp_buf1_read_blk_table_fail:
-	kfree(spare_buf_bt_search_bt_in_block);
-spare_buf_bt_search_bt_in_block_fail:
-	kfree(spare_buf_search_bt_in_block);
-spare_buf_search_bt_in_block_fail:
-	kfree(tmp_buf_search_bt_in_block);
-tmp_buf_search_bt_in_block_fail:
-	kfree(flag_check_blk_table);
-flag_check_blk_table_fail:
-	kfree(g_pBTBlocks);
-bt_blocks_fail:
-	kfree(g_pTempBuf);
-Temp_buf_fail:
-	kfree(cache_l2_blk_buf);
-cache_l2_blk_buf_fail:
-	kfree(cache_l2_page_buf);
-cache_l2_page_buf_fail:
-	kfree(g_pIPF);
-ipf_fail:
-cache_item_fail:
-	i--;
-	for (; i >= 0; i--)
-		kfree(Cache.array[i].buf);
-	kfree(g_pBlockTable);
-block_table_fail:
-	printk(KERN_ERR "Failed to kmalloc memory in %s Line %d.\n",
-		__FILE__, __LINE__);
-
-	return -ENOMEM;
-}
-
-/* .... */
-static int free_memory(void)
-{
-	int i;
-
-#if CMD_DMA
-	kfree(info.memcp_desc_buf);
-	kfree(info.cdma_desc_buf);
-	kfree(info.pcmds);
-	for (i = COPY_BACK_BUF_NUM - 1; i >= 0; i--)
-		kfree(cp_back_buf_copies[i]);
-	kfree(g_pBTDelta);
-	kfree(g_pBlockTableCopies);
-	kfree(g_pBTStartingCopy);
-	kfree(g_temp_buf);
-	kfree(buf_get_bad_block);
-#endif
-	kfree(buf_read_page_spare);
-	kfree(buf_write_page_main_spare);
-	kfree(buf_read_page_main_spare);
-	kfree(tmp_buf_read_disturbance);
-	kfree(tmp_buf_write_blk_table_data);
-	kfree(flags_static_wear_leveling);
-	kfree(tmp_buf2_read_blk_table);
-	kfree(tmp_buf1_read_blk_table);
-	kfree(spare_buf_bt_search_bt_in_block);
-	kfree(spare_buf_search_bt_in_block);
-	kfree(tmp_buf_search_bt_in_block);
-	kfree(flag_check_blk_table);
-	kfree(g_pBTBlocks);
-	kfree(g_pTempBuf);
-	kfree(g_pIPF);
-	for (i = CACHE_ITEM_NUM - 1; i >= 0; i--)
-		kfree(Cache.array[i].buf);
-	kfree(g_pBlockTable);
-
-	return 0;
-}
-
-static void dump_cache_l2_table(void)
-{
-	struct list_head *p;
-	struct spectra_l2_cache_list *pnd;
-	int n;
-
-	n = 0;
-	list_for_each(p, &cache_l2.table.list) {
-		pnd = list_entry(p, struct spectra_l2_cache_list, list);
-		nand_dbg_print(NAND_DBG_WARN, "dump_cache_l2_table node: %d, logical_blk_num: %d\n", n, pnd->logical_blk_num);
-/*
-		for (i = 0; i < DeviceInfo.wPagesPerBlock; i++) {
-			if (pnd->pages_array[i] != MAX_U32_VALUE)
-				nand_dbg_print(NAND_DBG_WARN, "    pages_array[%d]: 0x%x\n", i, pnd->pages_array[i]);
-		}
-*/
-		n++;
-	}
-}
-
-/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
-* Function:     GLOB_FTL_Init
-* Inputs:       none
-* Outputs:      PASS=0 / FAIL=1
-* Description:  allocates the memory for cache array,
-*               important data structures
-*               clears the cache array
-*               reads the block table from flash into array
-*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
-int GLOB_FTL_Init(void)
-{
-	int i;
-
-	nand_dbg_print(NAND_DBG_TRACE, "%s, Line %d, Function: %s\n",
-		__FILE__, __LINE__, __func__);
-
-	Cache.pages_per_item = 1;
-	Cache.cache_item_size = 1 * DeviceInfo.wPageDataSize;
-
-	if (allocate_memory() != PASS)
-		return FAIL;
-
-#if CMD_DMA
-#if RESTORE_CACHE_ON_CDMA_CHAIN_FAILURE
-	memcpy((void *)&cache_start_copy, (void *)&Cache,
-		sizeof(struct flash_cache_tag));
-	memset((void *)&int_cache, -1,
-		sizeof(struct flash_cache_delta_list_tag) *
-		(MAX_CHANS + MAX_DESCS));
-#endif
-	ftl_cmd_cnt = 0;
-#endif
-
-	if (FTL_Read_Block_Table() != PASS)
-		return FAIL;
-
-	/* Init the Level2 Cache data structure */
-	for (i = 0; i < BLK_NUM_FOR_L2_CACHE; i++)
-		cache_l2.blk_array[i] = MAX_U32_VALUE;
-	cache_l2.cur_blk_idx = 0;
-	cache_l2.cur_page_num = 0;
-	INIT_LIST_HEAD(&cache_l2.table.list);
-	cache_l2.table.logical_blk_num = MAX_U32_VALUE;
-
-	dump_cache_l2_table();
-
-	return 0;
-}
-
-
-#if CMD_DMA
-#if 0
-static void save_blk_table_changes(u16 idx)
-{
-	u8 ftl_cmd;
-	u32 *pbt = (u32 *)g_pBTStartingCopy;
-
-#if RESTORE_CACHE_ON_CDMA_CHAIN_FAILURE
-	u16 id;
-	u8 cache_blks;
-
-	id = idx - MAX_CHANS;
-	if (int_cache[id].item != -1) {
-		cache_blks = int_cache[id].item;
-		cache_start_copy.array[cache_blks].address =
-			int_cache[id].cache.address;
-		cache_start_copy.array[cache_blks].changed =
-			int_cache[id].cache.changed;
-	}
-#endif
-
-	ftl_cmd = p_BTableChangesDelta->ftl_cmd_cnt;
-
-	while (ftl_cmd <= PendingCMD[idx].Tag) {
-		if (p_BTableChangesDelta->ValidFields == 0x01) {
-			g_wBlockTableOffset =
-				p_BTableChangesDelta->g_wBlockTableOffset;
-		} else if (p_BTableChangesDelta->ValidFields == 0x0C) {
-			pbt[p_BTableChangesDelta->BT_Index] =
-				p_BTableChangesDelta->BT_Entry_Value;
-			debug_boundary_error(((
-				p_BTableChangesDelta->BT_Index)),
-				DeviceInfo.wDataBlockNum, 0);
-		} else if (p_BTableChangesDelta->ValidFields == 0x03) {
-			g_wBlockTableOffset =
-				p_BTableChangesDelta->g_wBlockTableOffset;
-			g_wBlockTableIndex =
-				p_BTableChangesDelta->g_wBlockTableIndex;
-		} else if (p_BTableChangesDelta->ValidFields == 0x30) {
-			g_pWearCounterCopy[p_BTableChangesDelta->WC_Index] =
-				p_BTableChangesDelta->WC_Entry_Value;
-		} else if ((DeviceInfo.MLCDevice) &&
-			(p_BTableChangesDelta->ValidFields == 0xC0)) {
-			g_pReadCounterCopy[p_BTableChangesDelta->RC_Index] =
-				p_BTableChangesDelta->RC_Entry_Value;
-			nand_dbg_print(NAND_DBG_DEBUG,
-				"In event status setting read counter "
-				"GLOB_ftl_cmd_cnt %u Count %u Index %u\n",
-				ftl_cmd,
-				p_BTableChangesDelta->RC_Entry_Value,
-				(unsigned int)p_BTableChangesDelta->RC_Index);
-		} else {
-			nand_dbg_print(NAND_DBG_DEBUG,
-				"This should never occur \n");
-		}
-		p_BTableChangesDelta += 1;
-		ftl_cmd = p_BTableChangesDelta->ftl_cmd_cnt;
-	}
-}
-
-static void discard_cmds(u16 n)
-{
-	u32 *pbt = (u32 *)g_pBTStartingCopy;
-	u8 ftl_cmd;
-	unsigned long k;
-#if RESTORE_CACHE_ON_CDMA_CHAIN_FAILURE
-	u8 cache_blks;
-	u16 id;
-#endif
-
-	if ((PendingCMD[n].CMD == WRITE_MAIN_CMD) ||
-		(PendingCMD[n].CMD == WRITE_MAIN_SPARE_CMD)) {
-		for (k = 0; k < DeviceInfo.wDataBlockNum; k++) {
-			if (PendingCMD[n].Block == (pbt[k] & (~BAD_BLOCK)))
-				MARK_BLK_AS_DISCARD(pbt[k]);
-		}
-	}
-
-	ftl_cmd = p_BTableChangesDelta->ftl_cmd_cnt;
-	while (ftl_cmd <= PendingCMD[n].Tag) {
-		p_BTableChangesDelta += 1;
-		ftl_cmd = p_BTableChangesDelta->ftl_cmd_cnt;
-	}
-
-#if RESTORE_CACHE_ON_CDMA_CHAIN_FAILURE
-	id = n - MAX_CHANS;
-
-	if (int_cache[id].item != -1) {
-		cache_blks = int_cache[id].item;
-		if (PendingCMD[n].CMD == MEMCOPY_CMD) {
-			if ((cache_start_copy.array[cache_blks].buf <=
-				PendingCMD[n].DataDestAddr) &&
-				((cache_start_copy.array[cache_blks].buf +
-				Cache.cache_item_size) >
-				PendingCMD[n].DataDestAddr)) {
-				cache_start_copy.array[cache_blks].address =
-						NAND_CACHE_INIT_ADDR;
-				cache_start_copy.array[cache_blks].use_cnt =
-								0;
-				cache_start_copy.array[cache_blks].changed =
-								CLEAR;
-			}
-		} else {
-			cache_start_copy.array[cache_blks].address =
-					int_cache[id].cache.address;
-			cache_start_copy.array[cache_blks].changed =
-					int_cache[id].cache.changed;
-		}
-	}
-#endif
-}
-
-static void process_cmd_pass(int *first_failed_cmd, u16 idx)
-{
-	if (0 == *first_failed_cmd)
-		save_blk_table_changes(idx);
-	else
-		discard_cmds(idx);
-}
-
-static void process_cmd_fail_abort(int *first_failed_cmd,
-				u16 idx, int event)
-{
-	u32 *pbt = (u32 *)g_pBTStartingCopy;
-	u8 ftl_cmd;
-	unsigned long i;
-	int erase_fail, program_fail;
-#if RESTORE_CACHE_ON_CDMA_CHAIN_FAILURE
-	u8 cache_blks;
-	u16 id;
-#endif
-
-	if (0 == *first_failed_cmd)
-		*first_failed_cmd = PendingCMD[idx].SBDCmdIndex;
-
-	nand_dbg_print(NAND_DBG_DEBUG, "Uncorrectable error has occurred "
-		"while executing %u Command %u accesing Block %u\n",
-		(unsigned int)p_BTableChangesDelta->ftl_cmd_cnt,
-		PendingCMD[idx].CMD,
-		(unsigned int)PendingCMD[idx].Block);
-
-	ftl_cmd = p_BTableChangesDelta->ftl_cmd_cnt;
-	while (ftl_cmd <= PendingCMD[idx].Tag) {
-		p_BTableChangesDelta += 1;
-		ftl_cmd = p_BTableChangesDelta->ftl_cmd_cnt;
-	}
-
-#if RESTORE_CACHE_ON_CDMA_CHAIN_FAILURE
-	id = idx - MAX_CHANS;
-
-	if (int_cache[id].item != -1) {
-		cache_blks = int_cache[id].item;
-		if ((PendingCMD[idx].CMD == WRITE_MAIN_CMD)) {
-			cache_start_copy.array[cache_blks].address =
-					int_cache[id].cache.address;
-			cache_start_copy.array[cache_blks].changed = SET;
-		} else if ((PendingCMD[idx].CMD == READ_MAIN_CMD)) {
-			cache_start_copy.array[cache_blks].address =
-				NAND_CACHE_INIT_ADDR;
-			cache_start_copy.array[cache_blks].use_cnt = 0;
-			cache_start_copy.array[cache_blks].changed =
-							CLEAR;
-		} else if (PendingCMD[idx].CMD == ERASE_CMD) {
-			/* ? */
-		} else if (PendingCMD[idx].CMD == MEMCOPY_CMD) {
-			/* ? */
-		}
-	}
-#endif
-
-	erase_fail = (event == EVENT_ERASE_FAILURE) &&
-			(PendingCMD[idx].CMD == ERASE_CMD);
-
-	program_fail = (event == EVENT_PROGRAM_FAILURE) &&
-			((PendingCMD[idx].CMD == WRITE_MAIN_CMD) ||
-			(PendingCMD[idx].CMD == WRITE_MAIN_SPARE_CMD));
-
-	if (erase_fail || program_fail) {
-		for (i = 0; i < DeviceInfo.wDataBlockNum; i++) {
-			if (PendingCMD[idx].Block ==
-				(pbt[i] & (~BAD_BLOCK)))
-				MARK_BLOCK_AS_BAD(pbt[i]);
-		}
-	}
-}
-
-static void process_cmd(int *first_failed_cmd, u16 idx, int event)
-{
-	u8 ftl_cmd;
-	int cmd_match = 0;
-
-	if (p_BTableChangesDelta->ftl_cmd_cnt == PendingCMD[idx].Tag)
-		cmd_match = 1;
-
-	if (PendingCMD[idx].Status == CMD_PASS) {
-		process_cmd_pass(first_failed_cmd, idx);
-	} else if ((PendingCMD[idx].Status == CMD_FAIL) ||
-			(PendingCMD[idx].Status == CMD_ABORT)) {
-		process_cmd_fail_abort(first_failed_cmd, idx, event);
-	} else if ((PendingCMD[idx].Status == CMD_NOT_DONE) &&
-					PendingCMD[idx].Tag) {
-		nand_dbg_print(NAND_DBG_DEBUG,
-			" Command no. %hu is not executed\n",
-			(unsigned int)PendingCMD[idx].Tag);
-		ftl_cmd = p_BTableChangesDelta->ftl_cmd_cnt;
-		while (ftl_cmd <= PendingCMD[idx].Tag) {
-			p_BTableChangesDelta += 1;
-			ftl_cmd = p_BTableChangesDelta->ftl_cmd_cnt;
-		}
-	}
-}
-#endif
-
-static void process_cmd(int *first_failed_cmd, u16 idx, int event)
-{
-	printk(KERN_ERR "temporary workaround function. "
-		"Should not be called! \n");
-}
-
-/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
-* Function:    	GLOB_FTL_Event_Status
-* Inputs:       none
-* Outputs:      Event Code
-* Description:	It is called by SBD after hardware interrupt signalling
-*               completion of commands chain
-*               It does following things
-*               get event status from LLD
-*               analyze command chain status
-*               determine last command executed
-*               analyze results
-*               rebuild the block table in case of uncorrectable error
-*               return event code
-*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
-int GLOB_FTL_Event_Status(int *first_failed_cmd)
-{
-	int event_code = PASS;
-	u16 i_P;
-
-	nand_dbg_print(NAND_DBG_TRACE, "%s, Line %d, Function: %s\n",
-		__FILE__, __LINE__, __func__);
-
-	*first_failed_cmd = 0;
-
-	event_code = GLOB_LLD_Event_Status();
-
-	switch (event_code) {
-	case EVENT_PASS:
-		nand_dbg_print(NAND_DBG_DEBUG, "Handling EVENT_PASS\n");
-		break;
-	case EVENT_UNCORRECTABLE_DATA_ERROR:
-		nand_dbg_print(NAND_DBG_DEBUG, "Handling Uncorrectable ECC!\n");
-		break;
-	case EVENT_PROGRAM_FAILURE:
-	case EVENT_ERASE_FAILURE:
-		nand_dbg_print(NAND_DBG_WARN, "Handling Ugly case. "
-			"Event code: 0x%x\n", event_code);
-		p_BTableChangesDelta =
-			(struct BTableChangesDelta *)g_pBTDelta;
-		for (i_P = MAX_CHANS; i_P < (ftl_cmd_cnt + MAX_CHANS);
-				i_P++)
-			process_cmd(first_failed_cmd, i_P, event_code);
-		memcpy(g_pBlockTable, g_pBTStartingCopy,
-			DeviceInfo.wDataBlockNum * sizeof(u32));
-		memcpy(g_pWearCounter, g_pWearCounterCopy,
-			DeviceInfo.wDataBlockNum * sizeof(u8));
-		if (DeviceInfo.MLCDevice)
-			memcpy(g_pReadCounter, g_pReadCounterCopy,
-				DeviceInfo.wDataBlockNum * sizeof(u16));
-
-#if RESTORE_CACHE_ON_CDMA_CHAIN_FAILURE
-		memcpy((void *)&Cache, (void *)&cache_start_copy,
-			sizeof(struct flash_cache_tag));
-		memset((void *)&int_cache, -1,
-			sizeof(struct flash_cache_delta_list_tag) *
-			(MAX_DESCS + MAX_CHANS));
-#endif
-		break;
-	default:
-		nand_dbg_print(NAND_DBG_WARN,
-			"Handling unexpected event code - 0x%x\n",
-			event_code);
-		event_code = ERR;
-		break;
-	}
-
-	memcpy(g_pBTStartingCopy, g_pBlockTable,
-		DeviceInfo.wDataBlockNum * sizeof(u32));
-	memcpy(g_pWearCounterCopy, g_pWearCounter,
-		DeviceInfo.wDataBlockNum * sizeof(u8));
-	if (DeviceInfo.MLCDevice)
-		memcpy(g_pReadCounterCopy, g_pReadCounter,
-			DeviceInfo.wDataBlockNum * sizeof(u16));
-
-	g_pBTDelta_Free = g_pBTDelta;
-	ftl_cmd_cnt = 0;
-	g_pNextBlockTable = g_pBlockTableCopies;
-	cp_back_buf_idx = 0;
-
-#if RESTORE_CACHE_ON_CDMA_CHAIN_FAILURE
-	memcpy((void *)&cache_start_copy, (void *)&Cache,
-		sizeof(struct flash_cache_tag));
-	memset((void *)&int_cache, -1,
-		sizeof(struct flash_cache_delta_list_tag) *
-		(MAX_DESCS + MAX_CHANS));
-#endif
-
-	return event_code;
-}
-
-/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
-* Function:     glob_ftl_execute_cmds
-* Inputs:       none
-* Outputs:      none
-* Description:  pass thru to LLD
-***************************************************************/
-u16 glob_ftl_execute_cmds(void)
-{
-	nand_dbg_print(NAND_DBG_TRACE,
-		"glob_ftl_execute_cmds: ftl_cmd_cnt %u\n",
-		(unsigned int)ftl_cmd_cnt);
-	g_SBDCmdIndex = 0;
-	return glob_lld_execute_cmds();
-}
-
-#endif
-
-#if !CMD_DMA
-/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
-* Function:     GLOB_FTL_Read Immediate
-* Inputs:         pointer to data
-*                     address of data
-* Outputs:      PASS / FAIL
-* Description:  Reads one page of data into RAM directly from flash without
-*       using or disturbing cache.It is assumed this function is called
-*       with CMD-DMA disabled.
-*****************************************************************/
-int GLOB_FTL_Read_Immediate(u8 *read_data, u64 addr)
-{
-	int wResult = FAIL;
-	u32 Block;
-	u16 Page;
-	u32 phy_blk;
-	u32 *pbt = (u32 *)g_pBlockTable;
-
-	nand_dbg_print(NAND_DBG_TRACE, "%s, Line %d, Function: %s\n",
-		__FILE__, __LINE__, __func__);
-
-	Block = BLK_FROM_ADDR(addr);
-	Page = PAGE_FROM_ADDR(addr, Block);
-
-	if (!IS_SPARE_BLOCK(Block))
-		return FAIL;
-
-	phy_blk = pbt[Block];
-	wResult = GLOB_LLD_Read_Page_Main(read_data, phy_blk, Page, 1);
-
-	if (DeviceInfo.MLCDevice) {
-		g_pReadCounter[phy_blk - DeviceInfo.wSpectraStartBlock]++;
-		if (g_pReadCounter[phy_blk - DeviceInfo.wSpectraStartBlock]
-			>= MAX_READ_COUNTER)
-			FTL_Read_Disturbance(phy_blk);
-		if (g_cBlockTableStatus != IN_PROGRESS_BLOCK_TABLE) {
-			g_cBlockTableStatus = IN_PROGRESS_BLOCK_TABLE;
-			FTL_Write_IN_Progress_Block_Table_Page();
-		}
-	}
-
-	return wResult;
-}
-#endif
-
-#ifdef SUPPORT_BIG_ENDIAN
-/*********************************************************************
-* Function:     FTL_Invert_Block_Table
-* Inputs:       none
-* Outputs:      none
-* Description:  Re-format the block table in ram based on BIG_ENDIAN and
-*                     LARGE_BLOCKNUM if necessary
-**********************************************************************/
-static void FTL_Invert_Block_Table(void)
-{
-	u32 i;
-	u32 *pbt = (u32 *)g_pBlockTable;
-
-	nand_dbg_print(NAND_DBG_TRACE, "%s, Line %d, Function: %s\n",
-		__FILE__, __LINE__, __func__);
-
-#ifdef SUPPORT_LARGE_BLOCKNUM
-	for (i = 0; i < DeviceInfo.wDataBlockNum; i++) {
-		pbt[i] = INVERTUINT32(pbt[i]);
-		g_pWearCounter[i] = INVERTUINT32(g_pWearCounter[i]);
-	}
-#else
-	for (i = 0; i < DeviceInfo.wDataBlockNum; i++) {
-		pbt[i] = INVERTUINT16(pbt[i]);
-		g_pWearCounter[i] = INVERTUINT16(g_pWearCounter[i]);
-	}
-#endif
-}
-#endif
-
-/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
-* Function:     GLOB_FTL_Flash_Init
-* Inputs:       none
-* Outputs:      PASS=0 / FAIL=0x01 (based on read ID)
-* Description:  The flash controller is initialized
-*               The flash device is reset
-*               Perform a flash READ ID command to confirm that a
-*                   valid device is attached and active.
-*                   The DeviceInfo structure gets filled in
-*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
-int GLOB_FTL_Flash_Init(void)
-{
-	int status = FAIL;
-
-	nand_dbg_print(NAND_DBG_TRACE, "%s, Line %d, Function: %s\n",
-		__FILE__, __LINE__, __func__);
-
-	g_SBDCmdIndex = 0;
-
-	status = GLOB_LLD_Flash_Init();
-
-	return status;
-}
-
-/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
-* Inputs:       none
-* Outputs:      PASS=0 / FAIL=0x01 (based on read ID)
-* Description:  The flash controller is released
-*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
-int GLOB_FTL_Flash_Release(void)
-{
-	nand_dbg_print(NAND_DBG_TRACE, "%s, Line %d, Function: %s\n",
-		__FILE__, __LINE__, __func__);
-
-	return GLOB_LLD_Flash_Release();
-}
-
-
-/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
-* Function:     GLOB_FTL_Cache_Release
-* Inputs:       none
-* Outputs:      none
-* Description:  release all allocated memory in GLOB_FTL_Init
-*               (allocated in GLOB_FTL_Init)
-*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
-void GLOB_FTL_Cache_Release(void)
-{
-	nand_dbg_print(NAND_DBG_TRACE, "%s, Line %d, Function: %s\n",
-			       __FILE__, __LINE__, __func__);
-
-	free_memory();
-}
-
-/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
-* Function:     FTL_Cache_If_Hit
-* Inputs:       Page Address
-* Outputs:      Block number/UNHIT BLOCK
-* Description:  Determines if the addressed page is in cache
-*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
-static u16 FTL_Cache_If_Hit(u64 page_addr)
-{
-	u16 item;
-	u64 addr;
-	int i;
-
-	nand_dbg_print(NAND_DBG_TRACE, "%s, Line %d, Function: %s\n",
-		__FILE__, __LINE__, __func__);
-
-	item = UNHIT_CACHE_ITEM;
-	for (i = 0; i < CACHE_ITEM_NUM; i++) {
-		addr = Cache.array[i].address;
-		if ((page_addr >= addr) &&
-			(page_addr < (addr + Cache.cache_item_size))) {
-			item = i;
-			break;
-		}
-	}
-
-	return item;
-}
-
-/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
-* Function:     FTL_Calculate_LRU
-* Inputs:       None
-* Outputs:      None
-* Description:  Calculate the least recently block in a cache and record its
-*               index in LRU field.
-*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
-static void FTL_Calculate_LRU(void)
-{
-	u16 i, bCurrentLRU, bTempCount;
-
-	nand_dbg_print(NAND_DBG_TRACE, "%s, Line %d, Function: %s\n",
-		__FILE__, __LINE__, __func__);
-
-	bCurrentLRU = 0;
-	bTempCount = MAX_WORD_VALUE;
-
-	for (i = 0; i < CACHE_ITEM_NUM; i++) {
-		if (Cache.array[i].use_cnt < bTempCount) {
-			bCurrentLRU = i;
-			bTempCount = Cache.array[i].use_cnt;
-		}
-	}
-
-	Cache.LRU = bCurrentLRU;
-}
-
-/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
-* Function:     FTL_Cache_Read_Page
-* Inputs:       pointer to read buffer, logical address and cache item number
-* Outputs:      None
-* Description:  Read the page from the cached block addressed by blocknumber
-*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
-static void FTL_Cache_Read_Page(u8 *data_buf, u64 logic_addr, u16 cache_item)
-{
-	u8 *start_addr;
-
-	nand_dbg_print(NAND_DBG_TRACE, "%s, Line %d, Function: %s\n",
-		__FILE__, __LINE__, __func__);
-
-	start_addr = Cache.array[cache_item].buf;
-	start_addr += (u32)(((logic_addr - Cache.array[cache_item].address) >>
-		DeviceInfo.nBitsInPageDataSize) * DeviceInfo.wPageDataSize);
-
-#if CMD_DMA
-	GLOB_LLD_MemCopy_CMD(data_buf, start_addr,
-			DeviceInfo.wPageDataSize, 0);
-	ftl_cmd_cnt++;
-#else
-	memcpy(data_buf, start_addr, DeviceInfo.wPageDataSize);
-#endif
-
-	if (Cache.array[cache_item].use_cnt < MAX_WORD_VALUE)
-		Cache.array[cache_item].use_cnt++;
-}
-
-/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
-* Function:     FTL_Cache_Read_All
-* Inputs:       pointer to read buffer,block address
-* Outputs:      PASS=0 / FAIL =1
-* Description:  It reads pages in cache
-*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
-static int FTL_Cache_Read_All(u8 *pData, u64 phy_addr)
-{
-	int wResult = PASS;
-	u32 Block;
-	u32 lba;
-	u16 Page;
-	u16 PageCount;
-	u32 *pbt = (u32 *)g_pBlockTable;
-	u32 i;
-
-	Block = BLK_FROM_ADDR(phy_addr);
-	Page = PAGE_FROM_ADDR(phy_addr, Block);
-	PageCount = Cache.pages_per_item;
-
-	nand_dbg_print(NAND_DBG_DEBUG,
-			"%s, Line %d, Function: %s, Block: 0x%x\n",
-			__FILE__, __LINE__, __func__, Block);
-
-	lba = 0xffffffff;
-	for (i = 0; i < DeviceInfo.wDataBlockNum; i++) {
-		if ((pbt[i] & (~BAD_BLOCK)) == Block) {
-			lba = i;
-			if (IS_SPARE_BLOCK(i) || IS_BAD_BLOCK(i) ||
-				IS_DISCARDED_BLOCK(i)) {
-				/* Add by yunpeng -2008.12.3 */
-#if CMD_DMA
-				GLOB_LLD_MemCopy_CMD(pData, g_temp_buf,
-				PageCount * DeviceInfo.wPageDataSize, 0);
-				ftl_cmd_cnt++;
-#else
-				memset(pData, 0xFF,
-					PageCount * DeviceInfo.wPageDataSize);
-#endif
-				return wResult;
-			} else {
-				continue; /* break ?? */
-			}
-		}
-	}
-
-	if (0xffffffff == lba)
-		printk(KERN_ERR "FTL_Cache_Read_All: Block is not found in BT\n");
-
-#if CMD_DMA
-	wResult = GLOB_LLD_Read_Page_Main_cdma(pData, Block, Page,
-			PageCount, LLD_CMD_FLAG_MODE_CDMA);
-	if (DeviceInfo.MLCDevice) {
-		g_pReadCounter[Block - DeviceInfo.wSpectraStartBlock]++;
-		nand_dbg_print(NAND_DBG_DEBUG,
-			       "Read Counter modified in ftl_cmd_cnt %u"
-				" Block %u Counter%u\n",
-			       ftl_cmd_cnt, (unsigned int)Block,
-			       g_pReadCounter[Block -
-			       DeviceInfo.wSpectraStartBlock]);
-
-		p_BTableChangesDelta =
-			(struct BTableChangesDelta *)g_pBTDelta_Free;
-		g_pBTDelta_Free += sizeof(struct BTableChangesDelta);
-		p_BTableChangesDelta->ftl_cmd_cnt = ftl_cmd_cnt;
-		p_BTableChangesDelta->RC_Index =
-			Block - DeviceInfo.wSpectraStartBlock;
-		p_BTableChangesDelta->RC_Entry_Value =
-			g_pReadCounter[Block - DeviceInfo.wSpectraStartBlock];
-		p_BTableChangesDelta->ValidFields = 0xC0;
-
-		ftl_cmd_cnt++;
-
-		if (g_pReadCounter[Block - DeviceInfo.wSpectraStartBlock] >=
-		    MAX_READ_COUNTER)
-			FTL_Read_Disturbance(Block);
-		if (g_cBlockTableStatus != IN_PROGRESS_BLOCK_TABLE) {
-			g_cBlockTableStatus = IN_PROGRESS_BLOCK_TABLE;
-			FTL_Write_IN_Progress_Block_Table_Page();
-		}
-	} else {
-		ftl_cmd_cnt++;
-	}
-#else
-	wResult = GLOB_LLD_Read_Page_Main(pData, Block, Page, PageCount);
-	if (wResult == FAIL)
-		return wResult;
-
-	if (DeviceInfo.MLCDevice) {
-		g_pReadCounter[Block - DeviceInfo.wSpectraStartBlock]++;
-		if (g_pReadCounter[Block - DeviceInfo.wSpectraStartBlock] >=
-						MAX_READ_COUNTER)
-			FTL_Read_Disturbance(Block);
-		if (g_cBlockTableStatus != IN_PROGRESS_BLOCK_TABLE) {
-			g_cBlockTableStatus = IN_PROGRESS_BLOCK_TABLE;
-			FTL_Write_IN_Progress_Block_Table_Page();
-		}
-	}
-#endif
-	return wResult;
-}
-
-/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
-* Function:     FTL_Cache_Write_All
-* Inputs:       pointer to cache in sys memory
-*               address of free block in flash
-* Outputs:      PASS=0 / FAIL=1
-* Description:  writes all the pages of the block in cache to flash
-*
-*               NOTE:need to make sure this works ok when cache is limited
-*               to a partial block. This is where copy-back would be
-*               activated.  This would require knowing which pages in the
-*               cached block are clean/dirty.Right now we only know if
-*               the whole block is clean/dirty.
-*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
-static int FTL_Cache_Write_All(u8 *pData, u64 blk_addr)
-{
-	u16 wResult = PASS;
-	u32 Block;
-	u16 Page;
-	u16 PageCount;
-
-	nand_dbg_print(NAND_DBG_TRACE, "%s, Line %d, Function: %s\n",
-			       __FILE__, __LINE__, __func__);
-
-	nand_dbg_print(NAND_DBG_DEBUG, "This block %d going to be written "
-		"on %d\n", cache_block_to_write,
-		(u32)(blk_addr >> DeviceInfo.nBitsInBlockDataSize));
-
-	Block = BLK_FROM_ADDR(blk_addr);
-	Page = PAGE_FROM_ADDR(blk_addr, Block);
-	PageCount = Cache.pages_per_item;
-
-#if CMD_DMA
-	if (FAIL == GLOB_LLD_Write_Page_Main_cdma(pData,
-					Block, Page, PageCount)) {
-		nand_dbg_print(NAND_DBG_WARN,
-			"NAND Program fail in %s, Line %d, "
-			"Function: %s, new Bad Block %d generated! "
-			"Need Bad Block replacing.\n",
-			__FILE__, __LINE__, __func__, Block);
-		wResult = FAIL;
-	}
-	ftl_cmd_cnt++;
-#else
-	if (FAIL == GLOB_LLD_Write_Page_Main(pData, Block, Page, PageCount)) {
-		nand_dbg_print(NAND_DBG_WARN, "NAND Program fail in %s,"
-			" Line %d, Function %s, new Bad Block %d generated!"
-			"Need Bad Block replacing.\n",
-			__FILE__, __LINE__, __func__, Block);
-		wResult = FAIL;
-	}
-#endif
-	return wResult;
-}
-
-/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
-* Function:     FTL_Copy_Block
-* Inputs:       source block address
-*               Destination block address
-* Outputs:      PASS=0 / FAIL=1
-* Description:  used only for static wear leveling to move the block
-*               containing static data to new blocks(more worn)
-*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
-int FTL_Copy_Block(u64 old_blk_addr, u64 blk_addr)
-{
-	int i, r1, r2, wResult = PASS;
-
-	nand_dbg_print(NAND_DBG_TRACE, "%s, Line %d, Function: %s\n",
-		__FILE__, __LINE__, __func__);
-
-	for (i = 0; i < DeviceInfo.wPagesPerBlock; i += Cache.pages_per_item) {
-		r1 = FTL_Cache_Read_All(g_pTempBuf, old_blk_addr +
-					i * DeviceInfo.wPageDataSize);
-		r2 = FTL_Cache_Write_All(g_pTempBuf, blk_addr +
-					i * DeviceInfo.wPageDataSize);
-		if ((ERR == r1) || (FAIL == r2)) {
-			wResult = FAIL;
-			break;
-		}
-	}
-
-	return wResult;
-}
-
-/* Search the block table to find out the least wear block and then return it */
-static u32 find_least_worn_blk_for_l2_cache(void)
-{
-	int i;
-	u32 *pbt = (u32 *)g_pBlockTable;
-	u8 least_wear_cnt = MAX_BYTE_VALUE;
-	u32 least_wear_blk_idx = MAX_U32_VALUE;
-	u32 phy_idx;
-
-	for (i = 0; i < DeviceInfo.wDataBlockNum; i++) {
-		if (IS_SPARE_BLOCK(i)) {
-			phy_idx = (u32)((~BAD_BLOCK) & pbt[i]);
-			if (phy_idx > DeviceInfo.wSpectraEndBlock)
-				printk(KERN_ERR "find_least_worn_blk_for_l2_cache: "
-					"Too big phy block num (%d)\n", phy_idx);
-			if (g_pWearCounter[phy_idx -DeviceInfo.wSpectraStartBlock] < least_wear_cnt) {
-				least_wear_cnt = g_pWearCounter[phy_idx - DeviceInfo.wSpectraStartBlock];
-				least_wear_blk_idx = i;
-			}
-		}
-	}
-
-	nand_dbg_print(NAND_DBG_WARN,
-		"find_least_worn_blk_for_l2_cache: "
-		"find block %d with least worn counter (%d)\n",
-		least_wear_blk_idx, least_wear_cnt);
-
-	return least_wear_blk_idx;
-}
-
-
-
-/* Get blocks for Level2 Cache */
-static int get_l2_cache_blks(void)
-{
-	int n;
-	u32 blk;
-	u32 *pbt = (u32 *)g_pBlockTable;
-
-	for (n = 0; n < BLK_NUM_FOR_L2_CACHE; n++) {
-		blk = find_least_worn_blk_for_l2_cache();
-		if (blk >= DeviceInfo.wDataBlockNum) {
-			nand_dbg_print(NAND_DBG_WARN,
-				"find_least_worn_blk_for_l2_cache: "
-				"No enough free NAND blocks (n: %d) for L2 Cache!\n", n);
-			return FAIL;
-		}
-		/* Tag the free block as discard in block table */
-		pbt[blk] = (pbt[blk] & (~BAD_BLOCK)) | DISCARD_BLOCK;
-		/* Add the free block to the L2 Cache block array */
-		cache_l2.blk_array[n] = pbt[blk] & (~BAD_BLOCK);
-	}
-
-	return PASS;
-}
-
-static int erase_l2_cache_blocks(void)
-{
-	int i, ret = PASS;
-	u32 pblk, lblk = BAD_BLOCK;
-	u64 addr;
-	u32 *pbt = (u32 *)g_pBlockTable;
-
-	nand_dbg_print(NAND_DBG_WARN, "%s, Line %d, Function: %s\n",
-			       __FILE__, __LINE__, __func__);
-
-	for (i = 0; i < BLK_NUM_FOR_L2_CACHE; i++) {
-		pblk = cache_l2.blk_array[i];
-
-		/* If the L2 cache block is invalid, then just skip it */
-		if (MAX_U32_VALUE == pblk)
-			continue;
-
-		BUG_ON(pblk > DeviceInfo.wSpectraEndBlock);
-
-		addr = (u64)pblk << DeviceInfo.nBitsInBlockDataSize;
-		if (PASS == GLOB_FTL_Block_Erase(addr)) {
-			/* Get logical block number of the erased block */
-			lblk = FTL_Get_Block_Index(pblk);
-			BUG_ON(BAD_BLOCK == lblk);
-			/* Tag it as free in the block table */
-			pbt[lblk] &= (u32)(~DISCARD_BLOCK);
-			pbt[lblk] |= (u32)(SPARE_BLOCK);
-		} else {
-			MARK_BLOCK_AS_BAD(pbt[lblk]);
-			ret = ERR;
-		}
-	}
-
-	return ret;
-}
-
-/*
- * Merge the valid data page in the L2 cache blocks into NAND.
-*/
-static int flush_l2_cache(void)
-{
-	struct list_head *p;
-	struct spectra_l2_cache_list *pnd, *tmp_pnd;
-	u32 *pbt = (u32 *)g_pBlockTable;
-	u32 phy_blk, l2_blk;
-	u64 addr;
-	u16 l2_page;
-	int i, ret = PASS;
-
-	nand_dbg_print(NAND_DBG_WARN, "%s, Line %d, Function: %s\n",
-			       __FILE__, __LINE__, __func__);
-
-	if (list_empty(&cache_l2.table.list)) /* No data to flush */
-		return ret;
-
-	//dump_cache_l2_table();
-
-	if (IN_PROGRESS_BLOCK_TABLE != g_cBlockTableStatus) {
-		g_cBlockTableStatus = IN_PROGRESS_BLOCK_TABLE;
-		FTL_Write_IN_Progress_Block_Table_Page();
-	}
-
-	list_for_each(p, &cache_l2.table.list) {
-		pnd = list_entry(p, struct spectra_l2_cache_list, list);
-		if (IS_SPARE_BLOCK(pnd->logical_blk_num) ||
-			IS_BAD_BLOCK(pnd->logical_blk_num) ||
-			IS_DISCARDED_BLOCK(pnd->logical_blk_num)) {
-			nand_dbg_print(NAND_DBG_WARN, "%s, Line %d\n", __FILE__, __LINE__);
-			memset(cache_l2_blk_buf, 0xff, DeviceInfo.wPagesPerBlock * DeviceInfo.wPageDataSize);			
-		} else {
-			nand_dbg_print(NAND_DBG_WARN, "%s, Line %d\n", __FILE__, __LINE__);
-			phy_blk = pbt[pnd->logical_blk_num] & (~BAD_BLOCK);
-			ret = GLOB_LLD_Read_Page_Main(cache_l2_blk_buf,
-				phy_blk, 0, DeviceInfo.wPagesPerBlock);
-			if (ret == FAIL) {
-				printk(KERN_ERR "Read NAND page fail in %s, Line %d\n", __FILE__, __LINE__);
-			}
-		}
-
-		for (i = 0; i < DeviceInfo.wPagesPerBlock; i++) {
-			if (pnd->pages_array[i] != MAX_U32_VALUE) {
-				l2_blk = cache_l2.blk_array[(pnd->pages_array[i] >> 16) & 0xffff];
-				l2_page = pnd->pages_array[i] & 0xffff;
-				ret = GLOB_LLD_Read_Page_Main(cache_l2_page_buf, l2_blk, l2_page, 1);
-				if (ret == FAIL) {
-					printk(KERN_ERR "Read NAND page fail in %s, Line %d\n", __FILE__, __LINE__);
-				}
-				memcpy(cache_l2_blk_buf + i * DeviceInfo.wPageDataSize, cache_l2_page_buf, DeviceInfo.wPageDataSize);
-			}
-		}
-
-		/* Find a free block and tag the original block as discarded */
-		addr = (u64)pnd->logical_blk_num << DeviceInfo.nBitsInBlockDataSize;
-		ret = FTL_Replace_Block(addr);
-		if (ret == FAIL) {
-			printk(KERN_ERR "FTL_Replace_Block fail in %s, Line %d\n", __FILE__, __LINE__);
-		}
-
-		/* Write back the updated data into NAND */
-		phy_blk = pbt[pnd->logical_blk_num] & (~BAD_BLOCK);
-		if (FAIL == GLOB_LLD_Write_Page_Main(cache_l2_blk_buf, phy_blk, 0, DeviceInfo.wPagesPerBlock)) {
-			nand_dbg_print(NAND_DBG_WARN,
-				"Program NAND block %d fail in %s, Line %d\n",
-				phy_blk, __FILE__, __LINE__);
-			/* This may not be really a bad block. So just tag it as discarded. */
-			/* Then it has a chance to be erased when garbage collection. */
-			/* If it is really bad, then the erase will fail and it will be marked */
-			/* as bad then. Otherwise it will be marked as free and can be used again */
-			MARK_BLK_AS_DISCARD(pbt[pnd->logical_blk_num]);
-			/* Find another free block and write it again */
-			FTL_Replace_Block(addr);
-			phy_blk = pbt[pnd->logical_blk_num] & (~BAD_BLOCK);
-			if (FAIL == GLOB_LLD_Write_Page_Main(cache_l2_blk_buf, phy_blk, 0, DeviceInfo.wPagesPerBlock)) {
-				printk(KERN_ERR "Failed to write back block %d when flush L2 cache."
-					"Some data will be lost!\n", phy_blk);
-				MARK_BLOCK_AS_BAD(pbt[pnd->logical_blk_num]);
-			}
-		} else {
-			/* tag the new free block as used block */
-			pbt[pnd->logical_blk_num] &= (~SPARE_BLOCK);
-		}
-	}
-
-	/* Destroy the L2 Cache table and free the memory of all nodes */
-	list_for_each_entry_safe(pnd, tmp_pnd, &cache_l2.table.list, list) {
-		list_del(&pnd->list);
-		kfree(pnd);
-	}
-
-	/* Erase discard L2 cache blocks */
-	if (erase_l2_cache_blocks() != PASS)
-		nand_dbg_print(NAND_DBG_WARN,
-			" Erase L2 cache blocks error in %s, Line %d\n",
-			__FILE__, __LINE__);
-
-	/* Init the Level2 Cache data structure */
-	for (i = 0; i < BLK_NUM_FOR_L2_CACHE; i++)
-		cache_l2.blk_array[i] = MAX_U32_VALUE;
-	cache_l2.cur_blk_idx = 0;
-	cache_l2.cur_page_num = 0;
-	INIT_LIST_HEAD(&cache_l2.table.list);
-	cache_l2.table.logical_blk_num = MAX_U32_VALUE;
-
-	return ret;
-}
-
-/*
- * Write back a changed victim cache item to the Level2 Cache
- * and update the L2 Cache table to map the change.
- * If the L2 Cache is full, then start to do the L2 Cache flush.
-*/
-static int write_back_to_l2_cache(u8 *buf, u64 logical_addr)
-{
-	u32 logical_blk_num;
-	u16 logical_page_num;
-	struct list_head *p;
-	struct spectra_l2_cache_list *pnd, *pnd_new;
-	u32 node_size;
-	int i, found;
-
-	nand_dbg_print(NAND_DBG_DEBUG, "%s, Line %d, Function: %s\n",
-			       __FILE__, __LINE__, __func__);
-
-	/*
-	 * If Level2 Cache table is empty, then it means either:
-	 * 1. This is the first time that the function called after FTL_init
-	 * or
-	 * 2. The Level2 Cache has just been flushed
-	 *
-	 * So, 'steal' some free blocks from NAND for L2 Cache using
-	 * by just mask them as discard in the block table
-	*/
-	if (list_empty(&cache_l2.table.list)) {
-		BUG_ON(cache_l2.cur_blk_idx != 0);
-		BUG_ON(cache_l2.cur_page_num!= 0);
-		BUG_ON(cache_l2.table.logical_blk_num != MAX_U32_VALUE);
-		if (FAIL == get_l2_cache_blks()) {
-			GLOB_FTL_Garbage_Collection();
-			if (FAIL == get_l2_cache_blks()) {
-				printk(KERN_ALERT "Fail to get L2 cache blks!\n");
-				return FAIL;
-			}
-		}
-	}
-
-	logical_blk_num = BLK_FROM_ADDR(logical_addr);
-	logical_page_num = PAGE_FROM_ADDR(logical_addr, logical_blk_num);
-	BUG_ON(logical_blk_num == MAX_U32_VALUE);
-
-	/* Write the cache item data into the current position of L2 Cache */
-#if CMD_DMA
-	/*
-	 * TODO
-	 */
-#else
-	if (FAIL == GLOB_LLD_Write_Page_Main(buf,
-		cache_l2.blk_array[cache_l2.cur_blk_idx],
-		cache_l2.cur_page_num, 1)) {
-		nand_dbg_print(NAND_DBG_WARN, "NAND Program fail in "
-			"%s, Line %d, new Bad Block %d generated!\n",
-			__FILE__, __LINE__,
-			cache_l2.blk_array[cache_l2.cur_blk_idx]);
-
-		/* TODO: tag the current block as bad and try again */
-
-		return FAIL;
-	}
-#endif
-
-	/* 
-	 * Update the L2 Cache table.
-	 *
-	 * First seaching in the table to see whether the logical block
-	 * has been mapped. If not, then kmalloc a new node for the
-	 * logical block, fill data, and then insert it to the list.
-	 * Otherwise, just update the mapped node directly.
-	 */
-	found = 0;
-	list_for_each(p, &cache_l2.table.list) {
-		pnd = list_entry(p, struct spectra_l2_cache_list, list);
-		if (pnd->logical_blk_num == logical_blk_num) {
-			pnd->pages_array[logical_page_num] =
-				(cache_l2.cur_blk_idx << 16) |
-				cache_l2.cur_page_num;
-			found = 1;
-			break;
-		}
-	}
-	if (!found) { /* Create new node for the logical block here */
-
-		/* The logical pages to physical pages map array is
-		 * located at the end of struct spectra_l2_cache_list.
-		 */ 
-		node_size = sizeof(struct spectra_l2_cache_list) +
-			sizeof(u32) * DeviceInfo.wPagesPerBlock;
-		pnd_new = kmalloc(node_size, GFP_ATOMIC);
-		if (!pnd_new) {
-			printk(KERN_ERR "Failed to kmalloc in %s Line %d\n",
-				__FILE__, __LINE__);
-			/* 
-			 * TODO: Need to flush all the L2 cache into NAND ASAP
-			 * since no memory available here
-			 */
-		}
-		pnd_new->logical_blk_num = logical_blk_num;
-		for (i = 0; i < DeviceInfo.wPagesPerBlock; i++)
-			pnd_new->pages_array[i] = MAX_U32_VALUE;
-		pnd_new->pages_array[logical_page_num] =
-			(cache_l2.cur_blk_idx << 16) | cache_l2.cur_page_num;
-		list_add(&pnd_new->list, &cache_l2.table.list);
-	}
-
-	/* Increasing the current position pointer of the L2 Cache */
-	cache_l2.cur_page_num++;
-	if (cache_l2.cur_page_num >= DeviceInfo.wPagesPerBlock) {
-		cache_l2.cur_blk_idx++;
-		if (cache_l2.cur_blk_idx >= BLK_NUM_FOR_L2_CACHE) {
-			/* The L2 Cache is full. Need to flush it now */
-			nand_dbg_print(NAND_DBG_WARN,
-				"L2 Cache is full, will start to flush it\n");
-			flush_l2_cache();
-		} else {
-			cache_l2.cur_page_num = 0;
-		}
-	}
-
-	return PASS;
-}
-
-/*
- * Search in the Level2 Cache table to find the cache item.
- * If find, read the data from the NAND page of L2 Cache,
- * Otherwise, return FAIL.
- */
-static int search_l2_cache(u8 *buf, u64 logical_addr)
-{
-	u32 logical_blk_num;
-	u16 logical_page_num;
-	struct list_head *p;
-	struct spectra_l2_cache_list *pnd;
-	u32 tmp = MAX_U32_VALUE;
-	u32 phy_blk;
-	u16 phy_page;
-	int ret = FAIL;
-
-	logical_blk_num = BLK_FROM_ADDR(logical_addr);
-	logical_page_num = PAGE_FROM_ADDR(logical_addr, logical_blk_num);
-
-	list_for_each(p, &cache_l2.table.list) {
-		pnd = list_entry(p, struct spectra_l2_cache_list, list);
-		if (pnd->logical_blk_num == logical_blk_num) {
-			tmp = pnd->pages_array[logical_page_num];
-			break;
-		}
-	}
-
-	if (tmp != MAX_U32_VALUE) { /* Found valid map */
-		phy_blk = cache_l2.blk_array[(tmp >> 16) & 0xFFFF];
-		phy_page = tmp & 0xFFFF;
-#if CMD_DMA
-		/* TODO */
-#else
-		ret = GLOB_LLD_Read_Page_Main(buf, phy_blk, phy_page, 1);
-#endif
-	}
-
-	return ret;
-}
-
-/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
-* Function:     FTL_Cache_Write_Page
-* Inputs:       Pointer to buffer, page address, cache block number
-* Outputs:      PASS=0 / FAIL=1
-* Description:  It writes the data in Cache Block
-*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
-static void FTL_Cache_Write_Page(u8 *pData, u64 page_addr,
-				u8 cache_blk, u16 flag)
-{
-	u8 *pDest;
-	u64 addr;
-
-	nand_dbg_print(NAND_DBG_TRACE, "%s, Line %d, Function: %s\n",
-		__FILE__, __LINE__, __func__);
-
-	addr = Cache.array[cache_blk].address;
-	pDest = Cache.array[cache_blk].buf;
-
-	pDest += (unsigned long)(page_addr - addr);
-	Cache.array[cache_blk].changed = SET;
-#if CMD_DMA
-#if RESTORE_CACHE_ON_CDMA_CHAIN_FAILURE
-	int_cache[ftl_cmd_cnt].item = cache_blk;
-	int_cache[ftl_cmd_cnt].cache.address =
-			Cache.array[cache_blk].address;
-	int_cache[ftl_cmd_cnt].cache.changed =
-			Cache.array[cache_blk].changed;
-#endif
-	GLOB_LLD_MemCopy_CMD(pDest, pData, DeviceInfo.wPageDataSize, flag);
-	ftl_cmd_cnt++;
-#else
-	memcpy(pDest, pData, DeviceInfo.wPageDataSize);
-#endif
-	if (Cache.array[cache_blk].use_cnt < MAX_WORD_VALUE)
-		Cache.array[cache_blk].use_cnt++;
-}
-
-/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
-* Function:     FTL_Cache_Write
-* Inputs:       none
-* Outputs:      PASS=0 / FAIL=1
-* Description:  It writes least frequently used Cache block to flash if it
-*               has been changed
-*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
-static int FTL_Cache_Write(void)
-{
-	int i, bResult = PASS;
-	u16 bNO, least_count = 0xFFFF;
-
-	nand_dbg_print(NAND_DBG_TRACE, "%s, Line %d, Function: %s\n",
-		__FILE__, __LINE__, __func__);
-
-	FTL_Calculate_LRU();
-
-	bNO = Cache.LRU;
-	nand_dbg_print(NAND_DBG_DEBUG, "FTL_Cache_Write: "
-		"Least used cache block is %d\n", bNO);
-
-	if (Cache.array[bNO].changed != SET)
-		return bResult;
-
-	nand_dbg_print(NAND_DBG_DEBUG, "FTL_Cache_Write: Cache"
-		" Block %d containing logical block %d is dirty\n",
-		bNO,
-		(u32)(Cache.array[bNO].address >>
-		DeviceInfo.nBitsInBlockDataSize));
-#if CMD_DMA
-#if RESTORE_CACHE_ON_CDMA_CHAIN_FAILURE
-	int_cache[ftl_cmd_cnt].item = bNO;
-	int_cache[ftl_cmd_cnt].cache.address =
-				Cache.array[bNO].address;
-	int_cache[ftl_cmd_cnt].cache.changed = CLEAR;
-#endif
-#endif
-	bResult = write_back_to_l2_cache(Cache.array[bNO].buf,
-			Cache.array[bNO].address);
-	if (bResult != ERR)
-		Cache.array[bNO].changed = CLEAR;
-
-	least_count = Cache.array[bNO].use_cnt;
-
-	for (i = 0; i < CACHE_ITEM_NUM; i++) {
-		if (i == bNO)
-			continue;
-		if (Cache.array[i].use_cnt > 0)
-			Cache.array[i].use_cnt -= least_count;
-	}
-
-	return bResult;
-}
-
-/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
-* Function:     FTL_Cache_Read
-* Inputs:       Page address
-* Outputs:      PASS=0 / FAIL=1
-* Description:  It reads the block from device in Cache Block
-*               Set the LRU count to 1
-*               Mark the Cache Block as clean
-*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
-static int FTL_Cache_Read(u64 logical_addr)
-{
-	u64 item_addr, phy_addr;
-	u16 num;
-	int ret;
-
-	nand_dbg_print(NAND_DBG_TRACE, "%s, Line %d, Function: %s\n",
-		__FILE__, __LINE__, __func__);
-
-	num = Cache.LRU; /* The LRU cache item will be overwritten */
-
-	item_addr = (u64)GLOB_u64_Div(logical_addr, Cache.cache_item_size) *
-		Cache.cache_item_size;
-	Cache.array[num].address = item_addr;
-	Cache.array[num].use_cnt = 1;
-	Cache.array[num].changed = CLEAR;
-
-#if CMD_DMA
-#if RESTORE_CACHE_ON_CDMA_CHAIN_FAILURE
-	int_cache[ftl_cmd_cnt].item = num;
-	int_cache[ftl_cmd_cnt].cache.address =
-			Cache.array[num].address;
-	int_cache[ftl_cmd_cnt].cache.changed =
-			Cache.array[num].changed;
-#endif
-#endif
-	/*
-	 * Search in L2 Cache. If hit, fill data into L1 Cache item buffer,
-	 * Otherwise, read it from NAND
-	 */
-	ret = search_l2_cache(Cache.array[num].buf, logical_addr);
-	if (PASS == ret) /* Hit in L2 Cache */
-		return ret;
-
-	/* Compute the physical start address of NAND device according to */
-	/* the logical start address of the cache item (LRU cache item) */
-	phy_addr = FTL_Get_Physical_Block_Addr(item_addr) +
-		GLOB_u64_Remainder(item_addr, 2);
-
-	return FTL_Cache_Read_All(Cache.array[num].buf, phy_addr);
-}
-
-/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
-* Function:     FTL_Check_Block_Table
-* Inputs:       ?
-* Outputs:      PASS=0 / FAIL=1
-* Description:  It checks the correctness of each block table entry
-*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
-static int FTL_Check_Block_Table(int wOldTable)
-{
-	u32 i;
-	int wResult = PASS;
-	u32 blk_idx;
-	u32 *pbt = (u32 *)g_pBlockTable;
-	u8 *pFlag = flag_check_blk_table;
-
-	nand_dbg_print(NAND_DBG_TRACE, "%s, Line %d, Function: %s\n",
-		       __FILE__, __LINE__, __func__);
-
-	if (NULL != pFlag) {
-		memset(pFlag, FAIL, DeviceInfo.wDataBlockNum);
-		for (i = 0; i < DeviceInfo.wDataBlockNum; i++) {
-			blk_idx = (u32)(pbt[i] & (~BAD_BLOCK));
-
-			/*
-			 * 20081006/KBV - Changed to pFlag[i] reference
-			 * to avoid buffer overflow
-			 */
-
-			/*
-			 * 2008-10-20 Yunpeng Note: This change avoid
-			 * buffer overflow, but changed function of
-			 * the code, so it should be re-write later
-			 */
-			if ((blk_idx > DeviceInfo.wSpectraEndBlock) ||
-				PASS == pFlag[i]) {
-				wResult = FAIL;
-				break;
-			} else {
-				pFlag[i] = PASS;
-			}
-		}
-	}
-
-	return wResult;
-}
-
-
-/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
-* Function:     FTL_Write_Block_Table
-* Inputs:       flasg
-* Outputs:      0=Block Table was updated. No write done. 1=Block write needs to
-* happen. -1 Error
-* Description:  It writes the block table
-*               Block table always mapped to LBA 0 which inturn mapped
-*               to any physical block
-*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
-static int FTL_Write_Block_Table(int wForce)
-{
-	u32 *pbt = (u32 *)g_pBlockTable;
-	int wSuccess = PASS;
-	u32 wTempBlockTableIndex;
-	u16 bt_pages, new_bt_offset;
-	u8 blockchangeoccured = 0;
-
-	nand_dbg_print(NAND_DBG_TRACE, "%s, Line %d, Function: %s\n",
-			       __FILE__, __LINE__, __func__);
-
-	bt_pages = FTL_Get_Block_Table_Flash_Size_Pages();
-
-	if (IN_PROGRESS_BLOCK_TABLE != g_cBlockTableStatus)
-		return 0;
-
-	if (PASS == wForce) {
-		g_wBlockTableOffset =
-			(u16)(DeviceInfo.wPagesPerBlock - bt_pages);
-#if CMD_DMA
-		p_BTableChangesDelta =
-			(struct BTableChangesDelta *)g_pBTDelta_Free;
-		g_pBTDelta_Free += sizeof(struct BTableChangesDelta);
-
-		p_BTableChangesDelta->ftl_cmd_cnt = ftl_cmd_cnt;
-		p_BTableChangesDelta->g_wBlockTableOffset =
-			g_wBlockTableOffset;
-		p_BTableChangesDelta->ValidFields = 0x01;
-#endif
-	}
-
-	nand_dbg_print(NAND_DBG_DEBUG,
-		"Inside FTL_Write_Block_Table: block %d Page:%d\n",
-		g_wBlockTableIndex, g_wBlockTableOffset);
-
-	do {
-		new_bt_offset = g_wBlockTableOffset + bt_pages + 1;
-		if ((0 == (new_bt_offset % DeviceInfo.wPagesPerBlock)) ||
-			(new_bt_offset > DeviceInfo.wPagesPerBlock) ||
-			(FAIL == wSuccess)) {
-			wTempBlockTableIndex = FTL_Replace_Block_Table();
-			if (BAD_BLOCK == wTempBlockTableIndex)
-				return ERR;
-			if (!blockchangeoccured) {
-				bt_block_changed = 1;
-				blockchangeoccured = 1;
-			}
-
-			g_wBlockTableIndex = wTempBlockTableIndex;
-			g_wBlockTableOffset = 0;
-			pbt[BLOCK_TABLE_INDEX] = g_wBlockTableIndex;
-#if CMD_DMA
-			p_BTableChangesDelta =
-				(struct BTableChangesDelta *)g_pBTDelta_Free;
-			g_pBTDelta_Free += sizeof(struct BTableChangesDelta);
-
-			p_BTableChangesDelta->ftl_cmd_cnt =
-				    ftl_cmd_cnt;
-			p_BTableChangesDelta->g_wBlockTableOffset =
-				    g_wBlockTableOffset;
-			p_BTableChangesDelta->g_wBlockTableIndex =
-				    g_wBlockTableIndex;
-			p_BTableChangesDelta->ValidFields = 0x03;
-
-			p_BTableChangesDelta =
-				(struct BTableChangesDelta *)g_pBTDelta_Free;
-			g_pBTDelta_Free +=
-				sizeof(struct BTableChangesDelta);
-
-			p_BTableChangesDelta->ftl_cmd_cnt =
-				    ftl_cmd_cnt;
-			p_BTableChangesDelta->BT_Index =
-				    BLOCK_TABLE_INDEX;
-			p_BTableChangesDelta->BT_Entry_Value =
-				    pbt[BLOCK_TABLE_INDEX];
-			p_BTableChangesDelta->ValidFields = 0x0C;
-#endif
-		}
-
-		wSuccess = FTL_Write_Block_Table_Data();
-		if (FAIL == wSuccess)
-			MARK_BLOCK_AS_BAD(pbt[BLOCK_TABLE_INDEX]);
-	} while (FAIL == wSuccess);
-
-	g_cBlockTableStatus = CURRENT_BLOCK_TABLE;
-
-	return 1;
-}
-
-static int  force_format_nand(void)
-{
-	u32 i;
-
-	/* Force erase the whole unprotected physical partiton of NAND */
-	printk(KERN_ALERT "Start to force erase whole NAND device ...\n");
-	printk(KERN_ALERT "From phyical block %d to %d\n",
-		DeviceInfo.wSpectraStartBlock, DeviceInfo.wSpectraEndBlock);
-	for (i = DeviceInfo.wSpectraStartBlock; i <= DeviceInfo.wSpectraEndBlock; i++) {
-		if (GLOB_LLD_Erase_Block(i))
-			printk(KERN_ERR "Failed to force erase NAND block %d\n", i);
-	}
-	printk(KERN_ALERT "Force Erase ends. Please reboot the system ...\n");
-	while(1);
-
-	return PASS;
-}
-
-int GLOB_FTL_Flash_Format(void)
-{
-	//return FTL_Format_Flash(1);
-	return force_format_nand();
-
-}
-
-/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
-* Function:     FTL_Search_Block_Table_IN_Block
-* Inputs:       Block Number
-*               Pointer to page
-* Outputs:      PASS / FAIL
-*               Page contatining the block table
-* Description:  It searches the block table in the block
-*               passed as an argument.
-*
-*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
-static int FTL_Search_Block_Table_IN_Block(u32 BT_Block,
-						u8 BT_Tag, u16 *Page)
-{
-	u16 i, j, k;
-	u16 Result = PASS;
-	u16 Last_IPF = 0;
-	u8  BT_Found = 0;
-	u8 *tagarray;
-	u8 *tempbuf = tmp_buf_search_bt_in_block;
-	u8 *pSpareBuf = spare_buf_search_bt_in_block;
-	u8 *pSpareBufBTLastPage = spare_buf_bt_search_bt_in_block;
-	u8 bt_flag_last_page = 0xFF;
-	u8 search_in_previous_pages = 0;
-	u16 bt_pages;
-
-	nand_dbg_print(NAND_DBG_DEBUG, "%s, Line %d, Function: %s\n",
-			       __FILE__, __LINE__, __func__);
-
-	nand_dbg_print(NAND_DBG_DEBUG,
-		       "Searching block table in %u block\n",
-		       (unsigned int)BT_Block);
-
-	bt_pages = FTL_Get_Block_Table_Flash_Size_Pages();
-
-	for (i = bt_pages; i < DeviceInfo.wPagesPerBlock;
-				i += (bt_pages + 1)) {
-		nand_dbg_print(NAND_DBG_DEBUG,
-			       "Searching last IPF: %d\n", i);
-		Result = GLOB_LLD_Read_Page_Main_Polling(tempbuf,
-							BT_Block, i, 1);
-
-		if (0 == memcmp(tempbuf, g_pIPF, DeviceInfo.wPageDataSize)) {
-			if ((i + bt_pages + 1) < DeviceInfo.wPagesPerBlock) {
-				continue;
-			} else {
-				search_in_previous_pages = 1;
-				Last_IPF = i;
-			}
-		}
-
-		if (!search_in_previous_pages) {
-			if (i != bt_pages) {
-				i -= (bt_pages + 1);
-				Last_IPF = i;
-			}
-		}
-
-		if (0 == Last_IPF)
-			break;
-
-		if (!search_in_previous_pages) {
-			i = i + 1;
-			nand_dbg_print(NAND_DBG_DEBUG,
-				"Reading the spare area of Block %u Page %u",
-				(unsigned int)BT_Block, i);
-			Result = GLOB_LLD_Read_Page_Spare(pSpareBuf,
-							BT_Block, i, 1);
-			nand_dbg_print(NAND_DBG_DEBUG,
-				"Reading the spare area of Block %u Page %u",
-				(unsigned int)BT_Block, i + bt_pages - 1);
-			Result = GLOB_LLD_Read_Page_Spare(pSpareBufBTLastPage,
-				BT_Block, i + bt_pages - 1, 1);
-
-			k = 0;
-			j = FTL_Extract_Block_Table_Tag(pSpareBuf, &tagarray);
-			if (j) {
-				for (; k < j; k++) {
-					if (tagarray[k] == BT_Tag)
-						break;
-				}
-			}
-
-			if (k < j)
-				bt_flag = tagarray[k];
-			else
-				Result = FAIL;
-
-			if (Result == PASS) {
-				k = 0;
-				j = FTL_Extract_Block_Table_Tag(
-					pSpareBufBTLastPage, &tagarray);
-				if (j) {
-					for (; k < j; k++) {
-						if (tagarray[k] == BT_Tag)
-							break;
-					}
-				}
-
-				if (k < j)
-					bt_flag_last_page = tagarray[k];
-				else
-					Result = FAIL;
-
-				if (Result == PASS) {
-					if (bt_flag == bt_flag_last_page) {
-						nand_dbg_print(NAND_DBG_DEBUG,
-							"Block table is found"
-							" in page after IPF "
-							"at block %d "
-							"page %d\n",
-							(int)BT_Block, i);
-						BT_Found = 1;
-						*Page  = i;
-						g_cBlockTableStatus =
-							CURRENT_BLOCK_TABLE;
-						break;
-					} else {
-						Result = FAIL;
-					}
-				}
-			}
-		}
-
-		if (search_in_previous_pages)
-			i = i - bt_pages;
-		else
-			i = i - (bt_pages + 1);
-
-		Result = PASS;
-
-		nand_dbg_print(NAND_DBG_DEBUG,
-			"Reading the spare area of Block %d Page %d",
-			(int)BT_Block, i);
-
-		Result = GLOB_LLD_Read_Page_Spare(pSpareBuf, BT_Block, i, 1);
-		nand_dbg_print(NAND_DBG_DEBUG,
-			"Reading the spare area of Block %u Page %u",
-			(unsigned int)BT_Block, i + bt_pages - 1);
-
-		Result = GLOB_LLD_Read_Page_Spare(pSpareBufBTLastPage,
-					BT_Block, i + bt_pages - 1, 1);
-
-		k = 0;
-		j = FTL_Extract_Block_Table_Tag(pSpareBuf, &tagarray);
-		if (j) {
-			for (; k < j; k++) {
-				if (tagarray[k] == BT_Tag)
-					break;
-			}
-		}
-
-		if (k < j)
-			bt_flag = tagarray[k];
-		else
-			Result = FAIL;
-
-		if (Result == PASS) {
-			k = 0;
-			j = FTL_Extract_Block_Table_Tag(pSpareBufBTLastPage,
-						&tagarray);
-			if (j) {
-				for (; k < j; k++) {
-					if (tagarray[k] == BT_Tag)
-						break;
-				}
-			}
-
-			if (k < j) {
-				bt_flag_last_page = tagarray[k];
-			} else {
-				Result = FAIL;
-				break;
-			}
-
-			if (Result == PASS) {
-				if (bt_flag == bt_flag_last_page) {
-					nand_dbg_print(NAND_DBG_DEBUG,
-						"Block table is found "
-						"in page prior to IPF "
-						"at block %u page %d\n",
-						(unsigned int)BT_Block, i);
-					BT_Found = 1;
-					*Page  = i;
-					g_cBlockTableStatus =
-						IN_PROGRESS_BLOCK_TABLE;
-					break;
-				} else {
-					Result = FAIL;
-					break;
-				}
-			}
-		}
-	}
-
-	if (Result == FAIL) {
-		if ((Last_IPF > bt_pages) && (i < Last_IPF) && (!BT_Found)) {
-			BT_Found = 1;
-			*Page = i - (bt_pages + 1);
-		}
-		if ((Last_IPF == bt_pages) && (i < Last_IPF) && (!BT_Found))
-			goto func_return;
-	}
-
-	if (Last_IPF == 0) {
-		i = 0;
-		Result = PASS;
-		nand_dbg_print(NAND_DBG_DEBUG, "Reading the spare area of "
-			"Block %u Page %u", (unsigned int)BT_Block, i);
-
-		Result = GLOB_LLD_Read_Page_Spare(pSpareBuf, BT_Block, i, 1);
-		nand_dbg_print(NAND_DBG_DEBUG,
-			"Reading the spare area of Block %u Page %u",
-			(unsigned int)BT_Block, i + bt_pages - 1);
-		Result = GLOB_LLD_Read_Page_Spare(pSpareBufBTLastPage,
-					BT_Block, i + bt_pages - 1, 1);
-
-		k = 0;
-		j = FTL_Extract_Block_Table_Tag(pSpareBuf, &tagarray);
-		if (j) {
-			for (; k < j; k++) {
-				if (tagarray[k] == BT_Tag)
-					break;
-			}
-		}
-
-		if (k < j)
-			bt_flag = tagarray[k];
-		else
-			Result = FAIL;
-
-		if (Result == PASS) {
-			k = 0;
-			j = FTL_Extract_Block_Table_Tag(pSpareBufBTLastPage,
-							&tagarray);
-			if (j) {
-				for (; k < j; k++) {
-					if (tagarray[k] == BT_Tag)
-						break;
-				}
-			}
-
-			if (k < j)
-				bt_flag_last_page = tagarray[k];
-			else
-				Result = FAIL;
-
-			if (Result == PASS) {
-				if (bt_flag == bt_flag_last_page) {
-					nand_dbg_print(NAND_DBG_DEBUG,
-						"Block table is found "
-						"in page after IPF at "
-						"block %u page %u\n",
-						(unsigned int)BT_Block,
-						(unsigned int)i);
-					BT_Found = 1;
-					*Page  = i;
-					g_cBlockTableStatus =
-						CURRENT_BLOCK_TABLE;
-					goto func_return;
-				} else {
-					Result = FAIL;
-				}
-			}
-		}
-
-		if (Result == FAIL)
-			goto func_return;
-	}
-func_return:
-	return Result;
-}
-
-u8 *get_blk_table_start_addr(void)
-{
-	return g_pBlockTable;
-}
-
-unsigned long get_blk_table_len(void)
-{
-	return DeviceInfo.wDataBlockNum * sizeof(u32);
-}
-
-u8 *get_wear_leveling_table_start_addr(void)
-{
-	return g_pWearCounter;
-}
-
-unsigned long get_wear_leveling_table_len(void)
-{
-	return DeviceInfo.wDataBlockNum * sizeof(u8);
-}
-
-/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
-* Function:     FTL_Read_Block_Table
-* Inputs:       none
-* Outputs:      PASS / FAIL
-* Description:  read the flash spare area and find a block containing the
-*               most recent block table(having largest block_table_counter).
-*               Find the last written Block table in this block.
-*               Check the correctness of Block Table
-*               If CDMA is enabled, this function is called in
-*               polling mode.
-*               We don't need to store changes in Block table in this
-*               function as it is called only at initialization
-*
-*               Note: Currently this function is called at initialization
-*               before any read/erase/write command issued to flash so,
-*               there is no need to wait for CDMA list to complete as of now
-*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
-static int FTL_Read_Block_Table(void)
-{
-	u16 i = 0;
-	int k, j;
-	u8 *tempBuf, *tagarray;
-	int wResult = FAIL;
-	int status = FAIL;
-	u8 block_table_found = 0;
-	int search_result;
-	u32 Block;
-	u16 Page = 0;
-	u16 PageCount;
-	u16 bt_pages;
-	int wBytesCopied = 0, tempvar;
-
-	nand_dbg_print(NAND_DBG_TRACE, "%s, Line %d, Function: %s\n",
-			       __FILE__, __LINE__, __func__);
-
-	tempBuf = tmp_buf1_read_blk_table;
-	bt_pages = FTL_Get_Block_Table_Flash_Size_Pages();
-
-	for (j = DeviceInfo.wSpectraStartBlock;
-		j <= (int)DeviceInfo.wSpectraEndBlock;
-			j++) {
-		status = GLOB_LLD_Read_Page_Spare(tempBuf, j, 0, 1);
-		k = 0;
-		i = FTL_Extract_Block_Table_Tag(tempBuf, &tagarray);
-		if (i) {
-			status  = GLOB_LLD_Read_Page_Main_Polling(tempBuf,
-								j, 0, 1);
-			for (; k < i; k++) {
-				if (tagarray[k] == tempBuf[3])
-					break;
-			}
-		}
-
-		if (k < i)
-			k = tagarray[k];
-		else
-			continue;
-
-		nand_dbg_print(NAND_DBG_DEBUG,
-				"Block table is contained in Block %d %d\n",
-				       (unsigned int)j, (unsigned int)k);
-
-		if (g_pBTBlocks[k-FIRST_BT_ID] == BTBLOCK_INVAL) {
-			g_pBTBlocks[k-FIRST_BT_ID] = j;
-			block_table_found = 1;
-		} else {
-			printk(KERN_ERR "FTL_Read_Block_Table -"
-				"This should never happens. "
-				"Two block table have same counter %u!\n", k);
-		}
-	}
-
-	if (block_table_found) {
-		if (g_pBTBlocks[FIRST_BT_ID - FIRST_BT_ID] != BTBLOCK_INVAL &&
-		g_pBTBlocks[LAST_BT_ID - FIRST_BT_ID] != BTBLOCK_INVAL) {
-			j = LAST_BT_ID;
-			while ((j > FIRST_BT_ID) &&
-			(g_pBTBlocks[j - FIRST_BT_ID] != BTBLOCK_INVAL))
-				j--;
-			if (j == FIRST_BT_ID) {
-				j = LAST_BT_ID;
-				last_erased = LAST_BT_ID;
-			} else {
-				last_erased = (u8)j + 1;
-				while ((j > FIRST_BT_ID) && (BTBLOCK_INVAL ==
-					g_pBTBlocks[j - FIRST_BT_ID]))
-					j--;
-			}
-		} else {
-			j = FIRST_BT_ID;
-			while (g_pBTBlocks[j - FIRST_BT_ID] == BTBLOCK_INVAL)
-				j++;
-			last_erased = (u8)j;
-			while ((j < LAST_BT_ID) && (BTBLOCK_INVAL !=
-				g_pBTBlocks[j - FIRST_BT_ID]))
-				j++;
-			if (g_pBTBlocks[j-FIRST_BT_ID] == BTBLOCK_INVAL)
-				j--;
-		}
-
-		if (last_erased > j)
-			j += (1 + LAST_BT_ID - FIRST_BT_ID);
-
-		for (; (j >= last_erased) && (FAIL == wResult); j--) {
-			i = (j - FIRST_BT_ID) %
-				(1 + LAST_BT_ID - FIRST_BT_ID);
-			search_result =
-			FTL_Search_Block_Table_IN_Block(g_pBTBlocks[i],
-						i + FIRST_BT_ID, &Page);
-			if (g_cBlockTableStatus == IN_PROGRESS_BLOCK_TABLE)
-				block_table_found = 0;
-
-			while ((search_result == PASS) && (FAIL == wResult)) {
-				nand_dbg_print(NAND_DBG_DEBUG,
-					"FTL_Read_Block_Table:"
-					"Block: %u Page: %u "
-					"contains block table\n",
-					(unsigned int)g_pBTBlocks[i],
-					(unsigned int)Page);
-
-				tempBuf = tmp_buf2_read_blk_table;
-
-				for (k = 0; k < bt_pages; k++) {
-					Block = g_pBTBlocks[i];
-					PageCount = 1;
-
-					status  =
-					GLOB_LLD_Read_Page_Main_Polling(
-					tempBuf, Block, Page, PageCount);
-
-					tempvar = k ? 0 : 4;
-
-					wBytesCopied +=
-					FTL_Copy_Block_Table_From_Flash(
-					tempBuf + tempvar,
-					DeviceInfo.wPageDataSize - tempvar,
-					wBytesCopied);
-
-					Page++;
-				}
-
-				wResult = FTL_Check_Block_Table(FAIL);
-				if (FAIL == wResult) {
-					block_table_found = 0;
-					if (Page > bt_pages)
-						Page -= ((bt_pages<<1) + 1);
-					else
-						search_result = FAIL;
-				}
-			}
-		}
-	}
-
-	if (PASS == wResult) {
-		if (!block_table_found)
-			FTL_Execute_SPL_Recovery();
-
-		if (g_cBlockTableStatus == IN_PROGRESS_BLOCK_TABLE)
-			g_wBlockTableOffset = (u16)Page + 1;
-		else
-			g_wBlockTableOffset = (u16)Page - bt_pages;
-
-		g_wBlockTableIndex = (u32)g_pBTBlocks[i];
-
-#if CMD_DMA
-		if (DeviceInfo.MLCDevice)
-			memcpy(g_pBTStartingCopy, g_pBlockTable,
-				DeviceInfo.wDataBlockNum * sizeof(u32)
-				+ DeviceInfo.wDataBlockNum * sizeof(u8)
-				+ DeviceInfo.wDataBlockNum * sizeof(u16));
-		else
-			memcpy(g_pBTStartingCopy, g_pBlockTable,
-				DeviceInfo.wDataBlockNum * sizeof(u32)
-				+ DeviceInfo.wDataBlockNum * sizeof(u8));
-#endif
-	}
-
-	if (FAIL == wResult)
-		printk(KERN_ERR "Yunpeng - "
-		"Can not find valid spectra block table!\n");
-
-#if AUTO_FORMAT_FLASH
-	if (FAIL == wResult) {
-		nand_dbg_print(NAND_DBG_DEBUG, "doing auto-format\n");
-		wResult = FTL_Format_Flash(0);
-	}
-#endif
-
-	return wResult;
-}
-
-/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
-* Function:     FTL_Get_Page_Num
-* Inputs:       Size in bytes
-* Outputs:      Size in pages
-* Description:  It calculates the pages required for the length passed
-*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
-static u32 FTL_Get_Page_Num(u64 length)
-{
-	return (u32)((length >> DeviceInfo.nBitsInPageDataSize) +
-		(GLOB_u64_Remainder(length , 1) > 0 ? 1 : 0));
-}
-
-/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
-* Function:     FTL_Get_Physical_Block_Addr
-* Inputs:       Block Address (byte format)
-* Outputs:      Physical address of the block.
-* Description:  It translates LBA to PBA by returning address stored
-*               at the LBA location in the block table
-*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
-static u64 FTL_Get_Physical_Block_Addr(u64 logical_addr)
-{
-	u32 *pbt;
-	u64 physical_addr;
-
-	nand_dbg_print(NAND_DBG_TRACE, "%s, Line %d, Function: %s\n",
-		__FILE__, __LINE__, __func__);
-
-	pbt = (u32 *)g_pBlockTable;
-	physical_addr = (u64) DeviceInfo.wBlockDataSize *
-		(pbt[BLK_FROM_ADDR(logical_addr)] & (~BAD_BLOCK));
-
-	return physical_addr;
-}
-
-/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
-* Function:     FTL_Get_Block_Index
-* Inputs:       Physical Block no.
-* Outputs:      Logical block no. /BAD_BLOCK
-* Description:  It returns the logical block no. for the PBA passed
-*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
-static u32 FTL_Get_Block_Index(u32 wBlockNum)
-{
-	u32 *pbt = (u32 *)g_pBlockTable;
-	u32 i;
-
-	nand_dbg_print(NAND_DBG_TRACE, "%s, Line %d, Function: %s\n",
-		       __FILE__, __LINE__, __func__);
-
-	for (i = 0; i < DeviceInfo.wDataBlockNum; i++)
-		if (wBlockNum == (pbt[i] & (~BAD_BLOCK)))
-			return i;
-
-	return BAD_BLOCK;
-}
-
-/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
-* Function:     GLOB_FTL_Wear_Leveling
-* Inputs:       none
-* Outputs:      PASS=0
-* Description:  This is static wear leveling (done by explicit call)
-*               do complete static wear leveling
-*               do complete garbage collection
-*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
-int GLOB_FTL_Wear_Leveling(void)
-{
-	nand_dbg_print(NAND_DBG_WARN, "%s, Line %d, Function: %s\n",
-		__FILE__, __LINE__, __func__);
-
-	FTL_Static_Wear_Leveling();
-	GLOB_FTL_Garbage_Collection();
-
-	return PASS;
-}
-
-static void find_least_most_worn(u8 *chg,
-	u32 *least_idx, u8 *least_cnt,
-	u32 *most_idx, u8 *most_cnt)
-{
-	u32 *pbt = (u32 *)g_pBlockTable;
-	u32 idx;
-	u8 cnt;
-	int i;
-
-	for (i = BLOCK_TABLE_INDEX + 1; i < DeviceInfo.wDataBlockNum; i++) {
-		if (IS_BAD_BLOCK(i) || PASS == chg[i])
-			continue;
-
-		idx = (u32) ((~BAD_BLOCK) & pbt[i]);
-		cnt = g_pWearCounter[idx - DeviceInfo.wSpectraStartBlock];
-
-		if (IS_SPARE_BLOCK(i)) {
-			if (cnt > *most_cnt) {
-				*most_cnt = cnt;
-				*most_idx = idx;
-			}
-		}
-
-		if (IS_DATA_BLOCK(i)) {
-			if (cnt < *least_cnt) {
-				*least_cnt = cnt;
-				*least_idx = idx;
-			}
-		}
-
-		if (PASS == chg[*most_idx] || PASS == chg[*least_idx]) {
-			debug_boundary_error(*most_idx,
-				DeviceInfo.wDataBlockNum, 0);
-			debug_boundary_error(*least_idx,
-				DeviceInfo.wDataBlockNum, 0);
-			continue;
-		}
-	}
-}
-
-static int move_blks_for_wear_leveling(u8 *chg,
-	u32 *least_idx, u32 *rep_blk_num, int *result)
-{
-	u32 *pbt = (u32 *)g_pBlockTable;
-	u32 rep_blk;
-	int j, ret_cp_blk, ret_erase;
-	int ret = PASS;
-
-	chg[*least_idx] = PASS;
-	debug_boundary_error(*least_idx, DeviceInfo.wDataBlockNum, 0);
-
-	rep_blk = FTL_Replace_MWBlock();
-	if (rep_blk != BAD_BLOCK) {
-		nand_dbg_print(NAND_DBG_DEBUG,
-			"More than two spare blocks exist so do it\n");
-		nand_dbg_print(NAND_DBG_DEBUG, "Block Replaced is %d\n",
-				rep_blk);
-
-		chg[rep_blk] = PASS;
-
-		if (IN_PROGRESS_BLOCK_TABLE != g_cBlockTableStatus) {
-			g_cBlockTableStatus = IN_PROGRESS_BLOCK_TABLE;
-			FTL_Write_IN_Progress_Block_Table_Page();
-		}
-
-		for (j = 0; j < RETRY_TIMES; j++) {
-			ret_cp_blk = FTL_Copy_Block((u64)(*least_idx) *
-				DeviceInfo.wBlockDataSize,
-				(u64)rep_blk * DeviceInfo.wBlockDataSize);
-			if (FAIL == ret_cp_blk) {
-				ret_erase = GLOB_FTL_Block_Erase((u64)rep_blk
-					* DeviceInfo.wBlockDataSize);
-				if (FAIL == ret_erase)
-					MARK_BLOCK_AS_BAD(pbt[rep_blk]);
-			} else {
-				nand_dbg_print(NAND_DBG_DEBUG,
-					"FTL_Copy_Block == OK\n");
-				break;
-			}
-		}
-
-		if (j < RETRY_TIMES) {
-			u32 tmp;
-			u32 old_idx = FTL_Get_Block_Index(*least_idx);
-			u32 rep_idx = FTL_Get_Block_Index(rep_blk);
-			tmp = (u32)(DISCARD_BLOCK | pbt[old_idx]);
-			pbt[old_idx] = (u32)((~SPARE_BLOCK) &
-							pbt[rep_idx]);
-			pbt[rep_idx] = tmp;
-#if CMD_DMA
-			p_BTableChangesDelta = (struct BTableChangesDelta *)
-						g_pBTDelta_Free;
-			g_pBTDelta_Free += sizeof(struct BTableChangesDelta);
-			p_BTableChangesDelta->ftl_cmd_cnt =
-						ftl_cmd_cnt;
-			p_BTableChangesDelta->BT_Index = old_idx;
-			p_BTableChangesDelta->BT_Entry_Value = pbt[old_idx];
-			p_BTableChangesDelta->ValidFields = 0x0C;
-
-			p_BTableChangesDelta = (struct BTableChangesDelta *)
-						g_pBTDelta_Free;
-			g_pBTDelta_Free += sizeof(struct BTableChangesDelta);
-
-			p_BTableChangesDelta->ftl_cmd_cnt =
-						ftl_cmd_cnt;
-			p_BTableChangesDelta->BT_Index = rep_idx;
-			p_BTableChangesDelta->BT_Entry_Value = pbt[rep_idx];
-			p_BTableChangesDelta->ValidFields = 0x0C;
-#endif
-		} else {
-			pbt[FTL_Get_Block_Index(rep_blk)] |= BAD_BLOCK;
-#if CMD_DMA
-			p_BTableChangesDelta = (struct BTableChangesDelta *)
-						g_pBTDelta_Free;
-			g_pBTDelta_Free += sizeof(struct BTableChangesDelta);
-
-			p_BTableChangesDelta->ftl_cmd_cnt =
-						ftl_cmd_cnt;
-			p_BTableChangesDelta->BT_Index =
-					FTL_Get_Block_Index(rep_blk);
-			p_BTableChangesDelta->BT_Entry_Value =
-					pbt[FTL_Get_Block_Index(rep_blk)];
-			p_BTableChangesDelta->ValidFields = 0x0C;
-#endif
-			*result = FAIL;
-			ret = FAIL;
-		}
-
-		if (((*rep_blk_num)++) > WEAR_LEVELING_BLOCK_NUM)
-			ret = FAIL;
-	} else {
-		printk(KERN_ERR "Less than 3 spare blocks exist so quit\n");
-		ret = FAIL;
-	}
-
-	return ret;
-}
-
-/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
-* Function:     FTL_Static_Wear_Leveling
-* Inputs:       none
-* Outputs:      PASS=0 / FAIL=1
-* Description:  This is static wear leveling (done by explicit call)
-*               search for most&least used
-*               if difference < GATE:
-*                   update the block table with exhange
-*                   mark block table in flash as IN_PROGRESS
-*                   copy flash block
-*               the caller should handle GC clean up after calling this function
-*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
-int FTL_Static_Wear_Leveling(void)
-{
-	u8 most_worn_cnt;
-	u8 least_worn_cnt;
-	u32 most_worn_idx;
-	u32 least_worn_idx;
-	int result = PASS;
-	int go_on = PASS;
-	u32 replaced_blks = 0;
-	u8 *chang_flag = flags_static_wear_leveling;
-
-	nand_dbg_print(NAND_DBG_WARN, "%s, Line %d, Function: %s\n",
-		       __FILE__, __LINE__, __func__);
-
-	if (!chang_flag)
-		return FAIL;
-
-	memset(chang_flag, FAIL, DeviceInfo.wDataBlockNum);
-	while (go_on == PASS) {
-		nand_dbg_print(NAND_DBG_DEBUG,
-			"starting static wear leveling\n");
-		most_worn_cnt = 0;
-		least_worn_cnt = 0xFF;
-		least_worn_idx = BLOCK_TABLE_INDEX;
-		most_worn_idx = BLOCK_TABLE_INDEX;
-
-		find_least_most_worn(chang_flag, &least_worn_idx,
-			&least_worn_cnt, &most_worn_idx, &most_worn_cnt);
-
-		nand_dbg_print(NAND_DBG_DEBUG,
-			"Used and least worn is block %u, whos count is %u\n",
-			(unsigned int)least_worn_idx,
-			(unsigned int)least_worn_cnt);
-
-		nand_dbg_print(NAND_DBG_DEBUG,
-			"Free and  most worn is block %u, whos count is %u\n",
-			(unsigned int)most_worn_idx,
-			(unsigned int)most_worn_cnt);
-
-		if ((most_worn_cnt > least_worn_cnt) &&
-			(most_worn_cnt - least_worn_cnt > WEAR_LEVELING_GATE))
-			go_on = move_blks_for_wear_leveling(chang_flag,
-				&least_worn_idx, &replaced_blks, &result);
-		else
-			go_on = FAIL;
-	}
-
-	return result;
-}
-
-#if CMD_DMA
-static int do_garbage_collection(u32 discard_cnt)
-{
-	u32 *pbt = (u32 *)g_pBlockTable;
-	u32 pba;
-	u8 bt_block_erased = 0;
-	int i, cnt, ret = FAIL;
-	u64 addr;
-
-	i = 0;
-	while ((i < DeviceInfo.wDataBlockNum) && (discard_cnt > 0) &&
-			((ftl_cmd_cnt + 28) < 256)) {
-		if (((pbt[i] & BAD_BLOCK) != BAD_BLOCK) &&
-				(pbt[i] & DISCARD_BLOCK)) {
-			if (IN_PROGRESS_BLOCK_TABLE != g_cBlockTableStatus) {
-				g_cBlockTableStatus = IN_PROGRESS_BLOCK_TABLE;
-				FTL_Write_IN_Progress_Block_Table_Page();
-			}
-
-			addr = FTL_Get_Physical_Block_Addr((u64)i *
-						DeviceInfo.wBlockDataSize);
-			pba = BLK_FROM_ADDR(addr);
-
-			for (cnt = FIRST_BT_ID; cnt <= LAST_BT_ID; cnt++) {
-				if (pba == g_pBTBlocks[cnt - FIRST_BT_ID]) {
-					nand_dbg_print(NAND_DBG_DEBUG,
-						"GC will erase BT block %u\n",
-						(unsigned int)pba);
-					discard_cnt--;
-					i++;
-					bt_block_erased = 1;
-					break;
-				}
-			}
-
-			if (bt_block_erased) {
-				bt_block_erased = 0;
-				continue;
-			}
-
-			addr = FTL_Get_Physical_Block_Addr((u64)i *
-						DeviceInfo.wBlockDataSize);
-
-			if (PASS == GLOB_FTL_Block_Erase(addr)) {
-				pbt[i] &= (u32)(~DISCARD_BLOCK);
-				pbt[i] |= (u32)(SPARE_BLOCK);
-				p_BTableChangesDelta =
-					(struct BTableChangesDelta *)
-					g_pBTDelta_Free;
-				g_pBTDelta_Free +=
-					sizeof(struct BTableChangesDelta);
-				p_BTableChangesDelta->ftl_cmd_cnt =
-					ftl_cmd_cnt - 1;
-				p_BTableChangesDelta->BT_Index = i;
-				p_BTableChangesDelta->BT_Entry_Value = pbt[i];
-				p_BTableChangesDelta->ValidFields = 0x0C;
-				discard_cnt--;
-				ret = PASS;
-			} else {
-				MARK_BLOCK_AS_BAD(pbt[i]);
-			}
-		}
-
-		i++;
-	}
-
-	return ret;
-}
-
-#else
-static int do_garbage_collection(u32 discard_cnt)
-{
-	u32 *pbt = (u32 *)g_pBlockTable;
-	u32 pba;
-	u8 bt_block_erased = 0;
-	int i, cnt, ret = FAIL;
-	u64 addr;
-
-	i = 0;
-	while ((i < DeviceInfo.wDataBlockNum) && (discard_cnt > 0)) {
-		if (((pbt[i] & BAD_BLOCK) != BAD_BLOCK) &&
-				(pbt[i] & DISCARD_BLOCK)) {
-			if (IN_PROGRESS_BLOCK_TABLE != g_cBlockTableStatus) {
-				g_cBlockTableStatus = IN_PROGRESS_BLOCK_TABLE;
-				FTL_Write_IN_Progress_Block_Table_Page();
-			}
-
-			addr = FTL_Get_Physical_Block_Addr((u64)i *
-						DeviceInfo.wBlockDataSize);
-			pba = BLK_FROM_ADDR(addr);
-
-			for (cnt = FIRST_BT_ID; cnt <= LAST_BT_ID; cnt++) {
-				if (pba == g_pBTBlocks[cnt - FIRST_BT_ID]) {
-					nand_dbg_print(NAND_DBG_DEBUG,
-						"GC will erase BT block %d\n",
-						pba);
-					discard_cnt--;
-					i++;
-					bt_block_erased = 1;
-					break;
-				}
-			}
-
-			if (bt_block_erased) {
-				bt_block_erased = 0;
-				continue;
-			}
-
-			/* If the discard block is L2 cache block, then just skip it */
-			for (cnt = 0; cnt < BLK_NUM_FOR_L2_CACHE; cnt++) {
-				if (cache_l2.blk_array[cnt] == pba) {
-					nand_dbg_print(NAND_DBG_DEBUG,
-						"GC will erase L2 cache blk %d\n",
-						pba);
-					break;
-				}
-			}
-			if (cnt < BLK_NUM_FOR_L2_CACHE) { /* Skip it */
-				discard_cnt--;
-				i++;
-				continue;
-			}
-
-			addr = FTL_Get_Physical_Block_Addr((u64)i *
-						DeviceInfo.wBlockDataSize);
-
-			if (PASS == GLOB_FTL_Block_Erase(addr)) {
-				pbt[i] &= (u32)(~DISCARD_BLOCK);
-				pbt[i] |= (u32)(SPARE_BLOCK);
-				discard_cnt--;
-				ret = PASS;
-			} else {
-				MARK_BLOCK_AS_BAD(pbt[i]);
-			}
-		}
-
-		i++;
-	}
-
-	return ret;
-}
-#endif
-
-/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
-* Function:     GLOB_FTL_Garbage_Collection
-* Inputs:       none
-* Outputs:      PASS / FAIL (returns the number of un-erased blocks
-* Description:  search the block table for all discarded blocks to erase
-*               for each discarded block:
-*                   set the flash block to IN_PROGRESS
-*                   erase the block
-*                   update the block table
-*                   write the block table to flash
-*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
-int GLOB_FTL_Garbage_Collection(void)
-{
-	u32 i;
-	u32 wDiscard = 0;
-	int wResult = FAIL;
-	u32 *pbt = (u32 *)g_pBlockTable;
-
-	nand_dbg_print(NAND_DBG_WARN, "%s, Line %d, Function: %s\n",
-			       __FILE__, __LINE__, __func__);
-
-	if (GC_Called) {
-		printk(KERN_ALERT "GLOB_FTL_Garbage_Collection() "
-			"has been re-entered! Exit.\n");
-		return PASS;
-	}
-
-	GC_Called = 1;
-
-	GLOB_FTL_BT_Garbage_Collection();
-
-	for (i = 0; i < DeviceInfo.wDataBlockNum; i++) {
-		if (IS_DISCARDED_BLOCK(i))
-			wDiscard++;
-	}
-
-	if (wDiscard <= 0) {
-		GC_Called = 0;
-		return wResult;
-	}
-
-	nand_dbg_print(NAND_DBG_DEBUG,
-		"Found %d discarded blocks\n", wDiscard);
-
-	FTL_Write_Block_Table(FAIL);
-
-	wResult = do_garbage_collection(wDiscard);
-
-	FTL_Write_Block_Table(FAIL);
-
-	GC_Called = 0;
-
-	return wResult;
-}
-
-
-#if CMD_DMA
-static int do_bt_garbage_collection(void)
-{
-	u32 pba, lba;
-	u32 *pbt = (u32 *)g_pBlockTable;
-	u32 *pBTBlocksNode = (u32 *)g_pBTBlocks;
-	u64 addr;
-	int i, ret = FAIL;
-
-	nand_dbg_print(NAND_DBG_TRACE, "%s, Line %d, Function: %s\n",
-			       __FILE__, __LINE__, __func__);
-
-	if (BT_GC_Called)
-		return PASS;
-
-	BT_GC_Called = 1;
-
-	for (i = last_erased; (i <= LAST_BT_ID) &&
-		(g_pBTBlocks[((i + 2) % (1 + LAST_BT_ID - FIRST_BT_ID)) +
-		FIRST_BT_ID - FIRST_BT_ID] != BTBLOCK_INVAL) &&
-		((ftl_cmd_cnt + 28)) < 256; i++) {
-		pba = pBTBlocksNode[i - FIRST_BT_ID];
-		lba = FTL_Get_Block_Index(pba);
-		nand_dbg_print(NAND_DBG_DEBUG,
-			"do_bt_garbage_collection: pba %d, lba %d\n",
-			pba, lba);
-		nand_dbg_print(NAND_DBG_DEBUG,
-			"Block Table Entry: %d", pbt[lba]);
-
-		if (((pbt[lba] & BAD_BLOCK) != BAD_BLOCK) &&
-			(pbt[lba] & DISCARD_BLOCK)) {
-			nand_dbg_print(NAND_DBG_DEBUG,
-				"do_bt_garbage_collection_cdma: "
-				"Erasing Block tables present in block %d\n",
-				pba);
-			addr = FTL_Get_Physical_Block_Addr((u64)lba *
-						DeviceInfo.wBlockDataSize);
-			if (PASS == GLOB_FTL_Block_Erase(addr)) {
-				pbt[lba] &= (u32)(~DISCARD_BLOCK);
-				pbt[lba] |= (u32)(SPARE_BLOCK);
-
-				p_BTableChangesDelta =
-					(struct BTableChangesDelta *)
-					g_pBTDelta_Free;
-				g_pBTDelta_Free +=
-					sizeof(struct BTableChangesDelta);
-
-				p_BTableChangesDelta->ftl_cmd_cnt =
-					ftl_cmd_cnt - 1;
-				p_BTableChangesDelta->BT_Index = lba;
-				p_BTableChangesDelta->BT_Entry_Value =
-								pbt[lba];
-
-				p_BTableChangesDelta->ValidFields = 0x0C;
-
-				ret = PASS;
-				pBTBlocksNode[last_erased - FIRST_BT_ID] =
-							BTBLOCK_INVAL;
-				nand_dbg_print(NAND_DBG_DEBUG,
-					"resetting bt entry at index %d "
-					"value %d\n", i,
-					pBTBlocksNode[i - FIRST_BT_ID]);
-				if (last_erased == LAST_BT_ID)
-					last_erased = FIRST_BT_ID;
-				else
-					last_erased++;
-			} else {
-				MARK_BLOCK_AS_BAD(pbt[lba]);
-			}
-		}
-	}
-
-	BT_GC_Called = 0;
-
-	return ret;
-}
-
-#else
-static int do_bt_garbage_collection(void)
-{
-	u32 pba, lba;
-	u32 *pbt = (u32 *)g_pBlockTable;
-	u32 *pBTBlocksNode = (u32 *)g_pBTBlocks;
-	u64 addr;
-	int i, ret = FAIL;
-
-	nand_dbg_print(NAND_DBG_TRACE, "%s, Line %d, Function: %s\n",
-			       __FILE__, __LINE__, __func__);
-
-	if (BT_GC_Called)
-		return PASS;
-
-	BT_GC_Called = 1;
-
-	for (i = last_erased; (i <= LAST_BT_ID) &&
-		(g_pBTBlocks[((i + 2) % (1 + LAST_BT_ID - FIRST_BT_ID)) +
-		FIRST_BT_ID - FIRST_BT_ID] != BTBLOCK_INVAL); i++) {
-		pba = pBTBlocksNode[i - FIRST_BT_ID];
-		lba = FTL_Get_Block_Index(pba);
-		nand_dbg_print(NAND_DBG_DEBUG,
-			"do_bt_garbage_collection_cdma: pba %d, lba %d\n",
-			pba, lba);
-		nand_dbg_print(NAND_DBG_DEBUG,
-			"Block Table Entry: %d", pbt[lba]);
-
-		if (((pbt[lba] & BAD_BLOCK) != BAD_BLOCK) &&
-			(pbt[lba] & DISCARD_BLOCK)) {
-			nand_dbg_print(NAND_DBG_DEBUG,
-				"do_bt_garbage_collection: "
-				"Erasing Block tables present in block %d\n",
-				pba);
-			addr = FTL_Get_Physical_Block_Addr((u64)lba *
-						DeviceInfo.wBlockDataSize);
-			if (PASS == GLOB_FTL_Block_Erase(addr)) {
-				pbt[lba] &= (u32)(~DISCARD_BLOCK);
-				pbt[lba] |= (u32)(SPARE_BLOCK);
-				ret = PASS;
-				pBTBlocksNode[last_erased - FIRST_BT_ID] =
-							BTBLOCK_INVAL;
-				nand_dbg_print(NAND_DBG_DEBUG,
-					"resetting bt entry at index %d "
-					"value %d\n", i,
-					pBTBlocksNode[i - FIRST_BT_ID]);
-				if (last_erased == LAST_BT_ID)
-					last_erased = FIRST_BT_ID;
-				else
-					last_erased++;
-			} else {
-				MARK_BLOCK_AS_BAD(pbt[lba]);
-			}
-		}
-	}
-
-	BT_GC_Called = 0;
-
-	return ret;
-}
-
-#endif
-
-/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
-* Function:     GLOB_FTL_BT_Garbage_Collection
-* Inputs:       none
-* Outputs:      PASS / FAIL (returns the number of un-erased blocks
-* Description:  Erases discarded blocks containing Block table
-*
-*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
-int GLOB_FTL_BT_Garbage_Collection(void)
-{
-	return do_bt_garbage_collection();
-}
-
-/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
-* Function:     FTL_Replace_OneBlock
-* Inputs:       Block number 1
-*               Block number 2
-* Outputs:      Replaced Block Number
-* Description:  Interchange block table entries at wBlockNum and wReplaceNum
-*
-*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
-static u32 FTL_Replace_OneBlock(u32 blk, u32 rep_blk)
-{
-	u32 tmp_blk;
-	u32 replace_node = BAD_BLOCK;
-	u32 *pbt = (u32 *)g_pBlockTable;
-
-	nand_dbg_print(NAND_DBG_TRACE, "%s, Line %d, Function: %s\n",
-		__FILE__, __LINE__, __func__);
-
-	if (rep_blk != BAD_BLOCK) {
-		if (IS_BAD_BLOCK(blk))
-			tmp_blk = pbt[blk];
-		else
-			tmp_blk = DISCARD_BLOCK | (~SPARE_BLOCK & pbt[blk]);
-
-		replace_node = (u32) ((~SPARE_BLOCK) & pbt[rep_blk]);
-		pbt[blk] = replace_node;
-		pbt[rep_blk] = tmp_blk;
-
-#if CMD_DMA
-		p_BTableChangesDelta =
-			(struct BTableChangesDelta *)g_pBTDelta_Free;
-		g_pBTDelta_Free += sizeof(struct BTableChangesDelta);
-
-		p_BTableChangesDelta->ftl_cmd_cnt = ftl_cmd_cnt;
-		p_BTableChangesDelta->BT_Index = blk;
-		p_BTableChangesDelta->BT_Entry_Value = pbt[blk];
-
-		p_BTableChangesDelta->ValidFields = 0x0C;
-
-		p_BTableChangesDelta =
-			(struct BTableChangesDelta *)g_pBTDelta_Free;
-		g_pBTDelta_Free += sizeof(struct BTableChangesDelta);
-
-		p_BTableChangesDelta->ftl_cmd_cnt = ftl_cmd_cnt;
-		p_BTableChangesDelta->BT_Index = rep_blk;
-		p_BTableChangesDelta->BT_Entry_Value = pbt[rep_blk];
-		p_BTableChangesDelta->ValidFields = 0x0C;
-#endif
-	}
-
-	return replace_node;
-}
-
-/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
-* Function:     FTL_Write_Block_Table_Data
-* Inputs:       Block table size in pages
-* Outputs:      PASS=0 / FAIL=1
-* Description:  Write block table data in flash
-*               If first page and last page
-*                  Write data+BT flag
-*               else
-*                  Write data
-*               BT flag is a counter. Its value is incremented for block table
-*               write in a new Block
-*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
-static int FTL_Write_Block_Table_Data(void)
-{
-	u64 dwBlockTableAddr, pTempAddr;
-	u32 Block;
-	u16 Page, PageCount;
-	u8 *tempBuf = tmp_buf_write_blk_table_data;
-	int wBytesCopied;
-	u16 bt_pages;
-
-	nand_dbg_print(NAND_DBG_TRACE, "%s, Line %d, Function: %s\n",
-			       __FILE__, __LINE__, __func__);
-
-	dwBlockTableAddr =
-		(u64)((u64)g_wBlockTableIndex * DeviceInfo.wBlockDataSize +
-		(u64)g_wBlockTableOffset * DeviceInfo.wPageDataSize);
-	pTempAddr = dwBlockTableAddr;
-
-	bt_pages = FTL_Get_Block_Table_Flash_Size_Pages();
-
-	nand_dbg_print(NAND_DBG_DEBUG, "FTL_Write_Block_Table_Data: "
-			       "page= %d BlockTableIndex= %d "
-			       "BlockTableOffset=%d\n", bt_pages,
-			       g_wBlockTableIndex, g_wBlockTableOffset);
-
-	Block = BLK_FROM_ADDR(pTempAddr);
-	Page = PAGE_FROM_ADDR(pTempAddr, Block);
-	PageCount = 1;
-
-	if (bt_block_changed) {
-		if (bt_flag == LAST_BT_ID) {
-			bt_flag = FIRST_BT_ID;
-			g_pBTBlocks[bt_flag - FIRST_BT_ID] = Block;
-		} else if (bt_flag < LAST_BT_ID) {
-			bt_flag++;
-			g_pBTBlocks[bt_flag - FIRST_BT_ID] = Block;
-		}
-
-		if ((bt_flag > (LAST_BT_ID-4)) &&
-			g_pBTBlocks[FIRST_BT_ID - FIRST_BT_ID] !=
-						BTBLOCK_INVAL) {
-			bt_block_changed = 0;
-			GLOB_FTL_BT_Garbage_Collection();
-		}
-
-		bt_block_changed = 0;
-		nand_dbg_print(NAND_DBG_DEBUG,
-			"Block Table Counter is %u Block %u\n",
-			bt_flag, (unsigned int)Block);
-	}
-
-	memset(tempBuf, 0, 3);
-	tempBuf[3] = bt_flag;
-	wBytesCopied = FTL_Copy_Block_Table_To_Flash(tempBuf + 4,
-			DeviceInfo.wPageDataSize - 4, 0);
-	memset(&tempBuf[wBytesCopied + 4], 0xff,
-		DeviceInfo.wPageSize - (wBytesCopied + 4));
-	FTL_Insert_Block_Table_Signature(&tempBuf[DeviceInfo.wPageDataSize],
-					bt_flag);
-
-#if CMD_DMA
-	memcpy(g_pNextBlockTable, tempBuf,
-		DeviceInfo.wPageSize * sizeof(u8));
-	nand_dbg_print(NAND_DBG_DEBUG, "Writing First Page of Block Table "
-		"Block %u Page %u\n", (unsigned int)Block, Page);
-	if (FAIL == GLOB_LLD_Write_Page_Main_Spare_cdma(g_pNextBlockTable,
-		Block, Page, 1,
-		LLD_CMD_FLAG_MODE_CDMA | LLD_CMD_FLAG_ORDER_BEFORE_REST)) {
-		nand_dbg_print(NAND_DBG_WARN, "NAND Program fail in "
-			"%s, Line %d, Function: %s, "
-			"new Bad Block %d generated!\n",
-			__FILE__, __LINE__, __func__, Block);
-		goto func_return;
-	}
-
-	ftl_cmd_cnt++;
-	g_pNextBlockTable += ((DeviceInfo.wPageSize * sizeof(u8)));
-#else
-	if (FAIL == GLOB_LLD_Write_Page_Main_Spare(tempBuf, Block, Page, 1)) {
-		nand_dbg_print(NAND_DBG_WARN,
-			"NAND Program fail in %s, Line %d, Function: %s, "
-			"new Bad Block %d generated!\n",
-			__FILE__, __LINE__, __func__, Block);
-		goto func_return;
-	}
-#endif
-
-	if (bt_pages > 1) {
-		PageCount = bt_pages - 1;
-		if (PageCount > 1) {
-			wBytesCopied += FTL_Copy_Block_Table_To_Flash(tempBuf,
-				DeviceInfo.wPageDataSize * (PageCount - 1),
-				wBytesCopied);
-
-#if CMD_DMA
-			memcpy(g_pNextBlockTable, tempBuf,
-				(PageCount - 1) * DeviceInfo.wPageDataSize);
-			if (FAIL == GLOB_LLD_Write_Page_Main_cdma(
-				g_pNextBlockTable, Block, Page + 1,
-				PageCount - 1)) {
-				nand_dbg_print(NAND_DBG_WARN,
-					"NAND Program fail in %s, Line %d, "
-					"Function: %s, "
-					"new Bad Block %d generated!\n",
-					__FILE__, __LINE__, __func__,
-					(int)Block);
-				goto func_return;
-			}
-
-			ftl_cmd_cnt++;
-			g_pNextBlockTable += (PageCount - 1) *
-				DeviceInfo.wPageDataSize * sizeof(u8);
-#else
-			if (FAIL == GLOB_LLD_Write_Page_Main(tempBuf,
-					Block, Page + 1, PageCount - 1)) {
-				nand_dbg_print(NAND_DBG_WARN,
-					"NAND Program fail in %s, Line %d, "
-					"Function: %s, "
-					"new Bad Block %d generated!\n",
-					__FILE__, __LINE__, __func__,
-					(int)Block);
-				goto func_return;
-			}
-#endif
-		}
-
-		wBytesCopied = FTL_Copy_Block_Table_To_Flash(tempBuf,
-				DeviceInfo.wPageDataSize, wBytesCopied);
-		memset(&tempBuf[wBytesCopied], 0xff,
-			DeviceInfo.wPageSize-wBytesCopied);
-		FTL_Insert_Block_Table_Signature(
-			&tempBuf[DeviceInfo.wPageDataSize], bt_flag);
-#if CMD_DMA
-		memcpy(g_pNextBlockTable, tempBuf,
-				DeviceInfo.wPageSize * sizeof(u8));
-		nand_dbg_print(NAND_DBG_DEBUG,
-			"Writing the last Page of Block Table "
-			"Block %u Page %u\n",
-			(unsigned int)Block, Page + bt_pages - 1);
-		if (FAIL == GLOB_LLD_Write_Page_Main_Spare_cdma(
-			g_pNextBlockTable, Block, Page + bt_pages - 1, 1,
-			LLD_CMD_FLAG_MODE_CDMA |
-			LLD_CMD_FLAG_ORDER_BEFORE_REST)) {
-			nand_dbg_print(NAND_DBG_WARN,
-				"NAND Program fail in %s, Line %d, "
-				"Function: %s, new Bad Block %d generated!\n",
-				__FILE__, __LINE__, __func__, Block);
-			goto func_return;
-		}
-		ftl_cmd_cnt++;
-#else
-		if (FAIL == GLOB_LLD_Write_Page_Main_Spare(tempBuf,
-					Block, Page+bt_pages - 1, 1)) {
-			nand_dbg_print(NAND_DBG_WARN,
-				"NAND Program fail in %s, Line %d, "
-				"Function: %s, "
-				"new Bad Block %d generated!\n",
-				__FILE__, __LINE__, __func__, Block);
-			goto func_return;
-		}
-#endif
-	}
-
-	nand_dbg_print(NAND_DBG_DEBUG, "FTL_Write_Block_Table_Data: done\n");
-
-func_return:
-	return PASS;
-}
-
-/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
-* Function:     FTL_Replace_Block_Table
-* Inputs:       None
-* Outputs:      PASS=0 / FAIL=1
-* Description:  Get a new block to write block table
-*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
-static u32 FTL_Replace_Block_Table(void)
-{
-	u32 blk;
-	int gc;
-
-	nand_dbg_print(NAND_DBG_TRACE, "%s, Line %d, Function: %s\n",
-		__FILE__, __LINE__, __func__);
-
-	blk = FTL_Replace_LWBlock(BLOCK_TABLE_INDEX, &gc);
-
-	if ((BAD_BLOCK == blk) && (PASS == gc)) {
-		GLOB_FTL_Garbage_Collection();
-		blk = FTL_Replace_LWBlock(BLOCK_TABLE_INDEX, &gc);
-	}
-	if (BAD_BLOCK == blk)
-		printk(KERN_ERR "%s, %s: There is no spare block. "
-			"It should never happen\n",
-			__FILE__, __func__);
-
-	nand_dbg_print(NAND_DBG_DEBUG, "New Block table Block is %d\n", blk);
-
-	return blk;
-}
-
-/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
-* Function:     FTL_Replace_LWBlock
-* Inputs:       Block number
-*               Pointer to Garbage Collect flag
-* Outputs:
-* Description:  Determine the least weared block by traversing
-*               block table
-*               Set Garbage collection to be called if number of spare
-*               block is less than Free Block Gate count
-*               Change Block table entry to map least worn block for current
-*               operation
-*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
-static u32 FTL_Replace_LWBlock(u32 wBlockNum, int *pGarbageCollect)
-{
-	u32 i;
-	u32 *pbt = (u32 *)g_pBlockTable;
-	u8 wLeastWornCounter = 0xFF;
-	u32 wLeastWornIndex = BAD_BLOCK;
-	u32 wSpareBlockNum = 0;
-	u32 wDiscardBlockNum = 0;
-
-	nand_dbg_print(NAND_DBG_TRACE, "%s, Line %d, Function: %s\n",
-		__FILE__, __LINE__, __func__);
-
-	if (IS_SPARE_BLOCK(wBlockNum)) {
-		*pGarbageCollect = FAIL;
-		pbt[wBlockNum] = (u32)(pbt[wBlockNum] & (~SPARE_BLOCK));
-#if CMD_DMA
-		p_BTableChangesDelta =
-			(struct BTableChangesDelta *)g_pBTDelta_Free;
-		g_pBTDelta_Free += sizeof(struct BTableChangesDelta);
-		p_BTableChangesDelta->ftl_cmd_cnt =
-						ftl_cmd_cnt;
-		p_BTableChangesDelta->BT_Index = (u32)(wBlockNum);
-		p_BTableChangesDelta->BT_Entry_Value = pbt[wBlockNum];
-		p_BTableChangesDelta->ValidFields = 0x0C;
-#endif
-		return pbt[wBlockNum];
-	}
-
-	for (i = 0; i < DeviceInfo.wDataBlockNum; i++) {
-		if (IS_DISCARDED_BLOCK(i))
-			wDiscardBlockNum++;
-
-		if (IS_SPARE_BLOCK(i)) {
-			u32 wPhysicalIndex = (u32)((~BAD_BLOCK) & pbt[i]);
-			if (wPhysicalIndex > DeviceInfo.wSpectraEndBlock)
-				printk(KERN_ERR "FTL_Replace_LWBlock: "
-					"This should never occur!\n");
-			if (g_pWearCounter[wPhysicalIndex -
-				DeviceInfo.wSpectraStartBlock] <
-				wLeastWornCounter) {
-				wLeastWornCounter =
-					g_pWearCounter[wPhysicalIndex -
-					DeviceInfo.wSpectraStartBlock];
-				wLeastWornIndex = i;
-			}
-			wSpareBlockNum++;
-		}
-	}
-
-	nand_dbg_print(NAND_DBG_WARN,
-		"FTL_Replace_LWBlock: Least Worn Counter %d\n",
-		(int)wLeastWornCounter);
-
-	if ((wDiscardBlockNum >= NUM_FREE_BLOCKS_GATE) ||
-		(wSpareBlockNum <= NUM_FREE_BLOCKS_GATE))
-		*pGarbageCollect = PASS;
-	else
-		*pGarbageCollect = FAIL;
-
-	nand_dbg_print(NAND_DBG_DEBUG,
-		"FTL_Replace_LWBlock: Discarded Blocks %u Spare"
-		" Blocks %u\n",
-		(unsigned int)wDiscardBlockNum,
-		(unsigned int)wSpareBlockNum);
-
-	return FTL_Replace_OneBlock(wBlockNum, wLeastWornIndex);
-}
-
-/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
-* Function:     FTL_Replace_MWBlock
-* Inputs:       None
-* Outputs:      most worn spare block no./BAD_BLOCK
-* Description:  It finds most worn spare block.
-*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
-static u32 FTL_Replace_MWBlock(void)
-{
-	u32 i;
-	u32 *pbt = (u32 *)g_pBlockTable;
-	u8 wMostWornCounter = 0;
-	u32 wMostWornIndex = BAD_BLOCK;
-	u32 wSpareBlockNum = 0;
-
-	nand_dbg_print(NAND_DBG_TRACE, "%s, Line %d, Function: %s\n",
-		       __FILE__, __LINE__, __func__);
-
-	for (i = 0; i < DeviceInfo.wDataBlockNum; i++) {
-		if (IS_SPARE_BLOCK(i)) {
-			u32 wPhysicalIndex = (u32)((~SPARE_BLOCK) & pbt[i]);
-			if (g_pWearCounter[wPhysicalIndex -
-			    DeviceInfo.wSpectraStartBlock] >
-			    wMostWornCounter) {
-				wMostWornCounter =
-				    g_pWearCounter[wPhysicalIndex -
-				    DeviceInfo.wSpectraStartBlock];
-				wMostWornIndex = wPhysicalIndex;
-			}
-			wSpareBlockNum++;
-		}
-	}
-
-	if (wSpareBlockNum <= 2)
-		return BAD_BLOCK;
-
-	return wMostWornIndex;
-}
-
-/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
-* Function:     FTL_Replace_Block
-* Inputs:       Block Address
-* Outputs:      PASS=0 / FAIL=1
-* Description:  If block specified by blk_addr parameter is not free,
-*               replace it with the least worn block.
-*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
-static int FTL_Replace_Block(u64 blk_addr)
-{
-	u32 current_blk = BLK_FROM_ADDR(blk_addr);
-	u32 *pbt = (u32 *)g_pBlockTable;
-	int wResult = PASS;
-	int GarbageCollect = FAIL;
-
-	nand_dbg_print(NAND_DBG_TRACE, "%s, Line %d, Function: %s\n",
-		__FILE__, __LINE__, __func__);
-
-	if (IS_SPARE_BLOCK(current_blk)) {
-		pbt[current_blk] = (~SPARE_BLOCK) & pbt[current_blk];
-#if CMD_DMA
-		p_BTableChangesDelta =
-			(struct BTableChangesDelta *)g_pBTDelta_Free;
-		g_pBTDelta_Free += sizeof(struct BTableChangesDelta);
-		p_BTableChangesDelta->ftl_cmd_cnt =
-			ftl_cmd_cnt;
-		p_BTableChangesDelta->BT_Index = current_blk;
-		p_BTableChangesDelta->BT_Entry_Value = pbt[current_blk];
-		p_BTableChangesDelta->ValidFields = 0x0C ;
-#endif
-		return wResult;
-	}
-
-	FTL_Replace_LWBlock(current_blk, &GarbageCollect);
-
-	if (PASS == GarbageCollect)
-		wResult = GLOB_FTL_Garbage_Collection();
-
-	return wResult;
-}
-
-/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
-* Function:     GLOB_FTL_Is_BadBlock
-* Inputs:       block number to test
-* Outputs:      PASS (block is BAD) / FAIL (block is not bad)
-* Description:  test if this block number is flagged as bad
-*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
-int GLOB_FTL_Is_BadBlock(u32 wBlockNum)
-{
-	u32 *pbt = (u32 *)g_pBlockTable;
-
-	nand_dbg_print(NAND_DBG_TRACE, "%s, Line %d, Function: %s\n",
-		__FILE__, __LINE__, __func__);
-
-	if (wBlockNum >= DeviceInfo.wSpectraStartBlock
-		&& BAD_BLOCK == (pbt[wBlockNum] & BAD_BLOCK))
-		return PASS;
-	else
-		return FAIL;
-}
-
-/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
-* Function:     GLOB_FTL_Flush_Cache
-* Inputs:       none
-* Outputs:      PASS=0 / FAIL=1
-* Description:  flush all the cache blocks to flash
-*               if a cache block is not dirty, don't do anything with it
-*               else, write the block and update the block table
-* Note:         This function should be called at shutdown/power down.
-*               to write important data into device
-*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
-int GLOB_FTL_Flush_Cache(void)
-{
-	int i, ret;
-
-	nand_dbg_print(NAND_DBG_WARN, "%s, Line %d, Function: %s\n",
-		       __FILE__, __LINE__, __func__);
-
-	for (i = 0; i < CACHE_ITEM_NUM; i++) {
-		if (SET == Cache.array[i].changed) {
-#if CMD_DMA
-#if RESTORE_CACHE_ON_CDMA_CHAIN_FAILURE
-			int_cache[ftl_cmd_cnt].item = i;
-			int_cache[ftl_cmd_cnt].cache.address =
-					Cache.array[i].address;
-			int_cache[ftl_cmd_cnt].cache.changed = CLEAR;
-#endif
-#endif
-			ret = write_back_to_l2_cache(Cache.array[i].buf, Cache.array[i].address);
-			if (PASS == ret) {
-				Cache.array[i].changed = CLEAR;
-			} else {
-				printk(KERN_ALERT "Failed when write back to L2 cache!\n");
-				/* TODO - How to handle this? */
-			}
-		}
-	}
-
-	flush_l2_cache();
-
-	return FTL_Write_Block_Table(FAIL);
-}
-
-/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
-* Function:     GLOB_FTL_Page_Read
-* Inputs:       pointer to data
-*                   logical address of data (u64 is LBA * Bytes/Page)
-* Outputs:      PASS=0 / FAIL=1
-* Description:  reads a page of data into RAM from the cache
-*               if the data is not already in cache, read from flash to cache
-*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
-int GLOB_FTL_Page_Read(u8 *data, u64 logical_addr)
-{
-	u16 cache_item;
-	int res = PASS;
-
-	nand_dbg_print(NAND_DBG_DEBUG, "GLOB_FTL_Page_Read - "
-		"page_addr: %llu\n", logical_addr);
-
-	cache_item = FTL_Cache_If_Hit(logical_addr);
-
-	if (UNHIT_CACHE_ITEM == cache_item) {
-		nand_dbg_print(NAND_DBG_DEBUG,
-			       "GLOB_FTL_Page_Read: Cache not hit\n");
-		res = FTL_Cache_Write();
-		if (ERR == FTL_Cache_Read(logical_addr))
-			res = ERR;
-		cache_item = Cache.LRU;
-	}
-
-	FTL_Cache_Read_Page(data, logical_addr, cache_item);
-
-	return res;
-}
-
-/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
-* Function:     GLOB_FTL_Page_Write
-* Inputs:       pointer to data
-*               address of data (ADDRESSTYPE is LBA * Bytes/Page)
-* Outputs:      PASS=0 / FAIL=1
-* Description:  writes a page of data from RAM to the cache
-*               if the data is not already in cache, write back the
-*               least recently used block and read the addressed block
-*               from flash to cache
-*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
-int GLOB_FTL_Page_Write(u8 *pData, u64 dwPageAddr)
-{
-	u16 cache_blk;
-	u32 *pbt = (u32 *)g_pBlockTable;
-	int wResult = PASS;
-
-	nand_dbg_print(NAND_DBG_TRACE, "GLOB_FTL_Page_Write - "
-		"dwPageAddr: %llu\n", dwPageAddr);
-
-	cache_blk = FTL_Cache_If_Hit(dwPageAddr);
-
-	if (UNHIT_CACHE_ITEM == cache_blk) {
-		wResult = FTL_Cache_Write();
-		if (IS_BAD_BLOCK(BLK_FROM_ADDR(dwPageAddr))) {
-			wResult = FTL_Replace_Block(dwPageAddr);
-			pbt[BLK_FROM_ADDR(dwPageAddr)] |= SPARE_BLOCK;
-			if (wResult == FAIL)
-				return FAIL;
-		}
-		if (ERR == FTL_Cache_Read(dwPageAddr))
-			wResult = ERR;
-		cache_blk = Cache.LRU;
-		FTL_Cache_Write_Page(pData, dwPageAddr, cache_blk, 0);
-	} else {
-#if CMD_DMA
-		FTL_Cache_Write_Page(pData, dwPageAddr, cache_blk,
-				LLD_CMD_FLAG_ORDER_BEFORE_REST);
-#else
-		FTL_Cache_Write_Page(pData, dwPageAddr, cache_blk, 0);
-#endif
-	}
-
-	return wResult;
-}
-
-/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
-* Function:     GLOB_FTL_Block_Erase
-* Inputs:       address of block to erase (now in byte format, should change to
-* block format)
-* Outputs:      PASS=0 / FAIL=1
-* Description:  erases the specified block
-*               increments the erase count
-*               If erase count reaches its upper limit,call function to
-*               do the adjustment as per the relative erase count values
-*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
-int GLOB_FTL_Block_Erase(u64 blk_addr)
-{
-	int status;
-	u32 BlkIdx;
-
-	nand_dbg_print(NAND_DBG_TRACE, "%s, Line %d, Function: %s\n",
-			       __FILE__, __LINE__, __func__);
-
-	BlkIdx = (u32)(blk_addr >> DeviceInfo.nBitsInBlockDataSize);
-
-	if (BlkIdx < DeviceInfo.wSpectraStartBlock) {
-		printk(KERN_ERR "GLOB_FTL_Block_Erase: "
-			"This should never occur\n");
-		return FAIL;
-	}
-
-#if CMD_DMA
-	status = GLOB_LLD_Erase_Block_cdma(BlkIdx, LLD_CMD_FLAG_MODE_CDMA);
-	if (status == FAIL)
-		nand_dbg_print(NAND_DBG_WARN,
-			       "NAND Program fail in %s, Line %d, "
-			       "Function: %s, new Bad Block %d generated!\n",
-			       __FILE__, __LINE__, __func__, BlkIdx);
-#else
-	status = GLOB_LLD_Erase_Block(BlkIdx);
-	if (status == FAIL) {
-		nand_dbg_print(NAND_DBG_WARN,
-			       "NAND Program fail in %s, Line %d, "
-			       "Function: %s, new Bad Block %d generated!\n",
-			       __FILE__, __LINE__, __func__, BlkIdx);
-		return status;
-	}
-#endif
-
-	if (DeviceInfo.MLCDevice) {
-		g_pReadCounter[BlkIdx - DeviceInfo.wSpectraStartBlock] = 0;
-		if (g_cBlockTableStatus != IN_PROGRESS_BLOCK_TABLE) {
-			g_cBlockTableStatus = IN_PROGRESS_BLOCK_TABLE;
-			FTL_Write_IN_Progress_Block_Table_Page();
-		}
-	}
-
-	g_pWearCounter[BlkIdx - DeviceInfo.wSpectraStartBlock]++;
-
-#if CMD_DMA
-	p_BTableChangesDelta =
-		(struct BTableChangesDelta *)g_pBTDelta_Free;
-	g_pBTDelta_Free += sizeof(struct BTableChangesDelta);
-	p_BTableChangesDelta->ftl_cmd_cnt = ftl_cmd_cnt;
-	p_BTableChangesDelta->WC_Index =
-		BlkIdx - DeviceInfo.wSpectraStartBlock;
-	p_BTableChangesDelta->WC_Entry_Value =
-		g_pWearCounter[BlkIdx - DeviceInfo.wSpectraStartBlock];
-	p_BTableChangesDelta->ValidFields = 0x30;
-
-	if (DeviceInfo.MLCDevice) {
-		p_BTableChangesDelta =
-			(struct BTableChangesDelta *)g_pBTDelta_Free;
-		g_pBTDelta_Free += sizeof(struct BTableChangesDelta);
-		p_BTableChangesDelta->ftl_cmd_cnt =
-			ftl_cmd_cnt;
-		p_BTableChangesDelta->RC_Index =
-			BlkIdx - DeviceInfo.wSpectraStartBlock;
-		p_BTableChangesDelta->RC_Entry_Value =
-			g_pReadCounter[BlkIdx -
-				DeviceInfo.wSpectraStartBlock];
-		p_BTableChangesDelta->ValidFields = 0xC0;
-	}
-
-	ftl_cmd_cnt++;
-#endif
-
-	if (g_pWearCounter[BlkIdx - DeviceInfo.wSpectraStartBlock] == 0xFE)
-		FTL_Adjust_Relative_Erase_Count(BlkIdx);
-
-	return status;
-}
-
-
-/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
-* Function:     FTL_Adjust_Relative_Erase_Count
-* Inputs:       index to block that was just incremented and is at the max
-* Outputs:      PASS=0 / FAIL=1
-* Description:  If any erase counts at MAX, adjusts erase count of every
-*               block by subtracting least worn
-*               counter from counter value of every entry in wear table
-*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
-static int FTL_Adjust_Relative_Erase_Count(u32 Index_of_MAX)
-{
-	u8 wLeastWornCounter = MAX_BYTE_VALUE;
-	u8 wWearCounter;
-	u32 i, wWearIndex;
-	u32 *pbt = (u32 *)g_pBlockTable;
-	int wResult = PASS;
-
-	nand_dbg_print(NAND_DBG_TRACE, "%s, Line %d, Function: %s\n",
-		__FILE__, __LINE__, __func__);
-
-	for (i = 0; i < DeviceInfo.wDataBlockNum; i++) {
-		if (IS_BAD_BLOCK(i))
-			continue;
-		wWearIndex = (u32)(pbt[i] & (~BAD_BLOCK));
-
-		if ((wWearIndex - DeviceInfo.wSpectraStartBlock) < 0)
-			printk(KERN_ERR "FTL_Adjust_Relative_Erase_Count:"
-					"This should never occur\n");
-		wWearCounter = g_pWearCounter[wWearIndex -
-			DeviceInfo.wSpectraStartBlock];
-		if (wWearCounter < wLeastWornCounter)
-			wLeastWornCounter = wWearCounter;
-	}
-
-	if (wLeastWornCounter == 0) {
-		nand_dbg_print(NAND_DBG_WARN,
-			"Adjusting Wear Levelling Counters: Special Case\n");
-		g_pWearCounter[Index_of_MAX -
-			DeviceInfo.wSpectraStartBlock]--;
-#if CMD_DMA
-		p_BTableChangesDelta =
-			(struct BTableChangesDelta *)g_pBTDelta_Free;
-		g_pBTDelta_Free += sizeof(struct BTableChangesDelta);
-		p_BTableChangesDelta->ftl_cmd_cnt = ftl_cmd_cnt;
-		p_BTableChangesDelta->WC_Index =
-			Index_of_MAX - DeviceInfo.wSpectraStartBlock;
-		p_BTableChangesDelta->WC_Entry_Value =
-			g_pWearCounter[Index_of_MAX -
-				DeviceInfo.wSpectraStartBlock];
-		p_BTableChangesDelta->ValidFields = 0x30;
-#endif
-		FTL_Static_Wear_Leveling();
-	} else {
-		for (i = 0; i < DeviceInfo.wDataBlockNum; i++)
-			if (!IS_BAD_BLOCK(i)) {
-				wWearIndex = (u32)(pbt[i] & (~BAD_BLOCK));
-				g_pWearCounter[wWearIndex -
-					DeviceInfo.wSpectraStartBlock] =
-					(u8)(g_pWearCounter
-					[wWearIndex -
-					DeviceInfo.wSpectraStartBlock] -
-					wLeastWornCounter);
-#if CMD_DMA
-				p_BTableChangesDelta =
-				(struct BTableChangesDelta *)g_pBTDelta_Free;
-				g_pBTDelta_Free +=
-					sizeof(struct BTableChangesDelta);
-
-				p_BTableChangesDelta->ftl_cmd_cnt =
-					ftl_cmd_cnt;
-				p_BTableChangesDelta->WC_Index = wWearIndex -
-					DeviceInfo.wSpectraStartBlock;
-				p_BTableChangesDelta->WC_Entry_Value =
-					g_pWearCounter[wWearIndex -
-					DeviceInfo.wSpectraStartBlock];
-				p_BTableChangesDelta->ValidFields = 0x30;
-#endif
-			}
-	}
-
-	return wResult;
-}
-
-/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
-* Function:     FTL_Write_IN_Progress_Block_Table_Page
-* Inputs:       None
-* Outputs:      None
-* Description:  It writes in-progress flag page to the page next to
-*               block table
-***********************************************************************/
-static int FTL_Write_IN_Progress_Block_Table_Page(void)
-{
-	int wResult = PASS;
-	u16 bt_pages;
-	u16 dwIPFPageAddr;
-#if CMD_DMA
-#else
-	u32 *pbt = (u32 *)g_pBlockTable;
-	u32 wTempBlockTableIndex;
-#endif
-
-	nand_dbg_print(NAND_DBG_WARN, "%s, Line %d, Function: %s\n",
-			       __FILE__, __LINE__, __func__);
-
-	bt_pages = FTL_Get_Block_Table_Flash_Size_Pages();
-
-	dwIPFPageAddr = g_wBlockTableOffset + bt_pages;
-
-	nand_dbg_print(NAND_DBG_DEBUG, "Writing IPF at "
-			       "Block %d Page %d\n",
-			       g_wBlockTableIndex, dwIPFPageAddr);
-
-#if CMD_DMA
-	wResult = GLOB_LLD_Write_Page_Main_Spare_cdma(g_pIPF,
-		g_wBlockTableIndex, dwIPFPageAddr, 1,
-		LLD_CMD_FLAG_MODE_CDMA | LLD_CMD_FLAG_ORDER_BEFORE_REST);
-	if (wResult == FAIL) {
-		nand_dbg_print(NAND_DBG_WARN,
-			       "NAND Program fail in %s, Line %d, "
-			       "Function: %s, new Bad Block %d generated!\n",
-			       __FILE__, __LINE__, __func__,
-			       g_wBlockTableIndex);
-	}
-	g_wBlockTableOffset = dwIPFPageAddr + 1;
-	p_BTableChangesDelta = (struct BTableChangesDelta *)g_pBTDelta_Free;
-	g_pBTDelta_Free += sizeof(struct BTableChangesDelta);
-	p_BTableChangesDelta->ftl_cmd_cnt = ftl_cmd_cnt;
-	p_BTableChangesDelta->g_wBlockTableOffset = g_wBlockTableOffset;
-	p_BTableChangesDelta->ValidFields = 0x01;
-	ftl_cmd_cnt++;
-#else
-	wResult = GLOB_LLD_Write_Page_Main_Spare(g_pIPF,
-		g_wBlockTableIndex, dwIPFPageAddr, 1);
-	if (wResult == FAIL) {
-		nand_dbg_print(NAND_DBG_WARN,
-			       "NAND Program fail in %s, Line %d, "
-			       "Function: %s, new Bad Block %d generated!\n",
-			       __FILE__, __LINE__, __func__,
-			       (int)g_wBlockTableIndex);
-		MARK_BLOCK_AS_BAD(pbt[BLOCK_TABLE_INDEX]);
-		wTempBlockTableIndex = FTL_Replace_Block_Table();
-		bt_block_changed = 1;
-		if (BAD_BLOCK == wTempBlockTableIndex)
-			return ERR;
-		g_wBlockTableIndex = wTempBlockTableIndex;
-		g_wBlockTableOffset = 0;
-		/* Block table tag is '00'. Means it's used one */
-		pbt[BLOCK_TABLE_INDEX] = g_wBlockTableIndex;
-		return FAIL;
-	}
-	g_wBlockTableOffset = dwIPFPageAddr + 1;
-#endif
-	return wResult;
-}
-
-/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
-* Function:     FTL_Read_Disturbance
-* Inputs:       block address
-* Outputs:      PASS=0 / FAIL=1
-* Description:  used to handle read disturbance. Data in block that
-*               reaches its read limit is moved to new block
-*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
-int FTL_Read_Disturbance(u32 blk_addr)
-{
-	int wResult = FAIL;
-	u32 *pbt = (u32 *) g_pBlockTable;
-	u32 dwOldBlockAddr = blk_addr;
-	u32 wBlockNum;
-	u32 i;
-	u32 wLeastReadCounter = 0xFFFF;
-	u32 wLeastReadIndex = BAD_BLOCK;
-	u32 wSpareBlockNum = 0;
-	u32 wTempNode;
-	u32 wReplacedNode;
-	u8 *g_pTempBuf;
-
-	nand_dbg_print(NAND_DBG_DEBUG, "%s, Line %d, Function: %s\n",
-			       __FILE__, __LINE__, __func__);
-
-#if CMD_DMA
-	g_pTempBuf = cp_back_buf_copies[cp_back_buf_idx];
-	cp_back_buf_idx++;
-	if (cp_back_buf_idx > COPY_BACK_BUF_NUM) {
-		printk(KERN_ERR "cp_back_buf_copies overflow! Exit."
-		"Maybe too many pending commands in your CDMA chain.\n");
-		return FAIL;
-	}
-#else
-	g_pTempBuf = tmp_buf_read_disturbance;
-#endif
-
-	wBlockNum = FTL_Get_Block_Index(blk_addr);
-
-	do {
-		/* This is a bug.Here 'i' should be logical block number
-		 * and start from 1 (0 is reserved for block table).
-		 * Have fixed it.        - Yunpeng 2008. 12. 19
-		 */
-		for (i = 1; i < DeviceInfo.wDataBlockNum; i++) {
-			if (IS_SPARE_BLOCK(i)) {
-				u32 wPhysicalIndex =
-					(u32)((~SPARE_BLOCK) & pbt[i]);
-				if (g_pReadCounter[wPhysicalIndex -
-					DeviceInfo.wSpectraStartBlock] <
-					wLeastReadCounter) {
-					wLeastReadCounter =
-						g_pReadCounter[wPhysicalIndex -
-						DeviceInfo.wSpectraStartBlock];
-					wLeastReadIndex = i;
-				}
-				wSpareBlockNum++;
-			}
-		}
-
-		if (wSpareBlockNum <= NUM_FREE_BLOCKS_GATE) {
-			wResult = GLOB_FTL_Garbage_Collection();
-			if (PASS == wResult)
-				continue;
-			else
-				break;
-		} else {
-			wTempNode = (u32)(DISCARD_BLOCK | pbt[wBlockNum]);
-			wReplacedNode = (u32)((~SPARE_BLOCK) &
-					pbt[wLeastReadIndex]);
-#if CMD_DMA
-			pbt[wBlockNum] = wReplacedNode;
-			pbt[wLeastReadIndex] = wTempNode;
-			p_BTableChangesDelta =
-				(struct BTableChangesDelta *)g_pBTDelta_Free;
-			g_pBTDelta_Free += sizeof(struct BTableChangesDelta);
-
-			p_BTableChangesDelta->ftl_cmd_cnt =
-					ftl_cmd_cnt;
-			p_BTableChangesDelta->BT_Index = wBlockNum;
-			p_BTableChangesDelta->BT_Entry_Value = pbt[wBlockNum];
-			p_BTableChangesDelta->ValidFields = 0x0C;
-
-			p_BTableChangesDelta =
-				(struct BTableChangesDelta *)g_pBTDelta_Free;
-			g_pBTDelta_Free += sizeof(struct BTableChangesDelta);
-
-			p_BTableChangesDelta->ftl_cmd_cnt =
-					ftl_cmd_cnt;
-			p_BTableChangesDelta->BT_Index = wLeastReadIndex;
-			p_BTableChangesDelta->BT_Entry_Value =
-					pbt[wLeastReadIndex];
-			p_BTableChangesDelta->ValidFields = 0x0C;
-
-			wResult = GLOB_LLD_Read_Page_Main_cdma(g_pTempBuf,
-				dwOldBlockAddr, 0, DeviceInfo.wPagesPerBlock,
-				LLD_CMD_FLAG_MODE_CDMA);
-			if (wResult == FAIL)
-				return wResult;
-
-			ftl_cmd_cnt++;
-
-			if (wResult != FAIL) {
-				if (FAIL == GLOB_LLD_Write_Page_Main_cdma(
-					g_pTempBuf, pbt[wBlockNum], 0,
-					DeviceInfo.wPagesPerBlock)) {
-					nand_dbg_print(NAND_DBG_WARN,
-						"NAND Program fail in "
-						"%s, Line %d, Function: %s, "
-						"new Bad Block %d "
-						"generated!\n",
-						__FILE__, __LINE__, __func__,
-						(int)pbt[wBlockNum]);
-					wResult = FAIL;
-					MARK_BLOCK_AS_BAD(pbt[wBlockNum]);
-				}
-				ftl_cmd_cnt++;
-			}
-#else
-			wResult = GLOB_LLD_Read_Page_Main(g_pTempBuf,
-				dwOldBlockAddr, 0, DeviceInfo.wPagesPerBlock);
-			if (wResult == FAIL)
-				return wResult;
-
-			if (wResult != FAIL) {
-				/* This is a bug. At this time, pbt[wBlockNum]
-				is still the physical address of
-				discard block, and should not be write.
-				Have fixed it as below.
-					-- Yunpeng 2008.12.19
-				*/
-				wResult = GLOB_LLD_Write_Page_Main(g_pTempBuf,
-					wReplacedNode, 0,
-					DeviceInfo.wPagesPerBlock);
-				if (wResult == FAIL) {
-					nand_dbg_print(NAND_DBG_WARN,
-						"NAND Program fail in "
-						"%s, Line %d, Function: %s, "
-						"new Bad Block %d "
-						"generated!\n",
-						__FILE__, __LINE__, __func__,
-						(int)wReplacedNode);
-					MARK_BLOCK_AS_BAD(wReplacedNode);
-				} else {
-					pbt[wBlockNum] = wReplacedNode;
-					pbt[wLeastReadIndex] = wTempNode;
-				}
-			}
-
-			if ((wResult == PASS) && (g_cBlockTableStatus !=
-				IN_PROGRESS_BLOCK_TABLE)) {
-				g_cBlockTableStatus = IN_PROGRESS_BLOCK_TABLE;
-				FTL_Write_IN_Progress_Block_Table_Page();
-			}
-#endif
-		}
-	} while (wResult != PASS)
-	;
-
-#if CMD_DMA
-	/* ... */
-#endif
-
-	return wResult;
-}
-
diff --git a/drivers/staging/spectra/flash.h b/drivers/staging/spectra/flash.h
deleted file mode 100644
index e59cf4e..0000000
--- a/drivers/staging/spectra/flash.h
+++ /dev/null
@@ -1,198 +0,0 @@
-/*
- * NAND Flash Controller Device Driver
- * Copyright (c) 2009, Intel Corporation and its suppliers.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms and conditions of the GNU General Public License,
- * version 2, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
- *
- */
-
-#ifndef _FLASH_INTERFACE_
-#define _FLASH_INTERFACE_
-
-#include "ffsport.h"
-#include "spectraswconfig.h"
-
-#define MAX_BYTE_VALUE        0xFF
-#define MAX_WORD_VALUE        0xFFFF
-#define MAX_U32_VALUE        0xFFFFFFFF
-
-#define MAX_BLOCKNODE_VALUE     0xFFFFFF
-#define DISCARD_BLOCK           0x800000
-#define SPARE_BLOCK             0x400000
-#define BAD_BLOCK               0xC00000
-
-#define UNHIT_CACHE_ITEM         0xFFFF
-
-#define NAND_CACHE_INIT_ADDR    0xffffffffffffffffULL
-
-#define IN_PROGRESS_BLOCK_TABLE   0x00
-#define CURRENT_BLOCK_TABLE       0x01
-
-#define BTSIG_OFFSET   (0)
-#define BTSIG_BYTES    (5)
-#define BTSIG_DELTA    (3)
-
-#define MAX_READ_COUNTER  0x2710
-
-#define FIRST_BT_ID		(1)
-#define LAST_BT_ID    (254)
-#define BTBLOCK_INVAL  (u32)(0xFFFFFFFF)
-
-struct device_info_tag {
-	u16 wDeviceMaker;
-	u16 wDeviceID;
-	u32 wDeviceType;
-	u32 wSpectraStartBlock;
-	u32 wSpectraEndBlock;
-	u32 wTotalBlocks;
-	u16 wPagesPerBlock;
-	u16 wPageSize;
-	u16 wPageDataSize;
-	u16 wPageSpareSize;
-	u16 wNumPageSpareFlag;
-	u16 wECCBytesPerSector;
-	u32 wBlockSize;
-	u32 wBlockDataSize;
-	u32 wDataBlockNum;
-	u8 bPlaneNum;
-	u16 wDeviceMainAreaSize;
-	u16 wDeviceSpareAreaSize;
-	u16 wDevicesConnected;
-	u16 wDeviceWidth;
-	u16 wHWRevision;
-	u16 wHWFeatures;
-
-	u16 wONFIDevFeatures;
-	u16 wONFIOptCommands;
-	u16 wONFITimingMode;
-	u16 wONFIPgmCacheTimingMode;
-
-	u16 MLCDevice;
-	u16 wSpareSkipBytes;
-
-	u8 nBitsInPageNumber;
-	u8 nBitsInPageDataSize;
-	u8 nBitsInBlockDataSize;
-};
-
-extern struct device_info_tag DeviceInfo;
-
-/* Cache item format */
-struct flash_cache_item_tag {
-	u64 address;
-	u16 use_cnt;
-	u16 changed;
-	u8 *buf;
-};
-
-struct flash_cache_tag {
-	u32 cache_item_size; /* Size in bytes of each cache item */
-	u16 pages_per_item; /* How many NAND pages in each cache item */
-	u16 LRU; /* No. of the least recently used cache item */
-	struct flash_cache_item_tag array[CACHE_ITEM_NUM];
-};
-
-/*
- *Data structure for each list node of the management table
- * used for the Level 2 Cache. Each node maps one logical NAND block.
- */
-struct spectra_l2_cache_list {
-	struct list_head list;
-	u32 logical_blk_num; /* Logical block number */
-	u32 pages_array[]; /* Page map array of this logical block.
-			   * Array index is the logical block number,
-			   * and for every item of this arry:
-			   * high 16 bit is index of the L2 cache block num,
-			   * low 16 bit is the phy page num
-			   * of the above L2 cache block.
-			   * This array will be kmalloc during run time.
-			   */
-};
-
-struct spectra_l2_cache_info {
-	u32 blk_array[BLK_NUM_FOR_L2_CACHE];
-	u16 cur_blk_idx; /* idx to the phy block number of current using */
-	u16 cur_page_num; /* pages number of current using */
-	struct spectra_l2_cache_list table; /* First node of the table */
-};
-
-#define RESTORE_CACHE_ON_CDMA_CHAIN_FAILURE    1
-
-#if RESTORE_CACHE_ON_CDMA_CHAIN_FAILURE
-struct flash_cache_mod_item_tag {
-	u64 address;
-	u8 changed;
-};
-
-struct flash_cache_delta_list_tag {
-	u8 item;  /* used cache item */
-	struct flash_cache_mod_item_tag cache;
-};
-#endif
-
-extern struct flash_cache_tag Cache;
-
-extern u8 *buf_read_page_main_spare;
-extern u8 *buf_write_page_main_spare;
-extern u8 *buf_read_page_spare;
-extern u8 *buf_get_bad_block;
-extern u8 *cdma_desc_buf;
-extern u8 *memcp_desc_buf;
-
-/* struture used for IndentfyDevice function */
-struct spectra_indentfy_dev_tag {
-	u32 NumBlocks;
-	u16 PagesPerBlock;
-	u16 PageDataSize;
-	u16 wECCBytesPerSector;
-	u32 wDataBlockNum;
-};
-
-int GLOB_FTL_Flash_Init(void);
-int GLOB_FTL_Flash_Release(void);
-/*void GLOB_FTL_Erase_Flash(void);*/
-int GLOB_FTL_Block_Erase(u64 block_addr);
-int GLOB_FTL_Is_BadBlock(u32 block_num);
-int GLOB_FTL_IdentifyDevice(struct spectra_indentfy_dev_tag *dev_data);
-int GLOB_FTL_Event_Status(int *);
-u16 glob_ftl_execute_cmds(void);
-
-/*int FTL_Read_Disturbance(ADDRESSTYPE dwBlockAddr);*/
-int FTL_Read_Disturbance(u32 dwBlockAddr);
-
-/*Flash r/w based on cache*/
-int GLOB_FTL_Page_Read(u8 *read_data, u64 page_addr);
-int GLOB_FTL_Page_Write(u8 *write_data, u64 page_addr);
-int GLOB_FTL_Wear_Leveling(void);
-int GLOB_FTL_Flash_Format(void);
-int GLOB_FTL_Init(void);
-int GLOB_FTL_Flush_Cache(void);
-int GLOB_FTL_Garbage_Collection(void);
-int GLOB_FTL_BT_Garbage_Collection(void);
-void GLOB_FTL_Cache_Release(void);
-u8 *get_blk_table_start_addr(void);
-u8 *get_wear_leveling_table_start_addr(void);
-unsigned long get_blk_table_len(void);
-unsigned long get_wear_leveling_table_len(void);
-
-#if DEBUG_BNDRY
-void debug_boundary_lineno_error(int chnl, int limit, int no, int lineno,
-				char *filename);
-#define debug_boundary_error(chnl, limit, no) debug_boundary_lineno_error(chnl,\
-						limit, no, __LINE__, __FILE__)
-#else
-#define debug_boundary_error(chnl, limit, no) ;
-#endif
-
-#endif /*_FLASH_INTERFACE_*/
diff --git a/drivers/staging/spectra/lld.c b/drivers/staging/spectra/lld.c
deleted file mode 100644
index 5c3b976..0000000
--- a/drivers/staging/spectra/lld.c
+++ /dev/null
@@ -1,339 +0,0 @@
-/*
- * NAND Flash Controller Device Driver
- * Copyright (c) 2009, Intel Corporation and its suppliers.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms and conditions of the GNU General Public License,
- * version 2, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
- *
- */
-
-#include "spectraswconfig.h"
-#include "ffsport.h"
-#include "ffsdefs.h"
-#include "lld.h"
-#include "lld_nand.h"
-
-/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
-#if FLASH_EMU		/* vector all the LLD calls to the LLD_EMU code */
-#include "lld_emu.h"
-#include "lld_cdma.h"
-
-/* common functions: */
-u16 GLOB_LLD_Flash_Reset(void)
-{
-	return emu_Flash_Reset();
-}
-
-u16 GLOB_LLD_Read_Device_ID(void)
-{
-	return emu_Read_Device_ID();
-}
-
-int GLOB_LLD_Flash_Release(void)
-{
-	return emu_Flash_Release();
-}
-
-u16 GLOB_LLD_Flash_Init(void)
-{
-	return emu_Flash_Init();
-}
-
-u16 GLOB_LLD_Erase_Block(u32 block_add)
-{
-	return emu_Erase_Block(block_add);
-}
-
-u16 GLOB_LLD_Write_Page_Main(u8 *write_data, u32 block, u16 Page,
-				u16 PageCount)
-{
-	return emu_Write_Page_Main(write_data, block, Page, PageCount);
-}
-
-u16 GLOB_LLD_Read_Page_Main(u8 *read_data, u32 block, u16 Page,
-			       u16 PageCount)
-{
-	return emu_Read_Page_Main(read_data, block, Page, PageCount);
-}
-
-u16 GLOB_LLD_Read_Page_Main_Polling(u8 *read_data,
-			u32 block, u16 page, u16 page_count)
-{
-	return emu_Read_Page_Main(read_data, block, page, page_count);
-}
-
-u16 GLOB_LLD_Write_Page_Main_Spare(u8 *write_data, u32 block,
-				      u16 Page, u16 PageCount)
-{
-	return emu_Write_Page_Main_Spare(write_data, block, Page, PageCount);
-}
-
-u16 GLOB_LLD_Read_Page_Main_Spare(u8 *read_data, u32 block,
-				     u16 Page, u16 PageCount)
-{
-	return emu_Read_Page_Main_Spare(read_data, block, Page, PageCount);
-}
-
-u16 GLOB_LLD_Write_Page_Spare(u8 *write_data, u32 block, u16 Page,
-				 u16 PageCount)
-{
-	return emu_Write_Page_Spare(write_data, block, Page, PageCount);
-}
-
-u16 GLOB_LLD_Read_Page_Spare(u8 *read_data, u32 block, u16 Page,
-				u16 PageCount)
-{
-	return emu_Read_Page_Spare(read_data, block, Page, PageCount);
-}
-
-u16  GLOB_LLD_Get_Bad_Block(u32 block)
-{
-    return  emu_Get_Bad_Block(block);
-}
-
-#endif /* FLASH_EMU */
-
-/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
-#if FLASH_MTD		/* vector all the LLD calls to the LLD_MTD code */
-#include "lld_mtd.h"
-#include "lld_cdma.h"
-
-/* common functions: */
-u16 GLOB_LLD_Flash_Reset(void)
-{
-	return mtd_Flash_Reset();
-}
-
-u16 GLOB_LLD_Read_Device_ID(void)
-{
-	return mtd_Read_Device_ID();
-}
-
-int GLOB_LLD_Flash_Release(void)
-{
-	return mtd_Flash_Release();
-}
-
-u16 GLOB_LLD_Flash_Init(void)
-{
-	return mtd_Flash_Init();
-}
-
-u16 GLOB_LLD_Erase_Block(u32 block_add)
-{
-	return mtd_Erase_Block(block_add);
-}
-
-u16 GLOB_LLD_Write_Page_Main(u8 *write_data, u32 block, u16 Page,
-				u16 PageCount)
-{
-	return mtd_Write_Page_Main(write_data, block, Page, PageCount);
-}
-
-u16 GLOB_LLD_Read_Page_Main(u8 *read_data, u32 block, u16 Page,
-			       u16 PageCount)
-{
-	return mtd_Read_Page_Main(read_data, block, Page, PageCount);
-}
-
-u16 GLOB_LLD_Read_Page_Main_Polling(u8 *read_data,
-			u32 block, u16 page, u16 page_count)
-{
-	return mtd_Read_Page_Main(read_data, block, page, page_count);
-}
-
-u16 GLOB_LLD_Write_Page_Main_Spare(u8 *write_data, u32 block,
-				      u16 Page, u16 PageCount)
-{
-	return mtd_Write_Page_Main_Spare(write_data, block, Page, PageCount);
-}
-
-u16 GLOB_LLD_Read_Page_Main_Spare(u8 *read_data, u32 block,
-				     u16 Page, u16 PageCount)
-{
-	return mtd_Read_Page_Main_Spare(read_data, block, Page, PageCount);
-}
-
-u16 GLOB_LLD_Write_Page_Spare(u8 *write_data, u32 block, u16 Page,
-				 u16 PageCount)
-{
-	return mtd_Write_Page_Spare(write_data, block, Page, PageCount);
-}
-
-u16 GLOB_LLD_Read_Page_Spare(u8 *read_data, u32 block, u16 Page,
-				u16 PageCount)
-{
-	return mtd_Read_Page_Spare(read_data, block, Page, PageCount);
-}
-
-u16  GLOB_LLD_Get_Bad_Block(u32 block)
-{
-    return  mtd_Get_Bad_Block(block);
-}
-
-#endif /* FLASH_MTD */
-
-/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
-#if FLASH_NAND	/* vector all the LLD calls to the NAND controller code */
-#include "lld_nand.h"
-#include "lld_cdma.h"
-#include "flash.h"
-
-/* common functions for LLD_NAND */
-void GLOB_LLD_ECC_Control(int enable)
-{
-	NAND_ECC_Ctrl(enable);
-}
-
-/* common functions for LLD_NAND */
-u16 GLOB_LLD_Flash_Reset(void)
-{
-	return NAND_Flash_Reset();
-}
-
-u16 GLOB_LLD_Read_Device_ID(void)
-{
-	return NAND_Read_Device_ID();
-}
-
-u16 GLOB_LLD_UnlockArrayAll(void)
-{
-	return NAND_UnlockArrayAll();
-}
-
-u16 GLOB_LLD_Flash_Init(void)
-{
-	return NAND_Flash_Init();
-}
-
-int GLOB_LLD_Flash_Release(void)
-{
-	return nand_release_spectra();
-}
-
-u16 GLOB_LLD_Erase_Block(u32 block_add)
-{
-	return NAND_Erase_Block(block_add);
-}
-
-
-u16 GLOB_LLD_Write_Page_Main(u8 *write_data, u32 block, u16 Page,
-				u16 PageCount)
-{
-	return NAND_Write_Page_Main(write_data, block, Page, PageCount);
-}
-
-u16 GLOB_LLD_Read_Page_Main(u8 *read_data, u32 block, u16 page,
-			       u16 page_count)
-{
-	if (page_count == 1) /* Using polling to improve read speed */
-		return NAND_Read_Page_Main_Polling(read_data, block, page, 1);
-	else
-		return NAND_Read_Page_Main(read_data, block, page, page_count);
-}
-
-u16 GLOB_LLD_Read_Page_Main_Polling(u8 *read_data,
-			u32 block, u16 page, u16 page_count)
-{
-	return NAND_Read_Page_Main_Polling(read_data,
-			block, page, page_count);
-}
-
-u16 GLOB_LLD_Write_Page_Main_Spare(u8 *write_data, u32 block,
-				      u16 Page, u16 PageCount)
-{
-	return NAND_Write_Page_Main_Spare(write_data, block, Page, PageCount);
-}
-
-u16 GLOB_LLD_Write_Page_Spare(u8 *write_data, u32 block, u16 Page,
-				 u16 PageCount)
-{
-	return NAND_Write_Page_Spare(write_data, block, Page, PageCount);
-}
-
-u16 GLOB_LLD_Read_Page_Main_Spare(u8 *read_data, u32 block,
-				     u16 page, u16 page_count)
-{
-	return NAND_Read_Page_Main_Spare(read_data, block, page, page_count);
-}
-
-u16 GLOB_LLD_Read_Page_Spare(u8 *read_data, u32 block, u16 Page,
-				u16 PageCount)
-{
-	return NAND_Read_Page_Spare(read_data, block, Page, PageCount);
-}
-
-u16  GLOB_LLD_Get_Bad_Block(u32 block)
-{
-	return  NAND_Get_Bad_Block(block);
-}
-
-#if CMD_DMA
-u16 GLOB_LLD_Event_Status(void)
-{
-	return CDMA_Event_Status();
-}
-
-u16 glob_lld_execute_cmds(void)
-{
-	return CDMA_Execute_CMDs();
-}
-
-u16 GLOB_LLD_MemCopy_CMD(u8 *dest, u8 *src,
-			u32 ByteCount, u16 flag)
-{
-	/* Replace the hardware memcopy with software memcpy function */
-	if (CDMA_Execute_CMDs())
-		return FAIL;
-	memcpy(dest, src, ByteCount);
-	return PASS;
-
-	/* return CDMA_MemCopy_CMD(dest, src, ByteCount, flag); */
-}
-
-u16 GLOB_LLD_Erase_Block_cdma(u32 block, u16 flags)
-{
-	return CDMA_Data_CMD(ERASE_CMD, 0, block, 0, 0, flags);
-}
-
-u16 GLOB_LLD_Write_Page_Main_cdma(u8 *data, u32 block, u16 page, u16 count)
-{
-	return CDMA_Data_CMD(WRITE_MAIN_CMD, data, block, page, count, 0);
-}
-
-u16 GLOB_LLD_Read_Page_Main_cdma(u8 *data, u32 block, u16 page,
-				u16 count, u16 flags)
-{
-	return CDMA_Data_CMD(READ_MAIN_CMD, data, block, page, count, flags);
-}
-
-u16 GLOB_LLD_Write_Page_Main_Spare_cdma(u8 *data, u32 block, u16 page,
-					u16 count, u16 flags)
-{
-	return CDMA_Data_CMD(WRITE_MAIN_SPARE_CMD,
-			data, block, page, count, flags);
-}
-
-u16 GLOB_LLD_Read_Page_Main_Spare_cdma(u8 *data,
-				u32 block, u16 page, u16 count)
-{
-	return CDMA_Data_CMD(READ_MAIN_SPARE_CMD, data, block, page, count,
-			LLD_CMD_FLAG_MODE_CDMA);
-}
-
-#endif /* CMD_DMA */
-#endif /* FLASH_NAND */
-
-/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
-
-/* end of LLD.c */
diff --git a/drivers/staging/spectra/lld.h b/drivers/staging/spectra/lld.h
deleted file mode 100644
index d3738e0..0000000
--- a/drivers/staging/spectra/lld.h
+++ /dev/null
@@ -1,111 +0,0 @@
-/*
- * NAND Flash Controller Device Driver
- * Copyright (c) 2009, Intel Corporation and its suppliers.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms and conditions of the GNU General Public License,
- * version 2, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
- *
- */
-
-
-
-#ifndef _LLD_
-#define _LLD_
-
-#include "ffsport.h"
-#include "spectraswconfig.h"
-#include "flash.h"
-
-#define GOOD_BLOCK 0
-#define DEFECTIVE_BLOCK 1
-#define READ_ERROR 2
-
-#define CLK_X  5
-#define CLK_MULTI 4
-
-/* Typedefs */
-
-/*  prototypes: API for LLD */
-/* Currently, Write_Page_Main
- * 			  MemCopy
- * 			  Read_Page_Main_Spare
- * do not have flag because they were not implemented prior to this
- * They are not being added to keep changes to a minimum for now.
- * Currently, they are not required (only reqd for Wr_P_M_S.)
- * Later on, these NEED to be changed.
- */
-
-extern void GLOB_LLD_ECC_Control(int enable);
-
-extern u16 GLOB_LLD_Flash_Reset(void);
-
-extern u16 GLOB_LLD_Read_Device_ID(void);
-
-extern u16 GLOB_LLD_UnlockArrayAll(void);
-
-extern u16 GLOB_LLD_Flash_Init(void);
-
-extern int GLOB_LLD_Flash_Release(void);
-
-extern u16 GLOB_LLD_Erase_Block(u32 block_add);
-
-extern u16 GLOB_LLD_Write_Page_Main(u8 *write_data,
-	u32 block, u16 Page, u16 PageCount);
-
-extern u16 GLOB_LLD_Read_Page_Main(u8 *read_data,
-	u32 block, u16 page, u16 page_count);
-
-extern u16 GLOB_LLD_Read_Page_Main_Polling(u8 *read_data,
-	u32 block, u16 page, u16 page_count);
-
-extern u16 GLOB_LLD_Write_Page_Main_Spare(u8 *write_data,
-	u32 block, u16 Page, u16 PageCount);
-
-extern u16 GLOB_LLD_Write_Page_Spare(u8 *write_data,
-	u32 block, u16 Page, u16 PageCount);
-
-extern u16 GLOB_LLD_Read_Page_Main_Spare(u8 *read_data,
-	u32 block, u16 page, u16 page_count);
-
-extern u16 GLOB_LLD_Read_Page_Spare(u8 *read_data,
-	u32 block, u16 Page, u16 PageCount);
-
-extern u16  GLOB_LLD_Get_Bad_Block(u32 block);
-
-extern u16 GLOB_LLD_Event_Status(void);
-
-extern u16 GLOB_LLD_MemCopy_CMD(u8 *dest, u8 *src, u32 ByteCount, u16 flag);
-
-extern u16 glob_lld_execute_cmds(void);
-
-extern u16 GLOB_LLD_Erase_Block_cdma(u32 block, u16 flags);
-
-extern u16 GLOB_LLD_Write_Page_Main_cdma(u8 *data,
-	u32 block, u16 page, u16 count);
-
-extern u16 GLOB_LLD_Read_Page_Main_cdma(u8 *data,
-	u32 block, u16 page, u16 count, u16 flags);
-
-extern u16 GLOB_LLD_Write_Page_Main_Spare_cdma(u8 *data,
-	u32 block, u16 page, u16 count, u16 flags);
-
-extern u16 GLOB_LLD_Read_Page_Main_Spare_cdma(u8 *data,
-	u32 block, u16 page, u16 count);
-
-#define LLD_CMD_FLAG_ORDER_BEFORE_REST		(0x1)
-#define LLD_CMD_FLAG_MODE_CDMA			(0x8)
-
-
-#endif /*_LLD_ */
-
-
diff --git a/drivers/staging/spectra/lld_cdma.c b/drivers/staging/spectra/lld_cdma.c
deleted file mode 100644
index c6e7610..0000000
--- a/drivers/staging/spectra/lld_cdma.c
+++ /dev/null
@@ -1,910 +0,0 @@
-/*
- * NAND Flash Controller Device Driver
- * Copyright (c) 2009, Intel Corporation and its suppliers.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms and conditions of the GNU General Public License,
- * version 2, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
- *
- */
-
-#include <linux/fs.h>
-#include <linux/slab.h>
-
-#include "spectraswconfig.h"
-#include "lld.h"
-#include "lld_nand.h"
-#include "lld_cdma.h"
-#include "lld_emu.h"
-#include "flash.h"
-#include "nand_regs.h"
-
-#define MAX_PENDING_CMDS    4
-#define MODE_02             (0x2 << 26)
-
-/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
-* Function:     CDMA_Data_Cmd
-* Inputs:   cmd code (aligned for hw)
-*               data: pointer to source or destination
-*               block: block address
-*               page: page address
-*               num: num pages to transfer
-* Outputs:      PASS
-* Description:  This function takes the parameters and puts them
-*                   into the "pending commands" array.
-*               It does not parse or validate the parameters.
-*               The array index is same as the tag.
-*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
-u16 CDMA_Data_CMD(u8 cmd, u8 *data, u32 block, u16 page, u16 num, u16 flags)
-{
-	u8 bank;
-
-	nand_dbg_print(NAND_DBG_DEBUG, "%s, Line %d, Function: %s\n",
-		       __FILE__, __LINE__, __func__);
-
-	if (0 == cmd)
-		nand_dbg_print(NAND_DBG_DEBUG,
-		"%s, Line %d, Illegal cmd (0)\n", __FILE__, __LINE__);
-
-	/* If a command of another bank comes, then first execute */
-	/* pending commands of the current bank, then set the new */
-	/* bank as current bank */
-	bank = block / (DeviceInfo.wTotalBlocks / totalUsedBanks);
-	if (bank != info.flash_bank) {
-		nand_dbg_print(NAND_DBG_WARN,
-			"Will access new bank. old bank: %d, new bank: %d\n",
-			info.flash_bank, bank);
-		if (CDMA_Execute_CMDs()) {
-			printk(KERN_ERR "CDMA_Execute_CMDs fail!\n");
-			return FAIL;
-		}
-		info.flash_bank = bank;
-	}
-
-	info.pcmds[info.pcmds_num].CMD = cmd;
-	info.pcmds[info.pcmds_num].DataAddr = data;
-	info.pcmds[info.pcmds_num].Block = block;
-	info.pcmds[info.pcmds_num].Page = page;
-	info.pcmds[info.pcmds_num].PageCount = num;
-	info.pcmds[info.pcmds_num].DataDestAddr = 0;
-	info.pcmds[info.pcmds_num].DataSrcAddr = 0;
-	info.pcmds[info.pcmds_num].MemCopyByteCnt = 0;
-	info.pcmds[info.pcmds_num].Flags = flags;
-	info.pcmds[info.pcmds_num].Status = 0xB0B;
-
-	switch (cmd) {
-	case WRITE_MAIN_SPARE_CMD:
-		Conv_Main_Spare_Data_Log2Phy_Format(data, num);
-		break;
-	case WRITE_SPARE_CMD:
-		Conv_Spare_Data_Log2Phy_Format(data);
-		break;
-	default:
-		break;
-	}
-
-	info.pcmds_num++;
-
-	if (info.pcmds_num >= MAX_PENDING_CMDS) {
-		if (CDMA_Execute_CMDs()) {
-			printk(KERN_ERR "CDMA_Execute_CMDs fail!\n");
-			return FAIL;
-		}
-	}
-
-	return PASS;
-}
-
-/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
-* Function:     CDMA_MemCopy_CMD
-* Inputs:       dest: pointer to destination
-*               src:  pointer to source
-*               count: num bytes to transfer
-* Outputs:      PASS
-* Description:  This function takes the parameters and puts them
-*                   into the "pending commands" array.
-*               It does not parse or validate the parameters.
-*               The array index is same as the tag.
-*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
-u16 CDMA_MemCopy_CMD(u8 *dest, u8 *src, u32 byte_cnt, u16 flags)
-{
-	nand_dbg_print(NAND_DBG_DEBUG, "%s, Line %d, Function: %s\n",
-		       __FILE__, __LINE__, __func__);
-
-	info.pcmds[info.pcmds_num].CMD = MEMCOPY_CMD;
-	info.pcmds[info.pcmds_num].DataAddr = 0;
-	info.pcmds[info.pcmds_num].Block = 0;
-	info.pcmds[info.pcmds_num].Page = 0;
-	info.pcmds[info.pcmds_num].PageCount = 0;
-	info.pcmds[info.pcmds_num].DataDestAddr = dest;
-	info.pcmds[info.pcmds_num].DataSrcAddr = src;
-	info.pcmds[info.pcmds_num].MemCopyByteCnt = byte_cnt;
-	info.pcmds[info.pcmds_num].Flags = flags;
-	info.pcmds[info.pcmds_num].Status = 0xB0B;
-
-	info.pcmds_num++;
-
-	if (info.pcmds_num >= MAX_PENDING_CMDS) {
-		if (CDMA_Execute_CMDs()) {
-			printk(KERN_ERR "CDMA_Execute_CMDs fail!\n");
-			return FAIL;
-		}
-	}
-
-	return PASS;
-}
-
-#if 0
-/* Prints the PendingCMDs array */
-void print_pending_cmds(void)
-{
-	u16 i;
-
-	nand_dbg_print(NAND_DBG_DEBUG, "%s, Line %d, Function: %s\n",
-		       __FILE__, __LINE__, __func__);
-
-	for (i = 0; i < info.pcmds_num; i++) {
-		nand_dbg_print(NAND_DBG_DEBUG, "\ni: %d\n", i);
-		switch (info.pcmds[i].CMD) {
-		case ERASE_CMD:
-			nand_dbg_print(NAND_DBG_DEBUG,
-				"Erase Command (0x%x)\n",
-				info.pcmds[i].CMD);
-			break;
-		case WRITE_MAIN_CMD:
-			nand_dbg_print(NAND_DBG_DEBUG,
-				"Write Main Command (0x%x)\n",
-				info.pcmds[i].CMD);
-			break;
-		case WRITE_MAIN_SPARE_CMD:
-			nand_dbg_print(NAND_DBG_DEBUG,
-				"Write Main Spare Command (0x%x)\n",
-				info.pcmds[i].CMD);
-			break;
-		case READ_MAIN_SPARE_CMD:
-			nand_dbg_print(NAND_DBG_DEBUG,
-				"Read Main Spare Command (0x%x)\n",
-				info.pcmds[i].CMD);
-			break;
-		case READ_MAIN_CMD:
-			nand_dbg_print(NAND_DBG_DEBUG,
-				"Read Main Command (0x%x)\n",
-				info.pcmds[i].CMD);
-			break;
-		case MEMCOPY_CMD:
-			nand_dbg_print(NAND_DBG_DEBUG,
-				"Memcopy Command (0x%x)\n",
-				info.pcmds[i].CMD);
-			break;
-		case DUMMY_CMD:
-			nand_dbg_print(NAND_DBG_DEBUG,
-				"Dummy Command (0x%x)\n",
-				info.pcmds[i].CMD);
-			break;
-		default:
-			nand_dbg_print(NAND_DBG_DEBUG,
-				"Illegal Command (0x%x)\n",
-				info.pcmds[i].CMD);
-			break;
-		}
-
-		nand_dbg_print(NAND_DBG_DEBUG, "DataAddr: 0x%x\n",
-			(u32)info.pcmds[i].DataAddr);
-		nand_dbg_print(NAND_DBG_DEBUG, "Block: %d\n",
-			info.pcmds[i].Block);
-		nand_dbg_print(NAND_DBG_DEBUG, "Page: %d\n",
-			info.pcmds[i].Page);
-		nand_dbg_print(NAND_DBG_DEBUG, "PageCount: %d\n",
-			info.pcmds[i].PageCount);
-		nand_dbg_print(NAND_DBG_DEBUG, "DataDestAddr: 0x%x\n",
-			(u32)info.pcmds[i].DataDestAddr);
-		nand_dbg_print(NAND_DBG_DEBUG, "DataSrcAddr: 0x%x\n",
-			(u32)info.pcmds[i].DataSrcAddr);
-		nand_dbg_print(NAND_DBG_DEBUG, "MemCopyByteCnt: %d\n",
-			info.pcmds[i].MemCopyByteCnt);
-		nand_dbg_print(NAND_DBG_DEBUG, "Flags: 0x%x\n",
-			info.pcmds[i].Flags);
-		nand_dbg_print(NAND_DBG_DEBUG, "Status: 0x%x\n",
-			info.pcmds[i].Status);
-	}
-}
-
-/* Print the CDMA descriptors */
-void print_cdma_descriptors(void)
-{
-	struct cdma_descriptor *pc;
-	int i;
-
-	pc = (struct cdma_descriptor *)info.cdma_desc_buf;
-
-	nand_dbg_print(NAND_DBG_DEBUG, "\nWill dump cdma descriptors:\n");
-
-	for (i = 0; i < info.cdma_num; i++) {
-		nand_dbg_print(NAND_DBG_DEBUG, "\ni: %d\n", i);
-		nand_dbg_print(NAND_DBG_DEBUG,
-			"NxtPointerHi: 0x%x, NxtPointerLo: 0x%x\n",
-			pc[i].NxtPointerHi, pc[i].NxtPointerLo);
-		nand_dbg_print(NAND_DBG_DEBUG,
-			"FlashPointerHi: 0x%x, FlashPointerLo: 0x%x\n",
-			pc[i].FlashPointerHi, pc[i].FlashPointerLo);
-		nand_dbg_print(NAND_DBG_DEBUG, "CommandType: 0x%x\n",
-			pc[i].CommandType);
-		nand_dbg_print(NAND_DBG_DEBUG,
-			"MemAddrHi: 0x%x, MemAddrLo: 0x%x\n",
-			pc[i].MemAddrHi, pc[i].MemAddrLo);
-		nand_dbg_print(NAND_DBG_DEBUG, "CommandFlags: 0x%x\n",
-			pc[i].CommandFlags);
-		nand_dbg_print(NAND_DBG_DEBUG, "Channel: %d, Status: 0x%x\n",
-			pc[i].Channel, pc[i].Status);
-		nand_dbg_print(NAND_DBG_DEBUG,
-			"MemCopyPointerHi: 0x%x, MemCopyPointerLo: 0x%x\n",
-			pc[i].MemCopyPointerHi, pc[i].MemCopyPointerLo);
-		nand_dbg_print(NAND_DBG_DEBUG,
-			"Reserved12: 0x%x, Reserved13: 0x%x, "
-			"Reserved14: 0x%x, pcmd: %d\n",
-			pc[i].Reserved12, pc[i].Reserved13,
-			pc[i].Reserved14, pc[i].pcmd);
-	}
-}
-
-/* Print the Memory copy descriptors */
-static void print_memcp_descriptors(void)
-{
-	struct memcpy_descriptor *pm;
-	int i;
-
-	pm = (struct memcpy_descriptor *)info.memcp_desc_buf;
-
-	nand_dbg_print(NAND_DBG_DEBUG, "\nWill dump mem_cpy descriptors:\n");
-
-	for (i = 0; i < info.cdma_num; i++) {
-		nand_dbg_print(NAND_DBG_DEBUG, "\ni: %d\n", i);
-		nand_dbg_print(NAND_DBG_DEBUG,
-			"NxtPointerHi: 0x%x, NxtPointerLo: 0x%x\n",
-			pm[i].NxtPointerHi, pm[i].NxtPointerLo);
-		nand_dbg_print(NAND_DBG_DEBUG,
-			"SrcAddrHi: 0x%x, SrcAddrLo: 0x%x\n",
-			pm[i].SrcAddrHi, pm[i].SrcAddrLo);
-		nand_dbg_print(NAND_DBG_DEBUG,
-			"DestAddrHi: 0x%x, DestAddrLo: 0x%x\n",
-			pm[i].DestAddrHi, pm[i].DestAddrLo);
-		nand_dbg_print(NAND_DBG_DEBUG, "XferSize: %d\n",
-			pm[i].XferSize);
-		nand_dbg_print(NAND_DBG_DEBUG, "MemCopyFlags: 0x%x\n",
-			pm[i].MemCopyFlags);
-		nand_dbg_print(NAND_DBG_DEBUG, "MemCopyStatus: %d\n",
-			pm[i].MemCopyStatus);
-		nand_dbg_print(NAND_DBG_DEBUG, "reserved9: 0x%x\n",
-			pm[i].reserved9);
-		nand_dbg_print(NAND_DBG_DEBUG, "reserved10: 0x%x\n",
-			pm[i].reserved10);
-		nand_dbg_print(NAND_DBG_DEBUG, "reserved11: 0x%x\n",
-			pm[i].reserved11);
-		nand_dbg_print(NAND_DBG_DEBUG, "reserved12: 0x%x\n",
-			pm[i].reserved12);
-		nand_dbg_print(NAND_DBG_DEBUG, "reserved13: 0x%x\n",
-			pm[i].reserved13);
-		nand_dbg_print(NAND_DBG_DEBUG, "reserved14: 0x%x\n",
-			pm[i].reserved14);
-		nand_dbg_print(NAND_DBG_DEBUG, "reserved15: 0x%x\n",
-			pm[i].reserved15);
-	}
-}
-#endif
-
-/* Reset cdma_descriptor chain to 0 */
-static void reset_cdma_desc(int i)
-{
-	struct cdma_descriptor *ptr;
-
-	BUG_ON(i >= MAX_DESCS);
-
-	ptr = (struct cdma_descriptor *)info.cdma_desc_buf;
-
-	ptr[i].NxtPointerHi = 0;
-	ptr[i].NxtPointerLo = 0;
-	ptr[i].FlashPointerHi = 0;
-	ptr[i].FlashPointerLo = 0;
-	ptr[i].CommandType = 0;
-	ptr[i].MemAddrHi = 0;
-	ptr[i].MemAddrLo = 0;
-	ptr[i].CommandFlags = 0;
-	ptr[i].Channel = 0;
-	ptr[i].Status = 0;
-	ptr[i].MemCopyPointerHi = 0;
-	ptr[i].MemCopyPointerLo = 0;
-}
-
-/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
-* Function:     CDMA_UpdateEventStatus
-* Inputs:       none
-* Outputs:      none
-* Description:  This function update the event status of all the channels
-*               when an error condition is reported.
-*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
-void CDMA_UpdateEventStatus(void)
-{
-	int i, j, active_chan;
-	struct cdma_descriptor *ptr;
-
-	nand_dbg_print(NAND_DBG_DEBUG, "%s, Line %d, Function: %s\n",
-		       __FILE__, __LINE__, __func__);
-
-	ptr = (struct cdma_descriptor *)info.cdma_desc_buf;
-
-	for (j = 0; j < info.cdma_num; j++) {
-		/* Check for the descriptor with failure */
-		if ((ptr[j].Status & CMD_DMA_DESC_FAIL))
-			break;
-
-	}
-
-	/* All the previous cmd's status for this channel must be good */
-	for (i = 0; i < j; i++) {
-		if (ptr[i].pcmd != 0xff)
-			info.pcmds[ptr[i].pcmd].Status = CMD_PASS;
-	}
-
-	/* Abort the channel with type 0 reset command. It resets the */
-	/* selected channel after the descriptor completes the flash */
-	/* operation and status has been updated for the descriptor. */
-	/* Memory Copy and Sync associated with this descriptor will */
-	/* not be executed */
-	active_chan = ioread32(FlashReg + CHNL_ACTIVE);
-	if ((active_chan & (1 << info.flash_bank)) == (1 << info.flash_bank)) {
-		iowrite32(MODE_02 | (0 << 4), FlashMem); /* Type 0 reset */
-		iowrite32((0xF << 4) | info.flash_bank, FlashMem + 0x10);
-	} else { /* Should not reached here */
-		printk(KERN_ERR "Error! Used bank is not set in"
-			" reg CHNL_ACTIVE\n");
-	}
-}
-
-static void cdma_trans(u16 chan)
-{
-	u32 addr;
-
-	addr = info.cdma_desc;
-
-	iowrite32(MODE_10 | (chan << 24), FlashMem);
-	iowrite32((1 << 7) | chan, FlashMem + 0x10);
-
-	iowrite32(MODE_10 | (chan << 24) | ((0x0FFFF & (addr >> 16)) << 8),
-		FlashMem);
-	iowrite32((1 << 7) | (1 << 4) | 0, FlashMem + 0x10);
-
-	iowrite32(MODE_10 | (chan << 24) | ((0x0FFFF & addr) << 8), FlashMem);
-	iowrite32((1 << 7) | (1 << 5) | 0, FlashMem + 0x10);
-
-	iowrite32(MODE_10 | (chan << 24), FlashMem);
-	iowrite32((1 << 7) | (1 << 5) | (1 << 4) | 0, FlashMem + 0x10);
-}
-
-/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
-* Function:     CDMA_Execute_CMDs (for use with CMD_DMA)
-* Inputs:       tag_count:  the number of pending cmds to do
-* Outputs:      PASS/FAIL
-* Description:  Build the SDMA chain(s) by making one CMD-DMA descriptor
-*               for each pending command, start the CDMA engine, and return.
-*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
-u16 CDMA_Execute_CMDs(void)
-{
-	int i, ret;
-	u64 flash_add;
-	u32 ptr;
-	dma_addr_t map_addr, next_ptr;
-	u16 status = PASS;
-	u16 tmp_c;
-	struct cdma_descriptor *pc;
-	struct memcpy_descriptor *pm;
-
-	nand_dbg_print(NAND_DBG_TRACE, "%s, Line %d, Function: %s\n",
-		       __FILE__, __LINE__, __func__);
-
-	/* No pending cmds to execute, just exit */
-	if (0 == info.pcmds_num) {
-		nand_dbg_print(NAND_DBG_TRACE,
-			"No pending cmds to execute. Just exit.\n");
-		return PASS;
-	}
-
-	for (i = 0; i < MAX_DESCS; i++)
-		reset_cdma_desc(i);
-
-	pc = (struct cdma_descriptor *)info.cdma_desc_buf;
-	pm = (struct memcpy_descriptor *)info.memcp_desc_buf;
-
-	info.cdma_desc = virt_to_bus(info.cdma_desc_buf);
-	info.memcp_desc = virt_to_bus(info.memcp_desc_buf);
-	next_ptr = info.cdma_desc;
-	info.cdma_num = 0;
-
-	for (i = 0; i < info.pcmds_num; i++) {
-		if (info.pcmds[i].Block >= DeviceInfo.wTotalBlocks) {
-			info.pcmds[i].Status = CMD_NOT_DONE;
-			continue;
-		}
-
-		next_ptr += sizeof(struct cdma_descriptor);
-		pc[info.cdma_num].NxtPointerHi = next_ptr >> 16;
-		pc[info.cdma_num].NxtPointerLo = next_ptr & 0xffff;
-
-		/* Use the Block offset within a bank */
-		tmp_c = info.pcmds[i].Block /
-			(DeviceInfo.wTotalBlocks / totalUsedBanks);
-		flash_add = (u64)(info.pcmds[i].Block - tmp_c *
-			(DeviceInfo.wTotalBlocks / totalUsedBanks)) *
-			DeviceInfo.wBlockDataSize +
-			(u64)(info.pcmds[i].Page) *
-			DeviceInfo.wPageDataSize;
-
-		ptr = MODE_10 | (info.flash_bank << 24) |
-			(u32)GLOB_u64_Div(flash_add,
-				DeviceInfo.wPageDataSize);
-		pc[info.cdma_num].FlashPointerHi = ptr >> 16;
-		pc[info.cdma_num].FlashPointerLo = ptr & 0xffff;
-
-		if ((info.pcmds[i].CMD == WRITE_MAIN_SPARE_CMD) ||
-			(info.pcmds[i].CMD == READ_MAIN_SPARE_CMD)) {
-			/* Descriptor to set Main+Spare Access Mode */
-			pc[info.cdma_num].CommandType = 0x43;
-			pc[info.cdma_num].CommandFlags =
-				(0 << 10) | (1 << 9) | (0 << 8) | 0x40;
-			pc[info.cdma_num].MemAddrHi = 0;
-			pc[info.cdma_num].MemAddrLo = 0;
-			pc[info.cdma_num].Channel = 0;
-			pc[info.cdma_num].Status = 0;
-			pc[info.cdma_num].pcmd = i;
-
-			info.cdma_num++;
-			BUG_ON(info.cdma_num >= MAX_DESCS);
-
-			reset_cdma_desc(info.cdma_num);
-			next_ptr += sizeof(struct cdma_descriptor);
-			pc[info.cdma_num].NxtPointerHi = next_ptr >> 16;
-			pc[info.cdma_num].NxtPointerLo = next_ptr & 0xffff;
-			pc[info.cdma_num].FlashPointerHi = ptr >> 16;
-			pc[info.cdma_num].FlashPointerLo = ptr & 0xffff;
-		}
-
-		switch (info.pcmds[i].CMD) {
-		case ERASE_CMD:
-			pc[info.cdma_num].CommandType = 1;
-			pc[info.cdma_num].CommandFlags =
-				(0 << 10) | (1 << 9) | (0 << 8) | 0x40;
-			pc[info.cdma_num].MemAddrHi = 0;
-			pc[info.cdma_num].MemAddrLo = 0;
-			break;
-
-		case WRITE_MAIN_CMD:
-			pc[info.cdma_num].CommandType =
-				0x2100 | info.pcmds[i].PageCount;
-			pc[info.cdma_num].CommandFlags =
-				(0 << 10) | (1 << 9) | (0 << 8) | 0x40;
-			map_addr = virt_to_bus(info.pcmds[i].DataAddr);
-			pc[info.cdma_num].MemAddrHi = map_addr >> 16;
-			pc[info.cdma_num].MemAddrLo = map_addr & 0xffff;
-			break;
-
-		case READ_MAIN_CMD:
-			pc[info.cdma_num].CommandType =
-				0x2000 | info.pcmds[i].PageCount;
-			pc[info.cdma_num].CommandFlags =
-				(0 << 10) | (1 << 9) | (0 << 8) | 0x40;
-			map_addr = virt_to_bus(info.pcmds[i].DataAddr);
-			pc[info.cdma_num].MemAddrHi = map_addr >> 16;
-			pc[info.cdma_num].MemAddrLo = map_addr & 0xffff;
-			break;
-
-		case WRITE_MAIN_SPARE_CMD:
-			pc[info.cdma_num].CommandType =
-				0x2100 | info.pcmds[i].PageCount;
-			pc[info.cdma_num].CommandFlags =
-				(0 << 10) | (1 << 9) | (0 << 8) | 0x40;
-			map_addr = virt_to_bus(info.pcmds[i].DataAddr);
-			pc[info.cdma_num].MemAddrHi = map_addr >> 16;
-			pc[info.cdma_num].MemAddrLo = map_addr & 0xffff;
-			break;
-
-		case READ_MAIN_SPARE_CMD:
-			pc[info.cdma_num].CommandType =
-				0x2000 | info.pcmds[i].PageCount;
-			pc[info.cdma_num].CommandFlags =
-				(0 << 10) | (1 << 9) | (0 << 8) | 0x40;
-			map_addr = virt_to_bus(info.pcmds[i].DataAddr);
-			pc[info.cdma_num].MemAddrHi = map_addr >> 16;
-			pc[info.cdma_num].MemAddrLo = map_addr & 0xffff;
-			break;
-
-		case MEMCOPY_CMD:
-			pc[info.cdma_num].CommandType = 0xFFFF; /* NOP cmd */
-			/* Set bit 11 to let the CDMA engine continue to */
-			/* execute only after it has finished processing   */
-			/* the memcopy descriptor.                        */
-			/* Also set bit 10 and bit 9 to 1                  */
-			pc[info.cdma_num].CommandFlags = 0x0E40;
-			map_addr = info.memcp_desc + info.cdma_num *
-					sizeof(struct memcpy_descriptor);
-			pc[info.cdma_num].MemCopyPointerHi = map_addr >> 16;
-			pc[info.cdma_num].MemCopyPointerLo = map_addr & 0xffff;
-
-			pm[info.cdma_num].NxtPointerHi = 0;
-			pm[info.cdma_num].NxtPointerLo = 0;
-
-			map_addr = virt_to_bus(info.pcmds[i].DataSrcAddr);
-			pm[info.cdma_num].SrcAddrHi = map_addr >> 16;
-			pm[info.cdma_num].SrcAddrLo = map_addr & 0xffff;
-			map_addr = virt_to_bus(info.pcmds[i].DataDestAddr);
-			pm[info.cdma_num].DestAddrHi = map_addr >> 16;
-			pm[info.cdma_num].DestAddrLo = map_addr & 0xffff;
-
-			pm[info.cdma_num].XferSize =
-				info.pcmds[i].MemCopyByteCnt;
-			pm[info.cdma_num].MemCopyFlags =
-				(0 << 15 | 0 << 14 | 27 << 8 | 0x40);
-			pm[info.cdma_num].MemCopyStatus = 0;
-			break;
-
-		case DUMMY_CMD:
-		default:
-			pc[info.cdma_num].CommandType = 0XFFFF;
-			pc[info.cdma_num].CommandFlags =
-				(0 << 10) | (1 << 9) | (0 << 8) | 0x40;
-			pc[info.cdma_num].MemAddrHi = 0;
-			pc[info.cdma_num].MemAddrLo = 0;
-			break;
-		}
-
-		pc[info.cdma_num].Channel = 0;
-		pc[info.cdma_num].Status = 0;
-		pc[info.cdma_num].pcmd = i;
-
-		info.cdma_num++;
-		BUG_ON(info.cdma_num >= MAX_DESCS);
-
-		if ((info.pcmds[i].CMD == WRITE_MAIN_SPARE_CMD) ||
-			(info.pcmds[i].CMD == READ_MAIN_SPARE_CMD)) {
-			/* Descriptor to set back Main Area Access Mode */
-			reset_cdma_desc(info.cdma_num);
-			next_ptr += sizeof(struct cdma_descriptor);
-			pc[info.cdma_num].NxtPointerHi = next_ptr >> 16;
-			pc[info.cdma_num].NxtPointerLo = next_ptr & 0xffff;
-
-			pc[info.cdma_num].FlashPointerHi = ptr >> 16;
-			pc[info.cdma_num].FlashPointerLo = ptr & 0xffff;
-
-			pc[info.cdma_num].CommandType = 0x42;
-			pc[info.cdma_num].CommandFlags =
-				(0 << 10) | (1 << 9) | (0 << 8) | 0x40;
-			pc[info.cdma_num].MemAddrHi = 0;
-			pc[info.cdma_num].MemAddrLo = 0;
-
-			pc[info.cdma_num].Channel = 0;
-			pc[info.cdma_num].Status = 0;
-			pc[info.cdma_num].pcmd = i;
-
-			info.cdma_num++;
-			BUG_ON(info.cdma_num >= MAX_DESCS);
-		}
-	}
-
-	/* Add a dummy descriptor at end of the CDMA chain */
-	reset_cdma_desc(info.cdma_num);
-	ptr = MODE_10 | (info.flash_bank << 24);
-	pc[info.cdma_num].FlashPointerHi = ptr >> 16;
-	pc[info.cdma_num].FlashPointerLo = ptr & 0xffff;
-	pc[info.cdma_num].CommandType = 0xFFFF; /* NOP command */
-	/* Set Command Flags for the last CDMA descriptor: */
-	/* set Continue bit (bit 9) to 0 and Interrupt bit (bit 8) to 1 */
-	pc[info.cdma_num].CommandFlags =
-		(0 << 10) | (0 << 9) | (1 << 8) | 0x40;
-	pc[info.cdma_num].pcmd = 0xff; /* Set it to an illegal value */
-	info.cdma_num++;
-	BUG_ON(info.cdma_num >= MAX_DESCS);
-
-	iowrite32(1, FlashReg + GLOBAL_INT_ENABLE);  /* Enable Interrupt */
-
-	iowrite32(1, FlashReg + DMA_ENABLE);
-	/* Wait for DMA to be enabled before issuing the next command */
-	while (!(ioread32(FlashReg + DMA_ENABLE) & DMA_ENABLE__FLAG))
-		;
-	cdma_trans(info.flash_bank);
-
-	ret = wait_for_completion_timeout(&info.complete, 50 * HZ);
-	if (!ret)
-		printk(KERN_ERR "Wait for completion timeout "
-			"in %s, Line %d\n", __FILE__, __LINE__);
-	status = info.ret;
-
-	info.pcmds_num = 0; /* Clear the pending cmds number to 0 */
-
-	return status;
-}
-
-int is_cdma_interrupt(void)
-{
-	u32 ints_b0, ints_b1, ints_b2, ints_b3, ints_cdma;
-	u32 int_en_mask;
-	u32 cdma_int_en_mask;
-
-	nand_dbg_print(NAND_DBG_DEBUG, "%s, Line %d, Function: %s\n",
-		       __FILE__, __LINE__, __func__);
-
-	/* Set the global Enable masks for only those interrupts
-	 * that are supported */
-	cdma_int_en_mask = (DMA_INTR__DESC_COMP_CHANNEL0 |
-			DMA_INTR__DESC_COMP_CHANNEL1 |
-			DMA_INTR__DESC_COMP_CHANNEL2 |
-			DMA_INTR__DESC_COMP_CHANNEL3 |
-			DMA_INTR__MEMCOPY_DESC_COMP);
-
-	int_en_mask = (INTR_STATUS0__ECC_ERR |
-		INTR_STATUS0__PROGRAM_FAIL |
-		INTR_STATUS0__ERASE_FAIL);
-
-	ints_b0 = ioread32(FlashReg + INTR_STATUS0) & int_en_mask;
-	ints_b1 = ioread32(FlashReg + INTR_STATUS1) & int_en_mask;
-	ints_b2 = ioread32(FlashReg + INTR_STATUS2) & int_en_mask;
-	ints_b3 = ioread32(FlashReg + INTR_STATUS3) & int_en_mask;
-	ints_cdma = ioread32(FlashReg + DMA_INTR) & cdma_int_en_mask;
-
-	nand_dbg_print(NAND_DBG_WARN, "ints_bank0 to ints_bank3: "
-			"0x%x, 0x%x, 0x%x, 0x%x, ints_cdma: 0x%x\n",
-			ints_b0, ints_b1, ints_b2, ints_b3, ints_cdma);
-
-	if (ints_b0 || ints_b1 || ints_b2 || ints_b3 || ints_cdma) {
-		return 1;
-	} else {
-		iowrite32(ints_b0, FlashReg + INTR_STATUS0);
-		iowrite32(ints_b1, FlashReg + INTR_STATUS1);
-		iowrite32(ints_b2, FlashReg + INTR_STATUS2);
-		iowrite32(ints_b3, FlashReg + INTR_STATUS3);
-		nand_dbg_print(NAND_DBG_DEBUG,
-			"Not a NAND controller interrupt! Ignore it.\n");
-		return 0;
-	}
-}
-
-static void update_event_status(void)
-{
-	int i;
-	struct cdma_descriptor *ptr;
-
-	nand_dbg_print(NAND_DBG_TRACE, "%s, Line %d, Function: %s\n",
-		       __FILE__, __LINE__, __func__);
-
-	ptr = (struct cdma_descriptor *)info.cdma_desc_buf;
-
-	for (i = 0; i < info.cdma_num; i++) {
-		if (ptr[i].pcmd != 0xff)
-			info.pcmds[ptr[i].pcmd].Status = CMD_PASS;
-		if ((ptr[i].CommandType == 0x41) ||
-			(ptr[i].CommandType == 0x42) ||
-			(ptr[i].CommandType == 0x43))
-			continue;
-
-		switch (info.pcmds[ptr[i].pcmd].CMD) {
-		case READ_MAIN_SPARE_CMD:
-			Conv_Main_Spare_Data_Phy2Log_Format(
-				info.pcmds[ptr[i].pcmd].DataAddr,
-				info.pcmds[ptr[i].pcmd].PageCount);
-			break;
-		case READ_SPARE_CMD:
-			Conv_Spare_Data_Phy2Log_Format(
-				info.pcmds[ptr[i].pcmd].DataAddr);
-			break;
-		}
-	}
-}
-
-static u16 do_ecc_for_desc(u32 ch, u8 *buf, u16 page)
-{
-	u16 event = EVENT_NONE;
-	u16 err_byte;
-	u16 err_page = 0;
-	u8 err_sector;
-	u8 err_device;
-	u16 ecc_correction_info;
-	u16 err_address;
-	u32 eccSectorSize;
-	u8 *err_pos;
-
-	nand_dbg_print(NAND_DBG_WARN, "%s, Line %d, Function: %s\n",
-		       __FILE__, __LINE__, __func__);
-
-	eccSectorSize = ECC_SECTOR_SIZE * (DeviceInfo.wDevicesConnected);
-
-	do {
-		if (0 == ch)
-			err_page = ioread32(FlashReg + ERR_PAGE_ADDR0);
-		else if (1 == ch)
-			err_page = ioread32(FlashReg + ERR_PAGE_ADDR1);
-		else if (2 == ch)
-			err_page = ioread32(FlashReg + ERR_PAGE_ADDR2);
-		else if (3 == ch)
-			err_page = ioread32(FlashReg + ERR_PAGE_ADDR3);
-
-		err_address = ioread32(FlashReg + ECC_ERROR_ADDRESS);
-		err_byte = err_address & ECC_ERROR_ADDRESS__OFFSET;
-		err_sector = ((err_address &
-			ECC_ERROR_ADDRESS__SECTOR_NR) >> 12);
-
-		ecc_correction_info = ioread32(FlashReg + ERR_CORRECTION_INFO);
-		err_device = ((ecc_correction_info &
-			ERR_CORRECTION_INFO__DEVICE_NR) >> 8);
-
-		if (ecc_correction_info & ERR_CORRECTION_INFO__ERROR_TYPE) {
-			event = EVENT_UNCORRECTABLE_DATA_ERROR;
-		} else {
-			event = EVENT_CORRECTABLE_DATA_ERROR_FIXED;
-			if (err_byte < ECC_SECTOR_SIZE) {
-				err_pos = buf +
-					(err_page - page) *
-					DeviceInfo.wPageDataSize +
-					err_sector * eccSectorSize +
-					err_byte *
-					DeviceInfo.wDevicesConnected +
-					err_device;
-				*err_pos ^= ecc_correction_info &
-					ERR_CORRECTION_INFO__BYTEMASK;
-			}
-		}
-	} while (!(ecc_correction_info & ERR_CORRECTION_INFO__LAST_ERR_INFO));
-
-	return event;
-}
-
-static u16 process_ecc_int(u32 c, u16 *p_desc_num)
-{
-	struct cdma_descriptor *ptr;
-	u16 j;
-	int event = EVENT_PASS;
-
-	nand_dbg_print(NAND_DBG_WARN, "%s, Line %d, Function: %s\n",
-		       __FILE__, __LINE__, __func__);
-
-	if (c != info.flash_bank)
-		printk(KERN_ERR "Error!info.flash_bank is %d, while c is %d\n",
-				info.flash_bank, c);
-
-	ptr = (struct cdma_descriptor *)info.cdma_desc_buf;
-
-	for (j = 0; j < info.cdma_num; j++)
-		if ((ptr[j].Status & CMD_DMA_DESC_COMP) != CMD_DMA_DESC_COMP)
-			break;
-
-	*p_desc_num = j; /* Pass the descripter number found here */
-
-	if (j >= info.cdma_num) {
-		printk(KERN_ERR "Can not find the correct descriptor number "
-			"when ecc interrupt triggered!"
-			"info.cdma_num: %d, j: %d\n", info.cdma_num, j);
-		return EVENT_UNCORRECTABLE_DATA_ERROR;
-	}
-
-	event = do_ecc_for_desc(c, info.pcmds[ptr[j].pcmd].DataAddr,
-		info.pcmds[ptr[j].pcmd].Page);
-
-	if (EVENT_UNCORRECTABLE_DATA_ERROR == event) {
-		printk(KERN_ERR "Uncorrectable ECC error!"
-			"info.cdma_num: %d, j: %d, "
-			"pending cmd CMD: 0x%x, "
-			"Block: 0x%x, Page: 0x%x, PageCount: 0x%x\n",
-			info.cdma_num, j,
-			info.pcmds[ptr[j].pcmd].CMD,
-			info.pcmds[ptr[j].pcmd].Block,
-			info.pcmds[ptr[j].pcmd].Page,
-			info.pcmds[ptr[j].pcmd].PageCount);
-
-		if (ptr[j].pcmd != 0xff)
-			info.pcmds[ptr[j].pcmd].Status = CMD_FAIL;
-		CDMA_UpdateEventStatus();
-	}
-
-	return event;
-}
-
-static void process_prog_erase_fail_int(u16 desc_num)
-{
-	struct cdma_descriptor *ptr;
-
-	nand_dbg_print(NAND_DBG_DEBUG, "%s, Line %d, Function: %s\n",
-		       __FILE__, __LINE__, __func__);
-
-	ptr = (struct cdma_descriptor *)info.cdma_desc_buf;
-
-	if (ptr[desc_num].pcmd != 0xFF)
-		info.pcmds[ptr[desc_num].pcmd].Status = CMD_FAIL;
-
-	CDMA_UpdateEventStatus();
-}
-
-/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
-* Function:     CDMA_Event_Status (for use with CMD_DMA)
-* Inputs:       none
-* Outputs:      Event_Status code
-* Description:  This function is called after an interrupt has happened
-*               It reads the HW status register and ...tbd
-*               It returns the appropriate event status
-*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
-u16  CDMA_Event_Status(void)
-{
-	u32 ints_addr[4] = {INTR_STATUS0, INTR_STATUS1,
-		INTR_STATUS2, INTR_STATUS3};
-	u32 dma_intr_bit[4] = {DMA_INTR__DESC_COMP_CHANNEL0,
-		DMA_INTR__DESC_COMP_CHANNEL1,
-		DMA_INTR__DESC_COMP_CHANNEL2,
-		DMA_INTR__DESC_COMP_CHANNEL3};
-	u32 cdma_int_status, int_status;
-	u32 ecc_enable = 0;
-	u16 event = EVENT_PASS;
-	u16 cur_desc = 0;
-
-	nand_dbg_print(NAND_DBG_TRACE, "%s, Line %d, Function: %s\n",
-		       __FILE__, __LINE__, __func__);
-
-	ecc_enable = ioread32(FlashReg + ECC_ENABLE);
-
-	while (1) {
-		int_status = ioread32(FlashReg + ints_addr[info.flash_bank]);
-		if (ecc_enable && (int_status & INTR_STATUS0__ECC_ERR)) {
-			event = process_ecc_int(info.flash_bank, &cur_desc);
-			iowrite32(INTR_STATUS0__ECC_ERR,
-				FlashReg + ints_addr[info.flash_bank]);
-			if (EVENT_UNCORRECTABLE_DATA_ERROR == event) {
-				nand_dbg_print(NAND_DBG_WARN,
-					"ints_bank0 to ints_bank3: "
-					"0x%x, 0x%x, 0x%x, 0x%x, "
-					"ints_cdma: 0x%x\n",
-					ioread32(FlashReg + INTR_STATUS0),
-					ioread32(FlashReg + INTR_STATUS1),
-					ioread32(FlashReg + INTR_STATUS2),
-					ioread32(FlashReg + INTR_STATUS3),
-					ioread32(FlashReg + DMA_INTR));
-				break;
-			}
-		} else if (int_status & INTR_STATUS0__PROGRAM_FAIL) {
-			printk(KERN_ERR "NAND program fail interrupt!\n");
-			process_prog_erase_fail_int(cur_desc);
-			event = EVENT_PROGRAM_FAILURE;
-			break;
-		} else if (int_status & INTR_STATUS0__ERASE_FAIL) {
-			printk(KERN_ERR "NAND erase fail interrupt!\n");
-			process_prog_erase_fail_int(cur_desc);
-			event = EVENT_ERASE_FAILURE;
-			break;
-		} else {
-			cdma_int_status = ioread32(FlashReg + DMA_INTR);
-			if (cdma_int_status & dma_intr_bit[info.flash_bank]) {
-				iowrite32(dma_intr_bit[info.flash_bank],
-					FlashReg + DMA_INTR);
-				update_event_status();
-				event = EVENT_PASS;
-				break;
-			}
-		}
-	}
-
-	int_status = ioread32(FlashReg + ints_addr[info.flash_bank]);
-	iowrite32(int_status, FlashReg + ints_addr[info.flash_bank]);
-	cdma_int_status = ioread32(FlashReg + DMA_INTR);
-	iowrite32(cdma_int_status, FlashReg + DMA_INTR);
-
-	iowrite32(0, FlashReg + DMA_ENABLE);
-	while ((ioread32(FlashReg + DMA_ENABLE) & DMA_ENABLE__FLAG))
-		;
-
-	return event;
-}
-
-
-
diff --git a/drivers/staging/spectra/lld_cdma.h b/drivers/staging/spectra/lld_cdma.h
deleted file mode 100644
index 854ea06..0000000
--- a/drivers/staging/spectra/lld_cdma.h
+++ /dev/null
@@ -1,123 +0,0 @@
-/*
- * NAND Flash Controller Device Driver
- * Copyright (c) 2009, Intel Corporation and its suppliers.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms and conditions of the GNU General Public License,
- * version 2, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
- *
- */
-
-/* header for LLD_CDMA.c module */
-
-#ifndef _LLD_CDMA_
-#define _LLD_CDMA_
-
-#include "flash.h"
-
-#define  DEBUG_SYNC    1
-
-/*///////////   CDMA specific MACRO definition */
-#define MAX_DESCS         (255)
-#define MAX_CHANS  (4)
-#define MAX_SYNC_POINTS         (16)
-#define MAX_DESC_PER_CHAN     (MAX_DESCS * 3 + MAX_SYNC_POINTS + 2)
-
-#define CHANNEL_SYNC_MASK       (0x000F)
-#define CHANNEL_DMA_MASK        (0x00F0)
-#define CHANNEL_ID_MASK         (0x0300)
-#define CHANNEL_CONT_MASK       (0x4000)
-#define CHANNEL_INTR_MASK       (0x8000)
-
-#define CHANNEL_SYNC_OFFSET     (0)
-#define CHANNEL_DMA_OFFSET      (4)
-#define CHANNEL_ID_OFFSET       (8)
-#define CHANNEL_CONT_OFFSET     (14)
-#define CHANNEL_INTR_OFFSET     (15)
-
-u16 CDMA_Data_CMD(u8 cmd, u8 *data, u32 block, u16 page, u16 num, u16 flags);
-u16 CDMA_MemCopy_CMD(u8 *dest, u8 *src, u32 byte_cnt, u16 flags);
-u16 CDMA_Execute_CMDs(void);
-void print_pending_cmds(void);
-void print_cdma_descriptors(void);
-
-extern u8 g_SBDCmdIndex;
-extern struct mrst_nand_info info;
-
-
-/*///////////   prototypes: APIs for LLD_CDMA */
-int is_cdma_interrupt(void);
-u16 CDMA_Event_Status(void);
-
-/* CMD-DMA Descriptor Struct.  These are defined by the CMD_DMA HW */
-struct cdma_descriptor {
-	u32 NxtPointerHi;
-	u32 NxtPointerLo;
-	u32 FlashPointerHi;
-	u32 FlashPointerLo;
-	u32 CommandType;
-	u32 MemAddrHi;
-	u32 MemAddrLo;
-	u32 CommandFlags;
-	u32 Channel;
-	u32 Status;
-	u32 MemCopyPointerHi;
-	u32 MemCopyPointerLo;
-	u32 Reserved12;
-	u32 Reserved13;
-	u32 Reserved14;
-	u32 pcmd; /* pending cmd num related to this descriptor */
-};
-
-/* This struct holds one MemCopy descriptor as defined by the HW */
-struct memcpy_descriptor {
-	u32 NxtPointerHi;
-	u32 NxtPointerLo;
-	u32 SrcAddrHi;
-	u32 SrcAddrLo;
-	u32 DestAddrHi;
-	u32 DestAddrLo;
-	u32 XferSize;
-	u32 MemCopyFlags;
-	u32 MemCopyStatus;
-	u32 reserved9;
-	u32 reserved10;
-	u32 reserved11;
-	u32 reserved12;
-	u32 reserved13;
-	u32 reserved14;
-	u32 reserved15;
-};
-
-/* Pending CMD table entries (includes MemCopy parameters */
-struct pending_cmd {
-	u8 CMD;
-	u8 *DataAddr;
-	u32 Block;
-	u16 Page;
-	u16 PageCount;
-	u8 *DataDestAddr;
-	u8 *DataSrcAddr;
-	u32 MemCopyByteCnt;
-	u16 Flags;
-	u16 Status;
-};
-
-#if DEBUG_SYNC
-extern u32 debug_sync_cnt;
-#endif
-
-/* Definitions for CMD DMA descriptor chain fields */
-#define     CMD_DMA_DESC_COMP   0x8000
-#define     CMD_DMA_DESC_FAIL   0x4000
-
-#endif /*_LLD_CDMA_*/
diff --git a/drivers/staging/spectra/lld_emu.c b/drivers/staging/spectra/lld_emu.c
deleted file mode 100644
index 095f2f0..0000000
--- a/drivers/staging/spectra/lld_emu.c
+++ /dev/null
@@ -1,776 +0,0 @@
-/*
- * NAND Flash Controller Device Driver
- * Copyright (c) 2009, Intel Corporation and its suppliers.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms and conditions of the GNU General Public License,
- * version 2, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
- *
- */
-
-#include <linux/fs.h>
-#include <linux/slab.h>
-#include "flash.h"
-#include "ffsdefs.h"
-#include "lld_emu.h"
-#include "lld.h"
-#if CMD_DMA
-#include "lld_cdma.h"
-#if FLASH_EMU
-u32 totalUsedBanks;
-u32 valid_banks[MAX_CHANS];
-#endif
-#endif
-
-#define GLOB_LLD_PAGES           64
-#define GLOB_LLD_PAGE_SIZE       (512+16)
-#define GLOB_LLD_PAGE_DATA_SIZE  512
-#define GLOB_LLD_BLOCKS          2048
-
-#if FLASH_EMU			/* This is for entire module */
-
-static u8 *flash_memory[GLOB_LLD_BLOCKS * GLOB_LLD_PAGES];
-
-/* Read nand emu file and then fill it's content to flash_memory */
-int emu_load_file_to_mem(void)
-{
-	mm_segment_t fs;
-	struct file *nef_filp = NULL;
-	struct inode *inode = NULL;
-	loff_t nef_size = 0;
-	loff_t tmp_file_offset, file_offset;
-	ssize_t nread;
-	int i, rc = -EINVAL;
-
-	nand_dbg_print(NAND_DBG_TRACE, "%s, Line %d, Function: %s\n",
-		       __FILE__, __LINE__, __func__);
-
-	fs = get_fs();
-	set_fs(get_ds());
-
-	nef_filp = filp_open("/root/nand_emu_file", O_RDWR | O_LARGEFILE, 0);
-	if (IS_ERR(nef_filp)) {
-		printk(KERN_ERR "filp_open error: "
-		       "Unable to open nand emu file!\n");
-		return PTR_ERR(nef_filp);
-	}
-
-	if (nef_filp->f_path.dentry) {
-		inode = nef_filp->f_path.dentry->d_inode;
-	} else {
-		printk(KERN_ERR "Can not get valid inode!\n");
-		goto out;
-	}
-
-	nef_size = i_size_read(inode->i_mapping->host);
-	if (nef_size <= 0) {
-		printk(KERN_ERR "Invalid nand emu file size: "
-		       "0x%llx\n", nef_size);
-		goto out;
-	} else {
-		nand_dbg_print(NAND_DBG_DEBUG, "nand emu file size: %lld\n",
-			       nef_size);
-	}
-
-	file_offset = 0;
-	for (i = 0; i < GLOB_LLD_BLOCKS * GLOB_LLD_PAGES; i++) {
-		tmp_file_offset = file_offset;
-		nread = vfs_read(nef_filp,
-				 (char __user *)flash_memory[i],
-				 GLOB_LLD_PAGE_SIZE, &tmp_file_offset);
-		if (nread < GLOB_LLD_PAGE_SIZE) {
-			printk(KERN_ERR "%s, Line %d - "
-			       "nand emu file partial read: "
-			       "%d bytes\n", __FILE__, __LINE__, (int)nread);
-			goto out;
-		}
-		file_offset += GLOB_LLD_PAGE_SIZE;
-	}
-	rc = 0;
-
-out:
-	filp_close(nef_filp, current->files);
-	set_fs(fs);
-	return rc;
-}
-
-/* Write contents of flash_memory to nand emu file */
-int emu_write_mem_to_file(void)
-{
-	mm_segment_t fs;
-	struct file *nef_filp = NULL;
-	struct inode *inode = NULL;
-	loff_t nef_size = 0;
-	loff_t tmp_file_offset, file_offset;
-	ssize_t nwritten;
-	int i, rc = -EINVAL;
-
-	nand_dbg_print(NAND_DBG_TRACE, "%s, Line %d, Function: %s\n",
-		       __FILE__, __LINE__, __func__);
-
-	fs = get_fs();
-	set_fs(get_ds());
-
-	nef_filp = filp_open("/root/nand_emu_file", O_RDWR | O_LARGEFILE, 0);
-	if (IS_ERR(nef_filp)) {
-		printk(KERN_ERR "filp_open error: "
-		       "Unable to open nand emu file!\n");
-		return PTR_ERR(nef_filp);
-	}
-
-	if (nef_filp->f_path.dentry) {
-		inode = nef_filp->f_path.dentry->d_inode;
-	} else {
-		printk(KERN_ERR "Invalid " "nef_filp->f_path.dentry value!\n");
-		goto out;
-	}
-
-	nef_size = i_size_read(inode->i_mapping->host);
-	if (nef_size <= 0) {
-		printk(KERN_ERR "Invalid "
-		       "nand emu file size: 0x%llx\n", nef_size);
-		goto out;
-	} else {
-		nand_dbg_print(NAND_DBG_DEBUG, "nand emu file size: "
-			       "%lld\n", nef_size);
-	}
-
-	file_offset = 0;
-	for (i = 0; i < GLOB_LLD_BLOCKS * GLOB_LLD_PAGES; i++) {
-		tmp_file_offset = file_offset;
-		nwritten = vfs_write(nef_filp,
-				     (char __user *)flash_memory[i],
-				     GLOB_LLD_PAGE_SIZE, &tmp_file_offset);
-		if (nwritten < GLOB_LLD_PAGE_SIZE) {
-			printk(KERN_ERR "%s, Line %d - "
-			       "nand emu file partial write: "
-			       "%d bytes\n", __FILE__, __LINE__, (int)nwritten);
-			goto out;
-		}
-		file_offset += GLOB_LLD_PAGE_SIZE;
-	}
-	rc = 0;
-
-out:
-	filp_close(nef_filp, current->files);
-	set_fs(fs);
-	return rc;
-}
-
-/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
-* Function:     emu_Flash_Init
-* Inputs:       none
-* Outputs:      PASS=0 (notice 0=ok here)
-* Description:  Creates & initializes the flash RAM array.
-*
-*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
-u16 emu_Flash_Init(void)
-{
-	int i;
-
-	nand_dbg_print(NAND_DBG_TRACE, "%s, Line %d, Function: %s\n",
-		       __FILE__, __LINE__, __func__);
-
-	flash_memory[0] = vmalloc(GLOB_LLD_PAGE_SIZE * GLOB_LLD_BLOCKS *
-				  GLOB_LLD_PAGES * sizeof(u8));
-	if (!flash_memory[0]) {
-		printk(KERN_ERR "Fail to allocate memory "
-		       "for nand emulator!\n");
-		return ERR;
-	}
-
-	memset((char *)(flash_memory[0]), 0xFF,
-	       GLOB_LLD_PAGE_SIZE * GLOB_LLD_BLOCKS * GLOB_LLD_PAGES *
-	       sizeof(u8));
-
-	for (i = 1; i < GLOB_LLD_BLOCKS * GLOB_LLD_PAGES; i++)
-		flash_memory[i] = flash_memory[i - 1] + GLOB_LLD_PAGE_SIZE;
-
-	emu_load_file_to_mem(); /* Load nand emu file to mem */
-
-	return PASS;
-}
-
-/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
-* Function:     emu_Flash_Release
-* Inputs:       none
-* Outputs:      PASS=0 (notice 0=ok here)
-* Description:          Releases the flash.
-*
-*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
-int emu_Flash_Release(void)
-{
-	nand_dbg_print(NAND_DBG_TRACE, "%s, Line %d, Function: %s\n",
-		       __FILE__, __LINE__, __func__);
-
-	emu_write_mem_to_file();  /* Write back mem to nand emu file */
-
-	vfree(flash_memory[0]);
-	return PASS;
-}
-
-/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
-* Function:     emu_Read_Device_ID
-* Inputs:       none
-* Outputs:      PASS=1 FAIL=0
-* Description:  Reads the info from the controller registers.
-*               Sets up DeviceInfo structure with device parameters
-*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
-
-u16 emu_Read_Device_ID(void)
-{
-	nand_dbg_print(NAND_DBG_TRACE, "%s, Line %d, Function: %s\n",
-		       __FILE__, __LINE__, __func__);
-
-	DeviceInfo.wDeviceMaker = 0;
-	DeviceInfo.wDeviceType = 8;
-	DeviceInfo.wSpectraStartBlock = 36;
-	DeviceInfo.wSpectraEndBlock = GLOB_LLD_BLOCKS - 1;
-	DeviceInfo.wTotalBlocks = GLOB_LLD_BLOCKS;
-	DeviceInfo.wPagesPerBlock = GLOB_LLD_PAGES;
-	DeviceInfo.wPageSize = GLOB_LLD_PAGE_SIZE;
-	DeviceInfo.wPageDataSize = GLOB_LLD_PAGE_DATA_SIZE;
-	DeviceInfo.wPageSpareSize = GLOB_LLD_PAGE_SIZE -
-	    GLOB_LLD_PAGE_DATA_SIZE;
-	DeviceInfo.wBlockSize = DeviceInfo.wPageSize * GLOB_LLD_PAGES;
-	DeviceInfo.wBlockDataSize = DeviceInfo.wPageDataSize * GLOB_LLD_PAGES;
-	DeviceInfo.wDataBlockNum = (u32) (DeviceInfo.wSpectraEndBlock -
-						DeviceInfo.wSpectraStartBlock
-						+ 1);
-	DeviceInfo.MLCDevice = 1; /* Emulate MLC device */
-	DeviceInfo.nBitsInPageNumber =
-		(u8)GLOB_Calc_Used_Bits(DeviceInfo.wPagesPerBlock);
-	DeviceInfo.nBitsInPageDataSize =
-		(u8)GLOB_Calc_Used_Bits(DeviceInfo.wPageDataSize);
-	DeviceInfo.nBitsInBlockDataSize =
-		(u8)GLOB_Calc_Used_Bits(DeviceInfo.wBlockDataSize);
-
-#if CMD_DMA
-	totalUsedBanks = 4;
-	valid_banks[0] = 1;
-	valid_banks[1] = 1;
-	valid_banks[2] = 1;
-	valid_banks[3] = 1;
-#endif
-
-	return PASS;
-}
-
-/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
-* Function:     emu_Flash_Reset
-* Inputs:       none
-* Outputs:      PASS=0 (notice 0=ok here)
-* Description:          Reset the flash
-*
-*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
-u16 emu_Flash_Reset(void)
-{
-	nand_dbg_print(NAND_DBG_TRACE, "%s, Line %d, Function: %s\n",
-		       __FILE__, __LINE__, __func__);
-
-	return PASS;
-}
-
-/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
-* Function:     emu_Erase_Block
-* Inputs:       Address
-* Outputs:      PASS=0 (notice 0=ok here)
-* Description:          Erase a block
-*
-*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
-u16 emu_Erase_Block(u32 block_add)
-{
-	int i;
-
-	nand_dbg_print(NAND_DBG_TRACE, "%s, Line %d, Function: %s\n",
-		       __FILE__, __LINE__, __func__);
-
-	if (block_add >= DeviceInfo.wTotalBlocks) {
-		printk(KERN_ERR "emu_Erase_Block error! "
-		       "Too big block address: %d\n", block_add);
-		return FAIL;
-	}
-
-	nand_dbg_print(NAND_DBG_DEBUG, "Erasing block %d\n",
-		(int)block_add);
-
-	for (i = block_add * GLOB_LLD_PAGES;
-	     i < ((block_add + 1) * GLOB_LLD_PAGES); i++) {
-		if (flash_memory[i]) {
-			memset((u8 *)(flash_memory[i]), 0xFF,
-			       DeviceInfo.wPageSize * sizeof(u8));
-		}
-	}
-
-	return PASS;
-}
-
-/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
-* Function:     emu_Write_Page_Main
-* Inputs:       Write buffer address pointer
-*               Block number
-*               Page  number
-*               Number of pages to process
-* Outputs:      PASS=0 (notice 0=ok here)
-* Description:  Write the data in the buffer to main area of flash
-*
-*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
-u16 emu_Write_Page_Main(u8 *write_data, u32 Block,
-			   u16 Page, u16 PageCount)
-{
-	int i;
-
-	nand_dbg_print(NAND_DBG_TRACE, "%s, Line %d, Function: %s\n",
-		       __FILE__, __LINE__, __func__);
-
-	if (Block >= DeviceInfo.wTotalBlocks)
-		return FAIL;
-
-	if (Page + PageCount > DeviceInfo.wPagesPerBlock)
-		return FAIL;
-
-	nand_dbg_print(NAND_DBG_DEBUG, "emu_Write_Page_Main: "
-		       "lba %u Page %u PageCount %u\n",
-		       (unsigned int)Block,
-		       (unsigned int)Page, (unsigned int)PageCount);
-
-	for (i = 0; i < PageCount; i++) {
-		if (NULL == flash_memory[Block * GLOB_LLD_PAGES + Page]) {
-			printk(KERN_ERR "Run out of memory\n");
-			return FAIL;
-		}
-		memcpy((u8 *) (flash_memory[Block * GLOB_LLD_PAGES + Page]),
-		       write_data, DeviceInfo.wPageDataSize);
-		write_data += DeviceInfo.wPageDataSize;
-		Page++;
-	}
-
-	return PASS;
-}
-
-/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
-* Function:     emu_Read_Page_Main
-* Inputs:       Read buffer address pointer
-*               Block number
-*               Page  number
-*               Number of pages to process
-* Outputs:      PASS=0 (notice 0=ok here)
-* Description:  Read the data from the flash main area to the buffer
-*
-*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
-u16 emu_Read_Page_Main(u8 *read_data, u32 Block,
-			  u16 Page, u16 PageCount)
-{
-	int i;
-
-	nand_dbg_print(NAND_DBG_TRACE, "%s, Line %d, Function: %s\n",
-		       __FILE__, __LINE__, __func__);
-
-	if (Block >= DeviceInfo.wTotalBlocks)
-		return FAIL;
-
-	if (Page + PageCount > DeviceInfo.wPagesPerBlock)
-		return FAIL;
-
-	nand_dbg_print(NAND_DBG_DEBUG, "emu_Read_Page_Main: "
-		       "lba %u Page %u PageCount %u\n",
-		       (unsigned int)Block,
-		       (unsigned int)Page, (unsigned int)PageCount);
-
-	for (i = 0; i < PageCount; i++) {
-		if (NULL == flash_memory[Block * GLOB_LLD_PAGES + Page]) {
-			memset(read_data, 0xFF, DeviceInfo.wPageDataSize);
-		} else {
-			memcpy(read_data,
-			       (u8 *) (flash_memory[Block * GLOB_LLD_PAGES
-						      + Page]),
-			       DeviceInfo.wPageDataSize);
-		}
-		read_data += DeviceInfo.wPageDataSize;
-		Page++;
-	}
-
-	return PASS;
-}
-
-#ifndef ELDORA
-/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
-* Function:     emu_Read_Page_Main_Spare
-* Inputs:       Write Buffer
-*                       Address
-*                       Buffer size
-* Outputs:      PASS=0 (notice 0=ok here)
-* Description:          Read from flash main+spare area
-*
-*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
-u16 emu_Read_Page_Main_Spare(u8 *read_data, u32 Block,
-				u16 Page, u16 PageCount)
-{
-	int i;
-
-	nand_dbg_print(NAND_DBG_TRACE, "%s, Line %d, Function: %s\n",
-		       __FILE__, __LINE__, __func__);
-
-	if (Block >= DeviceInfo.wTotalBlocks) {
-		printk(KERN_ERR "Read Page Main+Spare "
-		       "Error: Block Address too big\n");
-		return FAIL;
-	}
-
-	if (Page + PageCount > DeviceInfo.wPagesPerBlock) {
-		printk(KERN_ERR "Read Page Main+Spare "
-		       "Error: Page number too big\n");
-		return FAIL;
-	}
-
-	nand_dbg_print(NAND_DBG_DEBUG, "Read Page Main + Spare - "
-		       "No. of pages %u block %u start page %u\n",
-		       (unsigned int)PageCount,
-		       (unsigned int)Block, (unsigned int)Page);
-
-	for (i = 0; i < PageCount; i++) {
-		if (NULL == flash_memory[Block * GLOB_LLD_PAGES + Page]) {
-			memset(read_data, 0xFF, DeviceInfo.wPageSize);
-		} else {
-			memcpy(read_data, (u8 *) (flash_memory[Block *
-								 GLOB_LLD_PAGES
-								 + Page]),
-			       DeviceInfo.wPageSize);
-		}
-
-		read_data += DeviceInfo.wPageSize;
-		Page++;
-	}
-
-	return PASS;
-}
-
-/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
-* Function:     emu_Write_Page_Main_Spare
-* Inputs:       Write buffer
-*                       address
-*                       buffer length
-* Outputs:      PASS=0 (notice 0=ok here)
-* Description:          Write the buffer to main+spare area of flash
-*
-*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
-u16 emu_Write_Page_Main_Spare(u8 *write_data, u32 Block,
-				 u16 Page, u16 page_count)
-{
-	u16 i;
-
-	nand_dbg_print(NAND_DBG_TRACE, "%s, Line %d, Function: %s\n",
-		       __FILE__, __LINE__, __func__);
-
-	if (Block >= DeviceInfo.wTotalBlocks) {
-		printk(KERN_ERR "Write Page Main + Spare "
-		       "Error: Block Address too big\n");
-		return FAIL;
-	}
-
-	if (Page + page_count > DeviceInfo.wPagesPerBlock) {
-		printk(KERN_ERR "Write Page Main + Spare "
-		       "Error: Page number too big\n");
-		return FAIL;
-	}
-
-	nand_dbg_print(NAND_DBG_DEBUG, "Write Page Main+Spare - "
-		       "No. of pages %u block %u start page %u\n",
-		       (unsigned int)page_count,
-		       (unsigned int)Block, (unsigned int)Page);
-
-	for (i = 0; i < page_count; i++) {
-		if (NULL == flash_memory[Block * GLOB_LLD_PAGES + Page]) {
-			printk(KERN_ERR "Run out of memory!\n");
-			return FAIL;
-		}
-		memcpy((u8 *) (flash_memory[Block * GLOB_LLD_PAGES + Page]),
-		       write_data, DeviceInfo.wPageSize);
-		write_data += DeviceInfo.wPageSize;
-		Page++;
-	}
-
-	return PASS;
-}
-
-/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
-* Function:     emu_Write_Page_Spare
-* Inputs:       Write buffer
-*                       Address
-*                       buffer size
-* Outputs:      PASS=0 (notice 0=ok here)
-* Description:          Write the buffer in the spare area
-*
-*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
-u16 emu_Write_Page_Spare(u8 *write_data, u32 Block,
-			    u16 Page, u16 PageCount)
-{
-	nand_dbg_print(NAND_DBG_TRACE, "%s, Line %d, Function: %s\n",
-		       __FILE__, __LINE__, __func__);
-
-	if (Block >= DeviceInfo.wTotalBlocks) {
-		printk(KERN_ERR "Read Page Spare Error: "
-		       "Block Address too big\n");
-		return FAIL;
-	}
-
-	if (Page + PageCount > DeviceInfo.wPagesPerBlock) {
-		printk(KERN_ERR "Read Page Spare Error: "
-		       "Page number too big\n");
-		return FAIL;
-	}
-
-	nand_dbg_print(NAND_DBG_DEBUG, "Write Page Spare- "
-		       "block %u page %u\n",
-		       (unsigned int)Block, (unsigned int)Page);
-
-	if (NULL == flash_memory[Block * GLOB_LLD_PAGES + Page]) {
-		printk(KERN_ERR "Run out of memory!\n");
-		return FAIL;
-	}
-
-	memcpy((u8 *) (flash_memory[Block * GLOB_LLD_PAGES + Page] +
-			 DeviceInfo.wPageDataSize), write_data,
-	       (DeviceInfo.wPageSize - DeviceInfo.wPageDataSize));
-
-	return PASS;
-}
-
-/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
-* Function:     emu_Read_Page_Spare
-* Inputs:       Write Buffer
-*                       Address
-*                       Buffer size
-* Outputs:      PASS=0 (notice 0=ok here)
-* Description:          Read data from the spare area
-*
-*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
-u16 emu_Read_Page_Spare(u8 *write_data, u32 Block,
-			   u16 Page, u16 PageCount)
-{
-	nand_dbg_print(NAND_DBG_TRACE, "%s, Line %d, Function: %s\n",
-		       __FILE__, __LINE__, __func__);
-
-	if (Block >= DeviceInfo.wTotalBlocks) {
-		printk(KERN_ERR "Read Page Spare "
-		       "Error: Block Address too big\n");
-		return FAIL;
-	}
-
-	if (Page + PageCount > DeviceInfo.wPagesPerBlock) {
-		printk(KERN_ERR "Read Page Spare "
-		       "Error: Page number too big\n");
-		return FAIL;
-	}
-
-	nand_dbg_print(NAND_DBG_DEBUG, "Read Page Spare- "
-		       "block %u page %u\n",
-		       (unsigned int)Block, (unsigned int)Page);
-
-	if (NULL == flash_memory[Block * GLOB_LLD_PAGES + Page]) {
-		memset(write_data, 0xFF,
-		       (DeviceInfo.wPageSize - DeviceInfo.wPageDataSize));
-	} else {
-		memcpy(write_data,
-		       (u8 *) (flash_memory[Block * GLOB_LLD_PAGES + Page]
-				 + DeviceInfo.wPageDataSize),
-		       (DeviceInfo.wPageSize - DeviceInfo.wPageDataSize));
-	}
-
-	return PASS;
-}
-
-/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
-* Function:     emu_Enable_Disable_Interrupts
-* Inputs:       enable or disable
-* Outputs:      none
-* Description:  NOP
-*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
-void emu_Enable_Disable_Interrupts(u16 INT_ENABLE)
-{
-	nand_dbg_print(NAND_DBG_TRACE, "%s, Line %d, Function: %s\n",
-		       __FILE__, __LINE__, __func__);
-}
-
-u16 emu_Get_Bad_Block(u32 block)
-{
-	return 0;
-}
-
-#if CMD_DMA
-/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
-* Support for CDMA functions
-************************************
-*       emu_CDMA_Flash_Init
-*           CDMA_process_data command   (use LLD_CDMA)
-*           CDMA_MemCopy_CMD            (use LLD_CDMA)
-*       emu_CDMA_execute all commands
-*       emu_CDMA_Event_Status
-*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
-u16 emu_CDMA_Flash_Init(void)
-{
-	u16 i;
-
-	nand_dbg_print(NAND_DBG_TRACE, "%s, Line %d, Function: %s\n",
-		       __FILE__, __LINE__, __func__);
-
-	for (i = 0; i < MAX_DESCS + MAX_CHANS; i++) {
-		PendingCMD[i].CMD = 0;
-		PendingCMD[i].Tag = 0;
-		PendingCMD[i].DataAddr = 0;
-		PendingCMD[i].Block = 0;
-		PendingCMD[i].Page = 0;
-		PendingCMD[i].PageCount = 0;
-		PendingCMD[i].DataDestAddr = 0;
-		PendingCMD[i].DataSrcAddr = 0;
-		PendingCMD[i].MemCopyByteCnt = 0;
-		PendingCMD[i].ChanSync[0] = 0;
-		PendingCMD[i].ChanSync[1] = 0;
-		PendingCMD[i].ChanSync[2] = 0;
-		PendingCMD[i].ChanSync[3] = 0;
-		PendingCMD[i].ChanSync[4] = 0;
-		PendingCMD[i].Status = 3;
-	}
-
-	return PASS;
-}
-
-static void emu_isr(int irq, void *dev_id)
-{
-	/* TODO:  ... */
-}
-
-/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
-* Function:     CDMA_Execute_CMDs
-* Inputs:       tag_count:  the number of pending cmds to do
-* Outputs:      PASS/FAIL
-* Description:  execute each command in the pending CMD array
-*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
-u16 emu_CDMA_Execute_CMDs(u16 tag_count)
-{
-	u16 i, j;
-	u8 CMD;		/* cmd parameter */
-	u8 *data;
-	u32 block;
-	u16 page;
-	u16 count;
-	u16 status = PASS;
-
-	nand_dbg_print(NAND_DBG_TRACE, "%s, Line %d, Function: %s\n",
-		       __FILE__, __LINE__, __func__);
-
-	nand_dbg_print(NAND_DBG_TRACE, "At start of Execute CMDs: "
-		       "Tag Count %u\n", tag_count);
-
-	for (i = 0; i < totalUsedBanks; i++) {
-		PendingCMD[i].CMD = DUMMY_CMD;
-		PendingCMD[i].Tag = 0xFF;
-		PendingCMD[i].Block =
-		    (DeviceInfo.wTotalBlocks / totalUsedBanks) * i;
-
-		for (j = 0; j <= MAX_CHANS; j++)
-			PendingCMD[i].ChanSync[j] = 0;
-	}
-
-	CDMA_Execute_CMDs(tag_count);
-
-	print_pending_cmds(tag_count);
-
-#if DEBUG_SYNC
-	}
-	debug_sync_cnt++;
-#endif
-
-	for (i = MAX_CHANS;
-	     i < tag_count + MAX_CHANS; i++) {
-		CMD = PendingCMD[i].CMD;
-		data = PendingCMD[i].DataAddr;
-		block = PendingCMD[i].Block;
-		page = PendingCMD[i].Page;
-		count = PendingCMD[i].PageCount;
-
-		switch (CMD) {
-		case ERASE_CMD:
-			emu_Erase_Block(block);
-			PendingCMD[i].Status = PASS;
-			break;
-		case WRITE_MAIN_CMD:
-			emu_Write_Page_Main(data, block, page, count);
-			PendingCMD[i].Status = PASS;
-			break;
-		case WRITE_MAIN_SPARE_CMD:
-			emu_Write_Page_Main_Spare(data, block, page, count);
-			PendingCMD[i].Status = PASS;
-			break;
-		case READ_MAIN_CMD:
-			emu_Read_Page_Main(data, block, page, count);
-			PendingCMD[i].Status = PASS;
-			break;
-		case MEMCOPY_CMD:
-			memcpy(PendingCMD[i].DataDestAddr,
-			       PendingCMD[i].DataSrcAddr,
-			       PendingCMD[i].MemCopyByteCnt);
-		case DUMMY_CMD:
-			PendingCMD[i].Status = PASS;
-			break;
-		default:
-			PendingCMD[i].Status = FAIL;
-			break;
-		}
-	}
-
-	/*
-	 * Temperory adding code to reset PendingCMD array for basic testing.
-	 * It should be done at the end of  event status function.
-	 */
-	for (i = tag_count + MAX_CHANS; i < MAX_DESCS; i++) {
-		PendingCMD[i].CMD = 0;
-		PendingCMD[i].Tag = 0;
-		PendingCMD[i].DataAddr = 0;
-		PendingCMD[i].Block = 0;
-		PendingCMD[i].Page = 0;
-		PendingCMD[i].PageCount = 0;
-		PendingCMD[i].DataDestAddr = 0;
-		PendingCMD[i].DataSrcAddr = 0;
-		PendingCMD[i].MemCopyByteCnt = 0;
-		PendingCMD[i].ChanSync[0] = 0;
-		PendingCMD[i].ChanSync[1] = 0;
-		PendingCMD[i].ChanSync[2] = 0;
-		PendingCMD[i].ChanSync[3] = 0;
-		PendingCMD[i].ChanSync[4] = 0;
-		PendingCMD[i].Status = CMD_NOT_DONE;
-	}
-
-	nand_dbg_print(NAND_DBG_TRACE, "At end of Execute CMDs.\n");
-
-	emu_isr(0, 0); /* This is a null isr now. Need fill it in future */
-
-	return status;
-}
-
-/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
-* Function:     emu_Event_Status
-* Inputs:       none
-* Outputs:      Event_Status code
-* Description:  This function can also be used to force errors
-*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
-u16 emu_CDMA_Event_Status(void)
-{
-	nand_dbg_print(NAND_DBG_TRACE, "%s, Line %d, Function: %s\n",
-		       __FILE__, __LINE__, __func__);
-
-	return EVENT_PASS;
-}
-
-#endif /* CMD_DMA */
-#endif /* !ELDORA */
-#endif /* FLASH_EMU */
diff --git a/drivers/staging/spectra/lld_emu.h b/drivers/staging/spectra/lld_emu.h
deleted file mode 100644
index 63f84c3..0000000
--- a/drivers/staging/spectra/lld_emu.h
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * NAND Flash Controller Device Driver
- * Copyright (c) 2009, Intel Corporation and its suppliers.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms and conditions of the GNU General Public License,
- * version 2, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
- *
- */
-
-#ifndef _LLD_EMU_
-#define _LLD_EMU_
-
-#include "ffsport.h"
-#include "ffsdefs.h"
-
-/* prototypes: emulator API functions */
-extern u16 emu_Flash_Reset(void);
-extern u16 emu_Flash_Init(void);
-extern int emu_Flash_Release(void);
-extern u16 emu_Read_Device_ID(void);
-extern u16 emu_Erase_Block(u32 block_addr);
-extern u16 emu_Write_Page_Main(u8 *write_data, u32 Block,
-				u16 Page, u16 PageCount);
-extern u16 emu_Read_Page_Main(u8 *read_data, u32 Block, u16 Page,
-				 u16 PageCount);
-extern u16 emu_Event_Status(void);
-extern void emu_Enable_Disable_Interrupts(u16 INT_ENABLE);
-extern u16 emu_Write_Page_Main_Spare(u8 *write_data, u32 Block,
-					u16 Page, u16 PageCount);
-extern u16 emu_Write_Page_Spare(u8 *write_data, u32 Block,
-					u16 Page, u16 PageCount);
-extern u16 emu_Read_Page_Main_Spare(u8 *read_data, u32 Block,
-				       u16 Page, u16 PageCount);
-extern u16 emu_Read_Page_Spare(u8 *read_data, u32 Block, u16 Page,
-				  u16 PageCount);
-extern u16 emu_Get_Bad_Block(u32 block);
-
-u16 emu_CDMA_Flash_Init(void);
-u16 emu_CDMA_Execute_CMDs(u16 tag_count);
-u16 emu_CDMA_Event_Status(void);
-#endif /*_LLD_EMU_*/
diff --git a/drivers/staging/spectra/lld_mtd.c b/drivers/staging/spectra/lld_mtd.c
deleted file mode 100644
index a9c309a..0000000
--- a/drivers/staging/spectra/lld_mtd.c
+++ /dev/null
@@ -1,683 +0,0 @@
-/*
- * NAND Flash Controller Device Driver
- * Copyright (c) 2009, Intel Corporation and its suppliers.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms and conditions of the GNU General Public License,
- * version 2, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
- *
- */
-
-#include <linux/fs.h>
-#include <linux/slab.h>
-#include <linux/mtd/mtd.h>
-#include "flash.h"
-#include "ffsdefs.h"
-#include "lld_emu.h"
-#include "lld.h"
-#if CMD_DMA
-#include "lld_cdma.h"
-u32 totalUsedBanks;
-u32 valid_banks[MAX_CHANS];
-#endif
-
-#define GLOB_LLD_PAGES           64
-#define GLOB_LLD_PAGE_SIZE       (512+16)
-#define GLOB_LLD_PAGE_DATA_SIZE  512
-#define GLOB_LLD_BLOCKS          2048
-
-static struct mtd_info *spectra_mtd;
-static int mtddev = -1;
-module_param(mtddev, int, 0);
-
-/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
-* Function:     mtd_Flash_Init
-* Inputs:       none
-* Outputs:      PASS=0 (notice 0=ok here)
-* Description:  Creates & initializes the flash RAM array.
-*
-*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
-u16 mtd_Flash_Init(void)
-{
-	if (mtddev == -1) {
-		printk(KERN_ERR "No MTD device specified. Give mtddev parameter\n");
-		return FAIL;
-	}
-
-	spectra_mtd = get_mtd_device(NULL, mtddev);
-	if (!spectra_mtd) {
-		printk(KERN_ERR "Failed to obtain MTD device #%d\n", mtddev);
-		return FAIL;
-	}
-
-	nand_dbg_print(NAND_DBG_TRACE, "%s, Line %d, Function: %s\n",
-		       __FILE__, __LINE__, __func__);
-
-	return PASS;
-}
-
-/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
-* Function:     mtd_Flash_Release
-* Inputs:       none
-* Outputs:      PASS=0 (notice 0=ok here)
-* Description:          Releases the flash.
-*
-*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
-int mtd_Flash_Release(void)
-{
-	nand_dbg_print(NAND_DBG_TRACE, "%s, Line %d, Function: %s\n",
-		       __FILE__, __LINE__, __func__);
-	if (!spectra_mtd)
-		return PASS;
-
-	put_mtd_device(spectra_mtd);
-	spectra_mtd = NULL;
-
-	return PASS;
-}
-
-/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
-* Function:     mtd_Read_Device_ID
-* Inputs:       none
-* Outputs:      PASS=1 FAIL=0
-* Description:  Reads the info from the controller registers.
-*               Sets up DeviceInfo structure with device parameters
-*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
-
-u16 mtd_Read_Device_ID(void)
-{
-	uint64_t tmp;
-	nand_dbg_print(NAND_DBG_TRACE, "%s, Line %d, Function: %s\n",
-		       __FILE__, __LINE__, __func__);
-
-	if (!spectra_mtd)
-		return FAIL;
-
-	DeviceInfo.wDeviceMaker = 0;
-	DeviceInfo.wDeviceType = 8;
-	DeviceInfo.wSpectraStartBlock = SPECTRA_START_BLOCK;
-	tmp = spectra_mtd->size;
-	do_div(tmp, spectra_mtd->erasesize);
-	DeviceInfo.wTotalBlocks = tmp;
-	DeviceInfo.wSpectraEndBlock = DeviceInfo.wTotalBlocks - 1;
-	DeviceInfo.wPagesPerBlock = spectra_mtd->erasesize / spectra_mtd->writesize;
-	DeviceInfo.wPageSize = spectra_mtd->writesize + spectra_mtd->oobsize;
-	DeviceInfo.wPageDataSize = spectra_mtd->writesize;
-	DeviceInfo.wPageSpareSize = spectra_mtd->oobsize;
-	DeviceInfo.wBlockSize = DeviceInfo.wPageSize * DeviceInfo.wPagesPerBlock;
-	DeviceInfo.wBlockDataSize = DeviceInfo.wPageDataSize * DeviceInfo.wPagesPerBlock;
-	DeviceInfo.wDataBlockNum = (u32) (DeviceInfo.wSpectraEndBlock -
-						DeviceInfo.wSpectraStartBlock
-						+ 1);
-	DeviceInfo.MLCDevice = 0;//spectra_mtd->celltype & NAND_CI_CELLTYPE_MSK;
-	DeviceInfo.nBitsInPageNumber =
-		(u8)GLOB_Calc_Used_Bits(DeviceInfo.wPagesPerBlock);
-	DeviceInfo.nBitsInPageDataSize =
-		(u8)GLOB_Calc_Used_Bits(DeviceInfo.wPageDataSize);
-	DeviceInfo.nBitsInBlockDataSize =
-		(u8)GLOB_Calc_Used_Bits(DeviceInfo.wBlockDataSize);
-
-#if CMD_DMA
-	totalUsedBanks = 4;
-	valid_banks[0] = 1;
-	valid_banks[1] = 1;
-	valid_banks[2] = 1;
-	valid_banks[3] = 1;
-#endif
-
-	return PASS;
-}
-
-/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
-* Function:     mtd_Flash_Reset
-* Inputs:       none
-* Outputs:      PASS=0 (notice 0=ok here)
-* Description:          Reset the flash
-*
-*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
-u16 mtd_Flash_Reset(void)
-{
-	nand_dbg_print(NAND_DBG_TRACE, "%s, Line %d, Function: %s\n",
-		       __FILE__, __LINE__, __func__);
-
-	return PASS;
-}
-
-void erase_callback(struct erase_info *e)
-{
-	complete((void *)e->priv);
-}
-
-/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
-* Function:     mtd_Erase_Block
-* Inputs:       Address
-* Outputs:      PASS=0 (notice 0=ok here)
-* Description:          Erase a block
-*
-*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
-u16 mtd_Erase_Block(u32 block_add)
-{
-	struct erase_info erase;
-	DECLARE_COMPLETION_ONSTACK(comp);
-	int ret;
-
-	nand_dbg_print(NAND_DBG_TRACE, "%s, Line %d, Function: %s\n",
-		       __FILE__, __LINE__, __func__);
-
-	if (block_add >= DeviceInfo.wTotalBlocks) {
-		printk(KERN_ERR "mtd_Erase_Block error! "
-		       "Too big block address: %d\n", block_add);
-		return FAIL;
-	}
-
-	nand_dbg_print(NAND_DBG_DEBUG, "Erasing block %d\n",
-		(int)block_add);
-
-	erase.mtd = spectra_mtd;
-	erase.callback = erase_callback;
-	erase.addr = block_add * spectra_mtd->erasesize;
-	erase.len = spectra_mtd->erasesize;
-	erase.priv = (unsigned long)&comp;
-
-	ret = spectra_mtd->erase(spectra_mtd, &erase);
-	if (!ret) {
-		wait_for_completion(&comp);
-		if (erase.state != MTD_ERASE_DONE)
-			ret = -EIO;
-	}
-	if (ret) {
-		printk(KERN_WARNING "mtd_Erase_Block error! "
-		       "erase of region [0x%llx, 0x%llx] failed\n",
-		       erase.addr, erase.len);
-		return FAIL;
-	}
-
-	return PASS;
-}
-
-/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
-* Function:     mtd_Write_Page_Main
-* Inputs:       Write buffer address pointer
-*               Block number
-*               Page  number
-*               Number of pages to process
-* Outputs:      PASS=0 (notice 0=ok here)
-* Description:  Write the data in the buffer to main area of flash
-*
-*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
-u16 mtd_Write_Page_Main(u8 *write_data, u32 Block,
-			   u16 Page, u16 PageCount)
-{
-	size_t retlen;
-	int ret = 0;
-
-	if (Block >= DeviceInfo.wTotalBlocks)
-		return FAIL;
-
-	if (Page + PageCount > DeviceInfo.wPagesPerBlock)
-		return FAIL;
-
-	nand_dbg_print(NAND_DBG_DEBUG, "mtd_Write_Page_Main: "
-		       "lba %u Page %u PageCount %u\n",
-		       (unsigned int)Block,
-		       (unsigned int)Page, (unsigned int)PageCount);
-
-
-	while (PageCount) {
-		ret = spectra_mtd->write(spectra_mtd,
-					 (Block * spectra_mtd->erasesize) + (Page * spectra_mtd->writesize),
-					 DeviceInfo.wPageDataSize, &retlen, write_data);
-		if (ret) {
-			printk(KERN_ERR "%s failed %d\n", __func__, ret);
-			return FAIL;
-		}
-		write_data += DeviceInfo.wPageDataSize;
-		Page++;
-		PageCount--;
-	}
-
-	nand_dbg_print(NAND_DBG_TRACE, "%s, Line %d, Function: %s\n",
-		       __FILE__, __LINE__, __func__);
-
-	return PASS;
-}
-
-/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
-* Function:     mtd_Read_Page_Main
-* Inputs:       Read buffer address pointer
-*               Block number
-*               Page  number
-*               Number of pages to process
-* Outputs:      PASS=0 (notice 0=ok here)
-* Description:  Read the data from the flash main area to the buffer
-*
-*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
-u16 mtd_Read_Page_Main(u8 *read_data, u32 Block,
-			  u16 Page, u16 PageCount)
-{
-	size_t retlen;
-	int ret = 0;
-
-	nand_dbg_print(NAND_DBG_TRACE, "%s, Line %d, Function: %s\n",
-		       __FILE__, __LINE__, __func__);
-
-	if (Block >= DeviceInfo.wTotalBlocks)
-		return FAIL;
-
-	if (Page + PageCount > DeviceInfo.wPagesPerBlock)
-		return FAIL;
-
-	nand_dbg_print(NAND_DBG_DEBUG, "mtd_Read_Page_Main: "
-		       "lba %u Page %u PageCount %u\n",
-		       (unsigned int)Block,
-		       (unsigned int)Page, (unsigned int)PageCount);
-
-
-	while (PageCount) {
-		ret = spectra_mtd->read(spectra_mtd,
-					(Block * spectra_mtd->erasesize) + (Page * spectra_mtd->writesize),
-					DeviceInfo.wPageDataSize, &retlen, read_data);
-		if (ret) {
-			printk(KERN_ERR "%s failed %d\n", __func__, ret);
-			return FAIL;
-		}
-		read_data += DeviceInfo.wPageDataSize;
-		Page++;
-		PageCount--;
-	}
-
-	nand_dbg_print(NAND_DBG_TRACE, "%s, Line %d, Function: %s\n",
-		       __FILE__, __LINE__, __func__);
-
-	return PASS;
-}
-
-#ifndef ELDORA
-/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
-* Function:     mtd_Read_Page_Main_Spare
-* Inputs:       Write Buffer
-*                       Address
-*                       Buffer size
-* Outputs:      PASS=0 (notice 0=ok here)
-* Description:          Read from flash main+spare area
-*
-*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
-u16 mtd_Read_Page_Main_Spare(u8 *read_data, u32 Block,
-				u16 Page, u16 PageCount)
-{
-	nand_dbg_print(NAND_DBG_TRACE, "%s, Line %d, Function: %s\n",
-		       __FILE__, __LINE__, __func__);
-
-	if (Block >= DeviceInfo.wTotalBlocks) {
-		printk(KERN_ERR "Read Page Main+Spare "
-		       "Error: Block Address too big\n");
-		return FAIL;
-	}
-
-	if (Page + PageCount > DeviceInfo.wPagesPerBlock) {
-		printk(KERN_ERR "Read Page Main+Spare "
-		       "Error: Page number %d+%d too big in block %d\n",
-		       Page, PageCount, Block);
-		return FAIL;
-	}
-
-	nand_dbg_print(NAND_DBG_DEBUG, "Read Page Main + Spare - "
-		       "No. of pages %u block %u start page %u\n",
-		       (unsigned int)PageCount,
-		       (unsigned int)Block, (unsigned int)Page);
-
-
-	while (PageCount) {
-		struct mtd_oob_ops ops;
-		int ret;
-
-		ops.mode = MTD_OPS_AUTO_OOB;
-		ops.datbuf = read_data;
-		ops.len = DeviceInfo.wPageDataSize;
-		ops.oobbuf = read_data + DeviceInfo.wPageDataSize + BTSIG_OFFSET;
-		ops.ooblen = BTSIG_BYTES;
-		ops.ooboffs = 0;
-
-		ret = spectra_mtd->read_oob(spectra_mtd,
-					    (Block * spectra_mtd->erasesize) + (Page * spectra_mtd->writesize),
-					    &ops);
-		if (ret) {
-			printk(KERN_ERR "%s failed %d\n", __func__, ret);
-			return FAIL;
-		}
-		read_data += DeviceInfo.wPageSize;
-		Page++;
-		PageCount--;
-	}
-
-	return PASS;
-}
-
-/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
-* Function:     mtd_Write_Page_Main_Spare
-* Inputs:       Write buffer
-*                       address
-*                       buffer length
-* Outputs:      PASS=0 (notice 0=ok here)
-* Description:          Write the buffer to main+spare area of flash
-*
-*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
-u16 mtd_Write_Page_Main_Spare(u8 *write_data, u32 Block,
-				 u16 Page, u16 page_count)
-{
-	nand_dbg_print(NAND_DBG_TRACE, "%s, Line %d, Function: %s\n",
-		       __FILE__, __LINE__, __func__);
-
-	if (Block >= DeviceInfo.wTotalBlocks) {
-		printk(KERN_ERR "Write Page Main + Spare "
-		       "Error: Block Address too big\n");
-		return FAIL;
-	}
-
-	if (Page + page_count > DeviceInfo.wPagesPerBlock) {
-		printk(KERN_ERR "Write Page Main + Spare "
-		       "Error: Page number %d+%d too big in block %d\n",
-		       Page, page_count, Block);
-		WARN_ON(1);
-		return FAIL;
-	}
-
-	nand_dbg_print(NAND_DBG_DEBUG, "Write Page Main+Spare - "
-		       "No. of pages %u block %u start page %u\n",
-		       (unsigned int)page_count,
-		       (unsigned int)Block, (unsigned int)Page);
-
-	while (page_count) {
-		struct mtd_oob_ops ops;
-		int ret;
-
-		ops.mode = MTD_OPS_AUTO_OOB;
-		ops.datbuf = write_data;
-		ops.len = DeviceInfo.wPageDataSize;
-		ops.oobbuf = write_data + DeviceInfo.wPageDataSize + BTSIG_OFFSET;
-		ops.ooblen = BTSIG_BYTES;
-		ops.ooboffs = 0;
-
-		ret = spectra_mtd->write_oob(spectra_mtd,
-					     (Block * spectra_mtd->erasesize) + (Page * spectra_mtd->writesize),
-					     &ops);
-		if (ret) {
-			printk(KERN_ERR "%s failed %d\n", __func__, ret);
-			return FAIL;
-		}
-		write_data += DeviceInfo.wPageSize;
-		Page++;
-		page_count--;
-	}
-
-	return PASS;
-}
-
-/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
-* Function:     mtd_Write_Page_Spare
-* Inputs:       Write buffer
-*                       Address
-*                       buffer size
-* Outputs:      PASS=0 (notice 0=ok here)
-* Description:          Write the buffer in the spare area
-*
-*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
-u16 mtd_Write_Page_Spare(u8 *write_data, u32 Block,
-			    u16 Page, u16 PageCount)
-{
-	WARN_ON(1);
-	return FAIL;
-}
-
-/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
-* Function:     mtd_Read_Page_Spare
-* Inputs:       Write Buffer
-*                       Address
-*                       Buffer size
-* Outputs:      PASS=0 (notice 0=ok here)
-* Description:          Read data from the spare area
-*
-*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
-u16 mtd_Read_Page_Spare(u8 *read_data, u32 Block,
-			   u16 Page, u16 PageCount)
-{
-	nand_dbg_print(NAND_DBG_TRACE, "%s, Line %d, Function: %s\n",
-		       __FILE__, __LINE__, __func__);
-
-	if (Block >= DeviceInfo.wTotalBlocks) {
-		printk(KERN_ERR "Read Page Spare "
-		       "Error: Block Address too big\n");
-		return FAIL;
-	}
-
-	if (Page + PageCount > DeviceInfo.wPagesPerBlock) {
-		printk(KERN_ERR "Read Page Spare "
-		       "Error: Page number too big\n");
-		return FAIL;
-	}
-
-	nand_dbg_print(NAND_DBG_DEBUG, "Read Page Spare- "
-		       "block %u page %u (%u pages)\n",
-		       (unsigned int)Block, (unsigned int)Page, PageCount);
-
-	while (PageCount) {
-		struct mtd_oob_ops ops;
-		int ret;
-
-		ops.mode = MTD_OPS_AUTO_OOB;
-		ops.datbuf = NULL;
-		ops.len = 0;
-		ops.oobbuf = read_data;
-		ops.ooblen = BTSIG_BYTES;
-		ops.ooboffs = 0;
-
-		ret = spectra_mtd->read_oob(spectra_mtd,
-					    (Block * spectra_mtd->erasesize) + (Page * spectra_mtd->writesize),
-					    &ops);
-		if (ret) {
-			printk(KERN_ERR "%s failed %d\n", __func__, ret);
-			return FAIL;
-		}
-
-		read_data += DeviceInfo.wPageSize;
-		Page++;
-		PageCount--;
-	}
-
-	return PASS;
-}
-
-/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
-* Function:     mtd_Enable_Disable_Interrupts
-* Inputs:       enable or disable
-* Outputs:      none
-* Description:  NOP
-*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
-void mtd_Enable_Disable_Interrupts(u16 INT_ENABLE)
-{
-	nand_dbg_print(NAND_DBG_TRACE, "%s, Line %d, Function: %s\n",
-		       __FILE__, __LINE__, __func__);
-}
-
-u16 mtd_Get_Bad_Block(u32 block)
-{
-	return 0;
-}
-
-#if CMD_DMA
-/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
-* Support for CDMA functions
-************************************
-*       mtd_CDMA_Flash_Init
-*           CDMA_process_data command   (use LLD_CDMA)
-*           CDMA_MemCopy_CMD            (use LLD_CDMA)
-*       mtd_CDMA_execute all commands
-*       mtd_CDMA_Event_Status
-*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
-u16 mtd_CDMA_Flash_Init(void)
-{
-	u16 i;
-
-	nand_dbg_print(NAND_DBG_TRACE, "%s, Line %d, Function: %s\n",
-		       __FILE__, __LINE__, __func__);
-
-	for (i = 0; i < MAX_DESCS + MAX_CHANS; i++) {
-		PendingCMD[i].CMD = 0;
-		PendingCMD[i].Tag = 0;
-		PendingCMD[i].DataAddr = 0;
-		PendingCMD[i].Block = 0;
-		PendingCMD[i].Page = 0;
-		PendingCMD[i].PageCount = 0;
-		PendingCMD[i].DataDestAddr = 0;
-		PendingCMD[i].DataSrcAddr = 0;
-		PendingCMD[i].MemCopyByteCnt = 0;
-		PendingCMD[i].ChanSync[0] = 0;
-		PendingCMD[i].ChanSync[1] = 0;
-		PendingCMD[i].ChanSync[2] = 0;
-		PendingCMD[i].ChanSync[3] = 0;
-		PendingCMD[i].ChanSync[4] = 0;
-		PendingCMD[i].Status = 3;
-	}
-
-	return PASS;
-}
-
-static void mtd_isr(int irq, void *dev_id)
-{
-	/* TODO:  ... */
-}
-
-/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
-* Function:     CDMA_Execute_CMDs
-* Inputs:       tag_count:  the number of pending cmds to do
-* Outputs:      PASS/FAIL
-* Description:  execute each command in the pending CMD array
-*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
-u16 mtd_CDMA_Execute_CMDs(u16 tag_count)
-{
-	u16 i, j;
-	u8 CMD;		/* cmd parameter */
-	u8 *data;
-	u32 block;
-	u16 page;
-	u16 count;
-	u16 status = PASS;
-
-	nand_dbg_print(NAND_DBG_TRACE, "%s, Line %d, Function: %s\n",
-		       __FILE__, __LINE__, __func__);
-
-	nand_dbg_print(NAND_DBG_TRACE, "At start of Execute CMDs: "
-		       "Tag Count %u\n", tag_count);
-
-	for (i = 0; i < totalUsedBanks; i++) {
-		PendingCMD[i].CMD = DUMMY_CMD;
-		PendingCMD[i].Tag = 0xFF;
-		PendingCMD[i].Block =
-		    (DeviceInfo.wTotalBlocks / totalUsedBanks) * i;
-
-		for (j = 0; j <= MAX_CHANS; j++)
-			PendingCMD[i].ChanSync[j] = 0;
-	}
-
-	CDMA_Execute_CMDs(tag_count);
-
-#ifdef VERBOSE
-		print_pending_cmds(tag_count);
-#endif
-#if DEBUG_SYNC
-	}
-	debug_sync_cnt++;
-#endif
-
-	for (i = MAX_CHANS;
-	     i < tag_count + MAX_CHANS; i++) {
-		CMD = PendingCMD[i].CMD;
-		data = PendingCMD[i].DataAddr;
-		block = PendingCMD[i].Block;
-		page = PendingCMD[i].Page;
-		count = PendingCMD[i].PageCount;
-
-		switch (CMD) {
-		case ERASE_CMD:
-			mtd_Erase_Block(block);
-			PendingCMD[i].Status = PASS;
-			break;
-		case WRITE_MAIN_CMD:
-			mtd_Write_Page_Main(data, block, page, count);
-			PendingCMD[i].Status = PASS;
-			break;
-		case WRITE_MAIN_SPARE_CMD:
-			mtd_Write_Page_Main_Spare(data, block, page, count);
-			PendingCMD[i].Status = PASS;
-			break;
-		case READ_MAIN_CMD:
-			mtd_Read_Page_Main(data, block, page, count);
-			PendingCMD[i].Status = PASS;
-			break;
-		case MEMCOPY_CMD:
-			memcpy(PendingCMD[i].DataDestAddr,
-			       PendingCMD[i].DataSrcAddr,
-			       PendingCMD[i].MemCopyByteCnt);
-		case DUMMY_CMD:
-			PendingCMD[i].Status = PASS;
-			break;
-		default:
-			PendingCMD[i].Status = FAIL;
-			break;
-		}
-	}
-
-	/*
-	 * Temperory adding code to reset PendingCMD array for basic testing.
-	 * It should be done at the end of  event status function.
-	 */
-	for (i = tag_count + MAX_CHANS; i < MAX_DESCS; i++) {
-		PendingCMD[i].CMD = 0;
-		PendingCMD[i].Tag = 0;
-		PendingCMD[i].DataAddr = 0;
-		PendingCMD[i].Block = 0;
-		PendingCMD[i].Page = 0;
-		PendingCMD[i].PageCount = 0;
-		PendingCMD[i].DataDestAddr = 0;
-		PendingCMD[i].DataSrcAddr = 0;
-		PendingCMD[i].MemCopyByteCnt = 0;
-		PendingCMD[i].ChanSync[0] = 0;
-		PendingCMD[i].ChanSync[1] = 0;
-		PendingCMD[i].ChanSync[2] = 0;
-		PendingCMD[i].ChanSync[3] = 0;
-		PendingCMD[i].ChanSync[4] = 0;
-		PendingCMD[i].Status = CMD_NOT_DONE;
-	}
-
-	nand_dbg_print(NAND_DBG_TRACE, "At end of Execute CMDs.\n");
-
-	mtd_isr(0, 0); /* This is a null isr now. Need fill it in future */
-
-	return status;
-}
-
-/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
-* Function:     mtd_Event_Status
-* Inputs:       none
-* Outputs:      Event_Status code
-* Description:  This function can also be used to force errors
-*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
-u16 mtd_CDMA_Event_Status(void)
-{
-	nand_dbg_print(NAND_DBG_TRACE, "%s, Line %d, Function: %s\n",
-		       __FILE__, __LINE__, __func__);
-
-	return EVENT_PASS;
-}
-
-#endif /* CMD_DMA */
-#endif /* !ELDORA */
diff --git a/drivers/staging/spectra/lld_mtd.h b/drivers/staging/spectra/lld_mtd.h
deleted file mode 100644
index 4e81ee8..0000000
--- a/drivers/staging/spectra/lld_mtd.h
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * NAND Flash Controller Device Driver
- * Copyright (c) 2009, Intel Corporation and its suppliers.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms and conditions of the GNU General Public License,
- * version 2, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
- *
- */
-
-#ifndef _LLD_MTD_
-#define _LLD_MTD_
-
-#include "ffsport.h"
-#include "ffsdefs.h"
-
-/* prototypes: MTD API functions */
-extern u16 mtd_Flash_Reset(void);
-extern u16 mtd_Flash_Init(void);
-extern int mtd_Flash_Release(void);
-extern u16 mtd_Read_Device_ID(void);
-extern u16 mtd_Erase_Block(u32 block_addr);
-extern u16 mtd_Write_Page_Main(u8 *write_data, u32 Block,
-				u16 Page, u16 PageCount);
-extern u16 mtd_Read_Page_Main(u8 *read_data, u32 Block, u16 Page,
-				 u16 PageCount);
-extern u16 mtd_Event_Status(void);
-extern void mtd_Enable_Disable_Interrupts(u16 INT_ENABLE);
-extern u16 mtd_Write_Page_Main_Spare(u8 *write_data, u32 Block,
-					u16 Page, u16 PageCount);
-extern u16 mtd_Write_Page_Spare(u8 *write_data, u32 Block,
-					u16 Page, u16 PageCount);
-extern u16 mtd_Read_Page_Main_Spare(u8 *read_data, u32 Block,
-				       u16 Page, u16 PageCount);
-extern u16 mtd_Read_Page_Spare(u8 *read_data, u32 Block, u16 Page,
-				  u16 PageCount);
-extern u16 mtd_Get_Bad_Block(u32 block);
-
-u16 mtd_CDMA_Flash_Init(void);
-u16 mtd_CDMA_Execute_CMDs(u16 tag_count);
-u16 mtd_CDMA_Event_Status(void);
-#endif /*_LLD_MTD_*/
diff --git a/drivers/staging/spectra/lld_nand.c b/drivers/staging/spectra/lld_nand.c
deleted file mode 100644
index 60a14ff..0000000
--- a/drivers/staging/spectra/lld_nand.c
+++ /dev/null
@@ -1,2619 +0,0 @@
-/*
- * NAND Flash Controller Device Driver
- * Copyright (c) 2009, Intel Corporation and its suppliers.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms and conditions of the GNU General Public License,
- * version 2, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
- *
- */
-
-#include "lld.h"
-#include "lld_nand.h"
-#include "lld_cdma.h"
-
-#include "spectraswconfig.h"
-#include "flash.h"
-#include "ffsdefs.h"
-
-#include <linux/interrupt.h>
-#include <linux/delay.h>
-#include <linux/wait.h>
-#include <linux/mutex.h>
-
-#include "nand_regs.h"
-
-#define SPECTRA_NAND_NAME    "nd"
-
-#define CEIL_DIV(X, Y) (((X)%(Y)) ? ((X)/(Y)+1) : ((X)/(Y)))
-#define MAX_PAGES_PER_RW        128
-
-#define INT_IDLE_STATE                 0
-#define INT_READ_PAGE_MAIN    0x01
-#define INT_WRITE_PAGE_MAIN    0x02
-#define INT_PIPELINE_READ_AHEAD    0x04
-#define INT_PIPELINE_WRITE_AHEAD    0x08
-#define INT_MULTI_PLANE_READ    0x10
-#define INT_MULTI_PLANE_WRITE    0x11
-
-static u32 enable_ecc;
-
-struct mrst_nand_info info;
-
-int totalUsedBanks;
-u32 GLOB_valid_banks[LLD_MAX_FLASH_BANKS];
-
-void __iomem *FlashReg;
-void __iomem *FlashMem;
-
-u16 conf_parameters[] = {
-	0x0000,
-	0x0000,
-	0x01F4,
-	0x01F4,
-	0x01F4,
-	0x01F4,
-	0x0000,
-	0x0000,
-	0x0001,
-	0x0000,
-	0x0000,
-	0x0000,
-	0x0000,
-	0x0040,
-	0x0001,
-	0x000A,
-	0x000A,
-	0x000A,
-	0x0000,
-	0x0000,
-	0x0005,
-	0x0012,
-	0x000C
-};
-
-u16   NAND_Get_Bad_Block(u32 block)
-{
-	u32 status = PASS;
-	u32 flag_bytes  = 0;
-	u32 skip_bytes  = DeviceInfo.wSpareSkipBytes;
-	u32 page, i;
-	u8 *pReadSpareBuf = buf_get_bad_block;
-
-	if (enable_ecc)
-		flag_bytes = DeviceInfo.wNumPageSpareFlag;
-
-	for (page = 0; page < 2; page++) {
-		status = NAND_Read_Page_Spare(pReadSpareBuf, block, page, 1);
-		if (status != PASS)
-			return READ_ERROR;
-		for (i = flag_bytes; i < (flag_bytes + skip_bytes); i++)
-			if (pReadSpareBuf[i] != 0xff)
-				return DEFECTIVE_BLOCK;
-	}
-
-	for (page = 1; page < 3; page++) {
-		status = NAND_Read_Page_Spare(pReadSpareBuf, block,
-			DeviceInfo.wPagesPerBlock - page , 1);
-		if (status != PASS)
-			return READ_ERROR;
-		for (i = flag_bytes; i < (flag_bytes + skip_bytes); i++)
-			if (pReadSpareBuf[i] != 0xff)
-				return DEFECTIVE_BLOCK;
-	}
-
-	return GOOD_BLOCK;
-}
-
-
-u16 NAND_Flash_Reset(void)
-{
-	u32 i;
-	u32 intr_status_rst_comp[4] = {INTR_STATUS0__RST_COMP,
-		INTR_STATUS1__RST_COMP,
-		INTR_STATUS2__RST_COMP,
-		INTR_STATUS3__RST_COMP};
-	u32 intr_status_time_out[4] = {INTR_STATUS0__TIME_OUT,
-		INTR_STATUS1__TIME_OUT,
-		INTR_STATUS2__TIME_OUT,
-		INTR_STATUS3__TIME_OUT};
-	u32 intr_status[4] = {INTR_STATUS0, INTR_STATUS1,
-		INTR_STATUS2, INTR_STATUS3};
-	u32 device_reset_banks[4] = {DEVICE_RESET__BANK0,
-		DEVICE_RESET__BANK1,
-		DEVICE_RESET__BANK2,
-		DEVICE_RESET__BANK3};
-
-	nand_dbg_print(NAND_DBG_TRACE, "%s, Line %d, Function: %s\n",
-		       __FILE__, __LINE__, __func__);
-
-	for (i = 0 ; i < LLD_MAX_FLASH_BANKS; i++)
-		iowrite32(intr_status_rst_comp[i] | intr_status_time_out[i],
-		FlashReg + intr_status[i]);
-
-	for (i = 0 ; i < LLD_MAX_FLASH_BANKS; i++) {
-		iowrite32(device_reset_banks[i], FlashReg + DEVICE_RESET);
-		while (!(ioread32(FlashReg + intr_status[i]) &
-			(intr_status_rst_comp[i] | intr_status_time_out[i])))
-			;
-		if (ioread32(FlashReg + intr_status[i]) &
-			intr_status_time_out[i])
-			nand_dbg_print(NAND_DBG_WARN,
-			"NAND Reset operation timed out on bank %d\n", i);
-	}
-
-	for (i = 0; i < LLD_MAX_FLASH_BANKS; i++)
-		iowrite32(intr_status_rst_comp[i] | intr_status_time_out[i],
-			FlashReg + intr_status[i]);
-
-	return PASS;
-}
-
-static void NAND_ONFi_Timing_Mode(u16 mode)
-{
-	u16 Trea[6] = {40, 30, 25, 20, 20, 16};
-	u16 Trp[6] = {50, 25, 17, 15, 12, 10};
-	u16 Treh[6] = {30, 15, 15, 10, 10, 7};
-	u16 Trc[6] = {100, 50, 35, 30, 25, 20};
-	u16 Trhoh[6] = {0, 15, 15, 15, 15, 15};
-	u16 Trloh[6] = {0, 0, 0, 0, 5, 5};
-	u16 Tcea[6] = {100, 45, 30, 25, 25, 25};
-	u16 Tadl[6] = {200, 100, 100, 100, 70, 70};
-	u16 Trhw[6] = {200, 100, 100, 100, 100, 100};
-	u16 Trhz[6] = {200, 100, 100, 100, 100, 100};
-	u16 Twhr[6] = {120, 80, 80, 60, 60, 60};
-	u16 Tcs[6] = {70, 35, 25, 25, 20, 15};
-
-	u16 TclsRising = 1;
-	u16 data_invalid_rhoh, data_invalid_rloh, data_invalid;
-	u16 dv_window = 0;
-	u16 en_lo, en_hi;
-	u16 acc_clks;
-	u16 addr_2_data, re_2_we, re_2_re, we_2_re, cs_cnt;
-
-	nand_dbg_print(NAND_DBG_TRACE, "%s, Line %d, Function: %s\n",
-		       __FILE__, __LINE__, __func__);
-
-	en_lo = CEIL_DIV(Trp[mode], CLK_X);
-	en_hi = CEIL_DIV(Treh[mode], CLK_X);
-
-#if ONFI_BLOOM_TIME
-	if ((en_hi * CLK_X) < (Treh[mode] + 2))
-		en_hi++;
-#endif
-
-	if ((en_lo + en_hi) * CLK_X < Trc[mode])
-		en_lo += CEIL_DIV((Trc[mode] - (en_lo + en_hi) * CLK_X), CLK_X);
-
-	if ((en_lo + en_hi) < CLK_MULTI)
-		en_lo += CLK_MULTI - en_lo - en_hi;
-
-	while (dv_window < 8) {
-		data_invalid_rhoh = en_lo * CLK_X + Trhoh[mode];
-
-		data_invalid_rloh = (en_lo + en_hi) * CLK_X + Trloh[mode];
-
-		data_invalid =
-		    data_invalid_rhoh <
-		    data_invalid_rloh ? data_invalid_rhoh : data_invalid_rloh;
-
-		dv_window = data_invalid - Trea[mode];
-
-		if (dv_window < 8)
-			en_lo++;
-	}
-
-	acc_clks = CEIL_DIV(Trea[mode], CLK_X);
-
-	while (((acc_clks * CLK_X) - Trea[mode]) < 3)
-		acc_clks++;
-
-	if ((data_invalid - acc_clks * CLK_X) < 2)
-		nand_dbg_print(NAND_DBG_WARN, "%s, Line %d: Warning!\n",
-			__FILE__, __LINE__);
-
-	addr_2_data = CEIL_DIV(Tadl[mode], CLK_X);
-	re_2_we = CEIL_DIV(Trhw[mode], CLK_X);
-	re_2_re = CEIL_DIV(Trhz[mode], CLK_X);
-	we_2_re = CEIL_DIV(Twhr[mode], CLK_X);
-	cs_cnt = CEIL_DIV((Tcs[mode] - Trp[mode]), CLK_X);
-	if (!TclsRising)
-		cs_cnt = CEIL_DIV(Tcs[mode], CLK_X);
-	if (cs_cnt == 0)
-		cs_cnt = 1;
-
-	if (Tcea[mode]) {
-		while (((cs_cnt * CLK_X) + Trea[mode]) < Tcea[mode])
-			cs_cnt++;
-	}
-
-#if MODE5_WORKAROUND
-	if (mode == 5)
-		acc_clks = 5;
-#endif
-
-	/* Sighting 3462430: Temporary hack for MT29F128G08CJABAWP:B */
-	if ((ioread32(FlashReg + MANUFACTURER_ID) == 0) &&
-		(ioread32(FlashReg + DEVICE_ID) == 0x88))
-		acc_clks = 6;
-
-	iowrite32(acc_clks, FlashReg + ACC_CLKS);
-	iowrite32(re_2_we, FlashReg + RE_2_WE);
-	iowrite32(re_2_re, FlashReg + RE_2_RE);
-	iowrite32(we_2_re, FlashReg + WE_2_RE);
-	iowrite32(addr_2_data, FlashReg + ADDR_2_DATA);
-	iowrite32(en_lo, FlashReg + RDWR_EN_LO_CNT);
-	iowrite32(en_hi, FlashReg + RDWR_EN_HI_CNT);
-	iowrite32(cs_cnt, FlashReg + CS_SETUP_CNT);
-}
-
-static void index_addr(u32 address, u32 data)
-{
-	iowrite32(address, FlashMem);
-	iowrite32(data, FlashMem + 0x10);
-}
-
-static void index_addr_read_data(u32 address, u32 *pdata)
-{
-	iowrite32(address, FlashMem);
-	*pdata = ioread32(FlashMem + 0x10);
-}
-
-static void set_ecc_config(void)
-{
-#if SUPPORT_8BITECC
-	if ((ioread32(FlashReg + DEVICE_MAIN_AREA_SIZE) < 4096) ||
-		(ioread32(FlashReg + DEVICE_SPARE_AREA_SIZE) <= 128))
-		iowrite32(8, FlashReg + ECC_CORRECTION);
-#endif
-
-	if ((ioread32(FlashReg + ECC_CORRECTION) & ECC_CORRECTION__VALUE)
-		== 1) {
-		DeviceInfo.wECCBytesPerSector = 4;
-		DeviceInfo.wECCBytesPerSector *= DeviceInfo.wDevicesConnected;
-		DeviceInfo.wNumPageSpareFlag =
-			DeviceInfo.wPageSpareSize -
-			DeviceInfo.wPageDataSize /
-			(ECC_SECTOR_SIZE * DeviceInfo.wDevicesConnected) *
-			DeviceInfo.wECCBytesPerSector
-			- DeviceInfo.wSpareSkipBytes;
-	} else {
-		DeviceInfo.wECCBytesPerSector =
-			(ioread32(FlashReg + ECC_CORRECTION) &
-			ECC_CORRECTION__VALUE) * 13 / 8;
-		if ((DeviceInfo.wECCBytesPerSector) % 2 == 0)
-			DeviceInfo.wECCBytesPerSector += 2;
-		else
-			DeviceInfo.wECCBytesPerSector += 1;
-
-		DeviceInfo.wECCBytesPerSector *= DeviceInfo.wDevicesConnected;
-		DeviceInfo.wNumPageSpareFlag = DeviceInfo.wPageSpareSize -
-			DeviceInfo.wPageDataSize /
-			(ECC_SECTOR_SIZE * DeviceInfo.wDevicesConnected) *
-			DeviceInfo.wECCBytesPerSector
-			- DeviceInfo.wSpareSkipBytes;
-	}
-}
-
-static u16 get_onfi_nand_para(void)
-{
-	int i;
-	u16 blks_lun_l, blks_lun_h, n_of_luns;
-	u32 blockperlun, id;
-
-	iowrite32(DEVICE_RESET__BANK0, FlashReg + DEVICE_RESET);
-
-	while (!((ioread32(FlashReg + INTR_STATUS0) &
-		INTR_STATUS0__RST_COMP) |
-		(ioread32(FlashReg + INTR_STATUS0) &
-		INTR_STATUS0__TIME_OUT)))
-		;
-
-	if (ioread32(FlashReg + INTR_STATUS0) & INTR_STATUS0__RST_COMP) {
-		iowrite32(DEVICE_RESET__BANK1, FlashReg + DEVICE_RESET);
-		while (!((ioread32(FlashReg + INTR_STATUS1) &
-			INTR_STATUS1__RST_COMP) |
-			(ioread32(FlashReg + INTR_STATUS1) &
-			INTR_STATUS1__TIME_OUT)))
-			;
-
-		if (ioread32(FlashReg + INTR_STATUS1) &
-			INTR_STATUS1__RST_COMP) {
-			iowrite32(DEVICE_RESET__BANK2,
-				FlashReg + DEVICE_RESET);
-			while (!((ioread32(FlashReg + INTR_STATUS2) &
-				INTR_STATUS2__RST_COMP) |
-				(ioread32(FlashReg + INTR_STATUS2) &
-				INTR_STATUS2__TIME_OUT)))
-				;
-
-			if (ioread32(FlashReg + INTR_STATUS2) &
-				INTR_STATUS2__RST_COMP) {
-				iowrite32(DEVICE_RESET__BANK3,
-					FlashReg + DEVICE_RESET);
-				while (!((ioread32(FlashReg + INTR_STATUS3) &
-					INTR_STATUS3__RST_COMP) |
-					(ioread32(FlashReg + INTR_STATUS3) &
-					INTR_STATUS3__TIME_OUT)))
-					;
-			} else {
-				printk(KERN_ERR "Getting a time out for bank 2!\n");
-			}
-		} else {
-			printk(KERN_ERR "Getting a time out for bank 1!\n");
-		}
-	}
-
-	iowrite32(INTR_STATUS0__TIME_OUT, FlashReg + INTR_STATUS0);
-	iowrite32(INTR_STATUS1__TIME_OUT, FlashReg + INTR_STATUS1);
-	iowrite32(INTR_STATUS2__TIME_OUT, FlashReg + INTR_STATUS2);
-	iowrite32(INTR_STATUS3__TIME_OUT, FlashReg + INTR_STATUS3);
-
-	DeviceInfo.wONFIDevFeatures =
-		ioread32(FlashReg + ONFI_DEVICE_FEATURES);
-	DeviceInfo.wONFIOptCommands =
-		ioread32(FlashReg + ONFI_OPTIONAL_COMMANDS);
-	DeviceInfo.wONFITimingMode =
-		ioread32(FlashReg + ONFI_TIMING_MODE);
-	DeviceInfo.wONFIPgmCacheTimingMode =
-		ioread32(FlashReg + ONFI_PGM_CACHE_TIMING_MODE);
-
-	n_of_luns = ioread32(FlashReg + ONFI_DEVICE_NO_OF_LUNS) &
-		ONFI_DEVICE_NO_OF_LUNS__NO_OF_LUNS;
-	blks_lun_l = ioread32(FlashReg + ONFI_DEVICE_NO_OF_BLOCKS_PER_LUN_L);
-	blks_lun_h = ioread32(FlashReg + ONFI_DEVICE_NO_OF_BLOCKS_PER_LUN_U);
-
-	blockperlun = (blks_lun_h << 16) | blks_lun_l;
-
-	DeviceInfo.wTotalBlocks = n_of_luns * blockperlun;
-
-	if (!(ioread32(FlashReg + ONFI_TIMING_MODE) &
-		ONFI_TIMING_MODE__VALUE))
-		return FAIL;
-
-	for (i = 5; i > 0; i--) {
-		if (ioread32(FlashReg + ONFI_TIMING_MODE) & (0x01 << i))
-			break;
-	}
-
-	NAND_ONFi_Timing_Mode(i);
-
-	index_addr(MODE_11 | 0, 0x90);
-	index_addr(MODE_11 | 1, 0);
-
-	for (i = 0; i < 3; i++)
-		index_addr_read_data(MODE_11 | 2, &id);
-
-	nand_dbg_print(NAND_DBG_DEBUG, "3rd ID: 0x%x\n", id);
-
-	DeviceInfo.MLCDevice = id & 0x0C;
-
-	/* By now, all the ONFI devices we know support the page cache */
-	/* rw feature. So here we enable the pipeline_rw_ahead feature */
-	/* iowrite32(1, FlashReg + CACHE_WRITE_ENABLE); */
-	/* iowrite32(1, FlashReg + CACHE_READ_ENABLE);  */
-
-	return PASS;
-}
-
-static void get_samsung_nand_para(void)
-{
-	u8 no_of_planes;
-	u32 blk_size;
-	u64 plane_size, capacity;
-	u32 id_bytes[5];
-	int i;
-
-	index_addr((u32)(MODE_11 | 0), 0x90);
-	index_addr((u32)(MODE_11 | 1), 0);
-	for (i = 0; i < 5; i++)
-		index_addr_read_data((u32)(MODE_11 | 2), &id_bytes[i]);
-
-	nand_dbg_print(NAND_DBG_DEBUG,
-		"ID bytes: 0x%x, 0x%x, 0x%x, 0x%x, 0x%x\n",
-		id_bytes[0], id_bytes[1], id_bytes[2],
-		id_bytes[3], id_bytes[4]);
-
-	if ((id_bytes[1] & 0xff) == 0xd3) { /* Samsung K9WAG08U1A */
-		/* Set timing register values according to datasheet */
-		iowrite32(5, FlashReg + ACC_CLKS);
-		iowrite32(20, FlashReg + RE_2_WE);
-		iowrite32(12, FlashReg + WE_2_RE);
-		iowrite32(14, FlashReg + ADDR_2_DATA);
-		iowrite32(3, FlashReg + RDWR_EN_LO_CNT);
-		iowrite32(2, FlashReg + RDWR_EN_HI_CNT);
-		iowrite32(2, FlashReg + CS_SETUP_CNT);
-	}
-
-	no_of_planes = 1 << ((id_bytes[4] & 0x0c) >> 2);
-	plane_size  = (u64)64 << ((id_bytes[4] & 0x70) >> 4);
-	blk_size = 64 << ((ioread32(FlashReg + DEVICE_PARAM_1) & 0x30) >> 4);
-	capacity = (u64)128 * plane_size * no_of_planes;
-
-	DeviceInfo.wTotalBlocks = (u32)GLOB_u64_Div(capacity, blk_size);
-}
-
-static void get_toshiba_nand_para(void)
-{
-	void __iomem *scratch_reg;
-	u32 tmp;
-
-	/* Workaround to fix a controller bug which reports a wrong */
-	/* spare area size for some kind of Toshiba NAND device */
-	if ((ioread32(FlashReg + DEVICE_MAIN_AREA_SIZE) == 4096) &&
-		(ioread32(FlashReg + DEVICE_SPARE_AREA_SIZE) == 64)) {
-		iowrite32(216, FlashReg + DEVICE_SPARE_AREA_SIZE);
-		tmp = ioread32(FlashReg + DEVICES_CONNECTED) *
-			ioread32(FlashReg + DEVICE_SPARE_AREA_SIZE);
-		iowrite32(tmp, FlashReg + LOGICAL_PAGE_SPARE_SIZE);
-#if SUPPORT_15BITECC
-		iowrite32(15, FlashReg + ECC_CORRECTION);
-#elif SUPPORT_8BITECC
-		iowrite32(8, FlashReg + ECC_CORRECTION);
-#endif
-	}
-
-	/* As Toshiba NAND can not provide it's block number, */
-	/* so here we need user to provide the correct block */
-	/* number in a scratch register before the Linux NAND */
-	/* driver is loaded. If no valid value found in the scratch */
-	/* register, then we use default block number value */
-	scratch_reg = ioremap_nocache(SCRATCH_REG_ADDR, SCRATCH_REG_SIZE);
-	if (!scratch_reg) {
-		printk(KERN_ERR "Spectra: ioremap failed in %s, Line %d",
-			__FILE__, __LINE__);
-		DeviceInfo.wTotalBlocks = GLOB_HWCTL_DEFAULT_BLKS;
-	} else {
-		nand_dbg_print(NAND_DBG_WARN,
-			"Spectra: ioremap reg address: 0x%p\n", scratch_reg);
-		DeviceInfo.wTotalBlocks = 1 << ioread8(scratch_reg);
-		if (DeviceInfo.wTotalBlocks < 512)
-			DeviceInfo.wTotalBlocks = GLOB_HWCTL_DEFAULT_BLKS;
-		iounmap(scratch_reg);
-	}
-}
-
-static void get_hynix_nand_para(void)
-{
-	void __iomem *scratch_reg;
-	u32 main_size, spare_size;
-
-	switch (DeviceInfo.wDeviceID) {
-	case 0xD5: /* Hynix H27UAG8T2A, H27UBG8U5A or H27UCG8VFA */
-	case 0xD7: /* Hynix H27UDG8VEM, H27UCG8UDM or H27UCG8V5A */
-		iowrite32(128, FlashReg + PAGES_PER_BLOCK);
-		iowrite32(4096, FlashReg + DEVICE_MAIN_AREA_SIZE);
-		iowrite32(224, FlashReg + DEVICE_SPARE_AREA_SIZE);
-		main_size = 4096 * ioread32(FlashReg + DEVICES_CONNECTED);
-		spare_size = 224 * ioread32(FlashReg + DEVICES_CONNECTED);
-		iowrite32(main_size, FlashReg + LOGICAL_PAGE_DATA_SIZE);
-		iowrite32(spare_size, FlashReg + LOGICAL_PAGE_SPARE_SIZE);
-		iowrite32(0, FlashReg + DEVICE_WIDTH);
-#if SUPPORT_15BITECC
-		iowrite32(15, FlashReg + ECC_CORRECTION);
-#elif SUPPORT_8BITECC
-		iowrite32(8, FlashReg + ECC_CORRECTION);
-#endif
-		DeviceInfo.MLCDevice  = 1;
-		break;
-	default:
-		nand_dbg_print(NAND_DBG_WARN,
-			"Spectra: Unknown Hynix NAND (Device ID: 0x%x)."
-			"Will use default parameter values instead.\n",
-			DeviceInfo.wDeviceID);
-	}
-
-	scratch_reg = ioremap_nocache(SCRATCH_REG_ADDR, SCRATCH_REG_SIZE);
-	if (!scratch_reg) {
-		printk(KERN_ERR "Spectra: ioremap failed in %s, Line %d",
-			__FILE__, __LINE__);
-		DeviceInfo.wTotalBlocks = GLOB_HWCTL_DEFAULT_BLKS;
-	} else {
-		nand_dbg_print(NAND_DBG_WARN,
-			"Spectra: ioremap reg address: 0x%p\n", scratch_reg);
-		DeviceInfo.wTotalBlocks = 1 << ioread8(scratch_reg);
-		if (DeviceInfo.wTotalBlocks < 512)
-			DeviceInfo.wTotalBlocks = GLOB_HWCTL_DEFAULT_BLKS;
-		iounmap(scratch_reg);
-	}
-}
-
-static void find_valid_banks(void)
-{
-	u32 id[LLD_MAX_FLASH_BANKS];
-	int i;
-
-	totalUsedBanks = 0;
-	for (i = 0; i < LLD_MAX_FLASH_BANKS; i++) {
-		index_addr((u32)(MODE_11 | (i << 24) | 0), 0x90);
-		index_addr((u32)(MODE_11 | (i << 24) | 1), 0);
-		index_addr_read_data((u32)(MODE_11 | (i << 24) | 2), &id[i]);
-
-		nand_dbg_print(NAND_DBG_DEBUG,
-			"Return 1st ID for bank[%d]: %x\n", i, id[i]);
-
-		if (i == 0) {
-			if (id[i] & 0x0ff)
-				GLOB_valid_banks[i] = 1;
-		} else {
-			if ((id[i] & 0x0ff) == (id[0] & 0x0ff))
-				GLOB_valid_banks[i] = 1;
-		}
-
-		totalUsedBanks += GLOB_valid_banks[i];
-	}
-
-	nand_dbg_print(NAND_DBG_DEBUG,
-		"totalUsedBanks: %d\n", totalUsedBanks);
-}
-
-static void detect_partition_feature(void)
-{
-	if (ioread32(FlashReg + FEATURES) & FEATURES__PARTITION) {
-		if ((ioread32(FlashReg + PERM_SRC_ID_1) &
-			PERM_SRC_ID_1__SRCID) == SPECTRA_PARTITION_ID) {
-			DeviceInfo.wSpectraStartBlock =
-			    ((ioread32(FlashReg + MIN_MAX_BANK_1) &
-			      MIN_MAX_BANK_1__MIN_VALUE) *
-			     DeviceInfo.wTotalBlocks)
-			    +
-			    (ioread32(FlashReg + MIN_BLK_ADDR_1) &
-			    MIN_BLK_ADDR_1__VALUE);
-
-			DeviceInfo.wSpectraEndBlock =
-			    (((ioread32(FlashReg + MIN_MAX_BANK_1) &
-			       MIN_MAX_BANK_1__MAX_VALUE) >> 2) *
-			     DeviceInfo.wTotalBlocks)
-			    +
-			    (ioread32(FlashReg + MAX_BLK_ADDR_1) &
-			    MAX_BLK_ADDR_1__VALUE);
-
-			DeviceInfo.wTotalBlocks *= totalUsedBanks;
-
-			if (DeviceInfo.wSpectraEndBlock >=
-			    DeviceInfo.wTotalBlocks) {
-				DeviceInfo.wSpectraEndBlock =
-				    DeviceInfo.wTotalBlocks - 1;
-			}
-
-			DeviceInfo.wDataBlockNum =
-				DeviceInfo.wSpectraEndBlock -
-				DeviceInfo.wSpectraStartBlock + 1;
-		} else {
-			DeviceInfo.wTotalBlocks *= totalUsedBanks;
-			DeviceInfo.wSpectraStartBlock = SPECTRA_START_BLOCK;
-			DeviceInfo.wSpectraEndBlock =
-				DeviceInfo.wTotalBlocks - 1;
-			DeviceInfo.wDataBlockNum =
-				DeviceInfo.wSpectraEndBlock -
-				DeviceInfo.wSpectraStartBlock + 1;
-		}
-	} else {
-		DeviceInfo.wTotalBlocks *= totalUsedBanks;
-		DeviceInfo.wSpectraStartBlock = SPECTRA_START_BLOCK;
-		DeviceInfo.wSpectraEndBlock = DeviceInfo.wTotalBlocks - 1;
-		DeviceInfo.wDataBlockNum =
-			DeviceInfo.wSpectraEndBlock -
-			DeviceInfo.wSpectraStartBlock + 1;
-	}
-}
-
-static void dump_device_info(void)
-{
-	nand_dbg_print(NAND_DBG_DEBUG, "DeviceInfo:\n");
-	nand_dbg_print(NAND_DBG_DEBUG, "DeviceMaker: 0x%x\n",
-		DeviceInfo.wDeviceMaker);
-	nand_dbg_print(NAND_DBG_DEBUG, "DeviceID: 0x%x\n",
-		DeviceInfo.wDeviceID);
-	nand_dbg_print(NAND_DBG_DEBUG, "DeviceType: 0x%x\n",
-		DeviceInfo.wDeviceType);
-	nand_dbg_print(NAND_DBG_DEBUG, "SpectraStartBlock: %d\n",
-		DeviceInfo.wSpectraStartBlock);
-	nand_dbg_print(NAND_DBG_DEBUG, "SpectraEndBlock: %d\n",
-		DeviceInfo.wSpectraEndBlock);
-	nand_dbg_print(NAND_DBG_DEBUG, "TotalBlocks: %d\n",
-		DeviceInfo.wTotalBlocks);
-	nand_dbg_print(NAND_DBG_DEBUG, "PagesPerBlock: %d\n",
-		DeviceInfo.wPagesPerBlock);
-	nand_dbg_print(NAND_DBG_DEBUG, "PageSize: %d\n",
-		DeviceInfo.wPageSize);
-	nand_dbg_print(NAND_DBG_DEBUG, "PageDataSize: %d\n",
-		DeviceInfo.wPageDataSize);
-	nand_dbg_print(NAND_DBG_DEBUG, "PageSpareSize: %d\n",
-		DeviceInfo.wPageSpareSize);
-	nand_dbg_print(NAND_DBG_DEBUG, "NumPageSpareFlag: %d\n",
-		DeviceInfo.wNumPageSpareFlag);
-	nand_dbg_print(NAND_DBG_DEBUG, "ECCBytesPerSector: %d\n",
-		DeviceInfo.wECCBytesPerSector);
-	nand_dbg_print(NAND_DBG_DEBUG, "BlockSize: %d\n",
-		DeviceInfo.wBlockSize);
-	nand_dbg_print(NAND_DBG_DEBUG, "BlockDataSize: %d\n",
-		DeviceInfo.wBlockDataSize);
-	nand_dbg_print(NAND_DBG_DEBUG, "DataBlockNum: %d\n",
-		DeviceInfo.wDataBlockNum);
-	nand_dbg_print(NAND_DBG_DEBUG, "PlaneNum: %d\n",
-		DeviceInfo.bPlaneNum);
-	nand_dbg_print(NAND_DBG_DEBUG, "DeviceMainAreaSize: %d\n",
-		DeviceInfo.wDeviceMainAreaSize);
-	nand_dbg_print(NAND_DBG_DEBUG, "DeviceSpareAreaSize: %d\n",
-		DeviceInfo.wDeviceSpareAreaSize);
-	nand_dbg_print(NAND_DBG_DEBUG, "DevicesConnected: %d\n",
-		DeviceInfo.wDevicesConnected);
-	nand_dbg_print(NAND_DBG_DEBUG, "DeviceWidth: %d\n",
-		DeviceInfo.wDeviceWidth);
-	nand_dbg_print(NAND_DBG_DEBUG, "HWRevision: 0x%x\n",
-		DeviceInfo.wHWRevision);
-	nand_dbg_print(NAND_DBG_DEBUG, "HWFeatures: 0x%x\n",
-		DeviceInfo.wHWFeatures);
-	nand_dbg_print(NAND_DBG_DEBUG, "ONFIDevFeatures: 0x%x\n",
-		DeviceInfo.wONFIDevFeatures);
-	nand_dbg_print(NAND_DBG_DEBUG, "ONFIOptCommands: 0x%x\n",
-		DeviceInfo.wONFIOptCommands);
-	nand_dbg_print(NAND_DBG_DEBUG, "ONFITimingMode: 0x%x\n",
-		DeviceInfo.wONFITimingMode);
-	nand_dbg_print(NAND_DBG_DEBUG, "ONFIPgmCacheTimingMode: 0x%x\n",
-		DeviceInfo.wONFIPgmCacheTimingMode);
-	nand_dbg_print(NAND_DBG_DEBUG, "MLCDevice: %s\n",
-		DeviceInfo.MLCDevice ? "Yes" : "No");
-	nand_dbg_print(NAND_DBG_DEBUG, "SpareSkipBytes: %d\n",
-		DeviceInfo.wSpareSkipBytes);
-	nand_dbg_print(NAND_DBG_DEBUG, "BitsInPageNumber: %d\n",
-		DeviceInfo.nBitsInPageNumber);
-	nand_dbg_print(NAND_DBG_DEBUG, "BitsInPageDataSize: %d\n",
-		DeviceInfo.nBitsInPageDataSize);
-	nand_dbg_print(NAND_DBG_DEBUG, "BitsInBlockDataSize: %d\n",
-		DeviceInfo.nBitsInBlockDataSize);
-}
-
-u16 NAND_Read_Device_ID(void)
-{
-	u16 status = PASS;
-	u8 no_of_planes;
-
-	nand_dbg_print(NAND_DBG_TRACE, "%s, Line %d, Function: %s\n",
-		       __FILE__, __LINE__, __func__);
-
-	iowrite32(0x02, FlashReg + SPARE_AREA_SKIP_BYTES);
-	iowrite32(0xffff, FlashReg + SPARE_AREA_MARKER);
-	DeviceInfo.wDeviceMaker = ioread32(FlashReg + MANUFACTURER_ID);
-	DeviceInfo.wDeviceID = ioread32(FlashReg + DEVICE_ID);
-	DeviceInfo.MLCDevice = ioread32(FlashReg + DEVICE_PARAM_0) & 0x0c;
-
-	if (ioread32(FlashReg + ONFI_DEVICE_NO_OF_LUNS) &
-		ONFI_DEVICE_NO_OF_LUNS__ONFI_DEVICE) { /* ONFI 1.0 NAND */
-		if (FAIL == get_onfi_nand_para())
-			return FAIL;
-	} else if (DeviceInfo.wDeviceMaker == 0xEC) { /* Samsung NAND */
-		get_samsung_nand_para();
-	} else if (DeviceInfo.wDeviceMaker == 0x98) { /* Toshiba NAND */
-		get_toshiba_nand_para();
-	} else if (DeviceInfo.wDeviceMaker == 0xAD) { /* Hynix NAND */
-		get_hynix_nand_para();
-	} else {
-		DeviceInfo.wTotalBlocks = GLOB_HWCTL_DEFAULT_BLKS;
-	}
-
-	nand_dbg_print(NAND_DBG_DEBUG, "Dump timing register values:"
-			"acc_clks: %d, re_2_we: %d, we_2_re: %d,"
-			"addr_2_data: %d, rdwr_en_lo_cnt: %d, "
-			"rdwr_en_hi_cnt: %d, cs_setup_cnt: %d\n",
-			ioread32(FlashReg + ACC_CLKS),
-			ioread32(FlashReg + RE_2_WE),
-			ioread32(FlashReg + WE_2_RE),
-			ioread32(FlashReg + ADDR_2_DATA),
-			ioread32(FlashReg + RDWR_EN_LO_CNT),
-			ioread32(FlashReg + RDWR_EN_HI_CNT),
-			ioread32(FlashReg + CS_SETUP_CNT));
-
-	DeviceInfo.wHWRevision = ioread32(FlashReg + REVISION);
-	DeviceInfo.wHWFeatures = ioread32(FlashReg + FEATURES);
-
-	DeviceInfo.wDeviceMainAreaSize =
-		ioread32(FlashReg + DEVICE_MAIN_AREA_SIZE);
-	DeviceInfo.wDeviceSpareAreaSize =
-		ioread32(FlashReg + DEVICE_SPARE_AREA_SIZE);
-
-	DeviceInfo.wPageDataSize =
-		ioread32(FlashReg + LOGICAL_PAGE_DATA_SIZE);
-
-	/* Note: When using the Micon 4K NAND device, the controller will report
-	 * Page Spare Size as 216 bytes. But Micron's Spec say it's 218 bytes.
-	 * And if force set it to 218 bytes, the controller can not work
-	 * correctly. So just let it be. But keep in mind that this bug may
-	 * cause
-	 * other problems in future.       - Yunpeng  2008-10-10
-	 */
-	DeviceInfo.wPageSpareSize =
-		ioread32(FlashReg + LOGICAL_PAGE_SPARE_SIZE);
-
-	DeviceInfo.wPagesPerBlock = ioread32(FlashReg + PAGES_PER_BLOCK);
-
-	DeviceInfo.wPageSize =
-	    DeviceInfo.wPageDataSize + DeviceInfo.wPageSpareSize;
-	DeviceInfo.wBlockSize =
-	    DeviceInfo.wPageSize * DeviceInfo.wPagesPerBlock;
-	DeviceInfo.wBlockDataSize =
-	    DeviceInfo.wPagesPerBlock * DeviceInfo.wPageDataSize;
-
-	DeviceInfo.wDeviceWidth = ioread32(FlashReg + DEVICE_WIDTH);
-	DeviceInfo.wDeviceType =
-		((ioread32(FlashReg + DEVICE_WIDTH) > 0) ? 16 : 8);
-
-	DeviceInfo.wDevicesConnected = ioread32(FlashReg + DEVICES_CONNECTED);
-
-	DeviceInfo.wSpareSkipBytes =
-		ioread32(FlashReg + SPARE_AREA_SKIP_BYTES) *
-		DeviceInfo.wDevicesConnected;
-
-	DeviceInfo.nBitsInPageNumber =
-		(u8)GLOB_Calc_Used_Bits(DeviceInfo.wPagesPerBlock);
-	DeviceInfo.nBitsInPageDataSize =
-		(u8)GLOB_Calc_Used_Bits(DeviceInfo.wPageDataSize);
-	DeviceInfo.nBitsInBlockDataSize =
-		(u8)GLOB_Calc_Used_Bits(DeviceInfo.wBlockDataSize);
-
-	set_ecc_config();
-
-	no_of_planes = ioread32(FlashReg + NUMBER_OF_PLANES) &
-		NUMBER_OF_PLANES__VALUE;
-
-	switch (no_of_planes) {
-	case 0:
-	case 1:
-	case 3:
-	case 7:
-		DeviceInfo.bPlaneNum = no_of_planes + 1;
-		break;
-	default:
-		status = FAIL;
-		break;
-	}
-
-	find_valid_banks();
-
-	detect_partition_feature();
-
-	dump_device_info();
-
-	return status;
-}
-
-u16 NAND_UnlockArrayAll(void)
-{
-	u64 start_addr, end_addr;
-
-	nand_dbg_print(NAND_DBG_TRACE, "%s, Line %d, Function: %s\n",
-		       __FILE__, __LINE__, __func__);
-
-	start_addr = 0;
-	end_addr = ((u64)DeviceInfo.wBlockSize *
-		(DeviceInfo.wTotalBlocks - 1)) >>
-		DeviceInfo.nBitsInPageDataSize;
-
-	index_addr((u32)(MODE_10 | (u32)start_addr), 0x10);
-	index_addr((u32)(MODE_10 | (u32)end_addr), 0x11);
-
-	return PASS;
-}
-
-void NAND_LLD_Enable_Disable_Interrupts(u16 INT_ENABLE)
-{
-	nand_dbg_print(NAND_DBG_TRACE, "%s, Line %d, Function: %s\n",
-		       __FILE__, __LINE__, __func__);
-
-	if (INT_ENABLE)
-		iowrite32(1, FlashReg + GLOBAL_INT_ENABLE);
-	else
-		iowrite32(0, FlashReg + GLOBAL_INT_ENABLE);
-}
-
-u16 NAND_Erase_Block(u32 block)
-{
-	u16 status = PASS;
-	u64 flash_add;
-	u16 flash_bank;
-	u32 intr_status = 0;
-	u32 intr_status_addresses[4] = {INTR_STATUS0,
-		INTR_STATUS1, INTR_STATUS2, INTR_STATUS3};
-
-	nand_dbg_print(NAND_DBG_TRACE, "%s, Line %d, Function: %s\n",
-		       __FILE__, __LINE__, __func__);
-
-	flash_add = (u64)(block % (DeviceInfo.wTotalBlocks / totalUsedBanks))
-		* DeviceInfo.wBlockDataSize;
-
-	flash_bank = block / (DeviceInfo.wTotalBlocks / totalUsedBanks);
-
-	if (block >= DeviceInfo.wTotalBlocks)
-		status = FAIL;
-
-	if (status == PASS) {
-		intr_status = intr_status_addresses[flash_bank];
-
-		iowrite32(INTR_STATUS0__ERASE_COMP | INTR_STATUS0__ERASE_FAIL,
-			FlashReg + intr_status);
-
-		index_addr((u32)(MODE_10 | (flash_bank << 24) |
-			(flash_add >> DeviceInfo.nBitsInPageDataSize)), 1);
-
-		while (!(ioread32(FlashReg + intr_status) &
-			(INTR_STATUS0__ERASE_COMP | INTR_STATUS0__ERASE_FAIL)))
-			;
-
-		if (ioread32(FlashReg + intr_status) &
-			INTR_STATUS0__ERASE_FAIL)
-			status = FAIL;
-
-		iowrite32(INTR_STATUS0__ERASE_COMP | INTR_STATUS0__ERASE_FAIL,
-			FlashReg + intr_status);
-	}
-
-	return status;
-}
-
-static u32 Boundary_Check_Block_Page(u32 block, u16 page,
-						u16 page_count)
-{
-	u32 status = PASS;
-
-	if (block >= DeviceInfo.wTotalBlocks)
-		status = FAIL;
-
-	if (page + page_count > DeviceInfo.wPagesPerBlock)
-		status = FAIL;
-
-	return status;
-}
-
-u16 NAND_Read_Page_Spare(u8 *read_data, u32 block, u16 page,
-			    u16 page_count)
-{
-	u32 status = PASS;
-	u32 i;
-	u64 flash_add;
-	u32 PageSpareSize = DeviceInfo.wPageSpareSize;
-	u32 spareFlagBytes = DeviceInfo.wNumPageSpareFlag;
-	u32 flash_bank;
-	u32 intr_status = 0;
-	u32 intr_status_addresses[4] = {INTR_STATUS0,
-		INTR_STATUS1, INTR_STATUS2, INTR_STATUS3};
-	u8 *page_spare = buf_read_page_spare;
-
-	if (block >= DeviceInfo.wTotalBlocks) {
-		printk(KERN_ERR "block too big: %d\n", (int)block);
-		status = FAIL;
-	}
-
-	if (page >= DeviceInfo.wPagesPerBlock) {
-		printk(KERN_ERR "page too big: %d\n", page);
-		status = FAIL;
-	}
-
-	if (page_count > 1) {
-		printk(KERN_ERR "page count too big: %d\n", page_count);
-		status = FAIL;
-	}
-
-	flash_add = (u64)(block % (DeviceInfo.wTotalBlocks / totalUsedBanks))
-		* DeviceInfo.wBlockDataSize +
-		(u64)page * DeviceInfo.wPageDataSize;
-
-	flash_bank = block / (DeviceInfo.wTotalBlocks / totalUsedBanks);
-
-	if (status == PASS) {
-		intr_status = intr_status_addresses[flash_bank];
-		iowrite32(ioread32(FlashReg + intr_status),
-			FlashReg + intr_status);
-
-		index_addr((u32)(MODE_10 | (flash_bank << 24) |
-			(flash_add >> DeviceInfo.nBitsInPageDataSize)),
-			0x41);
-		index_addr((u32)(MODE_10 | (flash_bank << 24) |
-			(flash_add >> DeviceInfo.nBitsInPageDataSize)),
-			0x2000 | page_count);
-		while (!(ioread32(FlashReg + intr_status) &
-			INTR_STATUS0__LOAD_COMP))
-			;
-
-		iowrite32((u32)(MODE_01 | (flash_bank << 24) |
-			(flash_add >> DeviceInfo.nBitsInPageDataSize)),
-			FlashMem);
-
-		for (i = 0; i < (PageSpareSize / 4); i++)
-			*((u32 *)page_spare + i) =
-					ioread32(FlashMem + 0x10);
-
-		if (enable_ecc) {
-			for (i = 0; i < spareFlagBytes; i++)
-				read_data[i] =
-					page_spare[PageSpareSize -
-						spareFlagBytes + i];
-			for (i = 0; i < (PageSpareSize - spareFlagBytes); i++)
-				read_data[spareFlagBytes + i] =
-							page_spare[i];
-		} else {
-			for (i = 0; i < PageSpareSize; i++)
-				read_data[i] = page_spare[i];
-		}
-
-		index_addr((u32)(MODE_10 | (flash_bank << 24) |
-			(flash_add >> DeviceInfo.nBitsInPageDataSize)), 0x42);
-	}
-
-	return status;
-}
-
-/* No use function. Should be removed later */
-u16 NAND_Write_Page_Spare(u8 *write_data, u32 block, u16 page,
-			     u16 page_count)
-{
-	printk(KERN_ERR
-	       "Error! This function (NAND_Write_Page_Spare) should never"
-		" be called!\n");
-	return ERR;
-}
-
-/* op value:  0 - DDMA read;  1 - DDMA write */
-static void ddma_trans(u8 *data, u64 flash_add,
-			u32 flash_bank, int op, u32 numPages)
-{
-	u32 data_addr;
-
-	/* Map virtual address to bus address for DDMA */
-	data_addr = virt_to_bus(data);
-
-	index_addr((u32)(MODE_10 | (flash_bank << 24) |
-		(flash_add >> DeviceInfo.nBitsInPageDataSize)),
-		(u16)(2 << 12) | (op << 8) | numPages);
-
-	index_addr((u32)(MODE_10 | (flash_bank << 24) |
-		((u16)(0x0FFFF & (data_addr >> 16)) << 8)),
-		(u16)(2 << 12) | (2 << 8) | 0);
-
-	index_addr((u32)(MODE_10 | (flash_bank << 24) |
-		((u16)(0x0FFFF & data_addr) << 8)),
-		(u16)(2 << 12) | (3 << 8) | 0);
-
-	index_addr((u32)(MODE_10 | (flash_bank << 24) |
-		(1 << 16) | (0x40 << 8)),
-		(u16)(2 << 12) | (4 << 8) | 0);
-}
-
-/* If data in buf are all 0xff, then return 1; otherwise return 0 */
-static int check_all_1(u8 *buf)
-{
-	int i, j, cnt;
-
-	for (i = 0; i < DeviceInfo.wPageDataSize; i++) {
-		if (buf[i] != 0xff) {
-			cnt = 0;
-			nand_dbg_print(NAND_DBG_WARN,
-				"the first non-0xff data byte is: %d\n", i);
-			for (j = i; j < DeviceInfo.wPageDataSize; j++) {
-				nand_dbg_print(NAND_DBG_WARN, "0x%x ", buf[j]);
-				cnt++;
-				if (cnt > 8)
-					break;
-			}
-			nand_dbg_print(NAND_DBG_WARN, "\n");
-			return 0;
-		}
-	}
-
-	return 1;
-}
-
-static int do_ecc_new(unsigned long bank, u8 *buf,
-				u32 block, u16 page)
-{
-	int status = PASS;
-	u16 err_page = 0;
-	u16 err_byte;
-	u8 err_sect;
-	u8 err_dev;
-	u16 err_fix_info;
-	u16 err_addr;
-	u32 ecc_sect_size;
-	u8 *err_pos;
-	u32 err_page_addr[4] = {ERR_PAGE_ADDR0,
-		ERR_PAGE_ADDR1, ERR_PAGE_ADDR2, ERR_PAGE_ADDR3};
-
-	ecc_sect_size = ECC_SECTOR_SIZE * (DeviceInfo.wDevicesConnected);
-
-	do {
-		err_page = ioread32(FlashReg + err_page_addr[bank]);
-		err_addr = ioread32(FlashReg + ECC_ERROR_ADDRESS);
-		err_byte = err_addr & ECC_ERROR_ADDRESS__OFFSET;
-		err_sect = ((err_addr & ECC_ERROR_ADDRESS__SECTOR_NR) >> 12);
-		err_fix_info = ioread32(FlashReg + ERR_CORRECTION_INFO);
-		err_dev = ((err_fix_info & ERR_CORRECTION_INFO__DEVICE_NR)
-			>> 8);
-		if (err_fix_info & ERR_CORRECTION_INFO__ERROR_TYPE) {
-			nand_dbg_print(NAND_DBG_WARN,
-				"%s, Line %d Uncorrectable ECC error "
-				"when read block %d page %d."
-				"PTN_INTR register: 0x%x "
-				"err_page: %d, err_sect: %d, err_byte: %d, "
-				"err_dev: %d, ecc_sect_size: %d, "
-				"err_fix_info: 0x%x\n",
-				__FILE__, __LINE__, block, page,
-				ioread32(FlashReg + PTN_INTR),
-				err_page, err_sect, err_byte, err_dev,
-				ecc_sect_size, (u32)err_fix_info);
-
-			if (check_all_1(buf))
-				nand_dbg_print(NAND_DBG_WARN, "%s, Line %d"
-					       "All 0xff!\n",
-					       __FILE__, __LINE__);
-			else
-				nand_dbg_print(NAND_DBG_WARN, "%s, Line %d"
-					       "Not all 0xff!\n",
-					       __FILE__, __LINE__);
-			status = FAIL;
-		} else {
-			nand_dbg_print(NAND_DBG_WARN,
-				"%s, Line %d Found ECC error "
-				"when read block %d page %d."
-				"err_page: %d, err_sect: %d, err_byte: %d, "
-				"err_dev: %d, ecc_sect_size: %d, "
-				"err_fix_info: 0x%x\n",
-				__FILE__, __LINE__, block, page,
-				err_page, err_sect, err_byte, err_dev,
-				ecc_sect_size, (u32)err_fix_info);
-			if (err_byte < ECC_SECTOR_SIZE) {
-				err_pos = buf +
-					(err_page - page) *
-					DeviceInfo.wPageDataSize +
-					err_sect * ecc_sect_size +
-					err_byte *
-					DeviceInfo.wDevicesConnected +
-					err_dev;
-
-				*err_pos ^= err_fix_info &
-					ERR_CORRECTION_INFO__BYTEMASK;
-			}
-		}
-	} while (!(err_fix_info & ERR_CORRECTION_INFO__LAST_ERR_INFO));
-
-	return status;
-}
-
-u16 NAND_Read_Page_Main_Polling(u8 *read_data,
-		u32 block, u16 page, u16 page_count)
-{
-	u32 status = PASS;
-	u64 flash_add;
-	u32 intr_status = 0;
-	u32 flash_bank;
-	u32 intr_status_addresses[4] = {INTR_STATUS0,
-		INTR_STATUS1, INTR_STATUS2, INTR_STATUS3};
-	u8 *read_data_l;
-
-	nand_dbg_print(NAND_DBG_WARN, "%s, Line %d, Function: %s\n",
-		       __FILE__, __LINE__, __func__);
-
-	status = Boundary_Check_Block_Page(block, page, page_count);
-	if (status != PASS)
-		return status;
-
-	flash_add = (u64)(block % (DeviceInfo.wTotalBlocks / totalUsedBanks))
-		* DeviceInfo.wBlockDataSize +
-		(u64)page * DeviceInfo.wPageDataSize;
-	flash_bank = block / (DeviceInfo.wTotalBlocks / totalUsedBanks);
-
-	iowrite32(0, FlashReg + TRANSFER_SPARE_REG);
-
-	intr_status = intr_status_addresses[flash_bank];
-	iowrite32(ioread32(FlashReg + intr_status), FlashReg + intr_status);
-
-	if (page_count > 1) {
-		read_data_l = read_data;
-		while (page_count > MAX_PAGES_PER_RW) {
-			if (ioread32(FlashReg + MULTIPLANE_OPERATION))
-				status = NAND_Multiplane_Read(read_data_l,
-					block, page, MAX_PAGES_PER_RW);
-			else
-				status = NAND_Pipeline_Read_Ahead_Polling(
-					read_data_l, block, page,
-					MAX_PAGES_PER_RW);
-
-			if (status == FAIL)
-				return status;
-
-			read_data_l += DeviceInfo.wPageDataSize *
-					MAX_PAGES_PER_RW;
-			page_count -= MAX_PAGES_PER_RW;
-			page += MAX_PAGES_PER_RW;
-		}
-		if (ioread32(FlashReg + MULTIPLANE_OPERATION))
-			status = NAND_Multiplane_Read(read_data_l,
-					block, page, page_count);
-		else
-			status = NAND_Pipeline_Read_Ahead_Polling(
-					read_data_l, block, page, page_count);
-
-		return status;
-	}
-
-	iowrite32(1, FlashReg + DMA_ENABLE);
-	while (!(ioread32(FlashReg + DMA_ENABLE) & DMA_ENABLE__FLAG))
-		;
-
-	iowrite32(0, FlashReg + TRANSFER_SPARE_REG);
-	iowrite32(ioread32(FlashReg + intr_status), FlashReg + intr_status);
-
-	ddma_trans(read_data, flash_add, flash_bank, 0, 1);
-
-	if (enable_ecc) {
-		while (!(ioread32(FlashReg + intr_status) &
-			(INTR_STATUS0__ECC_TRANSACTION_DONE |
-			INTR_STATUS0__ECC_ERR)))
-			;
-
-		if (ioread32(FlashReg + intr_status) &
-			INTR_STATUS0__ECC_ERR) {
-			iowrite32(INTR_STATUS0__ECC_ERR,
-				FlashReg + intr_status);
-			status = do_ecc_new(flash_bank, read_data,
-					block, page);
-		}
-
-		if (ioread32(FlashReg + intr_status) &
-			INTR_STATUS0__ECC_TRANSACTION_DONE &
-			INTR_STATUS0__ECC_ERR)
-			iowrite32(INTR_STATUS0__ECC_TRANSACTION_DONE |
-				INTR_STATUS0__ECC_ERR,
-				FlashReg + intr_status);
-		else if (ioread32(FlashReg + intr_status) &
-			INTR_STATUS0__ECC_TRANSACTION_DONE)
-			iowrite32(INTR_STATUS0__ECC_TRANSACTION_DONE,
-				FlashReg + intr_status);
-		else if (ioread32(FlashReg + intr_status) &
-			INTR_STATUS0__ECC_ERR)
-			iowrite32(INTR_STATUS0__ECC_ERR,
-				FlashReg + intr_status);
-	} else {
-		while (!(ioread32(FlashReg + intr_status) &
-			INTR_STATUS0__DMA_CMD_COMP))
-			;
-		iowrite32(INTR_STATUS0__DMA_CMD_COMP, FlashReg + intr_status);
-	}
-
-	iowrite32(ioread32(FlashReg + intr_status), FlashReg + intr_status);
-
-	iowrite32(0, FlashReg + DMA_ENABLE);
-	while ((ioread32(FlashReg + DMA_ENABLE) & DMA_ENABLE__FLAG))
-		;
-
-	return status;
-}
-
-u16 NAND_Pipeline_Read_Ahead_Polling(u8 *read_data,
-			u32 block, u16 page, u16 page_count)
-{
-	u32 status = PASS;
-	u32 NumPages = page_count;
-	u64 flash_add;
-	u32 flash_bank;
-	u32 intr_status = 0;
-	u32 intr_status_addresses[4] = {INTR_STATUS0,
-		INTR_STATUS1, INTR_STATUS2, INTR_STATUS3};
-	u32 ecc_done_OR_dma_comp;
-
-	nand_dbg_print(NAND_DBG_WARN, "%s, Line %d, Function: %s\n",
-		       __FILE__, __LINE__, __func__);
-
-	status = Boundary_Check_Block_Page(block, page, page_count);
-
-	if (page_count < 2)
-		status = FAIL;
-
-	flash_add = (u64)(block % (DeviceInfo.wTotalBlocks / totalUsedBanks))
-		*DeviceInfo.wBlockDataSize +
-		(u64)page * DeviceInfo.wPageDataSize;
-
-	flash_bank = block / (DeviceInfo.wTotalBlocks / totalUsedBanks);
-
-	if (status == PASS) {
-		intr_status = intr_status_addresses[flash_bank];
-		iowrite32(ioread32(FlashReg + intr_status),
-			FlashReg + intr_status);
-
-		iowrite32(1, FlashReg + DMA_ENABLE);
-		while (!(ioread32(FlashReg + DMA_ENABLE) & DMA_ENABLE__FLAG))
-			;
-
-		iowrite32(0, FlashReg + TRANSFER_SPARE_REG);
-
-		index_addr((u32)(MODE_10 | (flash_bank << 24) |
-			(flash_add >> DeviceInfo.nBitsInPageDataSize)), 0x42);
-		ddma_trans(read_data, flash_add, flash_bank, 0, NumPages);
-
-		ecc_done_OR_dma_comp = 0;
-		while (1) {
-			if (enable_ecc) {
-				while (!ioread32(FlashReg + intr_status))
-					;
-
-				if (ioread32(FlashReg + intr_status) &
-					INTR_STATUS0__ECC_ERR) {
-					iowrite32(INTR_STATUS0__ECC_ERR,
-						FlashReg + intr_status);
-					status = do_ecc_new(flash_bank,
-						read_data, block, page);
-				} else if (ioread32(FlashReg + intr_status) &
-					INTR_STATUS0__DMA_CMD_COMP) {
-					iowrite32(INTR_STATUS0__DMA_CMD_COMP,
-						FlashReg + intr_status);
-
-					if (1 == ecc_done_OR_dma_comp)
-						break;
-
-					ecc_done_OR_dma_comp = 1;
-				} else if (ioread32(FlashReg + intr_status) &
-					INTR_STATUS0__ECC_TRANSACTION_DONE) {
-					iowrite32(
-					INTR_STATUS0__ECC_TRANSACTION_DONE,
-					FlashReg + intr_status);
-
-					if (1 == ecc_done_OR_dma_comp)
-						break;
-
-					ecc_done_OR_dma_comp = 1;
-				}
-			} else {
-				while (!(ioread32(FlashReg + intr_status) &
-					INTR_STATUS0__DMA_CMD_COMP))
-					;
-
-				iowrite32(INTR_STATUS0__DMA_CMD_COMP,
-					FlashReg + intr_status);
-				break;
-			}
-
-			iowrite32((~INTR_STATUS0__ECC_ERR) &
-				(~INTR_STATUS0__ECC_TRANSACTION_DONE) &
-				(~INTR_STATUS0__DMA_CMD_COMP),
-				FlashReg + intr_status);
-
-		}
-
-		iowrite32(ioread32(FlashReg + intr_status),
-			FlashReg + intr_status);
-
-		iowrite32(0, FlashReg + DMA_ENABLE);
-
-		while ((ioread32(FlashReg + DMA_ENABLE) & DMA_ENABLE__FLAG))
-			;
-	}
-	return status;
-}
-
-u16 NAND_Read_Page_Main(u8 *read_data, u32 block, u16 page,
-			   u16 page_count)
-{
-	u32 status = PASS;
-	u64 flash_add;
-	u32 intr_status = 0;
-	u32 flash_bank;
-	u32 intr_status_addresses[4] = {INTR_STATUS0,
-		INTR_STATUS1, INTR_STATUS2, INTR_STATUS3};
-	int ret;
-	u8 *read_data_l;
-
-	nand_dbg_print(NAND_DBG_DEBUG, "%s, Line %d, Function: %s\n",
-		       __FILE__, __LINE__, __func__);
-
-	status = Boundary_Check_Block_Page(block, page, page_count);
-	if (status != PASS)
-		return status;
-
-	flash_add = (u64)(block % (DeviceInfo.wTotalBlocks / totalUsedBanks))
-		* DeviceInfo.wBlockDataSize +
-		(u64)page * DeviceInfo.wPageDataSize;
-	flash_bank = block / (DeviceInfo.wTotalBlocks / totalUsedBanks);
-
-	iowrite32(0, FlashReg + TRANSFER_SPARE_REG);
-
-	intr_status = intr_status_addresses[flash_bank];
-	iowrite32(ioread32(FlashReg + intr_status), FlashReg + intr_status);
-
-	if (page_count > 1) {
-		read_data_l = read_data;
-		while (page_count > MAX_PAGES_PER_RW) {
-			if (ioread32(FlashReg + MULTIPLANE_OPERATION))
-				status = NAND_Multiplane_Read(read_data_l,
-					block, page, MAX_PAGES_PER_RW);
-			else
-				status = NAND_Pipeline_Read_Ahead(
-					read_data_l, block, page,
-					MAX_PAGES_PER_RW);
-
-			if (status == FAIL)
-				return status;
-
-			read_data_l += DeviceInfo.wPageDataSize *
-					MAX_PAGES_PER_RW;
-			page_count -= MAX_PAGES_PER_RW;
-			page += MAX_PAGES_PER_RW;
-		}
-		if (ioread32(FlashReg + MULTIPLANE_OPERATION))
-			status = NAND_Multiplane_Read(read_data_l,
-					block, page, page_count);
-		else
-			status = NAND_Pipeline_Read_Ahead(
-					read_data_l, block, page, page_count);
-
-		return status;
-	}
-
-	iowrite32(1, FlashReg + DMA_ENABLE);
-	while (!(ioread32(FlashReg + DMA_ENABLE) & DMA_ENABLE__FLAG))
-		;
-
-	iowrite32(0, FlashReg + TRANSFER_SPARE_REG);
-	iowrite32(ioread32(FlashReg + intr_status), FlashReg + intr_status);
-
-	/* Fill the mrst_nand_info structure */
-	info.state = INT_READ_PAGE_MAIN;
-	info.read_data = read_data;
-	info.flash_bank = flash_bank;
-	info.block = block;
-	info.page = page;
-	info.ret = PASS;
-
-	ddma_trans(read_data, flash_add, flash_bank, 0, 1);
-
-	iowrite32(1, FlashReg + GLOBAL_INT_ENABLE); /* Enable Interrupt */
-
-	ret = wait_for_completion_timeout(&info.complete, 10 * HZ);
-	if (!ret) {
-		printk(KERN_ERR "Wait for completion timeout "
-			"in %s, Line %d\n", __FILE__, __LINE__);
-		status = ERR;
-	} else {
-		status = info.ret;
-	}
-
-	iowrite32(ioread32(FlashReg + intr_status), FlashReg + intr_status);
-
-	iowrite32(0, FlashReg + DMA_ENABLE);
-	while ((ioread32(FlashReg + DMA_ENABLE) & DMA_ENABLE__FLAG))
-		;
-
-	return status;
-}
-
-void Conv_Spare_Data_Log2Phy_Format(u8 *data)
-{
-	int i;
-	const u32 spareFlagBytes = DeviceInfo.wNumPageSpareFlag;
-	const u32 PageSpareSize  = DeviceInfo.wPageSpareSize;
-
-	if (enable_ecc) {
-		for (i = spareFlagBytes - 1; i >= 0; i--)
-			data[PageSpareSize - spareFlagBytes + i] = data[i];
-	}
-}
-
-void Conv_Spare_Data_Phy2Log_Format(u8 *data)
-{
-	int i;
-	const u32 spareFlagBytes = DeviceInfo.wNumPageSpareFlag;
-	const u32 PageSpareSize = DeviceInfo.wPageSpareSize;
-
-	if (enable_ecc) {
-		for (i = 0; i < spareFlagBytes; i++)
-			data[i] = data[PageSpareSize - spareFlagBytes + i];
-	}
-}
-
-
-void Conv_Main_Spare_Data_Log2Phy_Format(u8 *data, u16 page_count)
-{
-	const u32 PageSize = DeviceInfo.wPageSize;
-	const u32 PageDataSize = DeviceInfo.wPageDataSize;
-	const u32 eccBytes = DeviceInfo.wECCBytesPerSector;
-	const u32 spareSkipBytes = DeviceInfo.wSpareSkipBytes;
-	const u32 spareFlagBytes = DeviceInfo.wNumPageSpareFlag;
-	u32 eccSectorSize;
-	u32 page_offset;
-	int i, j;
-
-	eccSectorSize = ECC_SECTOR_SIZE * (DeviceInfo.wDevicesConnected);
-	if (enable_ecc) {
-		while (page_count > 0) {
-			page_offset = (page_count - 1) * PageSize;
-			j = (DeviceInfo.wPageDataSize / eccSectorSize);
-			for (i = spareFlagBytes - 1; i >= 0; i--)
-				data[page_offset +
-					(eccSectorSize + eccBytes) * j + i] =
-					data[page_offset + PageDataSize + i];
-			for (j--; j >= 1; j--) {
-				for (i = eccSectorSize - 1; i >= 0; i--)
-					data[page_offset +
-					(eccSectorSize + eccBytes) * j + i] =
-						data[page_offset +
-						eccSectorSize * j + i];
-			}
-			for (i = (PageSize - spareSkipBytes) - 1;
-				i >= PageDataSize; i--)
-				data[page_offset + i + spareSkipBytes] =
-					data[page_offset + i];
-			page_count--;
-		}
-	}
-}
-
-void Conv_Main_Spare_Data_Phy2Log_Format(u8 *data, u16 page_count)
-{
-	const u32 PageSize = DeviceInfo.wPageSize;
-	const u32 PageDataSize = DeviceInfo.wPageDataSize;
-	const u32 eccBytes = DeviceInfo.wECCBytesPerSector;
-	const u32 spareSkipBytes = DeviceInfo.wSpareSkipBytes;
-	const u32 spareFlagBytes = DeviceInfo.wNumPageSpareFlag;
-	u32 eccSectorSize;
-	u32 page_offset;
-	int i, j;
-
-	eccSectorSize = ECC_SECTOR_SIZE * (DeviceInfo.wDevicesConnected);
-	if (enable_ecc) {
-		while (page_count > 0) {
-			page_offset = (page_count - 1) * PageSize;
-			for (i = PageDataSize;
-				i < PageSize - spareSkipBytes;
-				i++)
-				data[page_offset + i] =
-					data[page_offset + i +
-					spareSkipBytes];
-			for (j = 1;
-			j < DeviceInfo.wPageDataSize / eccSectorSize;
-			j++) {
-				for (i = 0; i < eccSectorSize; i++)
-					data[page_offset +
-					eccSectorSize * j + i] =
-						data[page_offset +
-						(eccSectorSize + eccBytes) * j
-						+ i];
-			}
-			for (i = 0; i < spareFlagBytes; i++)
-				data[page_offset + PageDataSize + i] =
-					data[page_offset +
-					(eccSectorSize + eccBytes) * j + i];
-			page_count--;
-		}
-	}
-}
-
-/* Un-tested function */
-u16 NAND_Multiplane_Read(u8 *read_data, u32 block, u16 page,
-			    u16 page_count)
-{
-	u32 status = PASS;
-	u32 NumPages = page_count;
-	u64 flash_add;
-	u32 flash_bank;
-	u32 intr_status = 0;
-	u32 intr_status_addresses[4] = {INTR_STATUS0,
-		INTR_STATUS1, INTR_STATUS2, INTR_STATUS3};
-	u32 ecc_done_OR_dma_comp;
-
-	nand_dbg_print(NAND_DBG_WARN, "%s, Line %d, Function: %s\n",
-		       __FILE__, __LINE__, __func__);
-
-	status = Boundary_Check_Block_Page(block, page, page_count);
-
-	flash_add = (u64)(block % (DeviceInfo.wTotalBlocks / totalUsedBanks))
-		* DeviceInfo.wBlockDataSize +
-		(u64)page * DeviceInfo.wPageDataSize;
-
-	flash_bank = block / (DeviceInfo.wTotalBlocks / totalUsedBanks);
-
-	if (status == PASS) {
-		intr_status = intr_status_addresses[flash_bank];
-		iowrite32(ioread32(FlashReg + intr_status),
-			FlashReg + intr_status);
-
-		iowrite32(0, FlashReg + TRANSFER_SPARE_REG);
-		iowrite32(0x01, FlashReg + MULTIPLANE_OPERATION);
-
-		iowrite32(1, FlashReg + DMA_ENABLE);
-		while (!(ioread32(FlashReg + DMA_ENABLE) & DMA_ENABLE__FLAG))
-			;
-		index_addr((u32)(MODE_10 | (flash_bank << 24) |
-			(flash_add >> DeviceInfo.nBitsInPageDataSize)), 0x42);
-		ddma_trans(read_data, flash_add, flash_bank, 0, NumPages);
-
-		ecc_done_OR_dma_comp = 0;
-		while (1) {
-			if (enable_ecc) {
-				while (!ioread32(FlashReg + intr_status))
-					;
-
-				if (ioread32(FlashReg + intr_status) &
-					INTR_STATUS0__ECC_ERR) {
-					iowrite32(INTR_STATUS0__ECC_ERR,
-						FlashReg + intr_status);
-					status = do_ecc_new(flash_bank,
-						read_data, block, page);
-				} else if (ioread32(FlashReg + intr_status) &
-					INTR_STATUS0__DMA_CMD_COMP) {
-					iowrite32(INTR_STATUS0__DMA_CMD_COMP,
-						FlashReg + intr_status);
-
-					if (1 == ecc_done_OR_dma_comp)
-						break;
-
-					ecc_done_OR_dma_comp = 1;
-				} else if (ioread32(FlashReg + intr_status) &
-					INTR_STATUS0__ECC_TRANSACTION_DONE) {
-					iowrite32(
-					INTR_STATUS0__ECC_TRANSACTION_DONE,
-					FlashReg + intr_status);
-
-					if (1 == ecc_done_OR_dma_comp)
-						break;
-
-					ecc_done_OR_dma_comp = 1;
-				}
-			} else {
-				while (!(ioread32(FlashReg + intr_status) &
-					INTR_STATUS0__DMA_CMD_COMP))
-					;
-				iowrite32(INTR_STATUS0__DMA_CMD_COMP,
-					FlashReg + intr_status);
-				break;
-			}
-
-			iowrite32((~INTR_STATUS0__ECC_ERR) &
-				(~INTR_STATUS0__ECC_TRANSACTION_DONE) &
-				(~INTR_STATUS0__DMA_CMD_COMP),
-				FlashReg + intr_status);
-
-		}
-
-		iowrite32(ioread32(FlashReg + intr_status),
-			FlashReg + intr_status);
-
-		iowrite32(0, FlashReg + DMA_ENABLE);
-
-		while ((ioread32(FlashReg + DMA_ENABLE) & DMA_ENABLE__FLAG))
-			;
-
-		iowrite32(0, FlashReg + MULTIPLANE_OPERATION);
-	}
-
-	return status;
-}
-
-u16 NAND_Pipeline_Read_Ahead(u8 *read_data, u32 block,
-				u16 page, u16 page_count)
-{
-	u32 status = PASS;
-	u32 NumPages = page_count;
-	u64 flash_add;
-	u32 flash_bank;
-	u32 intr_status = 0;
-	u32 intr_status_addresses[4] = {INTR_STATUS0,
-		INTR_STATUS1, INTR_STATUS2, INTR_STATUS3};
-	int ret;
-
-	nand_dbg_print(NAND_DBG_DEBUG, "%s, Line %d, Function: %s\n",
-		       __FILE__, __LINE__, __func__);
-
-	status = Boundary_Check_Block_Page(block, page, page_count);
-
-	if (page_count < 2)
-		status = FAIL;
-
-	if (status != PASS)
-		return status;
-
-	flash_add = (u64)(block % (DeviceInfo.wTotalBlocks / totalUsedBanks))
-		*DeviceInfo.wBlockDataSize +
-		(u64)page * DeviceInfo.wPageDataSize;
-
-	flash_bank = block / (DeviceInfo.wTotalBlocks / totalUsedBanks);
-
-	intr_status = intr_status_addresses[flash_bank];
-	iowrite32(ioread32(FlashReg + intr_status), FlashReg + intr_status);
-
-	iowrite32(1, FlashReg + DMA_ENABLE);
-	while (!(ioread32(FlashReg + DMA_ENABLE) & DMA_ENABLE__FLAG))
-		;
-
-	iowrite32(0, FlashReg + TRANSFER_SPARE_REG);
-
-	/* Fill the mrst_nand_info structure */
-	info.state = INT_PIPELINE_READ_AHEAD;
-	info.read_data = read_data;
-	info.flash_bank = flash_bank;
-	info.block = block;
-	info.page = page;
-	info.ret = PASS;
-
-	index_addr((u32)(MODE_10 | (flash_bank << 24) |
-		(flash_add >> DeviceInfo.nBitsInPageDataSize)), 0x42);
-
-	ddma_trans(read_data, flash_add, flash_bank, 0, NumPages);
-
-	iowrite32(1, FlashReg + GLOBAL_INT_ENABLE); /* Enable Interrupt */
-
-	ret = wait_for_completion_timeout(&info.complete, 10 * HZ);
-	if (!ret) {
-		printk(KERN_ERR "Wait for completion timeout "
-			"in %s, Line %d\n", __FILE__, __LINE__);
-		status = ERR;
-	} else {
-		status = info.ret;
-	}
-
-	iowrite32(ioread32(FlashReg + intr_status), FlashReg + intr_status);
-
-	iowrite32(0, FlashReg + DMA_ENABLE);
-
-	while ((ioread32(FlashReg + DMA_ENABLE) & DMA_ENABLE__FLAG))
-		;
-
-	return status;
-}
-
-
-u16 NAND_Write_Page_Main(u8 *write_data, u32 block, u16 page,
-			    u16 page_count)
-{
-	u32 status = PASS;
-	u64 flash_add;
-	u32 intr_status = 0;
-	u32 flash_bank;
-	u32 intr_status_addresses[4] = {INTR_STATUS0,
-		INTR_STATUS1, INTR_STATUS2, INTR_STATUS3};
-	int ret;
-	u8 *write_data_l;
-
-	nand_dbg_print(NAND_DBG_DEBUG, "%s, Line %d, Function: %s\n",
-		       __FILE__, __LINE__, __func__);
-
-	status = Boundary_Check_Block_Page(block, page, page_count);
-	if (status != PASS)
-		return status;
-
-	flash_add = (u64)(block % (DeviceInfo.wTotalBlocks / totalUsedBanks))
-		* DeviceInfo.wBlockDataSize +
-		(u64)page * DeviceInfo.wPageDataSize;
-
-	flash_bank = block / (DeviceInfo.wTotalBlocks / totalUsedBanks);
-
-	intr_status = intr_status_addresses[flash_bank];
-
-	iowrite32(0, FlashReg + TRANSFER_SPARE_REG);
-
-	iowrite32(INTR_STATUS0__PROGRAM_COMP |
-		INTR_STATUS0__PROGRAM_FAIL, FlashReg + intr_status);
-
-	if (page_count > 1) {
-		write_data_l = write_data;
-		while (page_count > MAX_PAGES_PER_RW) {
-			if (ioread32(FlashReg + MULTIPLANE_OPERATION))
-				status = NAND_Multiplane_Write(write_data_l,
-					block, page, MAX_PAGES_PER_RW);
-			else
-				status = NAND_Pipeline_Write_Ahead(
-					write_data_l, block, page,
-					MAX_PAGES_PER_RW);
-			if (status == FAIL)
-				return status;
-
-			write_data_l += DeviceInfo.wPageDataSize *
-					MAX_PAGES_PER_RW;
-			page_count -= MAX_PAGES_PER_RW;
-			page += MAX_PAGES_PER_RW;
-		}
-		if (ioread32(FlashReg + MULTIPLANE_OPERATION))
-			status = NAND_Multiplane_Write(write_data_l,
-				block, page, page_count);
-		else
-			status = NAND_Pipeline_Write_Ahead(write_data_l,
-				block, page, page_count);
-
-		return status;
-	}
-
-	iowrite32(1, FlashReg + DMA_ENABLE);
-	while (!(ioread32(FlashReg + DMA_ENABLE) & DMA_ENABLE__FLAG))
-		;
-
-	iowrite32(0, FlashReg + TRANSFER_SPARE_REG);
-
-	iowrite32(ioread32(FlashReg + intr_status), FlashReg + intr_status);
-
-	/* Fill the mrst_nand_info structure */
-	info.state = INT_WRITE_PAGE_MAIN;
-	info.write_data = write_data;
-	info.flash_bank = flash_bank;
-	info.block = block;
-	info.page = page;
-	info.ret = PASS;
-
-	ddma_trans(write_data, flash_add, flash_bank, 1, 1);
-
-	iowrite32(1, FlashReg + GLOBAL_INT_ENABLE); /* Enable interrupt */
-
-	ret = wait_for_completion_timeout(&info.complete, 10 * HZ);
-	if (!ret) {
-		printk(KERN_ERR "Wait for completion timeout "
-			"in %s, Line %d\n", __FILE__, __LINE__);
-		status = ERR;
-	} else {
-		status = info.ret;
-	}
-
-	iowrite32(ioread32(FlashReg + intr_status), FlashReg + intr_status);
-
-	iowrite32(0, FlashReg + DMA_ENABLE);
-	while (ioread32(FlashReg + DMA_ENABLE) & DMA_ENABLE__FLAG)
-		;
-
-	return status;
-}
-
-void NAND_ECC_Ctrl(int enable)
-{
-	if (enable) {
-		nand_dbg_print(NAND_DBG_WARN,
-			"Will enable ECC in %s, Line %d, Function: %s\n",
-			__FILE__, __LINE__, __func__);
-		iowrite32(1, FlashReg + ECC_ENABLE);
-		enable_ecc = 1;
-	} else {
-		nand_dbg_print(NAND_DBG_WARN,
-			"Will disable ECC in %s, Line %d, Function: %s\n",
-			__FILE__, __LINE__, __func__);
-		iowrite32(0, FlashReg + ECC_ENABLE);
-		enable_ecc = 0;
-	}
-}
-
-u16 NAND_Write_Page_Main_Spare(u8 *write_data, u32 block,
-					u16 page, u16 page_count)
-{
-	u32 status = PASS;
-	u32 i, j, page_num = 0;
-	u32 PageSize = DeviceInfo.wPageSize;
-	u32 PageDataSize = DeviceInfo.wPageDataSize;
-	u32 eccBytes = DeviceInfo.wECCBytesPerSector;
-	u32 spareFlagBytes = DeviceInfo.wNumPageSpareFlag;
-	u32 spareSkipBytes  = DeviceInfo.wSpareSkipBytes;
-	u64 flash_add;
-	u32 eccSectorSize;
-	u32 flash_bank;
-	u32 intr_status = 0;
-	u32 intr_status_addresses[4] = {INTR_STATUS0,
-		INTR_STATUS1, INTR_STATUS2, INTR_STATUS3};
-	u8 *page_main_spare = buf_write_page_main_spare;
-
-	nand_dbg_print(NAND_DBG_WARN, "%s, Line %d, Function: %s\n",
-		       __FILE__, __LINE__, __func__);
-
-	eccSectorSize = ECC_SECTOR_SIZE * (DeviceInfo.wDevicesConnected);
-
-	status = Boundary_Check_Block_Page(block, page, page_count);
-
-	flash_bank = block / (DeviceInfo.wTotalBlocks / totalUsedBanks);
-
-	if (status == PASS) {
-		intr_status = intr_status_addresses[flash_bank];
-
-		iowrite32(1, FlashReg + TRANSFER_SPARE_REG);
-
-		while ((status != FAIL) && (page_count > 0)) {
-			flash_add = (u64)(block %
-			(DeviceInfo.wTotalBlocks / totalUsedBanks)) *
-			DeviceInfo.wBlockDataSize +
-			(u64)page * DeviceInfo.wPageDataSize;
-
-			iowrite32(ioread32(FlashReg + intr_status),
-				FlashReg + intr_status);
-
-			iowrite32((u32)(MODE_01 | (flash_bank << 24) |
-				(flash_add >>
-				DeviceInfo.nBitsInPageDataSize)),
-				FlashMem);
-
-			if (enable_ecc) {
-				for (j = 0;
-				     j <
-				     DeviceInfo.wPageDataSize / eccSectorSize;
-				     j++) {
-					for (i = 0; i < eccSectorSize; i++)
-						page_main_spare[(eccSectorSize +
-								 eccBytes) * j +
-								i] =
-						    write_data[eccSectorSize *
-							       j + i];
-
-					for (i = 0; i < eccBytes; i++)
-						page_main_spare[(eccSectorSize +
-								 eccBytes) * j +
-								eccSectorSize +
-								i] =
-						    write_data[PageDataSize +
-							       spareFlagBytes +
-							       eccBytes * j +
-							       i];
-				}
-
-				for (i = 0; i < spareFlagBytes; i++)
-					page_main_spare[(eccSectorSize +
-							 eccBytes) * j + i] =
-					    write_data[PageDataSize + i];
-
-				for (i = PageSize - 1; i >= PageDataSize +
-							spareSkipBytes; i--)
-					page_main_spare[i] = page_main_spare[i -
-								spareSkipBytes];
-
-				for (i = PageDataSize; i < PageDataSize +
-							spareSkipBytes; i++)
-					page_main_spare[i] = 0xff;
-
-				for (i = 0; i < PageSize / 4; i++)
-					iowrite32(
-					*((u32 *)page_main_spare + i),
-					FlashMem + 0x10);
-			} else {
-
-				for (i = 0; i < PageSize / 4; i++)
-					iowrite32(*((u32 *)write_data + i),
-						FlashMem + 0x10);
-			}
-
-			while (!(ioread32(FlashReg + intr_status) &
-				(INTR_STATUS0__PROGRAM_COMP |
-				INTR_STATUS0__PROGRAM_FAIL)))
-				;
-
-			if (ioread32(FlashReg + intr_status) &
-				INTR_STATUS0__PROGRAM_FAIL)
-				status = FAIL;
-
-			iowrite32(ioread32(FlashReg + intr_status),
-					FlashReg + intr_status);
-
-			page_num++;
-			page_count--;
-			write_data += PageSize;
-		}
-
-		iowrite32(0, FlashReg + TRANSFER_SPARE_REG);
-	}
-
-	return status;
-}
-
-u16 NAND_Read_Page_Main_Spare(u8 *read_data, u32 block, u16 page,
-				 u16 page_count)
-{
-	u32 status = PASS;
-	u32 i, j;
-	u64 flash_add = 0;
-	u32 PageSize = DeviceInfo.wPageSize;
-	u32 PageDataSize = DeviceInfo.wPageDataSize;
-	u32 PageSpareSize = DeviceInfo.wPageSpareSize;
-	u32 eccBytes = DeviceInfo.wECCBytesPerSector;
-	u32 spareFlagBytes = DeviceInfo.wNumPageSpareFlag;
-	u32 spareSkipBytes  = DeviceInfo.wSpareSkipBytes;
-	u32 eccSectorSize;
-	u32 flash_bank;
-	u32 intr_status = 0;
-	u8 *read_data_l = read_data;
-	u32 intr_status_addresses[4] = {INTR_STATUS0,
-		INTR_STATUS1, INTR_STATUS2, INTR_STATUS3};
-	u8 *page_main_spare = buf_read_page_main_spare;
-
-	nand_dbg_print(NAND_DBG_WARN, "%s, Line %d, Function: %s\n",
-		       __FILE__, __LINE__, __func__);
-
-	eccSectorSize = ECC_SECTOR_SIZE * (DeviceInfo.wDevicesConnected);
-
-	status = Boundary_Check_Block_Page(block, page, page_count);
-
-	flash_bank = block / (DeviceInfo.wTotalBlocks / totalUsedBanks);
-
-	if (status == PASS) {
-		intr_status = intr_status_addresses[flash_bank];
-
-		iowrite32(1, FlashReg + TRANSFER_SPARE_REG);
-
-		iowrite32(ioread32(FlashReg + intr_status),
-				FlashReg + intr_status);
-
-		while ((status != FAIL) && (page_count > 0)) {
-			flash_add = (u64)(block %
-				(DeviceInfo.wTotalBlocks / totalUsedBanks))
-				* DeviceInfo.wBlockDataSize +
-				(u64)page * DeviceInfo.wPageDataSize;
-
-			index_addr((u32)(MODE_10 | (flash_bank << 24) |
-				(flash_add >> DeviceInfo.nBitsInPageDataSize)),
-				0x43);
-			index_addr((u32)(MODE_10 | (flash_bank << 24) |
-				(flash_add >> DeviceInfo.nBitsInPageDataSize)),
-				0x2000 | page_count);
-
-			while (!(ioread32(FlashReg + intr_status) &
-				INTR_STATUS0__LOAD_COMP))
-				;
-
-			iowrite32((u32)(MODE_01 | (flash_bank << 24) |
-				(flash_add >>
-				DeviceInfo.nBitsInPageDataSize)),
-				FlashMem);
-
-			for (i = 0; i < PageSize / 4; i++)
-				*(((u32 *)page_main_spare) + i) =
-					ioread32(FlashMem + 0x10);
-
-			if (enable_ecc) {
-				for (i = PageDataSize;  i < PageSize -
-							spareSkipBytes; i++)
-					page_main_spare[i] = page_main_spare[i +
-								spareSkipBytes];
-
-				for (j = 0;
-				j < DeviceInfo.wPageDataSize / eccSectorSize;
-				j++) {
-
-					for (i = 0; i < eccSectorSize; i++)
-						read_data_l[eccSectorSize * j +
-							    i] =
-						    page_main_spare[
-							(eccSectorSize +
-							eccBytes) * j + i];
-
-					for (i = 0; i < eccBytes; i++)
-						read_data_l[PageDataSize +
-							    spareFlagBytes +
-							    eccBytes * j + i] =
-						    page_main_spare[
-							(eccSectorSize +
-							eccBytes) * j +
-							eccSectorSize + i];
-				}
-
-				for (i = 0; i < spareFlagBytes; i++)
-					read_data_l[PageDataSize + i] =
-					    page_main_spare[(eccSectorSize +
-							     eccBytes) * j + i];
-			} else {
-				for (i = 0; i < (PageDataSize + PageSpareSize);
-				     i++)
-					read_data_l[i] = page_main_spare[i];
-
-			}
-
-			if (enable_ecc) {
-				while (!(ioread32(FlashReg + intr_status) &
-					(INTR_STATUS0__ECC_TRANSACTION_DONE |
-					INTR_STATUS0__ECC_ERR)))
-					;
-
-				if (ioread32(FlashReg + intr_status) &
-					INTR_STATUS0__ECC_ERR) {
-					iowrite32(INTR_STATUS0__ECC_ERR,
-						FlashReg + intr_status);
-					status = do_ecc_new(flash_bank,
-						read_data, block, page);
-				}
-
-				if (ioread32(FlashReg + intr_status) &
-					INTR_STATUS0__ECC_TRANSACTION_DONE &
-					INTR_STATUS0__ECC_ERR) {
-					iowrite32(INTR_STATUS0__ECC_ERR |
-					INTR_STATUS0__ECC_TRANSACTION_DONE,
-					FlashReg + intr_status);
-				} else if (ioread32(FlashReg + intr_status) &
-					INTR_STATUS0__ECC_TRANSACTION_DONE) {
-					iowrite32(
-					INTR_STATUS0__ECC_TRANSACTION_DONE,
-					FlashReg + intr_status);
-				} else if (ioread32(FlashReg + intr_status) &
-					INTR_STATUS0__ECC_ERR) {
-					iowrite32(INTR_STATUS0__ECC_ERR,
-						FlashReg + intr_status);
-				}
-			}
-
-			page++;
-			page_count--;
-			read_data_l += PageSize;
-		}
-	}
-
-	iowrite32(0, FlashReg + TRANSFER_SPARE_REG);
-
-	index_addr((u32)(MODE_10 | (flash_bank << 24) |
-		(flash_add >> DeviceInfo.nBitsInPageDataSize)), 0x42);
-
-	return status;
-}
-
-u16 NAND_Pipeline_Write_Ahead(u8 *write_data, u32 block,
-			u16 page, u16 page_count)
-{
-	u16 status = PASS;
-	u32 NumPages = page_count;
-	u64 flash_add;
-	u32 flash_bank;
-	u32 intr_status = 0;
-	u32 intr_status_addresses[4] = {INTR_STATUS0,
-		INTR_STATUS1, INTR_STATUS2, INTR_STATUS3};
-	int ret;
-
-	nand_dbg_print(NAND_DBG_DEBUG, "%s, Line %d, Function: %s\n",
-		       __FILE__, __LINE__, __func__);
-
-	status = Boundary_Check_Block_Page(block, page, page_count);
-
-	if (page_count < 2)
-		status = FAIL;
-
-	if (status != PASS)
-		return status;
-
-	flash_add = (u64)(block % (DeviceInfo.wTotalBlocks / totalUsedBanks))
-		* DeviceInfo.wBlockDataSize +
-		(u64)page * DeviceInfo.wPageDataSize;
-
-	flash_bank = block / (DeviceInfo.wTotalBlocks / totalUsedBanks);
-
-	intr_status = intr_status_addresses[flash_bank];
-	iowrite32(ioread32(FlashReg + intr_status), FlashReg + intr_status);
-
-	iowrite32(1, FlashReg + DMA_ENABLE);
-	while (!(ioread32(FlashReg + DMA_ENABLE) & DMA_ENABLE__FLAG))
-		;
-
-	iowrite32(0, FlashReg + TRANSFER_SPARE_REG);
-
-	/* Fill the mrst_nand_info structure */
-	info.state = INT_PIPELINE_WRITE_AHEAD;
-	info.write_data = write_data;
-	info.flash_bank = flash_bank;
-	info.block = block;
-	info.page = page;
-	info.ret = PASS;
-
-	index_addr((u32)(MODE_10 | (flash_bank << 24) |
-		(flash_add >> DeviceInfo.nBitsInPageDataSize)), 0x42);
-
-	ddma_trans(write_data, flash_add, flash_bank, 1, NumPages);
-
-	iowrite32(1, FlashReg + GLOBAL_INT_ENABLE); /* Enable interrupt */
-
-	ret = wait_for_completion_timeout(&info.complete, 10 * HZ);
-	if (!ret) {
-		printk(KERN_ERR "Wait for completion timeout "
-			"in %s, Line %d\n", __FILE__, __LINE__);
-		status = ERR;
-	} else {
-		status = info.ret;
-	}
-
-	iowrite32(ioread32(FlashReg + intr_status), FlashReg + intr_status);
-
-	iowrite32(0, FlashReg + DMA_ENABLE);
-	while ((ioread32(FlashReg + DMA_ENABLE) & DMA_ENABLE__FLAG))
-		;
-
-	return status;
-}
-
-/* Un-tested function */
-u16 NAND_Multiplane_Write(u8 *write_data, u32 block, u16 page,
-			     u16 page_count)
-{
-	u16 status = PASS;
-	u32 NumPages = page_count;
-	u64 flash_add;
-	u32 flash_bank;
-	u32 intr_status = 0;
-	u32 intr_status_addresses[4] = {INTR_STATUS0,
-		INTR_STATUS1, INTR_STATUS2, INTR_STATUS3};
-	u16 status2 = PASS;
-	u32 t;
-
-	nand_dbg_print(NAND_DBG_WARN, "%s, Line %d, Function: %s\n",
-		       __FILE__, __LINE__, __func__);
-
-	status = Boundary_Check_Block_Page(block, page, page_count);
-	if (status != PASS)
-		return status;
-
-	flash_add = (u64)(block % (DeviceInfo.wTotalBlocks / totalUsedBanks))
-		* DeviceInfo.wBlockDataSize +
-		(u64)page * DeviceInfo.wPageDataSize;
-
-	flash_bank = block / (DeviceInfo.wTotalBlocks / totalUsedBanks);
-
-	intr_status = intr_status_addresses[flash_bank];
-	iowrite32(ioread32(FlashReg + intr_status), FlashReg + intr_status);
-
-	iowrite32(0, FlashReg + TRANSFER_SPARE_REG);
-	iowrite32(0x01, FlashReg + MULTIPLANE_OPERATION);
-
-	iowrite32(1, FlashReg + DMA_ENABLE);
-	while (!(ioread32(FlashReg + DMA_ENABLE) & DMA_ENABLE__FLAG))
-		;
-
-	iowrite32(0, FlashReg + TRANSFER_SPARE_REG);
-
-	index_addr((u32)(MODE_10 | (flash_bank << 24) |
-		(flash_add >> DeviceInfo.nBitsInPageDataSize)), 0x42);
-
-	ddma_trans(write_data, flash_add, flash_bank, 1, NumPages);
-
-	while (1) {
-		while (!ioread32(FlashReg + intr_status))
-			;
-
-		if (ioread32(FlashReg + intr_status) &
-			INTR_STATUS0__DMA_CMD_COMP) {
-			iowrite32(INTR_STATUS0__DMA_CMD_COMP,
-				FlashReg + intr_status);
-			status = PASS;
-			if (status2 == FAIL)
-				status = FAIL;
-			break;
-		} else if (ioread32(FlashReg + intr_status) &
-				INTR_STATUS0__PROGRAM_FAIL) {
-			status2 = FAIL;
-			status = FAIL;
-			t = ioread32(FlashReg + intr_status) &
-				INTR_STATUS0__PROGRAM_FAIL;
-			iowrite32(t, FlashReg + intr_status);
-		} else {
-			iowrite32((~INTR_STATUS0__PROGRAM_FAIL) &
-				(~INTR_STATUS0__DMA_CMD_COMP),
-				FlashReg + intr_status);
-		}
-	}
-
-	iowrite32(ioread32(FlashReg + intr_status), FlashReg + intr_status);
-
-	iowrite32(0, FlashReg + DMA_ENABLE);
-
-	while ((ioread32(FlashReg + DMA_ENABLE) & DMA_ENABLE__FLAG))
-		;
-
-	iowrite32(0, FlashReg + MULTIPLANE_OPERATION);
-
-	return status;
-}
-
-
-#if CMD_DMA
-static irqreturn_t cdma_isr(int irq, void *dev_id)
-{
-	struct mrst_nand_info *dev = dev_id;
-	int first_failed_cmd;
-
-	nand_dbg_print(NAND_DBG_DEBUG, "%s, Line %d, Function: %s\n",
-		       __FILE__, __LINE__, __func__);
-
-	if (!is_cdma_interrupt())
-		return IRQ_NONE;
-
-	/* Disable controller interrupts */
-	iowrite32(0, FlashReg + GLOBAL_INT_ENABLE);
-	GLOB_FTL_Event_Status(&first_failed_cmd);
-	complete(&dev->complete);
-
-	return IRQ_HANDLED;
-}
-#else
-static void handle_nand_int_read(struct mrst_nand_info *dev)
-{
-	u32 intr_status_addresses[4] = {INTR_STATUS0,
-		INTR_STATUS1, INTR_STATUS2, INTR_STATUS3};
-	u32 intr_status;
-	u32 ecc_done_OR_dma_comp = 0;
-
-	nand_dbg_print(NAND_DBG_DEBUG, "%s, Line %d, Function: %s\n",
-		       __FILE__, __LINE__, __func__);
-
-	dev->ret = PASS;
-	intr_status = intr_status_addresses[dev->flash_bank];
-
-	while (1) {
-		if (enable_ecc) {
-			if (ioread32(FlashReg + intr_status) &
-				INTR_STATUS0__ECC_ERR) {
-				iowrite32(INTR_STATUS0__ECC_ERR,
-					FlashReg + intr_status);
-				dev->ret = do_ecc_new(dev->flash_bank,
-						dev->read_data,
-						dev->block, dev->page);
-			} else if (ioread32(FlashReg + intr_status) &
-				INTR_STATUS0__DMA_CMD_COMP) {
-				iowrite32(INTR_STATUS0__DMA_CMD_COMP,
-					FlashReg + intr_status);
-				if (1 == ecc_done_OR_dma_comp)
-					break;
-				ecc_done_OR_dma_comp = 1;
-			} else if (ioread32(FlashReg + intr_status) &
-				INTR_STATUS0__ECC_TRANSACTION_DONE) {
-				iowrite32(INTR_STATUS0__ECC_TRANSACTION_DONE,
-					FlashReg + intr_status);
-				if (1 == ecc_done_OR_dma_comp)
-					break;
-				ecc_done_OR_dma_comp = 1;
-			}
-		} else {
-			if (ioread32(FlashReg + intr_status) &
-				INTR_STATUS0__DMA_CMD_COMP) {
-				iowrite32(INTR_STATUS0__DMA_CMD_COMP,
-					FlashReg + intr_status);
-				break;
-			} else {
-				printk(KERN_ERR "Illegal INTS "
-					"(offset addr 0x%x) value: 0x%x\n",
-					intr_status,
-					ioread32(FlashReg + intr_status));
-			}
-		}
-
-		iowrite32((~INTR_STATUS0__ECC_ERR) &
-		(~INTR_STATUS0__ECC_TRANSACTION_DONE) &
-		(~INTR_STATUS0__DMA_CMD_COMP),
-		FlashReg + intr_status);
-	}
-}
-
-static void handle_nand_int_write(struct mrst_nand_info *dev)
-{
-	u32 intr_status;
-	u32 intr[4] = {INTR_STATUS0, INTR_STATUS1,
-		INTR_STATUS2, INTR_STATUS3};
-	int status = PASS;
-
-	nand_dbg_print(NAND_DBG_DEBUG, "%s, Line %d, Function: %s\n",
-		       __FILE__, __LINE__, __func__);
-
-	dev->ret = PASS;
-	intr_status = intr[dev->flash_bank];
-
-	while (1) {
-		while (!ioread32(FlashReg + intr_status))
-			;
-
-		if (ioread32(FlashReg + intr_status) &
-			INTR_STATUS0__DMA_CMD_COMP) {
-			iowrite32(INTR_STATUS0__DMA_CMD_COMP,
-				FlashReg + intr_status);
-			if (FAIL == status)
-				dev->ret = FAIL;
-			break;
-		} else if (ioread32(FlashReg + intr_status) &
-			INTR_STATUS0__PROGRAM_FAIL) {
-			status = FAIL;
-			iowrite32(INTR_STATUS0__PROGRAM_FAIL,
-				FlashReg + intr_status);
-		} else {
-			iowrite32((~INTR_STATUS0__PROGRAM_FAIL) &
-				(~INTR_STATUS0__DMA_CMD_COMP),
-				FlashReg + intr_status);
-		}
-	}
-}
-
-static irqreturn_t ddma_isr(int irq, void *dev_id)
-{
-	struct mrst_nand_info *dev = dev_id;
-	u32 int_mask, ints0, ints1, ints2, ints3, ints_offset;
-	u32 intr[4] = {INTR_STATUS0, INTR_STATUS1,
-		INTR_STATUS2, INTR_STATUS3};
-
-	int_mask = INTR_STATUS0__DMA_CMD_COMP |
-		INTR_STATUS0__ECC_TRANSACTION_DONE |
-		INTR_STATUS0__ECC_ERR |
-		INTR_STATUS0__PROGRAM_FAIL |
-		INTR_STATUS0__ERASE_FAIL;
-
-	ints0 = ioread32(FlashReg + INTR_STATUS0);
-	ints1 = ioread32(FlashReg + INTR_STATUS1);
-	ints2 = ioread32(FlashReg + INTR_STATUS2);
-	ints3 = ioread32(FlashReg + INTR_STATUS3);
-
-	ints_offset = intr[dev->flash_bank];
-
-	nand_dbg_print(NAND_DBG_DEBUG,
-		"INTR0: 0x%x, INTR1: 0x%x, INTR2: 0x%x, INTR3: 0x%x, "
-		"DMA_INTR: 0x%x, "
-		"dev->state: 0x%x, dev->flash_bank: %d\n",
-		ints0, ints1, ints2, ints3,
-		ioread32(FlashReg + DMA_INTR),
-		dev->state, dev->flash_bank);
-
-	if (!(ioread32(FlashReg + ints_offset) & int_mask)) {
-		iowrite32(ints0, FlashReg + INTR_STATUS0);
-		iowrite32(ints1, FlashReg + INTR_STATUS1);
-		iowrite32(ints2, FlashReg + INTR_STATUS2);
-		iowrite32(ints3, FlashReg + INTR_STATUS3);
-		nand_dbg_print(NAND_DBG_WARN,
-			"ddma_isr: Invalid interrupt for NAND controller. "
-			"Ignore it\n");
-		return IRQ_NONE;
-	}
-
-	switch (dev->state) {
-	case INT_READ_PAGE_MAIN:
-	case INT_PIPELINE_READ_AHEAD:
-		/* Disable controller interrupts */
-		iowrite32(0, FlashReg + GLOBAL_INT_ENABLE);
-		handle_nand_int_read(dev);
-		break;
-	case INT_WRITE_PAGE_MAIN:
-	case INT_PIPELINE_WRITE_AHEAD:
-		iowrite32(0, FlashReg + GLOBAL_INT_ENABLE);
-		handle_nand_int_write(dev);
-		break;
-	default:
-		printk(KERN_ERR "ddma_isr - Illegal state: 0x%x\n",
-			dev->state);
-		return IRQ_NONE;
-	}
-
-	dev->state = INT_IDLE_STATE;
-	complete(&dev->complete);
-	return IRQ_HANDLED;
-}
-#endif
-
-static const struct pci_device_id nand_pci_ids[] = {
-	{
-	 .vendor = 0x8086,
-	 .device = 0x0809,
-	 .subvendor = PCI_ANY_ID,
-	 .subdevice = PCI_ANY_ID,
-	 },
-	{ /* end: all zeroes */ }
-};
-
-static int nand_pci_probe(struct pci_dev *dev, const struct pci_device_id *id)
-{
-	int ret = -ENODEV;
-	unsigned long csr_base;
-	unsigned long csr_len;
-	struct mrst_nand_info *pndev = &info;
-	u32 int_mask;
-
-	ret = pci_enable_device(dev);
-	if (ret) {
-		printk(KERN_ERR "Spectra: pci_enable_device failed.\n");
-		return ret;
-	}
-
-	nand_dbg_print(NAND_DBG_WARN, "%s, Line %d, Function: %s\n",
-		       __FILE__, __LINE__, __func__);
-
-	FlashReg = ioremap_nocache(GLOB_HWCTL_REG_BASE,
-			GLOB_HWCTL_REG_SIZE);
-	if (!FlashReg) {
-		printk(KERN_ERR "Spectra: ioremap_nocache failed!");
-		goto failed_disable;
-	}
-	nand_dbg_print(NAND_DBG_WARN,
-		"Spectra: Remapped reg base address: "
-		"0x%p, len: %d\n",
-		FlashReg, GLOB_HWCTL_REG_SIZE);
-
-	FlashMem = ioremap_nocache(GLOB_HWCTL_MEM_BASE,
-			GLOB_HWCTL_MEM_SIZE);
-	if (!FlashMem) {
-		printk(KERN_ERR "Spectra: ioremap_nocache failed!");
-		iounmap(FlashReg);
-		goto failed_disable;
-	}
-	nand_dbg_print(NAND_DBG_WARN,
-		"Spectra: Remapped flash base address: "
-		"0x%p, len: %d\n",
-		(void *)FlashMem, GLOB_HWCTL_MEM_SIZE);
-
-	nand_dbg_print(NAND_DBG_DEBUG, "Dump timing register values:"
-			"acc_clks: %d, re_2_we: %d, we_2_re: %d,"
-			"addr_2_data: %d, rdwr_en_lo_cnt: %d, "
-			"rdwr_en_hi_cnt: %d, cs_setup_cnt: %d\n",
-			ioread32(FlashReg + ACC_CLKS),
-			ioread32(FlashReg + RE_2_WE),
-			ioread32(FlashReg + WE_2_RE),
-			ioread32(FlashReg + ADDR_2_DATA),
-			ioread32(FlashReg + RDWR_EN_LO_CNT),
-			ioread32(FlashReg + RDWR_EN_HI_CNT),
-			ioread32(FlashReg + CS_SETUP_CNT));
-
-	NAND_Flash_Reset();
-
-	iowrite32(0, FlashReg + GLOBAL_INT_ENABLE);
-
-#if CMD_DMA
-	info.pcmds_num = 0;
-	info.flash_bank = 0;
-	info.cdma_num = 0;
-	int_mask = (DMA_INTR__DESC_COMP_CHANNEL0 |
-		DMA_INTR__DESC_COMP_CHANNEL1 |
-		DMA_INTR__DESC_COMP_CHANNEL2 |
-		DMA_INTR__DESC_COMP_CHANNEL3 |
-		DMA_INTR__MEMCOPY_DESC_COMP);
-	iowrite32(int_mask, FlashReg + DMA_INTR_EN);
-	iowrite32(0xFFFF, FlashReg + DMA_INTR);
-
-	int_mask = (INTR_STATUS0__ECC_ERR |
-		INTR_STATUS0__PROGRAM_FAIL |
-		INTR_STATUS0__ERASE_FAIL);
-#else
-	int_mask = INTR_STATUS0__DMA_CMD_COMP |
-		INTR_STATUS0__ECC_TRANSACTION_DONE |
-		INTR_STATUS0__ECC_ERR |
-		INTR_STATUS0__PROGRAM_FAIL |
-		INTR_STATUS0__ERASE_FAIL;
-#endif
-	iowrite32(int_mask, FlashReg + INTR_EN0);
-	iowrite32(int_mask, FlashReg + INTR_EN1);
-	iowrite32(int_mask, FlashReg + INTR_EN2);
-	iowrite32(int_mask, FlashReg + INTR_EN3);
-
-	/* Clear all status bits */
-	iowrite32(0xFFFF, FlashReg + INTR_STATUS0);
-	iowrite32(0xFFFF, FlashReg + INTR_STATUS1);
-	iowrite32(0xFFFF, FlashReg + INTR_STATUS2);
-	iowrite32(0xFFFF, FlashReg + INTR_STATUS3);
-
-	iowrite32(0x0F, FlashReg + RB_PIN_ENABLED);
-	iowrite32(CHIP_EN_DONT_CARE__FLAG, FlashReg + CHIP_ENABLE_DONT_CARE);
-
-	/* Should set value for these registers when init */
-	iowrite32(0, FlashReg + TWO_ROW_ADDR_CYCLES);
-	iowrite32(1, FlashReg + ECC_ENABLE);
-	enable_ecc = 1;
-
-	pci_set_master(dev);
-	pndev->dev = dev;
-
-	csr_base = pci_resource_start(dev, 0);
-	if (!csr_base) {
-		printk(KERN_ERR "Spectra: pci_resource_start failed!\n");
-		ret = -ENODEV;
-		goto failed_req_csr;
-	}
-
-	csr_len = pci_resource_len(dev, 0);
-	if (!csr_len) {
-		printk(KERN_ERR "Spectra: pci_resource_len failed!\n");
-		ret = -ENODEV;
-		goto failed_req_csr;
-	}
-
-	ret = pci_request_regions(dev, SPECTRA_NAND_NAME);
-	if (ret) {
-		printk(KERN_ERR "Spectra: Unable to request "
-		       "memory region\n");
-		goto failed_req_csr;
-	}
-
-	pndev->ioaddr = ioremap_nocache(csr_base, csr_len);
-	if (!pndev->ioaddr) {
-		printk(KERN_ERR "Spectra: Unable to remap memory region\n");
-		ret = -ENOMEM;
-		goto failed_remap_csr;
-	}
-	nand_dbg_print(NAND_DBG_DEBUG, "Spectra: CSR 0x%08lx -> 0x%p (0x%lx)\n",
-		       csr_base, pndev->ioaddr, csr_len);
-
-	init_completion(&pndev->complete);
-	nand_dbg_print(NAND_DBG_DEBUG, "Spectra: IRQ %d\n", dev->irq);
-
-#if CMD_DMA
-	if (request_irq(dev->irq, cdma_isr, IRQF_SHARED,
-			SPECTRA_NAND_NAME, &info)) {
-		printk(KERN_ERR "Spectra: Unable to allocate IRQ\n");
-		ret = -ENODEV;
-		iounmap(pndev->ioaddr);
-		goto failed_remap_csr;
-	}
-#else
-	if (request_irq(dev->irq, ddma_isr, IRQF_SHARED,
-			SPECTRA_NAND_NAME, &info)) {
-		printk(KERN_ERR "Spectra: Unable to allocate IRQ\n");
-		ret = -ENODEV;
-		iounmap(pndev->ioaddr);
-		goto failed_remap_csr;
-	}
-#endif
-
-	pci_set_drvdata(dev, pndev);
-
-	ret = GLOB_LLD_Read_Device_ID();
-	if (ret) {
-		iounmap(pndev->ioaddr);
-		goto failed_remap_csr;
-	}
-
-	ret = register_spectra_ftl();
-	if (ret) {
-		iounmap(pndev->ioaddr);
-		goto failed_remap_csr;
-	}
-
-	return 0;
-
-failed_remap_csr:
-	pci_release_regions(dev);
-failed_req_csr:
-	iounmap(FlashMem);
-	iounmap(FlashReg);
-failed_disable:
-	pci_disable_device(dev);
-
-	return ret;
-}
-
-static void nand_pci_remove(struct pci_dev *dev)
-{
-	struct mrst_nand_info *pndev = pci_get_drvdata(dev);
-
-	nand_dbg_print(NAND_DBG_WARN, "%s, Line %d, Function: %s\n",
-		       __FILE__, __LINE__, __func__);
-
-#if CMD_DMA
-	free_irq(dev->irq, pndev);
-#endif
-	iounmap(pndev->ioaddr);
-	pci_release_regions(dev);
-	pci_disable_device(dev);
-}
-
-MODULE_DEVICE_TABLE(pci, nand_pci_ids);
-
-static struct pci_driver nand_pci_driver = {
-	.name = SPECTRA_NAND_NAME,
-	.id_table = nand_pci_ids,
-	.probe = nand_pci_probe,
-	.remove = nand_pci_remove,
-};
-
-int NAND_Flash_Init(void)
-{
-	int retval;
-
-	nand_dbg_print(NAND_DBG_TRACE, "%s, Line %d, Function: %s\n",
-		       __FILE__, __LINE__, __func__);
-
-	retval = pci_register_driver(&nand_pci_driver);
-	if (retval)
-		return -ENOMEM;
-
-	return PASS;
-}
-
-/* Free memory */
-int nand_release_spectra(void)
-{
-	pci_unregister_driver(&nand_pci_driver);
-	iounmap(FlashMem);
-	iounmap(FlashReg);
-
-	return 0;
-}
-
-
-
diff --git a/drivers/staging/spectra/lld_nand.h b/drivers/staging/spectra/lld_nand.h
deleted file mode 100644
index d083882..0000000
--- a/drivers/staging/spectra/lld_nand.h
+++ /dev/null
@@ -1,131 +0,0 @@
-/*
- * NAND Flash Controller Device Driver
- * Copyright (c) 2009, Intel Corporation and its suppliers.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms and conditions of the GNU General Public License,
- * version 2, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
- *
- */
-
-#ifndef _LLD_NAND_
-#define _LLD_NAND_
-
-#ifdef ELDORA
-#include "defs.h"
-#else
-#include "flash.h"
-#include "ffsport.h"
-#endif
-
-#define MODE_00    0x00000000
-#define MODE_01    0x04000000
-#define MODE_10    0x08000000
-#define MODE_11    0x0C000000
-
-
-#define DATA_TRANSFER_MODE              0
-#define PROTECTION_PER_BLOCK            1
-#define LOAD_WAIT_COUNT                 2
-#define PROGRAM_WAIT_COUNT              3
-#define ERASE_WAIT_COUNT                4
-#define INT_MONITOR_CYCLE_COUNT         5
-#define READ_BUSY_PIN_ENABLED           6
-#define MULTIPLANE_OPERATION_SUPPORT    7
-#define PRE_FETCH_MODE                  8
-#define CE_DONT_CARE_SUPPORT            9
-#define COPYBACK_SUPPORT                10
-#define CACHE_WRITE_SUPPORT             11
-#define CACHE_READ_SUPPORT              12
-#define NUM_PAGES_IN_BLOCK              13
-#define ECC_ENABLE_SELECT               14
-#define WRITE_ENABLE_2_READ_ENABLE      15
-#define ADDRESS_2_DATA                  16
-#define READ_ENABLE_2_WRITE_ENABLE      17
-#define TWO_ROW_ADDRESS_CYCLES          18
-#define MULTIPLANE_ADDRESS_RESTRICT     19
-#define ACC_CLOCKS                      20
-#define READ_WRITE_ENABLE_LOW_COUNT     21
-#define READ_WRITE_ENABLE_HIGH_COUNT    22
-
-#define ECC_SECTOR_SIZE     512
-#define LLD_MAX_FLASH_BANKS     4
-
-struct mrst_nand_info {
-	struct pci_dev *dev;
-	u32 state;
-	u32 flash_bank;
-	u8 *read_data;
-	u8 *write_data;
-	u32 block;
-	u16 page;
-	u32 use_dma;
-	void __iomem *ioaddr;  /* Mapped io reg base address */
-	int ret;
-	u32 pcmds_num;
-	struct pending_cmd *pcmds;
-	int cdma_num;           /* CDMA descriptor number in this chan */
-	u8 *cdma_desc_buf;	/* CDMA descriptor table */
-	u8 *memcp_desc_buf;	/* Memory copy descriptor table */
-	dma_addr_t cdma_desc;	/* Mapped CDMA descriptor table */
-	dma_addr_t memcp_desc;	/* Mapped memory copy descriptor table */
-	struct completion complete;
-};
-
-int NAND_Flash_Init(void);
-int nand_release_spectra(void);
-u16  NAND_Flash_Reset(void);
-u16  NAND_Read_Device_ID(void);
-u16  NAND_Erase_Block(u32 flash_add);
-u16  NAND_Write_Page_Main(u8 *write_data, u32 block, u16 page,
-				u16 page_count);
-u16  NAND_Read_Page_Main(u8 *read_data, u32 block, u16 page,
-				u16 page_count);
-u16  NAND_UnlockArrayAll(void);
-u16  NAND_Write_Page_Main_Spare(u8 *write_data, u32 block,
-				u16 page, u16 page_count);
-u16  NAND_Write_Page_Spare(u8 *read_data, u32 block, u16 page,
-				u16 page_count);
-u16  NAND_Read_Page_Main_Spare(u8 *read_data, u32 block, u16 page,
-				u16 page_count);
-u16  NAND_Read_Page_Spare(u8 *read_data, u32 block, u16 page,
-				u16 page_count);
-void NAND_LLD_Enable_Disable_Interrupts(u16 INT_ENABLE);
-u16  NAND_Get_Bad_Block(u32 block);
-u16  NAND_Pipeline_Read_Ahead(u8 *read_data, u32 block, u16 page,
-				u16 page_count);
-u16  NAND_Pipeline_Write_Ahead(u8 *write_data, u32 block,
-				u16 page, u16 page_count);
-u16  NAND_Multiplane_Read(u8 *read_data, u32 block, u16 page,
-				u16 page_count);
-u16  NAND_Multiplane_Write(u8 *write_data, u32 block, u16 page,
-				u16 page_count);
-void NAND_ECC_Ctrl(int enable);
-u16 NAND_Read_Page_Main_Polling(u8 *read_data,
-		u32 block, u16 page, u16 page_count);
-u16 NAND_Pipeline_Read_Ahead_Polling(u8 *read_data,
-			u32 block, u16 page, u16 page_count);
-void Conv_Spare_Data_Log2Phy_Format(u8 *data);
-void Conv_Spare_Data_Phy2Log_Format(u8 *data);
-void Conv_Main_Spare_Data_Log2Phy_Format(u8 *data, u16 page_count);
-void Conv_Main_Spare_Data_Phy2Log_Format(u8 *data, u16 page_count);
-
-extern void __iomem *FlashReg;
-extern void __iomem *FlashMem;
-
-extern int totalUsedBanks;
-extern u32 GLOB_valid_banks[LLD_MAX_FLASH_BANKS];
-
-#endif /*_LLD_NAND_*/
-
-
-
diff --git a/drivers/staging/spectra/nand_regs.h b/drivers/staging/spectra/nand_regs.h
deleted file mode 100644
index e192e4a..0000000
--- a/drivers/staging/spectra/nand_regs.h
+++ /dev/null
@@ -1,619 +0,0 @@
-/*
- * NAND Flash Controller Device Driver
- * Copyright (c) 2009, Intel Corporation and its suppliers.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms and conditions of the GNU General Public License,
- * version 2, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
- *
- */
-
-#define DEVICE_RESET				0x0
-#define     DEVICE_RESET__BANK0				0x0001
-#define     DEVICE_RESET__BANK1				0x0002
-#define     DEVICE_RESET__BANK2				0x0004
-#define     DEVICE_RESET__BANK3				0x0008
-
-#define TRANSFER_SPARE_REG			0x10
-#define     TRANSFER_SPARE_REG__FLAG			0x0001
-
-#define LOAD_WAIT_CNT				0x20
-#define     LOAD_WAIT_CNT__VALUE				0xffff
-
-#define PROGRAM_WAIT_CNT			0x30
-#define     PROGRAM_WAIT_CNT__VALUE			0xffff
-
-#define ERASE_WAIT_CNT				0x40
-#define     ERASE_WAIT_CNT__VALUE			0xffff
-
-#define INT_MON_CYCCNT				0x50
-#define     INT_MON_CYCCNT__VALUE			0xffff
-
-#define RB_PIN_ENABLED				0x60
-#define     RB_PIN_ENABLED__BANK0			0x0001
-#define     RB_PIN_ENABLED__BANK1			0x0002
-#define     RB_PIN_ENABLED__BANK2			0x0004
-#define     RB_PIN_ENABLED__BANK3			0x0008
-
-#define MULTIPLANE_OPERATION			0x70
-#define     MULTIPLANE_OPERATION__FLAG			0x0001
-
-#define MULTIPLANE_READ_ENABLE			0x80
-#define     MULTIPLANE_READ_ENABLE__FLAG		0x0001
-
-#define COPYBACK_DISABLE			0x90
-#define     COPYBACK_DISABLE__FLAG			0x0001
-
-#define CACHE_WRITE_ENABLE			0xa0
-#define     CACHE_WRITE_ENABLE__FLAG			0x0001
-
-#define CACHE_READ_ENABLE			0xb0
-#define     CACHE_READ_ENABLE__FLAG			0x0001
-
-#define PREFETCH_MODE				0xc0
-#define     PREFETCH_MODE__PREFETCH_EN			0x0001
-#define     PREFETCH_MODE__PREFETCH_BURST_LENGTH	0xfff0
-
-#define CHIP_ENABLE_DONT_CARE			0xd0
-#define     CHIP_EN_DONT_CARE__FLAG			0x01
-
-#define ECC_ENABLE				0xe0
-#define     ECC_ENABLE__FLAG				0x0001
-
-#define GLOBAL_INT_ENABLE			0xf0
-#define     GLOBAL_INT_EN_FLAG				0x01
-
-#define WE_2_RE					0x100
-#define     WE_2_RE__VALUE				0x003f
-
-#define ADDR_2_DATA				0x110
-#define     ADDR_2_DATA__VALUE				0x003f
-
-#define RE_2_WE					0x120
-#define     RE_2_WE__VALUE				0x003f
-
-#define ACC_CLKS    				0x130
-#define     ACC_CLKS__VALUE				0x000f
-
-#define NUMBER_OF_PLANES			0x140
-#define     NUMBER_OF_PLANES__VALUE			0x0007
-
-#define PAGES_PER_BLOCK				0x150
-#define     PAGES_PER_BLOCK__VALUE			0xffff
-
-#define DEVICE_WIDTH				0x160
-#define     DEVICE_WIDTH__VALUE				0x0003
-
-#define DEVICE_MAIN_AREA_SIZE			0x170
-#define     DEVICE_MAIN_AREA_SIZE__VALUE		0xffff
-
-#define DEVICE_SPARE_AREA_SIZE			0x180
-#define     DEVICE_SPARE_AREA_SIZE__VALUE		0xffff
-
-#define TWO_ROW_ADDR_CYCLES			0x190
-#define     TWO_ROW_ADDR_CYCLES__FLAG			0x0001
-
-#define MULTIPLANE_ADDR_RESTRICT		0x1a0
-#define     MULTIPLANE_ADDR_RESTRICT__FLAG		0x0001
-
-#define ECC_CORRECTION				0x1b0
-#define     ECC_CORRECTION__VALUE			0x001f
-
-#define READ_MODE				0x1c0
-#define     READ_MODE__VALUE				0x000f
-
-#define WRITE_MODE				0x1d0
-#define     WRITE_MODE__VALUE				0x000f
-
-#define COPYBACK_MODE				0x1e0
-#define     COPYBACK_MODE__VALUE			0x000f
-
-#define RDWR_EN_LO_CNT				0x1f0
-#define     RDWR_EN_LO_CNT__VALUE			0x001f
-
-#define RDWR_EN_HI_CNT				0x200
-#define     RDWR_EN_HI_CNT__VALUE			0x001f
-
-#define MAX_RD_DELAY				0x210
-#define     MAX_RD_DELAY__VALUE				0x000f
-
-#define CS_SETUP_CNT				0x220
-#define     CS_SETUP_CNT__VALUE				0x001f
-
-#define SPARE_AREA_SKIP_BYTES			0x230
-#define     SPARE_AREA_SKIP_BYTES__VALUE		0x003f
-
-#define SPARE_AREA_MARKER			0x240
-#define     SPARE_AREA_MARKER__VALUE			0xffff
-
-#define DEVICES_CONNECTED			0x250
-#define     DEVICES_CONNECTED__VALUE			0x0007
-
-#define DIE_MASK					0x260
-#define     DIE_MASK__VALUE				0x00ff
-
-#define FIRST_BLOCK_OF_NEXT_PLANE		0x270
-#define     FIRST_BLOCK_OF_NEXT_PLANE__VALUE		0xffff
-
-#define WRITE_PROTECT				0x280
-#define     WRITE_PROTECT__FLAG				0x0001
-
-#define RE_2_RE					0x290
-#define     RE_2_RE__VALUE				0x003f
-
-#define MANUFACTURER_ID			0x300
-#define     MANUFACTURER_ID__VALUE			0x00ff
-
-#define DEVICE_ID				0x310
-#define     DEVICE_ID__VALUE				0x00ff
-
-#define DEVICE_PARAM_0				0x320
-#define     DEVICE_PARAM_0__VALUE			0x00ff
-
-#define DEVICE_PARAM_1				0x330
-#define     DEVICE_PARAM_1__VALUE			0x00ff
-
-#define DEVICE_PARAM_2				0x340
-#define     DEVICE_PARAM_2__VALUE			0x00ff
-
-#define LOGICAL_PAGE_DATA_SIZE			0x350
-#define     LOGICAL_PAGE_DATA_SIZE__VALUE		0xffff
-
-#define LOGICAL_PAGE_SPARE_SIZE			0x360
-#define     LOGICAL_PAGE_SPARE_SIZE__VALUE		0xffff
-
-#define REVISION					0x370
-#define     REVISION__VALUE				0xffff
-
-#define ONFI_DEVICE_FEATURES			0x380
-#define     ONFI_DEVICE_FEATURES__VALUE			0x003f
-
-#define ONFI_OPTIONAL_COMMANDS		0x390
-#define     ONFI_OPTIONAL_COMMANDS__VALUE		0x003f
-
-#define ONFI_TIMING_MODE			0x3a0
-#define     ONFI_TIMING_MODE__VALUE			0x003f
-
-#define ONFI_PGM_CACHE_TIMING_MODE		0x3b0
-#define     ONFI_PGM_CACHE_TIMING_MODE__VALUE		0x003f
-
-#define ONFI_DEVICE_NO_OF_LUNS			0x3c0
-#define     ONFI_DEVICE_NO_OF_LUNS__NO_OF_LUNS		0x00ff
-#define     ONFI_DEVICE_NO_OF_LUNS__ONFI_DEVICE		0x0100
-
-#define ONFI_DEVICE_NO_OF_BLOCKS_PER_LUN_L	0x3d0
-#define     ONFI_DEVICE_NO_OF_BLOCKS_PER_LUN_L__VALUE	0xffff
-
-#define ONFI_DEVICE_NO_OF_BLOCKS_PER_LUN_U	0x3e0
-#define     ONFI_DEVICE_NO_OF_BLOCKS_PER_LUN_U__VALUE	0xffff
-
-#define FEATURES					0x3f0
-#define     FEATURES__N_BANKS				0x0003
-#define     FEATURES__ECC_MAX_ERR			0x003c
-#define     FEATURES__DMA					0x0040
-#define     FEATURES__CMD_DMA				0x0080
-#define     FEATURES__PARTITION				0x0100
-#define     FEATURES__XDMA_SIDEBAND			0x0200
-#define     FEATURES__GPREG				0x0400
-#define     FEATURES__INDEX_ADDR				0x0800
-
-#define TRANSFER_MODE				0x400
-#define     TRANSFER_MODE__VALUE			0x0003
-
-#define INTR_STATUS0				0x410
-#define     INTR_STATUS0__ECC_TRANSACTION_DONE		0x0001
-#define     INTR_STATUS0__ECC_ERR			0x0002
-#define     INTR_STATUS0__DMA_CMD_COMP			0x0004
-#define     INTR_STATUS0__TIME_OUT			0x0008
-#define     INTR_STATUS0__PROGRAM_FAIL			0x0010
-#define     INTR_STATUS0__ERASE_FAIL			0x0020
-#define     INTR_STATUS0__LOAD_COMP			0x0040
-#define     INTR_STATUS0__PROGRAM_COMP			0x0080
-#define     INTR_STATUS0__ERASE_COMP			0x0100
-#define     INTR_STATUS0__PIPE_CPYBCK_CMD_COMP		0x0200
-#define     INTR_STATUS0__LOCKED_BLK			0x0400
-#define     INTR_STATUS0__UNSUP_CMD			0x0800
-#define     INTR_STATUS0__INT_ACT			0x1000
-#define     INTR_STATUS0__RST_COMP			0x2000
-#define     INTR_STATUS0__PIPE_CMD_ERR			0x4000
-#define     INTR_STATUS0__PAGE_XFER_INC			0x8000
-
-#define INTR_EN0					0x420
-#define     INTR_EN0__ECC_TRANSACTION_DONE		0x0001
-#define     INTR_EN0__ECC_ERR				0x0002
-#define     INTR_EN0__DMA_CMD_COMP			0x0004
-#define     INTR_EN0__TIME_OUT				0x0008
-#define     INTR_EN0__PROGRAM_FAIL			0x0010
-#define     INTR_EN0__ERASE_FAIL				0x0020
-#define     INTR_EN0__LOAD_COMP				0x0040
-#define     INTR_EN0__PROGRAM_COMP			0x0080
-#define     INTR_EN0__ERASE_COMP				0x0100
-#define     INTR_EN0__PIPE_CPYBCK_CMD_COMP		0x0200
-#define     INTR_EN0__LOCKED_BLK				0x0400
-#define     INTR_EN0__UNSUP_CMD				0x0800
-#define     INTR_EN0__INT_ACT				0x1000
-#define     INTR_EN0__RST_COMP				0x2000
-#define     INTR_EN0__PIPE_CMD_ERR			0x4000
-#define     INTR_EN0__PAGE_XFER_INC			0x8000
-
-#define PAGE_CNT0				0x430
-#define     PAGE_CNT0__VALUE				0x00ff
-
-#define ERR_PAGE_ADDR0				0x440
-#define     ERR_PAGE_ADDR0__VALUE			0xffff
-
-#define ERR_BLOCK_ADDR0			0x450
-#define     ERR_BLOCK_ADDR0__VALUE			0xffff
-
-#define INTR_STATUS1				0x460
-#define     INTR_STATUS1__ECC_TRANSACTION_DONE		0x0001
-#define     INTR_STATUS1__ECC_ERR			0x0002
-#define     INTR_STATUS1__DMA_CMD_COMP			0x0004
-#define     INTR_STATUS1__TIME_OUT			0x0008
-#define     INTR_STATUS1__PROGRAM_FAIL			0x0010
-#define     INTR_STATUS1__ERASE_FAIL			0x0020
-#define     INTR_STATUS1__LOAD_COMP			0x0040
-#define     INTR_STATUS1__PROGRAM_COMP			0x0080
-#define     INTR_STATUS1__ERASE_COMP			0x0100
-#define     INTR_STATUS1__PIPE_CPYBCK_CMD_COMP		0x0200
-#define     INTR_STATUS1__LOCKED_BLK			0x0400
-#define     INTR_STATUS1__UNSUP_CMD			0x0800
-#define     INTR_STATUS1__INT_ACT			0x1000
-#define     INTR_STATUS1__RST_COMP			0x2000
-#define     INTR_STATUS1__PIPE_CMD_ERR			0x4000
-#define     INTR_STATUS1__PAGE_XFER_INC			0x8000
-
-#define INTR_EN1					0x470
-#define     INTR_EN1__ECC_TRANSACTION_DONE		0x0001
-#define     INTR_EN1__ECC_ERR				0x0002
-#define     INTR_EN1__DMA_CMD_COMP			0x0004
-#define     INTR_EN1__TIME_OUT				0x0008
-#define     INTR_EN1__PROGRAM_FAIL			0x0010
-#define     INTR_EN1__ERASE_FAIL				0x0020
-#define     INTR_EN1__LOAD_COMP				0x0040
-#define     INTR_EN1__PROGRAM_COMP			0x0080
-#define     INTR_EN1__ERASE_COMP				0x0100
-#define     INTR_EN1__PIPE_CPYBCK_CMD_COMP		0x0200
-#define     INTR_EN1__LOCKED_BLK				0x0400
-#define     INTR_EN1__UNSUP_CMD				0x0800
-#define     INTR_EN1__INT_ACT				0x1000
-#define     INTR_EN1__RST_COMP				0x2000
-#define     INTR_EN1__PIPE_CMD_ERR			0x4000
-#define     INTR_EN1__PAGE_XFER_INC			0x8000
-
-#define PAGE_CNT1				0x480
-#define     PAGE_CNT1__VALUE				0x00ff
-
-#define ERR_PAGE_ADDR1				0x490
-#define     ERR_PAGE_ADDR1__VALUE			0xffff
-
-#define ERR_BLOCK_ADDR1			0x4a0
-#define     ERR_BLOCK_ADDR1__VALUE			0xffff
-
-#define INTR_STATUS2				0x4b0
-#define     INTR_STATUS2__ECC_TRANSACTION_DONE		0x0001
-#define     INTR_STATUS2__ECC_ERR			0x0002
-#define     INTR_STATUS2__DMA_CMD_COMP			0x0004
-#define     INTR_STATUS2__TIME_OUT			0x0008
-#define     INTR_STATUS2__PROGRAM_FAIL			0x0010
-#define     INTR_STATUS2__ERASE_FAIL			0x0020
-#define     INTR_STATUS2__LOAD_COMP			0x0040
-#define     INTR_STATUS2__PROGRAM_COMP			0x0080
-#define     INTR_STATUS2__ERASE_COMP			0x0100
-#define     INTR_STATUS2__PIPE_CPYBCK_CMD_COMP		0x0200
-#define     INTR_STATUS2__LOCKED_BLK			0x0400
-#define     INTR_STATUS2__UNSUP_CMD			0x0800
-#define     INTR_STATUS2__INT_ACT			0x1000
-#define     INTR_STATUS2__RST_COMP			0x2000
-#define     INTR_STATUS2__PIPE_CMD_ERR			0x4000
-#define     INTR_STATUS2__PAGE_XFER_INC			0x8000
-
-#define INTR_EN2					0x4c0
-#define     INTR_EN2__ECC_TRANSACTION_DONE		0x0001
-#define     INTR_EN2__ECC_ERR				0x0002
-#define     INTR_EN2__DMA_CMD_COMP			0x0004
-#define     INTR_EN2__TIME_OUT				0x0008
-#define     INTR_EN2__PROGRAM_FAIL			0x0010
-#define     INTR_EN2__ERASE_FAIL				0x0020
-#define     INTR_EN2__LOAD_COMP				0x0040
-#define     INTR_EN2__PROGRAM_COMP			0x0080
-#define     INTR_EN2__ERASE_COMP				0x0100
-#define     INTR_EN2__PIPE_CPYBCK_CMD_COMP		0x0200
-#define     INTR_EN2__LOCKED_BLK				0x0400
-#define     INTR_EN2__UNSUP_CMD				0x0800
-#define     INTR_EN2__INT_ACT				0x1000
-#define     INTR_EN2__RST_COMP				0x2000
-#define     INTR_EN2__PIPE_CMD_ERR			0x4000
-#define     INTR_EN2__PAGE_XFER_INC			0x8000
-
-#define PAGE_CNT2				0x4d0
-#define     PAGE_CNT2__VALUE				0x00ff
-
-#define ERR_PAGE_ADDR2				0x4e0
-#define     ERR_PAGE_ADDR2__VALUE			0xffff
-
-#define ERR_BLOCK_ADDR2			0x4f0
-#define     ERR_BLOCK_ADDR2__VALUE			0xffff
-
-#define INTR_STATUS3				0x500
-#define     INTR_STATUS3__ECC_TRANSACTION_DONE		0x0001
-#define     INTR_STATUS3__ECC_ERR			0x0002
-#define     INTR_STATUS3__DMA_CMD_COMP			0x0004
-#define     INTR_STATUS3__TIME_OUT			0x0008
-#define     INTR_STATUS3__PROGRAM_FAIL			0x0010
-#define     INTR_STATUS3__ERASE_FAIL			0x0020
-#define     INTR_STATUS3__LOAD_COMP			0x0040
-#define     INTR_STATUS3__PROGRAM_COMP			0x0080
-#define     INTR_STATUS3__ERASE_COMP			0x0100
-#define     INTR_STATUS3__PIPE_CPYBCK_CMD_COMP		0x0200
-#define     INTR_STATUS3__LOCKED_BLK			0x0400
-#define     INTR_STATUS3__UNSUP_CMD			0x0800
-#define     INTR_STATUS3__INT_ACT			0x1000
-#define     INTR_STATUS3__RST_COMP			0x2000
-#define     INTR_STATUS3__PIPE_CMD_ERR			0x4000
-#define     INTR_STATUS3__PAGE_XFER_INC			0x8000
-
-#define INTR_EN3					0x510
-#define     INTR_EN3__ECC_TRANSACTION_DONE		0x0001
-#define     INTR_EN3__ECC_ERR				0x0002
-#define     INTR_EN3__DMA_CMD_COMP			0x0004
-#define     INTR_EN3__TIME_OUT				0x0008
-#define     INTR_EN3__PROGRAM_FAIL			0x0010
-#define     INTR_EN3__ERASE_FAIL				0x0020
-#define     INTR_EN3__LOAD_COMP				0x0040
-#define     INTR_EN3__PROGRAM_COMP			0x0080
-#define     INTR_EN3__ERASE_COMP				0x0100
-#define     INTR_EN3__PIPE_CPYBCK_CMD_COMP		0x0200
-#define     INTR_EN3__LOCKED_BLK				0x0400
-#define     INTR_EN3__UNSUP_CMD				0x0800
-#define     INTR_EN3__INT_ACT				0x1000
-#define     INTR_EN3__RST_COMP				0x2000
-#define     INTR_EN3__PIPE_CMD_ERR			0x4000
-#define     INTR_EN3__PAGE_XFER_INC			0x8000
-
-#define PAGE_CNT3				0x520
-#define     PAGE_CNT3__VALUE				0x00ff
-
-#define ERR_PAGE_ADDR3				0x530
-#define     ERR_PAGE_ADDR3__VALUE			0xffff
-
-#define ERR_BLOCK_ADDR3			0x540
-#define     ERR_BLOCK_ADDR3__VALUE			0xffff
-
-#define DATA_INTR				0x550
-#define     DATA_INTR__WRITE_SPACE_AV			0x0001
-#define     DATA_INTR__READ_DATA_AV			0x0002
-
-#define DATA_INTR_EN				0x560
-#define     DATA_INTR_EN__WRITE_SPACE_AV		0x0001
-#define     DATA_INTR_EN__READ_DATA_AV			0x0002
-
-#define GPREG_0					0x570
-#define     GPREG_0__VALUE				0xffff
-
-#define GPREG_1					0x580
-#define     GPREG_1__VALUE				0xffff
-
-#define GPREG_2					0x590
-#define     GPREG_2__VALUE				0xffff
-
-#define GPREG_3					0x5a0
-#define     GPREG_3__VALUE				0xffff
-
-#define ECC_THRESHOLD				0x600
-#define     ECC_THRESHOLD__VALUE				0x03ff
-
-#define ECC_ERROR_BLOCK_ADDRESS		0x610
-#define     ECC_ERROR_BLOCK_ADDRESS__VALUE		0xffff
-
-#define ECC_ERROR_PAGE_ADDRESS			0x620
-#define     ECC_ERROR_PAGE_ADDRESS__VALUE		0x0fff
-#define     ECC_ERROR_PAGE_ADDRESS__BANK		0xf000
-
-#define ECC_ERROR_ADDRESS			0x630
-#define     ECC_ERROR_ADDRESS__OFFSET			0x0fff
-#define     ECC_ERROR_ADDRESS__SECTOR_NR		0xf000
-
-#define ERR_CORRECTION_INFO			0x640
-#define     ERR_CORRECTION_INFO__BYTEMASK		0x00ff
-#define     ERR_CORRECTION_INFO__DEVICE_NR		0x0f00
-#define     ERR_CORRECTION_INFO__ERROR_TYPE		0x4000
-#define     ERR_CORRECTION_INFO__LAST_ERR_INFO		0x8000
-
-#define DMA_ENABLE				0x700
-#define     DMA_ENABLE__FLAG				0x0001
-
-#define IGNORE_ECC_DONE				0x710
-#define     IGNORE_ECC_DONE__FLAG			0x0001
-
-#define DMA_INTR				0x720
-#define     DMA_INTR__TARGET_ERROR			0x0001
-#define     DMA_INTR__DESC_COMP_CHANNEL0		0x0002
-#define     DMA_INTR__DESC_COMP_CHANNEL1		0x0004
-#define     DMA_INTR__DESC_COMP_CHANNEL2		0x0008
-#define     DMA_INTR__DESC_COMP_CHANNEL3		0x0010
-#define     DMA_INTR__MEMCOPY_DESC_COMP		0x0020
-
-#define DMA_INTR_EN				0x730
-#define     DMA_INTR_EN__TARGET_ERROR			0x0001
-#define     DMA_INTR_EN__DESC_COMP_CHANNEL0		0x0002
-#define     DMA_INTR_EN__DESC_COMP_CHANNEL1		0x0004
-#define     DMA_INTR_EN__DESC_COMP_CHANNEL2		0x0008
-#define     DMA_INTR_EN__DESC_COMP_CHANNEL3		0x0010
-#define     DMA_INTR_EN__MEMCOPY_DESC_COMP		0x0020
-
-#define TARGET_ERR_ADDR_LO			0x740
-#define     TARGET_ERR_ADDR_LO__VALUE			0xffff
-
-#define TARGET_ERR_ADDR_HI			0x750
-#define     TARGET_ERR_ADDR_HI__VALUE			0xffff
-
-#define CHNL_ACTIVE				0x760
-#define     CHNL_ACTIVE__CHANNEL0			0x0001
-#define     CHNL_ACTIVE__CHANNEL1			0x0002
-#define     CHNL_ACTIVE__CHANNEL2			0x0004
-#define     CHNL_ACTIVE__CHANNEL3			0x0008
-
-#define ACTIVE_SRC_ID				0x800
-#define     ACTIVE_SRC_ID__VALUE				0x00ff
-
-#define PTN_INTR					0x810
-#define     PTN_INTR__CONFIG_ERROR			0x0001
-#define     PTN_INTR__ACCESS_ERROR_BANK0		0x0002
-#define     PTN_INTR__ACCESS_ERROR_BANK1		0x0004
-#define     PTN_INTR__ACCESS_ERROR_BANK2		0x0008
-#define     PTN_INTR__ACCESS_ERROR_BANK3		0x0010
-#define     PTN_INTR__REG_ACCESS_ERROR			0x0020
-
-#define PTN_INTR_EN				0x820
-#define     PTN_INTR_EN__CONFIG_ERROR			0x0001
-#define     PTN_INTR_EN__ACCESS_ERROR_BANK0		0x0002
-#define     PTN_INTR_EN__ACCESS_ERROR_BANK1		0x0004
-#define     PTN_INTR_EN__ACCESS_ERROR_BANK2		0x0008
-#define     PTN_INTR_EN__ACCESS_ERROR_BANK3		0x0010
-#define     PTN_INTR_EN__REG_ACCESS_ERROR		0x0020
-
-#define PERM_SRC_ID_0				0x830
-#define     PERM_SRC_ID_0__SRCID				0x00ff
-#define     PERM_SRC_ID_0__DIRECT_ACCESS_ACTIVE		0x0800
-#define     PERM_SRC_ID_0__WRITE_ACTIVE			0x2000
-#define     PERM_SRC_ID_0__READ_ACTIVE			0x4000
-#define     PERM_SRC_ID_0__PARTITION_VALID		0x8000
-
-#define MIN_BLK_ADDR_0				0x840
-#define     MIN_BLK_ADDR_0__VALUE			0xffff
-
-#define MAX_BLK_ADDR_0				0x850
-#define     MAX_BLK_ADDR_0__VALUE			0xffff
-
-#define MIN_MAX_BANK_0				0x860
-#define     MIN_MAX_BANK_0__MIN_VALUE			0x0003
-#define     MIN_MAX_BANK_0__MAX_VALUE			0x000c
-
-#define PERM_SRC_ID_1				0x870
-#define     PERM_SRC_ID_1__SRCID				0x00ff
-#define     PERM_SRC_ID_1__DIRECT_ACCESS_ACTIVE		0x0800
-#define     PERM_SRC_ID_1__WRITE_ACTIVE			0x2000
-#define     PERM_SRC_ID_1__READ_ACTIVE			0x4000
-#define     PERM_SRC_ID_1__PARTITION_VALID		0x8000
-
-#define MIN_BLK_ADDR_1				0x880
-#define     MIN_BLK_ADDR_1__VALUE			0xffff
-
-#define MAX_BLK_ADDR_1				0x890
-#define     MAX_BLK_ADDR_1__VALUE			0xffff
-
-#define MIN_MAX_BANK_1				0x8a0
-#define     MIN_MAX_BANK_1__MIN_VALUE			0x0003
-#define     MIN_MAX_BANK_1__MAX_VALUE			0x000c
-
-#define PERM_SRC_ID_2				0x8b0
-#define     PERM_SRC_ID_2__SRCID				0x00ff
-#define     PERM_SRC_ID_2__DIRECT_ACCESS_ACTIVE		0x0800
-#define     PERM_SRC_ID_2__WRITE_ACTIVE			0x2000
-#define     PERM_SRC_ID_2__READ_ACTIVE			0x4000
-#define     PERM_SRC_ID_2__PARTITION_VALID		0x8000
-
-#define MIN_BLK_ADDR_2				0x8c0
-#define     MIN_BLK_ADDR_2__VALUE			0xffff
-
-#define MAX_BLK_ADDR_2				0x8d0
-#define     MAX_BLK_ADDR_2__VALUE			0xffff
-
-#define MIN_MAX_BANK_2				0x8e0
-#define     MIN_MAX_BANK_2__MIN_VALUE			0x0003
-#define     MIN_MAX_BANK_2__MAX_VALUE			0x000c
-
-#define PERM_SRC_ID_3				0x8f0
-#define     PERM_SRC_ID_3__SRCID				0x00ff
-#define     PERM_SRC_ID_3__DIRECT_ACCESS_ACTIVE		0x0800
-#define     PERM_SRC_ID_3__WRITE_ACTIVE			0x2000
-#define     PERM_SRC_ID_3__READ_ACTIVE			0x4000
-#define     PERM_SRC_ID_3__PARTITION_VALID		0x8000
-
-#define MIN_BLK_ADDR_3				0x900
-#define     MIN_BLK_ADDR_3__VALUE			0xffff
-
-#define MAX_BLK_ADDR_3				0x910
-#define     MAX_BLK_ADDR_3__VALUE			0xffff
-
-#define MIN_MAX_BANK_3				0x920
-#define     MIN_MAX_BANK_3__MIN_VALUE			0x0003
-#define     MIN_MAX_BANK_3__MAX_VALUE			0x000c
-
-#define PERM_SRC_ID_4				0x930
-#define     PERM_SRC_ID_4__SRCID				0x00ff
-#define     PERM_SRC_ID_4__DIRECT_ACCESS_ACTIVE		0x0800
-#define     PERM_SRC_ID_4__WRITE_ACTIVE			0x2000
-#define     PERM_SRC_ID_4__READ_ACTIVE			0x4000
-#define     PERM_SRC_ID_4__PARTITION_VALID		0x8000
-
-#define MIN_BLK_ADDR_4				0x940
-#define     MIN_BLK_ADDR_4__VALUE			0xffff
-
-#define MAX_BLK_ADDR_4				0x950
-#define     MAX_BLK_ADDR_4__VALUE			0xffff
-
-#define MIN_MAX_BANK_4				0x960
-#define     MIN_MAX_BANK_4__MIN_VALUE			0x0003
-#define     MIN_MAX_BANK_4__MAX_VALUE			0x000c
-
-#define PERM_SRC_ID_5				0x970
-#define     PERM_SRC_ID_5__SRCID				0x00ff
-#define     PERM_SRC_ID_5__DIRECT_ACCESS_ACTIVE		0x0800
-#define     PERM_SRC_ID_5__WRITE_ACTIVE			0x2000
-#define     PERM_SRC_ID_5__READ_ACTIVE			0x4000
-#define     PERM_SRC_ID_5__PARTITION_VALID		0x8000
-
-#define MIN_BLK_ADDR_5				0x980
-#define     MIN_BLK_ADDR_5__VALUE			0xffff
-
-#define MAX_BLK_ADDR_5				0x990
-#define     MAX_BLK_ADDR_5__VALUE			0xffff
-
-#define MIN_MAX_BANK_5				0x9a0
-#define     MIN_MAX_BANK_5__MIN_VALUE			0x0003
-#define     MIN_MAX_BANK_5__MAX_VALUE			0x000c
-
-#define PERM_SRC_ID_6				0x9b0
-#define     PERM_SRC_ID_6__SRCID				0x00ff
-#define     PERM_SRC_ID_6__DIRECT_ACCESS_ACTIVE		0x0800
-#define     PERM_SRC_ID_6__WRITE_ACTIVE			0x2000
-#define     PERM_SRC_ID_6__READ_ACTIVE			0x4000
-#define     PERM_SRC_ID_6__PARTITION_VALID		0x8000
-
-#define MIN_BLK_ADDR_6				0x9c0
-#define     MIN_BLK_ADDR_6__VALUE			0xffff
-
-#define MAX_BLK_ADDR_6				0x9d0
-#define     MAX_BLK_ADDR_6__VALUE			0xffff
-
-#define MIN_MAX_BANK_6				0x9e0
-#define     MIN_MAX_BANK_6__MIN_VALUE			0x0003
-#define     MIN_MAX_BANK_6__MAX_VALUE			0x000c
-
-#define PERM_SRC_ID_7				0x9f0
-#define     PERM_SRC_ID_7__SRCID				0x00ff
-#define     PERM_SRC_ID_7__DIRECT_ACCESS_ACTIVE		0x0800
-#define     PERM_SRC_ID_7__WRITE_ACTIVE			0x2000
-#define     PERM_SRC_ID_7__READ_ACTIVE			0x4000
-#define     PERM_SRC_ID_7__PARTITION_VALID		0x8000
-
-#define MIN_BLK_ADDR_7				0xa00
-#define     MIN_BLK_ADDR_7__VALUE			0xffff
-
-#define MAX_BLK_ADDR_7				0xa10
-#define     MAX_BLK_ADDR_7__VALUE			0xffff
-
-#define MIN_MAX_BANK_7				0xa20
-#define     MIN_MAX_BANK_7__MIN_VALUE			0x0003
-#define     MIN_MAX_BANK_7__MAX_VALUE			0x000c
diff --git a/drivers/staging/spectra/spectraswconfig.h b/drivers/staging/spectra/spectraswconfig.h
deleted file mode 100644
index 1725946..0000000
--- a/drivers/staging/spectra/spectraswconfig.h
+++ /dev/null
@@ -1,82 +0,0 @@
-/*
- * NAND Flash Controller Device Driver
- * Copyright (c) 2009, Intel Corporation and its suppliers.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms and conditions of the GNU General Public License,
- * version 2, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
- *
- */
-
-#ifndef _SPECTRASWCONFIG_
-#define _SPECTRASWCONFIG_
-
-/* NAND driver version */
-#define GLOB_VERSION          "driver version 20100311"
-
-
-/***** Common Parameters *****/
-#define RETRY_TIMES                   3
-
-#define READ_BADBLOCK_INFO            1
-#define READBACK_VERIFY               0
-#define AUTO_FORMAT_FLASH             0
-
-/***** Cache Parameters *****/
-#define CACHE_ITEM_NUM            128
-#define BLK_NUM_FOR_L2_CACHE        16
-
-/***** Block Table Parameters *****/
-#define BLOCK_TABLE_INDEX             0
-
-/***** Wear Leveling Parameters *****/
-#define WEAR_LEVELING_GATE         0x10
-#define WEAR_LEVELING_BLOCK_NUM      10
-
-#define DEBUG_BNDRY             0
-
-/***** Product Feature Support *****/
-#define FLASH_EMU               defined(CONFIG_SPECTRA_EMU)
-#define FLASH_NAND              defined(CONFIG_SPECTRA_MRST_HW)
-#define FLASH_MTD               defined(CONFIG_SPECTRA_MTD)
-#define CMD_DMA                 defined(CONFIG_SPECTRA_MRST_HW_DMA)
-
-#define SPECTRA_PARTITION_ID    0
-
-/* Enable this macro if the number of flash blocks is larger than 16K. */
-#define SUPPORT_LARGE_BLOCKNUM  1
-
-/**** Block Table and Reserved Block Parameters *****/
-#define SPECTRA_START_BLOCK     3
-//#define NUM_FREE_BLOCKS_GATE    30
-#define NUM_FREE_BLOCKS_GATE    60
-
-/**** Hardware Parameters ****/
-#define GLOB_HWCTL_REG_BASE     0xFFA40000
-#define GLOB_HWCTL_REG_SIZE     4096
-
-#define GLOB_HWCTL_MEM_BASE     0xFFA48000
-#define GLOB_HWCTL_MEM_SIZE     4096
-
-/* KBV - Updated to LNW scratch register address */
-#define SCRATCH_REG_ADDR    0xFF108018
-#define SCRATCH_REG_SIZE    64
-
-#define GLOB_HWCTL_DEFAULT_BLKS    2048
-
-#define SUPPORT_15BITECC        1
-#define SUPPORT_8BITECC         1
-
-#define ONFI_BLOOM_TIME         0
-#define MODE5_WORKAROUND        1
-
-#endif /*_SPECTRASWCONFIG_*/
diff --git a/drivers/staging/usbip/stub_dev.c b/drivers/staging/usbip/stub_dev.c
index 55c0b51..03420e2 100644
--- a/drivers/staging/usbip/stub_dev.c
+++ b/drivers/staging/usbip/stub_dev.c
@@ -109,11 +109,6 @@
 			spin_unlock(&sdev->ud.lock);
 			return -EINVAL;
 		}
-#if 0
-		setnodelay(socket);
-		setkeepalive(socket);
-		setreuse(socket);
-#endif
 		sdev->ud.tcp_socket = socket;
 
 		spin_unlock(&sdev->ud.lock);
diff --git a/drivers/staging/usbip/stub_rx.c b/drivers/staging/usbip/stub_rx.c
index 6b4e3e1..27ac363 100644
--- a/drivers/staging/usbip/stub_rx.c
+++ b/drivers/staging/usbip/stub_rx.c
@@ -564,7 +564,7 @@
 	memset(&pdu, 0, sizeof(pdu));
 
 	/* 1. receive a pdu header */
-	ret = usbip_xmit(0, ud->tcp_socket, (char *) &pdu, sizeof(pdu), 0);
+	ret = usbip_recv(ud->tcp_socket, &pdu, sizeof(pdu));
 	if (ret != sizeof(pdu)) {
 		dev_err(dev, "recv a header, %d\n", ret);
 		usbip_event_add(ud, SDEV_EVENT_ERROR_TCP);
diff --git a/drivers/staging/usbip/usbip_common.c b/drivers/staging/usbip/usbip_common.c
index 3b7a847..d93e7f1 100644
--- a/drivers/staging/usbip/usbip_common.c
+++ b/drivers/staging/usbip/usbip_common.c
@@ -334,9 +334,8 @@
 }
 EXPORT_SYMBOL_GPL(usbip_dump_header);
 
-/* Send/receive messages over TCP/IP. I refer drivers/block/nbd.c */
-int usbip_xmit(int send, struct socket *sock, char *buf, int size,
-	       int msg_flags)
+/* Receive data over TCP/IP. */
+int usbip_recv(struct socket *sock, void *buf, int size)
 {
 	int result;
 	struct msghdr msg;
@@ -355,19 +354,6 @@
 		return -EINVAL;
 	}
 
-	if (usbip_dbg_flag_xmit) {
-		if (send) {
-			if (!in_interrupt())
-				pr_debug("%-10s:", current->comm);
-			else
-				pr_debug("interrupt  :");
-
-			pr_debug("sending... , sock %p, buf %p, size %d, "
-				 "msg_flags %d\n", sock, buf, size, msg_flags);
-			usbip_dump_buffer(buf, size);
-		}
-	}
-
 	do {
 		sock->sk->sk_allocation = GFP_NOIO;
 		iov.iov_base    = buf;
@@ -377,42 +363,30 @@
 		msg.msg_control = NULL;
 		msg.msg_controllen = 0;
 		msg.msg_namelen    = 0;
-		msg.msg_flags      = msg_flags | MSG_NOSIGNAL;
+		msg.msg_flags      = MSG_NOSIGNAL;
 
-		if (send)
-			result = kernel_sendmsg(sock, &msg, &iov, 1, size);
-		else
-			result = kernel_recvmsg(sock, &msg, &iov, 1, size,
-						MSG_WAITALL);
-
+		result = kernel_recvmsg(sock, &msg, &iov, 1, size, MSG_WAITALL);
 		if (result <= 0) {
-			pr_debug("%s sock %p buf %p size %u ret %d total %d\n",
-				 send ? "send" : "receive", sock, buf, size,
-				 result, total);
+			pr_debug("receive sock %p buf %p size %u ret %d total %d\n",
+				 sock, buf, size, result, total);
 			goto err;
 		}
 
 		size -= result;
 		buf += result;
 		total += result;
-
 	} while (size > 0);
 
 	if (usbip_dbg_flag_xmit) {
-		if (!send) {
-			if (!in_interrupt())
-				pr_debug("%-10s:", current->comm);
-			else
-				pr_debug("interrupt  :");
+		if (!in_interrupt())
+			pr_debug("%-10s:", current->comm);
+		else
+			pr_debug("interrupt  :");
 
-			pr_debug("receiving....\n");
-			usbip_dump_buffer(bp, osize);
-			pr_debug("received, osize %d ret %d size %d total %d\n",
-				 osize, result, size, total);
-		}
-
-		if (send)
-			pr_debug("send, total %d\n", total);
+		pr_debug("receiving....\n");
+		usbip_dump_buffer(bp, osize);
+		pr_debug("received, osize %d ret %d size %d total %d\n",
+			osize, result, size, total);
 	}
 
 	return total;
@@ -420,7 +394,7 @@
 err:
 	return result;
 }
-EXPORT_SYMBOL_GPL(usbip_xmit);
+EXPORT_SYMBOL_GPL(usbip_recv);
 
 struct socket *sockfd_to_socket(unsigned int sockfd)
 {
@@ -712,7 +686,7 @@
 	if (!buff)
 		return -ENOMEM;
 
-	ret = usbip_xmit(0, ud->tcp_socket, buff, size, 0);
+	ret = usbip_recv(ud->tcp_socket, buff, size);
 	if (ret != size) {
 		dev_err(&urb->dev->dev, "recv iso_frame_descriptor, %d\n",
 			ret);
@@ -823,8 +797,7 @@
 	if (!(size > 0))
 		return 0;
 
-	ret = usbip_xmit(0, ud->tcp_socket, (char *)urb->transfer_buffer,
-			 size, 0);
+	ret = usbip_recv(ud->tcp_socket, urb->transfer_buffer, size);
 	if (ret != size) {
 		dev_err(&urb->dev->dev, "recv xbuf, %d\n", ret);
 		if (ud->side == USBIP_STUB) {
diff --git a/drivers/staging/usbip/usbip_common.h b/drivers/staging/usbip/usbip_common.h
index be21617..b8f8c48 100644
--- a/drivers/staging/usbip/usbip_common.h
+++ b/drivers/staging/usbip/usbip_common.h
@@ -292,21 +292,11 @@
 	} eh_ops;
 };
 
-#if 0
-int usbip_sendmsg(struct socket *, struct msghdr *, int);
-int set_sockaddr(struct socket *socket, struct sockaddr_storage *ss);
-int setnodelay(struct socket *);
-int setquickack(struct socket *);
-int setkeepalive(struct socket *socket);
-void setreuse(struct socket *);
-#endif
-
 /* usbip_common.c */
 void usbip_dump_urb(struct urb *purb);
 void usbip_dump_header(struct usbip_header *pdu);
 
-int usbip_xmit(int send, struct socket *sock, char *buf, int size,
-	       int msg_flags);
+int usbip_recv(struct socket *sock, void *buf, int size);
 struct socket *sockfd_to_socket(unsigned int sockfd);
 
 void usbip_pack_pdu(struct usbip_header *pdu, struct urb *urb, int cmd,
@@ -337,9 +327,4 @@
 	return udev->devnum;
 }
 
-static inline int interface_to_infnum(struct usb_interface *interface)
-{
-	return interface->cur_altsetting->desc.bInterfaceNumber;
-}
-
 #endif /* __USBIP_COMMON_H */
diff --git a/drivers/staging/usbip/vhci_rx.c b/drivers/staging/usbip/vhci_rx.c
index 3872b8c..3f511b4 100644
--- a/drivers/staging/usbip/vhci_rx.c
+++ b/drivers/staging/usbip/vhci_rx.c
@@ -206,7 +206,7 @@
 	memset(&pdu, 0, sizeof(pdu));
 
 	/* 1. receive a pdu header */
-	ret = usbip_xmit(0, ud->tcp_socket, (char *) &pdu, sizeof(pdu), 0);
+	ret = usbip_recv(ud->tcp_socket, &pdu, sizeof(pdu));
 	if (ret < 0) {
 		if (ret == -ECONNRESET)
 			pr_info("connection reset by peer\n");
diff --git a/drivers/staging/vme/TODO b/drivers/staging/vme/TODO
index 82c222b..79f0033 100644
--- a/drivers/staging/vme/TODO
+++ b/drivers/staging/vme/TODO
@@ -1,70 +1,5 @@
 				TODO
 				====
 
-API
-===
-
-Master window broadcast select mask
------------------------------------
-
-API currently provides no method to set or get Broadcast Select mask. Suggest
-somthing like:
-
-	int vme_master_bmsk_set (struct vme_resource *res, int mask);
-	int vme_master_bmsk_get (struct vme_resource *res, int *mask);
-
-
-Interrupt Generation
---------------------
-
-Add optional timeout when waiting for an IACK.
-
-
-CR/CSR Buffer
--------------
-
-The VME API provides no functions to access the buffer mapped into the CR/CSR
-space.
-
-
-Mailboxes
----------
-
-Whilst not part of the VME specification, they are provided by a number of
-chips. They are currently not supported at all by the API.
-
-
-Core
-====
-
-- Improve generic sanity checks (Such as does an offset and size fit within a
-  window and parameter checking).
-
-Bridge Support
-==============
-
-Tempe (tsi148)
---------------
-
-- 2eSST Broadcast mode.
-- Mailboxes unsupported.
-- Improve error detection.
-- Control of prefetch size, threshold.
-- Arbiter control
-- Requestor control
-
-Universe II (ca91c142)
-----------------------
-
-- Mailboxes unsupported.
-- Error Detection.
-- Control of prefetch size, threshold.
-- Arbiter control
-- Requestor control
-- Slot detection
-
-Universe I (ca91x042)
----------------------
-
-Currently completely unsupported.
+- Add one or more device drivers which use the VME framework.
 
diff --git a/drivers/staging/vme/bridges/vme_ca91cx42.c b/drivers/staging/vme/bridges/vme_ca91cx42.c
index 0e4feac..515b8b8 100644
--- a/drivers/staging/vme/bridges/vme_ca91cx42.c
+++ b/drivers/staging/vme/bridges/vme_ca91cx42.c
@@ -338,7 +338,7 @@
 
 static int ca91cx42_slave_set(struct vme_slave_resource *image, int enabled,
 	unsigned long long vme_base, unsigned long long size,
-	dma_addr_t pci_base, vme_address_t aspace, vme_cycle_t cycle)
+	dma_addr_t pci_base, u32 aspace, u32 cycle)
 {
 	unsigned int i, addr = 0, granularity;
 	unsigned int temp_ctl = 0;
@@ -444,7 +444,7 @@
 
 static int ca91cx42_slave_get(struct vme_slave_resource *image, int *enabled,
 	unsigned long long *vme_base, unsigned long long *size,
-	dma_addr_t *pci_base, vme_address_t *aspace, vme_cycle_t *cycle)
+	dma_addr_t *pci_base, u32 *aspace, u32 *cycle)
 {
 	unsigned int i, granularity = 0, ctl = 0;
 	unsigned long long vme_bound, pci_offset;
@@ -595,8 +595,8 @@
 
 
 static int ca91cx42_master_set(struct vme_master_resource *image, int enabled,
-	unsigned long long vme_base, unsigned long long size,
-	vme_address_t aspace, vme_cycle_t cycle, vme_width_t dwidth)
+	unsigned long long vme_base, unsigned long long size, u32 aspace,
+	u32 cycle, u32 dwidth)
 {
 	int retval = 0;
 	unsigned int i, granularity = 0;
@@ -753,7 +753,7 @@
 
 static int __ca91cx42_master_get(struct vme_master_resource *image,
 	int *enabled, unsigned long long *vme_base, unsigned long long *size,
-	vme_address_t *aspace, vme_cycle_t *cycle, vme_width_t *dwidth)
+	u32 *aspace, u32 *cycle, u32 *dwidth)
 {
 	unsigned int i, ctl;
 	unsigned long long pci_base, pci_bound, vme_offset;
@@ -839,8 +839,8 @@
 }
 
 static int ca91cx42_master_get(struct vme_master_resource *image, int *enabled,
-	unsigned long long *vme_base, unsigned long long *size,
-	vme_address_t *aspace, vme_cycle_t *cycle, vme_width_t *dwidth)
+	unsigned long long *vme_base, unsigned long long *size, u32 *aspace,
+	u32 *cycle, u32 *dwidth)
 {
 	int retval;
 
@@ -876,13 +876,13 @@
 	 * maximal configured data cycle is used and splits it
 	 * automatically for non-aligned addresses.
 	 */
-	if ((int)addr & 0x1) {
+	if ((uintptr_t)addr & 0x1) {
 		*(u8 *)buf = ioread8(addr);
 		done += 1;
 		if (done == count)
 			goto out;
 	}
-	if ((int)addr & 0x2) {
+	if ((uintptr_t)addr & 0x2) {
 		if ((count - done) < 2) {
 			*(u8 *)(buf + done) = ioread8(addr + done);
 			done += 1;
@@ -930,13 +930,13 @@
 	/* Here we apply for the same strategy we do in master_read
 	 * function in order to assure D16 cycle when required.
 	 */
-	if ((int)addr & 0x1) {
+	if ((uintptr_t)addr & 0x1) {
 		iowrite8(*(u8 *)buf, addr);
 		done += 1;
 		if (done == count)
 			goto out;
 	}
-	if ((int)addr & 0x2) {
+	if ((uintptr_t)addr & 0x2) {
 		if ((count - done) < 2) {
 			iowrite8(*(u8 *)(buf + done), addr + done);
 			done += 1;
@@ -973,7 +973,8 @@
 	unsigned int mask, unsigned int compare, unsigned int swap,
 	loff_t offset)
 {
-	u32 pci_addr, result;
+	u32 result;
+	uintptr_t pci_addr;
 	int i;
 	struct ca91cx42_driver *bridge;
 	struct device *dev;
@@ -990,7 +991,7 @@
 	/* Lock image */
 	spin_lock(&image->lock);
 
-	pci_addr = (u32)image->kern_base + offset;
+	pci_addr = (uintptr_t)image->kern_base + offset;
 
 	/* Address must be 4-byte aligned */
 	if (pci_addr & 0x3) {
@@ -1291,7 +1292,7 @@
  * callback is attached and disabled when the last callback is removed.
  */
 static int ca91cx42_lm_set(struct vme_lm_resource *lm,
-	unsigned long long lm_base, vme_address_t aspace, vme_cycle_t cycle)
+	unsigned long long lm_base, u32 aspace, u32 cycle)
 {
 	u32 temp_base, lm_ctl = 0;
 	int i;
@@ -1359,7 +1360,7 @@
  * or disabled.
  */
 static int ca91cx42_lm_get(struct vme_lm_resource *lm,
-	unsigned long long *lm_base, vme_address_t *aspace, vme_cycle_t *cycle)
+	unsigned long long *lm_base, u32 *aspace, u32 *cycle)
 {
 	u32 lm_ctl, enabled = 0;
 	struct ca91cx42_driver *bridge;
diff --git a/drivers/staging/vme/bridges/vme_tsi148.c b/drivers/staging/vme/bridges/vme_tsi148.c
index 6c1167c..08a449b 100644
--- a/drivers/staging/vme/bridges/vme_tsi148.c
+++ b/drivers/staging/vme/bridges/vme_tsi148.c
@@ -483,7 +483,7 @@
  * Find the first error in this address range
  */
 static struct vme_bus_error *tsi148_find_error(struct vme_bridge *tsi148_bridge,
-	vme_address_t aspace, unsigned long long address, size_t count)
+	u32 aspace, unsigned long long address, size_t count)
 {
 	struct list_head *err_pos;
 	struct vme_bus_error *vme_err, *valid = NULL;
@@ -517,7 +517,7 @@
  * Clear errors in the provided address range.
  */
 static void tsi148_clear_errors(struct vme_bridge *tsi148_bridge,
-	vme_address_t aspace, unsigned long long address, size_t count)
+	u32 aspace, unsigned long long address, size_t count)
 {
 	struct list_head *err_pos, *temp;
 	struct vme_bus_error *vme_err;
@@ -551,7 +551,7 @@
  */
 static int tsi148_slave_set(struct vme_slave_resource *image, int enabled,
 	unsigned long long vme_base, unsigned long long size,
-	dma_addr_t pci_base, vme_address_t aspace, vme_cycle_t cycle)
+	dma_addr_t pci_base, u32 aspace, u32 cycle)
 {
 	unsigned int i, addr = 0, granularity = 0;
 	unsigned int temp_ctl = 0;
@@ -701,7 +701,7 @@
  */
 static int tsi148_slave_get(struct vme_slave_resource *image, int *enabled,
 	unsigned long long *vme_base, unsigned long long *size,
-	dma_addr_t *pci_base, vme_address_t *aspace, vme_cycle_t *cycle)
+	dma_addr_t *pci_base, u32 *aspace, u32 *cycle)
 {
 	unsigned int i, granularity = 0, ctl = 0;
 	unsigned int vme_base_low, vme_base_high;
@@ -893,8 +893,8 @@
  * Set the attributes of an outbound window.
  */
 static int tsi148_master_set(struct vme_master_resource *image, int enabled,
-	unsigned long long vme_base, unsigned long long size,
-	vme_address_t aspace, vme_cycle_t cycle, vme_width_t dwidth)
+	unsigned long long vme_base, unsigned long long size, u32 aspace,
+	u32 cycle, u32 dwidth)
 {
 	int retval = 0;
 	unsigned int i;
@@ -1129,8 +1129,8 @@
  * XXX Not parsing prefetch information.
  */
 static int __tsi148_master_get(struct vme_master_resource *image, int *enabled,
-	unsigned long long *vme_base, unsigned long long *size,
-	vme_address_t *aspace, vme_cycle_t *cycle, vme_width_t *dwidth)
+	unsigned long long *vme_base, unsigned long long *size, u32 *aspace,
+	u32 *cycle, u32 *dwidth)
 {
 	unsigned int i, ctl;
 	unsigned int pci_base_low, pci_base_high;
@@ -1239,8 +1239,8 @@
 
 
 static int tsi148_master_get(struct vme_master_resource *image, int *enabled,
-	unsigned long long *vme_base, unsigned long long *size,
-	vme_address_t *aspace, vme_cycle_t *cycle, vme_width_t *dwidth)
+	unsigned long long *vme_base, unsigned long long *size, u32 *aspace,
+	u32 *cycle, u32 *dwidth)
 {
 	int retval;
 
@@ -1259,9 +1259,7 @@
 {
 	int retval, enabled;
 	unsigned long long vme_base, size;
-	vme_address_t aspace;
-	vme_cycle_t cycle;
-	vme_width_t dwidth;
+	u32 aspace, cycle, dwidth;
 	struct vme_bus_error *vme_err = NULL;
 	struct vme_bridge *tsi148_bridge;
 
@@ -1301,9 +1299,7 @@
 {
 	int retval = 0, enabled;
 	unsigned long long vme_base, size;
-	vme_address_t aspace;
-	vme_cycle_t cycle;
-	vme_width_t dwidth;
+	u32 aspace, cycle, dwidth;
 
 	struct vme_bus_error *vme_err = NULL;
 	struct vme_bridge *tsi148_bridge;
@@ -1420,7 +1416,7 @@
 }
 
 static int tsi148_dma_set_vme_src_attributes(struct device *dev, u32 *attr,
-	vme_address_t aspace, vme_cycle_t cycle, vme_width_t dwidth)
+	u32 aspace, u32 cycle, u32 dwidth)
 {
 	/* Setup 2eSST speeds */
 	switch (cycle & (VME_2eSST160 | VME_2eSST267 | VME_2eSST320)) {
@@ -1514,7 +1510,7 @@
 }
 
 static int tsi148_dma_set_vme_dest_attributes(struct device *dev, u32 *attr,
-	vme_address_t aspace, vme_cycle_t cycle, vme_width_t dwidth)
+	u32 aspace, u32 cycle, u32 dwidth)
 {
 	/* Setup 2eSST speeds */
 	switch (cycle & (VME_2eSST160 | VME_2eSST267 | VME_2eSST320)) {
@@ -1886,7 +1882,7 @@
  * callback is attached and disabled when the last callback is removed.
  */
 static int tsi148_lm_set(struct vme_lm_resource *lm, unsigned long long lm_base,
-	vme_address_t aspace, vme_cycle_t cycle)
+	u32 aspace, u32 cycle)
 {
 	u32 lm_base_high, lm_base_low, lm_ctl = 0;
 	int i;
@@ -1953,7 +1949,7 @@
  * or disabled.
  */
 static int tsi148_lm_get(struct vme_lm_resource *lm,
-	unsigned long long *lm_base, vme_address_t *aspace, vme_cycle_t *cycle)
+	unsigned long long *lm_base, u32 *aspace, u32 *cycle)
 {
 	u32 lm_base_high, lm_base_low, lm_ctl, enabled = 0;
 	struct tsi148_driver *bridge;
diff --git a/drivers/staging/vme/devices/Kconfig b/drivers/staging/vme/devices/Kconfig
index ca5ba89..55ec30c 100644
--- a/drivers/staging/vme/devices/Kconfig
+++ b/drivers/staging/vme/devices/Kconfig
@@ -6,3 +6,16 @@
 	  If you say Y here you want to be able to access a limited number of
 	  VME windows in a manner at least semi-compatible with the interface
 	  provided with the original driver at http://vmelinux.org/.
+
+config VME_PIO2
+	tristate "GE PIO2 VME"
+	depends on GPIOLIB
+	help
+	  Say Y here to include support for the GE PIO2. The PIO2 is a 6U VME
+	  slave card, implementing 32 solid-state relay switched IO lines, in
+	  4 groups of 8. Each bank of IO lines is built to function as input,
+	  output or both depending on the variant of the card.
+
+	  To compile this driver as a module, choose M here. The module will
+	  be called vme_pio2. If unsure, say N.
+
diff --git a/drivers/staging/vme/devices/Makefile b/drivers/staging/vme/devices/Makefile
index 459742a..172512c 100644
--- a/drivers/staging/vme/devices/Makefile
+++ b/drivers/staging/vme/devices/Makefile
@@ -3,3 +3,6 @@
 #
 
 obj-$(CONFIG_VME_USER)		+= vme_user.o
+
+vme_pio2-objs	:= vme_pio2_cntr.o vme_pio2_gpio.o vme_pio2_core.o
+obj-$(CONFIG_VME_PIO2)         += vme_pio2.o
diff --git a/drivers/staging/vme/devices/vme_pio2.h b/drivers/staging/vme/devices/vme_pio2.h
new file mode 100644
index 0000000..3c59313
--- /dev/null
+++ b/drivers/staging/vme/devices/vme_pio2.h
@@ -0,0 +1,249 @@
+#ifndef _VME_PIO2_H_
+#define _VME_PIO2_H_
+
+#define PIO2_CARDS_MAX			32
+
+#define PIO2_VARIANT_LENGTH		5
+
+#define PIO2_NUM_CHANNELS		32
+#define PIO2_NUM_IRQS			11
+#define PIO2_NUM_CNTRS			6
+
+#define PIO2_REGS_SIZE			0x40
+
+#define PIO2_REGS_DATA0			0x0
+#define PIO2_REGS_DATA1			0x1
+#define PIO2_REGS_DATA2			0x2
+#define PIO2_REGS_DATA3			0x3
+
+static const int PIO2_REGS_DATA[4] = { PIO2_REGS_DATA0, PIO2_REGS_DATA1,
+					PIO2_REGS_DATA2, PIO2_REGS_DATA3 };
+
+#define PIO2_REGS_INT_STAT0		0x8
+#define PIO2_REGS_INT_STAT1		0x9
+#define PIO2_REGS_INT_STAT2		0xa
+#define PIO2_REGS_INT_STAT3		0xb
+
+static const int PIO2_REGS_INT_STAT[4] = { PIO2_REGS_INT_STAT0,
+					PIO2_REGS_INT_STAT1,
+					PIO2_REGS_INT_STAT2,
+					PIO2_REGS_INT_STAT3 };
+
+#define PIO2_REGS_INT_STAT_CNTR		0xc
+#define PIO2_REGS_INT_MASK0		0x10
+#define PIO2_REGS_INT_MASK1		0x11
+#define PIO2_REGS_INT_MASK2		0x12
+#define PIO2_REGS_INT_MASK3		0x13
+#define PIO2_REGS_INT_MASK4		0x14
+#define PIO2_REGS_INT_MASK5		0x15
+#define PIO2_REGS_INT_MASK6		0x16
+#define PIO2_REGS_INT_MASK7		0x17
+
+static const int PIO2_REGS_INT_MASK[8] = { PIO2_REGS_INT_MASK0,
+					PIO2_REGS_INT_MASK1,
+					PIO2_REGS_INT_MASK2,
+					PIO2_REGS_INT_MASK3,
+					PIO2_REGS_INT_MASK4,
+					PIO2_REGS_INT_MASK5,
+					PIO2_REGS_INT_MASK6,
+					PIO2_REGS_INT_MASK7 };
+
+
+
+#define PIO2_REGS_CTRL			0x18
+#define PIO2_REGS_VME_VECTOR		0x19
+#define PIO2_REGS_CNTR0			0x20
+#define PIO2_REGS_CNTR1			0x22
+#define PIO2_REGS_CNTR2			0x24
+#define PIO2_REGS_CTRL_WRD0		0x26
+#define PIO2_REGS_CNTR3			0x28
+#define PIO2_REGS_CNTR4			0x2a
+#define PIO2_REGS_CNTR5			0x2c
+#define PIO2_REGS_CTRL_WRD1		0x2e
+
+#define PIO2_REGS_ID			0x30
+
+
+/* PIO2_REGS_DATAx (0x0 - 0x3) */
+
+static const int PIO2_CHANNEL_BANK[32] = { 0, 0, 0, 0, 0, 0, 0, 0,
+					1, 1, 1, 1, 1, 1, 1, 1,
+					2, 2, 2, 2, 2, 2, 2, 2,
+					3, 3, 3, 3, 3, 3, 3, 3 };
+
+#define PIO2_CHANNEL0_BIT		(1 << 0)
+#define PIO2_CHANNEL1_BIT		(1 << 1)
+#define PIO2_CHANNEL2_BIT		(1 << 2)
+#define PIO2_CHANNEL3_BIT		(1 << 3)
+#define PIO2_CHANNEL4_BIT		(1 << 4)
+#define PIO2_CHANNEL5_BIT		(1 << 5)
+#define PIO2_CHANNEL6_BIT		(1 << 6)
+#define PIO2_CHANNEL7_BIT		(1 << 7)
+#define PIO2_CHANNEL8_BIT		(1 << 0)
+#define PIO2_CHANNEL9_BIT		(1 << 1)
+#define PIO2_CHANNEL10_BIT		(1 << 2)
+#define PIO2_CHANNEL11_BIT		(1 << 3)
+#define PIO2_CHANNEL12_BIT		(1 << 4)
+#define PIO2_CHANNEL13_BIT		(1 << 5)
+#define PIO2_CHANNEL14_BIT		(1 << 6)
+#define PIO2_CHANNEL15_BIT		(1 << 7)
+#define PIO2_CHANNEL16_BIT		(1 << 0)
+#define PIO2_CHANNEL17_BIT		(1 << 1)
+#define PIO2_CHANNEL18_BIT		(1 << 2)
+#define PIO2_CHANNEL19_BIT		(1 << 3)
+#define PIO2_CHANNEL20_BIT		(1 << 4)
+#define PIO2_CHANNEL21_BIT		(1 << 5)
+#define PIO2_CHANNEL22_BIT		(1 << 6)
+#define PIO2_CHANNEL23_BIT		(1 << 7)
+#define PIO2_CHANNEL24_BIT		(1 << 0)
+#define PIO2_CHANNEL25_BIT		(1 << 1)
+#define PIO2_CHANNEL26_BIT		(1 << 2)
+#define PIO2_CHANNEL27_BIT		(1 << 3)
+#define PIO2_CHANNEL28_BIT		(1 << 4)
+#define PIO2_CHANNEL29_BIT		(1 << 5)
+#define PIO2_CHANNEL30_BIT		(1 << 6)
+#define PIO2_CHANNEL31_BIT		(1 << 7)
+
+static const int PIO2_CHANNEL_BIT[32] = { PIO2_CHANNEL0_BIT, PIO2_CHANNEL1_BIT,
+					PIO2_CHANNEL2_BIT, PIO2_CHANNEL3_BIT,
+					PIO2_CHANNEL4_BIT, PIO2_CHANNEL5_BIT,
+					PIO2_CHANNEL6_BIT, PIO2_CHANNEL7_BIT,
+					PIO2_CHANNEL8_BIT, PIO2_CHANNEL9_BIT,
+					PIO2_CHANNEL10_BIT, PIO2_CHANNEL11_BIT,
+					PIO2_CHANNEL12_BIT, PIO2_CHANNEL13_BIT,
+					PIO2_CHANNEL14_BIT, PIO2_CHANNEL15_BIT,
+					PIO2_CHANNEL16_BIT, PIO2_CHANNEL17_BIT,
+					PIO2_CHANNEL18_BIT, PIO2_CHANNEL19_BIT,
+					PIO2_CHANNEL20_BIT, PIO2_CHANNEL21_BIT,
+					PIO2_CHANNEL22_BIT, PIO2_CHANNEL23_BIT,
+					PIO2_CHANNEL24_BIT, PIO2_CHANNEL25_BIT,
+					PIO2_CHANNEL26_BIT, PIO2_CHANNEL27_BIT,
+					PIO2_CHANNEL28_BIT, PIO2_CHANNEL29_BIT,
+					PIO2_CHANNEL30_BIT, PIO2_CHANNEL31_BIT
+					};
+
+/* PIO2_REGS_INT_STAT_CNTR (0xc) */
+#define PIO2_COUNTER0			(1 << 0)
+#define PIO2_COUNTER1			(1 << 1)
+#define PIO2_COUNTER2			(1 << 2)
+#define PIO2_COUNTER3			(1 << 3)
+#define PIO2_COUNTER4			(1 << 4)
+#define PIO2_COUNTER5			(1 << 5)
+
+static const int PIO2_COUNTER[6] = { PIO2_COUNTER0, PIO2_COUNTER1,
+					PIO2_COUNTER2, PIO2_COUNTER3,
+					PIO2_COUNTER4, PIO2_COUNTER5 };
+
+/* PIO2_REGS_CTRL (0x18) */
+#define PIO2_VME_INT_MASK		0x7
+#define PIO2_LED			(1 << 6)
+#define PIO2_LOOP			(1 << 7)
+
+/* PIO2_REGS_VME_VECTOR (0x19) */
+#define PIO2_VME_VECTOR_SPUR		0x0
+#define PIO2_VME_VECTOR_BANK0		0x1
+#define PIO2_VME_VECTOR_BANK1		0x2
+#define PIO2_VME_VECTOR_BANK2		0x3
+#define PIO2_VME_VECTOR_BANK3		0x4
+#define PIO2_VME_VECTOR_CNTR0		0x5
+#define PIO2_VME_VECTOR_CNTR1		0x6
+#define PIO2_VME_VECTOR_CNTR2		0x7
+#define PIO2_VME_VECTOR_CNTR3		0x8
+#define PIO2_VME_VECTOR_CNTR4		0x9
+#define PIO2_VME_VECTOR_CNTR5		0xa
+
+#define PIO2_VME_VECTOR_MASK		0xf0
+
+static const int PIO2_VECTOR_BANK[4] = { PIO2_VME_VECTOR_BANK0,
+					PIO2_VME_VECTOR_BANK1,
+					PIO2_VME_VECTOR_BANK2,
+					PIO2_VME_VECTOR_BANK3 };
+
+static const int PIO2_VECTOR_CNTR[6] = { PIO2_VME_VECTOR_CNTR0,
+					PIO2_VME_VECTOR_CNTR1,
+					PIO2_VME_VECTOR_CNTR2,
+					PIO2_VME_VECTOR_CNTR3,
+					PIO2_VME_VECTOR_CNTR4,
+					PIO2_VME_VECTOR_CNTR5 };
+
+/* PIO2_REGS_CNTRx (0x20 - 0x24 & 0x28 - 0x2c) */
+
+static const int PIO2_CNTR_DATA[6] = { PIO2_REGS_CNTR0, PIO2_REGS_CNTR1,
+					PIO2_REGS_CNTR2, PIO2_REGS_CNTR3,
+					PIO2_REGS_CNTR4, PIO2_REGS_CNTR5 };
+
+/* PIO2_REGS_CTRL_WRDx (0x26 & 0x2e) */
+
+static const int PIO2_CNTR_CTRL[6] = { PIO2_REGS_CTRL_WRD0,
+					PIO2_REGS_CTRL_WRD0,
+					PIO2_REGS_CTRL_WRD0,
+					PIO2_REGS_CTRL_WRD1,
+					PIO2_REGS_CTRL_WRD1,
+					PIO2_REGS_CTRL_WRD1 };
+
+#define PIO2_CNTR_SC_DEV0		0
+#define PIO2_CNTR_SC_DEV1		(1 << 6)
+#define PIO2_CNTR_SC_DEV2		(2 << 6)
+#define PIO2_CNTR_SC_RDBACK		(3 << 6)
+
+static const int PIO2_CNTR_SC_DEV[6] = { PIO2_CNTR_SC_DEV0, PIO2_CNTR_SC_DEV1,
+					PIO2_CNTR_SC_DEV2, PIO2_CNTR_SC_DEV0,
+					PIO2_CNTR_SC_DEV1, PIO2_CNTR_SC_DEV2 };
+
+#define PIO2_CNTR_RW_LATCH		0
+#define PIO2_CNTR_RW_LSB		(1 << 4)
+#define PIO2_CNTR_RW_MSB		(2 << 4)
+#define PIO2_CNTR_RW_BOTH		(3 << 4)
+
+#define PIO2_CNTR_MODE0			0
+#define PIO2_CNTR_MODE1			(1 << 1)
+#define PIO2_CNTR_MODE2			(2 << 1)
+#define PIO2_CNTR_MODE3			(3 << 1)
+#define PIO2_CNTR_MODE4			(4 << 1)
+#define PIO2_CNTR_MODE5			(5 << 1)
+
+#define PIO2_CNTR_BCD			1
+
+
+
+enum pio2_bank_config { NOFIT, INPUT, OUTPUT, BOTH };
+enum pio2_int_config { NONE = 0, LOW2HIGH = 1, HIGH2LOW = 2, EITHER = 4 };
+
+/* Bank configuration structure */
+struct pio2_io_bank {
+	enum pio2_bank_config config;
+	u8 value;
+	enum pio2_int_config irq[8];
+};
+
+/* Counter configuration structure */
+struct pio2_cntr {
+	int mode;
+	int count;
+};
+
+struct pio2_card {
+	int id;
+	int bus;
+	long base;
+	int irq_vector;
+	int irq_level;
+	char variant[6];
+	int led;
+
+	struct vme_dev *vdev;
+	struct vme_resource *window;
+
+	struct gpio_chip gc;
+	struct pio2_io_bank bank[4];
+
+	struct pio2_cntr cntr[6];
+};
+
+int pio2_cntr_reset(struct pio2_card *);
+
+int pio2_gpio_reset(struct pio2_card *);
+int __init pio2_gpio_init(struct pio2_card *);
+void __exit pio2_gpio_exit(struct pio2_card *);
+
+#endif /* _VME_PIO2_H_ */
diff --git a/drivers/staging/vme/devices/vme_pio2_cntr.c b/drivers/staging/vme/devices/vme_pio2_cntr.c
new file mode 100644
index 0000000..08e0d59
--- /dev/null
+++ b/drivers/staging/vme/devices/vme_pio2_cntr.c
@@ -0,0 +1,71 @@
+/*
+ * GE PIO2 Counter Driver
+ *
+ * Author: Martyn Welch <martyn.welch@ge.com>
+ * Copyright 2009 GE Intelligent Platforms Embedded Systems, Inc.
+ *
+ * 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.
+ *
+ * The PIO-2 has 6 counters, currently this code just disables the interrupts
+ * and leaves them alone.
+ *
+ */
+
+#include <linux/device.h>
+#include <linux/types.h>
+#include <linux/gpio.h>
+
+#include "../vme.h"
+#include "vme_pio2.h"
+
+static int pio2_cntr_irq_set(struct pio2_card *card, int id)
+{
+	int retval;
+	u8 data;
+
+	data = PIO2_CNTR_SC_DEV[id] | PIO2_CNTR_RW_BOTH | card->cntr[id].mode;
+	retval = vme_master_write(card->window, &data, 1, PIO2_CNTR_CTRL[id]);
+	if (retval < 0)
+		return retval;
+
+	data = card->cntr[id].count & 0xFF;
+	retval = vme_master_write(card->window, &data, 1, PIO2_CNTR_DATA[id]);
+	if (retval < 0)
+		return retval;
+
+	data = (card->cntr[id].count >> 8) & 0xFF;
+	retval = vme_master_write(card->window, &data, 1, PIO2_CNTR_DATA[id]);
+	if (retval < 0)
+		return retval;
+
+	return 0;
+}
+
+int pio2_cntr_reset(struct pio2_card *card)
+{
+	int i, retval = 0;
+	u8 reg;
+
+	/* Clear down all timers */
+	for (i = 0; i < 6; i++) {
+		card->cntr[i].mode = PIO2_CNTR_MODE5;
+		card->cntr[i].count = 0;
+		retval = pio2_cntr_irq_set(card, i);
+		if (retval < 0)
+			return retval;
+	}
+
+	/* Ensure all counter interrupts are cleared */
+	do {
+		retval = vme_master_read(card->window, &reg, 1,
+			PIO2_REGS_INT_STAT_CNTR);
+		if (retval < 0)
+			return retval;
+	} while (reg != 0);
+
+	return retval;
+}
+
diff --git a/drivers/staging/vme/devices/vme_pio2_core.c b/drivers/staging/vme/devices/vme_pio2_core.c
new file mode 100644
index 0000000..9fedc44
--- /dev/null
+++ b/drivers/staging/vme/devices/vme_pio2_core.c
@@ -0,0 +1,524 @@
+/*
+ * GE PIO2 6U VME I/O Driver
+ *
+ * Author: Martyn Welch <martyn.welch@ge.com>
+ * Copyright 2009 GE Intelligent Platforms Embedded Systems, Inc.
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ */
+
+#include <linux/version.h>
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/device.h>
+#include <linux/ctype.h>
+#include <linux/gpio.h>
+#include <linux/slab.h>
+
+#include "../vme.h"
+#include "vme_pio2.h"
+
+
+static const char driver_name[] = "pio2";
+
+static int bus[PIO2_CARDS_MAX];
+static int bus_num;
+static long base[PIO2_CARDS_MAX];
+static int base_num;
+static int vector[PIO2_CARDS_MAX];
+static int vector_num;
+static int level[PIO2_CARDS_MAX];
+static int level_num;
+static const char *variant[PIO2_CARDS_MAX];
+static int variant_num;
+
+static int loopback;
+
+static int pio2_match(struct vme_dev *);
+static int __devinit pio2_probe(struct vme_dev *);
+static int __devexit pio2_remove(struct vme_dev *);
+
+static int pio2_get_led(struct pio2_card *card)
+{
+	/* Can't read hardware, state saved in structure */
+	return card->led;
+}
+
+static int pio2_set_led(struct pio2_card *card, int state)
+{
+	u8 reg;
+	int retval;
+
+	reg = card->irq_level;
+
+	/* Register state inverse of led state */
+	if (!state)
+		reg |= PIO2_LED;
+
+	if (loopback)
+		reg |= PIO2_LOOP;
+
+	retval = vme_master_write(card->window, &reg, 1, PIO2_REGS_CTRL);
+	if (retval < 0)
+		return retval;
+
+	card->led = state ? 1 : 0;
+
+	return 0;
+}
+
+static void pio2_int(int level, int vector, void *ptr)
+{
+	int vec, i, channel, retval;
+	u8 reg;
+	struct pio2_card *card  = ptr;
+
+	vec = vector & ~PIO2_VME_VECTOR_MASK;
+
+	switch (vec) {
+	case 0:
+		dev_warn(&card->vdev->dev, "Spurious Interrupt\n");
+		break;
+	case 1:
+	case 2:
+	case 3:
+	case 4:
+		/* Channels 0 to 7 */
+		retval = vme_master_read(card->window, &reg, 1,
+			PIO2_REGS_INT_STAT[vec - 1]);
+		if (retval < 0) {
+			dev_err(&card->vdev->dev,
+				"Unable to read IRQ status register\n");
+			return;
+		}
+		for (i = 0; i < 8; i++) {
+			channel = ((vec - 1) * 8) + i;
+			if (reg & PIO2_CHANNEL_BIT[channel])
+				dev_info(&card->vdev->dev,
+					"Interrupt on I/O channel %d\n",
+					channel);
+		}
+		break;
+	case 5:
+	case 6:
+	case 7:
+	case 8:
+	case 9:
+	case 10:
+		/* Counters are dealt with by their own handler */
+		dev_err(&card->vdev->dev,
+			"Counter interrupt\n");
+		break;
+	}
+}
+
+
+/*
+ * We return whether this has been successful - this is used in the probe to
+ * ensure we have a valid card.
+ */
+static int pio2_reset_card(struct pio2_card *card)
+{
+	int retval = 0;
+	u8 data = 0;
+
+	/* Clear main register*/
+	retval = vme_master_write(card->window, &data, 1, PIO2_REGS_CTRL);
+	if (retval < 0)
+		return retval;
+
+	/* Clear VME vector */
+	retval = vme_master_write(card->window, &data, 1, PIO2_REGS_VME_VECTOR);
+	if (retval < 0)
+		return retval;
+
+	/* Reset GPIO */
+	retval = pio2_gpio_reset(card);
+	if (retval < 0)
+		return retval;
+
+	/* Reset counters */
+	retval = pio2_cntr_reset(card);
+	if (retval < 0)
+		return retval;
+
+	return 0;
+}
+
+static struct vme_driver pio2_driver = {
+	.name = driver_name,
+	.match = pio2_match,
+	.probe = pio2_probe,
+	.remove = __devexit_p(pio2_remove),
+};
+
+
+static int __init pio2_init(void)
+{
+	int retval = 0;
+
+	if (bus_num == 0) {
+		printk(KERN_ERR "%s: No cards, skipping registration\n",
+			driver_name);
+		goto err_nocard;
+	}
+
+	if (bus_num > PIO2_CARDS_MAX) {
+		printk(KERN_ERR
+			"%s: Driver only able to handle %d PIO2 Cards\n",
+			driver_name, PIO2_CARDS_MAX);
+		bus_num = PIO2_CARDS_MAX;
+	}
+
+	/* Register the PIO2 driver */
+	retval = vme_register_driver(&pio2_driver, bus_num);
+	if (retval != 0)
+		goto err_reg;
+
+	return retval;
+
+err_reg:
+err_nocard:
+	return retval;
+}
+
+static int pio2_match(struct vme_dev *vdev)
+{
+
+	if (vdev->num >= bus_num) {
+		dev_err(&vdev->dev,
+			"The enumeration of the VMEbus to which the board is connected must be specified");
+		return 0;
+	}
+
+	if (vdev->num >= base_num) {
+		dev_err(&vdev->dev,
+			"The VME address for the cards registers must be specified");
+		return 0;
+	}
+
+	if (vdev->num >= vector_num) {
+		dev_err(&vdev->dev,
+			"The IRQ vector used by the card must be specified");
+		return 0;
+	}
+
+	if (vdev->num >= level_num) {
+		dev_err(&vdev->dev,
+			"The IRQ level used by the card must be specified");
+		return 0;
+	}
+
+	if (vdev->num >= variant_num) {
+		dev_err(&vdev->dev, "The variant of the card must be specified");
+		return 0;
+	}
+
+	return 1;
+}
+
+static int __devinit pio2_probe(struct vme_dev *vdev)
+{
+	struct pio2_card *card;
+	int retval;
+	int i;
+	u8 reg;
+	int vec;
+
+	card = kzalloc(sizeof(struct pio2_card), GFP_KERNEL);
+	if (card == NULL) {
+		dev_err(&vdev->dev, "Unable to allocate card structure\n");
+		retval = -ENOMEM;
+		goto err_struct;
+	}
+
+	card->id = vdev->num;
+	card->bus = bus[card->id];
+	card->base = base[card->id];
+	card->irq_vector = vector[card->id];
+	card->irq_level = level[card->id] & PIO2_VME_INT_MASK;
+	strncpy(card->variant, variant[card->id], PIO2_VARIANT_LENGTH);
+	card->vdev = vdev;
+
+	for (i = 0; i < PIO2_VARIANT_LENGTH; i++) {
+
+		if (isdigit(card->variant[i]) == 0) {
+			dev_err(&card->vdev->dev, "Variant invalid\n");
+			retval = -EINVAL;
+			goto err_variant;
+		}
+	}
+
+	/*
+	 * Bottom 4 bits of VME interrupt vector used to determine source,
+	 * provided vector should only use upper 4 bits.
+	 */
+	if (card->irq_vector & ~PIO2_VME_VECTOR_MASK) {
+		dev_err(&card->vdev->dev,
+			"Invalid VME IRQ Vector, vector must not use lower 4 bits\n");
+		retval = -EINVAL;
+		goto err_vector;
+	}
+
+	/*
+	 * There is no way to determine the build variant or whether each bank
+	 * is input, output or both at run time. The inputs are also inverted
+	 * if configured as both.
+	 *
+	 * We pass in the board variant and use that to determine the
+	 * configuration of the banks.
+	 */
+	for (i = 1; i < PIO2_VARIANT_LENGTH; i++) {
+		switch (card->variant[i]) {
+		case '0':
+			card->bank[i-1].config = NOFIT;
+			break;
+		case '1':
+		case '2':
+		case '3':
+		case '4':
+			card->bank[i-1].config = INPUT;
+			break;
+		case '5':
+			card->bank[i-1].config = OUTPUT;
+			break;
+		case '6':
+		case '7':
+		case '8':
+		case '9':
+			card->bank[i-1].config = BOTH;
+			break;
+		}
+	}
+
+	/* Get a master window and position over regs */
+	card->window = vme_master_request(vdev, VME_A24, VME_SCT, VME_D16);
+	if (card->window == NULL) {
+		dev_err(&card->vdev->dev,
+			"Unable to assign VME master resource\n");
+		retval = -EIO;
+		goto err_window;
+	}
+
+	retval = vme_master_set(card->window, 1, card->base, 0x10000, VME_A24,
+		(VME_SCT | VME_USER | VME_DATA), VME_D16);
+	if (retval) {
+		dev_err(&card->vdev->dev,
+			"Unable to configure VME master resource\n");
+		goto err_set;
+	}
+
+	/*
+	 * There is also no obvious register which we can probe to determine
+	 * whether the provided base is valid. If we can read the "ID Register"
+	 * offset and the reset function doesn't error, assume we have a valid
+	 * location.
+	 */
+	retval = vme_master_read(card->window, &reg, 1, PIO2_REGS_ID);
+	if (retval < 0) {
+		dev_err(&card->vdev->dev, "Unable to read from device\n");
+		goto err_read;
+	}
+
+	dev_dbg(&card->vdev->dev, "ID Register:%x\n", reg);
+
+	/*
+	 * Ensure all the I/O is cleared. We can't read back the states, so
+	 * this is the only method we have to ensure that the I/O is in a known
+	 * state.
+	 */
+	retval = pio2_reset_card(card);
+	if (retval) {
+		dev_err(&card->vdev->dev,
+			"Failed to reset card, is location valid?");
+		retval = -ENODEV;
+		goto err_reset;
+	}
+
+	/* Configure VME Interrupts */
+	reg = card->irq_level;
+	if (pio2_get_led(card))
+		reg |= PIO2_LED;
+	if (loopback)
+		reg |= PIO2_LOOP;
+	retval = vme_master_write(card->window, &reg, 1, PIO2_REGS_CTRL);
+	if (retval < 0)
+		return retval;
+
+	/* Set VME vector */
+	retval = vme_master_write(card->window, &card->irq_vector, 1,
+		PIO2_REGS_VME_VECTOR);
+	if (retval < 0)
+		return retval;
+
+	/* Attach spurious interrupt handler. */
+	vec = card->irq_vector | PIO2_VME_VECTOR_SPUR;
+
+	retval = vme_irq_request(vdev, card->irq_level, vec,
+		&pio2_int, (void *)card);
+	if (retval < 0) {
+		dev_err(&card->vdev->dev,
+			"Unable to attach VME interrupt vector0x%x, level 0x%x\n",
+			 vec, card->irq_level);
+		goto err_irq;
+	}
+
+	/* Attach GPIO interrupt handlers. */
+	for (i = 0; i < 4; i++) {
+		vec = card->irq_vector | PIO2_VECTOR_BANK[i];
+
+		retval = vme_irq_request(vdev, card->irq_level, vec,
+			&pio2_int, (void *)card);
+		if (retval < 0) {
+			dev_err(&card->vdev->dev,
+				"Unable to attach VME interrupt vector0x%x, level 0x%x\n",
+				 vec, card->irq_level);
+			goto err_gpio_irq;
+		}
+	}
+
+	/* Attach counter interrupt handlers. */
+	for (i = 0; i < 6; i++) {
+		vec = card->irq_vector | PIO2_VECTOR_CNTR[i];
+
+		retval = vme_irq_request(vdev, card->irq_level, vec,
+			&pio2_int, (void *)card);
+		if (retval < 0) {
+			dev_err(&card->vdev->dev,
+				"Unable to attach VME interrupt vector0x%x, level 0x%x\n",
+				vec, card->irq_level);
+			goto err_cntr_irq;
+		}
+	}
+
+	/* Register IO */
+	retval = pio2_gpio_init(card);
+	if (retval < 0) {
+		dev_err(&card->vdev->dev,
+			"Unable to register with GPIO framework\n");
+		goto err_gpio;
+	}
+
+	/* Set LED - This also sets interrupt level */
+	retval = pio2_set_led(card, 0);
+	if (retval < 0) {
+		dev_err(&card->vdev->dev, "Unable to set LED\n");
+		goto err_led;
+	}
+
+	dev_set_drvdata(&card->vdev->dev, card);
+
+	dev_info(&card->vdev->dev,
+		"PIO2 (variant %s) configured at 0x%lx\n", card->variant,
+		card->base);
+
+	return 0;
+
+err_led:
+	pio2_gpio_exit(card);
+err_gpio:
+	i = 6;
+err_cntr_irq:
+	while (i > 0) {
+		i--;
+		vec = card->irq_vector | PIO2_VECTOR_CNTR[i];
+		vme_irq_free(vdev, card->irq_level, vec);
+	}
+
+	i = 4;
+err_gpio_irq:
+	while (i > 0) {
+		i--;
+		vec = card->irq_vector | PIO2_VECTOR_BANK[i];
+		vme_irq_free(vdev, card->irq_level, vec);
+	}
+
+	vec = (card->irq_vector & PIO2_VME_VECTOR_MASK) | PIO2_VME_VECTOR_SPUR;
+	vme_irq_free(vdev, card->irq_level, vec);
+err_irq:
+	 pio2_reset_card(card);
+err_reset:
+err_read:
+	vme_master_set(card->window, 0, 0, 0, VME_A16, 0, VME_D16);
+err_set:
+	vme_master_free(card->window);
+err_window:
+err_vector:
+err_variant:
+	kfree(card);
+err_struct:
+	return retval;
+}
+
+static int __devexit pio2_remove(struct vme_dev *vdev)
+{
+	int vec;
+	int i;
+
+	struct pio2_card *card = dev_get_drvdata(&vdev->dev);
+
+	pio2_gpio_exit(card);
+
+	for (i = 0; i < 6; i++) {
+		vec = card->irq_vector | PIO2_VECTOR_CNTR[i];
+		vme_irq_free(vdev, card->irq_level, vec);
+	}
+
+	for (i = 0; i < 4; i++) {
+		vec = card->irq_vector | PIO2_VECTOR_BANK[i];
+		vme_irq_free(vdev, card->irq_level, vec);
+	}
+
+	vec = (card->irq_vector & PIO2_VME_VECTOR_MASK) | PIO2_VME_VECTOR_SPUR;
+	vme_irq_free(vdev, card->irq_level, vec);
+
+	pio2_reset_card(card);
+
+	vme_master_set(card->window, 0, 0, 0, VME_A16, 0, VME_D16);
+
+	vme_master_free(card->window);
+
+	kfree(card);
+
+	return 0;
+}
+
+static void __exit pio2_exit(void)
+{
+	vme_unregister_driver(&pio2_driver);
+}
+
+
+/* These are required for each board */
+MODULE_PARM_DESC(bus, "Enumeration of VMEbus to which the board is connected");
+module_param_array(bus, int, &bus_num, S_IRUGO);
+
+MODULE_PARM_DESC(base, "Base VME address for PIO2 Registers");
+module_param_array(base, long, &base_num, S_IRUGO);
+
+MODULE_PARM_DESC(vector, "VME IRQ Vector (Lower 4 bits masked)");
+module_param_array(vector, int, &vector_num, S_IRUGO);
+
+MODULE_PARM_DESC(level, "VME IRQ Level");
+module_param_array(level, int, &level_num, S_IRUGO);
+
+MODULE_PARM_DESC(variant, "Last 4 characters of PIO2 board variant");
+module_param_array(variant, charp, &variant_num, S_IRUGO);
+
+/* This is for debugging */
+MODULE_PARM_DESC(loopback, "Enable loopback mode on all cards");
+module_param(loopback, bool, S_IRUGO);
+
+MODULE_DESCRIPTION("GE PIO2 6U VME I/O Driver");
+MODULE_AUTHOR("Martyn Welch <martyn.welch@ge.com");
+MODULE_LICENSE("GPL");
+
+module_init(pio2_init);
+module_exit(pio2_exit);
+
diff --git a/drivers/staging/vme/devices/vme_pio2_gpio.c b/drivers/staging/vme/devices/vme_pio2_gpio.c
new file mode 100644
index 0000000..dc837de
--- /dev/null
+++ b/drivers/staging/vme/devices/vme_pio2_gpio.c
@@ -0,0 +1,232 @@
+/*
+ * GE PIO2 GPIO Driver
+ *
+ * Author: Martyn Welch <martyn.welch@ge.com>
+ * Copyright 2009 GE Intelligent Platforms Embedded Systems, Inc.
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ */
+
+#include <linux/version.h>
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/device.h>
+#include <linux/platform_device.h>
+#include <linux/ctype.h>
+#include <linux/gpio.h>
+#include <linux/slab.h>
+
+#include "../vme.h"
+#include "vme_pio2.h"
+
+static const char driver_name[] = "pio2_gpio";
+
+static struct pio2_card *gpio_to_pio2_card(struct gpio_chip *chip)
+{
+	return container_of(chip, struct pio2_card, gc);
+}
+
+static int pio2_gpio_get(struct gpio_chip *chip, unsigned int offset)
+{
+	u8 reg;
+	int retval;
+	struct pio2_card *card = gpio_to_pio2_card(chip);
+
+	if ((card->bank[PIO2_CHANNEL_BANK[offset]].config == OUTPUT) |
+		(card->bank[PIO2_CHANNEL_BANK[offset]].config == NOFIT)) {
+
+		dev_err(&card->vdev->dev, "Channel not available as input\n");
+		return 0;
+	}
+
+	retval = vme_master_read(card->window, &reg, 1,
+		PIO2_REGS_DATA[PIO2_CHANNEL_BANK[offset]]);
+	if (retval < 0) {
+		dev_err(&card->vdev->dev, "Unable to read from GPIO\n");
+		return 0;
+	}
+
+	/*
+	 * Remember, input on channels configured as both input and output
+	 * are inverted!
+	 */
+	if (reg & PIO2_CHANNEL_BIT[offset]) {
+		if (card->bank[PIO2_CHANNEL_BANK[offset]].config != BOTH)
+			return 0;
+		else
+			return 1;
+	} else {
+		if (card->bank[PIO2_CHANNEL_BANK[offset]].config != BOTH)
+			return 1;
+		else
+			return 0;
+	}
+}
+
+static void pio2_gpio_set(struct gpio_chip *chip, unsigned int offset,
+	int value)
+{
+	u8 reg;
+	int retval;
+	struct pio2_card *card = gpio_to_pio2_card(chip);
+
+	if ((card->bank[PIO2_CHANNEL_BANK[offset]].config == INPUT) |
+		(card->bank[PIO2_CHANNEL_BANK[offset]].config == NOFIT)) {
+
+		dev_err(&card->vdev->dev, "Channel not availabe as output\n");
+		return;
+	}
+
+	if (value)
+		reg = card->bank[PIO2_CHANNEL_BANK[offset]].value |
+			PIO2_CHANNEL_BIT[offset];
+	else
+		reg = card->bank[PIO2_CHANNEL_BANK[offset]].value &
+			~PIO2_CHANNEL_BIT[offset];
+
+	retval = vme_master_write(card->window, &reg, 1,
+		PIO2_REGS_DATA[PIO2_CHANNEL_BANK[offset]]);
+	if (retval < 0) {
+		dev_err(&card->vdev->dev, "Unable to write to GPIO\n");
+		return;
+	}
+
+	card->bank[PIO2_CHANNEL_BANK[offset]].value = reg;
+}
+
+/* Directionality configured at board build - send appropriate response */
+static int pio2_gpio_dir_in(struct gpio_chip *chip, unsigned offset)
+{
+	int data;
+	struct pio2_card *card = gpio_to_pio2_card(chip);
+
+	if ((card->bank[PIO2_CHANNEL_BANK[offset]].config == OUTPUT) |
+		(card->bank[PIO2_CHANNEL_BANK[offset]].config == NOFIT)) {
+		dev_err(&card->vdev->dev,
+			"Channel directionality not configurable at runtine\n");
+
+		data = -EINVAL;
+	} else {
+		data = 0;
+	}
+
+	return data;
+}
+
+/* Directionality configured at board build - send appropriate response */
+static int pio2_gpio_dir_out(struct gpio_chip *chip, unsigned offset, int value)
+{
+	int data;
+	struct pio2_card *card = gpio_to_pio2_card(chip);
+
+	if ((card->bank[PIO2_CHANNEL_BANK[offset]].config == INPUT) |
+		(card->bank[PIO2_CHANNEL_BANK[offset]].config == NOFIT)) {
+		dev_err(&card->vdev->dev,
+			"Channel directionality not configurable at runtine\n");
+
+		data = -EINVAL;
+	} else {
+		data = 0;
+	}
+
+	return data;
+}
+
+/*
+ * We return whether this has been successful - this is used in the probe to
+ * ensure we have a valid card.
+ */
+int pio2_gpio_reset(struct pio2_card *card)
+{
+	int retval = 0;
+	int i, j;
+
+	u8 data = 0;
+
+	/* Zero output registers */
+	for (i = 0; i < 4; i++) {
+		retval = vme_master_write(card->window, &data, 1,
+			PIO2_REGS_DATA[i]);
+		if (retval < 0)
+			return retval;
+		card->bank[i].value = 0;
+	}
+
+	/* Set input interrupt masks */
+	for (i = 0; i < 4; i++) {
+		retval = vme_master_write(card->window, &data, 1,
+			PIO2_REGS_INT_MASK[i * 2]);
+		if (retval < 0)
+			return retval;
+
+		retval = vme_master_write(card->window, &data, 1,
+			PIO2_REGS_INT_MASK[(i * 2) + 1]);
+		if (retval < 0)
+			return retval;
+
+		for (j = 0; j < 8; j++)
+			card->bank[i].irq[j] = NONE;
+	}
+
+	/* Ensure all I/O interrupts are cleared */
+	for (i = 0; i < 4; i++) {
+		do {
+			retval = vme_master_read(card->window, &data, 1,
+				PIO2_REGS_INT_STAT[i]);
+			if (retval < 0)
+				return retval;
+		} while (data != 0);
+	}
+
+	return 0;
+}
+
+int __init pio2_gpio_init(struct pio2_card *card)
+{
+	int retval = 0;
+	char *label;
+
+	label = kmalloc(PIO2_NUM_CHANNELS, GFP_KERNEL);
+	if (label == NULL) {
+		dev_err(&card->vdev->dev, "Unable to allocate GPIO label\n");
+		return -ENOMEM;
+	}
+
+	sprintf(label, "%s@%s", driver_name, dev_name(&card->vdev->dev));
+	card->gc.label = label;
+
+	card->gc.ngpio = PIO2_NUM_CHANNELS;
+	/* Dynamic allocation of base */
+	card->gc.base = -1;
+	/* Setup pointers to chip functions */
+	card->gc.direction_input = pio2_gpio_dir_in;
+	card->gc.direction_output = pio2_gpio_dir_out;
+	card->gc.get = pio2_gpio_get;
+	card->gc.set = pio2_gpio_set;
+
+	/* This function adds a memory mapped GPIO chip */
+	retval = gpiochip_add(&(card->gc));
+	if (retval) {
+		dev_err(&card->vdev->dev, "Unable to register GPIO\n");
+		kfree(card->gc.label);
+	}
+
+	return retval;
+};
+
+void __exit pio2_gpio_exit(struct pio2_card *card)
+{
+	const char *label = card->gc.label;
+
+	if (gpiochip_remove(&(card->gc)))
+		dev_err(&card->vdev->dev, "Failed to remove GPIO");
+
+	kfree(label);
+}
+
diff --git a/drivers/staging/vme/devices/vme_user.h b/drivers/staging/vme/devices/vme_user.h
index d85a1e9..7d24cd6 100644
--- a/drivers/staging/vme/devices/vme_user.h
+++ b/drivers/staging/vme/devices/vme_user.h
@@ -10,9 +10,9 @@
 	int enable;			/* State of Window */
 	unsigned long long vme_addr;	/* Starting Address on the VMEbus */
 	unsigned long long size;	/* Window Size */
-	vme_address_t aspace;		/* Address Space */
-	vme_cycle_t cycle;		/* Cycle properties */
-	vme_width_t dwidth;		/* Maximum Data Width */
+	u32 aspace;			/* Address Space */
+	u32 cycle;		/* Cycle properties */
+	u32 dwidth;		/* Maximum Data Width */
 #if 0
 	char prefetchEnable;		/* Prefetch Read Enable State */
 	int prefetchSize;		/* Prefetch Read Size (Cache Lines) */
@@ -34,8 +34,8 @@
 	int enable;			/* State of Window */
 	unsigned long long vme_addr;	/* Starting Address on the VMEbus */
 	unsigned long long size;	/* Window Size */
-	vme_address_t aspace;		/* Address Space */
-	vme_cycle_t cycle;		/* Cycle properties */
+	u32 aspace;			/* Address Space */
+	u32 cycle;		/* Cycle properties */
 #if 0
 	char wrPostEnable;		/* Write Post State */
 	char rmwLock;			/* Lock PCI during RMW Cycles */
diff --git a/drivers/staging/vme/vme.c b/drivers/staging/vme/vme.c
index b04b468..70722ae 100644
--- a/drivers/staging/vme/vme.c
+++ b/drivers/staging/vme/vme.c
@@ -153,9 +153,7 @@
 	int enabled, retval;
 	unsigned long long base, size;
 	dma_addr_t buf_base;
-	vme_address_t aspace;
-	vme_cycle_t cycle;
-	vme_width_t dwidth;
+	u32 aspace, cycle, dwidth;
 
 	switch (resource->type) {
 	case VME_MASTER:
@@ -181,7 +179,7 @@
 }
 EXPORT_SYMBOL(vme_get_size);
 
-static int vme_check_window(vme_address_t aspace, unsigned long long vme_base,
+static int vme_check_window(u32 aspace, unsigned long long vme_base,
 	unsigned long long size)
 {
 	int retval = 0;
@@ -232,8 +230,8 @@
  * Request a slave image with specific attributes, return some unique
  * identifier.
  */
-struct vme_resource *vme_slave_request(struct vme_dev *vdev,
-	vme_address_t address, vme_cycle_t cycle)
+struct vme_resource *vme_slave_request(struct vme_dev *vdev, u32 address,
+	u32 cycle)
 {
 	struct vme_bridge *bridge;
 	struct list_head *slave_pos = NULL;
@@ -298,7 +296,7 @@
 
 int vme_slave_set(struct vme_resource *resource, int enabled,
 	unsigned long long vme_base, unsigned long long size,
-	dma_addr_t buf_base, vme_address_t aspace, vme_cycle_t cycle)
+	dma_addr_t buf_base, u32 aspace, u32 cycle)
 {
 	struct vme_bridge *bridge = find_bridge(resource);
 	struct vme_slave_resource *image;
@@ -333,7 +331,7 @@
 
 int vme_slave_get(struct vme_resource *resource, int *enabled,
 	unsigned long long *vme_base, unsigned long long *size,
-	dma_addr_t *buf_base, vme_address_t *aspace, vme_cycle_t *cycle)
+	dma_addr_t *buf_base, u32 *aspace, u32 *cycle)
 {
 	struct vme_bridge *bridge = find_bridge(resource);
 	struct vme_slave_resource *image;
@@ -388,8 +386,8 @@
  * Request a master image with specific attributes, return some unique
  * identifier.
  */
-struct vme_resource *vme_master_request(struct vme_dev *vdev,
-	vme_address_t address, vme_cycle_t cycle, vme_width_t dwidth)
+struct vme_resource *vme_master_request(struct vme_dev *vdev, u32 address,
+	u32 cycle, u32 dwidth)
 {
 	struct vme_bridge *bridge;
 	struct list_head *master_pos = NULL;
@@ -456,8 +454,8 @@
 EXPORT_SYMBOL(vme_master_request);
 
 int vme_master_set(struct vme_resource *resource, int enabled,
-	unsigned long long vme_base, unsigned long long size,
-	vme_address_t aspace, vme_cycle_t cycle, vme_width_t dwidth)
+	unsigned long long vme_base, unsigned long long size, u32 aspace,
+	u32 cycle, u32 dwidth)
 {
 	struct vme_bridge *bridge = find_bridge(resource);
 	struct vme_master_resource *image;
@@ -492,8 +490,8 @@
 EXPORT_SYMBOL(vme_master_set);
 
 int vme_master_get(struct vme_resource *resource, int *enabled,
-	unsigned long long *vme_base, unsigned long long *size,
-	vme_address_t *aspace, vme_cycle_t *cycle, vme_width_t *dwidth)
+	unsigned long long *vme_base, unsigned long long *size, u32 *aspace,
+	u32 *cycle, u32 *dwidth)
 {
 	struct vme_bridge *bridge = find_bridge(resource);
 	struct vme_master_resource *image;
@@ -646,8 +644,7 @@
  * Request a DMA controller with specific attributes, return some unique
  * identifier.
  */
-struct vme_resource *vme_dma_request(struct vme_dev *vdev,
-	vme_dma_route_t route)
+struct vme_resource *vme_dma_request(struct vme_dev *vdev, u32 route)
 {
 	struct vme_bridge *bridge;
 	struct list_head *dma_pos = NULL;
@@ -743,8 +740,7 @@
 /*
  * Create "Pattern" type attributes
  */
-struct vme_dma_attr *vme_dma_pattern_attribute(u32 pattern,
-	vme_pattern_t type)
+struct vme_dma_attr *vme_dma_pattern_attribute(u32 pattern, u32 type)
 {
 	struct vme_dma_attr *attributes;
 	struct vme_dma_pattern *pattern_attr;
@@ -822,7 +818,7 @@
  * Create "VME" type attributes
  */
 struct vme_dma_attr *vme_dma_vme_attribute(unsigned long long address,
-	vme_address_t aspace, vme_cycle_t cycle, vme_width_t dwidth)
+	u32 aspace, u32 cycle, u32 dwidth)
 {
 	struct vme_dma_attr *attributes;
 	struct vme_dma_vme *vme_attr;
@@ -1173,7 +1169,7 @@
 EXPORT_SYMBOL(vme_lm_count);
 
 int vme_lm_set(struct vme_resource *resource, unsigned long long lm_base,
-	vme_address_t aspace, vme_cycle_t cycle)
+	u32 aspace, u32 cycle)
 {
 	struct vme_bridge *bridge = find_bridge(resource);
 	struct vme_lm_resource *lm;
@@ -1195,7 +1191,7 @@
 EXPORT_SYMBOL(vme_lm_set);
 
 int vme_lm_get(struct vme_resource *resource, unsigned long long *lm_base,
-	vme_address_t *aspace, vme_cycle_t *cycle)
+	u32 *aspace, u32 *cycle)
 {
 	struct vme_bridge *bridge = find_bridge(resource);
 	struct vme_lm_resource *lm;
@@ -1307,7 +1303,12 @@
 
 /* - Bridge Registration --------------------------------------------------- */
 
-static int vme_add_bus(struct vme_bridge *bridge)
+static void vme_dev_release(struct device *dev)
+{
+	kfree(dev_to_vme_dev(dev));
+}
+
+int vme_register_bridge(struct vme_bridge *bridge)
 {
 	int i;
 	int ret = -1;
@@ -1327,8 +1328,9 @@
 
 	return ret;
 }
+EXPORT_SYMBOL(vme_register_bridge);
 
-static void vme_remove_bus(struct vme_bridge *bridge)
+void vme_unregister_bridge(struct vme_bridge *bridge)
 {
 	struct vme_dev *vdev;
 	struct vme_dev *tmp;
@@ -1343,22 +1345,6 @@
 	list_del(&bridge->bus_list);
 	mutex_unlock(&vme_buses_lock);
 }
-
-static void vme_dev_release(struct device *dev)
-{
-	kfree(dev_to_vme_dev(dev));
-}
-
-int vme_register_bridge(struct vme_bridge *bridge)
-{
-	return vme_add_bus(bridge);
-}
-EXPORT_SYMBOL(vme_register_bridge);
-
-void vme_unregister_bridge(struct vme_bridge *bridge)
-{
-	vme_remove_bus(bridge);
-}
 EXPORT_SYMBOL(vme_unregister_bridge);
 
 /* - Driver Registration --------------------------------------------------- */
@@ -1421,10 +1407,7 @@
 		 * and if the bridge is removed, it will have to go through
 		 * vme_unregister_bridge() to do it (which calls remove() on
 		 * the bridge which in turn tries to acquire vme_buses_lock and
-		 * will have to wait). The probe() called after device
-		 * registration in __vme_register_driver below will also fail
-		 * as the bridge is being removed (since the probe() calls
-		 * vme_bridge_get()).
+		 * will have to wait).
 		 */
 		err = __vme_register_driver_bus(drv, bridge, ndevs);
 		if (err)
diff --git a/drivers/staging/vme/vme.h b/drivers/staging/vme/vme.h
index e3828ba..9d38cee 100644
--- a/drivers/staging/vme/vme.h
+++ b/drivers/staging/vme/vme.h
@@ -10,7 +10,6 @@
 };
 
 /* VME Address Spaces */
-typedef u32 vme_address_t;
 #define VME_A16		0x1
 #define VME_A24		0x2
 #define	VME_A32		0x4
@@ -29,7 +28,6 @@
 
 
 /* VME Cycle Types */
-typedef u32 vme_cycle_t;
 #define VME_SCT		0x1
 #define VME_BLT		0x2
 #define VME_MBLT	0x4
@@ -47,28 +45,23 @@
 #define	VME_DATA	0x8000
 
 /* VME Data Widths */
-typedef u32 vme_width_t;
 #define VME_D8		0x1
 #define VME_D16		0x2
 #define VME_D32		0x4
 #define VME_D64		0x8
 
 /* Arbitration Scheduling Modes */
-typedef u32 vme_arbitration_t;
 #define VME_R_ROBIN_MODE	0x1
 #define VME_PRIORITY_MODE	0x2
 
-typedef u32 vme_dma_t;
 #define VME_DMA_PATTERN			(1<<0)
 #define VME_DMA_PCI			(1<<1)
 #define VME_DMA_VME			(1<<2)
 
-typedef u32 vme_pattern_t;
 #define VME_DMA_PATTERN_BYTE		(1<<0)
 #define VME_DMA_PATTERN_WORD		(1<<1)
 #define VME_DMA_PATTERN_INCREMENT	(1<<2)
 
-typedef u32 vme_dma_route_t;
 #define VME_DMA_VME_TO_MEM		(1<<0)
 #define VME_DMA_MEM_TO_VME		(1<<1)
 #define VME_DMA_VME_TO_VME		(1<<2)
@@ -77,7 +70,7 @@
 #define VME_DMA_PATTERN_TO_MEM		(1<<5)
 
 struct vme_dma_attr {
-	vme_dma_t type;
+	u32 type;
 	void *private;
 };
 
@@ -97,7 +90,7 @@
 
 /**
  * Structure representing a VME device
- * @id: The ID of the device (currently the bus and slot number)
+ * @num: The device number
  * @bridge: Pointer to the bridge device this device is on
  * @dev: Internal device structure
  * @drv_list: List of devices (per driver)
@@ -128,32 +121,29 @@
 
 size_t vme_get_size(struct vme_resource *);
 
-struct vme_resource *vme_slave_request(struct vme_dev *, vme_address_t,
-	vme_cycle_t);
+struct vme_resource *vme_slave_request(struct vme_dev *, u32, u32);
 int vme_slave_set(struct vme_resource *, int, unsigned long long,
-	unsigned long long, dma_addr_t, vme_address_t, vme_cycle_t);
+	unsigned long long, dma_addr_t, u32, u32);
 int vme_slave_get(struct vme_resource *, int *, unsigned long long *,
-	unsigned long long *, dma_addr_t *, vme_address_t *, vme_cycle_t *);
+	unsigned long long *, dma_addr_t *, u32 *, u32 *);
 void vme_slave_free(struct vme_resource *);
 
-struct vme_resource *vme_master_request(struct vme_dev *, vme_address_t,
-	vme_cycle_t, vme_width_t);
+struct vme_resource *vme_master_request(struct vme_dev *, u32, u32, u32);
 int vme_master_set(struct vme_resource *, int, unsigned long long,
-	unsigned long long, vme_address_t, vme_cycle_t, vme_width_t);
+	unsigned long long, u32, u32, u32);
 int vme_master_get(struct vme_resource *, int *, unsigned long long *,
-	unsigned long long *, vme_address_t *, vme_cycle_t *, vme_width_t *);
+	unsigned long long *, u32 *, u32 *, u32 *);
 ssize_t vme_master_read(struct vme_resource *, void *, size_t, loff_t);
 ssize_t vme_master_write(struct vme_resource *, void *, size_t, loff_t);
 unsigned int vme_master_rmw(struct vme_resource *, unsigned int, unsigned int,
 	unsigned int, loff_t);
 void vme_master_free(struct vme_resource *);
 
-struct vme_resource *vme_dma_request(struct vme_dev *, vme_dma_route_t);
+struct vme_resource *vme_dma_request(struct vme_dev *, u32);
 struct vme_dma_list *vme_new_dma_list(struct vme_resource *);
-struct vme_dma_attr *vme_dma_pattern_attribute(u32, vme_pattern_t);
+struct vme_dma_attr *vme_dma_pattern_attribute(u32, u32);
 struct vme_dma_attr *vme_dma_pci_attribute(dma_addr_t);
-struct vme_dma_attr *vme_dma_vme_attribute(unsigned long long, vme_address_t,
-	vme_cycle_t, vme_width_t);
+struct vme_dma_attr *vme_dma_vme_attribute(unsigned long long, u32, u32, u32);
 void vme_dma_free_attribute(struct vme_dma_attr *);
 int vme_dma_list_add(struct vme_dma_list *, struct vme_dma_attr *,
 	struct vme_dma_attr *, size_t);
@@ -168,10 +158,8 @@
 
 struct vme_resource * vme_lm_request(struct vme_dev *);
 int vme_lm_count(struct vme_resource *);
-int vme_lm_set(struct vme_resource *, unsigned long long, vme_address_t,
-	vme_cycle_t);
-int vme_lm_get(struct vme_resource *, unsigned long long *, vme_address_t *,
-	vme_cycle_t *);
+int vme_lm_set(struct vme_resource *, unsigned long long, u32, u32);
+int vme_lm_get(struct vme_resource *, unsigned long long *, u32 *, u32 *);
 int vme_lm_attach(struct vme_resource *, int, void (*callback)(int));
 int vme_lm_detach(struct vme_resource *, int);
 void vme_lm_free(struct vme_resource *);
diff --git a/drivers/staging/vme/vme_api.txt b/drivers/staging/vme/vme_api.txt
index e8ff215..856efa3 100644
--- a/drivers/staging/vme/vme_api.txt
+++ b/drivers/staging/vme/vme_api.txt
@@ -86,26 +86,26 @@
 driver in question:
 
 	struct vme_resource * vme_master_request(struct vme_dev *dev,
-		vme_address_t aspace, vme_cycle_t cycle, vme_width_t width);
+		u32 aspace, u32 cycle, u32 width);
 
-	struct vme_resource * vme_slave_request(struct vme_dev *dev,
-		vme_address_t aspace, vme_cycle_t cycle);
+	struct vme_resource * vme_slave_request(struct vme_dev *dev, u32 aspace,
+		u32 cycle);
 
-	struct vme_resource *vme_dma_request(struct vme_dev *dev,
-		vme_dma_route_t route);
+	struct vme_resource *vme_dma_request(struct vme_dev *dev, u32 route);
 
-For slave windows these attributes are split into those of type 'vme_address_t'
-and 'vme_cycle_t'. Master windows add a further set of attributes
-'vme_cycle_t'.  These attributes are defined as bitmasks and as such any
-combination of the attributes can be requested for a single window, the core
-will assign a window that meets the requirements, returning a pointer of type
-vme_resource that should be used to identify the allocated resource when it is
-used. For DMA controllers, the request function requires the potential
-direction of any transfers to be provided in the route attributes. This is
-typically VME-to-MEM and/or MEM-to-VME, though some hardware can support
-VME-to-VME and MEM-to-MEM transfers as well as test pattern generation. If an
-unallocated window fitting the requirements can not be found a NULL pointer
-will be returned.
+For slave windows these attributes are split into the VME address spaces that
+need to be accessed in 'aspace' and VME bus cycle types required in 'cycle'.
+Master windows add a further set of attributes in 'width' specifying the
+required data transfer widths. These attributes are defined as bitmasks and as
+such any combination of the attributes can be requested for a single window,
+the core will assign a window that meets the requirements, returning a pointer
+of type vme_resource that should be used to identify the allocated resource
+when it is used. For DMA controllers, the request function requires the
+potential direction of any transfers to be provided in the route attributes.
+This is typically VME-to-MEM and/or MEM-to-VME, though some hardware can
+support VME-to-VME and MEM-to-MEM transfers as well as test pattern generation.
+If an unallocated window fitting the requirements can not be found a NULL
+pointer will be returned.
 
 Functions are also provided to free window allocations once they are no longer
 required. These functions should be passed the pointer to the resource provided
@@ -133,12 +133,12 @@
 configure it and retrieve the current settings:
 
 	int vme_master_set (struct vme_resource *res, int enabled,
-		unsigned long long base, unsigned long long size,
-		vme_address_t aspace, vme_cycle_t cycle, vme_width_t width);
+		unsigned long long base, unsigned long long size, u32 aspace,
+		u32 cycle, u32 width);
 
 	int vme_master_get (struct vme_resource *res, int *enabled,
-		unsigned long long *base, unsigned long long *size,
-		vme_address_t *aspace, vme_cycle_t *cycle, vme_width_t *width);
+		unsigned long long *base, unsigned long long *size, u32 *aspace,
+		u32 *cycle, u32 *width);
 
 The address spaces, transfer widths and cycle types are the same as described
 under resource management, however some of the options are mutually exclusive.
@@ -189,11 +189,11 @@
 
 	int vme_slave_set (struct vme_resource *res, int enabled,
 		unsigned long long base, unsigned long long size,
-		dma_addr_t mem, vme_address_t aspace, vme_cycle_t cycle);
+		dma_addr_t mem, u32 aspace, u32 cycle);
 
 	int vme_slave_get (struct vme_resource *res, int *enabled,
 		unsigned long long *base, unsigned long long *size,
-		dma_addr_t *mem, vme_address_t *aspace, vme_cycle_t *cycle);
+		dma_addr_t *mem, u32 *aspace, u32 *cycle);
 
 The address spaces, transfer widths and cycle types are the same as described
 under resource management, however some of the options are mutually exclusive.
@@ -273,8 +273,7 @@
 
 Pattern source:
 
-	struct vme_dma_attr *vme_dma_pattern_attribute(u32 pattern,
-		vme_pattern_t type);
+	struct vme_dma_attr *vme_dma_pattern_attribute(u32 pattern, u32 type);
 
 PCI source or destination:
 
@@ -283,7 +282,7 @@
 VME source or destination:
 
 	struct vme_dma_attr *vme_dma_vme_attribute(unsigned long long base,
-		vme_address_t aspace, vme_cycle_t cycle, vme_width_t width);
+		u32 aspace, u32 cycle, u32 width);
 
 The following function should be used to free an attribute:
 
@@ -366,10 +365,10 @@
 are provided to configure the location and mode of the location monitor:
 
 	int vme_lm_set(struct vme_resource *res, unsigned long long base,
-		vme_address_t aspace, vme_cycle_t cycle);
+		u32 aspace, u32 cycle);
 
 	int vme_lm_get(struct vme_resource *res, unsigned long long *base,
-		vme_address_t *aspace, vme_cycle_t *cycle);
+		u32 *aspace, u32 *cycle);
 
 
 Location Monitor Use
diff --git a/drivers/staging/vme/vme_bridge.h b/drivers/staging/vme/vme_bridge.h
index c2deda2..934949a 100644
--- a/drivers/staging/vme/vme_bridge.h
+++ b/drivers/staging/vme/vme_bridge.h
@@ -15,9 +15,9 @@
 	spinlock_t lock;
 	int locked;
 	int number;
-	vme_address_t address_attr;
-	vme_cycle_t cycle_attr;
-	vme_width_t width_attr;
+	u32 address_attr;
+	u32 cycle_attr;
+	u32 width_attr;
 	struct resource bus_resource;
 	void __iomem *kern_base;
 };
@@ -28,13 +28,13 @@
 	struct mutex mtx;
 	int locked;
 	int number;
-	vme_address_t address_attr;
-	vme_cycle_t cycle_attr;
+	u32 address_attr;
+	u32 cycle_attr;
 };
 
 struct vme_dma_pattern {
 	u32 pattern;
-	vme_pattern_t type;
+	u32 type;
 };
 
 struct vme_dma_pci {
@@ -43,9 +43,9 @@
 
 struct vme_dma_vme {
 	unsigned long long address;
-	vme_address_t aspace;
-	vme_cycle_t cycle;
-	vme_width_t dwidth;
+	u32 aspace;
+	u32 cycle;
+	u32 dwidth;
 };
 
 struct vme_dma_list {
@@ -63,7 +63,7 @@
 	int number;
 	struct list_head pending;
 	struct list_head running;
-	vme_dma_route_t route_attr;
+	u32 route_attr;
 };
 
 struct vme_lm_resource {
@@ -122,17 +122,16 @@
 	/* Slave Functions */
 	int (*slave_get) (struct vme_slave_resource *, int *,
 		unsigned long long *, unsigned long long *, dma_addr_t *,
-		vme_address_t *, vme_cycle_t *);
+		u32 *, u32 *);
 	int (*slave_set) (struct vme_slave_resource *, int, unsigned long long,
-		unsigned long long, dma_addr_t, vme_address_t, vme_cycle_t);
+		unsigned long long, dma_addr_t, u32, u32);
 
 	/* Master Functions */
 	int (*master_get) (struct vme_master_resource *, int *,
-		unsigned long long *, unsigned long long *, vme_address_t *,
-		vme_cycle_t *, vme_width_t *);
+		unsigned long long *, unsigned long long *, u32 *, u32 *,
+		u32 *);
 	int (*master_set) (struct vme_master_resource *, int,
-		unsigned long long, unsigned long long,  vme_address_t,
-		vme_cycle_t, vme_width_t);
+		unsigned long long, unsigned long long,  u32, u32, u32);
 	ssize_t (*master_read) (struct vme_master_resource *, void *, size_t,
 		loff_t);
 	ssize_t (*master_write) (struct vme_master_resource *, void *, size_t,
@@ -151,10 +150,9 @@
 	int (*irq_generate) (struct vme_bridge *, int, int);
 
 	/* Location monitor functions */
-	int (*lm_set) (struct vme_lm_resource *, unsigned long long,
-		vme_address_t, vme_cycle_t);
-	int (*lm_get) (struct vme_lm_resource *, unsigned long long *,
-		vme_address_t *, vme_cycle_t *);
+	int (*lm_set) (struct vme_lm_resource *, unsigned long long, u32, u32);
+	int (*lm_get) (struct vme_lm_resource *, unsigned long long *, u32 *,
+		u32 *);
 	int (*lm_attach) (struct vme_lm_resource *, int, void (*callback)(int));
 	int (*lm_detach) (struct vme_lm_resource *, int);
 
diff --git a/drivers/staging/vt6655/device_main.c b/drivers/staging/vt6655/device_main.c
index d8dd784..3e8283c 100644
--- a/drivers/staging/vt6655/device_main.c
+++ b/drivers/staging/vt6655/device_main.c
@@ -3153,11 +3153,7 @@
 		break;
 
 	case SIOCGIWNWID:     //0x8b03  support
-	#ifdef  WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT
-          rc = iwctl_giwnwid(dev, NULL, &(wrq->u.nwid), NULL);
-	#else
-        rc = -EOPNOTSUPP;
-	#endif
+		rc = -EOPNOTSUPP;
 		break;
 
 		// Set frequency/channel
diff --git a/drivers/staging/vt6655/ioctl.c b/drivers/staging/vt6655/ioctl.c
index 432a209..7fd5cc5 100644
--- a/drivers/staging/vt6655/ioctl.c
+++ b/drivers/staging/vt6655/ioctl.c
@@ -300,6 +300,10 @@
 			result = -EFAULT;
 			break;
 		}
+		if (sList.uItem > (ULONG_MAX - sizeof(SBSSIDList)) / sizeof(SBSSIDItem)) {
+			result = -EINVAL;
+			break;
+		}
 		pList = (PSBSSIDList)kmalloc(sizeof(SBSSIDList) + (sList.uItem * sizeof(SBSSIDItem)), (int)GFP_ATOMIC);
 		if (pList == NULL) {
 			result = -ENOMEM;
@@ -571,6 +575,10 @@
 			result = -EFAULT;
 			break;
 		}
+		if (sNodeList.uItem > (ULONG_MAX - sizeof(SNodeList)) / sizeof(SNodeItem)) {
+			result = -EINVAL;
+			break;
+		}
 		pNodeList = (PSNodeList)kmalloc(sizeof(SNodeList) + (sNodeList.uItem * sizeof(SNodeItem)), (int)GFP_ATOMIC);
 		if (pNodeList == NULL) {
 			result = -ENOMEM;
diff --git a/drivers/staging/vt6655/iwctl.c b/drivers/staging/vt6655/iwctl.c
index 5e425d1..87288db 100644
--- a/drivers/staging/vt6655/iwctl.c
+++ b/drivers/staging/vt6655/iwctl.c
@@ -151,18 +151,6 @@
 	return 0;
 }
 
-int iwctl_giwnwid(struct net_device *dev,
-             struct iw_request_info *info,
-			 struct iw_param *wrq,
-                   char *extra)
-{
- 	//wrq->value = 0x100;
-	//wrq->disabled = 0;
-	//wrq->fixed = 1;
-	//return 0;
-  return -EOPNOTSUPP;
-}
-
 /*
  * Wireless Handler : set scan
  */
diff --git a/drivers/staging/vt6655/iwctl.h b/drivers/staging/vt6655/iwctl.h
index 3096de0..d224f91 100644
--- a/drivers/staging/vt6655/iwctl.h
+++ b/drivers/staging/vt6655/iwctl.h
@@ -79,11 +79,6 @@
 			 char *wrq,
 			 char *extra);
 
-int iwctl_giwnwid(struct net_device *dev,
-             struct iw_request_info *info,
-			 struct iw_param *wrq,
-                   char *extra) ;
-
 int iwctl_giwsens(struct net_device *dev,
 			 struct iw_request_info *info,
 			 struct iw_param *wrq,
diff --git a/drivers/staging/vt6656/80211mgr.c b/drivers/staging/vt6656/80211mgr.c
index fceec49..39f9842 100644
--- a/drivers/staging/vt6656/80211mgr.c
+++ b/drivers/staging/vt6656/80211mgr.c
@@ -224,8 +224,6 @@
         }
         pItem = (PWLAN_IE)(((PBYTE)pItem) + 2 + pItem->len);
     }
-
-    return;
 }
 
 
@@ -248,8 +246,6 @@
 {
     pFrame->pHdr = (PUWLAN_80211HDR)pFrame->pBuf;
     pFrame->len = WLAN_HDR_ADDR3_LEN;
-
-    return;
 }
 
 
@@ -270,8 +266,6 @@
     )
 {
     pFrame->pHdr = (PUWLAN_80211HDR)pFrame->pBuf;
-
-    return;
 }
 
 
@@ -298,8 +292,6 @@
     pFrame->pwReason = (PWORD)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3))
                                + WLAN_DISASSOC_OFF_REASON);
     pFrame->len = WLAN_HDR_ADDR3_LEN + WLAN_DISASSOC_OFF_REASON + sizeof(*(pFrame->pwReason));
-
-    return;
 }
 
 
@@ -324,8 +316,6 @@
     /* Fixed Fields */
     pFrame->pwReason = (PWORD)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3))
                                + WLAN_DISASSOC_OFF_REASON);
-
-    return;
 }
 
 /*+
@@ -352,7 +342,6 @@
     pFrame->pwListenInterval = (PWORD)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3))
                                        + WLAN_ASSOCREQ_OFF_LISTEN_INT);
     pFrame->len = WLAN_HDR_ADDR3_LEN + WLAN_ASSOCREQ_OFF_LISTEN_INT + sizeof(*(pFrame->pwListenInterval));
-    return;
 }
 
 
@@ -418,7 +407,6 @@
         }
         pItem = (PWLAN_IE)(((PBYTE)pItem) + 2 + pItem->len);
     }
-    return;
 }
 
 /*+
@@ -448,8 +436,6 @@
                             + WLAN_ASSOCRESP_OFF_AID);
     pFrame->len = WLAN_HDR_ADDR3_LEN + WLAN_ASSOCRESP_OFF_AID
                   + sizeof(*(pFrame->pwAid));
-
-    return;
 }
 
 
@@ -491,10 +477,8 @@
     if ((((PBYTE)pItem) < (pFrame->pBuf + pFrame->len)) && (pItem->byElementID == WLAN_EID_EXTSUPP_RATES)) {
         pFrame->pExtSuppRates = (PWLAN_IE_SUPP_RATES)pItem;
         DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "pFrame->pExtSuppRates=[%p].\n", pItem);
-    } else {
+	} else
         pFrame->pExtSuppRates = NULL;
-    }
-    return;
 }
 
 
@@ -524,8 +508,6 @@
     pFrame->pAddrCurrAP = (PIEEE_ADDR)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3))
                                        + WLAN_REASSOCREQ_OFF_CURR_AP);
     pFrame->len = WLAN_HDR_ADDR3_LEN + WLAN_REASSOCREQ_OFF_CURR_AP + sizeof(*(pFrame->pAddrCurrAP));
-
-    return;
 }
 
 
@@ -578,10 +560,9 @@
                 pFrame->pRSN = (PWLAN_IE_RSN)pItem;
             break;
         case WLAN_EID_RSN_WPA:
-            if (pFrame->pRSNWPA == NULL) {
+		if (pFrame->pRSNWPA == NULL)
                 if (WPAb_Is_RSN((PWLAN_IE_RSN_EXT)pItem) == TRUE)
                     pFrame->pRSNWPA = (PWLAN_IE_RSN_EXT)pItem;
-            }
             break;
 
         case WLAN_EID_EXTSUPP_RATES:
@@ -595,7 +576,6 @@
         }
         pItem = (PWLAN_IE)(((PBYTE)pItem) + 2 + pItem->len);
     }
-    return;
 }
 
 
@@ -619,7 +599,6 @@
 {
     pFrame->pHdr = (PUWLAN_80211HDR)pFrame->pBuf;
     pFrame->len = WLAN_HDR_ADDR3_LEN;
-    return;
 }
 
 /*+
@@ -670,7 +649,6 @@
 
         pItem = (PWLAN_IE)(((PBYTE)pItem) + 2 +  pItem->len);
     }
-    return;
 }
 
 
@@ -703,8 +681,6 @@
 
     pFrame->len = WLAN_HDR_ADDR3_LEN + WLAN_PROBERESP_OFF_CAP_INFO +
                   sizeof(*(pFrame->pwCapInfo));
-
-    return;
 }
 
 
@@ -818,7 +794,6 @@
 
         pItem = (PWLAN_IE)(((PBYTE)pItem) + 2 +  pItem->len);
     }
-    return;
 }
 
 
@@ -848,7 +823,6 @@
     pFrame->pwStatus = (PWORD)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3))
                                + WLAN_AUTHEN_OFF_STATUS);
     pFrame->len = WLAN_HDR_ADDR3_LEN + WLAN_AUTHEN_OFF_STATUS + sizeof(*(pFrame->pwStatus));
-    return;
 }
 
 
@@ -886,7 +860,6 @@
 
     if ((((PBYTE)pItem) < (pFrame->pBuf + pFrame->len)) && (pItem->byElementID == WLAN_EID_CHALLENGE))
         pFrame->pChallenge = (PWLAN_IE_CHALLENGE)pItem;
-    return;
 }
 
 
@@ -912,7 +885,6 @@
     pFrame->pwReason = (PWORD)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3))
                                + WLAN_DEAUTHEN_OFF_REASON);
     pFrame->len = WLAN_HDR_ADDR3_LEN + WLAN_DEAUTHEN_OFF_REASON + sizeof(*(pFrame->pwReason));
-    return;
 }
 
 
@@ -937,7 +909,6 @@
     /* Fixed Fields */
     pFrame->pwReason = (PWORD)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3))
                                + WLAN_DEAUTHEN_OFF_REASON);
-    return;
 }
 
 
@@ -968,7 +939,6 @@
                             + WLAN_REASSOCRESP_OFF_AID);
 
     pFrame->len = WLAN_HDR_ADDR3_LEN + WLAN_REASSOCRESP_OFF_AID + sizeof(*(pFrame->pwAid));
-    return;
 }
 
 
@@ -1010,5 +980,4 @@
 
     if ((((PBYTE)pItem) < (pFrame->pBuf + pFrame->len)) && (pItem->byElementID == WLAN_EID_EXTSUPP_RATES))
         pFrame->pExtSuppRates = (PWLAN_IE_SUPP_RATES)pItem;
-    return;
 }
diff --git a/drivers/staging/vt6656/baseband.c b/drivers/staging/vt6656/baseband.c
index 0d11147..06f27f6 100644
--- a/drivers/staging/vt6656/baseband.c
+++ b/drivers/staging/vt6656/baseband.c
@@ -932,30 +932,8 @@
 void
 BBvSetAntennaMode (PSDevice pDevice, BYTE byAntennaMode)
 {
-    //{{ RobertYu: 20041124, ABG Mode, VC1/VC2 define, make the ANT_A, ANT_B inverted
-    /*if ( (pDevice->byRFType == RF_MAXIM2829) ||
-         (pDevice->byRFType == RF_UW2452) ||
-         (pDevice->byRFType == RF_AIROHA7230) ) { // RobertYu: 20041210, 20050104
-
-        switch (byAntennaMode) {
-            case ANT_TXA:
-                byAntennaMode = ANT_TXB;
-                break;
-            case ANT_TXB:
-                byAntennaMode = ANT_TXA;
-                break;
-            case ANT_RXA:
-                byAntennaMode = ANT_RXB;
-                break;
-            case ANT_RXB:
-                byAntennaMode = ANT_RXA;
-                break;
-        }
-    }*/
-
     switch (byAntennaMode) {
         case ANT_TXA:
-            break;
         case ANT_TXB:
             break;
         case ANT_RXA:
@@ -1249,8 +1227,7 @@
         // Set the CR33 Bit2 to disable internal Loopback.
         ControlvReadByte (pDevice, MESSAGE_REQUEST_BBREG, 0x21, &byData);//CR33
         ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0x21, (BYTE)(byData & 0xFE));//CR33
-    }
-    else { // OFDM
+	} else { /* OFDM */
         ControlvReadByte (pDevice, MESSAGE_REQUEST_BBREG, 0x9A, &byData);//CR154
         ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0x9A, (BYTE)(byData & 0xFE));//CR154
     }
@@ -1277,19 +1254,16 @@
 {
     BYTE byBBVGA=0;
 
-    if (pDevice->bShortSlotTime) {
+	if (pDevice->bShortSlotTime)
         pDevice->byBBRxConf &= 0xDF;//1101 1111
-    } else {
+	else
         pDevice->byBBRxConf |= 0x20;//0010 0000
-    }
 
     ControlvReadByte (pDevice, MESSAGE_REQUEST_BBREG, 0xE7, &byBBVGA);
-    if (byBBVGA == pDevice->abyBBVGA[0]) {
+	if (byBBVGA == pDevice->abyBBVGA[0])
         pDevice->byBBRxConf |= 0x20;//0010 0000
-    }
 
     ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0x0A, pDevice->byBBRxConf);
-
 }
 
 
@@ -1299,13 +1273,11 @@
     ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xE7, byData);
 
     // patch for 3253B0 Baseband with Cardbus module
-    if (byData == pDevice->abyBBVGA[0]) {
-        pDevice->byBBRxConf |= 0x20;//0010 0000
-    } else if (pDevice->bShortSlotTime) {
-        pDevice->byBBRxConf &= 0xDF;//1101 1111
-    } else {
-        pDevice->byBBRxConf |= 0x20;//0010 0000
-    }
+	if (pDevice->bShortSlotTime)
+		pDevice->byBBRxConf &= 0xDF; /* 1101 1111 */
+	else
+		pDevice->byBBRxConf |= 0x20; /* 0010 0000 */
+
     ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0x0A, pDevice->byBBRxConf);//CR10
 }
 
@@ -1365,15 +1337,14 @@
 	unsigned long ulMaxPacket;
 
     ulMaxPacket = pDevice->aulPktNum[RATE_54M];
-    if ( pDevice->aulPktNum[RATE_54M] != 0 ) {
+	if (pDevice->aulPktNum[RATE_54M] != 0)
         ulSQ3 = pDevice->aulSQ3Val[RATE_54M] / pDevice->aulPktNum[RATE_54M];
-    }
-    for ( ii=RATE_48M;ii>=RATE_6M;ii-- ) {
-        if ( pDevice->aulPktNum[ii] > ulMaxPacket ) {
+
+	for (ii = RATE_48M; ii >= RATE_6M; ii--)
+		if (pDevice->aulPktNum[ii] > ulMaxPacket) {
             ulMaxPacket = pDevice->aulPktNum[ii];
             ulSQ3 = pDevice->aulSQ3Val[ii] / pDevice->aulPktNum[ii];
         }
-    }
 
     return ulSQ3;
 }
@@ -1392,7 +1363,7 @@
         ulRatio = (ulPacketNum * 1000 / pDevice->uDiversityCnt);
         ulRatio += TOP_RATE_54M;
     }
-    for ( ii=RATE_48M;ii>=RATE_1M;ii-- ) {
+	for (ii = RATE_48M; ii >= RATE_1M; ii--)
         if ( pDevice->aulPktNum[ii] > ulMaxPacket ) {
             ulPacketNum = 0;
             for ( jj=RATE_54M;jj>=ii;jj--)
@@ -1402,8 +1373,6 @@
             ulMaxPacket = pDevice->aulPktNum[ii];
         }
 
-    }
-
     return ulRatio;
 }
 
@@ -1589,7 +1558,6 @@
 
 
     spin_unlock_irq(&pDevice->lock);
-    return;
 }
 
 
@@ -1637,7 +1605,6 @@
     add_timer(&pDevice->TimerSQ3Tmax1);
 
     spin_unlock_irq(&pDevice->lock);
-    return;
 }
 
 void
diff --git a/drivers/staging/vt6656/bssdb.c b/drivers/staging/vt6656/bssdb.c
index af006df..32c67ed 100644
--- a/drivers/staging/vt6656/bssdb.c
+++ b/drivers/staging/vt6656/bssdb.c
@@ -216,26 +216,6 @@
                         continue;
                     }
                 }
-/*
-                if (pMgmt->eAuthenMode < WMAC_AUTH_WPA) {
-                    if (pCurrBSS->bWPAValid == TRUE) {
-                        // WPA AP will reject connection of station without WPA enable.
-                        continue;
-                    }
-                } else if ((pMgmt->eAuthenMode == WMAC_AUTH_WPA) ||
-                           (pMgmt->eAuthenMode == WMAC_AUTH_WPAPSK)) {
-                    if (pCurrBSS->bWPAValid == FALSE) {
-                        // station with WPA enable can't join NonWPA AP.
-                        continue;
-                    }
-                } else if ((pMgmt->eAuthenMode == WMAC_AUTH_WPA2) ||
-                           (pMgmt->eAuthenMode == WMAC_AUTH_WPA2PSK)) {
-                    if (pCurrBSS->bWPA2Valid == FALSE) {
-                        // station with WPA2 enable can't join NonWPA2 AP.
-                        continue;
-                    }
-                }
-*/
 
         pMgmt->pSameBSS[jj].uChannel = pCurrBSS->uChannel;
         DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"BSSpSearchBSSList pSelect1[%02X %02X %02X-%02X %02X %02X]\n",*pCurrBSS->abyBSSID,*(pCurrBSS->abyBSSID+1),*(pCurrBSS->abyBSSID+2),*(pCurrBSS->abyBSSID+3),*(pCurrBSS->abyBSSID+4),*(pCurrBSS->abyBSSID+5));
@@ -300,18 +280,11 @@
                 continue;
             }
         }
-/*
-        if ((pMgmt->sBSSList[ii].bActive) && (pMgmt->sBSSList[ii].uClearCount < BSS_CLEAR_COUNT)) {
-             pMgmt->sBSSList[ii].uClearCount ++;
-             continue;
-        }
-*/
-        pMgmt->sBSSList[ii].bActive = FALSE;
+
+	pMgmt->sBSSList[ii].bActive = FALSE;
         memset(&pMgmt->sBSSList[ii], 0, sizeof(KnownBSS));
     }
     BSSvClearAnyBSSJoinRecord(pDevice);
-
-    return;
 }
 
 
@@ -524,46 +497,6 @@
             pBSSList->ldBmAverage[ii] = 0;
     }
 
-/*
-    if ((pIE_Country != NULL) &&
-        (pMgmt->b11hEnable == TRUE)) {
-        CARDvSetCountryInfo(pMgmt->pAdapter,
-                            pBSSList->eNetworkTypeInUse,
-                            pIE_Country);
-    }
-
-    if ((bParsingQuiet == TRUE) && (pIE_Quiet != NULL)) {
-        if ((((PWLAN_IE_QUIET)pIE_Quiet)->len == 8) &&
-            (((PWLAN_IE_QUIET)pIE_Quiet)->byQuietCount != 0)) {
-            // valid EID
-            if (pQuiet == NULL) {
-                pQuiet = (PWLAN_IE_QUIET)pIE_Quiet;
-                CARDbSetQuiet(  pMgmt->pAdapter,
-                                TRUE,
-                                pQuiet->byQuietCount,
-                                pQuiet->byQuietPeriod,
-                                *((PWORD)pQuiet->abyQuietDuration),
-                                *((PWORD)pQuiet->abyQuietOffset)
-                                );
-            } else {
-                pQuiet = (PWLAN_IE_QUIET)pIE_Quiet;
-                CARDbSetQuiet(  pMgmt->pAdapter,
-                                FALSE,
-                                pQuiet->byQuietCount,
-                                pQuiet->byQuietPeriod,
-                                *((PWORD)pQuiet->abyQuietDuration),
-                                *((PWORD)pQuiet->abyQuietOffset)
-                                );
-            }
-        }
-    }
-
-    if ((bParsingQuiet == TRUE) &&
-        (pQuiet != NULL)) {
-        CARDbStartQuiet(pMgmt->pAdapter);
-    }
-*/
-
     pBSSList->uIELength = uIELength;
     if (pBSSList->uIELength > WLAN_BEACON_FR_MAXLEN)
         pBSSList->uIELength = WLAN_BEACON_FR_MAXLEN;
@@ -609,8 +542,6 @@
     PSRxMgmtPacket  pRxPacket = (PSRxMgmtPacket)pRxPacketContext;
     signed long            ldBm, ldBmSum;
     BOOL            bParsingQuiet = FALSE;
-  //  BYTE            abyTmpSSID[WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1];
-
 
     if (pBSSList == NULL)
         return FALSE;
@@ -622,7 +553,6 @@
     pBSSList->wCapInfo = cpu_to_le16(wCapInfo);
     pBSSList->uClearCount = 0;
     pBSSList->uChannel = byCurrChannel;
-//    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"BSSbUpdateToBSSList: pBSSList->uChannel: %d\n", pBSSList->uChannel);
 
     if (pSSID->len > WLAN_SSID_MAXLEN)
         pSSID->len = WLAN_SSID_MAXLEN;
@@ -809,7 +739,6 @@
     pMgmt->sNodeDBTable[*puNodeIndex].byAuthSequence = 0;
     pMgmt->sNodeDBTable[*puNodeIndex].wEnQueueCnt = 0;
     DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Create node index = %d\n", ii);
-    return;
 };
 
 
@@ -840,8 +769,6 @@
     memset(&pMgmt->sNodeDBTable[uNodeIndex], 0, sizeof(KnownNodeDB));
     // clear tx bit map
     pMgmt->abyPSTxMap[pMgmt->sNodeDBTable[uNodeIndex].wAID >> 3] &=  ~byMask[pMgmt->sNodeDBTable[uNodeIndex].wAID & 7];
-
-    return;
 };
 /*+
  *
@@ -1054,10 +981,6 @@
 
             // Rate fallback check
             if (!pDevice->bFixRate) {
-/*
-                if ((pMgmt->eCurrMode == WMAC_MODE_ESS_STA) && (ii == 0))
-                    RATEvTxRateFallBack(pDevice, &(pMgmt->sNodeDBTable[ii]));
-*/
                 if (ii > 0) {
                     // ii = 0 for multicast node (AP & Adhoc)
 			RATEvTxRateFallBack((void *)pDevice,
@@ -1152,7 +1075,6 @@
         (pMgmt->eCurrMode == WMAC_MODE_ESS_STA)) {
 
         if (pMgmt->sNodeDBTable[0].bActive) { // Assoc with BSS
-           // DBG_PRT(MSG_LEVEL_INFO, KERN_INFO "Callback inactive Count = [%d]\n", pMgmt->sNodeDBTable[0].uInActiveCount);
 
             if (pDevice->bUpdateBBVGA) {
 		/* s_vCheckSensitivity((void *) pDevice); */
@@ -1194,7 +1116,6 @@
              pDevice->skb = dev_alloc_skb((int)pDevice->rx_buf_sz);
          }
    #ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT
-  // if(pDevice->bWPASuppWextEnabled == TRUE)
       {
 	union iwreq_data  wrqu;
 	memset(&wrqu, 0, sizeof (wrqu));
@@ -1223,7 +1144,6 @@
                 pDevice->uIsroamingTime = 0;
                 pDevice->bRoaming = FALSE;
 
-//            if ((pDevice->bWPADEVUp) && (pDevice->skb != NULL)) {
              wpahdr = (viawget_wpa_header *)pDevice->skb->data;
              wpahdr->type = VIAWGET_CCKM_ROAM_MSG;
              wpahdr->resp_ie_len = 0;
@@ -1237,7 +1157,6 @@
              netif_rx(pDevice->skb);
             pDevice->skb = dev_alloc_skb((int)pDevice->rx_buf_sz);
 
-//         }
           }
       else if ((pDevice->bRoaming == FALSE)&&(pDevice->bIsRoaming == TRUE)) {
                             pDevice->uIsroamingTime++;
@@ -1315,7 +1234,6 @@
 
     pMgmt->sTimerSecondCallback.expires = RUN_AT(HZ);
     add_timer(&pMgmt->sTimerSecondCallback);
-    return;
 }
 
 /*+
@@ -1364,7 +1282,6 @@
 
     // Only Unicast using support rates
     if (wFIFOCtl & FIFOCTL_NEEDACK) {
-        //DBG_PRN_GRP21(("Device %08X, wRate %04X, byTSR %02X\n", hDeviceContext, wRate, byTSR));
         if (pMgmt->eCurrMode == WMAC_MODE_ESS_STA) {
             pMgmt->sNodeDBTable[0].uTxAttempts += 1;
             if ( !(byTSR & (TSR_TMO | TSR_RETRYTMO))) {
@@ -1475,10 +1392,6 @@
             }
         }
     }
-
-    return;
-
-
 }
 
 /*+
@@ -1519,8 +1432,6 @@
             memset(&pMgmt->sNodeDBTable[ii], 0, sizeof(KnownNodeDB));
         }
     }
-
-    return;
 };
 
 void s_vCheckSensitivity(void *hDeviceContext)
@@ -1584,7 +1495,6 @@
 //decide link quality
 if(pDevice->bLinkPass !=TRUE)
 {
- //  printk("s_uCalculateLinkQual-->Link disconnect and Poor quality**\n");
    pDevice->scStatistic.LinkQuality = 0;
    pDevice->scStatistic.SignalStren = 0;
 }
@@ -1608,7 +1518,6 @@
    pDevice->scStatistic.TxFailCount = 0;
    pDevice->scStatistic.TxNoRetryOkCount = 0;
    pDevice->scStatistic.TxRetryOkCount = 0;
-   return;
 }
 
 void BSSvClearAnyBSSJoinRecord(void *hDeviceContext)
@@ -1617,10 +1526,8 @@
     PSMgmtObject    pMgmt = &(pDevice->sMgmtObj);
     unsigned int            ii;
 
-    for (ii = 0; ii < MAX_BSS_NUM; ii++) {
+	for (ii = 0; ii < MAX_BSS_NUM; ii++)
         pMgmt->sBSSList[ii].bSelected = FALSE;
-    }
-    return;
 }
 
 void s_vCheckPreEDThreshold(void *hDeviceContext)
@@ -1637,6 +1544,5 @@
             BBvUpdatePreEDThreshold(pDevice, FALSE);
         }
     }
-    return;
 }
 
diff --git a/drivers/staging/vt6656/card.c b/drivers/staging/vt6656/card.c
index a49053b..9d09e9f 100644
--- a/drivers/staging/vt6656/card.c
+++ b/drivers/staging/vt6656/card.c
@@ -91,15 +91,10 @@
  *      uConnectionChannel  - Channel to be set
  *  Out:
  *      none
- *
- * Return Value: TRUE if succeeded; FALSE if failed.
- *
  */
-BOOL CARDbSetMediaChannel(void *pDeviceHandler, unsigned int uConnectionChannel)
+void CARDbSetMediaChannel(void *pDeviceHandler, unsigned int uConnectionChannel)
 {
 PSDevice            pDevice = (PSDevice) pDeviceHandler;
-BOOL                bResult = TRUE;
-
 
     if (pDevice->byBBType == BB_TYPE_11A) { // 15 ~ 38
         if ((uConnectionChannel < (CB_MAX_CHANNEL_24G+1)) || (uConnectionChannel > CB_MAX_CHANNEL))
@@ -140,7 +135,6 @@
         RFbRawSetPower(pDevice, pDevice->abyCCKPwrTbl[uConnectionChannel-1], RATE_1M);
     }
     ControlvWriteByte(pDevice,MESSAGE_REQUEST_MACREG,MAC_REG_CHANNEL,(BYTE)(uConnectionChannel|0x80));
-    return(bResult);
 }
 
 /*
@@ -607,7 +601,7 @@
  * Return Value: TRUE if succeeded; FALSE if failed.
  *
  */
-BOOL CARDbAddBasicRate(void *pDeviceHandler, WORD wRateIdx)
+void CARDbAddBasicRate(void *pDeviceHandler, WORD wRateIdx)
 {
 PSDevice    pDevice = (PSDevice) pDeviceHandler;
 WORD wRate = (WORD)(1<<wRateIdx);
@@ -616,8 +610,6 @@
 
     //Determines the highest basic rate.
     CARDvUpdateBasicTopRate(pDevice);
-
-    return(TRUE);
 }
 
 BOOL CARDbIsOFDMinBasicRate(void *pDeviceHandler)
@@ -1090,7 +1082,7 @@
 
     if (byCount == 0) {
         pDevice->sMgmtObj.uCurrChannel = byNewChannel;
-        bResult = CARDbSetMediaChannel(pDevice, byNewChannel);
+	CARDbSetMediaChannel(pDevice, byNewChannel);
 
 	return bResult;
     }
diff --git a/drivers/staging/vt6656/card.h b/drivers/staging/vt6656/card.h
index 6c91343..9cf71a3 100644
--- a/drivers/staging/vt6656/card.h
+++ b/drivers/staging/vt6656/card.h
@@ -60,12 +60,12 @@
 
 /*---------------------  Export Functions  --------------------------*/
 
-BOOL CARDbSetMediaChannel(void *pDeviceHandler,
+void CARDbSetMediaChannel(void *pDeviceHandler,
 			  unsigned int uConnectionChannel);
 void CARDvSetRSPINF(void *pDeviceHandler, BYTE byBBType);
 void vUpdateIFS(void *pDeviceHandler);
 void CARDvUpdateBasicTopRate(void *pDeviceHandler);
-BOOL CARDbAddBasicRate(void *pDeviceHandler, WORD wRateIdx);
+void CARDbAddBasicRate(void *pDeviceHandler, WORD wRateIdx);
 BOOL CARDbIsOFDMinBasicRate(void *pDeviceHandler);
 void CARDvAdjustTSF(void *pDeviceHandler, BYTE byRxRate,
 		    QWORD qwBSSTimestamp, QWORD qwLocalTSF);
diff --git a/drivers/staging/vt6656/int.c b/drivers/staging/vt6656/int.c
index c95833a..0a11423 100644
--- a/drivers/staging/vt6656/int.c
+++ b/drivers/staging/vt6656/int.c
@@ -92,9 +92,8 @@
 	spin_unlock_irq(&pDevice->lock);
 }
 
-int INTnsProcessData(PSDevice pDevice)
+void INTnsProcessData(PSDevice pDevice)
 {
-	int status = STATUS_SUCCESS;
 	PSINTData	pINTData;
 	PSMgmtObject	pMgmt = &(pDevice->sMgmtObj);
 	struct net_device_stats *pStats = &pDevice->stats;
@@ -218,6 +217,4 @@
 			pDevice->scStatistic.ullTxBroadcastBytes;
 	pStats->tx_errors = pDevice->scStatistic.dwTsrErr;
 	pStats->tx_dropped = pDevice->scStatistic.dwTsrErr;
-
-	return status;
 }
diff --git a/drivers/staging/vt6656/int.h b/drivers/staging/vt6656/int.h
index 3176c8d..a5d96b9 100644
--- a/drivers/staging/vt6656/int.h
+++ b/drivers/staging/vt6656/int.h
@@ -68,6 +68,6 @@
 /*---------------------  Export Functions  --------------------------*/
 
 void INTvWorkItem(void *Context);
-int INTnsProcessData(PSDevice pDevice);
+void INTnsProcessData(PSDevice pDevice);
 
 #endif /* __INT_H__ */
diff --git a/drivers/staging/vt6656/ioctl.c b/drivers/staging/vt6656/ioctl.c
index 4939002..1463d76 100644
--- a/drivers/staging/vt6656/ioctl.c
+++ b/drivers/staging/vt6656/ioctl.c
@@ -295,6 +295,10 @@
 			result = -EFAULT;
 			break;
 		}
+		if (sList.uItem > (ULONG_MAX - sizeof(SBSSIDList)) / sizeof(SBSSIDItem)) {
+			result = -EINVAL;
+			break;
+		}
 		pList = (PSBSSIDList)kmalloc(sizeof(SBSSIDList) + (sList.uItem * sizeof(SBSSIDItem)), (int)GFP_ATOMIC);
 		if (pList == NULL) {
 			result = -ENOMEM;
@@ -557,6 +561,10 @@
 			result = -EFAULT;
 			break;
 		}
+		if (sNodeList.uItem > (ULONG_MAX - sizeof(SNodeList)) / sizeof(SNodeItem)) {
+			result = -ENOMEM;
+			break;
+		}
 		pNodeList = (PSNodeList)kmalloc(sizeof(SNodeList) + (sNodeList.uItem * sizeof(SNodeItem)), (int)GFP_ATOMIC);
 		if (pNodeList == NULL) {
 			result = -ENOMEM;
diff --git a/drivers/staging/vt6656/iwctl.c b/drivers/staging/vt6656/iwctl.c
index 2121205..ecfda52 100644
--- a/drivers/staging/vt6656/iwctl.c
+++ b/drivers/staging/vt6656/iwctl.c
@@ -128,17 +128,6 @@
 	return 0;
 }
 
-int iwctl_giwnwid(struct net_device *dev,
-             struct iw_request_info *info,
-			 struct iw_param *wrq,
-                   char *extra)
-{
- 	//wrq->value = 0x100;
-	//wrq->disabled = 0;
-	//wrq->fixed = 1;
-	//return 0;
-  return -EOPNOTSUPP;
-}
 /*
  * Wireless Handler : set scan
  */
@@ -1939,7 +1928,6 @@
 	(iw_handler) iwctl_commit,      // SIOCSIWCOMMIT
 	(iw_handler) iwctl_giwname,     // SIOCGIWNAME
 	(iw_handler) NULL,				// SIOCSIWNWID
-	(iw_handler) NULL,				// SIOCGIWNWID
 	(iw_handler) iwctl_siwfreq,		// SIOCSIWFREQ
 	(iw_handler) iwctl_giwfreq,		// SIOCGIWFREQ
 	(iw_handler) iwctl_siwmode,		// SIOCSIWMODE
diff --git a/drivers/staging/vt6656/iwctl.h b/drivers/staging/vt6656/iwctl.h
index cc48954..10a240e 100644
--- a/drivers/staging/vt6656/iwctl.h
+++ b/drivers/staging/vt6656/iwctl.h
@@ -77,11 +77,6 @@
 			 char *wrq,
 			 char *extra);
 
-int iwctl_giwnwid(struct net_device *dev,
-             struct iw_request_info *info,
-			 struct iw_param *wrq,
-                   char *extra) ;
-
 int iwctl_giwsens(struct net_device *dev,
 			 struct iw_request_info *info,
 			 struct iw_param *wrq,
diff --git a/drivers/staging/vt6656/mac.c b/drivers/staging/vt6656/mac.c
index 26c19d1..af4a29d 100644
--- a/drivers/staging/vt6656/mac.c
+++ b/drivers/staging/vt6656/mac.c
@@ -133,10 +133,9 @@
  *  Out:
  *      none
  *
- * Return Value: TRUE if success; otherwise FALSE
  *
  */
-BOOL MACbShutdown (PSDevice pDevice)
+void MACbShutdown(PSDevice pDevice)
 {
     CONTROLnsRequestOutAsyn(pDevice,
                         MESSAGE_TYPE_MACSHUTDOWN,
@@ -145,7 +144,6 @@
                         0,
                         NULL
                         );
-    return TRUE;
 }
 
 void MACvSetBBType(PSDevice pDevice,BYTE byType)
diff --git a/drivers/staging/vt6656/mac.h b/drivers/staging/vt6656/mac.h
index 491ff5e..147ac50 100644
--- a/drivers/staging/vt6656/mac.h
+++ b/drivers/staging/vt6656/mac.h
@@ -422,7 +422,7 @@
 
 void MACvSetMultiAddrByHash(PSDevice pDevice, BYTE byHashIdx);
 void MACvWriteMultiAddr(PSDevice pDevice, unsigned int uByteIdx, BYTE byData);
-BOOL MACbShutdown(PSDevice pDevice);
+void MACbShutdown(PSDevice pDevice);
 void MACvSetBBType(PSDevice pDevice, BYTE byType);
 void MACvSetMISCFifo(PSDevice pDevice, WORD wOffset, DWORD dwData);
 void MACvDisableKeyEntry(PSDevice pDevice, unsigned int uEntryIdx);
diff --git a/drivers/staging/vt6656/main_usb.c b/drivers/staging/vt6656/main_usb.c
index 541f9aa..6a708f4 100644
--- a/drivers/staging/vt6656/main_usb.c
+++ b/drivers/staging/vt6656/main_usb.c
@@ -900,7 +900,7 @@
     }
 
     // allocate rcb mem
-    pDevice->pRCBMem = kmalloc((sizeof(RCB) * pDevice->cbRD), GFP_KERNEL);
+	pDevice->pRCBMem = kzalloc((sizeof(RCB) * pDevice->cbRD), GFP_KERNEL);
     if (pDevice->pRCBMem == NULL) {
         DBG_PRT(MSG_LEVEL_ERR,KERN_ERR "%s : alloc rx usb context failed\n", pDevice->dev->name);
         goto free_tx;
@@ -912,7 +912,6 @@
     pDevice->FirstRecvMngList = NULL;
     pDevice->LastRecvMngList = NULL;
     pDevice->NumRecvFreeList = 0;
-    memset(pDevice->pRCBMem, 0, (sizeof(RCB) * pDevice->cbRD));
     pRCB = (PRCB) pDevice->pRCBMem;
 
     for (ii = 0; ii < pDevice->cbRD; ii++) {
@@ -1618,15 +1617,8 @@
 		break;
 
 	case SIOCSIWNWID:
-        rc = -EOPNOTSUPP;
-		break;
-
 	case SIOCGIWNWID:     //0x8b03  support
-	#ifdef  WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT
-          rc = iwctl_giwnwid(dev, NULL, &(wrq->u.nwid), NULL);
-	#else
-        rc = -EOPNOTSUPP;
-	#endif
+		rc = -EOPNOTSUPP;
 		break;
 
 		// Set frequency/channel
diff --git a/drivers/staging/wlags49_h2/wl_pci.c b/drivers/staging/wlags49_h2/wl_pci.c
index 1f1d986..2bd9b84 100644
--- a/drivers/staging/wlags49_h2/wl_pci.c
+++ b/drivers/staging/wlags49_h2/wl_pci.c
@@ -112,17 +112,10 @@
 #endif  // DBG
 
 /* define the PCI device Table Cardname and id tables */
-enum hermes_pci_versions {
-	CH_Agere_Systems_Mini_PCI_V1 = 0,
-};
-
 static struct pci_device_id wl_pci_tbl[] __devinitdata = {
-	{ PCI_VENDOR_ID_WL_LKM, PCI_DEVICE_ID_WL_LKM_0,
-	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_Agere_Systems_Mini_PCI_V1 },
-	{ PCI_VENDOR_ID_WL_LKM, PCI_DEVICE_ID_WL_LKM_1,
-	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_Agere_Systems_Mini_PCI_V1 },
-	{ PCI_VENDOR_ID_WL_LKM, PCI_DEVICE_ID_WL_LKM_2,
-	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_Agere_Systems_Mini_PCI_V1 },
+	{ PCI_DEVICE(PCI_VENDOR_ID_WL_LKM, PCI_DEVICE_ID_WL_LKM_0), },
+	{ PCI_DEVICE(PCI_VENDOR_ID_WL_LKM, PCI_DEVICE_ID_WL_LKM_1), },
+	{ PCI_DEVICE(PCI_VENDOR_ID_WL_LKM, PCI_DEVICE_ID_WL_LKM_2), },
 
 	{ }			/* Terminating entry */
 };
diff --git a/drivers/staging/xgifb/Makefile b/drivers/staging/xgifb/Makefile
index 3c8c7de..55e5199 100644
--- a/drivers/staging/xgifb/Makefile
+++ b/drivers/staging/xgifb/Makefile
@@ -1,4 +1,4 @@
 obj-$(CONFIG_FB_XGI)  += xgifb.o
 
-xgifb-y := XGI_main_26.o vb_init.o vb_setmode.o vb_util.o vb_ext.o
+xgifb-y := XGI_main_26.o vb_init.o vb_setmode.o vb_util.o
 
diff --git a/drivers/staging/xgifb/XGI_main.h b/drivers/staging/xgifb/XGI_main.h
index 71aebe3..35f7b2a 100644
--- a/drivers/staging/xgifb/XGI_main.h
+++ b/drivers/staging/xgifb/XGI_main.h
@@ -32,14 +32,10 @@
 #endif
 
 static DEFINE_PCI_DEVICE_TABLE(xgifb_pci_table) = {
-	{PCI_VENDOR_ID_XG, PCI_DEVICE_ID_XG_20, PCI_ANY_ID, PCI_ANY_ID,
-	 0, 0, 0},
-	{PCI_VENDOR_ID_XG, PCI_DEVICE_ID_XG_27, PCI_ANY_ID, PCI_ANY_ID,
-	 0, 0, 1},
-	{PCI_VENDOR_ID_XG, PCI_DEVICE_ID_XG_40, PCI_ANY_ID, PCI_ANY_ID,
-	 0, 0, 2},
-	{PCI_VENDOR_ID_XG, PCI_DEVICE_ID_XG_42, PCI_ANY_ID, PCI_ANY_ID,
-	 0, 0, 3},
+	{PCI_DEVICE(PCI_VENDOR_ID_XG, PCI_DEVICE_ID_XG_20)},
+	{PCI_DEVICE(PCI_VENDOR_ID_XG, PCI_DEVICE_ID_XG_27)},
+	{PCI_DEVICE(PCI_VENDOR_ID_XG, PCI_DEVICE_ID_XG_40)},
+	{PCI_DEVICE(PCI_VENDOR_ID_XG, PCI_DEVICE_ID_XG_42)},
 	{0}
 };
 
@@ -128,7 +124,6 @@
 /* display status */
 static int XGIfb_crt1off;
 static int XGIfb_forcecrt1 = -1;
-static int XGIfb_userom ;
 
 /* global flags */
 static int XGIfb_tvmode;
diff --git a/drivers/staging/xgifb/XGI_main_26.c b/drivers/staging/xgifb/XGI_main_26.c
index 277e408..2502c49 100644
--- a/drivers/staging/xgifb/XGI_main_26.c
+++ b/drivers/staging/xgifb/XGI_main_26.c
@@ -21,7 +21,6 @@
 #include <linux/ioport.h>
 #include <linux/init.h>
 #include <linux/pci.h>
-#include <linux/vmalloc.h>
 #include <linux/vt_kern.h>
 #include <linux/capability.h>
 #include <linux/fs.h>
@@ -46,8 +45,7 @@
 #define GPIOG_EN    (1<<6)
 #define GPIOG_READ  (1<<1)
 
-#define XGIFB_ROM_SIZE	65536
-
+static char *forcecrt2type;
 static char *mode;
 static int vesa = -1;
 static unsigned int refresh_rate;
@@ -159,7 +157,6 @@
 
 	/* unsigned long  temp = 0; */
 	int Clock;
-	XGI_Pr->ROMAddr = HwDeviceExtension->pjVirtualRomBase;
 	InitTo330Pointer(HwDeviceExtension->jChipType, XGI_Pr);
 
 	RefreshRateTableIndex = XGI_GetRatePtrCRT2(HwDeviceExtension, ModeNo,
@@ -199,7 +196,6 @@
 	unsigned char sr_data, cr_data, cr_data2;
 	unsigned long cr_data3;
 	int A, B, C, D, E, F, temp, j;
-	XGI_Pr->ROMAddr = HwDeviceExtension->pjVirtualRomBase;
 	InitTo330Pointer(HwDeviceExtension->jChipType, XGI_Pr);
 	RefreshRateTableIndex = XGI_GetRatePtrCRT2(HwDeviceExtension, ModeNo,
 			ModeIdIndex, XGI_Pr);
@@ -387,7 +383,7 @@
 
 /* ------------------ Internal helper routines ----------------- */
 
-static int XGIfb_GetXG21DefaultLVDSModeIdx(void)
+static int XGIfb_GetXG21DefaultLVDSModeIdx(struct xgifb_video_info *xgifb_info)
 {
 
 	int found_mode = 0;
@@ -396,11 +392,11 @@
 	found_mode = 0;
 	while ((XGIbios_mode[XGIfb_mode_idx].mode_no != 0)
 			&& (XGIbios_mode[XGIfb_mode_idx].xres
-					<= XGI21_LCDCapList[0].LVDSHDE)) {
+					<= xgifb_info->lvds_data.LVDSHDE)) {
 		if ((XGIbios_mode[XGIfb_mode_idx].xres
-				== XGI21_LCDCapList[0].LVDSHDE)
+				== xgifb_info->lvds_data.LVDSHDE)
 				&& (XGIbios_mode[XGIfb_mode_idx].yres
-						== XGI21_LCDCapList[0].LVDSVDE)
+					== xgifb_info->lvds_data.LVDSVDE)
 				&& (XGIbios_mode[XGIfb_mode_idx].bpp == 8)) {
 			found_mode = 1;
 			break;
@@ -456,51 +452,6 @@
 		printk(KERN_INFO "XGIfb: Invalid VESA mode 0x%x'\n", vesamode);
 }
 
-static int XGIfb_GetXG21LVDSData(struct xgifb_video_info *xgifb_info)
-{
-	u8 tmp;
-	void __iomem *data = xgifb_info->mmio_vbase + 0x20000;
-	int i, j, k;
-
-	tmp = xgifb_reg_get(XGISR, 0x1e);
-	xgifb_reg_set(XGISR, 0x1e, tmp | 4);
-
-	if ((readb(data) == 0x55) &&
-	    (readb(data + 1) == 0xAA) &&
-	    (readb(data + 0x65) & 0x1)) {
-		i = readw(data + 0x316);
-		j = readb(data + i - 1);
-		if (j == 0xff)
-			j = 1;
-
-		k = 0;
-		do {
-			XGI21_LCDCapList[k].LVDS_Capability = readw(data + i);
-			XGI21_LCDCapList[k].LVDSHT = readw(data + i + 2);
-			XGI21_LCDCapList[k].LVDSVT = readw(data + i + 4);
-			XGI21_LCDCapList[k].LVDSHDE = readw(data + i + 6);
-			XGI21_LCDCapList[k].LVDSVDE = readw(data + i + 8);
-			XGI21_LCDCapList[k].LVDSHFP = readw(data + i + 10);
-			XGI21_LCDCapList[k].LVDSVFP = readw(data + i + 12);
-			XGI21_LCDCapList[k].LVDSHSYNC = readw(data + i + 14);
-			XGI21_LCDCapList[k].LVDSVSYNC = readw(data + i + 16);
-			XGI21_LCDCapList[k].VCLKData1 = readb(data + i + 18);
-			XGI21_LCDCapList[k].VCLKData2 = readb(data + i + 19);
-			XGI21_LCDCapList[k].PSC_S1 = readb(data + i + 20);
-			XGI21_LCDCapList[k].PSC_S2 = readb(data + i + 21);
-			XGI21_LCDCapList[k].PSC_S3 = readb(data + i + 22);
-			XGI21_LCDCapList[k].PSC_S4 = readb(data + i + 23);
-			XGI21_LCDCapList[k].PSC_S5 = readb(data + i + 24);
-			i += 25;
-			j--;
-			k++;
-		} while ((j > 0) && (k < (sizeof(XGI21_LCDCapList)
-				/ sizeof(struct XGI21_LVDSCapStruct))));
-		return 1;
-	}
-	return 0;
-}
-
 static int XGIfb_validate_mode(struct xgifb_video_info *xgifb_info, int myindex)
 {
 	u16 xres, yres;
@@ -508,8 +459,8 @@
 
 	if (xgifb_info->chip == XG21) {
 		if (xgifb_info->display2 == XGIFB_DISP_LCD) {
-			xres = XGI21_LCDCapList[0].LVDSHDE;
-			yres = XGI21_LCDCapList[0].LVDSVDE;
+			xres = xgifb_info->lvds_data.LVDSHDE;
+			yres = xgifb_info->lvds_data.LVDSVDE;
 			if (XGIbios_mode[myindex].xres > xres)
 				return -1;
 			if (XGIbios_mode[myindex].yres > yres)
@@ -1223,7 +1174,7 @@
 	if (isactive) {
 
 		XGIfb_pre_setmode(xgifb_info);
-		if (XGISetModeNew(hw_info,
+		if (XGISetModeNew(xgifb_info, hw_info,
 				  XGIbios_mode[xgifb_info->mode_idx].mode_no)
 					== 0) {
 			printk(KERN_ERR "XGIfb: Setting mode[0x%x] failed\n",
@@ -1794,17 +1745,16 @@
 			XGIfb_crt1off = 0;
 	}
 
-	if (XGIfb_crt2type != -1)
-		/* TW: Override with option */
-		xgifb_info->display2 = XGIfb_crt2type;
-	else if (cr32 & XGI_VB_TV)
-		xgifb_info->display2 = XGIFB_DISP_TV;
-	else if (cr32 & XGI_VB_LCD)
-		xgifb_info->display2 = XGIFB_DISP_LCD;
-	else if (cr32 & XGI_VB_CRT2)
-		xgifb_info->display2 = XGIFB_DISP_CRT;
-	else
-		xgifb_info->display2 = XGIFB_DISP_NONE;
+	if (!xgifb_info->display2_force) {
+		if (cr32 & XGI_VB_TV)
+			xgifb_info->display2 = XGIFB_DISP_TV;
+		else if (cr32 & XGI_VB_LCD)
+			xgifb_info->display2 = XGIFB_DISP_LCD;
+		else if (cr32 & XGI_VB_CRT2)
+			xgifb_info->display2 = XGIFB_DISP_CRT;
+		else
+			xgifb_info->display2 = XGIFB_DISP_NONE;
+	}
 
 	if (XGIfb_tvplug != -1)
 		/* PR/TW: Override with option */
@@ -1925,8 +1875,6 @@
 			XGIfb_crt2type = XGIFB_DISP_LCD;
 		} else if (!strncmp(this_opt, "noypan", 6)) {
 			XGIfb_ypan = 0;
-		} else if (!strncmp(this_opt, "userom:", 7)) {
-			XGIfb_userom = xgifb_optval(this_opt, 7);
 		} else {
 			mode = this_opt;
 		}
@@ -1934,35 +1882,12 @@
 	return 0;
 }
 
-static unsigned char *xgifb_copy_rom(struct pci_dev *dev)
-{
-	void __iomem *rom_address;
-	unsigned char *rom_copy;
-	size_t rom_size;
-
-	rom_address = pci_map_rom(dev, &rom_size);
-	if (rom_address == NULL)
-		return NULL;
-
-	rom_copy = vzalloc(XGIFB_ROM_SIZE);
-	if (rom_copy == NULL)
-		goto done;
-
-	rom_size = min_t(size_t, rom_size, XGIFB_ROM_SIZE);
-	memcpy_fromio(rom_copy, rom_address, rom_size);
-
-done:
-	pci_unmap_rom(dev, rom_address);
-	return rom_copy;
-}
-
 static int __devinit xgifb_probe(struct pci_dev *pdev,
 		const struct pci_device_id *ent)
 {
 	u8 reg, reg1;
 	u8 CR48, CR38;
 	int ret;
-	bool xgi21_drvlcdcaplist = false;
 	struct fb_info *fb_info;
 	struct xgifb_video_info *xgifb_info;
 	struct xgi_hw_device_info *hw_info;
@@ -2001,6 +1926,11 @@
 		goto error;
 	}
 
+	if (XGIfb_crt2type != -1) {
+		xgifb_info->display2 = XGIfb_crt2type;
+		xgifb_info->display2_force = true;
+	}
+
 	XGIRegInit(&xgifb_info->dev_info, (unsigned long)hw_info->pjIOAddress);
 
 	xgifb_reg_set(XGISR, IND_XGI_PASSWORD, XGI_PASSWORD);
@@ -2041,18 +1971,6 @@
 	printk("XGIfb:chipid = %x\n", xgifb_info->chip);
 	hw_info->jChipType = xgifb_info->chip;
 
-	if ((xgifb_info->chip == XG21) || (XGIfb_userom)) {
-		hw_info->pjVirtualRomBase = xgifb_copy_rom(pdev);
-		if (hw_info->pjVirtualRomBase)
-			printk(KERN_INFO "XGIfb: Video ROM found and mapped to %p\n",
-			       hw_info->pjVirtualRomBase);
-		else
-			printk(KERN_INFO "XGIfb: Video ROM not found\n");
-	} else {
-		hw_info->pjVirtualRomBase = NULL;
-		printk(KERN_INFO "XGIfb: Video ROM usage disabled\n");
-	}
-
 	if (XGIfb_get_dram_size(xgifb_info)) {
 		printk(KERN_INFO "XGIfb: Fatal error: Unable to determine RAM size.\n");
 		ret = -ENODEV;
@@ -2117,8 +2035,6 @@
 		CR38 = xgifb_reg_get(XGICR, 0x38);
 		if ((CR38&0xE0) == 0xC0) {
 			xgifb_info->display2 = XGIFB_DISP_LCD;
-			if (!XGIfb_GetXG21LVDSData(xgifb_info))
-				xgi21_drvlcdcaplist = true;
 		} else if ((CR38&0xE0) == 0x60) {
 			xgifb_info->hasVB = HASVB_CHRONTEL;
 		} else {
@@ -2193,6 +2109,8 @@
 
 	if (xgifb_info->hasVB != HASVB_NONE)
 		XGIfb_detect_VB(xgifb_info);
+	else if (xgifb_info->chip != XG21)
+		xgifb_info->display2 = XGIFB_DISP_NONE;
 
 	if (xgifb_info->display2 == XGIFB_DISP_LCD) {
 		if (!enable_dstn) {
@@ -2254,7 +2172,7 @@
 		if (xgifb_info->display2 == XGIFB_DISP_LCD &&
 		    xgifb_info->chip == XG21)
 			xgifb_info->mode_idx =
-				XGIfb_GetXG21DefaultLVDSModeIdx();
+				XGIfb_GetXG21DefaultLVDSModeIdx(xgifb_info);
 		else
 			xgifb_info->mode_idx = DEFAULT_MODE;
 	}
@@ -2264,21 +2182,6 @@
 		goto error_1;
 	}
 
-	if (xgi21_drvlcdcaplist) {
-		int m;
-
-		for (m = 0; m < ARRAY_SIZE(XGI21_LCDCapList); m++)
-			if ((XGI21_LCDCapList[m].LVDSHDE ==
-				XGIbios_mode[xgifb_info->mode_idx].xres) &&
-			    (XGI21_LCDCapList[m].LVDSVDE ==
-				XGIbios_mode[xgifb_info->mode_idx].yres)) {
-				xgifb_reg_set(xgifb_info->dev_info.P3d4,
-					      0x36,
-					      m);
-				break;
-			}
-	}
-
 	/* yilin set default refresh rate */
 	xgifb_info->refresh_rate = refresh_rate;
 	if (xgifb_info->refresh_rate == 0)
@@ -2418,7 +2321,6 @@
 error_0:
 	release_mem_region(xgifb_info->video_base, xgifb_info->video_size);
 error:
-	vfree(hw_info->pjVirtualRomBase);
 	framebuffer_release(fb_info);
 	return ret;
 }
@@ -2442,7 +2344,6 @@
 	iounmap(xgifb_info->video_vbase);
 	release_mem_region(xgifb_info->mmio_base, xgifb_info->mmio_size);
 	release_mem_region(xgifb_info->video_base, xgifb_info->video_size);
-	vfree(xgifb_info->hw_info.pjVirtualRomBase);
 	framebuffer_release(fb_info);
 	pci_set_drvdata(pdev, NULL);
 }
@@ -2458,6 +2359,8 @@
 {
 	char *option = NULL;
 
+	if (forcecrt2type != NULL)
+		XGIfb_search_crt2type(forcecrt2type);
 	if (fb_get_options("xgifb", &option))
 		return -ENODEV;
 	XGIfb_setup(option);
@@ -2480,6 +2383,11 @@
 module_param(mode, charp, 0);
 module_param(vesa, int, 0);
 module_param(filter, int, 0);
+module_param(forcecrt2type, charp, 0);
+
+MODULE_PARM_DESC(forcecrt2type,
+	"\nForce the second display output type. Possible values are NONE,\n"
+	"LCD, TV, VGA, SVIDEO or COMPOSITE.\n");
 
 MODULE_PARM_DESC(mode,
 	"\nSelects the desired default display mode in the format XxYxDepth,\n"
diff --git a/drivers/staging/xgifb/XGIfb.h b/drivers/staging/xgifb/XGIfb.h
index 7611846..2c866bb 100644
--- a/drivers/staging/xgifb/XGIfb.h
+++ b/drivers/staging/xgifb/XGIfb.h
@@ -86,10 +86,13 @@
 	unsigned int refresh_rate;
 
 	enum xgifb_display_type display2; /* the second display output type */
+	bool display2_force;
 	unsigned char hasVB;
 	unsigned char TV_type;
 	unsigned char TV_plug;
 
+	struct XGI21_LVDSCapStruct lvds_data;
+
 	enum XGI_CHIP_TYPE chip;
 	unsigned char revision_id;
 
diff --git a/drivers/staging/xgifb/vb_ext.c b/drivers/staging/xgifb/vb_ext.c
deleted file mode 100644
index b1a2573..0000000
--- a/drivers/staging/xgifb/vb_ext.c
+++ /dev/null
@@ -1,444 +0,0 @@
-#include <linux/io.h>
-#include <linux/types.h>
-#include "XGIfb.h"
-
-#include "vb_def.h"
-#include "vgatypes.h"
-#include "vb_struct.h"
-#include "vb_util.h"
-#include "vb_setmode.h"
-#include "vb_ext.h"
-
-/**************************************************************
- *********************** Dynamic Sense ************************
- *************************************************************/
-
-static unsigned char XGINew_Is301B(struct vb_device_info *pVBInfo)
-{
-	unsigned short flag;
-
-	flag = xgifb_reg_get(pVBInfo->Part4Port, 0x01);
-
-	if (flag > 0x0B0)
-		return 0; /* 301b */
-	else
-		return 1;
-}
-
-static unsigned char XGINew_Sense(unsigned short tempbx,
-				  unsigned short tempcx,
-				  struct vb_device_info *pVBInfo)
-{
-	unsigned short temp, i, tempch;
-
-	temp = tempbx & 0xFF;
-	xgifb_reg_set(pVBInfo->Part4Port, 0x11, temp);
-	temp = (tempbx & 0xFF00) >> 8;
-	temp |= (tempcx & 0x00FF);
-	xgifb_reg_and_or(pVBInfo->Part4Port, 0x10, ~0x1F, temp);
-
-	for (i = 0; i < 10; i++)
-		XGI_LongWait(pVBInfo);
-
-	tempch = (tempcx & 0x7F00) >> 8;
-	temp = xgifb_reg_get(pVBInfo->Part4Port, 0x03);
-	temp = temp ^ (0x0E);
-	temp &= tempch;
-
-	if (temp > 0)
-		return 1;
-	else
-		return 0;
-}
-
-static unsigned char
-XGINew_GetLCDDDCInfo(struct xgi_hw_device_info *HwDeviceExtension,
-		     struct vb_device_info *pVBInfo)
-{
-	unsigned short temp;
-
-	/* add lcd sense */
-	if (HwDeviceExtension->ulCRT2LCDType == LCD_UNKNOWN) {
-		return 0;
-	} else {
-		temp = (unsigned short) HwDeviceExtension->ulCRT2LCDType;
-		switch (HwDeviceExtension->ulCRT2LCDType) {
-		case LCD_INVALID:
-		case LCD_800x600:
-		case LCD_1024x768:
-		case LCD_1280x1024:
-			break;
-
-		case LCD_640x480:
-		case LCD_1024x600:
-		case LCD_1152x864:
-		case LCD_1280x960:
-		case LCD_1152x768:
-			temp = 0;
-			break;
-
-		case LCD_1400x1050:
-		case LCD_1280x768:
-		case LCD_1600x1200:
-			break;
-
-		case LCD_1920x1440:
-		case LCD_2048x1536:
-			temp = 0;
-			break;
-
-		default:
-			break;
-		}
-		xgifb_reg_and_or(pVBInfo->P3d4, 0x36, 0xF0, temp);
-		return 1;
-	}
-}
-
-static unsigned char XGINew_GetPanelID(struct vb_device_info *pVBInfo)
-{
-	unsigned short PanelTypeTable[16] = { SyncNN | PanelRGB18Bit
-			| Panel800x600  | _PanelType00, SyncNN | PanelRGB18Bit
-			| Panel1024x768 | _PanelType01, SyncNN | PanelRGB18Bit
-			| Panel800x600  | _PanelType02, SyncNN | PanelRGB18Bit
-			| Panel640x480  | _PanelType03, SyncNN | PanelRGB18Bit
-			| Panel1024x768 | _PanelType04, SyncNN | PanelRGB18Bit
-			| Panel1024x768 | _PanelType05, SyncNN | PanelRGB18Bit
-			| Panel1024x768 | _PanelType06, SyncNN | PanelRGB24Bit
-			| Panel1024x768 | _PanelType07, SyncNN | PanelRGB18Bit
-			| Panel800x600  | _PanelType08, SyncNN | PanelRGB18Bit
-			| Panel1024x768 | _PanelType09, SyncNN | PanelRGB18Bit
-			| Panel800x600  | _PanelType0A, SyncNN | PanelRGB18Bit
-			| Panel1024x768 | _PanelType0B, SyncNN | PanelRGB18Bit
-			| Panel1024x768 | _PanelType0C, SyncNN | PanelRGB24Bit
-			| Panel1024x768 | _PanelType0D, SyncNN | PanelRGB18Bit
-			| Panel1024x768 | _PanelType0E, SyncNN | PanelRGB18Bit
-			| Panel1024x768 | _PanelType0F };
-	unsigned short tempax, tempbx, temp;
-	/* unsigned short return_flag; */
-
-	tempax = xgifb_reg_get(pVBInfo->P3c4, 0x1A);
-	tempbx = tempax & 0x1E;
-
-	if (tempax == 0)
-		return 0;
-	else {
-		/*
-		if (!(tempax & 0x10)) {
-			if (pVBInfo->IF_DEF_LVDS == 1) {
-				tempbx = 0;
-				temp = xgifb_reg_get(pVBInfo->P3c4, 0x38);
-				if (temp & 0x40)
-					tempbx |= 0x08;
-				if (temp & 0x20)
-					tempbx |= 0x02;
-				if (temp & 0x01)
-					tempbx |= 0x01;
-
-				temp = xgifb_reg_get(pVBInfo->P3c4, 0x39);
-				if (temp & 0x80)
-					tempbx |= 0x04;
-			 } else {
-				return(0);
-			 }
-		}
-		*/
-
-		tempbx = tempbx >> 1;
-		temp = tempbx & 0x00F;
-		xgifb_reg_set(pVBInfo->P3d4, 0x36, temp);
-		tempbx--;
-		tempbx = PanelTypeTable[tempbx];
-
-		temp = (tempbx & 0xFF00) >> 8;
-		xgifb_reg_and_or(pVBInfo->P3d4, 0x37, ~(LCDSyncBit
-				| LCDRGB18Bit), temp);
-		return 1;
-	}
-}
-
-static unsigned char
-XGINew_BridgeIsEnable(struct xgi_hw_device_info *HwDeviceExtension,
-		      struct vb_device_info *pVBInfo)
-{
-	unsigned short flag;
-
-	if (XGI_BridgeIsOn(pVBInfo) == 0) {
-		flag = xgifb_reg_get(pVBInfo->Part1Port, 0x0);
-
-		if (flag & 0x050)
-			return 1;
-		else
-			return 0;
-
-	}
-	return 0;
-}
-
-static unsigned char
-XGINew_SenseHiTV(struct xgi_hw_device_info *HwDeviceExtension,
-		 struct vb_device_info *pVBInfo)
-{
-	unsigned short tempbx, tempcx, temp, i, tempch;
-
-	tempbx = *pVBInfo->pYCSenseData2;
-
-	tempcx = 0x0604;
-
-	temp = tempbx & 0xFF;
-	xgifb_reg_set(pVBInfo->Part4Port, 0x11, temp);
-	temp = (tempbx & 0xFF00) >> 8;
-	temp |= (tempcx & 0x00FF);
-	xgifb_reg_and_or(pVBInfo->Part4Port, 0x10, ~0x1F, temp);
-
-	for (i = 0; i < 10; i++)
-		XGI_LongWait(pVBInfo);
-
-	tempch = (tempcx & 0xFF00) >> 8;
-	temp = xgifb_reg_get(pVBInfo->Part4Port, 0x03);
-	temp = temp ^ (0x0E);
-	temp &= tempch;
-
-	if (temp != tempch)
-		return 0;
-
-	tempbx = *pVBInfo->pVideoSenseData2;
-
-	tempcx = 0x0804;
-	temp = tempbx & 0xFF;
-	xgifb_reg_set(pVBInfo->Part4Port, 0x11, temp);
-	temp = (tempbx & 0xFF00) >> 8;
-	temp |= (tempcx & 0x00FF);
-	xgifb_reg_and_or(pVBInfo->Part4Port, 0x10, ~0x1F, temp);
-
-	for (i = 0; i < 10; i++)
-		XGI_LongWait(pVBInfo);
-
-	tempch = (tempcx & 0xFF00) >> 8;
-	temp = xgifb_reg_get(pVBInfo->Part4Port, 0x03);
-	temp = temp ^ (0x0E);
-	temp &= tempch;
-
-	if (temp != tempch) {
-		return 0;
-	} else {
-		tempbx = 0x3FF;
-		tempcx = 0x0804;
-		temp = tempbx & 0xFF;
-		xgifb_reg_set(pVBInfo->Part4Port, 0x11, temp);
-		temp = (tempbx & 0xFF00) >> 8;
-		temp |= (tempcx & 0x00FF);
-		xgifb_reg_and_or(pVBInfo->Part4Port, 0x10, ~0x1F, temp);
-
-		for (i = 0; i < 10; i++)
-			XGI_LongWait(pVBInfo);
-
-		tempch = (tempcx & 0xFF00) >> 8;
-		temp = xgifb_reg_get(pVBInfo->Part4Port, 0x03);
-		temp = temp ^ (0x0E);
-		temp &= tempch;
-
-		if (temp != tempch)
-			return 1;
-		else
-			return 0;
-	}
-}
-
-void XGI_GetSenseStatus(struct xgi_hw_device_info *HwDeviceExtension,
-			struct vb_device_info *pVBInfo)
-{
-	unsigned short  tempax = 0, tempbx, tempcx, temp,
-			P2reg0 = 0, SenseModeNo = 0,
-			OutputSelect = *pVBInfo->pOutputSelect,
-			ModeIdIndex, i;
-	pVBInfo->BaseAddr = (unsigned long) HwDeviceExtension->pjIOAddress;
-
-	if (pVBInfo->IF_DEF_LVDS == 1) {
-		/* ynlai 02/27/2002 */
-		tempax = xgifb_reg_get(pVBInfo->P3c4, 0x1A);
-		tempbx = xgifb_reg_get(pVBInfo->P3c4, 0x1B);
-		tempax = ((tempax & 0xFE) >> 1) | (tempbx << 8);
-		if (tempax == 0x00) { /* Get Panel id from DDC */
-			temp = XGINew_GetLCDDDCInfo(HwDeviceExtension, pVBInfo);
-			if (temp == 1) { /* LCD connect */
-				/* set CR39 bit0="1" */
-				xgifb_reg_and_or(pVBInfo->P3d4,
-						 0x39, 0xFF, 0x01);
-				/* clean CR37 bit4="0" */
-				xgifb_reg_and_or(pVBInfo->P3d4,
-						 0x37, 0xEF, 0x00);
-				temp = LCDSense;
-			} else { /* LCD don't connect */
-				temp = 0;
-			}
-		} else {
-			XGINew_GetPanelID(pVBInfo);
-			temp = LCDSense;
-		}
-
-		tempbx = ~(LCDSense | AVIDEOSense | SVIDEOSense);
-		xgifb_reg_and_or(pVBInfo->P3d4, 0x32, tempbx, temp);
-	} else { /* for 301 */
-		if (pVBInfo->VBInfo & SetCRT2ToHiVisionTV) { /* for HiVision */
-			tempax = xgifb_reg_get(pVBInfo->P3c4, 0x38);
-			temp = tempax & 0x01;
-			tempax = xgifb_reg_get(pVBInfo->P3c4, 0x3A);
-			temp = temp | (tempax & 0x02);
-			xgifb_reg_and_or(pVBInfo->P3d4, 0x32, 0xA0, temp);
-		} else {
-			if (XGI_BridgeIsOn(pVBInfo)) {
-				P2reg0 = xgifb_reg_get(pVBInfo->Part2Port,
-						       0x00);
-				if (!XGINew_BridgeIsEnable(HwDeviceExtension,
-							   pVBInfo)) {
-					SenseModeNo = 0x2e;
-				/* xgifb_reg_set(pVBInfo->P3d4, 0x30, 0x41);
-				 * XGISetModeNew(HwDeviceExtension, 0x2e);
-				 * // ynlai InitMode */
-
-					temp = XGI_SearchModeID(SenseModeNo,
-								&ModeIdIndex,
-								pVBInfo);
-					XGI_GetVGAType(HwDeviceExtension,
-						       pVBInfo);
-					XGI_GetVBType(pVBInfo);
-					pVBInfo->SetFlag = 0x00;
-					pVBInfo->ModeType = ModeVGA;
-					pVBInfo->VBInfo = SetCRT2ToRAMDAC |
-							  LoadDACFlag |
-							  SetInSlaveMode;
-					XGI_GetLCDInfo(0x2e,
-						       ModeIdIndex,
-						       pVBInfo);
-					XGI_GetTVInfo(0x2e,
-						      ModeIdIndex,
-						      pVBInfo);
-					XGI_EnableBridge(HwDeviceExtension,
-							 pVBInfo);
-					XGI_SetCRT2Group301(SenseModeNo,
-							    HwDeviceExtension,
-							    pVBInfo);
-					XGI_SetCRT2ModeRegs(0x2e,
-							    HwDeviceExtension,
-							    pVBInfo);
-					/* XGI_DisableBridge(HwDeviceExtension,
-					 *		     pVBInfo ) ; */
-					/* Display Off 0212 */
-					xgifb_reg_and_or(pVBInfo->P3c4,
-							 0x01,
-							 0xDF,
-							 0x20);
-					for (i = 0; i < 20; i++)
-						XGI_LongWait(pVBInfo);
-				}
-				xgifb_reg_set(pVBInfo->Part2Port, 0x00, 0x1c);
-				tempax = 0;
-				tempbx = *pVBInfo->pRGBSenseData;
-
-				if (!(XGINew_Is301B(pVBInfo)))
-					tempbx = *pVBInfo->pRGBSenseData2;
-
-				tempcx = 0x0E08;
-				if (XGINew_Sense(tempbx, tempcx, pVBInfo)) {
-					if (XGINew_Sense(tempbx,
-							 tempcx,
-							 pVBInfo))
-						tempax |= Monitor2Sense;
-				}
-
-				if (pVBInfo->VBType & VB_XGI301C)
-					xgifb_reg_or(pVBInfo->Part4Port,
-						     0x0d,
-						     0x04);
-
-				/* add by kuku for Multi-adapter sense HiTV */
-				if (XGINew_SenseHiTV(HwDeviceExtension,
-						     pVBInfo)) {
-					tempax |= HiTVSense;
-					if ((pVBInfo->VBType & VB_XGI301C))
-						tempax ^= (HiTVSense |
-							   YPbPrSense);
-				}
-
-				/* start */
-				if (!(tempax & (HiTVSense | YPbPrSense))) {
-					tempbx = *pVBInfo->pYCSenseData;
-					if (!(XGINew_Is301B(pVBInfo)))
-						tempbx = *pVBInfo->pYCSenseData2;
-					tempcx = 0x0604;
-					if (XGINew_Sense(tempbx,
-							 tempcx,
-							 pVBInfo)) {
-						if (XGINew_Sense(tempbx,
-								 tempcx,
-								 pVBInfo))
-							tempax |= SVIDEOSense;
-					}
-
-					if (OutputSelect & BoardTVType) {
-						tempbx = *pVBInfo->pVideoSenseData;
-
-						if (!(XGINew_Is301B(pVBInfo)))
-							tempbx = *pVBInfo->pVideoSenseData2;
-
-						tempcx = 0x0804;
-						if (XGINew_Sense(tempbx,
-								 tempcx,
-								 pVBInfo)) {
-							if (XGINew_Sense(tempbx,
-									 tempcx,
-									 pVBInfo))
-								tempax |= AVIDEOSense;
-						}
-					} else {
-						if (!(tempax & SVIDEOSense)) {
-							tempbx = *pVBInfo->pVideoSenseData;
-
-							if (!(XGINew_Is301B(pVBInfo)))
-								tempbx = *pVBInfo->pVideoSenseData2;
-
-							tempcx = 0x0804;
-							if (XGINew_Sense(tempbx,
-									 tempcx,
-									 pVBInfo)) {
-								if (XGINew_Sense(tempbx, tempcx, pVBInfo))
-									tempax |= AVIDEOSense;
-							}
-						}
-					}
-				}
-			} /* end */
-			if (!(tempax & Monitor2Sense)) {
-				if (XGINew_SenseLCD(HwDeviceExtension, pVBInfo))
-					tempax |= LCDSense;
-			}
-			tempbx = 0;
-			tempcx = 0;
-			XGINew_Sense(tempbx, tempcx, pVBInfo);
-
-			xgifb_reg_and_or(pVBInfo->P3d4, 0x32, ~0xDF, tempax);
-			xgifb_reg_set(pVBInfo->Part2Port, 0x00, P2reg0);
-
-			if (!(P2reg0 & 0x20)) {
-				pVBInfo->VBInfo = DisableCRT2Display;
-				/* XGI_SetCRT2Group301(SenseModeNo,
-				 *		       HwDeviceExtension,
-				 *		       pVBInfo); */
-			}
-		}
-	}
-	XGI_DisableBridge(HwDeviceExtension, pVBInfo); /* shampoo 0226 */
-
-}
-
-unsigned short XGINew_SenseLCD(struct xgi_hw_device_info *HwDeviceExtension,
-			       struct vb_device_info *pVBInfo)
-{
-	/* unsigned short SoftSetting ; */
-	unsigned short temp;
-
-	temp = XGINew_GetLCDDDCInfo(HwDeviceExtension, pVBInfo);
-
-	return temp;
-}
diff --git a/drivers/staging/xgifb/vb_ext.h b/drivers/staging/xgifb/vb_ext.h
deleted file mode 100644
index 0b1f55b..0000000
--- a/drivers/staging/xgifb/vb_ext.h
+++ /dev/null
@@ -1,9 +0,0 @@
-#ifndef _VBEXT_
-#define _VBEXT_
-
-extern void XGI_GetSenseStatus(struct xgi_hw_device_info *HwDeviceExtension,
-			       struct vb_device_info *pVBInfo);
-extern unsigned short XGINew_SenseLCD(struct xgi_hw_device_info *,
-				      struct vb_device_info *pVBInfo);
-
-#endif
diff --git a/drivers/staging/xgifb/vb_init.c b/drivers/staging/xgifb/vb_init.c
index 9e890a1..4ccd988 100644
--- a/drivers/staging/xgifb/vb_init.c
+++ b/drivers/staging/xgifb/vb_init.c
@@ -1,6 +1,7 @@
 #include <linux/types.h>
 #include <linux/delay.h> /* udelay */
 #include <linux/pci.h>
+#include <linux/vmalloc.h>
 
 #include "vgatypes.h"
 #include "XGIfb.h"
@@ -10,7 +11,6 @@
 #include "vb_util.h"
 #include "vb_setmode.h"
 #include "vb_init.h"
-#include "vb_ext.h"
 
 
 #include <linux/io.h>
@@ -35,6 +35,8 @@
 	{ 2, 12,  9,  8, 0x35},
 	{ 2, 12,  8,  4, 0x31} };
 
+#define XGIFB_ROM_SIZE	65536
+
 static unsigned char
 XGINew_GetXG20DRAMType(struct xgi_hw_device_info *HwDeviceExtension,
 		       struct vb_device_info *pVBInfo)
@@ -1068,20 +1070,20 @@
 	return 0;
 }
 
-static void XGINew_SetDRAMSize_340(struct xgi_hw_device_info *HwDeviceExtension,
+static void XGINew_SetDRAMSize_340(struct xgifb_video_info *xgifb_info,
+		struct xgi_hw_device_info *HwDeviceExtension,
 		struct vb_device_info *pVBInfo)
 {
 	unsigned short data;
 
-	pVBInfo->ROMAddr = HwDeviceExtension->pjVirtualRomBase;
 	pVBInfo->FBAddr = HwDeviceExtension->pjVideoMemoryAddress;
 
-	XGISetModeNew(HwDeviceExtension, 0x2e);
+	XGISetModeNew(xgifb_info, HwDeviceExtension, 0x2e);
 
 	data = xgifb_reg_get(pVBInfo->P3c4, 0x21);
 	/* disable read cache */
 	xgifb_reg_set(pVBInfo->P3c4, 0x21, (unsigned short) (data & 0xDF));
-	XGI_DisplayOff(HwDeviceExtension, pVBInfo);
+	XGI_DisplayOff(xgifb_info, HwDeviceExtension, pVBInfo);
 
 	/* data = xgifb_reg_get(pVBInfo->P3c4, 0x1); */
 	/* data |= 0x20 ; */
@@ -1092,118 +1094,100 @@
 	xgifb_reg_set(pVBInfo->P3c4, 0x21, (unsigned short) (data | 0x20));
 }
 
-static void ReadVBIOSTablData(unsigned char ChipType,
+static u8 *xgifb_copy_rom(struct pci_dev *dev, size_t *rom_size)
+{
+	void __iomem *rom_address;
+	u8 *rom_copy;
+
+	rom_address = pci_map_rom(dev, rom_size);
+	if (rom_address == NULL)
+		return NULL;
+
+	rom_copy = vzalloc(XGIFB_ROM_SIZE);
+	if (rom_copy == NULL)
+		goto done;
+
+	*rom_size = min_t(size_t, *rom_size, XGIFB_ROM_SIZE);
+	memcpy_fromio(rom_copy, rom_address, *rom_size);
+
+done:
+	pci_unmap_rom(dev, rom_address);
+	return rom_copy;
+}
+
+static void xgifb_read_vbios(struct pci_dev *pdev,
 			      struct vb_device_info *pVBInfo)
 {
-	volatile unsigned char *pVideoMemory =
-		(unsigned char *) pVBInfo->ROMAddr;
+	struct xgifb_video_info *xgifb_info = pci_get_drvdata(pdev);
+	u8 *vbios;
 	unsigned long i;
-	unsigned char j, k;
-	/* Volari customize data area end */
+	unsigned char j;
+	struct XGI21_LVDSCapStruct *lvds;
+	size_t vbios_size;
+	int entry;
 
-	if (ChipType == XG21) {
-		pVBInfo->IF_DEF_LVDS = 0;
-		if (pVideoMemory[0x65] & 0x1) {
-			pVBInfo->IF_DEF_LVDS = 1;
-			i = pVideoMemory[0x316] | (pVideoMemory[0x317] << 8);
-			j = pVideoMemory[i - 1];
-			if (j != 0xff) {
-				k = 0;
-				do {
-					pVBInfo->XG21_LVDSCapList[k].
-						 LVDS_Capability
-						= pVideoMemory[i] |
-						 (pVideoMemory[i + 1] << 8);
-					pVBInfo->XG21_LVDSCapList[k].LVDSHT
-						= pVideoMemory[i + 2] |
-						  (pVideoMemory[i + 3] << 8);
-					pVBInfo->XG21_LVDSCapList[k].LVDSVT
-						= pVideoMemory[i + 4] |
-						  (pVideoMemory[i + 5] << 8);
-					pVBInfo->XG21_LVDSCapList[k].LVDSHDE
-						= pVideoMemory[i + 6] |
-						  (pVideoMemory[i + 7] << 8);
-					pVBInfo->XG21_LVDSCapList[k].LVDSVDE
-						= pVideoMemory[i + 8] |
-						  (pVideoMemory[i + 9] << 8);
-					pVBInfo->XG21_LVDSCapList[k].LVDSHFP
-						= pVideoMemory[i + 10] |
-						  (pVideoMemory[i + 11] << 8);
-					pVBInfo->XG21_LVDSCapList[k].LVDSVFP
-						= pVideoMemory[i + 12] |
-						  (pVideoMemory[i + 13] << 8);
-					pVBInfo->XG21_LVDSCapList[k].LVDSHSYNC
-						= pVideoMemory[i + 14] |
-						  (pVideoMemory[i + 15] << 8);
-					pVBInfo->XG21_LVDSCapList[k].LVDSVSYNC
-						= pVideoMemory[i + 16] |
-						  (pVideoMemory[i + 17] << 8);
-					pVBInfo->XG21_LVDSCapList[k].VCLKData1
-						= pVideoMemory[i + 18];
-					pVBInfo->XG21_LVDSCapList[k].VCLKData2
-						= pVideoMemory[i + 19];
-					pVBInfo->XG21_LVDSCapList[k].PSC_S1
-						= pVideoMemory[i + 20];
-					pVBInfo->XG21_LVDSCapList[k].PSC_S2
-						= pVideoMemory[i + 21];
-					pVBInfo->XG21_LVDSCapList[k].PSC_S3
-						= pVideoMemory[i + 22];
-					pVBInfo->XG21_LVDSCapList[k].PSC_S4
-						= pVideoMemory[i + 23];
-					pVBInfo->XG21_LVDSCapList[k].PSC_S5
-						= pVideoMemory[i + 24];
-					i += 25;
-					j--;
-					k++;
-				} while ((j > 0) &&
-					 (k < (sizeof(XGI21_LCDCapList) /
-					       sizeof(struct
-							XGI21_LVDSCapStruct))));
-			} else {
-				pVBInfo->XG21_LVDSCapList[0].LVDS_Capability
-						= pVideoMemory[i] |
-						  (pVideoMemory[i + 1] << 8);
-				pVBInfo->XG21_LVDSCapList[0].LVDSHT
-						= pVideoMemory[i + 2] |
-						  (pVideoMemory[i + 3] << 8);
-				pVBInfo->XG21_LVDSCapList[0].LVDSVT
-						= pVideoMemory[i + 4] |
-						  (pVideoMemory[i + 5] << 8);
-				pVBInfo->XG21_LVDSCapList[0].LVDSHDE
-						= pVideoMemory[i + 6] |
-						  (pVideoMemory[i + 7] << 8);
-				pVBInfo->XG21_LVDSCapList[0].LVDSVDE
-						= pVideoMemory[i + 8] |
-						  (pVideoMemory[i + 9] << 8);
-				pVBInfo->XG21_LVDSCapList[0].LVDSHFP
-						= pVideoMemory[i + 10] |
-						  (pVideoMemory[i + 11] << 8);
-				pVBInfo->XG21_LVDSCapList[0].LVDSVFP
-						= pVideoMemory[i + 12] |
-						  (pVideoMemory[i + 13] << 8);
-				pVBInfo->XG21_LVDSCapList[0].LVDSHSYNC
-						= pVideoMemory[i + 14] |
-						  (pVideoMemory[i + 15] << 8);
-				pVBInfo->XG21_LVDSCapList[0].LVDSVSYNC
-						= pVideoMemory[i + 16] |
-						  (pVideoMemory[i + 17] << 8);
-				pVBInfo->XG21_LVDSCapList[0].VCLKData1
-						= pVideoMemory[i + 18];
-				pVBInfo->XG21_LVDSCapList[0].VCLKData2
-						= pVideoMemory[i + 19];
-				pVBInfo->XG21_LVDSCapList[0].PSC_S1
-						= pVideoMemory[i + 20];
-				pVBInfo->XG21_LVDSCapList[0].PSC_S2
-						= pVideoMemory[i + 21];
-				pVBInfo->XG21_LVDSCapList[0].PSC_S3
-						= pVideoMemory[i + 22];
-				pVBInfo->XG21_LVDSCapList[0].PSC_S4
-						= pVideoMemory[i + 23];
-				pVBInfo->XG21_LVDSCapList[0].PSC_S5
-						= pVideoMemory[i + 24];
-			}
-		}
+	if (xgifb_info->chip != XG21)
+		return;
+	pVBInfo->IF_DEF_LVDS = 0;
+	vbios = xgifb_copy_rom(pdev, &vbios_size);
+	if (vbios == NULL) {
+		dev_err(&pdev->dev, "video BIOS not available\n");
+		return;
 	}
+	if (vbios_size <= 0x65)
+		goto error;
+	/*
+	 * The user can ignore the LVDS bit in the BIOS and force the display
+	 * type.
+	 */
+	if (!(vbios[0x65] & 0x1) &&
+	    (!xgifb_info->display2_force ||
+	     xgifb_info->display2 != XGIFB_DISP_LCD)) {
+		vfree(vbios);
+		return;
+	}
+	if (vbios_size <= 0x317)
+		goto error;
+	i = vbios[0x316] | (vbios[0x317] << 8);
+	if (vbios_size <= i - 1)
+		goto error;
+	j = vbios[i - 1];
+	if (j == 0)
+		goto error;
+	if (j == 0xff)
+		j = 1;
+	/*
+	 * Read the LVDS table index scratch register set by the BIOS.
+	 */
+	entry = xgifb_reg_get(xgifb_info->dev_info.P3d4, 0x36);
+	if (entry >= j)
+		entry = 0;
+	i += entry * 25;
+	lvds = &xgifb_info->lvds_data;
+	if (vbios_size <= i + 24)
+		goto error;
+	lvds->LVDS_Capability	= vbios[i]	| (vbios[i + 1] << 8);
+	lvds->LVDSHT		= vbios[i + 2]	| (vbios[i + 3] << 8);
+	lvds->LVDSVT		= vbios[i + 4]	| (vbios[i + 5] << 8);
+	lvds->LVDSHDE		= vbios[i + 6]	| (vbios[i + 7] << 8);
+	lvds->LVDSVDE		= vbios[i + 8]	| (vbios[i + 9] << 8);
+	lvds->LVDSHFP		= vbios[i + 10]	| (vbios[i + 11] << 8);
+	lvds->LVDSVFP		= vbios[i + 12]	| (vbios[i + 13] << 8);
+	lvds->LVDSHSYNC		= vbios[i + 14]	| (vbios[i + 15] << 8);
+	lvds->LVDSVSYNC		= vbios[i + 16]	| (vbios[i + 17] << 8);
+	lvds->VCLKData1		= vbios[i + 18];
+	lvds->VCLKData2		= vbios[i + 19];
+	lvds->PSC_S1		= vbios[i + 20];
+	lvds->PSC_S2		= vbios[i + 21];
+	lvds->PSC_S3		= vbios[i + 22];
+	lvds->PSC_S4		= vbios[i + 23];
+	lvds->PSC_S5		= vbios[i + 24];
+	vfree(vbios);
+	pVBInfo->IF_DEF_LVDS = 1;
+	return;
+error:
+	dev_err(&pdev->dev, "video BIOS corrupted\n");
+	vfree(vbios);
 }
 
 static void XGINew_ChkSenseStatus(struct xgi_hw_device_info *HwDeviceExtension,
@@ -1336,18 +1320,57 @@
 
 }
 
+static unsigned short XGINew_SenseLCD(struct xgi_hw_device_info
+							*HwDeviceExtension,
+				      struct vb_device_info *pVBInfo)
+{
+	unsigned short temp;
+
+	/* add lcd sense */
+	if (HwDeviceExtension->ulCRT2LCDType == LCD_UNKNOWN) {
+		return 0;
+	} else {
+		temp = (unsigned short) HwDeviceExtension->ulCRT2LCDType;
+		switch (HwDeviceExtension->ulCRT2LCDType) {
+		case LCD_INVALID:
+		case LCD_800x600:
+		case LCD_1024x768:
+		case LCD_1280x1024:
+			break;
+
+		case LCD_640x480:
+		case LCD_1024x600:
+		case LCD_1152x864:
+		case LCD_1280x960:
+		case LCD_1152x768:
+			temp = 0;
+			break;
+
+		case LCD_1400x1050:
+		case LCD_1280x768:
+		case LCD_1600x1200:
+			break;
+
+		case LCD_1920x1440:
+		case LCD_2048x1536:
+			temp = 0;
+			break;
+
+		default:
+			break;
+		}
+		xgifb_reg_and_or(pVBInfo->P3d4, 0x36, 0xF0, temp);
+		return 1;
+	}
+}
+
 static void XGINew_GetXG21Sense(struct xgi_hw_device_info *HwDeviceExtension,
 		struct vb_device_info *pVBInfo)
 {
 	unsigned char Temp;
-	volatile unsigned char *pVideoMemory =
-			(unsigned char *) pVBInfo->ROMAddr;
-
-	pVBInfo->IF_DEF_LVDS = 0;
 
 #if 1
-	if ((pVideoMemory[0x65] & 0x01)) { /* For XG21 LVDS */
-		pVBInfo->IF_DEF_LVDS = 1;
+	if (pVBInfo->IF_DEF_LVDS) { /* For XG21 LVDS */
 		xgifb_reg_or(pVBInfo->P3d4, 0x32, LCDSense);
 		/* LVDS on chip */
 		xgifb_reg_and_or(pVBInfo->P3d4, 0x38, ~0xE0, 0xC0);
@@ -1393,7 +1416,6 @@
 	xgifb_reg_set(pVBInfo->P3d4, 0x4A, bCR4A);
 
 	if (Temp <= 0x02) {
-		pVBInfo->IF_DEF_LVDS = 1;
 		/* LVDS setting */
 		xgifb_reg_and_or(pVBInfo->P3d4, 0x38, ~0xE0, 0xC0);
 		xgifb_reg_set(pVBInfo->P3d4, 0x30, 0x21);
@@ -1451,24 +1473,15 @@
 	struct vb_device_info *pVBInfo = &VBINF;
 	unsigned char i, temp = 0, temp1;
 	/* VBIOSVersion[5]; */
-	volatile unsigned char *pVideoMemory;
 
 	/* unsigned long j, k; */
 
-	pVBInfo->ROMAddr = HwDeviceExtension->pjVirtualRomBase;
-
 	pVBInfo->FBAddr = HwDeviceExtension->pjVideoMemoryAddress;
 
 	pVBInfo->BaseAddr = (unsigned long) HwDeviceExtension->pjIOAddress;
 
-	pVideoMemory = (unsigned char *) pVBInfo->ROMAddr;
-
 	/* Newdebugcode(0x99); */
 
-
-	/* if (pVBInfo->ROMAddr == 0) */
-	/* return(0); */
-
 	if (pVBInfo->FBAddr == NULL) {
 		printk("\n pVBInfo->FBAddr == 0 ");
 		return 0;
@@ -1516,8 +1529,7 @@
 
 	InitTo330Pointer(HwDeviceExtension->jChipType, pVBInfo);
 
-	/* ReadVBIOSData */
-	ReadVBIOSTablData(HwDeviceExtension->jChipType, pVBInfo);
+	xgifb_read_vbios(pdev, pVBInfo);
 
 	/* 1.Openkey */
 	xgifb_reg_set(pVBInfo->P3c4, 0x05, 0x86);
@@ -1774,7 +1786,7 @@
 					 pVBInfo);
 
 	printk("20");
-	XGINew_SetDRAMSize_340(HwDeviceExtension, pVBInfo);
+	XGINew_SetDRAMSize_340(xgifb_info, HwDeviceExtension, pVBInfo);
 	printk("21");
 
 	printk("22");
diff --git a/drivers/staging/xgifb/vb_setmode.c b/drivers/staging/xgifb/vb_setmode.c
index 81c0cc4..67a316c 100644
--- a/drivers/staging/xgifb/vb_setmode.c
+++ b/drivers/staging/xgifb/vb_setmode.c
@@ -67,11 +67,6 @@
 	pVBInfo->XGINEWUB_CRT1Table
 			= (struct XGI_CRT1TableStruct *) XGI_CRT1Table;
 
-	/* add for new UNIVGABIOS */
-	/* XGINew_UBLCDDataTable =
-	 *	(struct XGI_LCDDataTablStruct *) XGI_LCDDataTable; */
-	/* XGINew_UBTVDataTable = (XGI_TVDataTablStruct *) XGI_TVDataTable; */
-
 	pVBInfo->MCLKData = (struct XGI_MCLKDataStruct *) XGI340New_MCLKData;
 	pVBInfo->ECLKData = (struct XGI_ECLKDataStruct *) XGI340_ECLKData;
 	pVBInfo->VCLKData = (struct XGI_VCLKDataStruct *) XGI_VCLKData;
@@ -148,9 +143,6 @@
 	else
 		pVBInfo->LCDCapList = XGI_LCDCapList;
 
-	if ((ChipType == XG21) || (ChipType == XG27))
-		pVBInfo->XG21_LVDSCapList = XGI21_LCDCapList;
-
 	pVBInfo->XGI_TVDelayList = XGI301TVDelayList;
 	pVBInfo->XGI_TVDelayList2 = XGI301TVDelayList2;
 
@@ -236,28 +228,6 @@
 	}
 }
 
-static void XGI_SetMiscRegs(unsigned short StandTableIndex,
-			    struct vb_device_info *pVBInfo)
-{
-	unsigned char Miscdata;
-
-	/* Get Misc from file */
-	Miscdata = pVBInfo->StandTable[StandTableIndex].MISC;
-	/*
-	if (pVBInfo->VBType & (VB_XGI301B |
-			       VB_XGI302B |
-			       VB_XGI301LV |
-			       VB_XGI302LV |
-			       VB_XGI301C)) {
-		if (pVBInfo->VBInfo & SetCRT2ToLCDA) {
-			Miscdata |= 0x0C;
-		}
-	}
-	*/
-
-	outb(Miscdata, pVBInfo->P3c2); /* Set Misc(3c2) */
-}
-
 static void XGI_SetCRTCRegs(struct xgi_hw_device_info *HwDeviceExtension,
 			    unsigned short StandTableIndex,
 			    struct vb_device_info *pVBInfo)
@@ -274,16 +244,6 @@
 		CRTCdata = pVBInfo->StandTable[StandTableIndex].CRTC[i];
 		xgifb_reg_set(pVBInfo->P3d4, i, CRTCdata); /* Set CRTC(3d4) */
 	}
-	/*
-	if ((HwDeviceExtension->jChipType == XGI_630) &&
-	    (HwDeviceExtension->jChipRevision == 0x30)) {
-		if (pVBInfo->VBInfo & SetInSlaveMode) {
-			if (pVBInfo->VBInfo & (SetCRT2ToLCD | SetCRT2ToTV)) {
-				xgifb_reg_set(pVBInfo->P3d4, 0x18, 0xFE);
-			}
-		}
-	}
-	*/
 }
 
 static void XGI_SetATTRegs(unsigned short ModeNo,
@@ -530,10 +490,6 @@
 	unsigned char data, data1, pushax;
 	unsigned short i, j;
 
-	/* xgifb_reg_set(pVBInfo->P3d4, 0x51, 0); */
-	/* xgifb_reg_set(pVBInfo->P3d4, 0x56, 0); */
-	/* xgifb_reg_and_or(pVBInfo->P3d4, 0x11, 0x7f, 0x00); */
-
 	/* unlock cr0-7 */
 	data = (unsigned char) xgifb_reg_get(pVBInfo->P3d4, 0x11);
 	data &= 0x7F;
@@ -595,10 +551,6 @@
 	unsigned char data;
 	unsigned short i, j;
 
-	/* xgifb_reg_set(pVBInfo->P3d4, 0x51, 0); */
-	/* xgifb_reg_set(pVBInfo->P3d4, 0x56, 0); */
-	/* xgifb_reg_and_or(pVBInfo->P3d4, 0x11, 0x7f, 0x00); */
-
 	for (i = 0x00; i <= 0x01; i++) {
 		data = pVBInfo->TimingV[0].data[i];
 		xgifb_reg_set(pVBInfo->P3d4, (unsigned short) (i + 6), data);
@@ -976,6 +928,20 @@
 	}
 }
 
+static void XGI_SetXG27FPBits(struct vb_device_info *pVBInfo)
+{
+	unsigned char temp;
+
+	/* D[1:0] 01: 18bit, 00: dual 12, 10: single 24 */
+	temp = xgifb_reg_get(pVBInfo->P3d4, 0x37);
+	temp = (temp & 3) << 6;
+	/* SR06[7]0: dual 12/1: single 24 [6] 18bit Dither <= 0 h/w recommend */
+	xgifb_reg_and_or(pVBInfo->P3c4, 0x06, ~0xc0, temp & 0x80);
+	/* SR09[7] enable FP output, SR09[6] 1: sigle 18bits, 0: 24bits */
+	xgifb_reg_and_or(pVBInfo->P3c4, 0x09, ~0xc0, temp | 0x80);
+
+}
+
 static void xgifb_set_lcd(int chip_id,
 			  struct vb_device_info *pVBInfo,
 			  unsigned short RefreshRateTableIndex,
@@ -1088,6 +1054,20 @@
 	}
 }
 
+static unsigned short XGI_GetResInfo(unsigned short ModeNo,
+		unsigned short ModeIdIndex, struct vb_device_info *pVBInfo)
+{
+	unsigned short resindex;
+
+	if (ModeNo <= 0x13)
+		/* si+St_ResInfo */
+		resindex = pVBInfo->SModeIDTable[ModeIdIndex].St_ResInfo;
+	else
+		/* si+Ext_ResInfo */
+		resindex = pVBInfo->EModeIDTable[ModeIdIndex].Ext_RESINFO;
+	return resindex;
+}
+
 static void XGI_SetCRT1DE(struct xgi_hw_device_info *HwDeviceExtension,
 		unsigned short ModeNo, unsigned short ModeIdIndex,
 		unsigned short RefreshRateTableIndex,
@@ -1127,9 +1107,6 @@
 
 	tempcx = 8;
 
-	/* if (!(modeflag & Charx8Dot)) */
-	/* tempcx = 9; */
-
 	tempax /= tempcx;
 	tempax -= 1;
 	tempbx -= 1;
@@ -1163,20 +1140,6 @@
 	xgifb_reg_set(pVBInfo->P3d4, 0x11, temp);
 }
 
-unsigned short XGI_GetResInfo(unsigned short ModeNo,
-		unsigned short ModeIdIndex, struct vb_device_info *pVBInfo)
-{
-	unsigned short resindex;
-
-	if (ModeNo <= 0x13)
-		/* si+St_ResInfo */
-		resindex = pVBInfo->SModeIDTable[ModeIdIndex].St_ResInfo;
-	else
-		/* si+Ext_ResInfo */
-		resindex = pVBInfo->EModeIDTable[ModeIdIndex].Ext_RESINFO;
-	return resindex;
-}
-
 static void XGI_SetCRT1Offset(unsigned short ModeNo,
 			      unsigned short ModeIdIndex,
 			      unsigned short RefreshRateTableIndex,
@@ -1308,77 +1271,55 @@
 				VCLKIndex = LCDXlat2VCLK[CRT2Index];
 			else
 				VCLKIndex = LCDXlat1VCLK[CRT2Index];
-		} else { /* for TV */
-			if (pVBInfo->VBInfo & SetCRT2ToTV) {
-				if (pVBInfo->VBInfo & SetCRT2ToHiVisionTV) {
-					if (pVBInfo->SetFlag & RPLLDIV2XO) {
-						VCLKIndex = HiTVVCLKDIV2;
-						VCLKIndex += 25;
-					} else {
-						VCLKIndex = HiTVVCLK;
-						VCLKIndex += 25;
-					}
+		} else if (pVBInfo->VBInfo & SetCRT2ToHiVisionTV) {
+			if (pVBInfo->SetFlag & RPLLDIV2XO) {
+				VCLKIndex = HiTVVCLKDIV2;
+				VCLKIndex += 25;
+			} else {
+				VCLKIndex = HiTVVCLK;
+				VCLKIndex += 25;
+			}
 
-					if (pVBInfo->SetFlag & TVSimuMode) {
-						if (modeflag & Charx8Dot) {
-							VCLKIndex =
-								HiTVSimuVCLK;
-							VCLKIndex += 25;
-						} else {
-							VCLKIndex =
-								HiTVTextVCLK;
-							VCLKIndex += 25;
-						}
-					}
-
-					/* 301lv */
-					if (pVBInfo->VBType & VB_XGI301LV) {
-						if (!(pVBInfo->VBExtInfo ==
-						     VB_YPbPr1080i)) {
-							VCLKIndex =
-								YPbPr750pVCLK;
-							if (!(pVBInfo->VBExtInfo
-									==
-							     VB_YPbPr750p)) {
-								VCLKIndex =
-								  YPbPr525pVCLK;
-								if (!(pVBInfo->VBExtInfo
-										== VB_YPbPr525p)) {
-									VCLKIndex
-											= YPbPr525iVCLK_2;
-									if (!(pVBInfo->SetFlag
-											& RPLLDIV2XO))
-										VCLKIndex
-												= YPbPr525iVCLK;
-								}
-							}
-						}
-					}
+			if (pVBInfo->SetFlag & TVSimuMode) {
+				if (modeflag & Charx8Dot) {
+					VCLKIndex = HiTVSimuVCLK;
+					VCLKIndex += 25;
 				} else {
-					if (pVBInfo->VBInfo & SetCRT2ToTV) {
-						if (pVBInfo->SetFlag &
-						    RPLLDIV2XO) {
-							VCLKIndex = TVVCLKDIV2;
-							VCLKIndex += 25;
-						} else {
-							VCLKIndex = TVVCLK;
-							VCLKIndex += 25;
-						}
-					}
+					VCLKIndex = HiTVTextVCLK;
+					VCLKIndex += 25;
 				}
-			} else { /* for CRT2 */
-				/* Port 3cch */
-				VCLKIndex = (unsigned char) inb(
-						(pVBInfo->P3ca + 0x02));
-				VCLKIndex = ((VCLKIndex >> 2) & 0x03);
-				if (ModeNo > 0x13) {
-					/* di+Ext_CRTVCLK */
-					VCLKIndex =
-						pVBInfo->RefIndex[
+			}
+
+			/* 301lv */
+			if ((pVBInfo->VBType & VB_XGI301LV) &&
+			    !(pVBInfo->VBExtInfo == VB_YPbPr1080i)) {
+				if (pVBInfo->VBExtInfo == VB_YPbPr750p)
+					VCLKIndex = YPbPr750pVCLK;
+				else if (pVBInfo->VBExtInfo == VB_YPbPr525p)
+					VCLKIndex = YPbPr525pVCLK;
+				else if (pVBInfo->SetFlag & RPLLDIV2XO)
+					VCLKIndex = YPbPr525iVCLK_2;
+				else
+					VCLKIndex = YPbPr525iVCLK;
+			}
+		} else if (pVBInfo->VBInfo & SetCRT2ToTV) {
+			if (pVBInfo->SetFlag & RPLLDIV2XO) {
+				VCLKIndex = TVVCLKDIV2;
+				VCLKIndex += 25;
+			} else {
+				VCLKIndex = TVVCLK;
+				VCLKIndex += 25;
+			}
+		} else { /* for CRT2 */
+			/* Port 3cch */
+			VCLKIndex = (unsigned char) inb((pVBInfo->P3ca + 0x02));
+			VCLKIndex = ((VCLKIndex >> 2) & 0x03);
+			if (ModeNo > 0x13) {
+				/* di+Ext_CRTVCLK */
+				VCLKIndex = pVBInfo->RefIndex[
 							RefreshRateTableIndex].
 								Ext_CRTVCLK;
-					VCLKIndex &= IndexMask;
-				}
+				VCLKIndex &= IndexMask;
 			}
 		}
 	} else { /* LVDS */
@@ -1397,7 +1338,6 @@
 		else
 			VCLKIndex = LVDSXlat3VCLK[VCLKIndex];
 	}
-	/* VCLKIndex = VCLKIndex&IndexMask; */
 
 	return VCLKIndex;
 }
@@ -1461,6 +1401,19 @@
 	}
 }
 
+static void XGI_SetXG21FPBits(struct vb_device_info *pVBInfo)
+{
+	unsigned char temp;
+
+	temp = xgifb_reg_get(pVBInfo->P3d4, 0x37); /* D[0] 1: 18bit */
+	temp = (temp & 1) << 6;
+	/* SR06[6] 18bit Dither */
+	xgifb_reg_and_or(pVBInfo->P3c4, 0x06, ~0x40, temp);
+	/* SR09[7] enable FP output, SR09[6] 1: sigle 18bits, 0: dual 12bits */
+	xgifb_reg_and_or(pVBInfo->P3c4, 0x09, ~0xc0, temp | 0x80);
+
+}
+
 static void XGI_SetCRT1FIFO(unsigned short ModeNo,
 		struct xgi_hw_device_info *HwDeviceExtension,
 		struct vb_device_info *pVBInfo)
@@ -1532,16 +1485,6 @@
 		xgifb_reg_set(pVBInfo->P3c4, 0x1F, data);
 	}
 
-	/*  Jong for Adavantech LCD ripple issue
-	if ((VCLK >= 0) && (VCLK < 135))
-		data2 = 0x03;
-	else if ((VCLK >= 135) && (VCLK < 160))
-		data2 = 0x02;
-	else if ((VCLK >= 160) && (VCLK < 260))
-		data2 = 0x01;
-	else if (VCLK > 260)
-		data2 = 0x00;
-	*/
 	data2 = 0x00;
 
 	xgifb_reg_and_or(pVBInfo->P3c4, 0x07, 0xFC, data2);
@@ -1591,7 +1534,6 @@
 		data2 |= 0x20;
 
 	xgifb_reg_and_or(pVBInfo->P3c4, 0x06, ~0x3F, data2);
-	/* xgifb_reg_set(pVBInfo->P3c4,0x06,data2); */
 	resindex = XGI_GetResInfo(ModeNo, ModeIdIndex, pVBInfo);
 	if (ModeNo <= 0x13)
 		xres = pVBInfo->StResInfo[resindex].HTotal;
@@ -1636,11 +1578,6 @@
 	XGI_SetVCLKState(HwDeviceExtension, ModeNo, RefreshRateTableIndex,
 			pVBInfo);
 
-	/* if (modeflag&HalfDCLK) //030305 fix lowresolution bug */
-	/* if (XGINew_IF_DEF_NEW_LOWRES) */
-	/* XGI_VesaLowResolution(ModeNo, ModeIdIndex);
-	 * //030305 fix lowresolution bug */
-
 	data = xgifb_reg_get(pVBInfo->P3d4, 0x31);
 
 	if (HwDeviceExtension->jChipType == XG27) {
@@ -1803,11 +1740,6 @@
 		/* si+Ext_ResInfo */
 		modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_RESINFO;
 
-	/* if (ModeNo > 0x13) */
-	/*	modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag; */
-	/* else */
-	/*	modeflag = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag; */
-
 	if (ModeNo <= 0x13)
 		/* si+St_ResInfo */
 		resindex = pVBInfo->SModeIDTable[ModeIdIndex].St_ResInfo;
@@ -1815,8 +1747,6 @@
 		/* si+Ext_ResInfo */
 		resindex = pVBInfo->EModeIDTable[ModeIdIndex].Ext_RESINFO;
 
-	/* resindex = XGI_GetResInfo(ModeNo, ModeIdIndex, pVBInfo); */
-
 	if (ModeNo <= 0x13) {
 		xres = pVBInfo->StResInfo[resindex].HTotal;
 		yres = pVBInfo->StResInfo[resindex].VTotal;
@@ -1831,13 +1761,10 @@
 		if (modeflag & DoubleScanMode)
 			yres = yres << 1;
 	}
-	/* if (modeflag & Charx8Dot) */
-	/* { */
 
 	if (xres == 720)
 		xres = 640;
 
-	/* } */
 	pVBInfo->VGAHDE = xres;
 	pVBInfo->HDE = xres;
 	pVBInfo->VGAVDE = yres;
@@ -1890,7 +1817,7 @@
 		tempal = (tempal & 0x0f);
 	}
 
-	tempcx = LCDLenList[tempbx]; /* mov cl,byte ptr cs:LCDLenList[bx] */
+	tempcx = LCDLenList[tempbx];
 
 	if (pVBInfo->LCDInfo & EnableScalingLCD) { /* ScaleLCD */
 		if ((tempbx == 5) || (tempbx) == 7)
@@ -1898,9 +1825,6 @@
 		else if ((tempbx == 3) || (tempbx == 8))
 			tempcx = LVDSDesDataLen2;
 	}
-	/* mov di, word ptr cs:LCDDataList[bx] */
-	/* tempdi = pVideoMemory[LCDDataList + tempbx * 2] |
-		    (pVideoMemory[LCDDataList + tempbx * 2 + 1] << 8); */
 
 	switch (tempbx) {
 	case 0:
@@ -2321,10 +2245,10 @@
 
 	switch (tempbx) {
 	case 0:
-		tempdi = NULL; /*EPLCHTVCRT1Ptr_H;*/
+		tempdi = NULL;
 		break;
 	case 1:
-		tempdi = NULL; /*EPLCHTVCRT1Ptr_V;*/
+		tempdi = NULL;
 		break;
 	case 2:
 	case 6:
@@ -2363,9 +2287,7 @@
 	}
 
 	/* 07/05/22 */
-	if (table == 0x00) {
-	} else if (table == 0x01) {
-	} else if (table == 0x04) {
+	if (table == 0x04) {
 		switch (tempdi[i].DATAPTR) {
 		case 0:
 			return &XGI_ExtPALData[tempal];
@@ -2429,7 +2351,6 @@
 		default:
 			break;
 		}
-	} else if (table == 0x06) {
 	}
 	return NULL;
 }
@@ -2741,7 +2662,6 @@
 	else
 		tempbx = LCDPtr->LCDVRS;
 
-	/* tempbx = tempbx >> 4; */
 	tempcx = push1;
 
 	if (pVBInfo->LCDInfo & EnableScalingLCD)
@@ -2881,7 +2801,6 @@
 	unsigned short index;
 
 	if (pVBInfo->VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
-		/* index = XGI_GetLCDCapPtr(pVBInfo); */
 		index = XGI_GetLCDCapPtr1(pVBInfo);
 
 		if (pVBInfo->VBInfo & SetCRT2ToLCD) { /* LCDB */
@@ -3105,19 +3024,6 @@
 	}
 }
 
-void XGI_GetVGAType(struct xgi_hw_device_info *HwDeviceExtension,
-		struct vb_device_info *pVBInfo)
-{
-	/*
-	if ( HwDeviceExtension->jChipType >= XG20 ) {
-		pVBInfo->Set_VGAType = XG20;
-	} else {
-		pVBInfo->Set_VGAType = VGA_XGI340;
-	}
-	*/
-	pVBInfo->Set_VGAType = HwDeviceExtension->jChipType;
-}
-
 void XGI_GetVBType(struct vb_device_info *pVBInfo)
 {
 	unsigned short flag, tempbx, tempah;
@@ -3160,7 +3066,7 @@
 	}
 }
 
-void XGI_GetVBInfo(unsigned short ModeNo, unsigned short ModeIdIndex,
+static void XGI_GetVBInfo(unsigned short ModeNo, unsigned short ModeIdIndex,
 		struct xgi_hw_device_info *HwDeviceExtension,
 		struct vb_device_info *pVBInfo)
 {
@@ -3193,14 +3099,9 @@
 
 		if (pVBInfo->IF_DEF_LCDA == 1) {
 
-			if ((pVBInfo->Set_VGAType >= XG20)
-					|| (pVBInfo->Set_VGAType >= XG40)) {
+			if ((HwDeviceExtension->jChipType >= XG20) ||
+			    (HwDeviceExtension->jChipType >= XG40)) {
 				if (pVBInfo->IF_DEF_LVDS == 0) {
-					/* if ((pVBInfo->VBType & VB_XGI302B)
-					    || (pVBInfo->VBType & VB_XGI301LV)
-					    || (pVBInfo->VBType & VB_XGI302LV)
-					    || (pVBInfo->VBType & VB_XGI301C))
-					*/
 					if (pVBInfo->VBType &
 					    (VB_XGI302B |
 					     VB_XGI301LV |
@@ -3225,7 +3126,7 @@
 			    ((pVBInfo->VBType & VB_XGI301LV) ||
 			    (pVBInfo->VBType & VB_XGI302LV) ||
 			    (pVBInfo->VBType & VB_XGI301C)))) {
-				if (temp & SetYPbPr) { /* temp = CR38 */
+				if (temp & SetYPbPr) {
 					if (pVBInfo->IF_DEF_HiVision == 1) {
 						/* shampoo add for new
 						 * scratch */
@@ -3242,8 +3143,6 @@
 							 SetCRT2ToYPbPr;
 						}
 					}
-
-					/* tempbx |= SetCRT2ToYPbPr; */
 				}
 			}
 		}
@@ -3368,7 +3267,7 @@
 	pVBInfo->VBInfo = tempbx;
 }
 
-void XGI_GetTVInfo(unsigned short ModeNo, unsigned short ModeIdIndex,
+static void XGI_GetTVInfo(unsigned short ModeNo, unsigned short ModeIdIndex,
 		struct vb_device_info *pVBInfo)
 {
 	unsigned short temp, tempbx = 0, resinfo = 0, modeflag, index1;
@@ -3404,17 +3303,6 @@
 				tempbx &= (SetCHTVOverScan |
 					   SetNTSCJ |
 					   SetPALTV);
-			/*
-			if (pVBInfo->IF_DEF_LVDS == 0) {
-				//PAL-M/PAL-N Info
-				index1 = xgifb_reg_get(pVBInfo->P3d4, 0x38);
-				//00:PAL, 01:PAL-M, 10:PAL-N
-				temp2 = (index1 & 0xC0) >> 5;
-				tempbx |= temp2;
-				if (temp2 & 0x02) //PAL-M
-					tempbx &= (~SetPALTV);
-			}
-			*/
 		}
 
 		if (pVBInfo->IF_DEF_LVDS == 0) {
@@ -3476,8 +3364,8 @@
 	pVBInfo->TVInfo = tempbx;
 }
 
-unsigned char XGI_GetLCDInfo(unsigned short ModeNo, unsigned short ModeIdIndex,
-		struct vb_device_info *pVBInfo)
+static unsigned char XGI_GetLCDInfo(unsigned short ModeNo,
+		unsigned short ModeIdIndex, struct vb_device_info *pVBInfo)
 {
 	unsigned short temp, tempax, tempbx, modeflag, resinfo = 0, LCDIdIndex;
 
@@ -3553,15 +3441,8 @@
 			tempbx |= SetLCDtoNonExpanding;
 	}
 
-	/*
-	if (tempax & LCDBToA) {
-		tempbx |= SetLCDBToA;
-	}
-	*/
-
 	if (pVBInfo->IF_DEF_ExpLink == 1) {
 		if (modeflag & HalfDCLK) {
-			/* if (!(pVBInfo->LCDInfo&LCDNonExpanding)) */
 			if (!(tempbx & SetLCDtoNonExpanding)) {
 				tempbx |= EnableLVDSDDA;
 			} else {
@@ -3604,25 +3485,6 @@
 		}
 	}
 
-	/*
-	if (pVBInfo->IF_DEF_LVDS == 0) {
-		if (tempax & (LockLCDBToA | StLCDBToA)) {
-			if (pVBInfo->VBInfo & SetInSlaveMode) {
-				if (!((!(tempax & LockLCDBToA)) &&
-				    (ModeNo > 0x13))) {
-					pVBInfo->VBInfo &=
-						~(SetSimuScanMode |
-						  SetInSlaveMode |
-						  SetCRT2ToLCD);
-					pVBInfo->VBInfo |=
-						SetCRT2ToLCDA |
-						SetCRT2ToDualEdge;
-				}
-			}
-		}
-	}
-	*/
-
 	return 1;
 }
 
@@ -3632,10 +3494,6 @@
 	if (ModeNo <= 5)
 		ModeNo |= 1;
 	if (ModeNo <= 0x13) {
-		/* for (*ModeIdIndex=0;
-			*ModeIdIndex < sizeof(pVBInfo->SModeIDTable)
-				/ sizeof(struct XGI_StStruct);
-			(*ModeIdIndex)++) */
 		for (*ModeIdIndex = 0;; (*ModeIdIndex)++) {
 			if (pVBInfo->SModeIDTable[*ModeIdIndex].St_ModeID ==
 			    ModeNo)
@@ -3651,10 +3509,6 @@
 			(*ModeIdIndex) += 2; /* 400 lines */
 		/* else 350 lines */
 	} else {
-		/* for (*ModeIdIndex=0;
-			*ModeIdIndex < sizeof(pVBInfo->EModeIDTable)
-				/ sizeof(struct XGI_ExtStruct);
-			(*ModeIdIndex)++) */
 		for (*ModeIdIndex = 0;; (*ModeIdIndex)++) {
 			if (pVBInfo->EModeIDTable[*ModeIdIndex].Ext_ModeID ==
 			    ModeNo)
@@ -3675,7 +3529,6 @@
 
 	for (i = 0; i < 8; i++) {
 		ujRet = ujRet << 1;
-		/* ujRet |= GETBITS(ujDate >> i, 0:0); */
 		ujRet |= (ujDate >> i) & 1;
 	}
 
@@ -3726,7 +3579,101 @@
 	return temp;
 }
 
-void XGI_DisplayOn(struct xgi_hw_device_info *pXGIHWDE,
+/*----------------------------------------------------------------------------*/
+/* input                                                                      */
+/*      bl[5] : 1;LVDS signal on                                              */
+/*      bl[1] : 1;LVDS backlight on                                           */
+/*      bl[0] : 1:LVDS VDD on                                                 */
+/*      bh: 100000b : clear bit 5, to set bit5                                */
+/*          000010b : clear bit 1, to set bit1                                */
+/*          000001b : clear bit 0, to set bit0                                */
+/*----------------------------------------------------------------------------*/
+static void XGI_XG21BLSignalVDD(unsigned short tempbh, unsigned short tempbl,
+		struct vb_device_info *pVBInfo)
+{
+	unsigned char CR4A, temp;
+
+	CR4A = xgifb_reg_get(pVBInfo->P3d4, 0x4A);
+	tempbh &= 0x23;
+	tempbl &= 0x23;
+	xgifb_reg_and(pVBInfo->P3d4, 0x4A, ~tempbh); /* enable GPIO write */
+
+	if (tempbh & 0x20) {
+		temp = (tempbl >> 4) & 0x02;
+
+		/* CR B4[1] */
+		xgifb_reg_and_or(pVBInfo->P3d4, 0xB4, ~0x02, temp);
+
+	}
+
+	temp = xgifb_reg_get(pVBInfo->P3d4, 0x48);
+
+	temp = XG21GPIODataTransfer(temp);
+	temp &= ~tempbh;
+	temp |= tempbl;
+	xgifb_reg_set(pVBInfo->P3d4, 0x48, temp);
+}
+
+static void XGI_XG27BLSignalVDD(unsigned short tempbh, unsigned short tempbl,
+		struct vb_device_info *pVBInfo)
+{
+	unsigned char CR4A, temp;
+	unsigned short tempbh0, tempbl0;
+
+	tempbh0 = tempbh;
+	tempbl0 = tempbl;
+	tempbh0 &= 0x20;
+	tempbl0 &= 0x20;
+	tempbh0 >>= 3;
+	tempbl0 >>= 3;
+
+	if (tempbh & 0x20) {
+		temp = (tempbl >> 4) & 0x02;
+
+		/* CR B4[1] */
+		xgifb_reg_and_or(pVBInfo->P3d4, 0xB4, ~0x02, temp);
+
+	}
+	xgifb_reg_and_or(pVBInfo->P3d4, 0xB4, ~tempbh0, tempbl0);
+
+	CR4A = xgifb_reg_get(pVBInfo->P3d4, 0x4A);
+	tempbh &= 0x03;
+	tempbl &= 0x03;
+	tempbh <<= 2;
+	tempbl <<= 2; /* GPIOC,GPIOD */
+	xgifb_reg_and(pVBInfo->P3d4, 0x4A, ~tempbh); /* enable GPIO write */
+	xgifb_reg_and_or(pVBInfo->P3d4, 0x48, ~tempbh, tempbl);
+}
+
+/* --------------------------------------------------------------------- */
+/* Function : XGI_XG21SetPanelDelay */
+/* Input : */
+/* Output : */
+/* Description : */
+/* I/P : bl : 1 ; T1 : the duration between CPL on and signal on */
+/* : bl : 2 ; T2 : the duration signal on and Vdd on */
+/* : bl : 3 ; T3 : the duration between CPL off and signal off */
+/* : bl : 4 ; T4 : the duration signal off and Vdd off */
+/* --------------------------------------------------------------------- */
+static void XGI_XG21SetPanelDelay(struct xgifb_video_info *xgifb_info,
+		unsigned short tempbl,
+		struct vb_device_info *pVBInfo)
+{
+	if (tempbl == 1)
+		mdelay(xgifb_info->lvds_data.PSC_S1);
+
+	if (tempbl == 2)
+		mdelay(xgifb_info->lvds_data.PSC_S2);
+
+	if (tempbl == 3)
+		mdelay(xgifb_info->lvds_data.PSC_S3);
+
+	if (tempbl == 4)
+		mdelay(xgifb_info->lvds_data.PSC_S4);
+}
+
+static void XGI_DisplayOn(struct xgifb_video_info *xgifb_info,
+		struct xgi_hw_device_info *pXGIHWDE,
 		struct vb_device_info *pVBInfo)
 {
 
@@ -3736,12 +3683,12 @@
 			if (!(XGI_XG21GetPSCValue(pVBInfo) & 0x1)) {
 				/* LVDS VDD on */
 				XGI_XG21BLSignalVDD(0x01, 0x01, pVBInfo);
-				XGI_XG21SetPanelDelay(2, pVBInfo);
+				XGI_XG21SetPanelDelay(xgifb_info, 2, pVBInfo);
 			}
 			if (!(XGI_XG21GetPSCValue(pVBInfo) & 0x20))
 				/* LVDS signal on */
 				XGI_XG21BLSignalVDD(0x20, 0x20, pVBInfo);
-			XGI_XG21SetPanelDelay(3, pVBInfo);
+			XGI_XG21SetPanelDelay(xgifb_info, 3, pVBInfo);
 			/* LVDS backlight on */
 			XGI_XG21BLSignalVDD(0x02, 0x02, pVBInfo);
 		} else {
@@ -3756,12 +3703,12 @@
 			if (!(XGI_XG27GetPSCValue(pVBInfo) & 0x1)) {
 				/* LVDS VDD on */
 				XGI_XG27BLSignalVDD(0x01, 0x01, pVBInfo);
-				XGI_XG21SetPanelDelay(2, pVBInfo);
+				XGI_XG21SetPanelDelay(xgifb_info, 2, pVBInfo);
 			}
 			if (!(XGI_XG27GetPSCValue(pVBInfo) & 0x20))
 				/* LVDS signal on */
 				XGI_XG27BLSignalVDD(0x20, 0x20, pVBInfo);
-			XGI_XG21SetPanelDelay(3, pVBInfo);
+			XGI_XG21SetPanelDelay(xgifb_info, 3, pVBInfo);
 			/* LVDS backlight on */
 			XGI_XG27BLSignalVDD(0x02, 0x02, pVBInfo);
 		} else {
@@ -3772,7 +3719,8 @@
 	}
 }
 
-void XGI_DisplayOff(struct xgi_hw_device_info *pXGIHWDE,
+void XGI_DisplayOff(struct xgifb_video_info *xgifb_info,
+		struct xgi_hw_device_info *pXGIHWDE,
 		struct vb_device_info *pVBInfo)
 {
 
@@ -3780,7 +3728,7 @@
 		if (pVBInfo->IF_DEF_LVDS == 1) {
 			/* LVDS backlight off */
 			XGI_XG21BLSignalVDD(0x02, 0x00, pVBInfo);
-			XGI_XG21SetPanelDelay(3, pVBInfo);
+			XGI_XG21SetPanelDelay(xgifb_info, 3, pVBInfo);
 		} else {
 			/* DVO/DVI signal off */
 			XGI_XG21BLSignalVDD(0x20, 0x00, pVBInfo);
@@ -3791,7 +3739,7 @@
 		if ((XGI_XG27GetPSCValue(pVBInfo) & 0x2)) {
 			/* LVDS backlight off */
 			XGI_XG27BLSignalVDD(0x02, 0x00, pVBInfo);
-			XGI_XG21SetPanelDelay(3, pVBInfo);
+			XGI_XG21SetPanelDelay(xgifb_info, 3, pVBInfo);
 		}
 
 		if (pVBInfo->IF_DEF_LVDS == 0)
@@ -3838,26 +3786,17 @@
 	if (ModeNo <= 0x13) {
 		xres = pVBInfo->StResInfo[resindex].HTotal;
 		yres = pVBInfo->StResInfo[resindex].VTotal;
-		/* si+St_ResInfo */
-		/* modeflag = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag;*/
 	} else {
 		xres = pVBInfo->ModeResInfo[resindex].HTotal; /* xres->ax */
 		yres = pVBInfo->ModeResInfo[resindex].VTotal; /* yres->bx */
 		/* si+St_ModeFlag */
 		modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag;
 
-		/*
-		if (pVBInfo->IF_DEF_FSTN) {
-			xres *= 2;
-			yres *= 2;
-		 } else {
-		*/
 		if (modeflag & HalfDCLK)
 			xres *= 2;
 
 		if (modeflag & DoubleScanMode)
 			yres *= 2;
-		/* } */
 	}
 
 	if (pVBInfo->VBInfo & SetCRT2ToLCD) {
@@ -4028,8 +3967,6 @@
 					tempbx = 775;
 				else if (pVBInfo->VGAVDE == 600)
 					tempbx = 775;
-				/* else if (pVBInfo->VGAVDE==350) tempbx=560; */
-				/* else if (pVBInfo->VGAVDE==400) tempbx=640; */
 				else
 					tempbx = 768;
 			} else
@@ -4294,7 +4231,6 @@
 	XGI_SetCRT2Offset(ModeNo, ModeIdIndex, RefreshRateTableIndex,
 			HwDeviceExtension, pVBInfo);
 	XGI_SetCRT2FIFO(pVBInfo);
-	/* XGI_SetCRT2Sync(ModeNo,RefreshRateTableIndex); */
 
 	for (tempcx = 4; tempcx < 7; tempcx++)
 		xgifb_reg_set(pVBInfo->Part1Port, tempcx, 0x0);
@@ -4497,9 +4433,6 @@
 
 	temp = 0xFF; /* set MAX HT */
 	xgifb_reg_set(pVBInfo->Part1Port, 0x03, temp);
-	/* if (modeflag & Charx8Dot) */
-	/*	tempcx = 0x08; */
-	/* else */
 	tempcx = 0x08;
 
 	if (pVBInfo->VBType & (VB_XGI301LV | VB_XGI302LV | VB_XGI301C))
@@ -4565,7 +4498,6 @@
 			}
 		}
 	} else {
-		/* tempcx = tempbx & 0x00FF ; */
 		tempbx = (tempbx & 0xFF00) >> 8;
 		tempcx = (tempcx + tempbx) >> 1;
 		temp = (tempcx & 0x00FF) + 2;
@@ -4579,36 +4511,23 @@
 						temp -= 6;
 				}
 			}
-		} else {
-			if (!(modeflag & HalfDCLK)) {
-				temp -= 4;
-				if (pVBInfo->LCDResInfo != Panel1280x960) {
-					if (pVBInfo->VGAHDE >= 800) {
-						temp -= 7;
-						if (pVBInfo->ModeType ==
-							ModeEGA) {
-							if (pVBInfo->VGAVDE ==
-							    1024) {
-								temp += 15;
-								if (pVBInfo->LCDResInfo != Panel1280x1024) {
-									temp +=
-									    7;
-								}
-							}
-						}
-
-						if (pVBInfo->VGAHDE >= 1280) {
-							if (pVBInfo->LCDResInfo
-									!= Panel1280x960) {
-								if (pVBInfo->LCDInfo
-										& LCDNonExpanding) {
-									temp
-											+= 28;
-								}
-							}
-						}
-					}
+		} else if (!(modeflag & HalfDCLK)) {
+			temp -= 4;
+			if (pVBInfo->LCDResInfo != Panel1280x960 &&
+			    pVBInfo->VGAHDE >= 800) {
+				temp -= 7;
+				if (pVBInfo->ModeType == ModeEGA &&
+				    pVBInfo->VGAVDE == 1024) {
+					temp += 15;
+					if (pVBInfo->LCDResInfo !=
+						Panel1280x1024)
+						temp += 7;
 				}
+
+				if (pVBInfo->VGAHDE >= 1280 &&
+				    pVBInfo->LCDResInfo != Panel1280x960 &&
+				    (pVBInfo->LCDInfo & LCDNonExpanding))
+					temp += 28;
 			}
 		}
 	}
@@ -5297,7 +5216,6 @@
 		tempax--;
 		xgifb_reg_and(pVBInfo->Part2Port, 0x01, tempax);
 
-		/* if ( !( pVBInfo->VBType & VB_XGI301C ) ) */
 		xgifb_reg_and(pVBInfo->Part2Port, 0x00, 0xEF);
 	}
 
@@ -5436,7 +5354,6 @@
 	tempax = pVBInfo->VT;
 	tempbx = pVBInfo->LCDVRS;
 
-	/* if (SetLCD_Info & EnableScalingLCD) */
 	tempcx += tempbx;
 	if (tempcx >= tempax)
 		tempcx -= tempax;
@@ -5478,12 +5395,10 @@
 	temp = (tempcx & 0xFF00) >> 8;
 	xgifb_reg_set(pVBInfo->Part2Port, 0x25, temp);
 
-	/* getlcdsync() */
 	XGI_GetLCDSync(&tempax, &tempbx, pVBInfo);
 	tempcx = tempax;
 	tempax = pVBInfo->HT;
 	tempbx = pVBInfo->LCDHRS;
-	/* if ( SetLCD_Info & EnableScalingLCD) */
 	if (XGI_IsLCDDualLink(pVBInfo)) {
 		tempax = tempax >> 1;
 		tempbx = tempbx >> 1;
@@ -5801,9 +5716,6 @@
 		if (XGI_IsLCDDualLink(pVBInfo))
 			tempax = tempax >> 1;
 
-		/* if((pVBInfo->VBInfo&(SetCRT2ToLCD)) ||
-		      ((pVBInfo->TVInfo&SetYPbPrMode525p) ||
-		      (pVBInfo->TVInfo&SetYPbPrMode750p))) { */
 		if (pVBInfo->VBInfo & SetCRT2ToLCD) {
 			if (tempax > 800)
 				tempax -= 800;
@@ -5817,33 +5729,6 @@
 		}
 		tempax -= 1;
 
-		/*
-		if (pVBInfo->VBInfo & (SetCRT2ToTV | SetCRT2ToHiVisionTV)) {
-			if (pVBInfo->VBType & VB_XGI301LV) {
-				if (!(pVBInfo->TVInfo &
-				      (SetYPbPrMode525p |
-				       SetYPbPrMode750p |
-				       SetYPbPrMode1080i))) {
-					if (pVBInfo->VGAHDE > 800) {
-						if (pVBInfo->VGAHDE == 1024)
-							tempax =(tempax * 25 /
-								 32) - 1;
-						else
-							tempax = (tempax * 20 /
-								  32) - 1;
-					}
-				}
-			} else {
-				if (pVBInfo->VGAHDE > 800) {
-					if (pVBInfo->VGAHDE == 1024)
-						tempax = (tempax * 25 / 32) - 1;
-					else
-						tempax = (tempax * 20 / 32) - 1;
-				}
-			}
-		}
-		*/
-
 		temp = (tempax & 0xFF00) >> 8;
 		temp = ((temp & 0x0003) << 4);
 		xgifb_reg_set(pVBInfo->Part4Port, 0x1E, temp);
@@ -5902,7 +5787,6 @@
 		if (!(pVBInfo->VBInfo & (SetInSlaveMode | LoadDACFlag
 				| CRT2DisplayFlag))) {
 			XGINew_EnableCRT2(pVBInfo);
-			/* LoadDAC2(pVBInfo->Part5Port, ModeNo, ModeIdIndex); */
 		}
 	}
 	return;
@@ -5921,118 +5805,11 @@
 	xgifb_reg_and_or(pVBInfo->P3d4, 0x63, 0xBF, 0x00);
 }
 
-/*----------------------------------------------------------------------------*/
-/* input                                                                      */
-/*      bl[5] : 1;LVDS signal on                                              */
-/*      bl[1] : 1;LVDS backlight on                                           */
-/*      bl[0] : 1:LVDS VDD on                                                 */
-/*      bh: 100000b : clear bit 5, to set bit5                                */
-/*          000010b : clear bit 1, to set bit1                                */
-/*          000001b : clear bit 0, to set bit0                                */
-/*----------------------------------------------------------------------------*/
-void XGI_XG21BLSignalVDD(unsigned short tempbh, unsigned short tempbl,
+static unsigned char XGI_XG21CheckLVDSMode(struct xgifb_video_info *xgifb_info,
+		unsigned short ModeNo, unsigned short ModeIdIndex,
 		struct vb_device_info *pVBInfo)
 {
-	unsigned char CR4A, temp;
-
-	CR4A = xgifb_reg_get(pVBInfo->P3d4, 0x4A);
-	tempbh &= 0x23;
-	tempbl &= 0x23;
-	xgifb_reg_and(pVBInfo->P3d4, 0x4A, ~tempbh); /* enable GPIO write */
-
-	if (tempbh & 0x20) {
-		temp = (tempbl >> 4) & 0x02;
-
-		/* CR B4[1] */
-		xgifb_reg_and_or(pVBInfo->P3d4, 0xB4, ~0x02, temp);
-
-	}
-
-	temp = xgifb_reg_get(pVBInfo->P3d4, 0x48);
-
-	temp = XG21GPIODataTransfer(temp);
-	temp &= ~tempbh;
-	temp |= tempbl;
-	xgifb_reg_set(pVBInfo->P3d4, 0x48, temp);
-}
-
-void XGI_XG27BLSignalVDD(unsigned short tempbh, unsigned short tempbl,
-		struct vb_device_info *pVBInfo)
-{
-	unsigned char CR4A, temp;
-	unsigned short tempbh0, tempbl0;
-
-	tempbh0 = tempbh;
-	tempbl0 = tempbl;
-	tempbh0 &= 0x20;
-	tempbl0 &= 0x20;
-	tempbh0 >>= 3;
-	tempbl0 >>= 3;
-
-	if (tempbh & 0x20) {
-		temp = (tempbl >> 4) & 0x02;
-
-		/* CR B4[1] */
-		xgifb_reg_and_or(pVBInfo->P3d4, 0xB4, ~0x02, temp);
-
-	}
-	xgifb_reg_and_or(pVBInfo->P3d4, 0xB4, ~tempbh0, tempbl0);
-
-	CR4A = xgifb_reg_get(pVBInfo->P3d4, 0x4A);
-	tempbh &= 0x03;
-	tempbl &= 0x03;
-	tempbh <<= 2;
-	tempbl <<= 2; /* GPIOC,GPIOD */
-	xgifb_reg_and(pVBInfo->P3d4, 0x4A, ~tempbh); /* enable GPIO write */
-	xgifb_reg_and_or(pVBInfo->P3d4, 0x48, ~tempbh, tempbl);
-}
-
-/* --------------------------------------------------------------------- */
-unsigned short XGI_GetLVDSOEMTableIndex(struct vb_device_info *pVBInfo)
-{
-	unsigned short index;
-
-	index = xgifb_reg_get(pVBInfo->P3d4, 0x36);
-	if (index < sizeof(XGI21_LCDCapList)
-			/ sizeof(struct XGI21_LVDSCapStruct))
-		return index;
-	return 0;
-}
-
-/* --------------------------------------------------------------------- */
-/* Function : XGI_XG21SetPanelDelay */
-/* Input : */
-/* Output : */
-/* Description : */
-/* I/P : bl : 1 ; T1 : the duration between CPL on and signal on */
-/* : bl : 2 ; T2 : the duration signal on and Vdd on */
-/* : bl : 3 ; T3 : the duration between CPL off and signal off */
-/* : bl : 4 ; T4 : the duration signal off and Vdd off */
-/* --------------------------------------------------------------------- */
-void XGI_XG21SetPanelDelay(unsigned short tempbl,
-		struct vb_device_info *pVBInfo)
-{
-	unsigned short index;
-
-	index = XGI_GetLVDSOEMTableIndex(pVBInfo);
-	if (tempbl == 1)
-		mdelay(pVBInfo->XG21_LVDSCapList[index].PSC_S1);
-
-	if (tempbl == 2)
-		mdelay(pVBInfo->XG21_LVDSCapList[index].PSC_S2);
-
-	if (tempbl == 3)
-		mdelay(pVBInfo->XG21_LVDSCapList[index].PSC_S3);
-
-	if (tempbl == 4)
-		mdelay(pVBInfo->XG21_LVDSCapList[index].PSC_S4);
-}
-
-unsigned char XGI_XG21CheckLVDSMode(unsigned short ModeNo,
-		unsigned short ModeIdIndex, struct vb_device_info *pVBInfo)
-{
-	unsigned short xres, yres, colordepth, modeflag, resindex,
-			lvdstableindex;
+	unsigned short xres, yres, colordepth, modeflag, resindex;
 
 	resindex = XGI_GetResInfo(ModeNo, ModeIdIndex, pVBInfo);
 	if (ModeNo <= 0x13) {
@@ -6061,18 +5838,15 @@
 
 	}
 
-	lvdstableindex = XGI_GetLVDSOEMTableIndex(pVBInfo);
-	if (xres > (pVBInfo->XG21_LVDSCapList[lvdstableindex].LVDSHDE))
+	if (xres > xgifb_info->lvds_data.LVDSHDE)
 		return 0;
 
-	if (yres > (pVBInfo->XG21_LVDSCapList[lvdstableindex].LVDSVDE))
+	if (yres > xgifb_info->lvds_data.LVDSVDE)
 		return 0;
 
 	if (ModeNo > 0x13) {
-		if ((xres != (pVBInfo->XG21_LVDSCapList[lvdstableindex].
-				LVDSHDE)) ||
-		    (yres != (pVBInfo->XG21_LVDSCapList[lvdstableindex].
-				LVDSVDE))) {
+		if (xres != xgifb_info->lvds_data.LVDSHDE ||
+		    yres != xgifb_info->lvds_data.LVDSVDE) {
 			colordepth = XGI_GetColorDepth(ModeNo,
 						       ModeIdIndex,
 						       pVBInfo);
@@ -6084,55 +5858,26 @@
 	return 1;
 }
 
-void XGI_SetXG21FPBits(struct vb_device_info *pVBInfo)
-{
-	unsigned char temp;
-
-	temp = xgifb_reg_get(pVBInfo->P3d4, 0x37); /* D[0] 1: 18bit */
-	temp = (temp & 1) << 6;
-	/* SR06[6] 18bit Dither */
-	xgifb_reg_and_or(pVBInfo->P3c4, 0x06, ~0x40, temp);
-	/* SR09[7] enable FP output, SR09[6] 1: sigle 18bits, 0: dual 12bits */
-	xgifb_reg_and_or(pVBInfo->P3c4, 0x09, ~0xc0, temp | 0x80);
-
-}
-
-void XGI_SetXG27FPBits(struct vb_device_info *pVBInfo)
-{
-	unsigned char temp;
-
-	/* D[1:0] 01: 18bit, 00: dual 12, 10: single 24 */
-	temp = xgifb_reg_get(pVBInfo->P3d4, 0x37);
-	temp = (temp & 3) << 6;
-	/* SR06[7]0: dual 12/1: single 24 [6] 18bit Dither <= 0 h/w recommend */
-	xgifb_reg_and_or(pVBInfo->P3c4, 0x06, ~0xc0, temp & 0x80);
-	/* SR09[7] enable FP output, SR09[6] 1: sigle 18bits, 0: 24bits */
-	xgifb_reg_and_or(pVBInfo->P3c4, 0x09, ~0xc0, temp | 0x80);
-
-}
-
-static void xgifb_set_lvds(int chip_id,
+static void xgifb_set_lvds(struct xgifb_video_info *xgifb_info,
+			   int chip_id,
 			   unsigned short ModeNo,
 			   unsigned short ModeIdIndex,
 			   struct vb_device_info *pVBInfo)
 {
 	unsigned char temp, Miscdata;
-	unsigned short xres, yres, modeflag, resindex, lvdstableindex;
+	unsigned short xres, yres, modeflag, resindex;
 	unsigned short LVDSHT, LVDSHBS, LVDSHRS, LVDSHRE, LVDSHBE;
 	unsigned short LVDSVT, LVDSVBS, LVDSVRS, LVDSVRE, LVDSVBE;
 	unsigned short value;
 
-	lvdstableindex = XGI_GetLVDSOEMTableIndex(pVBInfo);
-	temp = (unsigned char) ((pVBInfo->XG21_LVDSCapList[lvdstableindex].
-					LVDS_Capability &
+	temp = (unsigned char) ((xgifb_info->lvds_data.LVDS_Capability &
 				(LCDPolarity << 8)) >> 8);
 	temp &= LCDPolarity;
 	Miscdata = (unsigned char) inb(pVBInfo->P3cc);
 
 	outb((Miscdata & 0x3F) | temp, pVBInfo->P3c2);
 
-	temp = (unsigned char) (pVBInfo->XG21_LVDSCapList[lvdstableindex].
-					LVDS_Capability & LCDPolarity);
+	temp = xgifb_info->lvds_data.LVDS_Capability & LCDPolarity;
 	/* SR35[7] FP VSync polarity */
 	xgifb_reg_and_or(pVBInfo->P3c4, 0x35, ~0x80, temp & 0x80);
 	/* SR30[5] FP HSync polarity */
@@ -6159,48 +5904,43 @@
 	if (!(modeflag & Charx8Dot))
 		xres = xres * 8 / 9;
 
-	LVDSHT = pVBInfo->XG21_LVDSCapList[lvdstableindex].LVDSHT;
+	LVDSHT = xgifb_info->lvds_data.LVDSHT;
 
-	LVDSHBS = xres + (pVBInfo->XG21_LVDSCapList[lvdstableindex].LVDSHDE
-			- xres) / 2;
+	LVDSHBS = xres + (xgifb_info->lvds_data.LVDSHDE - xres) / 2;
 	if ((ModeNo <= 0x13) && (modeflag & HalfDCLK))
 		LVDSHBS -= xres / 4;
 
 	if (LVDSHBS > LVDSHT)
 		LVDSHBS -= LVDSHT;
 
-	LVDSHRS = LVDSHBS + pVBInfo->XG21_LVDSCapList[lvdstableindex].LVDSHFP;
+	LVDSHRS = LVDSHBS + xgifb_info->lvds_data.LVDSHFP;
 	if (LVDSHRS > LVDSHT)
 		LVDSHRS -= LVDSHT;
 
-	LVDSHRE = LVDSHRS + pVBInfo->XG21_LVDSCapList[lvdstableindex].LVDSHSYNC;
+	LVDSHRE = LVDSHRS + xgifb_info->lvds_data.LVDSHSYNC;
 	if (LVDSHRE > LVDSHT)
 		LVDSHRE -= LVDSHT;
 
-	LVDSHBE = LVDSHBS + LVDSHT
-			- pVBInfo->XG21_LVDSCapList[lvdstableindex].LVDSHDE;
+	LVDSHBE = LVDSHBS + LVDSHT - xgifb_info->lvds_data.LVDSHDE;
 
-	LVDSVT = pVBInfo->XG21_LVDSCapList[lvdstableindex].LVDSVT;
+	LVDSVT = xgifb_info->lvds_data.LVDSVT;
 
-	LVDSVBS = yres + (pVBInfo->XG21_LVDSCapList[lvdstableindex].LVDSVDE
-			- yres) / 2;
+	LVDSVBS = yres + (xgifb_info->lvds_data.LVDSVDE - yres) / 2;
 	if ((ModeNo > 0x13) && (modeflag & DoubleScanMode))
 		LVDSVBS += yres / 2;
 
 	if (LVDSVBS > LVDSVT)
 		LVDSVBS -= LVDSVT;
 
-	LVDSVRS = LVDSVBS + pVBInfo->XG21_LVDSCapList[lvdstableindex].LVDSVFP;
+	LVDSVRS = LVDSVBS + xgifb_info->lvds_data.LVDSVFP;
 	if (LVDSVRS > LVDSVT)
 		LVDSVRS -= LVDSVT;
 
-	LVDSVRE = LVDSVRS + pVBInfo->XG21_LVDSCapList[lvdstableindex].
-					LVDSVSYNC;
+	LVDSVRE = LVDSVRS + xgifb_info->lvds_data.LVDSVSYNC;
 	if (LVDSVRE > LVDSVT)
 		LVDSVRE -= LVDSVT;
 
-	LVDSVBE = LVDSVBS + LVDSVT
-			- pVBInfo->XG21_LVDSCapList[lvdstableindex].LVDSVDE;
+	LVDSVBE = LVDSVBS + LVDSVT - xgifb_info->lvds_data.LVDSVDE;
 
 	temp = (unsigned char) xgifb_reg_get(pVBInfo->P3d4, 0x11);
 	xgifb_reg_set(pVBInfo->P3d4, 0x11, temp & 0x7f); /* Unlock CRTC */
@@ -6300,13 +6040,9 @@
 
 		xgifb_reg_and_or(pVBInfo->P3c4, 0x31, ~0x30, value);
 		xgifb_reg_set(pVBInfo->P3c4,
-			      0x2B,
-			      pVBInfo->XG21_LVDSCapList[lvdstableindex].
-					VCLKData1);
+			      0x2B, xgifb_info->lvds_data.VCLKData1);
 		xgifb_reg_set(pVBInfo->P3c4,
-			      0x2C,
-			      pVBInfo->XG21_LVDSCapList[lvdstableindex].
-					VCLKData2);
+			      0x2C, xgifb_info->lvds_data.VCLKData2);
 		value += 0x10;
 	}
 
@@ -6398,7 +6134,8 @@
 	return 0;
 }
 
-void XGI_DisableBridge(struct xgi_hw_device_info *HwDeviceExtension,
+static void XGI_DisableBridge(struct xgifb_video_info *xgifb_info,
+		struct xgi_hw_device_info *HwDeviceExtension,
 		struct vb_device_info *pVBInfo)
 {
 	unsigned short tempah = 0;
@@ -6442,7 +6179,7 @@
 						| SetSimuScanMode))) {
 			if (pVBInfo->SetFlag & GatingCRT)
 				XGI_EnableGatingCRT(HwDeviceExtension, pVBInfo);
-			XGI_DisplayOff(HwDeviceExtension, pVBInfo);
+			XGI_DisplayOff(xgifb_info, HwDeviceExtension, pVBInfo);
 		}
 
 		if (pVBInfo->VBInfo & SetCRT2ToLCDA) {
@@ -6464,7 +6201,6 @@
 		    ((!(pVBInfo->VBInfo & SetCRT2ToLCDA)) &&
 		    (pVBInfo->VBInfo &
 			(SetCRT2ToRAMDAC | SetCRT2ToLCD | SetCRT2ToTV))))
-			/* BScreenOff=1 */
 			xgifb_reg_or(pVBInfo->Part1Port, 0x00, 0x80);
 
 		if ((pVBInfo->SetFlag & DisableChB) ||
@@ -6484,7 +6220,6 @@
 		}
 	} else { /* {301} */
 		if (pVBInfo->VBInfo & (SetCRT2ToLCD | SetCRT2ToTV)) {
-			/* BScreenOff=1 */
 			xgifb_reg_or(pVBInfo->Part1Port, 0x00, 0x80);
 			/* Disable CRT2 */
 			xgifb_reg_and(pVBInfo->Part1Port, 0x1E, 0xDF);
@@ -6494,7 +6229,7 @@
 
 		if (pVBInfo->VBInfo & (DisableCRT2Display | SetCRT2ToLCDA
 				| SetSimuScanMode))
-			XGI_DisplayOff(HwDeviceExtension, pVBInfo);
+			XGI_DisplayOff(xgifb_info, HwDeviceExtension, pVBInfo);
 	}
 }
 
@@ -6610,17 +6345,6 @@
 
 			if (pVBInfo->VBInfo & SetCRT2ToDualEdge)
 				tempbl = tempbl >> 4;
-			/*
-			if (pVBInfo->VBInfo & SetCRT2ToRAMDAC)
-				tempbl = CRT2Delay1;	// Get CRT2 Delay
-			if (pVBInfo->VBType &
-			    (VB_XGI301B |
-			     VB_XGI302B |
-			     VB_XGI301LV |
-			     VB_XGI302LV |
-			     VB_XGI301C))
-				tempbl = CRT2Delay2;
-			*/
 			if (pVBInfo->VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
 				/* Get LCD Delay */
 				index = XGI_GetLCDCapPtr(pVBInfo);
@@ -6680,23 +6404,6 @@
 				(unsigned short) (0x30 | (tempcx & 0x00C0)));
 		xgifb_reg_and_or(pVBInfo->Part1Port, 0x1A, 0x7F, 0x00);
 	}
-
-	/*
-	if (tempcx & EnableLCD24bpp) {	// 24bits
-		xgifb_reg_and_or(pVBInfo->Part1Port,
-				 0x19,
-				 0x0F,
-				 (unsigned short)(0x30 | (tempcx&0x00C0)));
-		xgifb_reg_and_or(pVBInfo->Part1Port, 0x1A, 0x7F, 0x00);
-	} else {
-		xgifb_reg_and_or(pVBInfo->Part1Port,
-				 0x19,
-				 0x0F,
-				 // Enable Dither
-				 (unsigned short)(0x20 | (tempcx&0x00C0)));
-		xgifb_reg_and_or(pVBInfo->Part1Port, 0x1A, 0x7F, 0x80);
-	}
-	*/
 }
 
 /* --------------------------------------------------------------------- */
@@ -6718,6 +6425,25 @@
 						| 0x18)); /* Enable Dither */
 }
 
+static void XGI_LongWait(struct vb_device_info *pVBInfo)
+{
+	unsigned short i;
+
+	i = xgifb_reg_get(pVBInfo->P3c4, 0x1F);
+
+	if (!(i & 0xC0)) {
+		for (i = 0; i < 0xFFFF; i++) {
+			if (!(inb(pVBInfo->P3da) & 0x08))
+				break;
+		}
+
+		for (i = 0; i < 0xFFFF; i++) {
+			if ((inb(pVBInfo->P3da) & 0x08))
+				break;
+		}
+	}
+}
+
 static void SetSpectrum(struct vb_device_info *pVBInfo)
 {
 	unsigned short index;
@@ -6940,14 +6666,12 @@
 			      unsigned short ModeIdIndex,
 			      struct vb_device_info *pVBInfo)
 {
-	/* GetPart1IO(); */
 	XGI_SetDelayComp(pVBInfo);
 
 	if (pVBInfo->VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA))
 		XGI_SetLCDCap(pVBInfo);
 
 	if (pVBInfo->VBInfo & SetCRT2ToTV) {
-		/* GetPart2IO() */
 		XGI_SetPhaseIncr(pVBInfo);
 		XGI_SetYFilter(ModeNo, ModeIdIndex, pVBInfo);
 		XGI_SetAntiFlicker(ModeNo, ModeIdIndex, pVBInfo);
@@ -6963,7 +6687,7 @@
 /* Output : */
 /* Description : Origin code for crt2group */
 /* --------------------------------------------------------------------- */
-void XGI_SetCRT2ModeRegs(unsigned short ModeNo,
+static void XGI_SetCRT2ModeRegs(unsigned short ModeNo,
 		struct xgi_hw_device_info *HwDeviceExtension,
 		struct vb_device_info *pVBInfo)
 {
@@ -6972,8 +6696,6 @@
 
 	unsigned char tempah;
 
-	/* // fix write part1 index 0 BTDRAM bit Bug
-	 * xgifb_reg_set(pVBInfo->Part1Port, 0x03, 0x00); */
 	tempah = 0;
 	if (!(pVBInfo->VBInfo & DisableCRT2Display)) {
 		tempah = xgifb_reg_get(pVBInfo->Part1Port, 0x00);
@@ -6999,32 +6721,6 @@
 		}
 	}
 
-	/* 0210 shampoo
-	if (pVBInfo->VBInfo & DisableCRT2Display) {
-		tempah = 0;
-	}
-
-	xgifb_reg_set(pVBInfo->Part1Port, 0x00, tempah);
-	if (pVBInfo->VBInfo & (SetCRT2ToRAMDAC | SetCRT2ToTV | SetCRT2ToLCD)) {
-		tempcl = pVBInfo->ModeType;
-		if (ModeNo > 0x13) {
-			tempcl -= ModeVGA;
-			if ((tempcl > 0) || (tempcl == 0)) {
-				tempah=(0x008>>tempcl) ;
-				if (tempah == 0)
-					tempah = 1;
-				tempah |= 0x040;
-			}
-		} else {
-			tempah = 0x040;
-		}
-
-		if (pVBInfo->VBInfo & SetInSlaveMode) {
-			tempah = (tempah ^ 0x050);
-		}
-	}
-	*/
-
 	xgifb_reg_set(pVBInfo->Part1Port, 0x00, tempah);
 	tempah = 0x08;
 	tempbl = 0xf0;
@@ -7093,14 +6789,11 @@
 		tempah |= 0x080;
 
 		if (pVBInfo->VBInfo & SetCRT2ToTV) {
-			/* if (!(pVBInfo->TVInfo &
-				 (SetYPbPrMode525p | SetYPbPrMode750p))) { */
 			tempah |= 0x020;
 			if (ModeNo > 0x13) {
 				if (pVBInfo->VBInfo & DriverMode)
 					tempah = tempah ^ 0x20;
 			}
-			/* } */
 		}
 
 		xgifb_reg_and_or(pVBInfo->Part4Port, 0x0D, ~0x0BF, tempah);
@@ -7110,12 +6803,8 @@
 			tempah |= 0x40;
 
 		if (pVBInfo->VBInfo & SetCRT2ToTV) {
-			/* if ((!(pVBInfo->VBInfo & SetCRT2ToHiVisionTV)) &&
-			       (!(pVBInfo->TVInfo &
-				  (SetYPbPrMode525p | SetYPbPrMode750p)))) { */
 			if (pVBInfo->TVInfo & RPLLDIV2XO)
 				tempah |= 0x40;
-			/* } */
 		}
 
 		if ((pVBInfo->LCDResInfo == Panel1280x1024)
@@ -7219,57 +6908,6 @@
 	}
 }
 
-void XGI_LongWait(struct vb_device_info *pVBInfo)
-{
-	unsigned short i;
-
-	i = xgifb_reg_get(pVBInfo->P3c4, 0x1F);
-
-	if (!(i & 0xC0)) {
-		for (i = 0; i < 0xFFFF; i++) {
-			if (!(inb(pVBInfo->P3da) & 0x08))
-				break;
-		}
-
-		for (i = 0; i < 0xFFFF; i++) {
-			if ((inb(pVBInfo->P3da) & 0x08))
-				break;
-		}
-	}
-}
-
-static void XGI_VBLongWait(struct vb_device_info *pVBInfo)
-{
-	unsigned short tempal, temp, i, j;
-	return;
-	if (!(pVBInfo->VBInfo & SetCRT2ToTV)) {
-		temp = 0;
-		for (i = 0; i < 3; i++) {
-			for (j = 0; j < 100; j++) {
-				tempal = inb(pVBInfo->P3da);
-				if (temp & 0x01) { /* VBWaitMode2 */
-					if ((tempal & 0x08))
-						continue;
-
-					if (!(tempal & 0x08))
-						break;
-
-				} else { /* VBWaitMode1 */
-					if (!(tempal & 0x08))
-						continue;
-
-					if ((tempal & 0x08))
-						break;
-				}
-			}
-			temp = temp ^ 0x01;
-		}
-	} else {
-		XGI_LongWait(pVBInfo);
-	}
-	return;
-}
-
 unsigned short XGI_GetRatePtrCRT2(struct xgi_hw_device_info *pXGIHWDE,
 		unsigned short ModeNo, unsigned short ModeIdIndex,
 		struct vb_device_info *pVBInfo)
@@ -7322,12 +6960,6 @@
 	RefreshRateTableIndex = pVBInfo->EModeIDTable[ModeIdIndex].REFindex;
 	ModeNo = pVBInfo->RefIndex[RefreshRateTableIndex].ModeID;
 	if (pXGIHWDE->jChipType >= XG20) { /* for XG20, XG21, XG27 */
-		/*
-		if (pVBInfo->RefIndex[RefreshRateTableIndex].Ext_InfoFlag &
-		    XG2xNotSupport) {
-			index++;
-		}
-		*/
 		if ((pVBInfo->RefIndex[RefreshRateTableIndex].XRes == 800) &&
 		    (pVBInfo->RefIndex[RefreshRateTableIndex].YRes == 600)) {
 			index++;
@@ -7371,7 +7003,7 @@
 		temp = XGI_AjustCRT2Rate(ModeNo, ModeIdIndex,
 				RefreshRateTableIndex, &i, pVBInfo);
 	}
-	return RefreshRateTableIndex + i; /* return (0x01 | (temp1<<1)); */
+	return RefreshRateTableIndex + i;
 }
 
 static void XGI_SetLCDAGroup(unsigned short ModeNo, unsigned short ModeIdIndex,
@@ -7379,9 +7011,6 @@
 		struct vb_device_info *pVBInfo)
 {
 	unsigned short RefreshRateTableIndex;
-	/* unsigned short temp ; */
-
-	/* pVBInfo->SelectCRT2Rate = 0; */
 
 	pVBInfo->SetFlag |= ProgrammingCRT2;
 	RefreshRateTableIndex = XGI_GetRatePtrCRT2(HwDeviceExtension, ModeNo,
@@ -7394,7 +7023,7 @@
 	XGI_SetCRT2ECLK(ModeNo, ModeIdIndex, RefreshRateTableIndex, pVBInfo);
 }
 
-unsigned char XGI_SetCRT2Group301(unsigned short ModeNo,
+static unsigned char XGI_SetCRT2Group301(unsigned short ModeNo,
 		struct xgi_hw_device_info *HwDeviceExtension,
 		struct vb_device_info *pVBInfo)
 {
@@ -7499,10 +7128,6 @@
 		outb((unsigned char) DAC_TEST_PARMS[2], (pVBInfo->P3c8 + 1));
 	}
 
-	XGI_VBLongWait(pVBInfo);
-	XGI_VBLongWait(pVBInfo);
-	XGI_VBLongWait(pVBInfo);
-
 	mdelay(1);
 
 	XGI_WaitDisply(pVBInfo);
@@ -7532,7 +7157,8 @@
 	xgifb_reg_set(pVBInfo->P3c4, 0x1F, (unsigned char) SR1F);
 }
 
-void XGI_EnableBridge(struct xgi_hw_device_info *HwDeviceExtension,
+static void XGI_EnableBridge(struct xgifb_video_info *xgifb_info,
+		struct xgi_hw_device_info *HwDeviceExtension,
 		struct vb_device_info *pVBInfo)
 {
 	unsigned short tempah;
@@ -7544,7 +7170,6 @@
 				/* Power on */
 				xgifb_reg_set(pVBInfo->Part1Port, 0x1E, 0x20);
 			} else {
-				/* SetCRT2ToLCDA ) */
 				if (pVBInfo->VBInfo & SetCRT2ToDualEdge) {
 					/* Power on */
 					xgifb_reg_set(pVBInfo->Part1Port,
@@ -7572,10 +7197,8 @@
 						pVBInfo->Part1Port, 0x2E);
 
 				if (!(tempah & 0x80))
-					/* BVBDOENABLE = 1 */
 					xgifb_reg_or(pVBInfo->Part1Port,
 							0x2E, 0x80);
-				/* BScreenOFF = 0 */
 				xgifb_reg_and(pVBInfo->Part1Port, 0x00, 0x7F);
 			}
 		}
@@ -7638,12 +7261,11 @@
 		xgifb_reg_or(pVBInfo->Part4Port, 0x1F, tempah);
 
 		if (!(pVBInfo->SetFlag & DisableChA)) {
-			XGI_VBLongWait(pVBInfo);
 			if (!(pVBInfo->SetFlag & GatingCRT)) {
 				XGI_DisableGatingCRT(HwDeviceExtension,
 						     pVBInfo);
-				XGI_DisplayOn(HwDeviceExtension, pVBInfo);
-				XGI_VBLongWait(pVBInfo);
+				XGI_DisplayOn(xgifb_info, HwDeviceExtension,
+						pVBInfo);
 			}
 		}
 	} /* 301 */
@@ -7656,15 +7278,15 @@
 		tempah = (unsigned char) xgifb_reg_get(pVBInfo->Part1Port,
 				0x2E);
 		if (!(tempah & 0x80))
-			/* BVBDOENABLE = 1 */
 			xgifb_reg_or(pVBInfo->Part1Port, 0x2E, 0x80);
 
 		xgifb_reg_and(pVBInfo->Part1Port, 0x00, 0x7F);
-		XGI_DisplayOn(HwDeviceExtension, pVBInfo);
+		XGI_DisplayOn(xgifb_info, HwDeviceExtension, pVBInfo);
 	} /* End of VB */
 }
 
-static void XGI_SetCRT1Group(struct xgi_hw_device_info *HwDeviceExtension,
+static void XGI_SetCRT1Group(struct xgifb_video_info *xgifb_info,
+		struct xgi_hw_device_info *HwDeviceExtension,
 		unsigned short ModeNo, unsigned short ModeIdIndex,
 		struct vb_device_info *pVBInfo)
 {
@@ -7672,18 +7294,14 @@
 
 	unsigned short XGINew_P3cc = pVBInfo->P3cc;
 
-	/* XGINew_CRT1Mode = ModeNo; // SaveModeID */
 	StandTableIndex = XGI_GetModePtr(ModeNo, ModeIdIndex, pVBInfo);
-	/* XGI_SetBIOSData(ModeNo, ModeIdIndex); */
-	/* XGI_ClearBankRegs(ModeNo, ModeIdIndex); */
 	XGI_SetSeqRegs(ModeNo, StandTableIndex, ModeIdIndex, pVBInfo);
-	XGI_SetMiscRegs(StandTableIndex, pVBInfo);
+	outb(pVBInfo->StandTable[StandTableIndex].MISC, pVBInfo->P3c2);
 	XGI_SetCRTCRegs(HwDeviceExtension, StandTableIndex, pVBInfo);
 	XGI_SetATTRegs(ModeNo, StandTableIndex, ModeIdIndex, pVBInfo);
 	XGI_SetGRCRegs(StandTableIndex, pVBInfo);
 	XGI_ClearExt1Regs(pVBInfo);
 
-	/* if (pVBInfo->IF_DEF_ExpLink) */
 	if (HwDeviceExtension->jChipType == XG27) {
 		if (pVBInfo->IF_DEF_LVDS == 0)
 			XGI_SetDefaultVCLK(pVBInfo);
@@ -7735,11 +7353,6 @@
 		temp = xgifb_reg_get(pVBInfo->P3d4, 0x38);
 		if (temp & 0xA0) {
 
-			/* Enable write GPIOF */
-			/* xgifb_reg_and(pVBInfo->P3d4, 0x4A, ~0x20); */
-			/* P. DWN */
-			/* xgifb_reg_and(pVBInfo->P3d4, 0x48, ~0x20); */
-			/* XG21 CRT1 Timing */
 			if (HwDeviceExtension->jChipType == XG27)
 				XGI_SetXG27CRTC(ModeNo, ModeIdIndex,
 						RefreshRateTableIndex, pVBInfo);
@@ -7754,10 +7367,9 @@
 					pVBInfo, RefreshRateTableIndex, ModeNo);
 
 			if (pVBInfo->IF_DEF_LVDS == 1)
-				xgifb_set_lvds(HwDeviceExtension->jChipType,
+				xgifb_set_lvds(xgifb_info,
+						HwDeviceExtension->jChipType,
 						ModeNo, ModeIdIndex, pVBInfo);
-			/* P. ON */
-			/* xgifb_reg_or(pVBInfo->P3d4, 0x48, 0x20); */
 		}
 	}
 
@@ -7765,22 +7377,16 @@
 	XGI_SetCRT1FIFO(ModeNo, HwDeviceExtension, pVBInfo);
 	XGI_SetCRT1ModeRegs(HwDeviceExtension, ModeNo, ModeIdIndex,
 			RefreshRateTableIndex, pVBInfo);
-
-	/* XGI_LoadCharacter(); //dif ifdef TVFont */
-
 	XGI_LoadDAC(ModeNo, ModeIdIndex, pVBInfo);
-	/* XGI_ClearBuffer(HwDeviceExtension, ModeNo, pVBInfo); */
 }
 
-unsigned char XGISetModeNew(struct xgi_hw_device_info *HwDeviceExtension,
+unsigned char XGISetModeNew(struct xgifb_video_info *xgifb_info,
+			struct xgi_hw_device_info *HwDeviceExtension,
 			unsigned short ModeNo)
 {
 	unsigned short ModeIdIndex;
-	/* unsigned char *pVBInfo->FBAddr =
-				HwDeviceExtension->pjVideoMemoryAddress; */
 	struct vb_device_info VBINF;
 	struct vb_device_info *pVBInfo = &VBINF;
-	pVBInfo->ROMAddr = HwDeviceExtension->pjVirtualRomBase;
 	pVBInfo->BaseAddr = (unsigned long) HwDeviceExtension->pjIOAddress;
 	pVBInfo->IF_DEF_LVDS = 0;
 	pVBInfo->IF_DEF_LCDA = 1;
@@ -7831,14 +7437,8 @@
 		XGI_GetVBType(pVBInfo);
 
 	InitTo330Pointer(HwDeviceExtension->jChipType, pVBInfo);
-	if (ModeNo & 0x80) {
+	if (ModeNo & 0x80)
 		ModeNo = ModeNo & 0x7F;
-		/* XGINew_flag_clearbuffer = 0; */
-	}
-	/* else {
-		XGINew_flag_clearbuffer = 1;
-	}
-	*/
 	xgifb_reg_set(pVBInfo->P3c4, 0x05, 0x86);
 
 	if (HwDeviceExtension->jChipType < XG20) /* kuku 2004/06/25 1.Openkey */
@@ -7846,16 +7446,14 @@
 
 	XGI_SearchModeID(ModeNo, &ModeIdIndex, pVBInfo);
 
-	XGI_GetVGAType(HwDeviceExtension, pVBInfo);
-
 	if (HwDeviceExtension->jChipType < XG20) { /* kuku 2004/06/25 */
 		XGI_GetVBInfo(ModeNo, ModeIdIndex, HwDeviceExtension, pVBInfo);
 		XGI_GetTVInfo(ModeNo, ModeIdIndex, pVBInfo);
 		XGI_GetLCDInfo(ModeNo, ModeIdIndex, pVBInfo);
-		XGI_DisableBridge(HwDeviceExtension, pVBInfo);
+		XGI_DisableBridge(xgifb_info, HwDeviceExtension, pVBInfo);
 
 		if (pVBInfo->VBInfo & (SetSimuScanMode | SetCRT2ToLCDA)) {
-			XGI_SetCRT1Group(HwDeviceExtension, ModeNo,
+			XGI_SetCRT1Group(xgifb_info, HwDeviceExtension, ModeNo,
 					ModeIdIndex, pVBInfo);
 
 			if (pVBInfo->VBInfo & SetCRT2ToLCDA) {
@@ -7864,7 +7462,8 @@
 			}
 		} else {
 			if (!(pVBInfo->VBInfo & SwitchToCRT2)) {
-				XGI_SetCRT1Group(HwDeviceExtension, ModeNo,
+				XGI_SetCRT1Group(xgifb_info,
+						HwDeviceExtension, ModeNo,
 						ModeIdIndex, pVBInfo);
 				if (pVBInfo->VBInfo & SetCRT2ToLCDA) {
 					XGI_SetLCDAGroup(ModeNo, ModeIdIndex,
@@ -7894,11 +7493,11 @@
 		XGI_SetCRT2ModeRegs(ModeNo, HwDeviceExtension, pVBInfo);
 		XGI_OEM310Setting(ModeNo, ModeIdIndex, pVBInfo); /*0212*/
 		XGI_CloseCRTC(HwDeviceExtension, pVBInfo);
-		XGI_EnableBridge(HwDeviceExtension, pVBInfo);
+		XGI_EnableBridge(xgifb_info, HwDeviceExtension, pVBInfo);
 	} /* !XG20 */
 	else {
 		if (pVBInfo->IF_DEF_LVDS == 1)
-			if (!XGI_XG21CheckLVDSMode(ModeNo,
+			if (!XGI_XG21CheckLVDSMode(xgifb_info, ModeNo,
 						   ModeIdIndex,
 						   pVBInfo))
 				return 0;
@@ -7914,40 +7513,14 @@
 		pVBInfo->SetFlag = 0;
 		pVBInfo->VBInfo = DisableCRT2Display;
 
-		XGI_DisplayOff(HwDeviceExtension, pVBInfo);
+		XGI_DisplayOff(xgifb_info, HwDeviceExtension, pVBInfo);
 
-		XGI_SetCRT1Group(HwDeviceExtension, ModeNo, ModeIdIndex,
-				pVBInfo);
+		XGI_SetCRT1Group(xgifb_info, HwDeviceExtension, ModeNo,
+				ModeIdIndex, pVBInfo);
 
-		XGI_DisplayOn(HwDeviceExtension, pVBInfo);
-		/*
-		if (HwDeviceExtension->jChipType == XG21)
-			xgifb_reg_and_or(pVBInfo->P3c4, 0x09, ~0x80, 0x80);
-		*/
+		XGI_DisplayOn(xgifb_info, HwDeviceExtension, pVBInfo);
 	}
 
-	/*
-	if (ModeNo <= 0x13) {
-		modeflag = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag;
-	} else {
-		modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag;
-	}
-	pVBInfo->ModeType = modeflag&ModeInfoFlag;
-	pVBInfo->SetFlag = 0x00;
-	pVBInfo->VBInfo = DisableCRT2Display;
-	temp = XGINew_CheckMemorySize(HwDeviceExtension,
-				      ModeNo,
-				      ModeIdIndex,
-				      pVBInfo);
-
-	if (temp == 0)
-		return (0);
-
-	XGI_DisplayOff(HwDeviceExtension, pVBInfo) ;
-	XGI_SetCRT1Group(HwDeviceExtension, ModeNo, ModeIdIndex, pVBInfo);
-	XGI_DisplayOn(HwDeviceExtension, pVBInfo);
-	*/
-
 	XGI_UpdateModeInfo(HwDeviceExtension, pVBInfo);
 
 	if (HwDeviceExtension->jChipType < XG20) { /* kuku 2004/06/25 */
diff --git a/drivers/staging/xgifb/vb_setmode.h b/drivers/staging/xgifb/vb_setmode.h
index 1bd8667..5524828 100644
--- a/drivers/staging/xgifb/vb_setmode.h
+++ b/drivers/staging/xgifb/vb_setmode.h
@@ -6,66 +6,22 @@
 			   struct vb_device_info *);
 extern void XGI_LockCRT2(struct xgi_hw_device_info *HwDeviceExtension,
 			 struct vb_device_info *);
-extern void XGI_LongWait(struct vb_device_info *);
-extern void XGI_SetCRT2ModeRegs(unsigned short ModeNo,
-				struct xgi_hw_device_info *,
-				struct vb_device_info *);
-extern void XGI_DisableBridge(struct xgi_hw_device_info *HwDeviceExtension,
-			      struct vb_device_info *);
-extern void XGI_EnableBridge(struct xgi_hw_device_info *HwDeviceExtension,
-			     struct vb_device_info *);
-extern void XGI_DisplayOff(struct xgi_hw_device_info *,
+extern void XGI_DisplayOff(struct xgifb_video_info *,
+			   struct xgi_hw_device_info *,
 			   struct vb_device_info *);
-extern void XGI_DisplayOn(struct xgi_hw_device_info *,
-			  struct vb_device_info *);
 extern void XGI_GetVBType(struct vb_device_info *);
 extern void XGI_SenseCRT1(struct vb_device_info *);
-extern void XGI_GetVGAType(struct xgi_hw_device_info *HwDeviceExtension,
-			   struct vb_device_info *);
-extern void XGI_GetVBInfo(unsigned short ModeNo,
-			  unsigned short ModeIdIndex,
-			  struct xgi_hw_device_info *HwDeviceExtension,
-			  struct vb_device_info *);
-extern void XGI_GetTVInfo(unsigned short ModeNo,
-			  unsigned short ModeIdIndex,
-			  struct vb_device_info *);
-extern unsigned short XGI_GetResInfo(unsigned short ModeNo,
-				     unsigned short ModeIdIndex,
-				     struct vb_device_info *pVBInfo);
-
-extern unsigned char XGISetModeNew(struct xgi_hw_device_info *HwDeviceExtension,
+extern unsigned char XGISetModeNew(struct xgifb_video_info *xgifb_info,
+				   struct xgi_hw_device_info *HwDeviceExtension,
 				   unsigned short ModeNo) ;
 
 extern unsigned char XGI_SearchModeID(unsigned short ModeNo,
 				      unsigned short *ModeIdIndex,
 				      struct vb_device_info *);
-extern unsigned char XGI_GetLCDInfo(unsigned short ModeNo,
-				    unsigned short ModeIdIndex,
-				    struct vb_device_info *);
 extern unsigned char XGI_BridgeIsOn(struct vb_device_info *);
-
-extern unsigned char
-XGI_SetCRT2Group301(unsigned short ModeNo,
-		    struct xgi_hw_device_info *HwDeviceExtension,
-		    struct vb_device_info *);
 extern unsigned short XGI_GetRatePtrCRT2(struct xgi_hw_device_info *pXGIHWDE,
 					 unsigned short ModeNo,
 					 unsigned short ModeIdIndex,
 					 struct vb_device_info *);
 
-extern void XGI_SetXG21FPBits(struct vb_device_info *pVBInfo);
-extern void XGI_SetXG27FPBits(struct vb_device_info *pVBInfo);
-extern void XGI_XG21BLSignalVDD(unsigned short tempbh,
-				unsigned short tempbl,
-				struct vb_device_info *pVBInfo);
-extern void XGI_XG27BLSignalVDD(unsigned short tempbh,
-				unsigned short tempbl,
-				struct vb_device_info *pVBInfo);
-extern void XGI_XG21SetPanelDelay(unsigned short tempbl,
-				  struct vb_device_info *pVBInfo);
-extern unsigned char XGI_XG21CheckLVDSMode(unsigned short ModeNo,
-					   unsigned short ModeIdIndex,
-					   struct vb_device_info *pVBInfo);
-extern unsigned short XGI_GetLVDSOEMTableIndex(struct vb_device_info *pVBInfo);
-
 #endif
diff --git a/drivers/staging/xgifb/vb_struct.h b/drivers/staging/xgifb/vb_struct.h
index f9ade6f..6556a0d 100644
--- a/drivers/staging/xgifb/vb_struct.h
+++ b/drivers/staging/xgifb/vb_struct.h
@@ -293,13 +293,12 @@
 	unsigned short   IF_DEF_ExpLink;
 	unsigned short   IF_DEF_HiVision;
 	unsigned short   LCDResInfo, LCDTypeInfo, VBType;/*301b*/
-	unsigned short   VBInfo, TVInfo, LCDInfo, Set_VGAType;
+	unsigned short   VBInfo, TVInfo, LCDInfo;
 	unsigned short   VBExtInfo;/*301lv*/
 	unsigned short   SetFlag;
 	unsigned short   NewFlickerMode;
 	unsigned short   SelectCRT2Rate;
 
-	unsigned char *ROMAddr;
 	void __iomem *FBAddr;
 	unsigned long BaseAddr;
 	unsigned long RelIO;
@@ -376,7 +375,6 @@
 	unsigned char   *pXGINew_CR97 ;
 
 	struct XGI330_LCDCapStruct  *LCDCapList;
-	struct XGI21_LVDSCapStruct  *XG21_LVDSCapList;
 
 	struct XGI_TimingHStruct  *TimingH;
 	struct XGI_TimingVStruct  *TimingV;
diff --git a/drivers/staging/xgifb/vb_table.h b/drivers/staging/xgifb/vb_table.h
index b81ac77..e7946f1 100644
--- a/drivers/staging/xgifb/vb_table.h
+++ b/drivers/staging/xgifb/vb_table.h
@@ -2569,33 +2569,6 @@
 	0x30, 0x10, 0x5A, 0x10, 0x10, 0x0A, 0xC0, 0x28, 0x10}
 };
 
-struct XGI21_LVDSCapStruct XGI21_LCDCapList[] = {
-	{DisableLCD24bpp + LCDPolarity,
-	 2160, 1250, 1600, 1200,   64,    1,  192,    3,
-	 0x70, 0x24, 0x20, 0x04, 0x0A, 0x02, 0xC8
-	},
-	{DisableLCD24bpp + LCDPolarity,
-	 1688, 1066, 1280, 1024,   48,    1,   112,    3,
-	 0x70, 0x44, 0x20, 0x04, 0x0A, 0x02, 0xC8
-	},
-	{DisableLCD24bpp + LCDPolarity + (LCDPolarity << 8),
-	 1344,  806, 1024,  768,   24,    3,   136,    6,
-	 0x6C, 0x65, 0x20, 0x04, 0x0A, 0x02, 0xC8
-	},
-	{DisableLCD24bpp + LCDPolarity,
-	 1056,  628,  800,  600,   40,    1,  128,    4,
-	 0x42, 0xE2, 0x20, 0x14, 0x0A, 0x02, 0x00
-	},
-	{DisableLCD24bpp + LCDPolarity,
-	  928,  525,  800,  480,   40,   13,   48,    3,
-	 0x52, 0xC5, 0x20, 0x14, 0x0A, 0x02, 0x00
-	},
-	{DisableLCD24bpp + LCDPolarity + (LCDPolarity << 8),
-	  800,  525,  640,  480,   16,   10,   96,    2,
-	 0x1B, 0xE1, 0x20, 0x04, 0x0A, 0x02, 0xC8
-	}
-};
-
 static struct XGI_Ext2Struct XGI330_RefIndex[] = {
 	{Support32Bpp + SupportAllCRT2 + SyncPN, RES320x200, VCLK25_175,
 	0x00, 0x10, 0x59, 320, 200},/* 00 */
diff --git a/drivers/staging/xgifb/vgatypes.h b/drivers/staging/xgifb/vgatypes.h
index 9b939b7..9e166bb 100644
--- a/drivers/staging/xgifb/vgatypes.h
+++ b/drivers/staging/xgifb/vgatypes.h
@@ -51,8 +51,6 @@
 	unsigned long ulExternalChip; /* NO VB or other video bridge*/
 				      /* if ujVBChipID = VB_CHIP_UNKNOWN, */
 
-	unsigned char *pjVirtualRomBase; /* ROM image */
-
 	void __iomem *pjVideoMemoryAddress;/* base virtual memory address */
 					    /* of Linear VGA memory */
 
diff --git a/drivers/staging/zcache/zcache-main.c b/drivers/staging/zcache/zcache-main.c
index 56c1f9c..642840c 100644
--- a/drivers/staging/zcache/zcache-main.c
+++ b/drivers/staging/zcache/zcache-main.c
@@ -787,7 +787,7 @@
 	if (!capable(CAP_SYS_ADMIN))
 		return -EPERM;
 
-	err = strict_strtoul(buf, 10, &val);
+	err = kstrtoul(buf, 10, &val);
 	if (err || (val == 0) || (val > (PAGE_SIZE / 8) * 7))
 		return -EINVAL;
 	zv_max_zsize = val;
@@ -819,7 +819,7 @@
 	if (!capable(CAP_SYS_ADMIN))
 		return -EPERM;
 
-	err = strict_strtoul(buf, 10, &val);
+	err = kstrtoul(buf, 10, &val);
 	if (err || (val == 0) || (val > (PAGE_SIZE / 8) * 7))
 		return -EINVAL;
 	zv_max_mean_zsize = val;
@@ -853,7 +853,7 @@
 	if (!capable(CAP_SYS_ADMIN))
 		return -EPERM;
 
-	err = strict_strtoul(buf, 10, &val);
+	err = kstrtoul(buf, 10, &val);
 	if (err || (val == 0) || (val > 150))
 		return -EINVAL;
 	zv_page_count_policy_percent = val;
diff --git a/drivers/staging/zram/zram_drv.c b/drivers/staging/zram/zram_drv.c
index 09de99f..2a2a92d 100644
--- a/drivers/staging/zram/zram_drv.c
+++ b/drivers/staging/zram/zram_drv.c
@@ -653,7 +653,8 @@
 		goto fail_no_table;
 	}
 
-	zram->compress_buffer = (void *)__get_free_pages(__GFP_ZERO, 1);
+	zram->compress_buffer =
+		(void *)__get_free_pages(GFP_KERNEL | __GFP_ZERO, 1);
 	if (!zram->compress_buffer) {
 		pr_err("Error allocating compressor buffer space\n");
 		ret = -ENOMEM;
diff --git a/drivers/staging/zram/zram_sysfs.c b/drivers/staging/zram/zram_sysfs.c
index 0ea8ed2..d521122 100644
--- a/drivers/staging/zram/zram_sysfs.c
+++ b/drivers/staging/zram/zram_sysfs.c
@@ -58,7 +58,7 @@
 	u64 disksize;
 	struct zram *zram = dev_to_zram(dev);
 
-	ret = strict_strtoull(buf, 10, &disksize);
+	ret = kstrtoull(buf, 10, &disksize);
 	if (ret)
 		return ret;
 
@@ -88,7 +88,7 @@
 		struct device_attribute *attr, const char *buf, size_t len)
 {
 	int ret;
-	unsigned long do_reset;
+	unsigned short do_reset;
 	struct zram *zram;
 	struct block_device *bdev;
 
@@ -99,7 +99,7 @@
 	if (bdev->bd_holders)
 		return -EBUSY;
 
-	ret = strict_strtoul(buf, 10, &do_reset);
+	ret = kstrtou16(buf, 10, &do_reset);
 	if (ret)
 		return ret;
 
diff --git a/drivers/video/omap2/omapfb/Kconfig b/drivers/video/omap2/omapfb/Kconfig
index 83d3fe7..4ea17dc 100644
--- a/drivers/video/omap2/omapfb/Kconfig
+++ b/drivers/video/omap2/omapfb/Kconfig
@@ -1,6 +1,6 @@
 menuconfig FB_OMAP2
         tristate "OMAP2+ frame buffer support"
-        depends on FB && OMAP2_DSS
+        depends on FB && OMAP2_DSS && !DRM_OMAP
 
 	select OMAP2_VRAM
 	select OMAP2_VRFB if ARCH_OMAP2 || ARCH_OMAP3
diff --git a/include/linux/hyperv.h b/include/linux/hyperv.h
index 12ec328..62b908e 100644
--- a/include/linux/hyperv.h
+++ b/include/linux/hyperv.h
@@ -35,7 +35,7 @@
 #include <linux/mod_devicetable.h>
 
 
-#define MAX_PAGE_BUFFER_COUNT				16
+#define MAX_PAGE_BUFFER_COUNT				18
 #define MAX_MULTIPAGE_BUFFER_COUNT			32 /* 128K */
 
 #pragma pack(push, 1)