Merge branch 'android-x86_64-fugu-3.10-nyc-mr1' into android-x86_64-fugu-3.10

September 2017.1

Bug: 63174165
Change-Id: Ie8d685edcbffbea72bcedcd02478b78017775b07
diff --git a/Documentation/networking/ip-sysctl.txt b/Documentation/networking/ip-sysctl.txt
index 45f824c..d1fc6a4 100644
--- a/Documentation/networking/ip-sysctl.txt
+++ b/Documentation/networking/ip-sysctl.txt
@@ -1159,11 +1159,20 @@
 	Functional default: enabled if accept_ra is enabled.
 			    disabled if accept_ra is disabled.
 
+accept_ra_rt_info_min_plen - INTEGER
+	Minimum prefix length of Route Information in RA.
+
+	Route Information w/ prefix smaller than this variable shall
+	be ignored.
+
+	Functional default: 0 if accept_ra_rtr_pref is enabled.
+			    -1 if accept_ra_rtr_pref is disabled.
+
 accept_ra_rt_info_max_plen - INTEGER
 	Maximum prefix length of Route Information in RA.
 
-	Route Information w/ prefix larger than or equal to this
-	variable shall be ignored.
+	Route Information w/ prefix larger than this variable shall
+	be ignored.
 
 	Functional default: 0 if accept_ra_rtr_pref is enabled.
 			    -1 if accept_ra_rtr_pref is disabled.
diff --git a/arch/x86/configs/fugu_defconfig b/arch/x86/configs/fugu_defconfig
index c5dc2333..acef58f 100644
--- a/arch/x86/configs/fugu_defconfig
+++ b/arch/x86/configs/fugu_defconfig
@@ -85,6 +85,8 @@
 CONFIG_NET=y
 CONFIG_PACKET=y
 CONFIG_UNIX=y
+CONFIG_XFRM_USER=y
+CONFIG_XFRM_STATISTICS=y
 CONFIG_NET_KEY=y
 CONFIG_NET_KEY_MIGRATE=y
 CONFIG_INET=y
@@ -411,6 +413,7 @@
 CONFIG_SERIAL_MFD_HSU_EXT=y
 CONFIG_SERIAL_MFD_HSU_EXT_CONSOLE=y
 CONFIG_ANDROID_BINDER_IPC=y
+CONFIG_ANDROID_BINDER_DEVICES="binder,hwbinder"
 # CONFIG_DMIID is not set
 CONFIG_EXT4_FS=y
 CONFIG_EXT4_FS_SECURITY=y
@@ -423,11 +426,11 @@
 CONFIG_TMPFS_POSIX_ACL=y
 CONFIG_SDCARD_FS=y
 CONFIG_SQUASHFS=y
-CONFIG_SQUASHFS_FILE_DIRECT=y
 CONFIG_SQUASHFS_DECOMP_MULTI_PERCPU=y
 CONFIG_SQUASHFS_XATTR=y
 # CONFIG_SQUASHFS_ZLIB is not set
 CONFIG_SQUASHFS_LZ4=y
+CONFIG_PSTORE_PMSG=y
 # CONFIG_NETWORK_FILESYSTEMS is not set
 CONFIG_NLS_DEFAULT="utf8"
 CONFIG_NLS_CODEPAGE_437=y
@@ -467,6 +470,7 @@
 CONFIG_SECURITY_PERF_EVENTS_RESTRICT=y
 CONFIG_SECURITY=y
 CONFIG_SECURITY_NETWORK=y
+CONFIG_LSM_MMAP_MIN_ADDR=32768
 CONFIG_SECURITY_SELINUX=y
 CONFIG_SECURITY_SELINUX_BOOTPARAM=y
 CONFIG_SECURITY_SELINUX_DISABLE=y
diff --git a/arch/x86/kernel/sys_x86_64.c b/arch/x86/kernel/sys_x86_64.c
index d050393..dcd2477 100644
--- a/arch/x86/kernel/sys_x86_64.c
+++ b/arch/x86/kernel/sys_x86_64.c
@@ -15,6 +15,7 @@
 #include <linux/random.h>
 #include <linux/uaccess.h>
 #include <linux/elf.h>
+#include <linux/security.h>
 
 #include <asm/ia32.h>
 #include <asm/syscalls.h>
@@ -120,13 +121,13 @@
 
 	find_start_end(flags, &begin, &end);
 
-	if (len > end)
+	if (len > end - mmap_min_addr)
 		return -ENOMEM;
 
 	if (addr) {
 		addr = PAGE_ALIGN(addr);
 		vma = find_vma(mm, addr);
-		if (end - len >= addr &&
+		if (end - len >= addr && addr >= mmap_min_addr &&
 		    (!vma || addr + len <= vm_start_gap(vma)))
 			return addr;
 	}
@@ -151,7 +152,7 @@
 	struct vm_unmapped_area_info info;
 
 	/* requested length too big for entire address space */
-	if (len > TASK_SIZE)
+	if (len > TASK_SIZE - mmap_min_addr)
 		return -ENOMEM;
 
 	if (flags & MAP_FIXED)
@@ -165,14 +166,14 @@
 	if (addr) {
 		addr = PAGE_ALIGN(addr);
 		vma = find_vma(mm, addr);
-		if (TASK_SIZE - len >= addr &&
+		if (TASK_SIZE - len >= addr && addr >= mmap_min_addr &&
 				(!vma || addr + len <= vm_start_gap(vma)))
 			return addr;
 	}
 
 	info.flags = VM_UNMAPPED_AREA_TOPDOWN;
 	info.length = len;
-	info.low_limit = PAGE_SIZE;
+	info.low_limit = max(PAGE_SIZE, mmap_min_addr);
 	info.high_limit = mm->mmap_base;
 	info.align_mask = filp ? get_align_mask() : 0;
 	info.align_offset = pgoff << PAGE_SHIFT;
diff --git a/build.config b/build.config
index e1127ee..9dd4426 100644
--- a/build.config
+++ b/build.config
@@ -4,6 +4,7 @@
 DEFCONFIG=fugu_defconfig
 EXTRA_CMDS=''
 KERNEL_DIR=private/x86_64-asus
+POST_DEFCONFIG_CMDS="check_defconfig"
 LINUX_GCC_CROSS_COMPILE_PREBUILTS_BIN=prebuilts/gcc/linux-x86/x86/x86_64-linux-android-4.8/bin
 FILES="
 arch/x86/boot/bzImage
diff --git a/drivers/android/Kconfig b/drivers/android/Kconfig
index bdfc6c6..a82fc02 100644
--- a/drivers/android/Kconfig
+++ b/drivers/android/Kconfig
@@ -19,6 +19,18 @@
 	  Android process, using Binder to identify, invoke and pass arguments
 	  between said processes.
 
+config ANDROID_BINDER_DEVICES
+	string "Android Binder devices"
+	depends on ANDROID_BINDER_IPC
+	default "binder"
+	---help---
+	  Default value for the binder.devices parameter.
+
+	  The binder.devices parameter is a comma-separated list of strings
+	  that specifies the names of the binder device nodes that will be
+	  created. Each binder device has its own context manager, and is
+	  therefore logically separated from the other devices.
+
 config ANDROID_BINDER_IPC_32BIT
 	bool
 	depends on !64BIT && ANDROID_BINDER_IPC
diff --git a/drivers/android/binder.c b/drivers/android/binder.c
index 4f9b583..23d0e68 100644
--- a/drivers/android/binder.c
+++ b/drivers/android/binder.c
@@ -50,14 +50,13 @@
 static DEFINE_MUTEX(binder_deferred_lock);
 static DEFINE_MUTEX(binder_mmap_lock);
 
+static HLIST_HEAD(binder_devices);
 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 kuid_t binder_context_mgr_uid = INVALID_UID;
 static int binder_last_id;
 static struct workqueue_struct *binder_deferred_workqueue;
 
@@ -116,6 +115,9 @@
 static bool binder_debug_no_lock;
 module_param_named(proc_no_lock, binder_debug_no_lock, bool, S_IWUSR | S_IRUGO);
 
+static char *binder_devices_param = CONFIG_ANDROID_BINDER_DEVICES;
+module_param_named(devices, binder_devices_param, charp, S_IRUGO);
+
 static DECLARE_WAIT_QUEUE_HEAD(binder_user_error_wait);
 static int binder_stop_on_user_error;
 
@@ -146,6 +148,17 @@
 			binder_stop_on_user_error = 2; \
 	} while (0)
 
+#define to_flat_binder_object(hdr) \
+	container_of(hdr, struct flat_binder_object, hdr)
+
+#define to_binder_fd_object(hdr) container_of(hdr, struct binder_fd_object, hdr)
+
+#define to_binder_buffer_object(hdr) \
+	container_of(hdr, struct binder_buffer_object, hdr)
+
+#define to_binder_fd_array_object(hdr) \
+	container_of(hdr, struct binder_fd_array_object, hdr)
+
 enum binder_stat_types {
 	BINDER_STAT_PROC,
 	BINDER_STAT_THREAD,
@@ -159,7 +172,7 @@
 
 struct binder_stats {
 	int br[_IOC_NR(BR_FAILED_REPLY) + 1];
-	int bc[_IOC_NR(BC_DEAD_BINDER_DONE) + 1];
+	int bc[_IOC_NR(BC_REPLY_SG) + 1];
 	int obj_created[BINDER_STAT_COUNT];
 	int obj_deleted[BINDER_STAT_COUNT];
 };
@@ -187,6 +200,7 @@
 	int to_node;
 	int data_size;
 	int offsets_size;
+	const char *context_name;
 };
 struct binder_transaction_log {
 	int next;
@@ -211,6 +225,18 @@
 	return e;
 }
 
+struct binder_context {
+	struct binder_node *binder_context_mgr_node;
+	kuid_t binder_context_mgr_uid;
+	const char *name;
+};
+
+struct binder_device {
+	struct hlist_node hlist;
+	struct miscdevice miscdev;
+	struct binder_context context;
+};
+
 struct binder_work {
 	struct list_head entry;
 	enum {
@@ -283,6 +309,7 @@
 	struct binder_node *target_node;
 	size_t data_size;
 	size_t offsets_size;
+	size_t extra_buffers_size;
 	uint8_t data[0];
 };
 
@@ -326,6 +353,7 @@
 	int ready_threads;
 	long default_priority;
 	struct dentry *debugfs_entry;
+	struct binder_context *context;
 };
 
 enum {
@@ -722,7 +750,9 @@
 
 static struct binder_buffer *binder_alloc_buf(struct binder_proc *proc,
 					      size_t data_size,
-					      size_t offsets_size, int is_async)
+					      size_t offsets_size,
+					      size_t extra_buffers_size,
+					      int is_async)
 {
 	struct rb_node *n = proc->free_buffers.rb_node;
 	struct binder_buffer *buffer;
@@ -730,7 +760,7 @@
 	struct rb_node *best_fit = NULL;
 	void *has_page_addr;
 	void *end_page_addr;
-	size_t size;
+	size_t size, data_offsets_size;
 
 	if (proc->vma == NULL) {
 		pr_err("%d: binder_alloc_buf, no vma\n",
@@ -738,15 +768,20 @@
 		return NULL;
 	}
 
-	size = ALIGN(data_size, sizeof(void *)) +
+	data_offsets_size = ALIGN(data_size, sizeof(void *)) +
 		ALIGN(offsets_size, sizeof(void *));
 
-	if (size < data_size || size < offsets_size) {
+	if (data_offsets_size < data_size || data_offsets_size < offsets_size) {
 		binder_user_error("%d: got transaction with invalid size %zd-%zd\n",
 				proc->pid, data_size, offsets_size);
 		return NULL;
 	}
-
+	size = data_offsets_size + ALIGN(extra_buffers_size, sizeof(void *));
+	if (size < data_offsets_size || size < extra_buffers_size) {
+		binder_user_error("%d: got transaction with invalid extra_buffers_size %zd\n",
+				  proc->pid, extra_buffers_size);
+		return NULL;
+	}
 	if (is_async &&
 	    proc->free_async_space < size + sizeof(struct binder_buffer)) {
 		binder_debug(BINDER_DEBUG_BUFFER_ALLOC,
@@ -815,6 +850,7 @@
 		      proc->pid, size, buffer);
 	buffer->data_size = data_size;
 	buffer->offsets_size = offsets_size;
+	buffer->extra_buffers_size = extra_buffers_size;
 	buffer->async_transaction = is_async;
 	if (is_async) {
 		proc->free_async_space -= size + sizeof(struct binder_buffer);
@@ -889,7 +925,8 @@
 	buffer_size = binder_buffer_size(proc, buffer);
 
 	size = ALIGN(buffer->data_size, sizeof(void *)) +
-		ALIGN(buffer->offsets_size, sizeof(void *));
+		ALIGN(buffer->offsets_size, sizeof(void *)) +
+		ALIGN(buffer->extra_buffers_size, sizeof(void *));
 
 	binder_debug(BINDER_DEBUG_BUFFER_ALLOC,
 		     "%d: binder_free_buf %pK size %zd buffer_size %zd\n",
@@ -1003,8 +1040,10 @@
 		if (internal) {
 			if (target_list == NULL &&
 			    node->internal_strong_refs == 0 &&
-			    !(node == binder_context_mgr_node &&
-			    node->has_strong_ref)) {
+			    !(node->proc &&
+			      node == node->proc->context->
+				      binder_context_mgr_node &&
+			      node->has_strong_ref)) {
 				pr_err("invalid inc strong node for %d\n",
 					node->debug_id);
 				return -EINVAL;
@@ -1105,6 +1144,7 @@
 	struct rb_node **p = &proc->refs_by_node.rb_node;
 	struct rb_node *parent = NULL;
 	struct binder_ref *ref, *new_ref;
+	struct binder_context *context = proc->context;
 
 	while (*p) {
 		parent = *p;
@@ -1127,7 +1167,7 @@
 	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;
+	new_ref->desc = (node == context->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)
@@ -1317,11 +1357,158 @@
 	}
 }
 
+/**
+ * binder_validate_object() - checks for a valid metadata object in a buffer.
+ * @buffer:	binder_buffer that we're parsing.
+ * @offset:	offset in the buffer at which to validate an object.
+ *
+ * Return:	If there's a valid metadata object at @offset in @buffer, the
+ *		size of that object. Otherwise, it returns zero.
+ */
+static size_t binder_validate_object(struct binder_buffer *buffer, u64 offset)
+{
+	/* Check if we can read a header first */
+	struct binder_object_header *hdr;
+	size_t object_size = 0;
+
+	if (offset > buffer->data_size - sizeof(*hdr) ||
+	    buffer->data_size < sizeof(*hdr) ||
+	    !IS_ALIGNED(offset, sizeof(u32)))
+		return 0;
+
+	/* Ok, now see if we can read a complete object. */
+	hdr = (struct binder_object_header *)(buffer->data + offset);
+	switch (hdr->type) {
+	case BINDER_TYPE_BINDER:
+	case BINDER_TYPE_WEAK_BINDER:
+	case BINDER_TYPE_HANDLE:
+	case BINDER_TYPE_WEAK_HANDLE:
+		object_size = sizeof(struct flat_binder_object);
+		break;
+	case BINDER_TYPE_FD:
+		object_size = sizeof(struct binder_fd_object);
+		break;
+	case BINDER_TYPE_PTR:
+		object_size = sizeof(struct binder_buffer_object);
+		break;
+	case BINDER_TYPE_FDA:
+		object_size = sizeof(struct binder_fd_array_object);
+		break;
+	default:
+		return 0;
+	}
+	if (offset <= buffer->data_size - object_size &&
+	    buffer->data_size >= object_size)
+		return object_size;
+	else
+		return 0;
+}
+
+/**
+ * binder_validate_ptr() - validates binder_buffer_object in a binder_buffer.
+ * @b:		binder_buffer containing the object
+ * @index:	index in offset array at which the binder_buffer_object is
+ *		located
+ * @start:	points to the start of the offset array
+ * @num_valid:	the number of valid offsets in the offset array
+ *
+ * Return:	If @index is within the valid range of the offset array
+ *		described by @start and @num_valid, and if there's a valid
+ *		binder_buffer_object at the offset found in index @index
+ *		of the offset array, that object is returned. Otherwise,
+ *		%NULL is returned.
+ *		Note that the offset found in index @index itself is not
+ *		verified; this function assumes that @num_valid elements
+ *		from @start were previously verified to have valid offsets.
+ */
+static struct binder_buffer_object *binder_validate_ptr(struct binder_buffer *b,
+							binder_size_t index,
+							binder_size_t *start,
+							binder_size_t num_valid)
+{
+	struct binder_buffer_object *buffer_obj;
+	binder_size_t *offp;
+
+	if (index >= num_valid)
+		return NULL;
+
+	offp = start + index;
+	buffer_obj = (struct binder_buffer_object *)(b->data + *offp);
+	if (buffer_obj->hdr.type != BINDER_TYPE_PTR)
+		return NULL;
+
+	return buffer_obj;
+}
+
+/**
+ * binder_validate_fixup() - validates pointer/fd fixups happen in order.
+ * @b:			transaction buffer
+ * @objects_start	start of objects buffer
+ * @buffer:		binder_buffer_object in which to fix up
+ * @offset:		start offset in @buffer to fix up
+ * @last_obj:		last binder_buffer_object that we fixed up in
+ * @last_min_offset:	minimum fixup offset in @last_obj
+ *
+ * Return:		%true if a fixup in buffer @buffer at offset @offset is
+ *			allowed.
+ *
+ * For safety reasons, we only allow fixups inside a buffer to happen
+ * at increasing offsets; additionally, we only allow fixup on the last
+ * buffer object that was verified, or one of its parents.
+ *
+ * Example of what is allowed:
+ *
+ * A
+ *   B (parent = A, offset = 0)
+ *   C (parent = A, offset = 16)
+ *     D (parent = C, offset = 0)
+ *   E (parent = A, offset = 32) // min_offset is 16 (C.parent_offset)
+ *
+ * Examples of what is not allowed:
+ *
+ * Decreasing offsets within the same parent:
+ * A
+ *   C (parent = A, offset = 16)
+ *   B (parent = A, offset = 0) // decreasing offset within A
+ *
+ * Referring to a parent that wasn't the last object or any of its parents:
+ * A
+ *   B (parent = A, offset = 0)
+ *   C (parent = A, offset = 0)
+ *   C (parent = A, offset = 16)
+ *     D (parent = B, offset = 0) // B is not A or any of A's parents
+ */
+static bool binder_validate_fixup(struct binder_buffer *b,
+				  binder_size_t *objects_start,
+				  struct binder_buffer_object *buffer,
+				  binder_size_t fixup_offset,
+				  struct binder_buffer_object *last_obj,
+				  binder_size_t last_min_offset)
+{
+	if (!last_obj) {
+		/* Nothing to fix up in */
+		return false;
+	}
+
+	while (last_obj != buffer) {
+		/*
+		 * Safe to retrieve the parent of last_obj, since it
+		 * was already previously verified by the driver.
+		 */
+		if ((last_obj->flags & BINDER_BUFFER_FLAG_HAS_PARENT) == 0)
+			return false;
+		last_min_offset = last_obj->parent_offset + sizeof(uintptr_t);
+		last_obj = (struct binder_buffer_object *)
+			(b->data + *(objects_start + last_obj->parent));
+	}
+	return (fixup_offset >= last_min_offset);
+}
+
 static void binder_transaction_buffer_release(struct binder_proc *proc,
 					      struct binder_buffer *buffer,
 					      binder_size_t *failed_at)
 {
-	binder_size_t *offp, *off_end;
+	binder_size_t *offp, *off_start, *off_end;
 	int debug_id = buffer->debug_id;
 
 	binder_debug(BINDER_DEBUG_TRANSACTION,
@@ -1332,28 +1519,30 @@
 	if (buffer->target_node)
 		binder_dec_node(buffer->target_node, 1, 0);
 
-	offp = (binder_size_t *)(buffer->data +
-				 ALIGN(buffer->data_size, sizeof(void *)));
+	off_start = (binder_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;
+		off_end = (void *)off_start + buffer->offsets_size;
+	for (offp = off_start; offp < off_end; offp++) {
+		struct binder_object_header *hdr;
+		size_t object_size = binder_validate_object(buffer, *offp);
 
-		if (*offp > buffer->data_size - sizeof(*fp) ||
-		    buffer->data_size < sizeof(*fp) ||
-		    !IS_ALIGNED(*offp, sizeof(u32))) {
-			pr_err("transaction release %d bad offset %lld, size %zd\n",
+		if (object_size == 0) {
+			pr_err("transaction release %d bad object at offset %lld, size %zd\n",
 			       debug_id, (u64)*offp, buffer->data_size);
 			continue;
 		}
-		fp = (struct flat_binder_object *)(buffer->data + *offp);
-		switch (fp->type) {
+		hdr = (struct binder_object_header *)(buffer->data + *offp);
+		switch (hdr->type) {
 		case BINDER_TYPE_BINDER:
 		case BINDER_TYPE_WEAK_BINDER: {
-			struct binder_node *node = binder_get_node(proc, fp->binder);
+			struct flat_binder_object *fp;
+			struct binder_node *node;
 
+			fp = to_flat_binder_object(hdr);
+			node = binder_get_node(proc, fp->binder);
 			if (node == NULL) {
 				pr_err("transaction release %d bad node %016llx\n",
 				       debug_id, (u64)fp->binder);
@@ -1362,13 +1551,17 @@
 			binder_debug(BINDER_DEBUG_TRANSACTION,
 				     "        node %d u%016llx\n",
 				     node->debug_id, (u64)node->ptr);
-			binder_dec_node(node, fp->type == BINDER_TYPE_BINDER, 0);
+			binder_dec_node(node, hdr->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,
-						fp->type == BINDER_TYPE_HANDLE);
+			struct flat_binder_object *fp;
+			struct binder_ref *ref;
 
+			fp = to_flat_binder_object(hdr);
+			ref = binder_get_ref(proc, fp->handle,
+					     hdr->type == BINDER_TYPE_HANDLE);
 			if (ref == NULL) {
 				pr_err("transaction release %d bad handle %d\n",
 				 debug_id, fp->handle);
@@ -1377,32 +1570,348 @@
 			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);
+			binder_dec_ref(&ref, hdr->type == BINDER_TYPE_HANDLE);
 		} break;
 
-		case BINDER_TYPE_FD:
-			binder_debug(BINDER_DEBUG_TRANSACTION,
-				     "        fd %d\n", fp->handle);
-			if (failed_at)
-				task_close_fd(proc, fp->handle);
-			break;
+		case BINDER_TYPE_FD: {
+			struct binder_fd_object *fp = to_binder_fd_object(hdr);
 
+			binder_debug(BINDER_DEBUG_TRANSACTION,
+				     "        fd %d\n", fp->fd);
+			if (failed_at)
+				task_close_fd(proc, fp->fd);
+		} break;
+		case BINDER_TYPE_PTR:
+			/*
+			 * Nothing to do here, this will get cleaned up when the
+			 * transaction buffer gets freed
+			 */
+			break;
+		case BINDER_TYPE_FDA: {
+			struct binder_fd_array_object *fda;
+			struct binder_buffer_object *parent;
+			uintptr_t parent_buffer;
+			u32 *fd_array;
+			size_t fd_index;
+			binder_size_t fd_buf_size;
+
+			fda = to_binder_fd_array_object(hdr);
+			parent = binder_validate_ptr(buffer, fda->parent,
+						     off_start,
+						     offp - off_start);
+			if (!parent) {
+				pr_err("transaction release %d bad parent offset",
+				       debug_id);
+				continue;
+			}
+			/*
+			 * Since the parent was already fixed up, convert it
+			 * back to kernel address space to access it
+			 */
+			parent_buffer = parent->buffer -
+				proc->user_buffer_offset;
+
+			fd_buf_size = sizeof(u32) * fda->num_fds;
+			if (fda->num_fds >= SIZE_MAX / sizeof(u32)) {
+				pr_err("transaction release %d invalid number of fds (%lld)\n",
+				       debug_id, (u64)fda->num_fds);
+				continue;
+			}
+			if (fd_buf_size > parent->length ||
+			    fda->parent_offset > parent->length - fd_buf_size) {
+				/* No space for all file descriptors here. */
+				pr_err("transaction release %d not enough space for %lld fds in buffer\n",
+				       debug_id, (u64)fda->num_fds);
+				continue;
+			}
+			fd_array = (u32 *)(parent_buffer + fda->parent_offset);
+			for (fd_index = 0; fd_index < fda->num_fds; fd_index++)
+				task_close_fd(proc, fd_array[fd_index]);
+		} break;
 		default:
 			pr_err("transaction release %d bad object type %x\n",
-				debug_id, fp->type);
+				debug_id, hdr->type);
 			break;
 		}
 	}
 }
 
+static int binder_translate_binder(struct flat_binder_object *fp,
+				   struct binder_transaction *t,
+				   struct binder_thread *thread)
+{
+	struct binder_node *node;
+	struct binder_ref *ref;
+	struct binder_proc *proc = thread->proc;
+	struct binder_proc *target_proc = t->to_proc;
+
+	node = binder_get_node(proc, fp->binder);
+	if (!node) {
+		node = binder_new_node(proc, fp->binder, fp->cookie);
+		if (!node)
+			return -ENOMEM;
+
+		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("%d:%d sending u%016llx node %d, cookie mismatch %016llx != %016llx\n",
+				  proc->pid, thread->pid, (u64)fp->binder,
+				  node->debug_id, (u64)fp->cookie,
+				  (u64)node->cookie);
+		return -EINVAL;
+	}
+	if (security_binder_transfer_binder(proc->tsk, target_proc->tsk))
+		return -EPERM;
+
+	ref = binder_get_ref_for_node(target_proc, node);
+	if (!ref)
+		return -EINVAL;
+
+	if (fp->hdr.type == BINDER_TYPE_BINDER)
+		fp->hdr.type = BINDER_TYPE_HANDLE;
+	else
+		fp->hdr.type = BINDER_TYPE_WEAK_HANDLE;
+	fp->binder = 0;
+	fp->handle = ref->desc;
+	fp->cookie = 0;
+	binder_inc_ref(ref, fp->hdr.type == BINDER_TYPE_HANDLE, &thread->todo);
+
+	trace_binder_transaction_node_to_ref(t, node, ref);
+	binder_debug(BINDER_DEBUG_TRANSACTION,
+		     "        node %d u%016llx -> ref %d desc %d\n",
+		     node->debug_id, (u64)node->ptr,
+		     ref->debug_id, ref->desc);
+
+	return 0;
+}
+
+static int binder_translate_handle(struct flat_binder_object *fp,
+				   struct binder_transaction *t,
+				   struct binder_thread *thread)
+{
+	struct binder_ref *ref;
+	struct binder_proc *proc = thread->proc;
+	struct binder_proc *target_proc = t->to_proc;
+
+	ref = binder_get_ref(proc, fp->handle,
+			     fp->hdr.type == BINDER_TYPE_HANDLE);
+	if (!ref) {
+		binder_user_error("%d:%d got transaction with invalid handle, %d\n",
+				  proc->pid, thread->pid, fp->handle);
+		return -EINVAL;
+	}
+	if (security_binder_transfer_binder(proc->tsk, target_proc->tsk))
+		return -EPERM;
+
+	if (ref->node->proc == target_proc) {
+		if (fp->hdr.type == BINDER_TYPE_HANDLE)
+			fp->hdr.type = BINDER_TYPE_BINDER;
+		else
+			fp->hdr.type = BINDER_TYPE_WEAK_BINDER;
+		fp->binder = ref->node->ptr;
+		fp->cookie = ref->node->cookie;
+		binder_inc_node(ref->node, fp->hdr.type == BINDER_TYPE_BINDER,
+				0, NULL);
+		trace_binder_transaction_ref_to_node(t, ref);
+		binder_debug(BINDER_DEBUG_TRANSACTION,
+			     "        ref %d desc %d -> node %d u%016llx\n",
+			     ref->debug_id, ref->desc, ref->node->debug_id,
+			     (u64)ref->node->ptr);
+	} else {
+		struct binder_ref *new_ref;
+
+		new_ref = binder_get_ref_for_node(target_proc, ref->node);
+		if (!new_ref)
+			return -EINVAL;
+
+		fp->binder = 0;
+		fp->handle = new_ref->desc;
+		fp->cookie = 0;
+		binder_inc_ref(new_ref, fp->hdr.type == BINDER_TYPE_HANDLE,
+			       NULL);
+		trace_binder_transaction_ref_to_ref(t, ref, new_ref);
+		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);
+	}
+	return 0;
+}
+
+static int binder_translate_fd(int fd,
+			       struct binder_transaction *t,
+			       struct binder_thread *thread,
+			       struct binder_transaction *in_reply_to)
+{
+	struct binder_proc *proc = thread->proc;
+	struct binder_proc *target_proc = t->to_proc;
+	int target_fd;
+	struct file *file;
+	int ret;
+	bool target_allows_fd;
+
+	if (in_reply_to)
+		target_allows_fd = !!(in_reply_to->flags & TF_ACCEPT_FDS);
+	else
+		target_allows_fd = t->buffer->target_node->accept_fds;
+	if (!target_allows_fd) {
+		binder_user_error("%d:%d got %s with fd, %d, but target does not allow fds\n",
+				  proc->pid, thread->pid,
+				  in_reply_to ? "reply" : "transaction",
+				  fd);
+		ret = -EPERM;
+		goto err_fd_not_accepted;
+	}
+
+	file = fget(fd);
+	if (!file) {
+		binder_user_error("%d:%d got transaction with invalid fd, %d\n",
+				  proc->pid, thread->pid, fd);
+		ret = -EBADF;
+		goto err_fget;
+	}
+	ret = security_binder_transfer_file(proc->tsk, target_proc->tsk, file);
+	if (ret < 0) {
+		ret = -EPERM;
+		goto err_security;
+	}
+
+	target_fd = task_get_unused_fd_flags(target_proc, O_CLOEXEC);
+	if (target_fd < 0) {
+		ret = -ENOMEM;
+		goto err_get_unused_fd;
+	}
+	task_fd_install(target_proc, target_fd, file);
+	trace_binder_transaction_fd(t, fd, target_fd);
+	binder_debug(BINDER_DEBUG_TRANSACTION, "        fd %d -> %d\n",
+		     fd, target_fd);
+
+	return target_fd;
+
+err_get_unused_fd:
+err_security:
+	fput(file);
+err_fget:
+err_fd_not_accepted:
+	return ret;
+}
+
+static int binder_translate_fd_array(struct binder_fd_array_object *fda,
+				     struct binder_buffer_object *parent,
+				     struct binder_transaction *t,
+				     struct binder_thread *thread,
+				     struct binder_transaction *in_reply_to)
+{
+	binder_size_t fdi, fd_buf_size, num_installed_fds;
+	int target_fd;
+	uintptr_t parent_buffer;
+	u32 *fd_array;
+	struct binder_proc *proc = thread->proc;
+	struct binder_proc *target_proc = t->to_proc;
+
+	fd_buf_size = sizeof(u32) * fda->num_fds;
+	if (fda->num_fds >= SIZE_MAX / sizeof(u32)) {
+		binder_user_error("%d:%d got transaction with invalid number of fds (%lld)\n",
+				  proc->pid, thread->pid, (u64)fda->num_fds);
+		return -EINVAL;
+	}
+	if (fd_buf_size > parent->length ||
+	    fda->parent_offset > parent->length - fd_buf_size) {
+		/* No space for all file descriptors here. */
+		binder_user_error("%d:%d not enough space to store %lld fds in buffer\n",
+				  proc->pid, thread->pid, (u64)fda->num_fds);
+		return -EINVAL;
+	}
+	/*
+	 * Since the parent was already fixed up, convert it
+	 * back to the kernel address space to access it
+	 */
+	parent_buffer = parent->buffer - target_proc->user_buffer_offset;
+	fd_array = (u32 *)(parent_buffer + fda->parent_offset);
+	if (!IS_ALIGNED((unsigned long)fd_array, sizeof(u32))) {
+		binder_user_error("%d:%d parent offset not aligned correctly.\n",
+				  proc->pid, thread->pid);
+		return -EINVAL;
+	}
+	for (fdi = 0; fdi < fda->num_fds; fdi++) {
+		target_fd = binder_translate_fd(fd_array[fdi], t, thread,
+						in_reply_to);
+		if (target_fd < 0)
+			goto err_translate_fd_failed;
+		fd_array[fdi] = target_fd;
+	}
+	return 0;
+
+err_translate_fd_failed:
+	/*
+	 * Failed to allocate fd or security error, free fds
+	 * installed so far.
+	 */
+	num_installed_fds = fdi;
+	for (fdi = 0; fdi < num_installed_fds; fdi++)
+		task_close_fd(target_proc, fd_array[fdi]);
+	return target_fd;
+}
+
+static int binder_fixup_parent(struct binder_transaction *t,
+			       struct binder_thread *thread,
+			       struct binder_buffer_object *bp,
+			       binder_size_t *off_start,
+			       binder_size_t num_valid,
+			       struct binder_buffer_object *last_fixup_obj,
+			       binder_size_t last_fixup_min_off)
+{
+	struct binder_buffer_object *parent;
+	u8 *parent_buffer;
+	struct binder_buffer *b = t->buffer;
+	struct binder_proc *proc = thread->proc;
+	struct binder_proc *target_proc = t->to_proc;
+
+	if (!(bp->flags & BINDER_BUFFER_FLAG_HAS_PARENT))
+		return 0;
+
+	parent = binder_validate_ptr(b, bp->parent, off_start, num_valid);
+	if (!parent) {
+		binder_user_error("%d:%d got transaction with invalid parent offset or type\n",
+				  proc->pid, thread->pid);
+		return -EINVAL;
+	}
+
+	if (!binder_validate_fixup(b, off_start,
+				   parent, bp->parent_offset,
+				   last_fixup_obj,
+				   last_fixup_min_off)) {
+		binder_user_error("%d:%d got transaction with out-of-order buffer fixup\n",
+				  proc->pid, thread->pid);
+		return -EINVAL;
+	}
+
+	if (parent->length < sizeof(binder_uintptr_t) ||
+	    bp->parent_offset > parent->length - sizeof(binder_uintptr_t)) {
+		/* No space for a pointer here! */
+		binder_user_error("%d:%d got transaction with invalid parent offset\n",
+				  proc->pid, thread->pid);
+		return -EINVAL;
+	}
+	parent_buffer = (u8 *)(parent->buffer -
+			       target_proc->user_buffer_offset);
+	*(binder_uintptr_t *)(parent_buffer + bp->parent_offset) = bp->buffer;
+
+	return 0;
+}
+
 static void binder_transaction(struct binder_proc *proc,
 			       struct binder_thread *thread,
-			       struct binder_transaction_data *tr, int reply)
+			       struct binder_transaction_data *tr, int reply,
+			       binder_size_t extra_buffers_size)
 {
+	int ret;
 	struct binder_transaction *t;
 	struct binder_work *tcomplete;
-	binder_size_t *offp, *off_end;
+	binder_size_t *offp, *off_end, *off_start;
 	binder_size_t off_min;
+	u8 *sg_bufp, *sg_buf_end;
 	struct binder_proc *target_proc;
 	struct binder_thread *target_thread = NULL;
 	struct binder_node *target_node = NULL;
@@ -1411,6 +1920,9 @@
 	struct binder_transaction *in_reply_to = NULL;
 	struct binder_transaction_log_entry *e;
 	uint32_t return_error;
+	struct binder_buffer_object *last_fixup_obj = NULL;
+	binder_size_t last_fixup_min_off = 0;
+	struct binder_context *context = proc->context;
 
 	e = binder_transaction_log_add(&binder_transaction_log);
 	e->call_type = reply ? 2 : !!(tr->flags & TF_ONE_WAY);
@@ -1419,6 +1931,7 @@
 	e->target_handle = tr->target.handle;
 	e->data_size = tr->data_size;
 	e->offsets_size = tr->offsets_size;
+	e->context_name = proc->context->name;
 
 	if (reply) {
 		in_reply_to = thread->transaction_stack;
@@ -1471,7 +1984,7 @@
 			}
 			target_node = ref->node;
 		} else {
-			target_node = binder_context_mgr_node;
+			target_node = context->binder_context_mgr_node;
 			if (target_node == NULL) {
 				return_error = BR_DEAD_REPLY;
 				goto err_no_context_mgr_node;
@@ -1537,20 +2050,22 @@
 
 	if (reply)
 		binder_debug(BINDER_DEBUG_TRANSACTION,
-			     "%d:%d BC_REPLY %d -> %d:%d, data %016llx-%016llx size %lld-%lld\n",
+			     "%d:%d BC_REPLY %d -> %d:%d, data %016llx-%016llx size %lld-%lld-%lld\n",
 			     proc->pid, thread->pid, t->debug_id,
 			     target_proc->pid, target_thread->pid,
 			     (u64)tr->data.ptr.buffer,
 			     (u64)tr->data.ptr.offsets,
-			     (u64)tr->data_size, (u64)tr->offsets_size);
+			     (u64)tr->data_size, (u64)tr->offsets_size,
+			     (u64)extra_buffers_size);
 	else
 		binder_debug(BINDER_DEBUG_TRANSACTION,
-			     "%d:%d BC_TRANSACTION %d -> %d - node %d, data %016llx-%016llx size %lld-%lld\n",
+			     "%d:%d BC_TRANSACTION %d -> %d - node %d, data %016llx-%016llx size %lld-%lld-%lld\n",
 			     proc->pid, thread->pid, t->debug_id,
 			     target_proc->pid, target_node->debug_id,
 			     (u64)tr->data.ptr.buffer,
 			     (u64)tr->data.ptr.offsets,
-			     (u64)tr->data_size, (u64)tr->offsets_size);
+			     (u64)tr->data_size, (u64)tr->offsets_size,
+			     (u64)extra_buffers_size);
 
 	if (!reply && !(tr->flags & TF_ONE_WAY))
 		t->from = thread;
@@ -1566,7 +2081,8 @@
 	trace_binder_transaction(reply, t, target_node);
 
 	t->buffer = binder_alloc_buf(target_proc, tr->data_size,
-		tr->offsets_size, !reply && (t->flags & TF_ONE_WAY));
+		tr->offsets_size, extra_buffers_size,
+		!reply && (t->flags & TF_ONE_WAY));
 	if (t->buffer == NULL) {
 		return_error = BR_FAILED_REPLY;
 		goto err_binder_alloc_buf_failed;
@@ -1579,8 +2095,9 @@
 	if (target_node)
 		binder_inc_node(target_node, 1, 0, NULL);
 
-	offp = (binder_size_t *)(t->buffer->data +
-				 ALIGN(tr->data_size, sizeof(void *)));
+	off_start = (binder_size_t *)(t->buffer->data +
+				      ALIGN(tr->data_size, sizeof(void *)));
+	offp = off_start;
 
 	if (copy_from_user_preempt_disabled(t->buffer->data, (const void __user *)(uintptr_t)
 			   tr->data.ptr.buffer, tr->data_size)) {
@@ -1602,171 +2119,139 @@
 		return_error = BR_FAILED_REPLY;
 		goto err_bad_offset;
 	}
-	off_end = (void *)offp + tr->offsets_size;
+	if (!IS_ALIGNED(extra_buffers_size, sizeof(u64))) {
+		binder_user_error("%d:%d got transaction with unaligned buffers size, %lld\n",
+				  proc->pid, thread->pid,
+				  extra_buffers_size);
+		return_error = BR_FAILED_REPLY;
+		goto err_bad_offset;
+	}
+	off_end = (void *)off_start + tr->offsets_size;
+	sg_bufp = (u8 *)(PTR_ALIGN(off_end, sizeof(void *)));
+	sg_buf_end = sg_bufp + extra_buffers_size;
 	off_min = 0;
 	for (; offp < off_end; offp++) {
-		struct flat_binder_object *fp;
+		struct binder_object_header *hdr;
+		size_t object_size = binder_validate_object(t->buffer, *offp);
 
-		if (*offp > t->buffer->data_size - sizeof(*fp) ||
-		    *offp < off_min ||
-		    t->buffer->data_size < sizeof(*fp) ||
-		    !IS_ALIGNED(*offp, sizeof(u32))) {
-			binder_user_error("%d:%d got transaction with invalid offset, %lld (min %lld, max %lld)\n",
+		if (object_size == 0 || *offp < off_min) {
+			binder_user_error("%d:%d got transaction with invalid offset (%lld, min %lld max %lld) or object.\n",
 					  proc->pid, thread->pid, (u64)*offp,
 					  (u64)off_min,
-					  (u64)(t->buffer->data_size -
-					  sizeof(*fp)));
+					  (u64)t->buffer->data_size);
 			return_error = BR_FAILED_REPLY;
 			goto err_bad_offset;
 		}
-		fp = (struct flat_binder_object *)(t->buffer->data + *offp);
-		off_min = *offp + sizeof(struct flat_binder_object);
-		switch (fp->type) {
+
+		hdr = (struct binder_object_header *)(t->buffer->data + *offp);
+		off_min = *offp + object_size;
+		switch (hdr->type) {
 		case BINDER_TYPE_BINDER:
 		case BINDER_TYPE_WEAK_BINDER: {
-			struct binder_ref *ref;
-			struct binder_node *node = binder_get_node(proc, fp->binder);
+			struct flat_binder_object *fp;
 
-			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("%d:%d sending u%016llx node %d, cookie mismatch %016llx != %016llx\n",
-					proc->pid, thread->pid,
-					(u64)fp->binder, node->debug_id,
-					(u64)fp->cookie, (u64)node->cookie);
+			fp = to_flat_binder_object(hdr);
+			ret = binder_translate_binder(fp, t, thread);
+			if (ret < 0) {
 				return_error = BR_FAILED_REPLY;
-				goto err_binder_get_ref_for_node_failed;
+				goto err_translate_failed;
 			}
-			if (security_binder_transfer_binder(proc->tsk, target_proc->tsk)) {
-				return_error = BR_FAILED_REPLY;
-				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->binder = 0;
-			fp->handle = ref->desc;
-			fp->cookie = 0;
-			binder_inc_ref(ref, fp->type == BINDER_TYPE_HANDLE,
-				       &thread->todo);
-
-			trace_binder_transaction_node_to_ref(t, node, ref);
-			binder_debug(BINDER_DEBUG_TRANSACTION,
-				     "        node %d u%016llx -> ref %d desc %d\n",
-				     node->debug_id, (u64)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,
-						fp->type == BINDER_TYPE_HANDLE);
+			struct flat_binder_object *fp;
 
-			if (ref == NULL) {
-				binder_user_error("%d:%d got transaction with invalid handle, %d\n",
-						proc->pid,
-						thread->pid, fp->handle);
+			fp = to_flat_binder_object(hdr);
+			ret = binder_translate_handle(fp, t, thread);
+			if (ret < 0) {
 				return_error = BR_FAILED_REPLY;
-				goto err_binder_get_ref_failed;
-			}
-			if (security_binder_transfer_binder(proc->tsk, target_proc->tsk)) {
-				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);
-				trace_binder_transaction_ref_to_node(t, ref);
-				binder_debug(BINDER_DEBUG_TRANSACTION,
-					     "        ref %d desc %d -> node %d u%016llx\n",
-					     ref->debug_id, ref->desc, ref->node->debug_id,
-					     (u64)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->binder = 0;
-				fp->handle = new_ref->desc;
-				fp->cookie = 0;
-				binder_inc_ref(new_ref, fp->type == BINDER_TYPE_HANDLE, NULL);
-				trace_binder_transaction_ref_to_ref(t, ref,
-								    new_ref);
-				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);
+				goto err_translate_failed;
 			}
 		} break;
 
 		case BINDER_TYPE_FD: {
-			int target_fd;
-			struct file *file;
+			struct binder_fd_object *fp = to_binder_fd_object(hdr);
+			int target_fd = binder_translate_fd(fp->fd, t, thread,
+							    in_reply_to);
 
-			if (reply) {
-				if (!(in_reply_to->flags & TF_ACCEPT_FDS)) {
-					binder_user_error("%d:%d got reply with fd, %d, 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("%d:%d got transaction with fd, %d, 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("%d:%d got transaction with invalid fd, %d\n",
-					proc->pid, thread->pid, fp->handle);
-				return_error = BR_FAILED_REPLY;
-				goto err_fget_failed;
-			}
-			if (security_binder_transfer_file(proc->tsk, target_proc->tsk, file) < 0) {
-				fput(file);
-				return_error = BR_FAILED_REPLY;
-				goto err_get_unused_fd_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;
+				goto err_translate_failed;
 			}
-			task_fd_install(target_proc, target_fd, file);
-			trace_binder_transaction_fd(t, fp->handle, target_fd);
-			binder_debug(BINDER_DEBUG_TRANSACTION,
-				     "        fd %d -> %d\n", fp->handle, target_fd);
-			/* TODO: fput? */
-			fp->binder = 0;
-			fp->handle = target_fd;
+			fp->pad_binder = 0;
+			fp->fd = target_fd;
 		} break;
+		case BINDER_TYPE_FDA: {
+			struct binder_fd_array_object *fda =
+				to_binder_fd_array_object(hdr);
+			struct binder_buffer_object *parent =
+				binder_validate_ptr(t->buffer, fda->parent,
+						    off_start,
+						    offp - off_start);
+			if (!parent) {
+				binder_user_error("%d:%d got transaction with invalid parent offset or type\n",
+						  proc->pid, thread->pid);
+				return_error = BR_FAILED_REPLY;
+				goto err_bad_parent;
+			}
+			if (!binder_validate_fixup(t->buffer, off_start,
+						   parent, fda->parent_offset,
+						   last_fixup_obj,
+						   last_fixup_min_off)) {
+				binder_user_error("%d:%d got transaction with out-of-order buffer fixup\n",
+						  proc->pid, thread->pid);
+				return_error = BR_FAILED_REPLY;
+				goto err_bad_parent;
+			}
+			ret = binder_translate_fd_array(fda, parent, t, thread,
+							in_reply_to);
+			if (ret < 0) {
+				return_error = BR_FAILED_REPLY;
+				goto err_translate_failed;
+			}
+			last_fixup_obj = parent;
+			last_fixup_min_off =
+				fda->parent_offset + sizeof(u32) * fda->num_fds;
+		} break;
+		case BINDER_TYPE_PTR: {
+			struct binder_buffer_object *bp =
+				to_binder_buffer_object(hdr);
+			size_t buf_left = sg_buf_end - sg_bufp;
 
+			if (bp->length > buf_left) {
+				binder_user_error("%d:%d got transaction with too large buffer\n",
+						  proc->pid, thread->pid);
+				return_error = BR_FAILED_REPLY;
+				goto err_bad_offset;
+			}
+			if (copy_from_user_preempt_disabled(
+					sg_bufp,
+					(const void __user *)(uintptr_t)
+					bp->buffer, bp->length)) {
+				binder_user_error("%d:%d got transaction with invalid offsets ptr\n",
+						  proc->pid, thread->pid);
+				return_error = BR_FAILED_REPLY;
+				goto err_copy_data_failed;
+			}
+			/* Fixup buffer pointer to target proc address space */
+			bp->buffer = (uintptr_t)sg_bufp +
+				target_proc->user_buffer_offset;
+			sg_bufp += ALIGN(bp->length, sizeof(u64));
+
+			ret = binder_fixup_parent(t, thread, bp, off_start,
+						  offp - off_start,
+						  last_fixup_obj,
+						  last_fixup_min_off);
+			if (ret < 0) {
+				return_error = BR_FAILED_REPLY;
+				goto err_translate_failed;
+			}
+			last_fixup_obj = bp;
+			last_fixup_min_off = 0;
+		} break;
 		default:
 			binder_user_error("%d:%d got transaction with invalid object type, %x\n",
-				proc->pid, thread->pid, fp->type);
+				proc->pid, thread->pid, hdr->type);
 			return_error = BR_FAILED_REPLY;
 			goto err_bad_object_type;
 		}
@@ -1804,14 +2289,10 @@
 	}
 	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_translate_failed:
 err_bad_object_type:
 err_bad_offset:
+err_bad_parent:
 err_copy_data_failed:
 	trace_binder_transaction_failed_buffer_release(t->buffer);
 	binder_transaction_buffer_release(target_proc, t->buffer, offp);
@@ -1855,6 +2336,7 @@
 			binder_size_t *consumed)
 {
 	uint32_t cmd;
+	struct binder_context *context = proc->context;
 	void __user *buffer = (void __user *)(uintptr_t)binder_buffer;
 	void __user *ptr = buffer + *consumed;
 	void __user *end = buffer + size;
@@ -1881,10 +2363,10 @@
 			if (get_user_preempt_disabled(target, (uint32_t __user *)ptr))
 				return -EFAULT;
 			ptr += sizeof(uint32_t);
-			if (target == 0 && binder_context_mgr_node &&
+			if (target == 0 && context->binder_context_mgr_node &&
 			    (cmd == BC_INCREFS || cmd == BC_ACQUIRE)) {
 				ref = binder_get_ref_for_node(proc,
-					       binder_context_mgr_node);
+					context->binder_context_mgr_node);
 				if (ref->desc != target) {
 					binder_user_error("%d:%d tried to acquire reference to desc 0, got %d instead\n",
 						proc->pid, thread->pid,
@@ -2036,6 +2518,18 @@
 			break;
 		}
 
+		case BC_TRANSACTION_SG:
+		case BC_REPLY_SG: {
+			struct binder_transaction_data_sg tr;
+
+			if (copy_from_user_preempt_disabled(&tr, ptr,
+							    sizeof(tr)))
+				return -EFAULT;
+			ptr += sizeof(tr);
+			binder_transaction(proc, thread, &tr.transaction_data,
+					   cmd == BC_REPLY_SG, tr.buffers_size);
+			break;
+		}
 		case BC_TRANSACTION:
 		case BC_REPLY: {
 			struct binder_transaction_data tr;
@@ -2043,7 +2537,8 @@
 			if (copy_from_user_preempt_disabled(&tr, ptr, sizeof(tr)))
 				return -EFAULT;
 			ptr += sizeof(tr);
-			binder_transaction(proc, thread, &tr, cmd == BC_REPLY);
+			binder_transaction(proc, thread, &tr,
+					   cmd == BC_REPLY, 0);
 			break;
 		}
 
@@ -2798,9 +3293,11 @@
 {
 	int ret = 0;
 	struct binder_proc *proc = filp->private_data;
+	struct binder_context *context = proc->context;
+
 	kuid_t curr_euid = current_euid();
 
-	if (binder_context_mgr_node != NULL) {
+	if (context->binder_context_mgr_node) {
 		pr_err("BINDER_SET_CONTEXT_MGR already set\n");
 		ret = -EBUSY;
 		goto out;
@@ -2808,27 +3305,27 @@
 	ret = security_binder_set_context_mgr(proc->tsk);
 	if (ret < 0)
 		goto out;
-	if (uid_valid(binder_context_mgr_uid)) {
-		if (!uid_eq(binder_context_mgr_uid, curr_euid)) {
+	if (uid_valid(context->binder_context_mgr_uid)) {
+		if (!uid_eq(context->binder_context_mgr_uid, curr_euid)) {
 			pr_err("BINDER_SET_CONTEXT_MGR bad uid %d != %d\n",
 			       from_kuid(&init_user_ns, curr_euid),
 			       from_kuid(&init_user_ns,
-					binder_context_mgr_uid));
+					 context->binder_context_mgr_uid));
 			ret = -EPERM;
 			goto out;
 		}
 	} else {
-		binder_context_mgr_uid = curr_euid;
+		context->binder_context_mgr_uid = curr_euid;
 	}
-	binder_context_mgr_node = binder_new_node(proc, 0, 0);
-	if (binder_context_mgr_node == NULL) {
+	context->binder_context_mgr_node = binder_new_node(proc, 0, 0);
+	if (!context->binder_context_mgr_node) {
 		ret = -ENOMEM;
 		goto out;
 	}
-	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;
+	context->binder_context_mgr_node->local_weak_refs++;
+	context->binder_context_mgr_node->local_strong_refs++;
+	context->binder_context_mgr_node->has_strong_ref = 1;
+	context->binder_context_mgr_node->has_weak_ref = 1;
 out:
 	return ret;
 }
@@ -2956,7 +3453,7 @@
 	const char *failure_string;
 	struct binder_buffer *buffer;
 
-	if (proc->tsk != current)
+	if (proc->tsk != current->group_leader)
 		return -EINVAL;
 
 	if ((vma->vm_end - vma->vm_start) > SZ_4M)
@@ -3054,6 +3551,7 @@
 static int binder_open(struct inode *nodp, struct file *filp)
 {
 	struct binder_proc *proc;
+	struct binder_device *binder_dev;
 
 	binder_debug(BINDER_DEBUG_OPEN_CLOSE, "binder_open: %d:%d\n",
 		     current->group_leader->pid, current->pid);
@@ -3061,11 +3559,14 @@
 	proc = kzalloc(sizeof(*proc), GFP_KERNEL);
 	if (proc == NULL)
 		return -ENOMEM;
-	get_task_struct(current);
-	proc->tsk = current;
+	get_task_struct(current->group_leader);
+	proc->tsk = current->group_leader;
 	INIT_LIST_HEAD(&proc->todo);
 	init_waitqueue_head(&proc->wait);
 	proc->default_priority = task_nice(current);
+	binder_dev = container_of(filp->private_data, struct binder_device,
+				  miscdev);
+	proc->context = &binder_dev->context;
 
 	binder_lock(__func__);
 
@@ -3081,8 +3582,17 @@
 		char strbuf[11];
 
 		snprintf(strbuf, sizeof(strbuf), "%u", proc->pid);
+		/*
+		 * proc debug entries are shared between contexts, so
+		 * this will fail if the process tries to open the driver
+		 * again with a different context. The priting code will
+		 * anyway print all contexts that a given PID has, so this
+		 * is not a problem.
+		 */
 		proc->debugfs_entry = debugfs_create_file(strbuf, S_IRUGO,
-			binder_debugfs_dir_entry_proc, proc, &binder_proc_fops);
+			binder_debugfs_dir_entry_proc,
+			(void *)(unsigned long)proc->pid,
+			&binder_proc_fops);
 	}
 
 	return 0;
@@ -3175,6 +3685,7 @@
 static void binder_deferred_release(struct binder_proc *proc)
 {
 	struct binder_transaction *t;
+	struct binder_context *context = proc->context;
 	struct rb_node *n;
 	int threads, nodes, incoming_refs, outgoing_refs, buffers,
 		active_transactions, page_count;
@@ -3184,11 +3695,12 @@
 
 	hlist_del(&proc->proc_node);
 
-	if (binder_context_mgr_node && binder_context_mgr_node->proc == proc) {
+	if (context->binder_context_mgr_node &&
+	    context->binder_context_mgr_node->proc == proc) {
 		binder_debug(BINDER_DEBUG_DEAD_BINDER,
 			     "%s: %d context_mgr_node gone\n",
 			     __func__, proc->pid);
-		binder_context_mgr_node = NULL;
+		context->binder_context_mgr_node = NULL;
 	}
 
 	threads = 0;
@@ -3481,6 +3993,7 @@
 	size_t header_pos;
 
 	seq_printf(m, "proc %d\n", proc->pid);
+	seq_printf(m, "context %s\n", proc->context->name);
 	header_pos = m->count;
 
 	for (n = rb_first(&proc->threads); n != NULL; n = rb_next(n))
@@ -3550,7 +4063,9 @@
 	"BC_EXIT_LOOPER",
 	"BC_REQUEST_DEATH_NOTIFICATION",
 	"BC_CLEAR_DEATH_NOTIFICATION",
-	"BC_DEAD_BINDER_DONE"
+	"BC_DEAD_BINDER_DONE",
+	"BC_TRANSACTION_SG",
+	"BC_REPLY_SG",
 };
 
 static const char * const binder_objstat_strings[] = {
@@ -3605,6 +4120,7 @@
 	int count, strong, weak;
 
 	seq_printf(m, "proc %d\n", proc->pid);
+	seq_printf(m, "context %s\n", proc->context->name);
 	count = 0;
 	for (n = rb_first(&proc->threads); n != NULL; n = rb_next(n))
 		count++;
@@ -3712,23 +4228,18 @@
 static int binder_proc_show(struct seq_file *m, void *unused)
 {
 	struct binder_proc *itr;
-	struct binder_proc *proc = m->private;
+	int pid = (unsigned long)m->private;
 	int do_lock = !binder_debug_no_lock;
-	bool valid_proc = false;
 
 	if (do_lock)
 		binder_lock(__func__);
 
 	hlist_for_each_entry(itr, &binder_procs, proc_node) {
-		if (itr == proc) {
-			valid_proc = true;
-			break;
+		if (itr->pid == pid) {
+			seq_puts(m, "binder proc state:\n");
+			print_binder_proc(m, itr, 1);
 		}
 	}
-	if (valid_proc) {
-		seq_puts(m, "binder proc state:\n");
-		print_binder_proc(m, proc, 1);
-	}
 	if (do_lock)
 		binder_unlock(__func__);
 	return 0;
@@ -3738,11 +4249,11 @@
 					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",
+		   "%d: %s from %d:%d to %d:%d context %s 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);
+		   e->from_thread, e->to_proc, e->to_thread, e->context_name,
+		   e->to_node, e->target_handle, e->data_size, e->offsets_size);
 }
 
 static int binder_transaction_log_show(struct seq_file *m, void *unused)
@@ -3770,20 +4281,44 @@
 	.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 init_binder_device(const char *name)
+{
+	int ret;
+	struct binder_device *binder_device;
+
+	binder_device = kzalloc(sizeof(*binder_device), GFP_KERNEL);
+	if (!binder_device)
+		return -ENOMEM;
+
+	binder_device->miscdev.fops = &binder_fops;
+	binder_device->miscdev.minor = MISC_DYNAMIC_MINOR;
+	binder_device->miscdev.name = name;
+
+	binder_device->context.binder_context_mgr_uid = INVALID_UID;
+	binder_device->context.name = name;
+
+	ret = misc_register(&binder_device->miscdev);
+	if (ret < 0) {
+		kfree(binder_device);
+		return ret;
+	}
+
+	hlist_add_head(&binder_device->hlist, &binder_devices);
+
+	return ret;
+}
+
 static int __init binder_init(void)
 {
 	int ret;
+	char *device_name, *device_names;
+	struct binder_device *device;
+	struct hlist_node *tmp;
 
 	binder_deferred_workqueue = create_singlethread_workqueue("binder");
 	if (!binder_deferred_workqueue)
@@ -3793,7 +4328,7 @@
 	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,
@@ -3821,6 +4356,37 @@
 				    &binder_transaction_log_failed,
 				    &binder_transaction_log_fops);
 	}
+
+	/*
+	 * Copy the module_parameter string, because we don't want to
+	 * tokenize it in-place.
+	 */
+	device_names = kzalloc(strlen(binder_devices_param) + 1, GFP_KERNEL);
+	if (!device_names) {
+		ret = -ENOMEM;
+		goto err_alloc_device_names_failed;
+	}
+	strcpy(device_names, binder_devices_param);
+
+	while ((device_name = strsep(&device_names, ","))) {
+		ret = init_binder_device(device_name);
+		if (ret)
+			goto err_init_binder_device_failed;
+	}
+
+	return ret;
+
+err_init_binder_device_failed:
+	hlist_for_each_entry_safe(device, tmp, &binder_devices, hlist) {
+		misc_deregister(&device->miscdev);
+		hlist_del(&device->hlist);
+		kfree(device);
+	}
+err_alloc_device_names_failed:
+	debugfs_remove_recursive(binder_debugfs_dir_entry_root);
+
+	destroy_workqueue(binder_deferred_workqueue);
+
 	return ret;
 }
 
diff --git a/drivers/media/usb/em28xx/em28xx-cards.c b/drivers/media/usb/em28xx/em28xx-cards.c
index 1c6fca2..1602a79 100644
--- a/drivers/media/usb/em28xx/em28xx-cards.c
+++ b/drivers/media/usb/em28xx/em28xx-cards.c
@@ -411,6 +411,18 @@
 	{             -1,   -1,   -1,  -1},
 };
 
+static struct em28xx_reg_seq pctv_292e[] = {
+	{EM2874_R80_GPIO,         0xff, 0xff,      0},
+	{0x0d,                    0xff, 0xff,    950},
+	{EM2874_R80_GPIO,         0xbd, 0xff,    100},
+	{EM2874_R80_GPIO,         0xfd, 0xff,    410},
+	{EM2874_R80_GPIO,         0x7d, 0xff,    300},
+	{EM2874_R80_GPIO,         0x7c, 0xff,     60},
+	{0x0d,                    0x42, 0xff,     50},
+	{EM2874_R5F_TS_ENABLE,    0x85, 0xff,      0},
+	{                  -1,      -1,   -1,     -1},
+};
+
 /* 2040:0265 Hauppauge WinTV-dualHD DVB
  * reg 0x80/0x84:
  * GPIO_0: Yellow LED tuner 1, 0=on, 1=off
@@ -2038,6 +2050,18 @@
 		.i2c_speed    = EM28XX_I2C_CLK_WAIT_ENABLE |
 				EM28XX_I2C_FREQ_400_KHZ,
 	},
+	/* 2013:025f PCTV tripleStick (292e).
+	 * 2040:0264 Hauppauge WinTV-SoloHD Isoc, 2040:8264 Bulk
+	 * Empia EM28178, Silicon Labs Si2168, Silicon Labs Si2157 */
+	[EM28178_BOARD_PCTV_292E] = {
+		.name          = "PCTV tripleStick (292e)",
+		.def_i2c_bus   = 1,
+		.i2c_speed     = EM28XX_I2C_CLK_WAIT_ENABLE | EM28XX_I2C_FREQ_400_KHZ,
+		.tuner_type    = TUNER_ABSENT,
+		.tuner_gpio    = pctv_292e,
+		.has_dvb       = 1,
+		.ir_codes      = RC_MAP_PINNACLE_PCTV_HD,
+	},
 	/* 2040:0265 Hauppauge WinTV-dualHD (DVB version).
 	 * Empia EM28274, 2x Silicon Labs Si2168, 2x Silicon Labs Si2157 */
 	[EM28174_BOARD_HAUPPAUGE_WINTV_DUALHD_DVB] = {
@@ -2223,6 +2247,12 @@
 			.driver_info = EM2884_BOARD_PCTV_510E },
 	{ USB_DEVICE(0x2013, 0x0251),
 			.driver_info = EM2884_BOARD_PCTV_520E },
+	{ USB_DEVICE(0x2013, 0x025f),
+			.driver_info = EM28178_BOARD_PCTV_292E },
+	{ USB_DEVICE(0x2040, 0x0264), /* Hauppauge WinTV-soloHD Isoc */
+			.driver_info = EM28178_BOARD_PCTV_292E },
+	{ USB_DEVICE(0x2040, 0x8264), /* Hauppauge WinTV-soloHD Bulk */
+			.driver_info = EM28178_BOARD_PCTV_292E },
 	{ USB_DEVICE(0x2040, 0x0265), /* ISOC */
 			.driver_info = EM28174_BOARD_HAUPPAUGE_WINTV_DUALHD_DVB },
 	{ USB_DEVICE(0x2040, 0x8265), /* BULK */
@@ -2999,6 +3029,12 @@
 			dev->wait_after_write = 0;
 			dev->eeprom_addrwidth_16bit = 1;
 			break;
+		case CHIP_ID_EM28178:
+			chip_name = "em28178";
+			dev->reg_gpio_num = EM2874_R80_GPIO;
+			dev->wait_after_write = 0;
+			dev->eeprom_addrwidth_16bit = 1;
+			break;
 		case CHIP_ID_EM2883:
 			chip_name = "em2882/3";
 			dev->wait_after_write = 0;
diff --git a/drivers/media/usb/em28xx/em28xx-core.c b/drivers/media/usb/em28xx/em28xx-core.c
index 14bceea..09a6472 100644
--- a/drivers/media/usb/em28xx/em28xx-core.c
+++ b/drivers/media/usb/em28xx/em28xx-core.c
@@ -526,7 +526,8 @@
 	u32 vid;
 
 	if (dev->chip_id == CHIP_ID_EM2870 || dev->chip_id == CHIP_ID_EM2874
-		|| dev->chip_id == CHIP_ID_EM28174) {
+		|| dev->chip_id == CHIP_ID_EM28174
+		|| dev->chip_id == CHIP_ID_EM28178) {
 		/* Digital only device - don't load any alsa module */
 		dev->audio_mode.has_audio = false;
 		dev->has_audio_class = false;
@@ -647,9 +648,10 @@
 {
 	int rc;
 
-	if (dev->chip_id == CHIP_ID_EM2874 ||
-	    dev->chip_id == CHIP_ID_EM2884 ||
-	    dev->chip_id == CHIP_ID_EM28174) {
+	if (dev->chip_id == CHIP_ID_EM2874  ||
+	    dev->chip_id == CHIP_ID_EM2884  ||
+	    dev->chip_id == CHIP_ID_EM28174 ||
+	    dev->chip_id == CHIP_ID_EM28178) {
 		/* The Transport Stream Enable Register moved in em2874 */
 		if(dev->dvb_xfer_bulk) {
 			/* TS1 Maximum Transfer Size = 188 * EM28XX_DVB_BULK_PACKET_MULTIPLIER */
diff --git a/drivers/media/usb/em28xx/em28xx-dvb.c b/drivers/media/usb/em28xx/em28xx-dvb.c
index d9706b5..c9a73f5 100644
--- a/drivers/media/usb/em28xx/em28xx-dvb.c
+++ b/drivers/media/usb/em28xx/em28xx-dvb.c
@@ -706,6 +706,20 @@
 #endif
 }
 
+static int em28xx_pctv_292e_set_lna(struct dvb_frontend *fe)
+{
+	struct dtv_frontend_properties *c = &fe->dtv_property_cache;
+	struct em28xx *dev = fe->dvb->priv;
+	u8 lna;
+
+	if (c->lna == 1)
+		lna = 0x01;
+	else
+		lna = 0x00;
+
+	return em28xx_write_reg_bits(dev, EM2874_R80_GPIO, lna, 0x01);
+}
+
 static int em28xx_mt352_terratec_xs_init(struct dvb_frontend *fe)
 {
 	/* Values extracted from a USB trace of the Terratec Windows driver */
@@ -1326,6 +1340,67 @@
 			goto out_free;
 		}
 		break;
+	case EM28178_BOARD_PCTV_292E:
+		{
+			struct i2c_adapter *adapter;
+			struct i2c_client *client;
+			struct i2c_board_info info;
+			struct si2168_config si2168_config;
+			struct si2157_config si2157_config;
+
+			/* attach demod */
+			memset(&si2168_config, 0, sizeof(si2168_config));
+			si2168_config.i2c_adapter = &adapter;
+			si2168_config.fe = &dvb->fe[0];
+			si2168_config.ts_mode = SI2168_TS_PARALLEL;
+			memset(&info, 0, sizeof(struct i2c_board_info));
+			strlcpy(info.type, "si2168", I2C_NAME_SIZE);
+			info.addr = 0x64;
+			info.platform_data = &si2168_config;
+			request_module(info.type);
+			client = i2c_new_device(&dev->i2c_adap[dev->def_i2c_bus], &info);
+			if (client == NULL || client->dev.driver == NULL) {
+				result = -ENODEV;
+				goto out_free;
+			}
+
+			if (!try_module_get(client->dev.driver->owner)) {
+				i2c_unregister_device(client);
+				result = -ENODEV;
+				goto out_free;
+			}
+
+			dvb->i2c_client_demod = client;
+
+			/* attach tuner */
+			memset(&si2157_config, 0, sizeof(si2157_config));
+			si2157_config.fe = dvb->fe[0];
+			si2157_config.if_port = 1;
+			memset(&info, 0, sizeof(struct i2c_board_info));
+			strlcpy(info.type, "si2157", I2C_NAME_SIZE);
+			info.addr = 0x60;
+			info.platform_data = &si2157_config;
+			request_module(info.type);
+			client = i2c_new_device(adapter, &info);
+			if (client == NULL || client->dev.driver == NULL) {
+				module_put(dvb->i2c_client_demod->dev.driver->owner);
+				i2c_unregister_device(dvb->i2c_client_demod);
+				result = -ENODEV;
+				goto out_free;
+			}
+
+			if (!try_module_get(client->dev.driver->owner)) {
+				i2c_unregister_device(client);
+				module_put(dvb->i2c_client_demod->dev.driver->owner);
+				i2c_unregister_device(dvb->i2c_client_demod);
+				result = -ENODEV;
+				goto out_free;
+			}
+
+			dvb->i2c_client_tuner = client;
+			dvb->fe[0]->ops.set_lna = em28xx_pctv_292e_set_lna;
+		}
+		break;
 	case EM28174_BOARD_HAUPPAUGE_WINTV_DUALHD_DVB:
 		{
 			struct i2c_adapter *adapter;
diff --git a/drivers/media/usb/em28xx/em28xx-input.c b/drivers/media/usb/em28xx/em28xx-input.c
index e16e2bc..d013490 100644
--- a/drivers/media/usb/em28xx/em28xx-input.c
+++ b/drivers/media/usb/em28xx/em28xx-input.c
@@ -443,6 +443,7 @@
 	case CHIP_ID_EM2884:
 	case CHIP_ID_EM2874:
 	case CHIP_ID_EM28174:
+	case CHIP_ID_EM28178:
 		return em2874_ir_change_protocol(rc_dev, rc_type);
 	default:
 		printk("Unrecognized em28xx chip id 0x%02x: IR not supported\n",
@@ -634,6 +635,7 @@
 		case CHIP_ID_EM2884:
 		case CHIP_ID_EM2874:
 		case CHIP_ID_EM28174:
+		case CHIP_ID_EM28178:
 			ir->get_key = em2874_polling_getkey;
 			rc->allowed_protos = RC_BIT_RC5 | RC_BIT_NEC |
 					     RC_BIT_RC6_0;
diff --git a/drivers/media/usb/em28xx/em28xx-reg.h b/drivers/media/usb/em28xx/em28xx-reg.h
index 18e715d..04db2c4 100644
--- a/drivers/media/usb/em28xx/em28xx-reg.h
+++ b/drivers/media/usb/em28xx/em28xx-reg.h
@@ -242,6 +242,7 @@
 	CHIP_ID_EM2874 = 65,
 	CHIP_ID_EM2884 = 68,
 	CHIP_ID_EM28174 = 113,
+	CHIP_ID_EM28178 = 114,
 };
 
 /*
diff --git a/drivers/media/usb/em28xx/em28xx.h b/drivers/media/usb/em28xx/em28xx.h
index e9d7ece..c0ee29b 100644
--- a/drivers/media/usb/em28xx/em28xx.h
+++ b/drivers/media/usb/em28xx/em28xx.h
@@ -130,8 +130,9 @@
 #define EM2884_BOARD_PCTV_520E			  86
 #define EM2884_BOARD_TERRATEC_HTC_USB_XS	  87
 #define EM2884_BOARD_C3TECH_DIGITAL_DUO		  88
-#define EM28174_BOARD_HAUPPAUGE_WINTV_DUALHD_DVB  89
-#define EM28174_BOARD_HAUPPAUGE_WINTV_DUALHD_ATSC 90
+#define EM28178_BOARD_PCTV_292E                   89
+#define EM28174_BOARD_HAUPPAUGE_WINTV_DUALHD_DVB  90
+#define EM28174_BOARD_HAUPPAUGE_WINTV_DUALHD_ATSC 91
 
 /* Limits minimum and default number of buffers */
 #define EM28XX_MIN_BUF 4
diff --git a/drivers/net/wireless/bcmdhd/Makefile b/drivers/net/wireless/bcmdhd/Makefile
index 4079316..aff0d9e 100644
--- a/drivers/net/wireless/bcmdhd/Makefile
+++ b/drivers/net/wireless/bcmdhd/Makefile
@@ -98,7 +98,6 @@
 DHDCFLAGS += -DWL_CFG80211_ACL
 DHDCFLAGS += -DDISABLE_11H_SOFTAP
 DHDCFLAGS += -DSET_RANDOM_MAC_SOFTAP
-DHDCFLAGS += -DCUSTOM_FORCE_NODFS_FLAG
 DHDCFLAGS += -DCUSTOM_SET_SHORT_DWELL_TIME
 
 ##########################
diff --git a/drivers/platform/x86/intel_scu_ipcutil.c b/drivers/platform/x86/intel_scu_ipcutil.c
index b55cf8c..9bce123 100644
--- a/drivers/platform/x86/intel_scu_ipcutil.c
+++ b/drivers/platform/x86/intel_scu_ipcutil.c
@@ -36,6 +36,7 @@
 #include <linux/pm_runtime.h>
 #include <linux/debugfs.h>
 #include <linux/seq_file.h>
+#include <linux/hardirq.h>
 
 #ifdef CONFIG_COMPAT
 #include <linux/compat.h>
@@ -2961,6 +2962,11 @@
 
 	pr_debug("%s: Set kernel panic reason to OSNIB\n", __func__);
 
+	if (in_interrupt()) {
+		pr_err("Invoked in interrupt cxt\n");
+		goto out;
+	}
+
 	ret = intel_scu_ipc_read_osnib_wd(&wd);
 	if (ret) {
 		pr_err("Fail reading kernel panic bit\n");
diff --git a/drivers/staging/imgtec/adf/adf_ext.h b/drivers/staging/imgtec/adf/adf_ext.h
index 68e972f..49d82d2 100644
--- a/drivers/staging/imgtec/adf/adf_ext.h
+++ b/drivers/staging/imgtec/adf/adf_ext.h
@@ -90,18 +90,6 @@
 	struct adf_post_ext __user *post_ext;
 } __packed;
 
-/* These shouldn't be stripped by the uapi process in the bionic headers,
- * but currently are being. Redefine them so the custom ioctl interface is
- * actually useful. Fixed in Lollipop.
- */
-#ifndef ADF_IOCTL_TYPE
-#define ADF_IOCTL_TYPE 'D'
-#endif
-
-#ifndef ADF_IOCTL_NR_CUSTOM
-#define ADF_IOCTL_NR_CUSTOM 128
-#endif
-
 #define ADF_IOCTL_NR_VALIDATE_IMG (ADF_IOCTL_NR_CUSTOM + 0)
 
 #define ADF_VALIDATE_CONFIG_EXT \
diff --git a/drivers/staging/imgtec/adf_common.c b/drivers/staging/imgtec/adf_common.c
index 1f1f28f..8d04909 100644
--- a/drivers/staging/imgtec/adf_common.c
+++ b/drivers/staging/imgtec/adf_common.c
@@ -1,5 +1,8 @@
+/* -*- mode: c; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
+/* vi: set ts=8 sw=8 sts=8: */
 /*************************************************************************/ /*!
 @File
+@Codingstyle    LinuxKernel
 @Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
 @License        Dual MIT/GPLv2
 
@@ -38,7 +41,6 @@
 IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */ /**************************************************************************/
-/* vi: set ts=8: */
 
 #include "adf_common.h"
 
@@ -223,8 +225,7 @@
 {
 	int err;
 
-	if (!access_ok(VERIFY_READ, arg,
-	     sizeof(struct adf_validate_config_ext))) {
+	if (!access_ok(VERIFY_READ, arg, sizeof(*arg))) {
 		err = -EFAULT;
 		goto err_out;
 	}
@@ -264,8 +265,7 @@
 	BUILD_BUG_ON_MSG(sizeof(struct adf_validate_config_ext) != 32,
 		"adf_validate_config_ext has unexpected size");
 
-	if (!access_ok(VERIFY_READ, arg_compat,
-		sizeof(struct adf_validate_config_ext32))) {
+	if (!access_ok(VERIFY_READ, arg_compat, sizeof(*arg_compat))) {
 		err = -EFAULT;
 		goto err_out;
 	}
diff --git a/drivers/staging/imgtec/adf_common.h b/drivers/staging/imgtec/adf_common.h
index 5fddbc8..3c4e4e5 100644
--- a/drivers/staging/imgtec/adf_common.h
+++ b/drivers/staging/imgtec/adf_common.h
@@ -1,5 +1,8 @@
+/* -*- mode: c; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
+/* vi: set ts=8 sw=8 sts=8: */
 /*************************************************************************/ /*!
 @File
+@Codingstyle    LinuxKernel
 @Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
 @License        Dual MIT/GPLv2
 
@@ -38,7 +41,6 @@
 IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */ /**************************************************************************/
-/* vi: set ts=8: */
 
 #include <video/adf.h>
 #include <adf/adf_ext.h>
diff --git a/drivers/staging/imgtec/adf_fbdev.c b/drivers/staging/imgtec/adf_fbdev.c
index fc8799a..0434754 100644
--- a/drivers/staging/imgtec/adf_fbdev.c
+++ b/drivers/staging/imgtec/adf_fbdev.c
@@ -1,5 +1,8 @@
+/* -*- mode: c; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
+/* vi: set ts=8 sw=8 sts=8: */
 /*************************************************************************/ /*!
 @File
+@Codingstyle    LinuxKernel
 @Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
 @License        Dual MIT/GPLv2
 
@@ -38,7 +41,6 @@
 IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */ /**************************************************************************/
-/* vi: set ts=8: */
 
 #include <linux/version.h>
 #include <linux/console.h>
@@ -86,7 +88,6 @@
 
 struct adf_fbdev_dmabuf {
 	struct sg_table	sg_table;
-	unsigned long paddr;
 	size_t offset;
 	size_t length;
 	void *vaddr;
@@ -130,8 +131,10 @@
 	struct adf_fbdev_dmabuf *fbdev_dmabuf;
 	struct scatterlist *sg;
 	size_t unitary_size;
+	struct page *page;
+	u32 offset = 0;
 	int i, err;
-	u32 id = 0;
+	u32 id;
 
 	spin_lock(&interface->alloc_lock);
 
@@ -155,14 +158,12 @@
 	 */
 	BUG_ON((unitary_size % PAGE_SIZE) != 0);
 
-	fbdev_dmabuf = kmalloc(sizeof(struct adf_fbdev_dmabuf), GFP_KERNEL);
+	fbdev_dmabuf = kmalloc(sizeof(*fbdev_dmabuf), GFP_KERNEL);
 	if (!fbdev_dmabuf)
 		return ERR_PTR(-ENOMEM);
 
-	/* We only need one scatterlist entry per buffer because fbdev memory
-	 * is always physically contiguous.
-	 */
-	err = sg_alloc_table(&fbdev_dmabuf->sg_table, 1, GFP_KERNEL);
+	err = sg_alloc_table(&fbdev_dmabuf->sg_table, unitary_size / PAGE_SIZE,
+			     GFP_KERNEL);
 	if (err) {
 		kfree(fbdev_dmabuf);
 		return ERR_PTR(err);
@@ -182,20 +183,23 @@
 	fbdev_dmabuf->length = unitary_size;
 	fbdev_dmabuf->vaddr  = interface->fb_info->screen_base +
 			       fbdev_dmabuf->offset;
-	fbdev_dmabuf->paddr  = interface->fb_info->fix.smem_start +
-			       fbdev_dmabuf->offset;
 
-	sg_set_page(fbdev_dmabuf->sg_table.sgl,
-		    pfn_to_page(PFN_DOWN(fbdev_dmabuf->paddr)),
-		    fbdev_dmabuf->length, 0);
-
-	/* Shadow what ion is doing currently to ensure sg_dma_address() is
-	 * valid. This is not strictly correct as the dma address should
-	 * only be valid after mapping (ownership changed), and we haven't
-	 * mapped the scatter list yet.
-	 */
 	for_each_sg(fbdev_dmabuf->sg_table.sgl, sg,
 		    fbdev_dmabuf->sg_table.nents, i) {
+		page = vmalloc_to_page(fbdev_dmabuf->vaddr + offset);
+		if (!page) {
+			pr_err("Failed to map fbdev vaddr to pages\n");
+			kfree(fbdev_dmabuf);
+			return ERR_PTR(-EFAULT);
+		}
+		sg_set_page(sg, page, PAGE_SIZE, 0);
+		offset += PAGE_SIZE;
+
+		/* Shadow what ion is doing currently to ensure sg_dma_address()
+		 * is valid. This is not strictly correct as the dma address
+		 * should only be valid after mapping (ownership changed), and
+		 * we haven't mapped the scatter list yet.
+		 */
 		sg_dma_address(sg) = sg_phys(sg);
 	}
 
@@ -241,11 +245,39 @@
 static int adf_fbdev_d_mmap(struct dma_buf *dmabuf, struct vm_area_struct *vma)
 {
 	struct adf_fbdev_dmabuf *fbdev_dmabuf = dmabuf->priv;
+	unsigned long offset = vma->vm_pgoff * PAGE_SIZE;
+	unsigned long addr = vma->vm_start;
+	unsigned long remainder, len;
+	struct scatterlist *sg;
+	struct page *page;
+	u32 i;
 
-	return remap_pfn_range(vma, vma->vm_start,
-			       PFN_DOWN(fbdev_dmabuf->paddr),
-			       vma->vm_end - vma->vm_start,
-			       vma->vm_page_prot);
+	for_each_sg(fbdev_dmabuf->sg_table.sgl, sg,
+		    fbdev_dmabuf->sg_table.nents, i) {
+		page = sg_page(sg);
+		if (!page) {
+			pr_err("Failed to retrieve pages\n");
+			return -EFAULT;
+		}
+		remainder = vma->vm_end - addr;
+		len = sg_dma_len(sg);
+		if (offset >= sg_dma_len(sg)) {
+			offset -= sg_dma_len(sg);
+			continue;
+		} else if (offset) {
+			page += offset / PAGE_SIZE;
+			len = sg_dma_len(sg) - offset;
+			offset = 0;
+		}
+		len = min(len, remainder);
+		remap_pfn_range(vma, addr, page_to_pfn(page), len,
+				vma->vm_page_prot);
+		addr += len;
+		if (addr >= vma->vm_end)
+			return 0;
+	}
+
+	return 0;
 }
 
 static void adf_fbdev_d_release(struct dma_buf *dmabuf)
@@ -253,6 +285,9 @@
 	adf_fbdev_free_buffer(dmabuf->priv);
 }
 
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 6, 0)) && \
+    !defined(CHROMIUMOS_WORKAROUNDS_KERNEL318)
+
 static int
 adf_fbdev_d_begin_cpu_access(struct dma_buf *dmabuf, size_t start, size_t len,
 			     enum dma_data_direction dir)
@@ -270,6 +305,9 @@
 	/* Framebuffer memory is cache coherent. No-op. */
 }
 
+#endif /* (LINUX_VERSION_CODE < KERNEL_VERSION(4, 6, 0)) &&
+          !defined(CHROMIUMOS_WORKAROUNDS_KERNEL318) */
+
 static void *
 adf_fbdev_d_kmap(struct dma_buf *dmabuf, unsigned long page_offset)
 {
@@ -306,8 +344,11 @@
 	.unmap_dma_buf		= adf_fbdev_d_unmap_dma_buf,
 	.mmap			= adf_fbdev_d_mmap,
 	.release		= adf_fbdev_d_release,
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 6, 0)) && \
+    !defined(CHROMIUMOS_WORKAROUNDS_KERNEL318)
 	.begin_cpu_access	= adf_fbdev_d_begin_cpu_access,
 	.end_cpu_access		= adf_fbdev_d_end_cpu_access,
+#endif
 	.kmap_atomic		= adf_fbdev_d_kmap,
 	.kunmap_atomic		= adf_fbdev_d_kunmap,
 	.kmap			= adf_fbdev_d_kmap,
diff --git a/drivers/staging/imgtec/config_kernel.h b/drivers/staging/imgtec/config_kernel.h
index 6266eff..5d327d7 100644
--- a/drivers/staging/imgtec/config_kernel.h
+++ b/drivers/staging/imgtec/config_kernel.h
@@ -1,3 +1,4 @@
+#define RGX_FW_HEAP_SHIFT  25
 #define RGX_FW_FILENAME "rgx.fw.signed"
 #define LINUX 
 #define PVR_BUILD_DIR "intel_android"
@@ -9,49 +10,94 @@
 #define RELEASE 
 #define RGX_BVNC_CORE_KM_HEADER "cores/rgxcore_km_1.72.4.12.h"
 #define RGX_BNC_CONFIG_KM_HEADER "configs/rgxconfig_km_1.V.4.12.h"
+#define SUPPORT_MULTIBVNC_RUNTIME_BVNC_ACQUISITION 
 #define SUPPORT_DBGDRV_EVENT_OBJECTS 
 #define PDUMP_STREAMBUF_MAX_SIZE_MB 16
-#define SYS_USING_INTERRUPTS 
 #define PVRSRV_NEED_PVR_DPF 
+#define PVRSRV_NEED_PVR_STACKTRACE 
 #define SUPPORT_GPUTRACE_EVENTS 
 #define SUPPORT_DISPLAY_CLASS 
 #define GPUVIRT_VALIDATION_NUM_OS 8
-#define PVRSRV_GPUVIRT_NUM_OSID  2
-#define PVRSRV_GPUVIRT_OSID 0
-#define PVRSRV_GPUVIRT_OSID_STR ""
-#define PVRSRV_GPUVIRT_FWHEAP_SIZE  4194304
-#define PVRSRV_GPUVIRT_FWHEAP_BASE  0
+#define PVRSRV_GPUVIRT_NUM_OSID 2
+#define SUPPORT_VDM_CONTEXT_STORE_BUFFER_AB 
 #define SUPPORT_LINUX_X86_WRITECOMBINE 
 #define SUPPORT_LINUX_X86_PAT 
 #define PVR_LINUX_USING_WORKQUEUES 
 #define PVR_LINUX_MISR_USING_PRIVATE_WORKQUEUE 
 #define PVR_LINUX_TIMERS_USING_WORKQUEUES 
 #define PVR_LDM_DRIVER_REGISTRATION_NAME "pvrsrvkm"
-#define LDM_PCI 
 #define PVRSRV_FULL_SYNC_TRACKING_HISTORY_LEN 256
-#define SUPPORT_SYSTEM_INTERRUPT_HANDLING 
+#define SUPPORT_MMU_PENDING_FAULT_PROTECTION 
 #define PVR_DUMMY_PAGE_INIT_VALUE 0x00
+#define CACHEFLUSH_UM_TYPE CACHEFLUSH_UM_X86_ONLY
 #define PVRSRV_UNMAP_ON_SPARSE_CHANGE 
 #define SUPPORT_PERCONTEXT_FREELIST 
 #define HWR_DEFAULT_ENABLED 
-#define SUPPORT_POWMON_WO_GPIO_PIN 
+#define PVRSRV_APPHINT_HWRDEBUGDUMPLIMIT APPHNT_BLDVAR_DBGDUMPLIMIT
+#define PVRSRV_APPHINT_ENABLETRUSTEDDEVICEACECONFIG IMG_FALSE
+#define PVRSRV_APPHINT_HTBUFFERSIZE 0x1000
+#define PVRSRV_APPHINT_GENERAL_NON4K_HEAP_PAGE_SIZE 0x4000
+#define PVRSRV_APPHINT_ENABLESIGNATURECHECKS APPHNT_BLDVAR_ENABLESIGNATURECHECKS
+#define PVRSRV_APPHINT_SIGNATURECHECKSBUFSIZE RGXFW_SIG_BUFFER_SIZE_MIN
+#define PVRSRV_APPHINT_DISABLECLOCKGATING 0
+#define PVRSRV_APPHINT_DISABLEDMOVERLAP 0
+#define PVRSRV_APPHINT_ENABLECDMKILLINGRANDMODE 0
+#define PVRSRV_APPHINT_ENABLEFWCONTEXTSWITCH RGXFWIF_INICFG_CTXSWITCH_DM_ALL
+#define PVRSRV_APPHINT_ENABLERDPOWERISLAND RGX_RD_POWER_ISLAND_DEFAULT
+#define PVRSRV_APPHINT_FIRMWAREPERF FW_PERF_CONF_NONE
+#define PVRSRV_APPHINT_FWCONTEXTSWITCHPROFILE RGXFWIF_CTXSWITCH_PROFILE_MEDIUM_EN
+#define PVRSRV_APPHINT_HWPERFDISABLECUSTOMCOUNTERFILTER 0
+#define PVRSRV_APPHINT_HWPERFFWBUFSIZEINKB RGXFW_HWPERF_L1_SIZE_DEFAULT
+#define PVRSRV_APPHINT_HWPERFHOSTBUFSIZEINKB HWPERF_HOST_TL_STREAM_SIZE_DEFAULT
+#define PVRSRV_APPHINT_JONESDISABLEMASK 0
+#define PVRSRV_APPHINT_NEWFILTERINGMODE 1
+#define PVRSRV_APPHINT_TRUNCATEMODE 0
+#define PVRSRV_APPHINT_USEMETAT1 RGX_META_T1_OFF
+#define PVRSRV_APPHINT_RGXBVNC ""
+#define PVRSRV_APPHINT_ENABLETRUSTEDDEVICEACECONFIG IMG_FALSE
+#define PVRSRV_APPHINT_CLEANUPTHREADPRIORITY 0
+#define PVRSRV_APPHINT_CLEANUPTHREADWEIGHT 0
+#define PVRSRV_APPHINT_WATCHDOGTHREADPRIORITY 0
+#define PVRSRV_APPHINT_WATCHDOGTHREADWEIGHT 0
+#define PVRSRV_APPHINT_ASSERTONHWRTRIGGER IMG_FALSE
+#define PVRSRV_APPHINT_ASSERTOUTOFMEMORY IMG_FALSE
+#define PVRSRV_APPHINT_CHECKMLIST APPHNT_BLDVAR_DEBUG
+#define PVRSRV_APPHINT_DISABLEFEDLOGGING IMG_FALSE
+#define PVRSRV_APPHINT_ENABLEAPM RGX_ACTIVEPM_DEFAULT
+#define PVRSRV_APPHINT_ENABLEHTBLOGGROUP 0
+#define PVRSRV_APPHINT_ENABLELOGGROUP 0
+#define PVRSRV_APPHINT_FIRMWARELOGTYPE 0
+#define PVRSRV_APPHINT_HTBOPERATIONMODE HTB_OPMODE_DROPLATEST
+#define PVRSRV_APPHINT_HWPERFFWFILTER 0
+#define PVRSRV_APPHINT_HWPERFHOSTFILTER 0
+#define PVRSRV_APPHINT_TIMECORRCLOCK 2
+#define PVRSRV_APPHINT_ENABLEFWPOISONONFREE IMG_FALSE
+#define PVRSRV_APPHINT_FWPOISONONFREEVALUE 0xBD
+#define PVRSRV_APPHINT_ZEROFREELIST IMG_FALSE
+#define PVRSRV_APPHINT_DUSTREQUESTINJECT IMG_FALSE
+#define PVRSRV_APPHINT_DISABLEPDUMPPANIC IMG_FALSE
 #define PVRSRV_ENABLE_PROCESS_STATS 
 #define SUPPORT_SHARED_SLC 
+#define PVRSRV_ENABLE_CCCB_UTILISATION_INFO 
+#define PVRSRV_ENABLE_CCCB_UTILISATION_INFO_THRESHOLD 90
+#define PVRSRV_ENABLE_MEMTRACK_STATS_FILE 
 #define PVR_LINUX_PHYSMEM_MAX_POOL_PAGES 5120
 #define PVR_LINUX_PHYSMEM_MAX_EXCESS_POOL_PAGES 16384
 #define PVR_LINUX_PHYSMEM_ZERO_ALL_PAGES
+#define PVR_DIRTY_BYTES_FLUSH_THRESHOLD 1048576
 #define PVR_DIRTY_PAGECOUNT_FLUSH_THRESHOLD  256
 #define PVR_LINUX_HIGHORDER_ALLOCATION_THRESHOLD  256 
 #define PVR_LINUX_PHYSMEM_MAX_ALLOC_ORDER_NUM  2 
 #define PVR_LINUX_KMALLOC_ALLOCATION_THRESHOLD  16384 
 #define SUPPORT_KERNEL_SRVINIT 
+#define SUPPORT_NATIVE_FENCE_SYNC 
+#define PVR_DRM_NAME "pvr"
 #define DEVICE_MEMSETCPY_ALIGN_IN_BYTES 8
-#define SUPPORT_DRM 
 #define ANDROID 
 #define SUPPORT_ION 
-#define SUPPORT_NATIVE_FENCE_SYNC 
 #define PVR_ANDROID_ION_HEADER "../drivers/staging/android/ion/ion.h"
 #define PVR_ANDROID_ION_PRIV_HEADER "../drivers/staging/android/ion/ion_priv.h"
 #define PVR_ANDROID_ION_USE_SG_LENGTH 
 #define PVR_ANDROID_SYNC_HEADER "../drivers/staging/android/sync.h"
+#define SUPPORT_DRM 
 #define SUPPORT_DRM_EXT 
diff --git a/drivers/staging/imgtec/debugfs_dma_buf.c b/drivers/staging/imgtec/debugfs_dma_buf.c
index 74ef584..68360c1 100644
--- a/drivers/staging/imgtec/debugfs_dma_buf.c
+++ b/drivers/staging/imgtec/debugfs_dma_buf.c
@@ -1,5 +1,8 @@
+/* -*- mode: c; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
+/* vi: set ts=8 sw=8 sts=8: */
 /*************************************************************************/ /*!
 @File           debugfs_dma_buf.c
+@Codingstyle    LinuxKernel
 @Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
 @License        Dual MIT/GPLv2
 
@@ -38,7 +41,6 @@
 IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */ /**************************************************************************/
-/* vi: set ts=8: */
 
 #include "debugfs_dma_buf.h"
 
@@ -47,6 +49,8 @@
 #include <linux/kernel.h>
 #include <linux/debugfs.h>
 
+#include "kernel_compatibility.h"
+
 static struct dentry *g_debugfs_dentry;
 static struct dma_buf *g_dma_buf;
 
@@ -56,6 +60,7 @@
 	size_t istart = *ppos / PAGE_SIZE, iend, i = istart;
 	ssize_t wb = 0, res = 0;
 	struct dma_buf *dma_buf = g_dma_buf;
+	int err;
 
 	if (!dma_buf)
 		goto err_out;
@@ -71,8 +76,7 @@
 	 * remaining dma buffer size or the available um buffer size. */
 	iend = istart + min((size_t)(dma_buf->size - *ppos), count) / PAGE_SIZE;
 
-	res = dma_buf_begin_cpu_access(dma_buf, istart * PAGE_SIZE,
-				       PAGE_ALIGN(count), DMA_FROM_DEVICE);
+	res = dma_buf_begin_cpu_access(dma_buf, DMA_FROM_DEVICE);
 	if (res)
 		goto err_put;
 
@@ -102,8 +106,9 @@
 	res = wb;
 
 err_access:
-	dma_buf_end_cpu_access(dma_buf, istart * PAGE_SIZE,
-			       PAGE_ALIGN(count), DMA_FROM_DEVICE);
+	do {
+		err = dma_buf_end_cpu_access(dma_buf, DMA_FROM_DEVICE);
+	} while (err == -EAGAIN || err == -EINTR);
 err_put:
 	dma_buf_put(dma_buf);
 err_out:
diff --git a/drivers/staging/imgtec/debugfs_dma_buf.h b/drivers/staging/imgtec/debugfs_dma_buf.h
index ab51269..55a163d 100644
--- a/drivers/staging/imgtec/debugfs_dma_buf.h
+++ b/drivers/staging/imgtec/debugfs_dma_buf.h
@@ -1,5 +1,8 @@
+/* -*- mode: c; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
+/* vi: set ts=8 sw=8 sts=8: */
 /*************************************************************************/ /*!
 @File           debugfs_dma_buf.h
+@Codingstyle    LinuxKernel
 @Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
 @License        Dual MIT/GPLv2
 
@@ -38,7 +41,6 @@
 IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */ /**************************************************************************/
-/* vi: set ts=8: */
 
 #ifndef _DEBUGFS_DMA_BUF_H
 #define _DEBUGFS_DMA_BUF_H
diff --git a/drivers/staging/imgtec/intel/bufferclass_video.h b/drivers/staging/imgtec/intel/bufferclass_video.h
index ece1729..d196ee3 100644
--- a/drivers/staging/imgtec/intel/bufferclass_video.h
+++ b/drivers/staging/imgtec/intel/bufferclass_video.h
@@ -43,7 +43,8 @@
 
 #include "img_defs.h"
 #include "bufferclass_interface.h"
-#include "imgpixfmts_km.h"
+#include <powervr/imgpixfmts.h>
+#include <powervr/mem_types.h>
 
 #if defined(__cplusplus)
 extern "C"
@@ -156,12 +157,12 @@
 void BCFreeKernelMem(void *pvMem);
 
 BCE_ERROR BCAllocDiscontigMemory(unsigned long ulSize,
-				 BCE_HANDLE unref__ * phMemHandle,
+				 BCE_HANDLE __maybe_unused * phMemHandle,
 				 IMG_CPU_VIRTADDR * pLinAddr,
 				 IMG_SYS_PHYADDR ** ppPhysAddr);
 
 void BCFreeDiscontigMemory(unsigned long ulSize,
-			   BCE_HANDLE unref__ hMemHandle,
+			   BCE_HANDLE __maybe_unused hMemHandle,
 			   IMG_CPU_VIRTADDR LinAddr,
 			   IMG_SYS_PHYADDR * pPhysAddr);
 
diff --git a/drivers/staging/imgtec/intel/bufferclass_video_linux.c b/drivers/staging/imgtec/intel/bufferclass_video_linux.c
index e308909..6305d65 100644
--- a/drivers/staging/imgtec/intel/bufferclass_video_linux.c
+++ b/drivers/staging/imgtec/intel/bufferclass_video_linux.c
@@ -38,6 +38,7 @@
 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */ /**************************************************************************/
 
+#include <linux/compiler.h>
 #include <linux/version.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
@@ -83,16 +84,9 @@
 		*tfile,
 		uint32_t handle);
 
-MODULE_SUPPORTED_DEVICE(DEVNAME);
-
-#if defined(LDM_PLATFORM) || defined(LDM_PCI)
 static struct class *psPvrClass;
-#endif
-
 static int AssignedMajorNumber;
 
-#define unref__ __attribute__ ((unused))
-
 #if defined(LMA)
 #define PVR_BUFFERCLASS_MEMOFFSET (220 * 1024 * 1024)
 #define PVR_BUFFERCLASS_MEMSIZE      (4 * 1024 * 1024)
@@ -130,10 +124,7 @@
 BCVideoModInit(void)
 {
 	int i, j;
-	/*LDM_PCI is defined, while LDM_PLATFORM and LMA are not defined.*/
-#if defined(LDM_PLATFORM) || defined(LDM_PCI)
 	struct device *psDev;
-#endif
 
 #if defined(LMA)
 	struct pci_dev *psPCIDev;
@@ -160,7 +151,6 @@
 	       AssignedMajorNumber);
 #endif
 
-#if defined(LDM_PLATFORM) || defined(LDM_PCI)
 	psPvrClass = class_create(THIS_MODULE, "bc_video");
 	if (IS_ERR(psPvrClass)) {
 		printk(KERN_ERR DRVNAME
@@ -180,7 +170,6 @@
 		       PTR_ERR(psDev));
 		goto ExitDestroyClass;
 	}
-#endif
 
 #if defined(LMA)
 	g_ulMemBase =
@@ -215,10 +204,8 @@
 
 	return 0;
 
-#if defined(LDM_PLATFORM) || defined(LDM_PCI)
 ExitDestroyClass:
 	class_destroy(psPvrClass);
-#endif
 ExitUnregister:
 	unregister_chrdev(AssignedMajorNumber, DEVNAME);
 	//ExitDisable:
@@ -233,10 +220,9 @@
 BCVideoModCleanup(void)
 {
 	int i;
-#if defined(LDM_PLATFORM) || defined(LDM_PCI)
+
 	device_destroy(psPvrClass, MKDEV(AssignedMajorNumber, 0));
 	class_destroy(psPvrClass);
-#endif
 
 	for (i = 0; i < BC_VIDEO_DEVICE_MAX_ID; i++) {
 		if (BC_Video_Deinit(i) != BCE_OK) {
@@ -275,7 +261,7 @@
 
 BCE_ERROR
 BCAllocDiscontigMemory(unsigned long ulSize,
-		       BCE_HANDLE unref__ * phMemHandle,
+		       BCE_HANDLE __maybe_unused * phMemHandle,
 		       IMG_CPU_VIRTADDR * pLinAddr,
 		       IMG_SYS_PHYADDR ** ppPhysAddr)
 {
@@ -312,7 +298,7 @@
 
 void
 BCFreeDiscontigMemory(unsigned long ulSize,
-		      BCE_HANDLE unref__ hMemHandle,
+		      BCE_HANDLE __maybe_unused hMemHandle,
 		      IMG_CPU_VIRTADDR LinAddr, IMG_SYS_PHYADDR * pPhysAddr)
 {
 	kfree(pPhysAddr);
@@ -323,7 +309,7 @@
 
 BCE_ERROR
 BCAllocContigMemory(unsigned long ulSize,
-		    BCE_HANDLE unref__ * phMemHandle,
+		    BCE_HANDLE __maybe_unused * phMemHandle,
 		    IMG_CPU_VIRTADDR * pLinAddr, IMG_CPU_PHYADDR * pPhysAddr)
 {
 #if defined(LMA)
@@ -384,7 +370,7 @@
 
 void
 BCFreeContigMemory(unsigned long ulSize,
-		   BCE_HANDLE unref__ hMemHandle,
+		   BCE_HANDLE __maybe_unused hMemHandle,
 		   IMG_CPU_VIRTADDR LinAddr, IMG_CPU_PHYADDR PhysAddr)
 {
 #if defined(LMA)
@@ -434,7 +420,7 @@
 
 
 BCE_ERROR
-BCClosePVRServices(BCE_HANDLE unref__ hPVRServices)
+BCClosePVRServices(BCE_HANDLE __maybe_unused hPVRServices)
 {
 	return (BCE_OK);
 }
@@ -468,7 +454,6 @@
 		break;
 	default:
 		return -EINVAL;
-		break;
 	}
 
 	stride = p->stride;
@@ -544,7 +529,7 @@
 	if (id < 0 ||
 		id >= BC_VIDEO_DEVICE_MAX_ID ||
 	    bc_video_id_usage[id] != 1) {
-		return 0;;
+		return 0;
 	}
 	bc_video_id_usage[id] = 0;
 
@@ -619,7 +604,6 @@
 			return err;
 		}
 		return 0;
-		break;
 	}
 	case BC_Video_ioctl_get_buffer_index: {
 		int idx;
@@ -635,7 +619,6 @@
 		}
 		printk(KERN_ERR DRVNAME ": BCIOGET_BUFFERIDX- buffer not found\n");
 		return -EINVAL;
-		break;
 	}
 	case BC_Video_ioctl_request_buffers: {
 		bc_buf_params_t p;
@@ -648,7 +631,6 @@
 		}
 		psBridge->outputparam = id;
 		return BC_CreateBuffers(id, &p, IMG_FALSE);
-		break;
 	}
 	case BC_Video_ioctl_set_buffer_phyaddr: {
 		bc_buf_ptr_t p;
@@ -692,14 +674,12 @@
 		if (bo)
 			ttm_bo_unref(&bo);
 		return 0;
-		break;
 	}
 	case BC_Video_ioctl_release_buffer_device: {
 		bc_video_id_usage[id] = 0;
 
 		BCVideoDestroyBuffers(id);
 		return 0;
-		break;
 	}
 	case BC_Video_ioctl_alloc_buffer: {
 		bc_buf_ptr_t p;
@@ -765,7 +745,6 @@
 		psBridge->outputparam = (int)(uintptr_t) pvBuf;
 
 		return 0;
-		break;
 	}
 	case BC_Video_ioctl_free_buffer: {
 		bc_buf_ptr_t p;
@@ -780,7 +759,6 @@
 
 		vfree(devinfo->psSystemBuffer[p.index].sCPUVAddr);
 		return 0;
-		break;
 	}
 	case BC_Video_ioctl_get_buffer_handle: {
 		int idx;
@@ -825,7 +803,6 @@
 			return err;
 		}
 		return 0;
-		break;
 	}
 	case BC_Video_ioctl_get_buffer_index: {
 		int idx;
@@ -841,7 +818,6 @@
 		}
 		printk(KERN_ERR DRVNAME ": BCIOGET_BUFFERIDX- buffer not found\n");
 		return -EINVAL;
-		break;
 	}
 	case BC_Video_ioctl_request_buffers: {
 		bc_buf_params_t p;
@@ -851,11 +827,9 @@
 			return BC_CreateBuffers(id, &p, IMG_TRUE);
 		else
 			return BC_CreateBuffers(id, &p, IMG_FALSE);
-		break;
 	}
 	case BC_Video_ioctl_release_buffer_device: {
 		return BCVideoDestroyBuffers(id);
-		break;
 	}
 	case BC_Video_ioctl_set_buffer_phyaddr: {
 		bc_buf_ptr_t p;
@@ -915,7 +889,6 @@
 			kfree(ppsPages);
 		}
 		return 0;
-		break;
 	}
 	default:
 		return err;
@@ -939,7 +912,7 @@
 	IOCTL_DEF(DRM_IOCTL_BUFFER_CLASS_VIDEO, BCVideoBridge, DRM_AUTH)
 };
 
-static int bc_max_ioctl = DRM_ARRAY_SIZE(sBCdrmIoctls);
+static int bc_max_ioctl = ARRAY_SIZE(sBCdrmIoctls);
 
 void BCVideoQueryIoctls(struct drm_ioctl_desc *ioctls)
 {
diff --git a/drivers/staging/imgtec/intel/display/tng/drv/mrfld_display.c b/drivers/staging/imgtec/intel/display/tng/drv/mrfld_display.c
index c578f99..f6e37c0 100644
--- a/drivers/staging/imgtec/intel/display/tng/drv/mrfld_display.c
+++ b/drivers/staging/imgtec/intel/display/tng/drv/mrfld_display.c
@@ -312,6 +312,48 @@
 		return;
 #endif
 
+	if ((!psb_intel_crtc->in_mode_setting) && (pipe == 1) &&
+			dev_priv->psb_hotplug_state) {
+		if (mode == DRM_MODE_DPMS_OFF) {
+			flush_workqueue(dev_priv->power_wq);
+
+			DCLockMutex();
+			DC_MRFLD_onPowerOff(1);
+			/* give time to the last flip to take effective, if we
+			 * disable hardware too quickly, overlay hardware may
+			 * crash, causing pipe hang next time when we try to
+			 * use overlay
+			 */
+			msleep(50);
+
+			drm_handle_vblank(dev, 1);
+			/* Turn off vsync interrupt. */
+			drm_vblank_off(dev, 1);
+
+			/* Make the pending flip request as completed. */
+			DCUnAttachPipe(1);
+			DCUnLockMutex();
+
+			android_hdmi_suspend_display(dev);
+		} else {
+			android_hdmi_resume_display(dev);
+
+			/*
+			 * Devices connect status will be changed
+			 * when system suspend,re-detect once here.
+			 */
+			if (android_hdmi_is_connected(dev)) {
+				DCLockMutex();
+				DCAttachPipe(1);
+				DC_MRFLD_onPowerOn(1);
+				mid_hdmi_audio_resume(dev);
+				DCUnLockMutex();
+			}
+		}
+
+		return;
+	}
+
 	power_island = pipe_to_island(pipe);
 
 	if (!power_island_get(power_island))
@@ -477,6 +519,10 @@
 		   if it's on this pipe */
 		/* psb_intel_crtc_dpms_video(crtc, true); TODO */
 
+		if (psb_intel_crtc->in_mode_setting && (pipe == 1) &&
+				!dev_priv->hdmi_first_boot)
+			android_hdmi_resume_display(dev);
+
 		break;
 	case DRM_MODE_DPMS_OFF:
 		DCLockMutex();
diff --git a/drivers/staging/imgtec/intel/display/tng/drv/ospm/video_ospm.c b/drivers/staging/imgtec/intel/display/tng/drv/ospm/video_ospm.c
index 9c1aaae..4f3e23a 100644
--- a/drivers/staging/imgtec/intel/display/tng/drv/ospm/video_ospm.c
+++ b/drivers/staging/imgtec/intel/display/tng/drv/ospm/video_ospm.c
@@ -160,7 +160,8 @@
 	struct drm_psb_private *dev_priv = psb_priv(dev);
 	struct msvdx_private *msvdx_priv = dev_priv->msvdx_private;
 
-	if (atomic_read(&msvdx_priv->vc1_workaround_ctx)) {
+	if (!(msvdx_priv->msvdx_ctx->ctx_type & VA_RT_FORMAT_PROTECTED) &&
+			atomic_read(&msvdx_priv->slc_workaround_ctx)) {
 		uint32_t reg, data;
 
 		/* soc.gfx_wrapper.gbypassenable_sw = 1 */
diff --git a/drivers/staging/imgtec/intel/display/tng/drv/psb_intel_display.c b/drivers/staging/imgtec/intel/display/tng/drv/psb_intel_display.c
index 265e62d..41506c5 100644
--- a/drivers/staging/imgtec/intel/display/tng/drv/psb_intel_display.c
+++ b/drivers/staging/imgtec/intel/display/tng/drv/psb_intel_display.c
@@ -183,13 +183,19 @@
 static void psb_intel_crtc_prepare(struct drm_crtc *crtc)
 {
 	struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private;
+	struct psb_intel_crtc *psb_intel_crtc = to_psb_intel_crtc(crtc);
+
+	psb_intel_crtc->in_mode_setting = true;
 	crtc_funcs->dpms(crtc, DRM_MODE_DPMS_OFF);
 }
 
 static void psb_intel_crtc_commit(struct drm_crtc *crtc)
 {
 	struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private;
+	struct psb_intel_crtc *psb_intel_crtc = to_psb_intel_crtc(crtc);
+
 	crtc_funcs->dpms(crtc, DRM_MODE_DPMS_ON);
+	psb_intel_crtc->in_mode_setting = false;
 }
 
 void psb_intel_encoder_prepare(struct drm_encoder *encoder)
diff --git a/drivers/staging/imgtec/intel/display/tng/drv/psb_intel_drv.h b/drivers/staging/imgtec/intel/display/tng/drv/psb_intel_drv.h
index 173d2f6..b424166 100644
--- a/drivers/staging/imgtec/intel/display/tng/drv/psb_intel_drv.h
+++ b/drivers/staging/imgtec/intel/display/tng/drv/psb_intel_drv.h
@@ -238,6 +238,7 @@
 	/* Saved Crtc HW states */
 	struct psb_intel_crtc_state *crtc_state;
 #endif
+	bool in_mode_setting;
 };
 
 #define to_psb_intel_crtc(x)	\
diff --git a/drivers/staging/imgtec/intel/display/tng/interface/drm_shared.h b/drivers/staging/imgtec/intel/display/tng/interface/drm_shared.h
index 6bbf686..612eced5 100644
--- a/drivers/staging/imgtec/intel/display/tng/interface/drm_shared.h
+++ b/drivers/staging/imgtec/intel/display/tng/interface/drm_shared.h
@@ -18,12 +18,12 @@
  * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
  *
  **************************************************************************/
+#include <powervr/mem_types.h>
 #include <img_types.h>
 
 #ifndef _DRM_SHARED_H_
 #define _DRM_SHARED_H_
 
-
 /* Controlling the kernel modesetting buffers */
 
 #define DRM_PSB_KMS_OFF		0x00
diff --git a/drivers/staging/imgtec/intel/graphics/rgx/services/3rdparty/intel_devfreq/dfrgx_utilstats.c b/drivers/staging/imgtec/intel/graphics/rgx/services/3rdparty/intel_devfreq/dfrgx_utilstats.c
index 7eda403..2175007 100644
--- a/drivers/staging/imgtec/intel/graphics/rgx/services/3rdparty/intel_devfreq/dfrgx_utilstats.c
+++ b/drivers/staging/imgtec/intel/graphics/rgx/services/3rdparty/intel_devfreq/dfrgx_utilstats.c
@@ -35,9 +35,8 @@
 #include "osfunc.h"
 #include "rgxdebug.h"
 #include "dfrgx_utilstats.h"
-#include "pvr_tlcommon.h"
 #include "img_types.h"
-#include "pvrsrv.h"
+#include "pvrsrv_ext.h"
 #include "rgxdevice.h"
 #include "rgxinit.h"
 
diff --git a/drivers/staging/imgtec/intel/graphics/rgx/services/3rdparty/intel_devfreq/rgxdf.c b/drivers/staging/imgtec/intel/graphics/rgx/services/3rdparty/intel_devfreq/rgxdf.c
index d375fd4..c394d9d 100644
--- a/drivers/staging/imgtec/intel/graphics/rgx/services/3rdparty/intel_devfreq/rgxdf.c
+++ b/drivers/staging/imgtec/intel/graphics/rgx/services/3rdparty/intel_devfreq/rgxdf.c
@@ -45,7 +45,7 @@
 #include "rgxdf.h"
 #include "device.h"
 #include "rgxdevice.h"
-#include "pvrsrv.h"
+#include "pvrsrv_ext.h"
 #include "rgx_fwif_km.h"
 #include "pdump_km.h"
 #include "osfunc.h"
@@ -56,6 +56,17 @@
 #include "rgxfwutils.h"
 #include "img_types.h"
 
+/* Between DDK 1.6 and 1.7 the Services API changed, to replace device
+ * indices with PVRSRV_DEVICE_NODE pointers. Define a helper macro to allow
+ * this code to work with both versions.
+ */
+#include "pvrversion.h"
+#if PVRVERSION_MAJ == 1 && PVRVERSION_MIN < 7
+# define DEVICE_NODE_OR_INDEX(psDeviceNode) ((psDeviceNode)->sDevId.ui32DeviceIndex)
+#else
+# define DEVICE_NODE_OR_INDEX(psDeviceNode) psDeviceNode
+#endif
+
 extern struct drm_device *gpsPVRDRMDev;
 
 static PVRSRV_DEVICE_NODE* pDevNode = NULL;
@@ -145,7 +156,7 @@
 	int isPowered = IMG_FALSE;
 
 	if(psDeviceNode)
-		isPowered = PVRSRVIsDevicePowered(psDeviceNode->sDevId.ui32DeviceIndex);
+		isPowered = PVRSRVIsDevicePowered(DEVICE_NODE_OR_INDEX(psDeviceNode));
 
 	return isPowered;
 }
@@ -180,7 +191,7 @@
 		goto out;
 	}
 
-	eError = PVRSRVDevicePreClockSpeedChange(psDeviceNode->sDevId.ui32DeviceIndex, IMG_FALSE, NULL);
+	eError = PVRSRVDevicePreClockSpeedChange(DEVICE_NODE_OR_INDEX(psDeviceNode), IMG_FALSE, NULL);
 out:
 	return eError;
 }
@@ -197,7 +208,7 @@
 	}
 
 
-	PVRSRVDevicePostClockSpeedChange(psDeviceNode->sDevId.ui32DeviceIndex, IMG_FALSE, NULL);
+	PVRSRVDevicePostClockSpeedChange(DEVICE_NODE_OR_INDEX(psDeviceNode), IMG_FALSE, NULL);
 
 out:
 	return eError;
diff --git a/drivers/staging/imgtec/intel/graphics/rgx/services/3rdparty/intel_drm/dc_mrfld.h b/drivers/staging/imgtec/intel/graphics/rgx/services/3rdparty/intel_drm/dc_mrfld.h
index 6f8cb41..4b20841 100644
--- a/drivers/staging/imgtec/intel/graphics/rgx/services/3rdparty/intel_drm/dc_mrfld.h
+++ b/drivers/staging/imgtec/intel/graphics/rgx/services/3rdparty/intel_drm/dc_mrfld.h
@@ -27,7 +27,8 @@
 #define __DC_MRFLD_H__
 
 #include <drm/drmP.h>
-#include <imgpixfmts_km.h>
+#include <powervr/mem_types.h>
+#include <powervr/imgpixfmts.h>
 #include "kerneldisplay.h"
 #include "psb_drm.h"
 #include "displayclass_interface.h"
diff --git a/drivers/staging/imgtec/intel/ion_support_intel.c b/drivers/staging/imgtec/intel/ion_support_intel.c
index 4742f6e..5967d0f 100644
--- a/drivers/staging/imgtec/intel/ion_support_intel.c
+++ b/drivers/staging/imgtec/intel/ion_support_intel.c
@@ -106,18 +106,13 @@
 	PVR_UNREFERENCED_PARAMETER(ulAlign);
 	PVR_UNREFERENCED_PARAMETER(ulFlags);
 
-	/* It's not really correct to hijack the PMR lock like this, but this
-	 * seems better than relying on the bridge lock since that could be
-	 * taken around a call to ion_alloc(). The PMR lock being held around
-	 * a call to ion_alloc() is much less likely.
-	 */
-	if (!PMRIsLockedByMe() || !gpsDCBufferPMR)
+	if (!gpsDCBufferPMR)
 	{
 		err = -ENOTTY;
 		goto err_out;
 	}
 
-	eError = PMRLockSysPhysAddresses(gpsDCBufferPMR, PAGE_SHIFT);
+	eError = PMRLockSysPhysAddresses(gpsDCBufferPMR);
 	if (eError != PVRSRV_OK)
 	{
 		err = -EFAULT;
@@ -327,7 +322,7 @@
 	IMG_DEVMEM_SIZE_T uSize;
 	struct file *psFile;
 	PVRSRV_ERROR eError;
-	DC_BUFFER *psBuffer;
+	DC_BUFFER *psBuffer = NULL;
 	int err = -EFAULT;
 
 	if (uiCmd != ION_IOC_ALLOC_FROM_DC_BUFFER)
@@ -358,11 +353,12 @@
 	eError = PVRSRVLookupHandle(psConnection->psHandleBase,
 								(void **)&psBuffer,
 								(IMG_HANDLE)sData.dc_buffer,
-								PVRSRV_HANDLE_TYPE_DC_BUFFER);
+								PVRSRV_HANDLE_TYPE_DC_BUFFER,
+								IMG_TRUE);
 	if (eError != PVRSRV_OK)
+	{
 		goto err_unlock;
-
-	PMRLock();
+	}
 
 	eError = DCBufferAcquire(psBuffer, &gpsDCBufferPMR);
 	if (eError != PVRSRV_OK)
@@ -393,9 +389,14 @@
 	err = 0;
 err_unlock_pmr:
 	DCBufferRelease(gpsDCBufferPMR);
-	PMRUnlock();
 	gpsDCBufferPMR = NULL;
 err_unlock:
+	if(psBuffer)
+	{
+		PVRSRVReleaseHandle(psConnection->psHandleBase,
+							(IMG_HANDLE)sData.dc_buffer,
+							PVRSRV_HANDLE_TYPE_DC_BUFFER);
+	}
 	OSReleaseBridgeLock();
 err_fput:
 	fput(psFile);
diff --git a/drivers/staging/imgtec/intel/otm_hdmi/os/android/android_hdmi.c b/drivers/staging/imgtec/intel/otm_hdmi/os/android/android_hdmi.c
index a688e19..d36c238 100644
--- a/drivers/staging/imgtec/intel/otm_hdmi/os/android/android_hdmi.c
+++ b/drivers/staging/imgtec/intel/otm_hdmi/os/android/android_hdmi.c
@@ -2586,12 +2586,10 @@
 
 void android_hdmi_connector_dpms(struct drm_connector *connector, int mode)
 {
-	struct drm_device *dev = connector->dev;
-	bool hdmi_audio_busy = false;
-	u32 dspcntr_val;
-	struct drm_psb_private *dev_priv = dev->dev_private;
 #if (defined CONFIG_PM_RUNTIME) && (!defined MERRIFIELD) \
 	&& (defined CONFIG_SUPPORT_MIPI)
+	struct drm_device *dev = connector->dev;
+	struct drm_psb_private *dev_priv = dev->dev_private;
 	bool panel_on = false, panel_on2 = false;
 	struct mdfld_dsi_config **dsi_configs;
 #endif
@@ -2601,35 +2599,12 @@
 				OSPM_UHB_FORCE_POWER_ON))
 		return ;
 
-	/* Check HDMI Audio Status */
-	hdmi_audio_busy = mid_hdmi_audio_is_busy(dev);
+	drm_helper_connector_dpms(connector, mode);
 
-	pr_debug("[DPMS] audio busy: 0x%x\n", hdmi_audio_busy);
-
-	/* if hdmi audio is busy, just turn off hdmi display plane */
-	if (hdmi_audio_busy) {
-		dspcntr_val = PSB_RVDC32(DSPBCNTR);
-		connector->dpms = mode;
-
-		if (mode != DRM_MODE_DPMS_ON) {
-			if (!dev_priv->hdmi_first_boot) {
-				REG_WRITE(DSPBCNTR, dspcntr_val &
-						~DISPLAY_PLANE_ENABLE);
-				DISP_PLANEB_STATUS = DISPLAY_PLANE_DISABLE;
-			}
-		} else {
-			REG_WRITE(DSPBCNTR, dspcntr_val |
-							DISPLAY_PLANE_ENABLE);
-			DISP_PLANEB_STATUS = DISPLAY_PLANE_ENABLE;
-		}
-	} else {
-		drm_helper_connector_dpms(connector, mode);
-
-		if (mode != DRM_MODE_DPMS_ON)
-			DISP_PLANEB_STATUS = DISPLAY_PLANE_DISABLE;
-		else
-			DISP_PLANEB_STATUS = DISPLAY_PLANE_ENABLE;
-	}
+	if (mode != DRM_MODE_DPMS_ON)
+		DISP_PLANEB_STATUS = DISPLAY_PLANE_DISABLE;
+	else
+		DISP_PLANEB_STATUS = DISPLAY_PLANE_ENABLE;
 
 #if (defined CONFIG_PM_RUNTIME) && (!defined MERRIFIELD) \
 	&& (defined CONFIG_SUPPORT_MIPI)
diff --git a/drivers/staging/imgtec/intel/pci_support.c b/drivers/staging/imgtec/intel/pci_support.c
index 2595c76..1d3c2c7 100644
--- a/drivers/staging/imgtec/intel/pci_support.c
+++ b/drivers/staging/imgtec/intel/pci_support.c
@@ -40,10 +40,10 @@
 */ /**************************************************************************/
 
 #include <linux/pci.h>
-#include <linux/version.h>
 
 #if defined(CONFIG_MTRR)
 #include <asm/mtrr.h>
+#include <linux/version.h>
 #endif
 
 #include "pci_support.h"
@@ -457,7 +457,7 @@
 
 	pci_disable_device(psPVRPCI->psPCIDev);
 
-	OSFreeMem((void *)psPVRPCI);
+	OSFreeMem(psPVRPCI);
 	/*not nulling pointer, copy on stack*/
 
 	return PVRSRV_OK;
@@ -540,16 +540,8 @@
 			return PVRSRV_ERROR_UNKNOWN_POWER_STATE;
 	}
 
-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
 	pci_restore_state(psPVRPCI->psPCIDev);
-#else
-	err = pci_restore_state(psPVRPCI->psPCIDev);
-	if (err != 0)
-	{
-		printk(KERN_ERR "OSPCIResumeDev: pci_restore_state failed (%d)", err);
-		return PVRSRV_ERROR_PCI_CALL_FAILED;
-	}
-#endif
+
 	err = pci_enable_device(psPVRPCI->psPCIDev);
 	if (err != 0)
 	{
diff --git a/drivers/staging/imgtec/intel/pci_support.h b/drivers/staging/imgtec/intel/pci_support.h
index 4322098..c420ff9 100644
--- a/drivers/staging/imgtec/intel/pci_support.h
+++ b/drivers/staging/imgtec/intel/pci_support.h
@@ -45,6 +45,13 @@
 #include "img_types.h"
 #include "pvrsrv_error.h"
 
+#if defined(LINUX)
+#include <linux/pci.h>
+#define TO_PCI_COOKIE(dev) to_pci_dev((struct device *)(dev))
+#else
+#define TO_PCI_COOKIE(dev) (dev)
+#endif
+
 typedef enum _HOST_PCI_INIT_FLAGS_
 {
 	HOST_PCI_INIT_FLAG_BUS_MASTER	= 0x00000001,
diff --git a/drivers/staging/imgtec/intel/pvr_drm_shared.h b/drivers/staging/imgtec/intel/pvr_drm.h
similarity index 70%
rename from drivers/staging/imgtec/intel/pvr_drm_shared.h
rename to drivers/staging/imgtec/intel/pvr_drm.h
index 69cd4b9..0527590 100644
--- a/drivers/staging/imgtec/intel/pvr_drm_shared.h
+++ b/drivers/staging/imgtec/intel/pvr_drm.h
@@ -40,12 +40,44 @@
 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */ /**************************************************************************/
 
-#if !defined(__PVR_DRM_SHARED_H__)
-#define __PVR_DRM_SHARED_H__
+#if !defined(__PVR_DRM_H__)
+#define __PVR_DRM_H__
 
-#if defined(SUPPORT_DRM)
 #include <linux/types.h>
 
+#if defined(__KERNEL__)
+#include <drm/drm.h>
+#elif defined(SUPPORT_ANDROID_PLATFORM) && \
+     !defined(PVR_ANDROID_OLD_LIBDRM_HEADER_PATH)
+#include <drm.h>
+#else
+#include <libdrm/drm.h>
+#endif
+
+/*
+ * The fields, types and ordering must match those of PVRSRV_BRIDGE_PACKAGE but
+ * the names must match those of the common version of this structure found in a
+ * header of the same name in the common Services code.
+ */
+struct drm_pvr_srvkm_cmd {
+	__u32 bridge_id;
+	__u32 bridge_func_id;
+	__u32 size;
+	void *in_data_ptr;
+	__u32 in_data_size;
+	void *out_data_ptr;
+	__u32 out_data_size;
+};
+
+struct drm_pvr_dbgdrv_cmd {
+	__u32 cmd;
+	__u32 pad;
+	__u64 in_data_ptr;
+	__u64 out_data_ptr;
+	__u32 in_data_size;
+	__u32 out_data_size;
+};
+
 /* 
  * DRM command numbers, relative to DRM_COMMAND_BASE. 
  * These defines must be prefixed with "DRM_".
@@ -54,5 +86,13 @@
 #define DRM_PVR_IS_MASTER_CMD	0x15 /* Used to check for master */
 #define DRM_PVR_DBGDRV_CMD		0x1E /* Debug driver (PDUMP) ioctls */
 
-#endif /* defined(SUPPORT_DRM) */
-#endif /* defined(__PVR_DRM_SHARED_H__) */
+#define DRM_IOCTL_PVR_SRVKM_CMD \
+	DRM_IOWR(DRM_COMMAND_BASE + DRM_PVR_SRVKM_CMD, struct drm_pvr_srvkm_cmd)
+
+#define DRM_IOCTL_PVR_IS_MASTER_CMD \
+	DRM_IO(DRM_COMMAND_BASE + DRM_PVR_IS_MASTER_CMD)
+
+#define	DRM_IOCTL_PVR_DBGDRV_CMD \
+	DRM_IOWR(DRM_COMMAND_BASE + DRM_PVR_DBGDRV_CMD, struct drm_pvr_dbgdrv_cmd)
+
+#endif /* defined(__PVR_DRM_H__) */
diff --git a/drivers/staging/imgtec/intel/pvr_drm_ext.c b/drivers/staging/imgtec/intel/pvr_drm_ext.c
index 9163358..70a0bc1 100644
--- a/drivers/staging/imgtec/intel/pvr_drm_ext.c
+++ b/drivers/staging/imgtec/intel/pvr_drm_ext.c
@@ -38,6 +38,7 @@
 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */ /**************************************************************************/
 
+#include <linux/kernel.h>
 #include <linux/mm.h>
 #include <linux/version.h>
 #include <drm/drmP.h>
@@ -46,17 +47,13 @@
 #include "img_defs.h"
 #include "lock.h"
 #include "pvr_drm_ext.h"
-#include "pvr_drm_shared.h"
+#include "pvr_drm.h"
+#include "pvrsrv_ext.h"
 #include "pvrsrv_interface.h"
-#include "pvr_bridge.h"
 #include "srvkm.h"
 #include "dc_mrfld.h"
 #include "drm_shared.h"
-#include "linkage.h"
-
-#if defined(PDUMP)
-#include "linuxsrv.h"
-#endif
+#include "module_common.h"
 
 #include <linux/module.h>
 #include "pvrmodule.h"
@@ -67,16 +64,6 @@
 #error Mismatch in IOCTL numbers
 #endif
 
-#define DRM_IOCTL_PVR_SRVKM_CMD \
-	DRM_IOW(DRM_COMMAND_BASE + DRM_PVR_SRVKM_CMD, PVRSRV_BRIDGE_PACKAGE)
-
-#define DRM_IOCTL_PVR_IS_MASTER_CMD \
-	DRM_IO(DRM_COMMAND_BASE + DRM_PVR_IS_MASTER_CMD)
-
-#if defined(PDUMP)
-#define	DRM_IOCTL_PVR_DBGDRV_CMD \
-	DRM_IOW(DRM_COMMAND_BASE + DRM_PVR_DBGDRV_CMD, IOCTL_PACKAGE)
-#endif
 
 static int
 PVRDRMIsMaster(struct drm_device *dev, void *arg, struct drm_file *pFile)
@@ -102,17 +89,80 @@
 };
 #endif /* (LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0)) */
 
+typedef struct _PVRSRV_DEVICE_NODE_ PVRSRV_DEVICE_NODE;
+
 DECLARE_WAIT_QUEUE_HEAD(sWaitForInit);
 
 static bool bInitComplete;
 static bool bInitFailed;
 
-struct pci_dev *gpsPVRLDMDev;
+static struct pci_dev *gpsPVRLDMDev;
 
 struct drm_device *gpsPVRDRMDev;
+static PVRSRV_DEVICE_NODE *gpsDeviceNode;
 
 #define PVR_DRM_FILE struct drm_file *
 
+int PVRCore_Init(void)
+{
+	int error = 0;
+
+	if ((error = PVRSRVCommonDriverInit()) != 0)
+	{
+		return error;
+	}
+
+	error = PVRSRVDeviceCreate(&gpsPVRLDMDev->dev, &gpsDeviceNode);
+	if (error != 0)
+	{
+		DRM_DEBUG("%s: unable to init PVR service (%d)", __FUNCTION__, error);
+		return error;
+	}
+
+	error = PVRSRVCommonDeviceInit(gpsDeviceNode);
+	if (error != 0)
+	{
+		return error;
+	}
+
+	return 0;
+}
+
+void PVRCore_Cleanup(void)
+{
+	PVRSRVCommonDeviceDeinit(gpsDeviceNode);
+	PVRSRVDeviceDestroy(gpsDeviceNode);
+	gpsDeviceNode = NULL;
+
+	PVRSRVCommonDriverDeinit();
+}
+
+int PVRSRVOpen(struct drm_device __maybe_unused *dev, struct drm_file *pDRMFile)
+{
+	int err;
+
+	if (!try_module_get(THIS_MODULE))
+	{
+		DRM_DEBUG("%s: Failed to get module", __FUNCTION__);
+		return -ENOENT;
+	}
+
+	err = PVRSRVCommonDeviceOpen(gpsDeviceNode, pDRMFile);
+	if (err)
+	{
+		module_put(THIS_MODULE);
+	}
+
+	return err;
+}
+
+void PVRSRVRelease(struct drm_device __maybe_unused *dev, struct drm_file *pDRMFile)
+{
+	PVRSRVCommonDeviceRelease(gpsDeviceNode, pDRMFile);
+
+	module_put(THIS_MODULE);
+}
+
 int PVRSRVDrmLoad(struct drm_device *dev, unsigned long flags)
 {
 	int iRes = 0;
@@ -121,19 +171,11 @@
 
 	gpsPVRDRMDev = dev;
 	gpsPVRLDMDev = dev->pdev;
-
-#if defined(PDUMP)
-	iRes = dbgdrv_init();
-	if (iRes != 0)
-	{
-		goto exit;
-	}
-#endif
 	
 	iRes = PVRCore_Init();
 	if (iRes != 0)
 	{
-		goto exit_dbgdrv_cleanup;
+		goto exit;
 	}
 
 	if (MerrifieldDCInit(dev) != PVRSRV_OK)
@@ -146,11 +188,6 @@
 
 exit_pvrcore_cleanup:
 	PVRCore_Cleanup();
-
-exit_dbgdrv_cleanup:
-#if defined(PDUMP)
-	dbgdrv_cleanup();
-#endif
 exit:
 	if (iRes != 0)
 	{
@@ -174,10 +211,6 @@
 
 	PVRCore_Cleanup();
 
-#if defined(PDUMP)
-	dbgdrv_cleanup();
-#endif
-
 	return 0;
 }
 
@@ -224,7 +257,7 @@
 {
 	int i;
 
-	for (i = 0; i < DRM_ARRAY_SIZE(pvr_ioctls); i++)
+	for (i = 0; i < ARRAY_SIZE(pvr_ioctls); i++)
 	{
 		unsigned int slot = DRM_IOCTL_NR(pvr_ioctls[i].cmd) - DRM_COMMAND_BASE;
 		ioctls[slot] = pvr_ioctls[i];
@@ -349,3 +382,59 @@
 {
 	return PVRSRV_MMap(pFile, ps_vma);
 }
+
+PVRSRV_ERROR PVRSRVEnumerateDevicesKM(IMG_UINT32 *pui32NumDevices,
+									  PVRSRV_DEVICE_TYPE *peDeviceType,
+									  PVRSRV_DEVICE_CLASS *peDeviceClass,
+									  IMG_UINT32 *pui32DeviceIndex)
+{
+	IMG_UINT32 i;
+
+	if (!pui32NumDevices || !peDeviceType || !peDeviceClass || !pui32DeviceIndex)
+	{
+		DRM_ERROR("%s: Invalid params", __func__);
+		return PVRSRV_ERROR_INVALID_PARAMS;
+	}
+
+	/* Setup input buffer to be `empty' */
+	for (i = 0; i < PVRSRV_MAX_DEVICES; i++)
+	{
+		peDeviceType[i] = PVRSRV_DEVICE_TYPE_UNKNOWN;
+	}
+
+	/* Only a single device is supported */
+	peDeviceType[0] = PVRSRV_DEVICE_TYPE_RGX;
+	peDeviceClass[0] = PVRSRV_DEVICE_CLASS_3D;
+	pui32DeviceIndex[0] = 0;
+	*pui32NumDevices = 1;
+
+	return PVRSRV_OK;
+}
+
+PVRSRV_ERROR PVRSRVAcquireDeviceDataKM(IMG_UINT32 ui32DevIndex,
+									   PVRSRV_DEVICE_TYPE eDeviceType,
+									   IMG_HANDLE *phDevCookie)
+{
+	if (phDevCookie)
+	{
+		DRM_ERROR("%s: Invalid params", __func__);
+		return PVRSRV_ERROR_INVALID_PARAMS;
+	}
+
+	if ((eDeviceType == PVRSRV_DEVICE_TYPE_RGX) ||
+		(eDeviceType == PVRSRV_DEVICE_TYPE_UNKNOWN && ui32DevIndex == 0))
+	{
+		PVRSRV_DATA *psPVRSRVData = PVRSRVGetPVRSRVData();
+
+		/*
+		 * Return the head of the list, which will only contain a single entry,
+		 * as only a single device is supported.
+		 */
+		*phDevCookie = (IMG_HANDLE) psPVRSRVData->psDeviceNodeList;
+
+		return PVRSRV_OK;
+	}
+
+	DRM_ERROR("%s: requested device is not present", __func__);
+	return PVRSRV_ERROR_INIT_FAILURE;
+}
diff --git a/drivers/staging/imgtec/intel/pvr_drm_ext.h b/drivers/staging/imgtec/intel/pvr_drm_ext.h
index a163927..537e52e 100644
--- a/drivers/staging/imgtec/intel/pvr_drm_ext.h
+++ b/drivers/staging/imgtec/intel/pvr_drm_ext.h
@@ -46,6 +46,7 @@
 void PVRSRVRelease(struct drm_device *dev, struct drm_file *pDRMFile);
 
 int PVRSRV_BridgeDispatchKM(struct drm_device *dev, void *arg, struct drm_file *pFile);
+int PVRSRV_MMap(struct file *file, struct vm_area_struct *ps_vma);
 
 int PVRSRVDrmOpen(struct drm_device *dev, struct drm_file *file);
 int PVRSRVDrmRelease(struct inode *inode, struct file *filp);
diff --git a/drivers/staging/imgtec/intel/pvrsrv_ext.h b/drivers/staging/imgtec/intel/pvrsrv_ext.h
index b2a1264..e3efd4d 100644
--- a/drivers/staging/imgtec/intel/pvrsrv_ext.h
+++ b/drivers/staging/imgtec/intel/pvrsrv_ext.h
@@ -39,9 +39,31 @@
 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */ /**************************************************************************/
 
-#if !defined(_PVRSRV_EXT_H_)
-#define _PVRSRV_EXT_H_
+#if !defined(__PRVRSRV_EXT_H__)
+#define __PRVRSRV_EXT_H__
 
+#include "img_types.h"
+#include "pvrsrv_error.h"
 #include "pvrsrv.h"
 
-#endif /* !defined(_PVRSRV_EXT_H_) */
+typedef enum PVRSRV_DEVICE_TYPE
+{
+	PVRSRV_DEVICE_TYPE_UNKNOWN = 0,
+	PVRSRV_DEVICE_TYPE_RGX = 10,
+} PVRSRV_DEVICE_TYPE;
+
+typedef enum _PVRSRV_DEVICE_CLASS_
+{
+	PVRSRV_DEVICE_CLASS_3D = 0,
+} PVRSRV_DEVICE_CLASS;
+
+PVRSRV_ERROR PVRSRVEnumerateDevicesKM(IMG_UINT32 *pui32NumDevices,
+									  PVRSRV_DEVICE_TYPE *peDeviceType,
+									  PVRSRV_DEVICE_CLASS *peDeviceClass,
+									  IMG_UINT32 *pui32DeviceIndex);
+
+PVRSRV_ERROR PVRSRVAcquireDeviceDataKM(IMG_UINT32 ui32DevIndex,
+									   PVRSRV_DEVICE_TYPE eDeviceType,
+									   IMG_HANDLE *phDevCookie);
+
+#endif /* !defined(__PRVRSRV_EXT_H__) */
diff --git a/drivers/staging/imgtec/intel/sysconfig.c b/drivers/staging/imgtec/intel/sysconfig.c
index 2ed7b76..dfd5c03 100644
--- a/drivers/staging/imgtec/intel/sysconfig.c
+++ b/drivers/staging/imgtec/intel/sysconfig.c
@@ -68,56 +68,77 @@
 	struct drm_device *psDRMDev;
 } PLAT_DATA;
 
-PLAT_DATA *gpsPlatData = NULL;
 extern struct drm_device *gpsPVRDRMDev;
 
 /* Unused globals to keep link with 3rdparty components happy */
 IMG_BOOL gbSystemActivePMEnabled;
 IMG_BOOL gbSystemActivePMInit;
 
-/*
-	PCIInitDev
-*/
-static PVRSRV_ERROR PCIInitDev(PLAT_DATA *psPlatData)
+
+PVRSRV_ERROR SysDevInit(void *pvOSDevice, PVRSRV_DEVICE_CONFIG **ppsDevConfig)
 {
-	PVRSRV_DEVICE_CONFIG *psDevice = &sSysConfig.pasDevices[0];
-	PVRSRV_ERROR eError;
+	PVRSRV_DEVICE_CONFIG *psDevice = &sDevices[0];
+	PLAT_DATA *psPlatData;
 	IMG_UINT32 ui32MaxOffset;
 	IMG_UINT32 ui32BaseAddr = 0;
+	PVRSRV_ERROR eError;
+
+	if (psDevice->pvOSDevice)
+	{
+		return PVRSRV_ERROR_INVALID_DEVICE;
+	}
+
+	psPlatData = OSAllocZMem(sizeof(*psPlatData));
+	if (!psPlatData)
+	{
+		return PVRSRV_ERROR_OUT_OF_MEMORY;
+	}
+
+	psDevice->hSysData = (IMG_HANDLE) psPlatData;
 
 	psPlatData->psDRMDev = gpsPVRDRMDev;
 	if (!psPlatData->psDRMDev)
 	{
-		PVR_DPF((PVR_DBG_ERROR,"PCIInitDev: DRM device not initialized"));
-		return PVRSRV_ERROR_NOT_SUPPORTED;
+		PVR_DPF((PVR_DBG_ERROR, "%s: DRM device not initialized", __func__));
+		eError = PVRSRV_ERROR_NOT_SUPPORTED;
+		goto ErrorFreePlatData;
 	}
 
 	if (!IS_MRFLD(psPlatData->psDRMDev))
 	{
-		PVR_DPF((PVR_DBG_ERROR,"PCIInitDev: Device 0x%08x not supported", psPlatData->psDRMDev->pci_device));
-		return PVRSRV_ERROR_NOT_SUPPORTED;
+		PVR_DPF((PVR_DBG_ERROR, "%s: Device 0x%08x not supported", __func__,
+				 psPlatData->psDRMDev->pci_device));
+		eError = PVRSRV_ERROR_NOT_SUPPORTED;
+		goto ErrorFreePlatData;
 	}
 
 	psPlatData->hRGXPCI = OSPCISetDev((void *)psPlatData->psDRMDev->pdev, 0);
 	if (!psPlatData->hRGXPCI)
 	{
-		PVR_DPF((PVR_DBG_ERROR,"PCIInitDev: Failed to acquire PCI device"));
-		return PVRSRV_ERROR_PCI_DEVICE_NOT_FOUND;
+		PVR_DPF((PVR_DBG_ERROR, "%s: Failed to acquire PCI device", __func__));
+		eError = PVRSRV_ERROR_PCI_DEVICE_NOT_FOUND;
+		goto ErrorFreePlatData;
 	}
 
 	ui32MaxOffset = OSPCIAddrRangeLen(psPlatData->hRGXPCI, 0);
 	if (ui32MaxOffset < (RGX_REG_OFFSET + RGX_REG_SIZE))
 	{
-		PVR_DPF((PVR_DBG_ERROR,"PCIInitDev: Device memory region 0x%08x isn't big enough", ui32MaxOffset));
-		return PVRSRV_ERROR_PCI_REGION_TOO_SMALL;
+		PVR_DPF((PVR_DBG_ERROR,
+				 "%s: Device memory region 0x%08x isn't big enough",
+				 __func__, ui32MaxOffset));
+		eError = PVRSRV_ERROR_PCI_REGION_TOO_SMALL;
+		goto ErrorFreePlatData;
 	}
-	PVR_DPF((PVR_DBG_WARNING,"PCIInitDev: Device memory region len 0x%08x", ui32MaxOffset));
+	PVR_DPF((PVR_DBG_WARNING, "%s: Device memory region len 0x%08x",
+			 __func__, ui32MaxOffset));
 
 	/* Reserve the address range */
 	if (OSPCIRequestAddrRange(psPlatData->hRGXPCI, 0) != PVRSRV_OK)
 	{
-		PVR_DPF((PVR_DBG_ERROR,"PCIInitDev: Device memory region not available"));
-		return PVRSRV_ERROR_PCI_REGION_UNAVAILABLE;
+		PVR_DPF((PVR_DBG_ERROR, "%s: Device memory region not available",
+				 __func__));
+		eError = PVRSRV_ERROR_PCI_REGION_UNAVAILABLE;
+		goto ErrorFreePlatData;
 
 	}
 
@@ -125,17 +146,27 @@
 
 	if (OSPCIIRQ(psPlatData->hRGXPCI, &psDevice->ui32IRQ) != PVRSRV_OK)
 	{
-		PVR_DPF((PVR_DBG_ERROR,"PCIInitDev: Couldn't get IRQ"));
+		PVR_DPF((PVR_DBG_ERROR, "%s: Couldn't get IRQ", __func__));
 		eError = PVRSRV_ERROR_INVALID_DEVICE;
 		goto e4;
 	}
-	PVR_DPF((PVR_DBG_WARNING, "PCIInitDev: BaseAddr 0x%08x, EndAddr 0x%llx, IRQ %d",
-			ui32BaseAddr, OSPCIAddrRangeEnd(psPlatData->hRGXPCI, 0), psDevice->ui32IRQ));
+	PVR_DPF((PVR_DBG_WARNING, "%s: BaseAddr 0x%08x, EndAddr 0x%llx, IRQ %d",
+			 __func__, ui32BaseAddr, OSPCIAddrRangeEnd(psPlatData->hRGXPCI, 0),
+			 psDevice->ui32IRQ));
 
 	psDevice->sRegsCpuPBase.uiAddr = ui32BaseAddr + RGX_REG_OFFSET;
 	psDevice->ui32RegsSize = RGX_REG_SIZE;
-	PVR_DPF((PVR_DBG_WARNING, "PCIInitDev: sRegsCpuPBase 0x%llx, size 0x%x",
-			psDevice->sRegsCpuPBase.uiAddr, psDevice->ui32RegsSize));
+	PVR_DPF((PVR_DBG_WARNING, "%s: sRegsCpuPBase 0x%llx, size 0x%x",
+			__func__, psDevice->sRegsCpuPBase.uiAddr, psDevice->ui32RegsSize));
+
+	/* Setup other system specific stuff */
+#if defined(SUPPORT_ION)
+	IonInit(NULL);
+#endif
+
+	psDevice->pvOSDevice = pvOSDevice;
+
+	*ppsDevConfig = psDevice;
 
 	return PVRSRV_OK;
 
@@ -143,88 +174,35 @@
 	OSPCIReleaseAddrRange(psPlatData->hRGXPCI, 0);
 	OSPCIReleaseDev(psPlatData->hRGXPCI);
 
+ErrorFreePlatData:
+	OSFreeMem(psPlatData);
+	psDevice->hSysData = NULL;
+
 	return eError;
 }
 
-/*!
-******************************************************************************
-
- @Function		PCIDeInitDev
-
- @Description
-
- Uninitialise the PCI device when it is no loger required
-
- @Input		psSysData :	System data
-
- @Return	none
-
-******************************************************************************/
-static void PCIDeInitDev(PLAT_DATA *psPlatData)
+void SysDevDeInit(PVRSRV_DEVICE_CONFIG *psDevConfig)
 {
+	PLAT_DATA *psPlatData = (PLAT_DATA *) psDevConfig->hSysData;
+
 	OSPCIReleaseAddrRange(psPlatData->hRGXPCI, 0);
 	OSPCIReleaseDev(psPlatData->hRGXPCI);
-}
-
-
-PVRSRV_ERROR SysCreateConfigData(PVRSRV_SYSTEM_CONFIG **ppsSysConfig, void *hDevice)
-{
-	PLAT_DATA *psPlatData;
-	PVRSRV_ERROR eError;
-
-	PVR_UNREFERENCED_PARAMETER(hDevice);
-
-	psPlatData = OSAllocZMem(sizeof(*psPlatData));
-
-	/* Query the Emu for reg and IRQ information */
-	eError = PCIInitDev(psPlatData);
-	if (eError != PVRSRV_OK)
-	{
-		goto e0;
-	}
-
-	/* Save data for this device */
-	sSysConfig.pasDevices[0].hSysData = (IMG_HANDLE) psPlatData;
-
-	/* Save private data for the physical memory heap */
-	gsPhysHeapConfig[0].hPrivData = (IMG_HANDLE) psPlatData;
-
-#if defined(SUPPORT_TRUSTED_DEVICE)
-	#error "Not supported services/3rdparty/intel_drm/sysconfig.c"
-	gsPhysHeapConfig[1].hPrivData = NULL;
-#endif
-
-	*ppsSysConfig = &sSysConfig;
-
-	gpsPlatData = psPlatData;
-
-
-	/* Setup other system specific stuff */
-#if defined(SUPPORT_ION)
-	IonInit(NULL);
-#endif
-
-	return PVRSRV_OK;
-e0:
-	return eError;
-}
-
-void SysDestroyConfigData(PVRSRV_SYSTEM_CONFIG *psSysConfig)
-{
-	PLAT_DATA *psPlatData = gpsPlatData;
-
-	PVR_UNREFERENCED_PARAMETER(psSysConfig);
-	PCIDeInitDev(psPlatData);
-	OSFreeMem(psPlatData);
 
 #if defined(SUPPORT_ION)
 	IonDeinit();
 #endif
+
+	OSFreeMem(psPlatData);
+	psDevConfig->hSysData = NULL;
+
+	psDevConfig->pvOSDevice = NULL;
 }
 
-PVRSRV_ERROR SysDebugInfo(PVRSRV_SYSTEM_CONFIG *psSysConfig, DUMPDEBUG_PRINTF_FUNC *pfnDumpDebugPrintf, void *pvDumpDebugFile)
+PVRSRV_ERROR SysDebugInfo(PVRSRV_DEVICE_CONFIG *psDevConfig,
+				DUMPDEBUG_PRINTF_FUNC *pfnDumpDebugPrintf,
+				void *pvDumpDebugFile)
 {
-	PVR_UNREFERENCED_PARAMETER(psSysConfig);
+	PVR_UNREFERENCED_PARAMETER(psDevConfig);
 	PVR_UNREFERENCED_PARAMETER(pfnDumpDebugPrintf);
 	PVR_UNREFERENCED_PARAMETER(pvDumpDebugFile);
 	return PVRSRV_OK;
@@ -263,6 +241,7 @@
 }
 
 static PVRSRV_ERROR SysDevicePrePowerState(
+		IMG_HANDLE hSysData,
 		PVRSRV_DEV_POWER_STATE eNewPowerState,
 		PVRSRV_DEV_POWER_STATE eCurrentPowerState,
 		IMG_BOOL bForced)
@@ -283,6 +262,7 @@
 }
 
 static PVRSRV_ERROR SysDevicePostPowerState(
+		IMG_HANDLE hSysData,
 		PVRSRV_DEV_POWER_STATE eNewPowerState,
 		PVRSRV_DEV_POWER_STATE eCurrentPowerState,
 		IMG_BOOL bForced)
@@ -304,8 +284,9 @@
 
 typedef int (*psb_irq_handler_t)(void *data);
 
-PVRSRV_ERROR SysInstallDeviceLISR(IMG_UINT32 ui32IRQ,
-				  IMG_CHAR *pszName,
+PVRSRV_ERROR SysInstallDeviceLISR(IMG_HANDLE hSysData,
+				  IMG_UINT32 ui32IRQ,
+				  const IMG_CHAR *pszName,
 				  PFN_LISR pfnLISR,
 				  void *pvData,
 				  IMG_HANDLE *phLISRData)
@@ -322,11 +303,6 @@
 
 }
 
-SYS_PHYS_ADDRESS_MASK SysDevicePhysAddressMask(void)
-{
-	return SYS_PHYS_ADDRESS_64_BIT;
-}
-
 /******************************************************************************
  End of file (sysconfig.c)
 ******************************************************************************/
diff --git a/drivers/staging/imgtec/intel/sysconfig.h b/drivers/staging/imgtec/intel/sysconfig.h
index 9ae9ea2..1f27526 100644
--- a/drivers/staging/imgtec/intel/sysconfig.h
+++ b/drivers/staging/imgtec/intel/sysconfig.h
@@ -59,11 +59,13 @@
 		IMG_DEV_PHYADDR *psDevPAddr);
 
 static PVRSRV_ERROR SysDevicePostPowerState(
+		IMG_HANDLE hSysData,
 		PVRSRV_DEV_POWER_STATE eNewPowerState,
 		PVRSRV_DEV_POWER_STATE eCurrentPowerState,
 		IMG_BOOL bForced);
 
 static PVRSRV_ERROR SysDevicePrePowerState(
+		IMG_HANDLE hSysData,
 		PVRSRV_DEV_POWER_STATE eNewPowerState,
 		PVRSRV_DEV_POWER_STATE eCurrentPowerState,
 		IMG_BOOL bForced);
@@ -112,13 +114,14 @@
 static PVRSRV_DEVICE_CONFIG sDevices[] =
 {
 	{
-		.eDeviceType		= PVRSRV_DEVICE_TYPE_RGX,
-		.pszName		= "RGX",
+		.pszName		= "moorefield",
+		.pszVersion		= NULL,
 
 		/* Device setup information */
 		.sRegsCpuPBase		= { 0 },
 		.ui32RegsSize		= 0,
 		.ui32IRQ		= 0,
+		.eCacheSnoopingMode	= PVRSRV_DEVICE_SNOOP_CPU_ONLY,
 
 		/* No power management on no HW system */
 		.pfnPrePowerState	= SysDevicePrePowerState,
@@ -127,33 +130,21 @@
 		.hDevData		= &sRGXData,
 		.hSysData		= NULL,
 
-		.aui32PhysHeapID	= { 0, 0, 0 },
-	}
-};
-
-static PVRSRV_SYSTEM_CONFIG sSysConfig =
-{
-	.pszSystemName			= "Merrifield with Rogue",
-	.uiDeviceCount			= sizeof(sDevices) /
-					  sizeof(PVRSRV_DEVICE_CONFIG),
-	.pasDevices			= &sDevices[0],
-
-	/* Physcial memory heaps */
-	.ui32PhysHeapCount		= sizeof(gsPhysHeapConfig) /
+		/* Physical memory heaps */
+		.ui32PhysHeapCount	= sizeof(gsPhysHeapConfig) /
 					  sizeof(PHYS_HEAP_CONFIG),
-	.pasPhysHeaps			= &(gsPhysHeapConfig[0]),
+		.pasPhysHeaps		= &gsPhysHeapConfig[0],
 
-	/* No power management on no HW system */
-	.pfnSysPrePowerState		= NULL,
-	.pfnSysPostPowerState		= NULL,
+		.aui32PhysHeapID	= { 0, 0, 0 },
 
-	.pui32BIFTilingHeapConfigs	=
-		&gauiBIFTilingHeapXStrides[0],
-	.ui32BIFTilingHeapCount		=
-		IMG_ARR_NUM_ELEMS(gauiBIFTilingHeapXStrides),
-
-	/* no cache snooping */
-	.eCacheSnoopingMode		= PVRSRV_SYSTEM_SNOOP_CPU_ONLY,
+		/* BIF Tiling mode configuration */
+		.eBIFTilingMode		= RGXFWIF_BIFTILINGMODE_256x16,
+		.pui32BIFTilingHeapConfigs =
+			&gauiBIFTilingHeapXStrides[0],
+		.ui32BIFTilingHeapCount	=
+			IMG_ARR_NUM_ELEMS(gauiBIFTilingHeapXStrides),
+		.pfnSysDevFeatureDepInit = NULL
+	}
 };
 
 #define VENDOR_ID_MERRIFIELD	0x8086
diff --git a/drivers/staging/imgtec/intel/sysinfo.h b/drivers/staging/imgtec/intel/sysinfo.h
index f1ea269..d1a8b0a 100644
--- a/drivers/staging/imgtec/intel/sysinfo.h
+++ b/drivers/staging/imgtec/intel/sysinfo.h
@@ -53,14 +53,6 @@
 #define FATAL_ERROR_DETECTION_POLL_MS  (10000)
 #define WAIT_TRY_COUNT                 (10000)
 
-#define SYS_DEVICE_COUNT 3 /* RGX, DISPLAY (external), BUFFER (external) */
-
-#if defined(SUPPORT_TRUSTED_DEVICE)
-#define SYS_PHYS_HEAP_COUNT		2
-#else
-#define SYS_PHYS_HEAP_COUNT		1
-#endif
-
 #define SYS_RGX_DEV_VENDOR_ID		0x8086
 #define SYS_RGX_DEV_DEVICE_ID		0x1180
 
@@ -74,18 +66,4 @@
 */
 #define RGX_CORE_CLOCK_SPEED_DEFAULT	(400000000)
 
-#if defined(__linux__)
-#define SYS_RGX_DEV_NAME    "Merrifield"
-#if defined(SUPPORT_DRM)
-/*
- * Use the static bus ID for the platform DRM device.
- */
-#if defined(PVR_DRM_DEV_BUS_ID)
-#define	SYS_RGX_DEV_DRM_BUS_ID	PVR_DRM_DEV_BUS_ID
-#else
-#define SYS_RGX_DEV_DRM_BUS_ID	"platform:Merrifield"
-#endif	/* defined(PVR_DRM_DEV_BUS_ID) */
-#endif	/* defined(SUPPORT_DRM) */
-#endif
-
 #endif	/* !defined(__SYSINFO_H__) */
diff --git a/drivers/staging/imgtec/intel/video/common/psb_ttm_glue.c b/drivers/staging/imgtec/intel/video/common/psb_ttm_glue.c
index 18aa72a..5ee6d39 100644
--- a/drivers/staging/imgtec/intel/video/common/psb_ttm_glue.c
+++ b/drivers/staging/imgtec/intel/video/common/psb_ttm_glue.c
@@ -50,8 +50,15 @@
 extern int sepapp_drm_playback(bool ied_status);
 static int ied_enabled;
 
-static void ann_rm_workaround_ctx(struct drm_psb_private *dev_priv, uint64_t ctx_type);
-static void ann_add_workaround_ctx(struct drm_psb_private *dev_priv, uint64_t ctx_type);
+enum slc_setting {
+	enable_slc,
+	disable_slc,
+};
+
+static void ann_workaround_ctx_set_slc(struct drm_psb_private *dev_priv,
+		uint64_t ctx_type, enum slc_setting slc_set);
+
+#define MB_SIZE 16
 
 #ifdef MERRIFIELD
 struct psb_fpriv *psb_fpriv(struct drm_file *file_priv)
@@ -295,7 +302,8 @@
 				  (found_ctx->ctx_type >> 8) & 0xff,
 				  (found_ctx->ctx_type & 0xff));
 		if (IS_ANN(dev))
-			ann_rm_workaround_ctx(dev_priv, found_ctx->ctx_type);
+			ann_workaround_ctx_set_slc(dev_priv, ctx_type,
+					enable_slc);
 #ifndef CONFIG_DRM_VXD_BYT
 		/* if current ctx points to it, set to NULL */
 		if ((VAEntrypointEncSlice ==
@@ -459,7 +467,8 @@
 		video_ctx->ctx_type = ctx_type;
 		video_ctx->cur_sequence = 0xffffffff;
 		if (IS_ANN(dev))
-			ann_add_workaround_ctx(dev_priv, ctx_type);
+			ann_workaround_ctx_set_slc(dev_priv, ctx_type,
+					disable_slc);
 #ifdef CONFIG_SLICE_HEADER_PARSING
 		video_ctx->frame_end_seq = 0xffffffff;
 		if (ctx_type & VA_RT_FORMAT_PROTECTED) {
@@ -520,14 +529,17 @@
 		else {
 			mutex_lock(&g_ied_mutex);
 			DRM_INFO("Video: ied_ref: %d\n", g_ied_ref);
-			while (g_ied_ref) {
-				ret = sepapp_drm_playback(false);
-				if (ret) {
-					DRM_ERROR("IED Clean-up \
-						Failed:0x%x\n", ret);
-					break;
+			/* To make sure no IED session still working. */
+			if (list_empty(&dev_priv->video_ctx)) {
+				while (g_ied_ref) {
+					ret = sepapp_drm_playback(false);
+					if (ret) {
+						DRM_ERROR("IED Clean-up \
+							Failed:0x%x\n", ret);
+						break;
+					}
+					g_ied_ref--;
 				}
-				g_ied_ref--;
 			}
 			mutex_unlock(&g_ied_mutex);
 		}
@@ -750,19 +762,22 @@
 	return 0;
 }
 
-/* SLC bug: there is green corruption for vc1 decode if width is not 64 aligned
- * Recode the number of VC1 ctx whose width is not 64 aligned
+/*
+ * SLC bug: there is green corruption for VC1/VP8/H.264 decode if:
+ * 1. VC1/VP8 width is not 64 aligned. Recode the number of VC1 ctx whose width
+ * is not 64 aligned;
+ * 2. H.264 resolution <= 720p.
  */
-static void ann_add_workaround_ctx(struct drm_psb_private *dev_priv, uint64_t ctx_type)
+static void ann_workaround_ctx_set_slc(struct drm_psb_private *dev_priv,
+		uint64_t ctx_type, enum slc_setting slc_set)
 {
 
 	struct msvdx_private *msvdx_priv;
 	int profile = (ctx_type >> 8) & 0xff;
-
-	if (profile != VAProfileVC1Simple &&
-	    profile != VAProfileVC1Main &&
-	    profile != VAProfileVC1Advanced)
-		return;
+	/* ctx_type >> 32 is width_in_mb */
+	uint64_t width = ((ctx_type >> 32) & 0xffff) * MB_SIZE;
+	/* ctx_type >> 48 is height_in_mb */
+	uint64_t height = ((ctx_type >> 48) & 0xffff) * MB_SIZE;
 
 	if (unlikely(!dev_priv))
 		return;
@@ -771,41 +786,32 @@
 	if (unlikely(!msvdx_priv))
 		return;
 
-	PSB_DEBUG_GENERAL(
-	    "add vc1 ctx, ctx_type is 0x%llx\n",
-		ctx_type);
+	switch (profile) {
+	case VAProfileVC1Simple:
+	case VAProfileVC1Main:
+	case VAProfileVC1Advanced:
+	case VAProfileVP8Version0_3:
+		if (width % 64) {
+			if (slc_set == disable_slc)
+				atomic_inc(&msvdx_priv->slc_workaround_ctx);
+			else
+				atomic_dec(&msvdx_priv->slc_workaround_ctx);
+		}
+		break;
 
-	/* ctx_type >> 32 is width_in_mb */
-	if ((ctx_type >> 32) % 4) {
-		atomic_inc(&msvdx_priv->vc1_workaround_ctx);
-		PSB_DEBUG_GENERAL("add workaround ctx %p in ctx\n", msvdx_priv);
-	}
-}
+	case VAProfileH264Baseline:
+	case VAProfileH264Main:
+	case VAProfileH264High:
+		if (((height == 128) && (width > 112) && (width <= 128)) ||
+				((width <= 1280) && (height <= 736))) {
+			if (slc_set == disable_slc)
+				atomic_inc(&msvdx_priv->slc_workaround_ctx);
+			else
+				atomic_dec(&msvdx_priv->slc_workaround_ctx);
+		}
+		break;
 
-static void ann_rm_workaround_ctx(struct drm_psb_private *dev_priv, uint64_t ctx_type)
-{
-
-	struct msvdx_private *msvdx_priv;
-	int profile = (ctx_type >> 8) & 0xff;
-
-	if (profile != VAProfileVC1Simple &&
-	    profile != VAProfileVC1Main &&
-	    profile != VAProfileVC1Advanced)
-		return;
-
-	if (unlikely(!dev_priv))
-		return;
-
-	msvdx_priv = dev_priv->msvdx_private;
-	if (unlikely(!msvdx_priv))
-		return;
-
-	PSB_DEBUG_GENERAL(
-	    "rm vc1 ctx, ctx_type is 0x%llx\n",
-		ctx_type);
-	/* ctx_type >> 32 is width_in_mb */
-	if ((ctx_type >> 32) % 4) {
-		atomic_dec(&msvdx_priv->vc1_workaround_ctx);
-		PSB_DEBUG_GENERAL("dec workaround ctx %p in ctx\n", msvdx_priv);
+	default:
+		break;
 	}
 }
diff --git a/drivers/staging/imgtec/intel/video/decode/psb_msvdx.h b/drivers/staging/imgtec/intel/video/decode/psb_msvdx.h
index 0dc8fed..6cb6376 100644
--- a/drivers/staging/imgtec/intel/video/decode/psb_msvdx.h
+++ b/drivers/staging/imgtec/intel/video/decode/psb_msvdx.h
@@ -276,7 +276,7 @@
 	uint32_t term_buf_addr;
 #endif
 
-	atomic_t vc1_workaround_ctx;
+	atomic_t slc_workaround_ctx;
 
 #ifdef CONFIG_ION
 	struct list_head ion_buffers_list;
diff --git a/drivers/staging/imgtec/powervr/buffer_attribs.h b/drivers/staging/imgtec/powervr/buffer_attribs.h
new file mode 100644
index 0000000..4c75e7c
--- /dev/null
+++ b/drivers/staging/imgtec/powervr/buffer_attribs.h
@@ -0,0 +1,84 @@
+/*************************************************************************/ /*!
+@File
+@Title          3D types for use by IMG APIs
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@License        MIT
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+*/ /**************************************************************************/
+#ifndef _POWERVR_BUFFER_ATTRIBS_H_
+#define _POWERVR_BUFFER_ATTRIBS_H_
+
+/**
+ * Memory layouts
+ * Defines how pixels are laid out within a surface.
+ */
+typedef enum
+{
+	IMG_MEMLAYOUT_STRIDED,       /**< Resource is strided, one row at a time */
+	IMG_MEMLAYOUT_TWIDDLED,      /**< Resource is 2D twiddled, classic style */
+	IMG_MEMLAYOUT_3DTWIDDLED,    /**< Resource is 3D twiddled, classic style */
+	IMG_MEMLAYOUT_TILED,         /**< Resource is tiled, tiling config specified elsewhere. */
+	IMG_MEMLAYOUT_PAGETILED,     /**< Resource is pagetiled */
+} IMG_MEMLAYOUT;
+
+/**
+ * Rotation types
+ */
+typedef enum
+{
+	IMG_ROTATION_0DEG = 0,
+	IMG_ROTATION_90DEG = 1,
+	IMG_ROTATION_180DEG = 2,
+	IMG_ROTATION_270DEG = 3,
+	IMG_ROTATION_FLIP_Y = 4,
+
+	IMG_ROTATION_BAD = 255,
+} IMG_ROTATION;
+
+/**
+ * Alpha types.
+ */
+typedef enum
+{
+	IMG_COLOURSPACE_FORMAT_UNKNOWN   =  0x00000000,  /**< Colourspace Format: Unknown */
+	IMG_COLOURSPACE_FORMAT_LINEAR    =  0x00010000,  /**< Colourspace Format: Linear */
+	IMG_COLOURSPACE_FORMAT_NONLINEAR =  0x00020000,  /**< Colourspace Format: Non-Linear */
+	IMG_COLOURSPACE_FORMAT_MASK      =  0x000F0000,  /**< Colourspace Format Mask */
+} IMG_COLOURSPACE_FORMAT;
+
+/**
+ * Types of framebuffer compression
+ */
+typedef enum
+{
+	IMG_FB_COMPRESSION_NONE,
+	IMG_FB_COMPRESSION_DIRECT_8x8,
+	IMG_FB_COMPRESSION_DIRECT_16x4,
+	IMG_FB_COMPRESSION_DIRECT_32x2,
+	IMG_FB_COMPRESSION_INDIRECT_8x8,
+	IMG_FB_COMPRESSION_INDIRECT_16x4,
+	IMG_FB_COMPRESSION_INDIRECT_4TILE_8x8,
+	IMG_FB_COMPRESSION_INDIRECT_4TILE_16x4
+} IMG_FB_COMPRESSION;
+
+
+#endif /* _POWERVR_BUFFER_ATTRIBS_H_ */
diff --git a/drivers/staging/imgtec/powervr/imgpixfmts.h b/drivers/staging/imgtec/powervr/imgpixfmts.h
new file mode 100644
index 0000000..ec9b615
--- /dev/null
+++ b/drivers/staging/imgtec/powervr/imgpixfmts.h
@@ -0,0 +1,77 @@
+/*************************************************************************/ /*!
+@File
+@Title          Pixel formats
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@License        MIT
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+*/ /**************************************************************************/
+
+/****************************************************************************
+ **
+ ** WARNING: This file is autogenerated - DO NOT EDIT.
+ **
+ ** See fmts_systable.txt to add new formats.
+ ****************************************************************************/
+
+#if !defined(_IMGPIXFMTS_H_)
+#define _IMGPIXFMTS_H_
+
+#include "powervr/imgyuv.h"
+
+typedef enum _IMG_PIXFMT_
+{
+	IMG_PIXFMT_UNKNOWN = 0,
+	IMG_PIXFMT_R8G8B8A8_UNORM = 32,
+	IMG_PIXFMT_R8G8B8X8_UNORM = 37,
+	IMG_PIXFMT_D32_FLOAT = 51,
+	IMG_PIXFMT_R8G8_UNORM = 62,
+	IMG_PIXFMT_R8_UNORM = 76,
+	IMG_PIXFMT_S8_UINT = 81,
+	IMG_PIXFMT_B5G6R5_UNORM = 85,
+	IMG_PIXFMT_R5G6B5_UNORM = 86,
+	IMG_PIXFMT_B5G5R5A1_UNORM = 87,
+	IMG_PIXFMT_B5G5R5X1_UNORM = 88,
+	IMG_PIXFMT_B8G8R8A8_UNORM = 89,
+	IMG_PIXFMT_B8G8R8X8_UNORM = 90,
+	IMG_PIXFMT_L8_UNORM = 136,
+	IMG_PIXFMT_L8A8_UNORM = 138,
+	IMG_PIXFMT_B4G4R4A4_UNORM = 145,
+	IMG_PIXFMT_UYVY = 171,
+	IMG_PIXFMT_VYUY = 172,
+	IMG_PIXFMT_YUYV = 173,
+	IMG_PIXFMT_YVYU = 174,
+	IMG_PIXFMT_YVU420_2PLANE = 175,
+	IMG_PIXFMT_YUV420_2PLANE = 176,
+	IMG_PIXFMT_YVU420_2PLANE_MACRO_BLOCK = 177,
+	IMG_PIXFMT_YUV420_3PLANE = 178,
+	IMG_PIXFMT_YVU420_3PLANE = 179,
+	IMG_PIXFMT_V8U8Y8A8 = 184,
+	IMG_PIXFMT_YUV8_422_2PLANE_PACK8 = 207,
+	IMG_PIXFMT_YUV8_444_3PLANE_PACK8 = 208,
+	IMG_PIXFMT_YVU8_420_2PLANE_PACK8_P = 245,
+	IMG_PIXFMT_YUV8_420_2PLANE_PACK8_P = 249,
+	IMG_PIXFMT_UYVY10_422_1PLANE_PACK10_CUST1 = 252,
+} IMG_PIXFMT;
+
+
+
+#endif /* _IMGPIXFMTS_H_ */
diff --git a/drivers/staging/imgtec/powervr/imgyuv.h b/drivers/staging/imgtec/powervr/imgyuv.h
new file mode 100644
index 0000000..a91ee10
--- /dev/null
+++ b/drivers/staging/imgtec/powervr/imgyuv.h
@@ -0,0 +1,58 @@
+/*************************************************************************/ /*!
+@File
+@Title          YUV defines
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@License        MIT
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+*/ /**************************************************************************/
+
+#if !defined(_IMGYUV_H_)
+#define _IMGYUV_H_
+
+typedef enum
+{
+	IMG_COLORSPACE_UNDEFINED = 0,
+	IMG_COLORSPACE_BT601_CONFORMANT_RANGE = 1,
+	IMG_COLORSPACE_BT601_FULL_RANGE = 2,
+	IMG_COLORSPACE_BT709_CONFORMANT_RANGE = 3,
+	IMG_COLORSPACE_BT709_FULL_RANGE = 4,
+	IMG_COLORSPACE_BT2020_CONFORMANT_RANGE = 5,
+	IMG_COLORSPACE_BT2020_FULL_RANGE = 6,
+	IMG_COLORSPACE_BT601_CONFORMANT_RANGE_INVERSE = 7,
+	IMG_COLORSPACE_BT601_FULL_RANGE_INVERSE = 8,
+	IMG_COLORSPACE_BT709_CONFORMANT_RANGE_INVERSE = 9,
+	IMG_COLORSPACE_BT709_FULL_RANGE_INVERSE = 10,
+	IMG_COLORSPACE_BT2020_CONFORMANT_RANGE_INVERSE = 11,
+	IMG_COLORSPACE_BT2020_FULL_RANGE_INVERSE = 12
+} IMG_YUV_COLORSPACE;
+
+typedef enum
+{
+	IMG_CHROMA_INTERP_UNDEFINED = 0,
+	IMG_CHROMA_INTERP_ZERO = 1,
+	IMG_CHROMA_INTERP_QUARTER = 2,
+	IMG_CHROMA_INTERP_HALF = 3,
+	IMG_CHROMA_INTERP_THREEQUARTERS = 4
+} IMG_YUV_CHROMA_INTERP;
+
+
+#endif /* _IMGYUV_H_ */
diff --git a/drivers/staging/imgtec/powervr/mem_types.h b/drivers/staging/imgtec/powervr/mem_types.h
new file mode 100644
index 0000000..ee8a289
--- /dev/null
+++ b/drivers/staging/imgtec/powervr/mem_types.h
@@ -0,0 +1,62 @@
+/*************************************************************************/ /*!
+@File
+@Title          Public types
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@License        MIT
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+*/ /**************************************************************************/
+
+#ifndef _POWERVR_TYPES_H_
+#define _POWERVR_TYPES_H_
+
+#if defined (__cplusplus)
+extern "C" {
+#endif
+
+#if defined(_MSC_VER)
+	#include "msvc_types.h"
+#elif defined(LINUX) && defined(__KERNEL__)
+	#include <linux/types.h>
+#else
+	#include <stdint.h>
+#endif
+
+typedef void *IMG_CPU_VIRTADDR;
+
+/* device virtual address */
+typedef struct _IMG_DEV_VIRTADDR
+{
+	uint64_t  uiAddr;
+#define IMG_CAST_TO_DEVVADDR_UINT(var)		(uint64_t)(var)
+	
+} IMG_DEV_VIRTADDR;
+
+typedef uint64_t IMG_DEVMEM_SIZE_T;
+typedef uint64_t IMG_DEVMEM_ALIGN_T;
+typedef uint64_t IMG_DEVMEM_OFFSET_T;
+typedef uint32_t IMG_DEVMEM_LOG2ALIGN_T;
+
+#if defined (__cplusplus)
+}
+#endif
+
+#endif
diff --git a/drivers/staging/imgtec/powervr/sync_external.h b/drivers/staging/imgtec/powervr/sync_external.h
new file mode 100644
index 0000000..f74ab15
--- /dev/null
+++ b/drivers/staging/imgtec/powervr/sync_external.h
@@ -0,0 +1,86 @@
+/*************************************************************************/ /*!
+@File
+@Title          Services external synchronisation interface header
+@Description    Defines synchronisation structures that are visible internally
+                and externally
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@License        MIT
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+*/ /**************************************************************************/
+
+#ifndef _SYNC_EXTERNAL_
+#define _SYNC_EXTERNAL_
+
+#if defined (__cplusplus)
+extern "C" {
+#endif
+
+#include <powervr/mem_types.h>
+
+/*!
+ * Maximum byte length for a sync prim name
+ */
+#define SYNC_MAX_CLASS_NAME_LEN 32
+
+/*!
+ * Number of sync primitives in operations
+ */
+#define	PVRSRV_MAX_SYNC_PRIMS 32
+
+typedef void* PVRSRV_CLIENT_SYNC_PRIM_HANDLE;
+typedef void* SYNC_BRIDGE_HANDLE;
+typedef struct SYNC_PRIM_CONTEXT *PSYNC_PRIM_CONTEXT;
+typedef struct _SYNC_OP_COOKIE_ *PSYNC_OP_COOKIE;
+
+/*!
+ * Client sync prim definition holding a CPU accessible address
+ *
+ *   Structure: #PVRSRV_CLIENT_SYNC_PRIM
+ *   Typedef: ::PVRSRV_CLIENT_SYNC_PRIM
+ */
+typedef struct PVRSRV_CLIENT_SYNC_PRIM
+{
+	volatile uint32_t	*pui32LinAddr;	/*!< User pointer to the primitive */
+} PVRSRV_CLIENT_SYNC_PRIM;
+
+/*!
+ * Bundled information for a sync prim operation
+ *
+ *   Structure: #PVRSRV_CLIENT_SYNC_PRIM_OP
+ *   Typedef: ::PVRSRV_CLIENT_SYNC_PRIM_OP
+ */
+typedef struct PVRSRV_CLIENT_SYNC_PRIM_OP
+{
+	#define PVRSRV_CLIENT_SYNC_PRIM_OP_CHECK	(1 << 0)
+	#define PVRSRV_CLIENT_SYNC_PRIM_OP_UPDATE	(1 << 1)
+	#define PVRSRV_CLIENT_SYNC_PRIM_OP_UNFENCED_UPDATE (PVRSRV_CLIENT_SYNC_PRIM_OP_UPDATE | (1<<2))
+	uint32_t                    ui32Flags;       /*!< Operation flags: PVRSRV_CLIENT_SYNC_PRIM_OP_XXX */
+	PVRSRV_CLIENT_SYNC_PRIM    *psSync;          /*!< Pointer to the client sync primitive */
+	uint32_t                    ui32FenceValue;  /*!< The Fence value (only used if PVRSRV_CLIENT_SYNC_PRIM_OP_CHECK is set) */
+	uint32_t                    ui32UpdateValue; /*!< The Update value (only used if PVRSRV_CLIENT_SYNC_PRIM_OP_UPDATE is set) */
+} PVRSRV_CLIENT_SYNC_PRIM_OP;
+
+#if defined (__cplusplus)
+}
+#endif
+
+#endif /* _SYNC_EXTERNAL_ */
diff --git a/drivers/staging/imgtec/pvr_drm.c b/drivers/staging/imgtec/pvr_drm.c
new file mode 100644
index 0000000..7daabe0
--- /dev/null
+++ b/drivers/staging/imgtec/pvr_drm.c
@@ -0,0 +1,266 @@
+/* -*- mode: c; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
+/* vi: set ts=8 sw=8 sts=8: */
+/*************************************************************************/ /*!
+@File
+@Title          PowerVR DRM driver
+@Codingstyle    LinuxKernel
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#include <drm/drm.h>
+#include <drm/drmP.h> /* include before drm_crtc.h for kernels older than 3.9 */
+#include <drm/drm_crtc.h>
+#include <linux/device.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/pm.h>
+#include <linux/version.h>
+
+#include "module_common.h"
+#include "pvr_drm.h"
+#include "pvr_drv.h"
+#include "pvrversion.h"
+#include "services_kernel_client.h"
+
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 12, 0))
+#define DRIVER_RENDER 0
+#define DRM_RENDER_ALLOW 0
+#endif
+
+#define PVR_DRM_DRIVER_NAME PVR_DRM_NAME
+#define PVR_DRM_DRIVER_DESC "Imagination Technologies PVR DRM"
+#define	PVR_DRM_DRIVER_DATE "20110701"
+
+
+static int pvr_pm_suspend(struct device *dev)
+{
+	struct drm_device *ddev = dev_get_drvdata(dev);
+
+	DRM_DEBUG_DRIVER("device %p\n", dev);
+
+	return PVRSRVCommonDeviceSuspend(ddev->dev_private);
+}
+
+static int pvr_pm_resume(struct device *dev)
+{
+	struct drm_device *ddev = dev_get_drvdata(dev);
+
+	DRM_DEBUG_DRIVER("device %p\n", dev);
+
+	return PVRSRVCommonDeviceResume(ddev->dev_private);
+}
+
+const struct dev_pm_ops pvr_pm_ops = {
+	.suspend = pvr_pm_suspend,
+	.resume = pvr_pm_resume,
+};
+
+
+static int pvr_drm_load(struct drm_device *ddev, unsigned long flags)
+{
+	struct _PVRSRV_DEVICE_NODE_ *dev_node;
+	enum PVRSRV_ERROR srv_err;
+	int err;
+
+	DRM_DEBUG_DRIVER("device %p\n", ddev->dev);
+
+	/*
+	 * The equivalent is done for PCI modesetting drivers by
+	 * drm_get_pci_dev()
+	 */
+	if (ddev->platformdev)
+		platform_set_drvdata(ddev->platformdev, ddev);
+
+	srv_err = PVRSRVDeviceCreate(ddev->dev, &dev_node);
+	if (srv_err != PVRSRV_OK) {
+		DRM_ERROR("failed to create device node for device %p (%s)\n",
+			  ddev->dev, PVRSRVGetErrorStringKM(srv_err));
+		if (srv_err == PVRSRV_ERROR_PROBE_DEFER)
+			err = -EPROBE_DEFER;
+		else
+			err = -ENODEV;
+		goto err_exit;
+	}
+
+	err = PVRSRVCommonDeviceInit(dev_node);
+	if (err) {
+		DRM_ERROR("device %p initialisation failed (err=%d)\n",
+			  ddev->dev, err);
+		goto err_device_destroy;
+	}
+
+	drm_mode_config_init(ddev);
+	ddev->dev_private = dev_node;
+
+	return 0;
+
+err_device_destroy:
+	PVRSRVDeviceDestroy(dev_node);
+err_exit:
+	return err;
+}
+
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 11, 0))
+static int pvr_drm_unload(struct drm_device *ddev)
+#else
+static void pvr_drm_unload(struct drm_device *ddev)
+#endif
+{
+	DRM_DEBUG_DRIVER("device %p\n", ddev->dev);
+
+	drm_mode_config_cleanup(ddev);
+
+	PVRSRVCommonDeviceDeinit(ddev->dev_private);
+
+	PVRSRVDeviceDestroy(ddev->dev_private);
+	ddev->dev_private = NULL;
+
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 11, 0))
+	return 0;
+#endif
+}
+
+static int pvr_drm_open(struct drm_device *ddev, struct drm_file *dfile)
+{
+	int err;
+
+	if (!try_module_get(THIS_MODULE)) {
+		DRM_ERROR("failed to get module reference\n");
+		return -ENOENT;
+	}
+
+	err = PVRSRVCommonDeviceOpen(ddev->dev_private, dfile);
+	if (err)
+		module_put(THIS_MODULE);
+
+	return err;
+}
+
+static void pvr_drm_release(struct drm_device *ddev, struct drm_file *dfile)
+{
+	PVRSRVCommonDeviceRelease(ddev->dev_private, dfile);
+
+	module_put(THIS_MODULE);
+}
+
+/*
+ * The DRM global lock is taken for ioctls unless the DRM_UNLOCKED flag is set.
+ * If you revise one of the driver specific ioctls, or add a new one, that has
+ * DRM_UNLOCKED set then consider whether the gPVRSRVLock mutex needs to be
+ * taken.
+ */
+static struct drm_ioctl_desc pvr_drm_ioctls[] = {
+	DRM_IOCTL_DEF_DRV(PVR_SRVKM_CMD, PVRSRV_BridgeDispatchKM, DRM_RENDER_ALLOW | DRM_UNLOCKED),
+#if defined(PDUMP)
+	DRM_IOCTL_DEF_DRV(PVR_DBGDRV_CMD, dbgdrv_ioctl, DRM_RENDER_ALLOW | DRM_AUTH | DRM_UNLOCKED),
+#endif
+};
+
+#if defined(CONFIG_COMPAT)
+#if defined(PDUMP)
+static drm_ioctl_compat_t *pvr_drm_compat_ioctls[] = {
+	[DRM_PVR_DBGDRV_CMD] = dbgdrv_ioctl_compat,
+};
+#endif
+
+static long pvr_compat_ioctl(struct file *file, unsigned int cmd,
+			     unsigned long arg)
+{
+	unsigned int nr = DRM_IOCTL_NR(cmd);
+
+	if (nr < DRM_COMMAND_BASE)
+		return drm_compat_ioctl(file, cmd, arg);
+
+#if defined(PDUMP)
+	if (nr < DRM_COMMAND_BASE + ARRAY_SIZE(pvr_drm_compat_ioctls)) {
+		drm_ioctl_compat_t *pfnBridge;
+
+		pfnBridge = pvr_drm_compat_ioctls[nr - DRM_COMMAND_BASE];
+		if (pfnBridge)
+			return pfnBridge(file, cmd, arg);
+	}
+#endif
+
+	return drm_ioctl(file, cmd, arg);
+}
+#endif /* defined(CONFIG_COMPAT) */
+
+static const struct file_operations pvr_drm_fops = {
+	.owner			= THIS_MODULE,
+	.open			= drm_open,
+	.release		= drm_release,
+	/*
+	 * FIXME:
+	 * Wrap this in a function that checks enough data has been
+	 * supplied with the ioctl (e.g. _IOCDIR(nr) != _IOC_NONE &&
+	 * _IOC_SIZE(nr) == size).
+	 */
+	.unlocked_ioctl		= drm_ioctl,
+#if defined(CONFIG_COMPAT)
+	.compat_ioctl		= pvr_compat_ioctl,
+#endif
+	.mmap			= PVRSRV_MMap,
+	.poll			= drm_poll,
+	.read			= drm_read,
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 12, 0))
+	.fasync			= drm_fasync,
+#endif
+};
+
+const struct drm_driver pvr_drm_generic_driver = {
+	.driver_features	= DRIVER_MODESET | DRIVER_RENDER,
+
+	.dev_priv_size		= 0,
+	.load			= pvr_drm_load,
+	.unload			= pvr_drm_unload,
+	.open			= pvr_drm_open,
+	.postclose		= pvr_drm_release,
+
+	.ioctls			= pvr_drm_ioctls,
+	.num_ioctls		= ARRAY_SIZE(pvr_drm_ioctls),
+	.fops			= &pvr_drm_fops,
+
+	.name			= PVR_DRM_DRIVER_NAME,
+	.desc			= PVR_DRM_DRIVER_DESC,
+	.date			= PVR_DRM_DRIVER_DATE,
+	.major			= PVRVERSION_MAJ,
+	.minor			= PVRVERSION_MIN,
+	.patchlevel		= PVRVERSION_BUILD,
+};
diff --git a/drivers/staging/imgtec/rogue/debug_request_ids.h b/drivers/staging/imgtec/pvr_drv.h
similarity index 72%
rename from drivers/staging/imgtec/rogue/debug_request_ids.h
rename to drivers/staging/imgtec/pvr_drv.h
index f76c932..e92cfe9 100644
--- a/drivers/staging/imgtec/rogue/debug_request_ids.h
+++ b/drivers/staging/imgtec/pvr_drv.h
@@ -1,9 +1,10 @@
+/* -*- mode: c; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
+/* vi: set ts=8 sw=8 sts=8: */
 /*************************************************************************/ /*!
 @File
-@Title          Debug requester ID's
+@Title          PowerVR DRM driver
+@Codingstyle    LinuxKernel
 @Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
-@Description    This header contains the defines for the debug ID's for all the
-				services components
 @License        Dual MIT/GPLv2
 
 The contents of this file are subject to the MIT license as set out below.
@@ -41,17 +42,28 @@
 IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */ /**************************************************************************/
- 
-#ifndef __DEBUG_REQUEST_IDS__
-#define __DEBUG_REQUEST_IDS__
 
-/* Services controlled devices should be 1st */
-#define DEBUG_REQUEST_RGX			(0)
-#define DEBUG_REQUEST_DC			(1)
-#define DEBUG_REQUEST_SERVERSYNC	(2)
-#define DEBUG_REQUEST_SYS           (3)
-#define DEBUG_REQUEST_ANDROIDSYNC   (4)
-#define DEBUG_REQUEST_DRMDISPLAY    (5)
-#define DEBUG_REQUEST_LINUXFENCE    (6)
+#if !defined(__PVR_DRV_H__)
+#define __PVR_DRV_H__
 
-#endif /* __DEBUG_REQUEST_IDS__ */
+#include <drm/drmP.h>
+#include <linux/pm.h>
+
+struct file;
+struct vm_area_struct;
+
+extern const struct dev_pm_ops pvr_pm_ops;
+extern const struct drm_driver pvr_drm_generic_driver;
+
+#if defined(PDUMP)
+int dbgdrv_init(void);
+void dbgdrv_cleanup(void);
+int dbgdrv_ioctl(struct drm_device *dev, void *arg, struct drm_file *file);
+int dbgdrv_ioctl_compat(struct file *file, unsigned int cmd, unsigned long arg);
+#endif
+
+int PVRSRV_BridgeDispatchKM(struct drm_device *dev, void *arg,
+			    struct drm_file *file);
+int PVRSRV_MMap(struct file *file, struct vm_area_struct *ps_vma);
+
+#endif /* !defined(__PVR_DRV_H__) */
diff --git a/drivers/staging/imgtec/pvr_sync.c b/drivers/staging/imgtec/pvr_sync.c
index e78af6a..4b66695 100644
--- a/drivers/staging/imgtec/pvr_sync.c
+++ b/drivers/staging/imgtec/pvr_sync.c
@@ -1,6 +1,9 @@
+/* -*- mode: c; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
+/* vi: set ts=8 sw=8 sts=8: */
 /*************************************************************************/ /*!
 @File           pvr_sync.c
 @Title          Kernel driver for Android's sync mechanism
+@Codingstyle    LinuxKernel
 @Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
 @License        Dual MIT/GPLv2
 
@@ -39,7 +42,6 @@
 IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */ /**************************************************************************/
-/* vi: set ts=8: */
 
 #include "pvr_sync.h"
 #include "pvr_fd_sync_kernel.h"
@@ -66,15 +68,9 @@
 #endif
 #endif
 
-/*
- * get_unused_fd was first removed from vanilla kernels in 3.19 and
- * get_unused_fd_flags was first exported from vanilla kernels in 3.7.
- */
-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 19, 0))
-#define get_unused_fd() get_unused_fd_flags(0)
-#endif
+#include "kernel_compatibility.h"
 
-#if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 18, 0))
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 17, 0))
 
 static inline struct sync_timeline *sync_pt_parent(struct sync_pt *pt)
 {
@@ -89,7 +85,7 @@
 #define for_each_sync_pt(s, f, c) \
 	list_for_each_entry((s), &(f)->pt_list_head, pt_list)
 
-#else /* (LINUX_VERSION_CODE < KERNEL_VERSION(3, 18, 0)) */
+#else /* (LINUX_VERSION_CODE < KERNEL_VERSION(3, 17, 0)) */
 
 static inline int sync_pt_get_status(struct sync_pt *pt)
 {
@@ -104,7 +100,7 @@
 	     (c)++,   (s) = (c) < (f)->num_fences ? \
 		(struct sync_pt *)(f)->cbs[c].sync_pt : NULL)
 
-#endif /* (LINUX_VERSION_CODE < KERNEL_VERSION(3, 18, 0)) */
+#endif /* (LINUX_VERSION_CODE < KERNEL_VERSION(3, 17, 0)) */
 
 /* #define DEBUG_OUTPUT 1 */
 
@@ -135,10 +131,10 @@
 
 struct pvr_sync_append_data {
 	u32					nr_updates;
-	PRGXFWIF_UFO_ADDR			*update_ufo_addresses;
+	struct _RGXFWIF_DEV_VIRTADDR_		*update_ufo_addresses;
 	u32					*update_values;
 	u32					nr_checks;
-	PRGXFWIF_UFO_ADDR			*check_ufo_addresses;
+	struct _RGXFWIF_DEV_VIRTADDR_		*check_ufo_addresses;
 	u32					*check_values;
 
 	/* The cleanup list is needed for rollback (as that's the only op
@@ -305,9 +301,6 @@
 
 /* Global data for the sync driver */
 static struct {
-	/* Services connection */
-	void *device_cookie;
-
 	/* Complete notify handle */
 	void *command_complete_handle;
 
@@ -363,6 +356,8 @@
 static LIST_HEAD(sync_fence_put_list);
 static DEFINE_SPINLOCK(sync_fence_put_list_spinlock);
 
+static void pvr_sync_update_all_timelines(void *command_complete_handle);
+
 static inline void set_sync_value(struct pvr_sync_native_sync_prim *sync,
 				  u32 value)
 {
@@ -432,6 +427,7 @@
 		unsigned int cleanup_count = 0;
 		unsigned int info1_pos = 0;
 		struct list_head *pos;
+
 		info1[0] = 0;
 
 		list_for_each(pos, &kernel->cleanup_sync_list) {
@@ -489,12 +485,13 @@
 {
 	struct pvr_sync_native_sync_prim *sync;
 	enum PVRSRV_ERROR error = PVRSRV_OK;
+	u32 sync_addr;
 
 	mutex_lock(&sync_pool_mutex);
 
 	if (list_empty(&sync_pool_free_list)) {
 		/* If there is nothing in the pool, create a new sync prim. */
-		sync = kmalloc(sizeof(struct pvr_sync_native_sync_prim),
+		sync = kmalloc(sizeof(*sync),
 			       GFP_KERNEL);
 		if (!sync) {
 			pr_err("pvr_sync: %s: Failed to allocate sync data\n",
@@ -511,7 +508,13 @@
 			goto err_free;
 		}
 
-		sync->vaddr = SyncPrimGetFirmwareAddr(sync->client_sync);
+		error = SyncPrimGetFirmwareAddr(sync->client_sync, &sync_addr);
+		if (error != PVRSRV_OK) {
+			pr_err("pvr_sync: %s: Failed to get FW address (%s)\n",
+			       __func__, PVRSRVGetErrorStringKM(error));
+			goto err_sync_prim_free;
+		}
+		sync->vaddr = sync_addr;
 
 		list_add_tail(&sync->list, &sync_pool_active_list);
 		++sync_pool_created;
@@ -527,7 +530,6 @@
 	sync->type = type;
 
 	strncpy(sync->class, class_name, sizeof(sync->class));
-	/* make sure string is null terminated */
 	sync->class[sizeof(sync->class) - 1] = '\0';
 	/* Its crucial to reset the sync to zero */
 	set_sync_value(sync, 0);
@@ -538,6 +540,9 @@
 	mutex_unlock(&sync_pool_mutex);
 	return error;
 
+err_sync_prim_free:
+	SyncPrimFree(sync->client_sync);
+
 err_free:
 	kfree(sync);
 	goto err_unlock;
@@ -585,9 +590,9 @@
 }
 
 static void pvr_sync_debug_request(void *hDebugRequestHandle,
-								   u32 ui32VerbLevel,
-								   DUMPDEBUG_PRINTF_FUNC *pfnDumpDebugPrintf,
-								   void *pvDumpDebugFile)
+				   u32 ui32VerbLevel,
+				   DUMPDEBUG_PRINTF_FUNC *pfnDumpDebugPrintf,
+				   void *pvDumpDebugFile)
 {
 	struct pvr_sync_native_sync_prim *sync;
 
@@ -622,12 +627,12 @@
 					  type_names[sync->type]);
 		}
 #if 0
-		PVR_DUMPDEBUG_LOG(g_pfnDumpDebugPrintf,
+		PVR_DUMPDEBUG_LOG(pfnDumpDebugPrintf,
 				  "Dumping all unused syncs");
 		list_for_each_entry(sync, &sync_pool_free_list, list) {
 			BUG_ON(sync->type >= ARRAY_SIZE(type_names));
 
-			PVR_DUMPDEBUG_LOG(g_pfnDumpDebugPrintf,
+			PVR_DUMPDEBUG_LOG(pfnDumpDebugPrintf,
 					  "\tID = %d, FWAddr = 0x%08x: Current = 0x%08x, Next = 0x%08x, %s (%s)",
 					  sync->id, sync->vaddr,
 					  get_sync_value(sync),
@@ -649,7 +654,7 @@
 
 	pvr_pt_b = (struct pvr_sync_pt *)
 		sync_pt_create(sync_pt_parent(sync_pt),
-			       sizeof(struct pvr_sync_pt));
+			       sizeof(*pvr_pt_b));
 	if (!pvr_pt_b) {
 		pr_err("pvr_sync: %s: Failed to dup sync pt\n", __func__);
 		goto err_out;
@@ -820,9 +825,8 @@
 	 *
 	 * 123456789012345678901234567890123456789012345678901234567890123
 	 *
-	 * ID     FW ADDR    C/N # REF CLEANUP_COUNT
-	 *                               TAKEN
-	 * 123456 0xdeadbeef 0/1 # r=2 1 123456
+	 * ID     FW ADDR    C/N # REF TAKEN  CLEANUP_COUNT
+	 * 123456 0xdeadbeef 0/1 # r=2 123456 1
 	 */
 	if (kernel) {
 		unsigned int cleanup_count = 0;
@@ -840,6 +844,7 @@
 			 atomic_read(&pvr_pt->sync_data->kref.refcount),
 			 cleanup_count,
 			 pvr_pt->sync_data->timeline_update_value);
+
 	} else {
 		snprintf(str, size, "idle # r=%d %u",
 			 atomic_read(&pvr_pt->sync_data->kref.refcount),
@@ -856,14 +861,14 @@
 	struct pvr_sync_data *sync_data = NULL;
 	enum PVRSRV_ERROR error;
 
-	sync_data = kzalloc(sizeof(struct pvr_sync_data), GFP_KERNEL);
+	sync_data = kzalloc(sizeof(*sync_data), GFP_KERNEL);
 	if (!sync_data)
 		goto err_out;
 
 	kref_init(&sync_data->kref);
 
 	sync_data->kernel =
-		kzalloc(sizeof(struct pvr_sync_kernel_pair),
+		kzalloc(sizeof(*sync_data->kernel),
 		GFP_KERNEL);
 
 	if (!sync_data->kernel)
@@ -943,7 +948,7 @@
 	struct pvr_sync_data *sync_data = pvr_pt->sync_data;
 	struct pvr_sync_kernel_pair *kernel = sync_data->kernel;
 
-	if (size < sizeof(struct pvr_sync_pt_info))
+	if (size < sizeof(*info))
 		return -ENOMEM;
 
 	info->ui32TlTaken = sync_data->timeline_update_value;
@@ -960,7 +965,7 @@
 		info->ui32NextOp = 0;
 	}
 
-	return sizeof(struct pvr_sync_pt_info);
+	return sizeof(*info);
 }
 
 /* foreign sync handling */
@@ -1016,7 +1021,7 @@
 		goto err_out;
 	}
 
-	kernel = kmalloc(sizeof(struct pvr_sync_kernel_pair), GFP_KERNEL);
+	kernel = kmalloc(sizeof(*kernel), GFP_KERNEL);
 	if (!kernel) {
 		pr_err("pvr_sync: %s: Failed to allocate sync kernel\n",
 		       __func__);
@@ -1025,7 +1030,7 @@
 
 	INIT_LIST_HEAD(&kernel->cleanup_sync_list);
 
-	sync_fence = kmalloc(sizeof(struct pvr_sync_fence), GFP_KERNEL);
+	sync_fence = kmalloc(sizeof(*sync_fence), GFP_KERNEL);
 	if (!sync_fence) {
 		pr_err("pvr_sync: %s: Failed to allocate pvr sync fence\n",
 		       __func__);
@@ -1044,8 +1049,8 @@
 
 	kernel->fence_sync->next_value++;
 
-	error = sync_pool_get(&cleanup_sync,
-			      fence->name, SYNC_PT_FOREIGN_CLEANUP_TYPE);
+	error = sync_pool_get(&cleanup_sync, fence->name,
+		SYNC_PT_FOREIGN_CLEANUP_TYPE);
 	if (error != PVRSRV_OK) {
 		pr_err("pvr_sync: %s: Failed to allocate cleanup sync prim (%s)\n",
 		       __func__, PVRSRVGetErrorStringKM(error));
@@ -1057,7 +1062,7 @@
 	list_add(&cleanup_sync->cleanup_list, &kernel->cleanup_sync_list);
 
 	/* The custom waiter structure is freed in the waiter callback */
-	waiter = kmalloc(sizeof(struct pvr_sync_fence_waiter), GFP_KERNEL);
+	waiter = kmalloc(sizeof(*waiter), GFP_KERNEL);
 	if (!waiter) {
 		pr_err("pvr_sync: %s: Failed to allocate waiter\n", __func__);
 		goto err_free_cleanup_sync;
@@ -1120,7 +1125,7 @@
 	sync_data->kernel->fence_sync->next_value++;
 
 	pvr_pt = (struct pvr_sync_pt *)
-		sync_pt_create(timeline->obj, sizeof(struct pvr_sync_pt));
+		sync_pt_create(timeline->obj, sizeof(*pvr_pt));
 
 	if (!pvr_pt) {
 		pr_err("pvr_sync: %s: Failed to create sync pt\n", __func__);
@@ -1149,23 +1154,23 @@
 static const struct file_operations pvr_sync_fops;
 
 enum PVRSRV_ERROR pvr_sync_append_fences(
-	const char                  *name,
-	const s32                   check_fence_fd,
-	const s32                   update_timeline_fd,
-	const u32                   nr_updates,
-	const PRGXFWIF_UFO_ADDR     *update_ufo_addresses,
-	const u32                   *update_values,
-	const u32                   nr_checks,
-	const PRGXFWIF_UFO_ADDR     *check_ufo_addresses,
-	const u32                   *check_values,
-	struct pvr_sync_append_data **append_sync_data)
+	const char				*name,
+	const s32				check_fence_fd,
+	const s32				update_timeline_fd,
+	const u32				nr_updates,
+	const struct _RGXFWIF_DEV_VIRTADDR_	*update_ufo_addresses,
+	const u32				*update_values,
+	const u32				nr_checks,
+	const struct _RGXFWIF_DEV_VIRTADDR_	*check_ufo_addresses,
+	const u32				*check_values,
+	struct pvr_sync_append_data		**append_sync_data)
 {
 	struct pvr_sync_native_sync_prim **cleanup_sync_pos;
 	struct pvr_sync_pt *update_point = NULL;
 	struct sync_fence *update_fence = NULL;
 	struct pvr_sync_append_data *sync_data;
-	PRGXFWIF_UFO_ADDR *update_address_pos;
-	PRGXFWIF_UFO_ADDR *check_address_pos;
+	struct _RGXFWIF_DEV_VIRTADDR_ *update_address_pos;
+	struct _RGXFWIF_DEV_VIRTADDR_ *check_address_pos;
 	struct pvr_sync_timeline *timeline;
 	unsigned int num_used_sync_updates;
 	unsigned int num_used_sync_checks;
@@ -1180,7 +1185,7 @@
 	}
 
 	sync_data =
-		kzalloc(sizeof(struct pvr_sync_append_data), GFP_KERNEL);
+		kzalloc(sizeof(*sync_data), GFP_KERNEL);
 	if (!sync_data) {
 		err = PVRSRV_ERROR_OUT_OF_MEMORY;
 		goto err_out;
@@ -1239,7 +1244,12 @@
 			goto err_free_append_data;
 		}
 
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 4, 0)) && \
+    defined(CHROMIUMOS_WORKAROUNDS_KERNEL318)
+		update_fence = sync_fence_create(name, &update_point->pt.base);
+#else
 		update_fence = sync_fence_create(name, &update_point->pt);
+#endif
 		if (!update_fence) {
 			struct pvr_sync_native_sync_prim *fence_prim =
 				update_point->sync_data->kernel->fence_sync;
@@ -1302,11 +1312,11 @@
 
 			pvr_pt = (struct pvr_sync_pt *)sync_pt;
 			sync_kernel = pvr_pt->sync_data->kernel;
-			if (!sync_kernel)
-				continue;
 
-			if (is_sync_met(sync_kernel->fence_sync))
+			if (!sync_kernel ||
+			    is_sync_met(sync_kernel->fence_sync)) {
 				continue;
+			}
 
 			/* We will use the above sync for "check" only. In this
 			 * case also insert a "cleanup" update command into the
@@ -1347,9 +1357,8 @@
 
 	if (sync_data->nr_updates > 0) {
 		sync_data->update_ufo_addresses =
-			kzalloc(sizeof(PRGXFWIF_UFO_ADDR) *
-					sync_data->nr_updates,
-				GFP_KERNEL);
+			kzalloc(sizeof(*sync_data->update_ufo_addresses) *
+					sync_data->nr_updates, GFP_KERNEL);
 		if (!sync_data->update_ufo_addresses) {
 			pr_err("pvr_sync: %s: Failed to allocate update UFO address list\n",
 				__func__);
@@ -1358,8 +1367,8 @@
 		}
 
 		sync_data->update_values =
-			kzalloc(sizeof(u32) * sync_data->nr_updates,
-				GFP_KERNEL);
+			kzalloc(sizeof(*sync_data->update_values) *
+				sync_data->nr_updates, GFP_KERNEL);
 		if (!sync_data->update_values) {
 			pr_err("pvr_sync: %s: Failed to allocate update value list\n",
 				__func__);
@@ -1371,9 +1380,8 @@
 	if (sync_data->nr_checks > 0) {
 
 		sync_data->check_ufo_addresses =
-			kzalloc(sizeof(PRGXFWIF_UFO_ADDR) *
-					sync_data->nr_checks,
-				GFP_KERNEL);
+			kzalloc(sizeof(*sync_data->check_ufo_addresses) *
+					sync_data->nr_checks, GFP_KERNEL);
 		if (!sync_data->check_ufo_addresses) {
 			pr_err("pvr_sync: %s: Failed to allocate check UFO address list\n",
 				__func__);
@@ -1382,8 +1390,8 @@
 		}
 
 		sync_data->check_values =
-			kzalloc(sizeof(u32) * sync_data->nr_checks,
-				GFP_KERNEL);
+			kzalloc(sizeof(*sync_data->check_values) *
+				sync_data->nr_checks, GFP_KERNEL);
 		if (!sync_data->check_values) {
 			pr_err("pvr_sync: %s: Failed to allocate check value list\n",
 				__func__);
@@ -1394,7 +1402,7 @@
 
 	if (sync_data->nr_cleanup_syncs > 0) {
 		sync_data->cleanup_syncs =
-			kzalloc(sizeof(struct pvr_sync_native_sync_prim *) *
+			kzalloc(sizeof(*sync_data->cleanup_syncs) *
 				sync_data->nr_cleanup_syncs, GFP_KERNEL);
 		if (!sync_data->cleanup_syncs) {
 			pr_err("pvr_sync: %s: Failed to allocate cleanup rollback list\n",
@@ -1410,7 +1418,6 @@
 	check_value_pos = sync_data->check_values;
 	cleanup_sync_pos = sync_data->cleanup_syncs;
 
-
 	/* Everything should be allocated/sanity checked. No errors are
 	 * possible after this point.
 	 */
@@ -1464,8 +1471,8 @@
 				struct pvr_sync_native_sync_prim *fence_sync =
 					foreign_sync_kernel->fence_sync;
 				struct pvr_sync_native_sync_prim *cleanup_sync =
-					foreign_sync_kernel->current_cleanup_sync;
-
+					foreign_sync_kernel->
+						current_cleanup_sync;
 
 				(*check_address_pos++).ui32Addr =
 					fence_sync->vaddr;
@@ -1477,7 +1484,8 @@
 				*update_value_pos++ =
 					++cleanup_sync->next_value;
 				*cleanup_sync_pos++ = cleanup_sync;
-				foreign_sync_kernel->current_cleanup_sync = NULL;
+				foreign_sync_kernel->current_cleanup_sync =
+					NULL;
 			}
 		}
 	}
@@ -1525,17 +1533,17 @@
 	/* Append original check and update sync values/addresses */
 	if (update_ufo_addresses)
 		memcpy(update_address_pos, update_ufo_addresses,
-			   sizeof(PRGXFWIF_UFO_ADDR) * nr_updates);
+			sizeof(*update_ufo_addresses) * nr_updates);
 	if (update_values)
 		memcpy(update_value_pos, update_values,
-			   sizeof(u32) * nr_updates);
+			sizeof(*update_values) * nr_updates);
 
 	if (check_ufo_addresses)
 		memcpy(check_address_pos, check_ufo_addresses,
-			   sizeof(PRGXFWIF_UFO_ADDR) * nr_checks);
+			sizeof(*check_ufo_addresses) * nr_checks);
 	if (check_values)
 		memcpy(check_value_pos, check_values,
-			   sizeof(u32) * nr_checks);
+			sizeof(*check_values) * nr_checks);
 
 	*append_sync_data = sync_data;
 
@@ -1554,7 +1562,7 @@
 }
 
 void pvr_sync_get_updates(const struct pvr_sync_append_data *sync_data,
-	u32 *nr_fences, PRGXFWIF_UFO_ADDR **ufo_addrs, u32 **values)
+	u32 *nr_fences, struct _RGXFWIF_DEV_VIRTADDR_ **ufo_addrs, u32 **values)
 {
 	*nr_fences = sync_data->nr_updates;
 	*ufo_addrs = sync_data->update_ufo_addresses;
@@ -1562,7 +1570,7 @@
 }
 
 void pvr_sync_get_checks(const struct pvr_sync_append_data *sync_data,
-	u32 *nr_fences, PRGXFWIF_UFO_ADDR **ufo_addrs, u32 **values)
+	u32 *nr_fences, struct _RGXFWIF_DEV_VIRTADDR_ **ufo_addrs, u32 **values)
 {
 	*nr_fences = sync_data->nr_checks;
 	*ufo_addrs = sync_data->check_ufo_addresses;
@@ -1673,6 +1681,8 @@
 		complete_sync(sync_data->update_sync);
 	if (sync_data->update_timeline_sync)
 		complete_sync(sync_data->update_timeline_sync);
+
+	pvr_sync_update_all_timelines(NULL);
 }
 
 /* ioctl and fops handling */
@@ -1689,19 +1699,19 @@
 
 	timeline_wrapper = (struct pvr_sync_timeline_wrapper *)
 		sync_timeline_create(&pvr_sync_timeline_ops,
-			sizeof(struct pvr_sync_timeline_wrapper), task_comm);
+			sizeof(*timeline_wrapper), task_comm);
 	if (!timeline_wrapper) {
 		pr_err("pvr_sync: %s: sync_timeline_create failed\n", __func__);
 		goto err_out;
 	}
 
-	timeline = kmalloc(sizeof(struct pvr_sync_timeline), GFP_KERNEL);
+	timeline = kmalloc(sizeof(*timeline), GFP_KERNEL);
 	if (!timeline) {
 		pr_err("pvr_sync: %s: Out of memory\n", __func__);
 		goto err_free_timeline_wrapper;
 	}
 
-	timeline->kernel = kzalloc(sizeof(struct pvr_sync_kernel_pair),
+	timeline->kernel = kzalloc(sizeof(*timeline->kernel),
 				   GFP_KERNEL);
 	if (!timeline->kernel) {
 		pr_err("pvr_sync: %s: Out of memory\n", __func__);
@@ -1711,10 +1721,8 @@
 	INIT_LIST_HEAD(&timeline->kernel->cleanup_sync_list);
 
 	OSAcquireBridgeLock();
-	PMRLock();
 	error = sync_pool_get(&timeline->kernel->fence_sync,
 			      task_comm, SYNC_TL_TYPE);
-	PMRUnlock();
 	OSReleaseBridgeLock();
 
 	if (error != PVRSRV_OK) {
@@ -1788,7 +1796,7 @@
 
 	mutex_lock(&sync_pool_mutex);
 	strlcpy(timeline->kernel->fence_sync->class, data.szName,
-	        sizeof(timeline->kernel->fence_sync->class));
+		sizeof(timeline->kernel->fence_sync->class));
 	mutex_unlock(&sync_pool_mutex);
 err:
 	return err;
@@ -1845,7 +1853,12 @@
 	}
 
 	data.name[sizeof(data.name) - 1] = '\0';
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 4, 0)) && \
+    defined(CHROMIUMOS_WORKAROUNDS_KERNEL318)
+	fence = sync_fence_create(data.name, &sync_pt->base);
+#else
 	fence = sync_fence_create(data.name, sync_pt);
+#endif
 	if (!fence) {
 		pr_err("pvr_sync: %s: Failed to create a fence (%d)\n",
 		       __func__, fd);
@@ -1959,7 +1972,6 @@
 		/* Check if this sync is not used anymore. */
 		if (!is_sync_met(kernel->fence_sync))
 			continue;
-
 		list_for_each(pos, &kernel->cleanup_sync_list) {
 			struct pvr_sync_native_sync_prim *cleanup_sync =
 				list_entry(pos,
@@ -2132,7 +2144,7 @@
 	mutex_unlock(&timeline_list_mutex);
 }
 
-enum PVRSRV_ERROR pvr_sync_init(void)
+enum PVRSRV_ERROR pvr_sync_init(void *device_cookie)
 {
 	enum PVRSRV_ERROR error;
 	int err;
@@ -2141,25 +2153,17 @@
 
 	atomic_set(&pvr_sync_data.sync_id, 0);
 
-	error = PVRSRVAcquireDeviceDataKM(0, PVRSRV_DEVICE_TYPE_RGX,
-					  &pvr_sync_data.device_cookie);
-	if (error != PVRSRV_OK) {
-		pr_err("pvr_sync: %s: Failed to initialise services (%s)\n",
-		       __func__, PVRSRVGetErrorStringKM(error));
-		goto err_out;
-	}
-
-	error = AcquireGlobalEventObjectServer(
+	error = PVRSRVAcquireGlobalEventObjectKM(
 		&pvr_sync_data.event_object_handle);
 	if (error != PVRSRV_OK) {
 		pr_err("pvr_sync: %s: Failed to acquire global event object (%s)\n",
 			__func__, PVRSRVGetErrorStringKM(error));
-		goto err_release_device_data;
+		goto err_out;
 	}
 
 	OSAcquireBridgeLock();
 
-	error = SyncPrimContextCreate(pvr_sync_data.device_cookie,
+	error = SyncPrimContextCreate(device_cookie,
 				      &pvr_sync_data.sync_prim_context);
 	if (error != PVRSRV_OK) {
 		pr_err("pvr_sync: %s: Failed to create sync prim context (%s)\n",
@@ -2194,7 +2198,7 @@
 	error = PVRSRVRegisterCmdCompleteNotify(
 			&pvr_sync_data.command_complete_handle,
 			&pvr_sync_update_all_timelines,
-			&pvr_sync_data.device_cookie);
+			&device_cookie);
 	if (error != PVRSRV_OK) {
 		pr_err("pvr_sync: %s: Failed to register MISR notification (%s)\n",
 		       __func__, PVRSRVGetErrorStringKM(error));
@@ -2203,6 +2207,7 @@
 
 	error = PVRSRVRegisterDbgRequestNotify(
 			&pvr_sync_data.debug_notify_handle,
+			device_cookie,
 			pvr_sync_debug_request,
 			DEBUG_REQUEST_ANDROIDSYNC,
 			NULL);
@@ -2237,9 +2242,7 @@
 	SyncPrimContextDestroy(pvr_sync_data.sync_prim_context);
 	OSReleaseBridgeLock();
 err_release_event_object:
-	ReleaseGlobalEventObjectServer(pvr_sync_data.event_object_handle);
-err_release_device_data:
-	PVRSRVReleaseDeviceDataKM(pvr_sync_data.device_cookie);
+	PVRSRVReleaseGlobalEventObjectKM(pvr_sync_data.event_object_handle);
 err_out:
 
 	return error;
@@ -2270,7 +2273,5 @@
 
 	OSReleaseBridgeLock();
 
-	ReleaseGlobalEventObjectServer(pvr_sync_data.event_object_handle);
-
-	PVRSRVReleaseDeviceDataKM(pvr_sync_data.device_cookie);
+	PVRSRVReleaseGlobalEventObjectKM(pvr_sync_data.event_object_handle);
 }
diff --git a/drivers/staging/imgtec/pvr_sync.h b/drivers/staging/imgtec/pvr_sync.h
index 1765308..4df9cba 100644
--- a/drivers/staging/imgtec/pvr_sync.h
+++ b/drivers/staging/imgtec/pvr_sync.h
@@ -1,6 +1,9 @@
+/* -*- mode: c; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
+/* vi: set ts=8 sw=8 sts=8: */
 /*************************************************************************/ /*!
 @File           pvr_sync.h
 @Title          Kernel driver for Android's sync mechanism
+@Codingstyle    LinuxKernel
 @Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
 @License        Dual MIT/GPLv2
 
@@ -39,40 +42,39 @@
 IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */ /**************************************************************************/
-/* vi: set ts=8: */
 
 #ifndef _PVR_SYNC_H
 #define _PVR_SYNC_H
 
 #include "pvr_fd_sync_kernel.h"
-#include "rgx_fwif_shared.h"
 
 /* Services internal interface */
-enum PVRSRV_ERROR pvr_sync_init(void);
+enum PVRSRV_ERROR pvr_sync_init(void *device_cookie);
 void pvr_sync_deinit(void);
 
+struct _RGXFWIF_DEV_VIRTADDR_;
 struct pvr_sync_append_data;
 
 enum PVRSRV_ERROR
 pvr_sync_append_fences(
-	const char			*name,
-	const s32			check_fence_fd,
-	const s32			update_timeline_fd,
-	const u32			nr_updates,
-	const PRGXFWIF_UFO_ADDR		*update_ufo_addresses,
-	const u32			*update_values,
-	const u32			nr_checks,
-	const PRGXFWIF_UFO_ADDR		*check_ufo_addresses,
-	const u32			*check_values,
-	struct pvr_sync_append_data	**append_sync_data);
+	const char				*name,
+	const s32				check_fence_fd,
+	const s32				update_timeline_fd,
+	const u32				nr_updates,
+	const struct _RGXFWIF_DEV_VIRTADDR_	*update_ufo_addresses,
+	const u32				*update_values,
+	const u32				nr_checks,
+	const struct _RGXFWIF_DEV_VIRTADDR_	*check_ufo_addresses,
+	const u32				*check_values,
+	struct pvr_sync_append_data		**append_sync_data);
 
 void pvr_sync_get_updates(const struct pvr_sync_append_data *sync_data,
 	u32 *nr_fences,
-	PRGXFWIF_UFO_ADDR **ufo_addrs,
+	struct _RGXFWIF_DEV_VIRTADDR_ **ufo_addrs,
 	u32 **values);
 void pvr_sync_get_checks(const struct pvr_sync_append_data *sync_data,
 	u32 *nr_fences,
-	PRGXFWIF_UFO_ADDR **ufo_addrs,
+	struct _RGXFWIF_DEV_VIRTADDR_ **ufo_addrs,
 	u32 **values);
 
 void pvr_sync_rollback_append_fences(struct pvr_sync_append_data *sync_data);
diff --git a/drivers/staging/imgtec/pvrversion.h b/drivers/staging/imgtec/pvrversion.h
index d4da954..f13ee3d 100644
--- a/drivers/staging/imgtec/pvrversion.h
+++ b/drivers/staging/imgtec/pvrversion.h
@@ -49,20 +49,20 @@
 #define PVR_STR2(X) PVR_STR(X)
 
 #define PVRVERSION_MAJ               1
-#define PVRVERSION_MIN               6
+#define PVRVERSION_MIN               8
 
 #define PVRVERSION_FAMILY           "rogueddk"
-#define PVRVERSION_BRANCHNAME       "1.6"
-#define PVRVERSION_BUILD             4278818
+#define PVRVERSION_BRANCHNAME       "1.8"
+#define PVRVERSION_BUILD             4688949
 #define PVRVERSION_BSCONTROL        "Rogue_DDK_Android"
 
-#define PVRVERSION_STRING           "Rogue_DDK_Android rogueddk 1.6@" PVR_STR2(PVRVERSION_BUILD)
-#define PVRVERSION_STRING_SHORT     "1.6@" PVR_STR2(PVRVERSION_BUILD) ""
+#define PVRVERSION_STRING           "Rogue_DDK_Android rogueddk 1.8@" PVR_STR2(PVRVERSION_BUILD)
+#define PVRVERSION_STRING_SHORT     "1.8@" PVR_STR2(PVRVERSION_BUILD) ""
 
 #define COPYRIGHT_TXT               "Copyright (c) Imagination Technologies Ltd. All Rights Reserved."
 
-#define PVRVERSION_BUILD_HI          427
-#define PVRVERSION_BUILD_LO          8818
+#define PVRVERSION_BUILD_HI          468
+#define PVRVERSION_BUILD_LO          8949
 #define PVRVERSION_STRING_NUMERIC    PVR_STR2(PVRVERSION_MAJ) "." PVR_STR2(PVRVERSION_MIN) "." PVR_STR2(PVRVERSION_BUILD_HI) "." PVR_STR2(PVRVERSION_BUILD_LO)
 
 #define PVRVERSION_PACK(MAJ,MIN) ((((MAJ)&0xFFFF) << 16) | (((MIN)&0xFFFF) << 0))
diff --git a/drivers/staging/imgtec/rogue/Makefile b/drivers/staging/imgtec/rogue/Makefile
index aea8ce5..1c89aec 100644
--- a/drivers/staging/imgtec/rogue/Makefile
+++ b/drivers/staging/imgtec/rogue/Makefile
@@ -13,12 +13,12 @@
 obj-$(CONFIG_POWERVR_ROGUE) += pvrsrvkm.o
 
 pvrsrvkm-y += allocmem.o
-pvrsrvkm-y += cache_generic.o
+pvrsrvkm-y += cache_km.o
 pvrsrvkm-y += connection_server.o
 pvrsrvkm-y += debugmisc_server.o
 pvrsrvkm-y += devicemem.o
 pvrsrvkm-y += devicemem_heapcfg.o
-pvrsrvkm-y += devicemem_mmap_stub.o
+pvrsrvkm-y += osmmap_stub.o
 pvrsrvkm-y += devicemem_server.o
 pvrsrvkm-y += devicemem_utils.o
 pvrsrvkm-y += event.o
@@ -27,9 +27,9 @@
 pvrsrvkm-y += hash.o
 pvrsrvkm-y += htbserver.o
 pvrsrvkm-y += htbuffer.o
+pvrsrvkm-y += km_apphint.o
 pvrsrvkm-y += lists.o
 pvrsrvkm-y += mem_utils.o
-pvrsrvkm-y += mm.o
 pvrsrvkm-y += mmu_common.o
 pvrsrvkm-y += module_common.o
 pvrsrvkm-y += osconnection_server.o
@@ -46,7 +46,7 @@
 pvrsrvkm-y += pvr_bridge_k.o
 pvrsrvkm-y += pvr_debug.o
 pvrsrvkm-y += pvr_debugfs.o
-pvrsrvkm-y += pvr_hwperf.o
+pvrsrvkm-y += pvr_notifier.o
 pvrsrvkm-y += pvrsrv.o
 pvrsrvkm-y += ra.o
 pvrsrvkm-y += rgx_compat_bvnc.o
@@ -60,18 +60,22 @@
 pvrsrvkm-y += rgxkicksync.o
 pvrsrvkm-y += rgxlayer_km_impl.o
 pvrsrvkm-y += rgxmem.o
+pvrsrvkm-y += rgxmipsmmuinit.o
 pvrsrvkm-y += rgxmmuinit.o
 pvrsrvkm-y += rgxpower.o
+pvrsrvkm-y += rgxray.o
 pvrsrvkm-y += rgxregconfig.o
+pvrsrvkm-y += rgxsignals.o
 pvrsrvkm-y += rgxstartstop.o
-pvrsrvkm-y += rgxsync.o
 pvrsrvkm-y += rgxta3d.o
+pvrsrvkm-y += rgxtdmtransfer.o
 pvrsrvkm-y += rgxtimecorr.o
 pvrsrvkm-y += rgxtimerquery.o
 pvrsrvkm-y += rgxtransfer.o
 pvrsrvkm-y += rgxutils.o
 pvrsrvkm-y += srvcore.o
 pvrsrvkm-y += sync.o
+pvrsrvkm-y += sync_checkpoint.o
 pvrsrvkm-y += sync_server.o
 pvrsrvkm-y += tlclient.o
 pvrsrvkm-y += tlintern.o
@@ -80,8 +84,6 @@
 pvrsrvkm-y += uniq_key_splay_tree.o
 
 # Kernel srvinit
-pvrsrvkm-y += htbinit.o
-pvrsrvkm-y += os_srvinit_param.o
 pvrsrvkm-y += rgx_compat_bvnc.o
 pvrsrvkm-y += rgx_hwperf_table.o
 pvrsrvkm-y += rgxfwimageutils.o
@@ -89,13 +91,12 @@
 pvrsrvkm-y += rgxlayer_impl.o
 pvrsrvkm-y += rgxsrvinit.o
 pvrsrvkm-y += rgxsrvinit_script.o
-pvrsrvkm-y += srvinit_km.o
 pvrsrvkm-$(CONFIG_POWERVR_ROGUE_PDUMP) += generated/dpdump_bridge/client_pdump_bridge.o
 pvrsrvkm-$(CONFIG_POWERVR_ROGUE_PDUMP) += generated/dpdumpctrl_bridge/client_pdumpctrl_bridge.o
 pvrsrvkm-$(CONFIG_POWERVR_ROGUE_PDUMP) += generated/drgxpdump_bridge/client_rgxpdump_bridge.o
 pvrsrvkm-y += generated/rgxinit_bridge/client_rgxinit_direct_bridge.o
 
-pvrsrvkm-y += drm_pci_module.o
+pvrsrvkm-$(CONFIG_DRM) += ../pvr_drm.o
 
 pvrsrvkm-$(CONFIG_DMA_SHARED_BUFFER) += physmem_dmabuf.o
 
@@ -144,14 +145,14 @@
 pvrsrvkm-y += generated/mm_bridge/client_mm_direct_bridge.o
 pvrsrvkm-y += generated/cmm_bridge/server_cmm_bridge.o
 pvrsrvkm-y += generated/rgxtq_bridge/server_rgxtq_bridge.o
-pvrsrvkm-y += generated/rgxinit_bridge/server_rgxinit_bridge.o
 pvrsrvkm-y += generated/rgxta3d_bridge/server_rgxta3d_bridge.o
 pvrsrvkm-y += generated/rgxcmp_bridge/server_rgxcmp_bridge.o
+pvrsrvkm-y += generated/rgxsignals_bridge/server_rgxsignals_bridge.o
 pvrsrvkm-y += generated/srvcore_bridge/server_srvcore_bridge.o
 pvrsrvkm-y += generated/sync_bridge/server_sync_bridge.o
 pvrsrvkm-y += generated/sync_bridge/client_sync_direct_bridge.o
-pvrsrvkm-y += generated/cachegeneric_bridge/server_cachegeneric_bridge.o
-pvrsrvkm-y += generated/cachegeneric_bridge/client_cachegeneric_direct_bridge.o
+pvrsrvkm-y += generated/cache_bridge/client_cache_direct_bridge.o
+pvrsrvkm-y += generated/cache_bridge/server_cache_bridge.o
 pvrsrvkm-y += generated/breakpoint_bridge/server_breakpoint_bridge.o
 pvrsrvkm-y += generated/debugmisc_bridge/server_debugmisc_bridge.o
 pvrsrvkm-y += generated/pvrtl_bridge/server_pvrtl_bridge.o
@@ -162,6 +163,8 @@
 pvrsrvkm-y += generated/htbuffer_bridge/server_htbuffer_bridge.o
 pvrsrvkm-y += generated/htbuffer_bridge/client_htbuffer_direct_bridge.o
 pvrsrvkm-y += generated/rgxkicksync_bridge/server_rgxkicksync_bridge.o
+pvrsrvkm-y += generated/rgxray_bridge/server_rgxray_bridge.o
+pvrsrvkm-y += generated/rgxtq2_bridge/server_rgxtq2_bridge.o
 pvrsrvkm-$(CONFIG_POWERVR_ROGUE_RESOURCE_INFO) += generated/ri_bridge/server_ri_bridge.o
 pvrsrvkm-$(CONFIG_POWERVR_ROGUE_RESOURCE_INFO) += generated/ri_bridge/client_ri_direct_bridge.o
 pvrsrvkm-$(CONFIG_POWERVR_ROGUE_DEVICEMEM_HISTORY) += generated/devicememhistory_bridge/server_devicememhistory_bridge.o
@@ -169,6 +172,7 @@
 pvrsrvkm-$(CONFIG_POWERVR_ROGUE_PDUMP) += generated/pdumpmm_bridge/server_pdumpmm_bridge.o
 pvrsrvkm-$(CONFIG_POWERVR_ROGUE_PDUMP) += generated/pdumpmm_bridge/client_pdumpmm_direct_bridge.o
 pvrsrvkm-$(CONFIG_POWERVR_ROGUE_PDUMP) += generated/pdump_bridge/server_pdump_bridge.o
+pvrsrvkm-$(CONFIG_POWERVR_ROGUE_PDUMP) += generated/pdumpctrl_bridge/client_pdumpctrl_direct_bridge.o
 pvrsrvkm-$(CONFIG_POWERVR_ROGUE_PDUMP) += generated/pdumpctrl_bridge/server_pdumpctrl_bridge.o
 pvrsrvkm-$(CONFIG_POWERVR_ROGUE_PDUMP) += generated/rgxpdump_bridge/server_rgxpdump_bridge.o
 pvrsrvkm-$(CONFIG_DMA_SHARED_BUFFER) += generated/dmabuf_bridge/server_dmabuf_bridge.o
diff --git a/drivers/staging/imgtec/rogue/allocmem.c b/drivers/staging/imgtec/rogue/allocmem.c
index d0f3985..ffabcf5 100644
--- a/drivers/staging/imgtec/rogue/allocmem.c
+++ b/drivers/staging/imgtec/rogue/allocmem.c
@@ -71,7 +71,7 @@
 			 * a whole number of pages, poison the minimum size known to have
 			 * been allocated.
 			 */
-			OSMemSet((void*)pvAddr, OS_MEM_POISON_VALUE, PVR_LINUX_KMALLOC_ALLOCATION_THRESHOLD);
+			OSCachedMemSet((void*)pvAddr, OS_MEM_POISON_VALUE, PVR_LINUX_KMALLOC_ALLOCATION_THRESHOLD);
 #endif
 			vfree(pvAddr);
 }
@@ -80,7 +80,7 @@
 {
 #if defined(DEBUG)
 			/* Poison whole memory block */
-			OSMemSet((void*)pvAddr, OS_MEM_POISON_VALUE, ksize(pvAddr));
+			OSCachedMemSet((void*)pvAddr, OS_MEM_POISON_VALUE, ksize(pvAddr));
 #endif
 			kfree(pvAddr);
 }
@@ -118,7 +118,11 @@
 	return pvRet;
 }
 
-IMG_INTERNAL void OSFreeMem(void *pvMem)
+/*
+ * The parentheses around OSFreeMem prevent the macro in allocmem.h from
+ * applying, as it would break the function's definition.
+ */
+IMG_INTERNAL void (OSFreeMem)(void *pvMem)
 {
 	if (pvMem != NULL)
 	{
@@ -349,7 +353,11 @@
 }
 #endif
 
-IMG_INTERNAL void OSFreeMem(void *pvMem)
+/*
+ * The parentheses around OSFreeMem prevent the macro in allocmem.h from
+ * applying, as it would break the function's definition.
+ */
+IMG_INTERNAL void (OSFreeMem)(void *pvMem)
 {
 	if (pvMem != NULL)
 	{
@@ -357,7 +365,10 @@
 		{
 #if !defined(PVR_DISABLE_KMALLOC_MEMSTATS)
 #if !defined(PVRSRV_ENABLE_MEMORY_STATS)
-			PVRSRVStatsDecrMemAllocStat(PVRSRV_MEM_ALLOC_TYPE_KMALLOC, ksize(pvMem));
+			{
+				IMG_UINT32 *puiTemp = (IMG_UINT32*) (((IMG_BYTE*)pvMem) + (ksize(pvMem) - ALLOCMEM_MEMSTATS_PADDING));
+				PVRSRVStatsDecrMemKAllocStat(ksize(pvMem), *puiTemp);
+			}
 #else
 			PVRSRVStatsRemoveMemAllocRecord(PVRSRV_MEM_ALLOC_TYPE_KMALLOC,
 			                                (IMG_UINT64)(uintptr_t) pvMem);
@@ -415,7 +426,11 @@
 	return pvRet;
 }
 
-IMG_INTERNAL void OSFreeMemNoStats(void *pvMem)
+/*
+ * The parentheses around OSFreeMemNoStats prevent the macro in allocmem.h from
+ * applying, as it would break the function's definition.
+ */
+IMG_INTERNAL void (OSFreeMemNoStats)(void *pvMem)
 {
 	if (pvMem != NULL)
 	{
diff --git a/drivers/staging/imgtec/rogue/allocmem.h b/drivers/staging/imgtec/rogue/allocmem.h
index f5c18d2..decef99 100644
--- a/drivers/staging/imgtec/rogue/allocmem.h
+++ b/drivers/staging/imgtec/rogue/allocmem.h
@@ -1,5 +1,5 @@
 /*************************************************************************/ /*!
-@File
+@File           allocmem.h
 @Title          memory allocation header
 @Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
 @Description    Memory-Allocation API definitions
@@ -45,13 +45,32 @@
 #define __ALLOCMEM_H__
 
 #include "img_types.h"
+#include "pvr_debug.h"
 
 #if defined (__cplusplus)
 extern "C" {
 #endif
 
 #if !defined(PVRSRV_DEBUG_LINUX_MEMORY_STATS) || !defined(DEBUG) || !defined(PVRSRV_ENABLE_PROCESS_STATS) || !defined(PVRSRV_ENABLE_MEMORY_STATS)
+/**************************************************************************/ /*!
+@Function       OSAllocMem
+@Description    Allocates CPU memory. Contents are uninitialized.
+                If passed a size of zero, function should not assert,
+                but just return a NULL pointer.
+@Input          ui32Size        Size of required allocation (in bytes)
+@Return         Pointer to allocated memory on success.
+                Otherwise NULL.
+ */ /**************************************************************************/
 void *OSAllocMem(IMG_UINT32 ui32Size);
+/**************************************************************************/ /*!
+@Function       OSAllocZMem
+@Description    Allocates CPU memory and initializes the contents to zero.
+                If passed a size of zero, function should not assert,
+                but just return a NULL pointer.
+@Input          ui32Size        Size of required allocation (in bytes)
+@Return         Pointer to allocated memory on success.
+                Otherwise NULL.
+ */ /**************************************************************************/
 void *OSAllocZMem(IMG_UINT32 ui32Size);
 #else
 void *_OSAllocMem(IMG_UINT32 ui32Size, void *pvAllocFromFile, IMG_UINT32 ui32AllocFromLine);
@@ -62,24 +81,87 @@
     _OSAllocZMem ((_size), (__FILE__), (__LINE__));
 #endif
 
+/**************************************************************************/ /*!
+@Function       OSAllocMemNoStats
+@Description    Allocates CPU memory. Contents are uninitialized.
+                If passed a size of zero, function should not assert,
+                but just return a NULL pointer.
+                The allocated memory is not accounted for by process stats.
+                Process stats are an optional feature (enabled only when
+                PVRSRV_ENABLE_PROCESS_STATS is defined) which track the amount
+                of memory allocated to help in debugging. Where this is not
+                required, OSAllocMem() and OSAllocMemNoStats() equate to
+                the same operation.
+@Input          ui32Size        Size of required allocation (in bytes)
+@Return         Pointer to allocated memory on success.
+                Otherwise NULL.
+ */ /**************************************************************************/
 void *OSAllocMemNoStats(IMG_UINT32 ui32Size);
 
+/**************************************************************************/ /*!
+@Function       OSAllocZMemNoStats
+@Description    Allocates CPU memory and initializes the contents to zero.
+                If passed a size of zero, function should not assert,
+                but just return a NULL pointer.
+                The allocated memory is not accounted for by process stats.
+                Process stats are an optional feature (enabled only when
+                PVRSRV_ENABLE_PROCESS_STATS is defined) which track the amount
+                of memory allocated to help in debugging. Where this is not
+                required, OSAllocZMem() and OSAllocZMemNoStats() equate to
+                the same operation.
+@Input          ui32Size        Size of required allocation (in bytes)
+@Return         Pointer to allocated memory on success.
+                Otherwise NULL.
+ */ /**************************************************************************/
 void *OSAllocZMemNoStats(IMG_UINT32 ui32Size);
 
+/**************************************************************************/ /*!
+@Function       OSFreeMem
+@Description    Frees previously allocated CPU memory.
+@Input          pvCpuVAddr       Pointer to the memory to be freed.
+@Return         None.
+ */ /**************************************************************************/
 void OSFreeMem(void *pvCpuVAddr);
 
-#define OSFREEMEM(_ptr) do \
-	{ OSFreeMem((_ptr)); \
-		(_ptr) = (void*)0; \
-		MSC_SUPPRESS_4127\
-	} while (0)
-
+/**************************************************************************/ /*!
+@Function       OSFreeMemNoStats
+@Description    Frees previously allocated CPU memory.
+                The freed memory does not update the figures in process stats.
+                Process stats are an optional feature (enabled only when
+                PVRSRV_ENABLE_PROCESS_STATS is defined) which track the amount
+                of memory allocated to help in debugging. Where this is not
+                required, OSFreeMem() and OSFreeMemNoStats() equate to the
+                same operation.
+@Input          pvCpuVAddr       Pointer to the memory to be freed.
+@Return         None.
+ */ /**************************************************************************/
 void OSFreeMemNoStats(void *pvCpuVAddr);
 
-#define OSFREEMEMNOSTATS(_ptr) do \
-	{ OSFreeMemNoStats((_ptr)); \
-		(_ptr) = (void*)0; \
-		MSC_SUPPRESS_4127\
+/*
+ * These macros allow us to catch double-free bugs on DEBUG builds and
+ * prevent crashes on RELEASE builds.
+ */
+
+#if defined(DEBUG)
+#define double_free_sentinel (void*) &OSFreeMem
+#define ALLOCMEM_ASSERT(exp) PVR_ASSERT(exp)
+#else
+#define double_free_sentinel NULL
+#define ALLOCMEM_ASSERT(exp) do {} while(0)
+#endif
+
+#define OSFreeMem(_ptr) do { \
+		ALLOCMEM_ASSERT((_ptr) != double_free_sentinel); \
+		(OSFreeMem)(_ptr); \
+		(_ptr) = double_free_sentinel; \
+		MSC_SUPPRESS_4127 \
+	} while (0)
+
+#define OSFreeMemNoStats(_ptr) do { \
+		ALLOCMEM_ASSERT((_ptr) != double_free_sentinel); \
+		(OSFreeMemNoStats)(_ptr); \
+		(_ptr) = double_free_sentinel; \
+		MSC_SUPPRESS_4127 \
 	} while (0)
 
 #if defined (__cplusplus)
diff --git a/drivers/staging/imgtec/rogue/cache_generic.c b/drivers/staging/imgtec/rogue/cache_generic.c
deleted file mode 100644
index 38eff4a..0000000
--- a/drivers/staging/imgtec/rogue/cache_generic.c
+++ /dev/null
@@ -1,380 +0,0 @@
-/*************************************************************************/ /*!
-@File           cache_generic.c
-@Title          CPU generic cache management
-@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
-@Description    Implements server side code for CPU cache management in a
-                CPU agnostic manner.
-@License        Dual MIT/GPLv2
-
-The contents of this file are subject to the MIT license as set out below.
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-Alternatively, the contents of this file may be used under the terms of
-the GNU General Public License Version 2 ("GPL") in which case the provisions
-of GPL are applicable instead of those above.
-
-If you wish to allow use of your version of this file only under the terms of
-GPL, and not to allow others to use your version of this file under the terms
-of the MIT license, indicate your decision by deleting the provisions above
-and replace them with the notice and other provisions required by GPL as set
-out in the file called "GPL-COPYING" included in this distribution. If you do
-not delete the provisions above, a recipient may use your version of this file
-under the terms of either the MIT license or GPL.
-
-This License is also included in this distribution in the file called
-"MIT-COPYING".
-
-EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
-PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
-BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
-PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
-COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
-IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
-CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-*/ /**************************************************************************/
-#include "cache_generic.h"
-#include "cache_internal.h"
-#include "device.h"
-#include "pvr_debug.h"
-#include "pvrsrv.h"
-#include "osfunc.h"
-#include "pmr.h"
-
-#if defined(SUPPORT_RANGEBASED_CACHEFLUSH)
-//#define CACHEOP_NO_CACHE_LINE_ALIGNED_ROUNDING
-static IMG_UINT32 guiCacheLineSize = 0;
-static size_t guiOSPageSize = 0;
-
-/* Perform requested CacheOp on the CPU data cache for successive cache
-   line worth of bytes up to page or in-page cache-line boundary */
-static INLINE void CacheOpCPURangeBased (PVRSRV_CACHE_OP uiCacheOp,
-										 IMG_BYTE *pbCpuVirtAddr,
-										 IMG_CPU_PHYADDR sCpuPhyAddr,
-										 IMG_DEVMEM_OFFSET_T uiPgAlignedOffset,
-										 IMG_DEVMEM_OFFSET_T uiCLAlignedStartOffset,
-										 IMG_DEVMEM_OFFSET_T uiCLAlignedEndOffset)
-{
-	IMG_BYTE *pbCpuVirtAddrEnd;
-	IMG_BYTE *pbCpuVirtAddrStart;
-	IMG_CPU_PHYADDR sCpuPhyAddrEnd;
-	IMG_CPU_PHYADDR sCpuPhyAddrStart;
-	IMG_DEVMEM_SIZE_T uiRelFlushSize;
-	IMG_DEVMEM_OFFSET_T uiRelFlushOffset;
-	IMG_DEVMEM_SIZE_T uiNextPgAlignedOffset;
-
-	/* These quantities allows us to perform cache operations
-	   at cache-line granularity thereby ensuring we do not
-	   perform more than is necessary */
-	PVR_ASSERT(uiPgAlignedOffset < uiCLAlignedEndOffset);
-	uiRelFlushSize = (IMG_DEVMEM_SIZE_T)guiOSPageSize;
-	uiRelFlushOffset = 0;
-
-	if (uiCLAlignedStartOffset > uiPgAlignedOffset)
-	{
-		/* Zero unless initially starting at an in-page offset */
-		uiRelFlushOffset = uiCLAlignedStartOffset - uiPgAlignedOffset;
-		uiRelFlushSize -= uiRelFlushOffset;
-	}
-
-	/* uiRelFlushSize is guiOSPageSize unless current outstanding CacheOp
-	   size is smaller. The 1st case handles in-page CacheOp range and
-	   the 2nd case handles multiple-page CacheOp range with a last
-	   CacheOp size that is less than guiOSPageSize */
-	uiNextPgAlignedOffset = uiPgAlignedOffset + (IMG_DEVMEM_SIZE_T)guiOSPageSize;
-	if (uiNextPgAlignedOffset < uiPgAlignedOffset)
-	{
-		/* uiNextPgAlignedOffset is greater than uiCLAlignedEndOffset
-		   by implication of this wrap-round; this only happens when
-		   uiPgAlignedOffset is the last page aligned offset */
-		uiRelFlushSize = uiRelFlushOffset ?
-				uiCLAlignedEndOffset - uiCLAlignedStartOffset :
-				uiCLAlignedEndOffset - uiPgAlignedOffset;
-	}
-	else
-	{
-		if (uiNextPgAlignedOffset > uiCLAlignedEndOffset)
-		{
-			uiRelFlushSize = uiRelFlushOffset ?
-					uiCLAlignedEndOffset - uiCLAlignedStartOffset :
-					uiCLAlignedEndOffset - uiPgAlignedOffset;
-		}
-	}
-
-	/* More efficient to request cache maintenance operation for full
-	   relative range as opposed to multiple cache-aligned ranges */
-	pbCpuVirtAddrStart = pbCpuVirtAddr + uiRelFlushOffset;
-	pbCpuVirtAddrEnd = pbCpuVirtAddrStart + uiRelFlushSize;
-	sCpuPhyAddrStart.uiAddr = sCpuPhyAddr.uiAddr + uiRelFlushOffset;
-	sCpuPhyAddrEnd.uiAddr = sCpuPhyAddrStart.uiAddr + uiRelFlushSize;
-
-	switch (uiCacheOp)
-	{
-		case PVRSRV_CACHE_OP_CLEAN:
-			OSCleanCPUCacheRangeKM(pbCpuVirtAddrStart, pbCpuVirtAddrEnd,
-									sCpuPhyAddrStart, sCpuPhyAddrEnd);
-			break;
-		case PVRSRV_CACHE_OP_INVALIDATE:
-			OSInvalidateCPUCacheRangeKM(pbCpuVirtAddrStart, pbCpuVirtAddrEnd,
-									sCpuPhyAddrStart, sCpuPhyAddrEnd);
-			break;
-		case PVRSRV_CACHE_OP_FLUSH:
-			OSFlushCPUCacheRangeKM(pbCpuVirtAddrStart, pbCpuVirtAddrEnd,
-									sCpuPhyAddrStart, sCpuPhyAddrEnd);
-			break;
-		default:
-			PVR_DPF((PVR_DBG_ERROR,	"%s: Invalid cache operation type %d",
-					__FUNCTION__, uiCacheOp));
-			PVR_ASSERT(0);
-			break;
-	}
-}
-
-PVRSRV_ERROR CacheOpQueue(PMR *psPMR,
-						  IMG_DEVMEM_OFFSET_T uiOffset,
-						  IMG_DEVMEM_SIZE_T uiSize,
-						  PVRSRV_CACHE_OP uiCacheOp)
-{
-	IMG_HANDLE hPrivOut;
-	IMG_BOOL bPMRIsSparse;
-	IMG_UINT32 ui32PageIndex;
-	IMG_UINT32 ui32NumOfPages;
-	IMG_DEVMEM_SIZE_T uiOutSize;
-	IMG_DEVMEM_SIZE_T uiPgAlignedSize;
-	IMG_DEVMEM_OFFSET_T uiCLAlignedEndOffset;
-	IMG_DEVMEM_OFFSET_T uiPgAlignedEndOffset;
-	IMG_DEVMEM_OFFSET_T uiCLAlignedStartOffset;
-	IMG_DEVMEM_OFFSET_T uiPgAlignedStartOffset;
-	IMG_DEVMEM_OFFSET_T uiPgAlignedOffsetNext;
-	PVRSRV_CACHE_OP_ADDR_TYPE uiCacheOpAddrType;
-	IMG_BOOL abValid[PMR_MAX_TRANSLATION_STACK_ALLOC];
-	IMG_CPU_PHYADDR asCpuPhyAddr[PMR_MAX_TRANSLATION_STACK_ALLOC];
-	IMG_UINT32 OS_PAGE_SHIFT = (IMG_UINT32) OSGetPageShift();
-	IMG_CPU_PHYADDR *psCpuPhyAddr = asCpuPhyAddr;
-	IMG_BOOL bIsPMRDataRetrieved = IMG_FALSE;
-	PVRSRV_ERROR eError = PVRSRV_OK;
-	IMG_BYTE *pbCpuVirtAddr = NULL;
-	IMG_BOOL *pbValid = abValid;
-
-	if (uiCacheOp == PVRSRV_CACHE_OP_NONE)
-	{
-		PVR_ASSERT(0);
-		return PVRSRV_OK;
-	}
-	else
-	{
-		/* Carry out full dcache operation if size (in pages) qualifies */
-		if ((uiSize >> OS_PAGE_SHIFT) > PVR_DIRTY_PAGECOUNT_FLUSH_THRESHOLD)
-		{
-			eError = OSCPUOperation(PVRSRV_CACHE_OP_FLUSH);
-			if (eError == PVRSRV_OK)
-			{
-				return PVRSRV_OK;
-			}
-		}
-
-		if (! guiCacheLineSize)
-		{
-			guiCacheLineSize = OSCPUCacheAttributeSize(PVR_DCACHE_LINE_SIZE);
-			PVR_ASSERT(guiCacheLineSize != 0);
-
-			guiOSPageSize = OSGetPageSize();
-			PVR_ASSERT(guiOSPageSize != 0);
-		}
-	}
-
-	/* Need this for kernel mapping */
-	bPMRIsSparse = PMR_IsSparse(psPMR);
-
-	/* Round the incoming offset down to the nearest cache-line / page aligned-address */
-	uiCLAlignedEndOffset = uiOffset + uiSize;
-	uiCLAlignedEndOffset = PVR_ALIGN(uiCLAlignedEndOffset, (IMG_DEVMEM_SIZE_T)guiCacheLineSize);
-	uiCLAlignedStartOffset = (uiOffset & ~((IMG_DEVMEM_OFFSET_T)guiCacheLineSize-1));
-
-	uiPgAlignedEndOffset = uiCLAlignedEndOffset;
-	uiPgAlignedEndOffset = PVR_ALIGN(uiPgAlignedEndOffset, (IMG_DEVMEM_SIZE_T)guiOSPageSize);
-	uiPgAlignedStartOffset = (uiOffset & ~((IMG_DEVMEM_OFFSET_T)guiOSPageSize-1));
-	uiPgAlignedSize = uiPgAlignedEndOffset - uiPgAlignedStartOffset;
-
-#if defined(CACHEOP_NO_CACHE_LINE_ALIGNED_ROUNDING)
-	/* For internal debug if cache-line optimised
-	   flushing is suspected of causing data corruption */
-	uiCLAlignedStartOffset = uiPgAlignedStartOffset;
-	uiCLAlignedEndOffset = uiPgAlignedEndOffset;
-#endif
-
-	/* Which type of address(es) do we need for this CacheOp */
-	uiCacheOpAddrType = OSCPUCacheOpAddressType(uiCacheOp);
-
-	/* Type of allocation backing the PMR data */
-	ui32NumOfPages = uiPgAlignedSize >> OS_PAGE_SHIFT;
-	if (ui32NumOfPages > PMR_MAX_TRANSLATION_STACK_ALLOC)
-	{
-		/* The pbValid array is allocated first as it is needed in
-		   both physical/virtual cache maintenance methods */
-		pbValid = OSAllocZMem(ui32NumOfPages * sizeof(IMG_BOOL));
-		if (pbValid != NULL)
-		{
-			if (uiCacheOpAddrType != PVRSRV_CACHE_OP_ADDR_TYPE_VIRTUAL)
-			{
-				psCpuPhyAddr = OSAllocZMem(ui32NumOfPages * sizeof(IMG_CPU_PHYADDR));
-				if (psCpuPhyAddr == NULL)
-				{
-					psCpuPhyAddr = asCpuPhyAddr;
-					OSFreeMem(pbValid);
-					pbValid = abValid;
-				}
-			}
-		}
-		else
-		{
-			pbValid = abValid;
-		}
-	}
-
-	/* We always retrieve PMR data in bulk, up-front if number of pages is within
-	   PMR_MAX_TRANSLATION_STACK_ALLOC limits else we check to ensure that a 
-	   dynamic buffer has been allocated to satisfy requests outside limits */
-	if (ui32NumOfPages <= PMR_MAX_TRANSLATION_STACK_ALLOC || pbValid != abValid)
-	{
-		if (uiCacheOpAddrType != PVRSRV_CACHE_OP_ADDR_TYPE_VIRTUAL)
-		{
-			/* Look-up PMR CpuPhyAddr once, if possible */
-			eError = PMR_CpuPhysAddr(psPMR,
-									 OS_PAGE_SHIFT,
-									 ui32NumOfPages,
-									 uiPgAlignedStartOffset,
-									 psCpuPhyAddr,
-									 pbValid);
-			if (eError == PVRSRV_OK)
-			{
-				bIsPMRDataRetrieved = IMG_TRUE;
-			}
-		}
-	}
-
-	/* For each device page, carry out the requested cache maintenance operation */
-	for (uiPgAlignedOffsetNext = uiPgAlignedStartOffset, ui32PageIndex = 0;
-		 uiPgAlignedOffsetNext < uiPgAlignedEndOffset;
-		 uiPgAlignedOffsetNext += (IMG_DEVMEM_OFFSET_T) guiOSPageSize, ui32PageIndex += 1)
-	{
-		if (bIsPMRDataRetrieved == IMG_FALSE)
-		{
-			/* Never cross page boundary without looking up corresponding
-			   PMR page physical address and/or page validity if these
-			   were not looked-up, in bulk, up-front */	
-			ui32PageIndex = 0;
-			if (uiCacheOpAddrType != PVRSRV_CACHE_OP_ADDR_TYPE_VIRTUAL)
-			{
-				eError = PMR_CpuPhysAddr(psPMR,
-										 OS_PAGE_SHIFT,
-										 1,
-										 uiPgAlignedOffsetNext,
-										 psCpuPhyAddr,
-										 pbValid);
-				if (eError != PVRSRV_OK)
-				{
-					PVR_ASSERT(0);
-					goto e0;
-				}
-			}
-			else
-			{
-				PMR_IsOffsetValid(psPMR,
-								  uiPgAlignedOffsetNext,
-								  pbValid);
-			}
-		}
-
-		/* Skip invalid PMR pages (i.e. sparse) */
-		if (pbValid[ui32PageIndex] == IMG_FALSE)
-		{
-			continue;
-		}
-
-		/* Skip virtual address acquire if CacheOp can be maintained
-		   entirely using PMR physical addresses */
-		if (uiCacheOpAddrType != PVRSRV_CACHE_OP_ADDR_TYPE_PHYSICAL)
-		{
-			if (bPMRIsSparse)
-			{
-				eError =
-					PMRAcquireSparseKernelMappingData(psPMR,
-													  uiPgAlignedOffsetNext,
-													  guiOSPageSize,
-													  (void **)&pbCpuVirtAddr,
-													  (size_t*)&uiOutSize,
-													  &hPrivOut);
-				if (eError != PVRSRV_OK)
-				{
-					PVR_ASSERT(0);
-					goto e0;
-				}
-			}
-			else
-			{
-				eError =
-					PMRAcquireKernelMappingData(psPMR,
-												uiPgAlignedOffsetNext,
-												guiOSPageSize,
-												(void **)&pbCpuVirtAddr,
-												(size_t*)&uiOutSize,
-												&hPrivOut);
-				if (eError != PVRSRV_OK)
-				{
-					PVR_ASSERT(0);
-					goto e0;
-				}
-			}
-		}
-
-		/* Issue actual cache maintenance for PMR */
-		CacheOpCPURangeBased(uiCacheOp,
-							 pbCpuVirtAddr,
-							 (uiCacheOpAddrType != PVRSRV_CACHE_OP_ADDR_TYPE_VIRTUAL) ?
-								psCpuPhyAddr[ui32PageIndex] : psCpuPhyAddr[0],
-							 uiPgAlignedOffsetNext,
-							 uiCLAlignedStartOffset,
-							 uiCLAlignedEndOffset);
-
-		/* Skip virtual address release if CacheOp can be maintained
-		   entirely using PMR physical addresses */
-		if (uiCacheOpAddrType != PVRSRV_CACHE_OP_ADDR_TYPE_PHYSICAL)
-		{
-			eError = PMRReleaseKernelMappingData(psPMR, hPrivOut);
-			PVR_ASSERT(eError == PVRSRV_OK);
-		}
-	}
-
-e0:
-	if (psCpuPhyAddr != asCpuPhyAddr)
-	{
-		OSFreeMem(psCpuPhyAddr);
-	}
-
-	if (pbValid != abValid)
-	{
-		OSFreeMem(pbValid);
-	}
-
-	return eError;
-}
-#else
-PVRSRV_ERROR CacheOpQueue(PMR *psPMR,
-						  IMG_DEVMEM_OFFSET_T uiOffset,
-						  IMG_DEVMEM_SIZE_T uiSize,
-						  PVRSRV_CACHE_OP uiCacheOp)
-{
-	PVRSRV_DATA *psData = PVRSRVGetPVRSRVData();
-	psData->uiCacheOp = SetCacheOp(psData->uiCacheOp, uiCacheOp);
-	return PVRSRV_OK;
-}
-#endif
diff --git a/drivers/staging/imgtec/rogue/cache_km.c b/drivers/staging/imgtec/rogue/cache_km.c
new file mode 100644
index 0000000..37100d6
--- /dev/null
+++ b/drivers/staging/imgtec/rogue/cache_km.c
@@ -0,0 +1,2219 @@
+/*************************************************************************/ /*!
+@File           cache_km.c
+@Title          CPU data cache management
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description    Implements server side code for CPU cache maintenance management.
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+#if defined(SUPPORT_NATIVE_FENCE_SYNC) && defined(CONFIG_SW_SYNC)
+#include <linux/version.h>
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 10, 0))
+#include <linux/sw_sync.h>
+#else
+#include <../drivers/staging/android/sw_sync.h>
+#endif
+#include <linux/file.h>
+#include <linux/fs.h>
+#endif
+#include "pmr.h"
+#include "device.h"
+#include "pvrsrv.h"
+#include "osfunc.h"
+#include "cache_km.h"
+#include "pvr_debug.h"
+#include "lock_types.h"
+#include "allocmem.h"
+#include "process_stats.h"
+#if defined(PVR_RI_DEBUG)
+#include "ri_server.h"
+#endif
+
+/* Top-level file-local build definitions */
+#if defined(DEBUG) && defined(LINUX)
+	#define CACHEOP_DEBUG
+#endif
+
+/* Type of cache maintenance mechanism being used */
+#if (CACHEFLUSH_KM_TYPE == CACHEFLUSH_KM_RANGEBASED_DEFERRED)
+	#define SUPPORT_RANGEBASED_CACHEFLUSH_DEFERRED
+	#define SUPPORT_RANGEBASED_CACHEFLUSH
+#elif (CACHEFLUSH_KM_TYPE == CACHEFLUSH_KM_RANGEBASED)
+	#define SUPPORT_RANGEBASED_CACHEFLUSH
+#elif (CACHEFLUSH_KM_TYPE == CACHEFLUSH_KM_GLOBAL)
+	/* Nothing to do here */
+#else
+	#error "Unknown CACHEFLUSH_KM_TYPE"
+#endif
+
+typedef struct _CACHEOP_WORK_ITEM_
+{
+	DLLIST_NODE sNode;
+	PMR *psPMR;
+	struct file *psTimeline;
+	IMG_UINT32 ui32OpSeqNum;
+	IMG_DEVMEM_SIZE_T uiSize;
+	PVRSRV_CACHE_OP uiCacheOp;
+	IMG_DEVMEM_OFFSET_T uiOffset;
+	IMG_BOOL bSignalEventObject;
+#if defined(CACHEOP_DEBUG)
+	IMG_UINT64	ui64QueuedTime;
+	IMG_UINT64	ui64ExecuteTime;
+	IMG_BOOL bRBF;
+	IMG_BOOL bUMF;
+	IMG_PID pid;
+#if defined(PVR_RI_DEBUG)
+	RGXFWIF_DM eFenceOpType;
+#endif
+#endif
+} CACHEOP_WORK_ITEM;
+
+/* Copy of CPU page & dcache-line size */
+static size_t guiOSPageSize;
+static IMG_UINT32 guiCacheLineSize;
+
+/* 
+  System-wide CacheOp sequence numbers
+  - ghCommonCacheOpSeqNum:
+		This common sequence, numbers mostly CacheOp requests
+		from UM/KM but might also number fence checks and
+		completed CacheOps depending on SUPPORT_XXX configs.
+  - ghCompletedCacheOpSeqNum:
+		This tracks last CacheOp request that was executed
+		in all SUPPORT_XXX configurations and is used for
+		fence checks exclusively.
+*/
+static ATOMIC_T ghCommonCacheOpSeqNum;
+static ATOMIC_T ghCompletedCacheOpSeqNum;
+
+#if defined(CACHEOP_DEBUG)
+#define CACHEOP_MAX_STATS_ITEMS 128
+#define INCR_WRAP(x) ((x+1) >= CACHEOP_MAX_STATS_ITEMS ? 0 : (x+1))
+#define DECR_WRAP(x) ((x-1) < 0 ? (CACHEOP_MAX_STATS_ITEMS-1) : (x-1))
+#if defined(PVR_RI_DEBUG)
+/* Refer to CacheOpStatExecLogHeader() for header item names */
+#define CACHEOP_RI_PRINTF_HEADER "%-10s %-10s %-5s %-8s %-16s %-10s %-10s %-18s %-12s"
+#define CACHEOP_RI_PRINTF_FENCE	 "%-10s %-10s %-5s %-8d %-16s %-10s %-10s %-18llu 0x%-10x\n"
+#define CACHEOP_RI_PRINTF		 "%-10s %-10s %-5s %-8d 0x%-14llx 0x%-8llx 0x%-8llx %-18llu 0x%-10x\n"
+#else
+#define CACHEOP_PRINTF_HEADER	 "%-10s %-10s %-5s %-10s %-10s %-18s %-12s"
+#define CACHEOP_PRINTF_FENCE	 "%-10s %-10s %-5s %-10s %-10s %-18llu 0x%-10x\n"
+#define CACHEOP_PRINTF		 	 "%-10s %-10s %-5s 0x%-8llx 0x%-8llx %-18llu 0x%-10x\n"
+#endif
+
+/* Divide a number by 10 using shifts only */
+static INLINE IMG_UINT64 DivBy10(IMG_UINT64 uiNum)
+{
+	IMG_UINT64 uiQuot;
+	IMG_UINT64 uiRem;
+
+	uiQuot = (uiNum >> 1) + (uiNum >> 2);
+	uiQuot = uiQuot + (uiQuot >> 4);
+	uiQuot = uiQuot + (uiQuot >> 8);
+	uiQuot = uiQuot + (uiQuot >> 16);
+	uiQuot = uiQuot >> 3;
+	uiRem  = uiNum - (((uiQuot << 2) + uiQuot) << 1);
+
+	return uiQuot + (uiRem > 9);
+}
+
+#if defined(SUPPORT_RANGEBASED_CACHEFLUSH_DEFERRED)
+typedef struct _CACHEOP_STAT_STALL_ITEM_
+{
+	IMG_UINT32 ui32OpSeqNum;
+	IMG_UINT32 ui32RetryCount;
+	IMG_UINT64 ui64QueuedTime;
+	IMG_UINT64 ui64ExecuteTime;
+} CACHEOP_STAT_STALL_ITEM;
+
+/* These are used in an atomic way so will never
+   hold values outside of the valid range */
+static IMG_INT32 gi32CacheOpStatStallWriteIdx;
+static IMG_HANDLE ghCacheOpStatStallLock;
+static void *pvCacheOpStatStallEntry;
+
+static CACHEOP_STAT_STALL_ITEM gasCacheOpStatStalled[CACHEOP_MAX_STATS_ITEMS];
+
+static INLINE void CacheOpStatStallLogHeader(IMG_CHAR szBuffer[PVR_MAX_DEBUG_MESSAGE_LEN])
+{
+	OSSNPrintf(szBuffer, PVR_MAX_DEBUG_MESSAGE_LEN,
+				"%-10s %-12s %-10s",
+				"SeqNo",
+				"Time (ns)",
+				"RetryCount");
+}
+
+static INLINE void CacheOpStatStallLogWrite(IMG_UINT32 ui32FenceOpSeqNum,
+											IMG_UINT64 ui64QueuedTime,
+											IMG_UINT64 ui64ExecuteTime,
+											IMG_UINT32 ui32RetryCount)
+{
+	IMG_INT32 i32WriteOffset = gi32CacheOpStatStallWriteIdx;
+	gi32CacheOpStatStallWriteIdx = INCR_WRAP(gi32CacheOpStatStallWriteIdx);
+	gasCacheOpStatStalled[i32WriteOffset].ui32RetryCount = ui32RetryCount;
+	gasCacheOpStatStalled[i32WriteOffset].ui32OpSeqNum = ui32FenceOpSeqNum;
+	gasCacheOpStatStalled[i32WriteOffset].ui64QueuedTime = ui64QueuedTime;
+	gasCacheOpStatStalled[i32WriteOffset].ui64ExecuteTime = ui64ExecuteTime;
+}
+
+static void CacheOpStatStallLogRead(void *pvFilePtr, void *pvData,
+							 OS_STATS_PRINTF_FUNC* pfnOSStatsPrintf)
+{
+	IMG_INT32 i32ReadOffset;
+	IMG_INT32 i32WriteOffset;
+	IMG_CHAR szBuffer[PVR_MAX_DEBUG_MESSAGE_LEN]={0};
+
+	PVR_UNREFERENCED_PARAMETER(pvData);
+
+	CacheOpStatStallLogHeader(szBuffer);
+	pfnOSStatsPrintf(pvFilePtr, "%s\n", szBuffer);
+
+	OSLockAcquire(ghCacheOpStatStallLock);
+
+	i32WriteOffset = gi32CacheOpStatStallWriteIdx;
+	for (i32ReadOffset = DECR_WRAP(i32WriteOffset);
+		 i32ReadOffset != i32WriteOffset; 
+		 i32ReadOffset = DECR_WRAP(i32ReadOffset))
+	{
+		IMG_UINT64 ui64QueuedTime, ui64ExecuteTime;
+
+		if (gasCacheOpStatStalled[i32ReadOffset].ui32OpSeqNum == 0)
+		{
+			break;
+		}
+
+		/* Convert from nano-seconds to micro-seconds */
+		ui64ExecuteTime = gasCacheOpStatStalled[i32ReadOffset].ui64ExecuteTime;
+		ui64QueuedTime = gasCacheOpStatStalled[i32ReadOffset].ui64QueuedTime;
+		ui64ExecuteTime = DivBy10(DivBy10(DivBy10(ui64ExecuteTime)));
+		ui64QueuedTime = DivBy10(DivBy10(DivBy10(ui64QueuedTime)));
+
+		pfnOSStatsPrintf(pvFilePtr,
+						"%-10x 0x%-10llx %-10x\n",
+						gasCacheOpStatStalled[i32ReadOffset].ui32OpSeqNum,
+						ui64QueuedTime < ui64ExecuteTime ?
+								ui64ExecuteTime - ui64QueuedTime :
+								ui64QueuedTime - ui64ExecuteTime,
+						gasCacheOpStatStalled[i32ReadOffset].ui32RetryCount);
+	}
+
+	OSLockRelease(ghCacheOpStatStallLock);
+}
+#endif
+
+typedef struct _CACHEOP_STAT_EXEC_ITEM_
+{
+	IMG_UINT32 ui32OpSeqNum;
+	PVRSRV_CACHE_OP uiCacheOp;
+	IMG_DEVMEM_SIZE_T uiOffset;
+	IMG_DEVMEM_SIZE_T uiSize;
+	IMG_UINT64 ui64QueuedTime;
+	IMG_UINT64 ui64ExecuteTime;
+	IMG_BOOL bHasTimeline;
+	IMG_BOOL bIsFence;
+	IMG_BOOL bRBF;
+	IMG_BOOL bUMF;
+#if defined(PVR_RI_DEBUG)
+	IMG_DEV_VIRTADDR sDevVAddr;
+	RGXFWIF_DM eFenceOpType;
+	IMG_PID pid;
+#endif
+} CACHEOP_STAT_EXEC_ITEM;
+
+/* These are used in an atomic way so will never
+   hold values outside of the valid range */
+static IMG_INT32 gi32CacheOpStatExecWriteIdx;
+static IMG_HANDLE ghCacheOpStatExecLock;
+static void *pvCacheOpStatExecEntry;
+
+static CACHEOP_STAT_EXEC_ITEM gasCacheOpStatExecuted[CACHEOP_MAX_STATS_ITEMS];
+
+static INLINE void CacheOpStatExecLogHeader(IMG_CHAR szBuffer[PVR_MAX_DEBUG_MESSAGE_LEN])
+{
+	OSSNPrintf(szBuffer, PVR_MAX_DEBUG_MESSAGE_LEN,
+#if defined(PVR_RI_DEBUG)
+				CACHEOP_RI_PRINTF_HEADER,
+#else
+				CACHEOP_PRINTF_HEADER,
+#endif
+				"CacheOp",
+				"Type",
+				"Mode",
+#if defined(PVR_RI_DEBUG)
+				"Pid",
+				"DevVAddr",
+#endif
+				"Offset",
+				"Size",
+				"Time (us)",
+				"SeqNo");
+}
+
+static INLINE void CacheOpStatExecLogWrite(DLLIST_NODE *psNode)
+{
+	CACHEOP_WORK_ITEM *psCacheOpWorkItem;
+	IMG_UINT64 ui64ExecuteTime;
+	IMG_UINT64 ui64QueuedTime;
+	IMG_INT32 i32WriteOffset;
+
+	psCacheOpWorkItem = IMG_CONTAINER_OF(psNode, CACHEOP_WORK_ITEM, sNode);	
+	if (psCacheOpWorkItem->ui32OpSeqNum == 0)
+	{
+		/* This breaks the logic of read-out, so we
+		   do not queue items with zero sequence
+		   number */
+		return;
+	}
+
+	i32WriteOffset = gi32CacheOpStatExecWriteIdx;
+	gi32CacheOpStatExecWriteIdx = INCR_WRAP(gi32CacheOpStatExecWriteIdx);
+
+	gasCacheOpStatExecuted[i32WriteOffset].uiSize = psCacheOpWorkItem->uiSize;
+	gasCacheOpStatExecuted[i32WriteOffset].uiOffset	= psCacheOpWorkItem->uiOffset;
+	gasCacheOpStatExecuted[i32WriteOffset].uiCacheOp = psCacheOpWorkItem->uiCacheOp;
+	gasCacheOpStatExecuted[i32WriteOffset].ui32OpSeqNum	= psCacheOpWorkItem->ui32OpSeqNum;
+	gasCacheOpStatExecuted[i32WriteOffset].ui64QueuedTime = psCacheOpWorkItem->ui64QueuedTime;
+	gasCacheOpStatExecuted[i32WriteOffset].ui64ExecuteTime = psCacheOpWorkItem->ui64ExecuteTime;
+	gasCacheOpStatExecuted[i32WriteOffset].bHasTimeline	= psCacheOpWorkItem->psPMR == NULL;
+	gasCacheOpStatExecuted[i32WriteOffset].bRBF = psCacheOpWorkItem->bRBF;
+	gasCacheOpStatExecuted[i32WriteOffset].bUMF = psCacheOpWorkItem->bUMF;
+	gasCacheOpStatExecuted[i32WriteOffset].bIsFence	 =
+			psCacheOpWorkItem->psPMR == NULL && psCacheOpWorkItem->psTimeline == NULL;
+#if defined(PVR_RI_DEBUG)
+	gasCacheOpStatExecuted[i32WriteOffset].pid = psCacheOpWorkItem->pid;
+	PVR_ASSERT(gasCacheOpStatExecuted[i32WriteOffset].pid);
+
+	if (psCacheOpWorkItem->psPMR != NULL)
+	{
+		PVRSRV_ERROR eError;
+
+		/* Get more detailed information regarding the sub allocations that
+		   PMR has from RI manager for process that requested the CacheOp */
+		eError = RIDumpProcessListKM(psCacheOpWorkItem->psPMR,
+									 gasCacheOpStatExecuted[i32WriteOffset].pid,
+									 gasCacheOpStatExecuted[i32WriteOffset].uiOffset,
+									 &gasCacheOpStatExecuted[i32WriteOffset].sDevVAddr);
+		if (eError != PVRSRV_OK)
+		{
+			return;
+		}
+	}
+
+	if (gasCacheOpStatExecuted[i32WriteOffset].bIsFence)
+	{
+		gasCacheOpStatExecuted[i32WriteOffset].eFenceOpType = psCacheOpWorkItem->eFenceOpType;
+	}
+#endif
+
+	ui64ExecuteTime = gasCacheOpStatExecuted[i32WriteOffset].ui64ExecuteTime;
+	ui64QueuedTime = gasCacheOpStatExecuted[i32WriteOffset].ui64QueuedTime;
+
+	/* This operation queues this CacheOp in per-PID process statistics database */
+	PVRSRVStatsUpdateCacheOpStats(gasCacheOpStatExecuted[i32WriteOffset].uiCacheOp,
+					gasCacheOpStatExecuted[i32WriteOffset].ui32OpSeqNum,
+#if defined(PVR_RI_DEBUG)
+					gasCacheOpStatExecuted[i32WriteOffset].sDevVAddr,
+					gasCacheOpStatExecuted[i32WriteOffset].eFenceOpType,
+#endif
+					gasCacheOpStatExecuted[i32WriteOffset].uiOffset,
+					gasCacheOpStatExecuted[i32WriteOffset].uiSize,
+					ui64QueuedTime < ui64ExecuteTime ?
+						ui64ExecuteTime - ui64QueuedTime:
+						ui64QueuedTime - ui64ExecuteTime,
+					gasCacheOpStatExecuted[i32WriteOffset].bRBF,
+					gasCacheOpStatExecuted[i32WriteOffset].bUMF,
+					gasCacheOpStatExecuted[i32WriteOffset].bIsFence,
+					gasCacheOpStatExecuted[i32WriteOffset].bHasTimeline,
+					psCacheOpWorkItem->pid);
+}
+
+static void CacheOpStatExecLogRead(void *pvFilePtr, void *pvData,
+								OS_STATS_PRINTF_FUNC* pfnOSStatsPrintf)
+{
+	IMG_INT32 i32ReadOffset;
+	IMG_INT32 i32WriteOffset;
+	IMG_CHAR *pszCacheOpType;
+	IMG_CHAR *pszFlushSource;
+	IMG_CHAR *pszFlushype;
+	IMG_UINT64 ui64QueuedTime, ui64ExecuteTime;
+	IMG_CHAR szBuffer[PVR_MAX_DEBUG_MESSAGE_LEN]={0};
+
+	PVR_UNREFERENCED_PARAMETER(pvData);
+
+	CacheOpStatExecLogHeader(szBuffer);
+	pfnOSStatsPrintf(pvFilePtr, "%s\n", szBuffer);
+
+	OSLockAcquire(ghCacheOpStatExecLock);
+
+	i32WriteOffset = gi32CacheOpStatExecWriteIdx;
+	for (i32ReadOffset = DECR_WRAP(i32WriteOffset);
+		 i32ReadOffset != i32WriteOffset;
+		 i32ReadOffset = DECR_WRAP(i32ReadOffset))
+	{
+		if (gasCacheOpStatExecuted[i32ReadOffset].ui32OpSeqNum == 0)
+		{
+			break;
+		}
+
+		/* Convert from nano-seconds to micro-seconds */
+		ui64ExecuteTime = gasCacheOpStatExecuted[i32ReadOffset].ui64ExecuteTime;
+		ui64QueuedTime = gasCacheOpStatExecuted[i32ReadOffset].ui64QueuedTime;
+		ui64ExecuteTime = DivBy10(DivBy10(DivBy10(ui64ExecuteTime)));
+		ui64QueuedTime = DivBy10(DivBy10(DivBy10(ui64QueuedTime)));
+
+		if (gasCacheOpStatExecuted[i32ReadOffset].bIsFence)
+		{
+			IMG_CHAR *pszFenceType = "";
+			pszCacheOpType = "Fence";
+
+#if defined(PVR_RI_DEBUG)
+			switch (gasCacheOpStatExecuted[i32ReadOffset].eFenceOpType)
+			{
+				case RGXFWIF_DM_GP:
+					pszFenceType = "GP";
+					break;
+
+				case RGXFWIF_DM_TDM:
+					/* Also case RGXFWIF_DM_2D: */
+					pszFenceType = "TDM/2D";
+					break;
+
+				case RGXFWIF_DM_TA:
+					pszFenceType = "TA";
+					break;
+
+				case RGXFWIF_DM_3D:
+					pszFenceType = "3D";
+					break;
+
+				case RGXFWIF_DM_CDM:
+					pszFenceType = "CDM";
+					break;
+
+				case RGXFWIF_DM_RTU:
+					pszFenceType = "RTU";
+					break;
+
+				case RGXFWIF_DM_SHG:
+					pszFenceType = "SHG";
+					break;
+
+				default:
+					PVR_ASSERT(0);
+					break;
+			}
+#endif
+			pfnOSStatsPrintf(pvFilePtr,
+#if defined(PVR_RI_DEBUG)
+							CACHEOP_RI_PRINTF_FENCE,
+#else
+							CACHEOP_PRINTF_FENCE,
+#endif
+							pszCacheOpType,
+							pszFenceType,
+							"",
+#if defined(PVR_RI_DEBUG)
+							gasCacheOpStatExecuted[i32ReadOffset].pid,
+							"",
+#endif
+							"",
+							"",
+							ui64QueuedTime < ui64ExecuteTime ?
+										ui64ExecuteTime - ui64QueuedTime :
+										ui64QueuedTime - ui64ExecuteTime,
+							gasCacheOpStatExecuted[i32ReadOffset].ui32OpSeqNum);
+		}
+		else if (gasCacheOpStatExecuted[i32ReadOffset].bHasTimeline)
+		{
+			pfnOSStatsPrintf(pvFilePtr,
+#if defined(PVR_RI_DEBUG)
+							CACHEOP_RI_PRINTF_FENCE,
+#else
+							CACHEOP_PRINTF_FENCE,
+#endif
+							"Timeline",
+							"",
+							"",
+#if defined(PVR_RI_DEBUG)
+							gasCacheOpStatExecuted[i32ReadOffset].pid,
+							"",
+#endif
+							"",
+							"",
+							ui64QueuedTime < ui64ExecuteTime ?
+										ui64ExecuteTime - ui64QueuedTime :
+										ui64QueuedTime - ui64ExecuteTime,
+							gasCacheOpStatExecuted[i32ReadOffset].ui32OpSeqNum);
+		}
+		else
+		{
+			if (gasCacheOpStatExecuted[i32ReadOffset].bRBF)
+			{
+				IMG_DEVMEM_SIZE_T ui64NumOfPages;
+
+				ui64NumOfPages = gasCacheOpStatExecuted[i32ReadOffset].uiSize >> OSGetPageShift();
+				if (ui64NumOfPages <= PMR_MAX_TRANSLATION_STACK_ALLOC)
+				{
+					pszFlushype = "RBF.Fast";
+				}
+				else
+				{
+					pszFlushype = "RBF.Slow";
+				}
+			}
+			else
+			{
+				pszFlushype = "GF";
+			}
+
+			if (gasCacheOpStatExecuted[i32ReadOffset].bUMF)
+			{
+				pszFlushSource = "UM";
+			}
+			else
+			{
+				pszFlushSource = "KM";
+			}
+
+			switch (gasCacheOpStatExecuted[i32ReadOffset].uiCacheOp)
+			{
+				case PVRSRV_CACHE_OP_NONE:
+					pszCacheOpType = "None";
+					break;
+				case PVRSRV_CACHE_OP_CLEAN:
+					pszCacheOpType = "Clean";
+					break;
+				case PVRSRV_CACHE_OP_INVALIDATE:
+					pszCacheOpType = "Invalidate";
+					break;
+				case PVRSRV_CACHE_OP_FLUSH:
+					pszCacheOpType = "Flush";
+					break;
+				default:
+					pszCacheOpType = "Unknown";
+					break;
+			}
+
+			pfnOSStatsPrintf(pvFilePtr,
+#if defined(PVR_RI_DEBUG)
+							CACHEOP_RI_PRINTF,
+#else
+							CACHEOP_PRINTF,
+#endif
+							pszCacheOpType,
+							pszFlushype,
+							pszFlushSource,
+#if defined(PVR_RI_DEBUG)
+							gasCacheOpStatExecuted[i32ReadOffset].pid,
+							gasCacheOpStatExecuted[i32ReadOffset].sDevVAddr.uiAddr,
+#endif
+							gasCacheOpStatExecuted[i32ReadOffset].uiOffset,
+							gasCacheOpStatExecuted[i32ReadOffset].uiSize,
+							ui64QueuedTime < ui64ExecuteTime ?
+										ui64ExecuteTime - ui64QueuedTime :
+										ui64QueuedTime - ui64ExecuteTime,
+							gasCacheOpStatExecuted[i32ReadOffset].ui32OpSeqNum);
+		}
+	}
+
+	OSLockRelease(ghCacheOpStatExecLock);
+}
+
+static PVRSRV_ERROR CacheOpStatExecLog(void *pvData)
+{
+	DLLIST_NODE *psListNode = (DLLIST_NODE *) pvData;
+	DLLIST_NODE *psCurrentNode, *psNextNode;
+
+	OSLockAcquire(ghCacheOpStatExecLock);
+
+	CacheOpStatExecLogWrite(psListNode);
+	dllist_foreach_node (psListNode, psCurrentNode, psNextNode)
+	{
+		CacheOpStatExecLogWrite(psCurrentNode);
+	}
+
+	OSLockRelease(ghCacheOpStatExecLock);
+
+	return PVRSRV_OK;
+}
+#endif /* defined(CACHEOP_DEBUG) */
+
+//#define CACHEOP_NO_CACHE_LINE_ALIGNED_ROUNDING
+#define CACHEOP_SEQ_MIDPOINT (IMG_UINT32) 0x7FFFFFFF
+#define CACHEOP_DPFL PVR_DBG_MESSAGE
+
+/* Perform requested CacheOp on the CPU data cache for successive cache
+   line worth of bytes up to page or in-page cache-line boundary */
+static INLINE void CacheOpCPURangeBased(PVRSRV_DEVICE_NODE *psDevNode,
+										PVRSRV_CACHE_OP uiCacheOp,
+										IMG_BYTE *pbCpuVirtAddr,
+										IMG_CPU_PHYADDR sCpuPhyAddr,
+										IMG_DEVMEM_OFFSET_T uiPgAlignedOffset,
+										IMG_DEVMEM_OFFSET_T uiCLAlignedStartOffset,
+										IMG_DEVMEM_OFFSET_T uiCLAlignedEndOffset)
+{
+	IMG_BYTE *pbCpuVirtAddrEnd;
+	IMG_BYTE *pbCpuVirtAddrStart;
+	IMG_CPU_PHYADDR sCpuPhyAddrEnd;
+	IMG_CPU_PHYADDR sCpuPhyAddrStart;
+	IMG_DEVMEM_SIZE_T uiRelFlushSize;
+	IMG_DEVMEM_OFFSET_T uiRelFlushOffset;
+	IMG_DEVMEM_SIZE_T uiNextPgAlignedOffset;
+
+	/* These quantities allows us to perform cache operations
+	   at cache-line granularity thereby ensuring we do not
+	   perform more than is necessary */
+	PVR_ASSERT(uiPgAlignedOffset < uiCLAlignedEndOffset);
+	uiRelFlushSize = (IMG_DEVMEM_SIZE_T)guiOSPageSize;
+	uiRelFlushOffset = 0;
+
+	if (uiCLAlignedStartOffset > uiPgAlignedOffset)
+	{
+		/* Zero unless initially starting at an in-page offset */
+		uiRelFlushOffset = uiCLAlignedStartOffset - uiPgAlignedOffset;
+		uiRelFlushSize -= uiRelFlushOffset;
+	}
+
+	/* uiRelFlushSize is guiOSPageSize unless current outstanding CacheOp
+	   size is smaller. The 1st case handles in-page CacheOp range and
+	   the 2nd case handles multiple-page CacheOp range with a last
+	   CacheOp size that is less than guiOSPageSize */
+	uiNextPgAlignedOffset = uiPgAlignedOffset + (IMG_DEVMEM_SIZE_T)guiOSPageSize;
+	if (uiNextPgAlignedOffset < uiPgAlignedOffset)
+	{
+		/* uiNextPgAlignedOffset is greater than uiCLAlignedEndOffset
+		   by implication of this wrap-round; this only happens when
+		   uiPgAlignedOffset is the last page aligned offset */
+		uiRelFlushSize = uiRelFlushOffset ?
+				uiCLAlignedEndOffset - uiCLAlignedStartOffset :
+				uiCLAlignedEndOffset - uiPgAlignedOffset;
+	}
+	else
+	{
+		if (uiNextPgAlignedOffset > uiCLAlignedEndOffset)
+		{
+			uiRelFlushSize = uiRelFlushOffset ?
+					uiCLAlignedEndOffset - uiCLAlignedStartOffset :
+					uiCLAlignedEndOffset - uiPgAlignedOffset;
+		}
+	}
+
+	/* More efficient to request cache maintenance operation for full
+	   relative range as opposed to multiple cache-aligned ranges */
+	pbCpuVirtAddrStart = pbCpuVirtAddr + uiRelFlushOffset;
+	pbCpuVirtAddrEnd = pbCpuVirtAddrStart + uiRelFlushSize;
+	sCpuPhyAddrStart.uiAddr = sCpuPhyAddr.uiAddr + uiRelFlushOffset;
+	sCpuPhyAddrEnd.uiAddr = sCpuPhyAddrStart.uiAddr + uiRelFlushSize;
+
+	switch (uiCacheOp)
+	{
+		case PVRSRV_CACHE_OP_CLEAN:
+			OSCleanCPUCacheRangeKM(psDevNode, pbCpuVirtAddrStart, pbCpuVirtAddrEnd,
+									sCpuPhyAddrStart, sCpuPhyAddrEnd);
+			break;
+		case PVRSRV_CACHE_OP_INVALIDATE:
+			OSInvalidateCPUCacheRangeKM(psDevNode, pbCpuVirtAddrStart, pbCpuVirtAddrEnd,
+									sCpuPhyAddrStart, sCpuPhyAddrEnd);
+			break;
+		case PVRSRV_CACHE_OP_FLUSH:
+			OSFlushCPUCacheRangeKM(psDevNode, pbCpuVirtAddrStart, pbCpuVirtAddrEnd,
+									sCpuPhyAddrStart, sCpuPhyAddrEnd);
+			break;
+		default:
+			PVR_DPF((PVR_DBG_ERROR,	"%s: Invalid cache operation type %d",
+					__FUNCTION__, uiCacheOp));
+			PVR_ASSERT(0);
+			break;
+	}
+}
+
+/* This function assumes the PMR is locked */
+static PVRSRV_ERROR CacheOpRangeBased (PMR *psPMR,
+									   IMG_DEVMEM_OFFSET_T uiOffset,
+									   IMG_DEVMEM_SIZE_T uiSize,
+									   PVRSRV_CACHE_OP uiCacheOp,
+									   IMG_BOOL *bUsedGlobalFlush)
+{
+	IMG_HANDLE hPrivOut;
+	IMG_BOOL bPMRIsSparse;
+	IMG_UINT32 ui32PageIndex;
+	IMG_UINT32 ui32NumOfPages;
+	IMG_DEVMEM_SIZE_T uiOutSize;
+	IMG_DEVMEM_SIZE_T uiPgAlignedSize;
+	IMG_DEVMEM_OFFSET_T uiCLAlignedEndOffset;
+	IMG_DEVMEM_OFFSET_T uiPgAlignedEndOffset;
+	IMG_DEVMEM_OFFSET_T uiCLAlignedStartOffset;
+	IMG_DEVMEM_OFFSET_T uiPgAlignedStartOffset;
+	IMG_DEVMEM_OFFSET_T uiPgAlignedOffsetNext;
+	PVRSRV_CACHE_OP_ADDR_TYPE uiCacheOpAddrType;
+	IMG_BOOL abValid[PMR_MAX_TRANSLATION_STACK_ALLOC];
+	IMG_CPU_PHYADDR asCpuPhyAddr[PMR_MAX_TRANSLATION_STACK_ALLOC];
+	IMG_UINT32 OS_PAGE_SHIFT = (IMG_UINT32) OSGetPageShift();
+	IMG_CPU_PHYADDR *psCpuPhyAddr = asCpuPhyAddr;
+	IMG_BOOL bIsPMRDataRetrieved = IMG_FALSE;
+	PVRSRV_ERROR eError = PVRSRV_OK;
+	IMG_BYTE *pbCpuVirtAddr = NULL;
+	IMG_BOOL *pbValid = abValid;
+
+	if (uiCacheOp == PVRSRV_CACHE_OP_NONE)
+	{
+		PVR_ASSERT(0);
+		return PVRSRV_OK;
+	}
+	else
+	{
+		/* Carry out full dcache operation if size (in pages) qualifies */
+		if (uiSize >= PVR_DIRTY_BYTES_FLUSH_THRESHOLD)
+		{
+			/* Flush, so we can skip subsequent invalidates */
+			eError = OSCPUOperation(PVRSRV_CACHE_OP_FLUSH);
+			if (eError == PVRSRV_OK)
+			{
+				*bUsedGlobalFlush = IMG_TRUE;
+				return PVRSRV_OK;
+			}
+		}
+	}
+
+	/* Need this for kernel mapping */
+	bPMRIsSparse = PMR_IsSparse(psPMR);
+
+	/* Round the incoming offset down to the nearest cache-line / page aligned-address */
+	uiCLAlignedEndOffset = uiOffset + uiSize;
+	uiCLAlignedEndOffset = PVR_ALIGN(uiCLAlignedEndOffset, (IMG_DEVMEM_SIZE_T)guiCacheLineSize);
+	uiCLAlignedStartOffset = (uiOffset & ~((IMG_DEVMEM_OFFSET_T)guiCacheLineSize-1));
+
+	uiPgAlignedEndOffset = uiCLAlignedEndOffset;
+	uiPgAlignedEndOffset = PVR_ALIGN(uiPgAlignedEndOffset, (IMG_DEVMEM_SIZE_T)guiOSPageSize);
+	uiPgAlignedStartOffset = (uiOffset & ~((IMG_DEVMEM_OFFSET_T)guiOSPageSize-1));
+	uiPgAlignedSize = uiPgAlignedEndOffset - uiPgAlignedStartOffset;
+
+#if defined(CACHEOP_NO_CACHE_LINE_ALIGNED_ROUNDING)
+	/* For internal debug if cache-line optimised
+	   flushing is suspected of causing data corruption */
+	uiCLAlignedStartOffset = uiPgAlignedStartOffset;
+	uiCLAlignedEndOffset = uiPgAlignedEndOffset;
+#endif
+
+	/* Which type of address(es) do we need for this CacheOp */
+	uiCacheOpAddrType = OSCPUCacheOpAddressType(uiCacheOp);
+
+	/* Type of allocation backing the PMR data */
+	ui32NumOfPages = uiPgAlignedSize >> OS_PAGE_SHIFT;
+	if (ui32NumOfPages > PMR_MAX_TRANSLATION_STACK_ALLOC)
+	{
+		/* The pbValid array is allocated first as it is needed in
+		   both physical/virtual cache maintenance methods */
+		pbValid = OSAllocZMem(ui32NumOfPages * sizeof(IMG_BOOL));
+		if (pbValid != NULL)
+		{
+			if (uiCacheOpAddrType != PVRSRV_CACHE_OP_ADDR_TYPE_VIRTUAL)
+			{
+				psCpuPhyAddr = OSAllocZMem(ui32NumOfPages * sizeof(IMG_CPU_PHYADDR));
+				if (psCpuPhyAddr == NULL)
+				{
+					psCpuPhyAddr = asCpuPhyAddr;
+					OSFreeMem(pbValid);
+					pbValid = abValid;
+				}
+			}
+		}
+		else
+		{
+			pbValid = abValid;
+		}
+	}
+
+	/* We always retrieve PMR data in bulk, up-front if number of pages is within
+	   PMR_MAX_TRANSLATION_STACK_ALLOC limits else we check to ensure that a 
+	   dynamic buffer has been allocated to satisfy requests outside limits */
+	if (ui32NumOfPages <= PMR_MAX_TRANSLATION_STACK_ALLOC || pbValid != abValid)
+	{
+		if (uiCacheOpAddrType != PVRSRV_CACHE_OP_ADDR_TYPE_VIRTUAL)
+		{
+			/* Look-up PMR CpuPhyAddr once, if possible */
+			eError = PMR_CpuPhysAddr(psPMR,
+									 OS_PAGE_SHIFT,
+									 ui32NumOfPages,
+									 uiPgAlignedStartOffset,
+									 psCpuPhyAddr,
+									 pbValid);
+			if (eError == PVRSRV_OK)
+			{
+				bIsPMRDataRetrieved = IMG_TRUE;
+			}
+		}
+		else
+		{
+			/* Look-up PMR per-page validity once, if possible */
+			eError = PMR_IsOffsetValid(psPMR,
+									   OS_PAGE_SHIFT,
+									   ui32NumOfPages,
+									   uiPgAlignedStartOffset,
+									   pbValid);
+			bIsPMRDataRetrieved = eError == PVRSRV_OK ? IMG_TRUE : IMG_FALSE;
+		}
+	}
+
+	/* For each device page, carry out the requested cache maintenance operation */
+	for (uiPgAlignedOffsetNext = uiPgAlignedStartOffset, ui32PageIndex = 0;
+		 uiPgAlignedOffsetNext < uiPgAlignedEndOffset;
+		 uiPgAlignedOffsetNext += (IMG_DEVMEM_OFFSET_T) guiOSPageSize, ui32PageIndex += 1)
+	{
+		if (bIsPMRDataRetrieved == IMG_FALSE)
+		{
+			/* Never cross page boundary without looking up corresponding
+			   PMR page physical address and/or page validity if these
+			   were not looked-up, in bulk, up-front */	
+			ui32PageIndex = 0;
+			if (uiCacheOpAddrType != PVRSRV_CACHE_OP_ADDR_TYPE_VIRTUAL)
+			{
+				eError = PMR_CpuPhysAddr(psPMR,
+										 OS_PAGE_SHIFT,
+										 1,
+										 uiPgAlignedOffsetNext,
+										 psCpuPhyAddr,
+										 pbValid);
+				if (eError != PVRSRV_OK)
+				{
+					PVR_ASSERT(0);
+					goto e0;
+				}
+			}
+			else
+			{
+				eError = PMR_IsOffsetValid(psPMR,
+										  OS_PAGE_SHIFT,
+										  1,
+										  uiPgAlignedOffsetNext,
+										  pbValid);
+				if (eError != PVRSRV_OK)
+				{
+					PVR_ASSERT(0);
+					goto e0;
+				}
+			}
+		}
+
+		/* Skip invalid PMR pages (i.e. sparse) */
+		if (pbValid[ui32PageIndex] == IMG_FALSE)
+		{
+			continue;
+		}
+
+		/* Skip virtual address acquire if CacheOp can be maintained
+		   entirely using PMR physical addresses */
+		if (uiCacheOpAddrType != PVRSRV_CACHE_OP_ADDR_TYPE_PHYSICAL)
+		{
+			if (bPMRIsSparse)
+			{
+				eError =
+					PMRAcquireSparseKernelMappingData(psPMR,
+													  uiPgAlignedOffsetNext,
+													  guiOSPageSize,
+													  (void **)&pbCpuVirtAddr,
+													  (size_t*)&uiOutSize,
+													  &hPrivOut);
+				if (eError != PVRSRV_OK)
+				{
+					PVR_ASSERT(0);
+					goto e0;
+				}
+			}
+			else
+			{
+				eError =
+					PMRAcquireKernelMappingData(psPMR,
+												uiPgAlignedOffsetNext,
+												guiOSPageSize,
+												(void **)&pbCpuVirtAddr,
+												(size_t*)&uiOutSize,
+												&hPrivOut);
+				if (eError != PVRSRV_OK)
+				{
+					PVR_ASSERT(0);
+					goto e0;
+				}
+			}
+		}
+
+		/* Issue actual cache maintenance for PMR */
+		CacheOpCPURangeBased(PMR_DeviceNode(psPMR),
+							uiCacheOp,
+							pbCpuVirtAddr,
+							(uiCacheOpAddrType != PVRSRV_CACHE_OP_ADDR_TYPE_VIRTUAL) ?
+								psCpuPhyAddr[ui32PageIndex] : psCpuPhyAddr[0],
+							uiPgAlignedOffsetNext,
+							uiCLAlignedStartOffset,
+							uiCLAlignedEndOffset);
+
+		/* Skip virtual address release if CacheOp can be maintained
+		   entirely using PMR physical addresses */
+		if (uiCacheOpAddrType != PVRSRV_CACHE_OP_ADDR_TYPE_PHYSICAL)
+		{
+			eError = PMRReleaseKernelMappingData(psPMR, hPrivOut);
+			PVR_ASSERT(eError == PVRSRV_OK);
+		}
+	}
+
+e0:
+	if (psCpuPhyAddr != asCpuPhyAddr)
+	{
+		OSFreeMem(psCpuPhyAddr);
+	}
+
+	if (pbValid != abValid)
+	{
+		OSFreeMem(pbValid);
+	}
+
+	return eError;
+}
+
+static INLINE IMG_BOOL CacheOpFenceCheck(IMG_UINT32 ui32UpdateSeqNum,
+										 IMG_UINT32 ui32FenceSeqNum)
+{
+	IMG_UINT32 ui32RebasedUpdateNum;
+	IMG_UINT32 ui32RebasedFenceNum;
+	IMG_UINT32 ui32Rebase;
+
+	if (ui32FenceSeqNum == 0)
+	{
+		return IMG_TRUE;
+	}
+
+	/*
+	   The problem statement is how to compare two values
+	   on a numerical sequentially incrementing timeline in
+	   the presence of wrap around arithmetic semantics using
+	   a single ui32 counter & atomic (increment) operations.
+
+	   The rationale for the solution here is to rebase the
+	   incoming values to the sequence midpoint and perform
+	   comparisons there; this allows us to handle overflow
+	   or underflow wrap-round using only a single integer.
+
+	   NOTE: We assume that the absolute value of the 
+	   difference between the two incoming values in _not_ 
+	   greater than CACHEOP_SEQ_MIDPOINT. This assumption
+	   holds as it implies that it is very _unlikely_ that 2
+	   billion CacheOp requests could have been made between
+	   a single client's CacheOp request & the corresponding
+	   fence check. This code sequence is hopefully a _more_
+	   hand optimised (branchless) version of this:
+
+	   	   x = ui32CompletedOpSeqNum
+	   	   y = ui32FenceOpSeqNum
+
+		   if (|x - y| < CACHEOP_SEQ_MIDPOINT)
+			   return (x - y) >= 0 ? true : false
+		   else
+			   return (y - x) >= 0 ? true : false
+	 */
+	ui32Rebase = CACHEOP_SEQ_MIDPOINT - ui32UpdateSeqNum;
+
+	/* ui32Rebase could be either positive/negative, in
+	   any case we still perform operation using unsigned
+	   semantics as 2's complement notation always means
+	   we end up with the correct result */
+	ui32RebasedUpdateNum = ui32Rebase + ui32UpdateSeqNum;
+	ui32RebasedFenceNum = ui32Rebase + ui32FenceSeqNum;
+
+	return (ui32RebasedUpdateNum >= ui32RebasedFenceNum);
+}
+
+#if defined(SUPPORT_RANGEBASED_CACHEFLUSH)
+#if defined(SUPPORT_RANGEBASED_CACHEFLUSH_DEFERRED)
+/* Wait 8hrs when no deferred CacheOp is required;
+   for fence checks, wait 10ms then retry */
+#define CACHEOP_THREAD_WAIT_TIMEOUT 28800000000ULL
+#define CACHEOP_FENCE_WAIT_TIMEOUT  10000ULL
+
+typedef struct _CACHEOP_CLEANUP_WORK_ITEM_
+{
+	PVRSRV_CLEANUP_THREAD_WORK sCleanupWorkItem;
+	DLLIST_NODE *psListNode;
+} CACHEOP_CLEANUP_WORK_ITEM;
+
+/* These are used to track pending CacheOps */
+static IMG_DEVMEM_SIZE_T guiPendingDevmemSize;
+static IMG_BOOL gbPendingTimeline;
+
+static INLINE PVRSRV_ERROR CacheOpFree(void *pvData)
+{
+	CACHEOP_CLEANUP_WORK_ITEM *psCacheOpCleanupItem = pvData;
+	DLLIST_NODE *psListNode = psCacheOpCleanupItem->psListNode;
+	CACHEOP_WORK_ITEM *psCacheOpWorkItem;
+	DLLIST_NODE *psNodeIter;
+
+	while (! dllist_is_empty(psListNode))
+	{
+		psNodeIter = dllist_get_next_node(psListNode);
+		dllist_remove_node(psNodeIter);
+
+		psCacheOpWorkItem = IMG_CONTAINER_OF(psNodeIter, CACHEOP_WORK_ITEM, sNode);
+		if (psCacheOpWorkItem->psPMR)
+		{
+			PMRUnlockSysPhysAddresses(psCacheOpWorkItem->psPMR);
+		}
+
+		OSFreeMem(psCacheOpWorkItem);
+	}
+
+	/* Finally free pseudo head node which is also a valid CacheOp work item */
+	psCacheOpWorkItem = IMG_CONTAINER_OF(psListNode, CACHEOP_WORK_ITEM, sNode);
+	if (psCacheOpWorkItem->psPMR)
+	{
+		PMRUnlockSysPhysAddresses(psCacheOpWorkItem->psPMR);
+	}
+
+	OSFreeMem(psCacheOpWorkItem);
+	OSFreeMem(psCacheOpCleanupItem);
+
+	return PVRSRV_OK;
+}
+
+static INLINE PVRSRV_ERROR CacheOpCleanup(DLLIST_NODE *psListNode)
+{
+	CACHEOP_CLEANUP_WORK_ITEM *psCacheOpCleanupItem;
+	PVRSRV_ERROR eError = PVRSRV_OK;
+
+	psCacheOpCleanupItem = OSAllocMem(sizeof(CACHEOP_CLEANUP_WORK_ITEM));
+	if (! psCacheOpCleanupItem)
+	{
+		PVR_DPF((CACHEOP_DPFL,
+				"%s: performing sync cleanup",
+				__FUNCTION__));
+		eError = CacheOpFree(psListNode);
+	}
+	else
+	{
+		psCacheOpCleanupItem->psListNode = psListNode;
+		psCacheOpCleanupItem->sCleanupWorkItem.ui32RetryCount = 0;
+		psCacheOpCleanupItem->sCleanupWorkItem.pfnFree = CacheOpFree;
+		psCacheOpCleanupItem->sCleanupWorkItem.pvData = psCacheOpCleanupItem;
+		psCacheOpCleanupItem->sCleanupWorkItem.bDependsOnHW = IMG_FALSE;
+		PVRSRVCleanupThreadAddWork(&psCacheOpCleanupItem->sCleanupWorkItem);
+	}
+
+	return eError;
+}
+
+static INLINE PVRSRV_ERROR CacheOpEnqueue(PVRSRV_DATA *psPVRSRVData,
+										CACHEOP_WORK_ITEM *psData,
+										IMG_UINT32 *psSeqNum)
+{
+	OSLockAcquire(psPVRSRVData->hCacheOpThreadWorkListLock);
+
+	/* Queue this CacheOp work item into the pending list, update queue size */
+	dllist_add_to_tail(&psPVRSRVData->sCacheOpThreadWorkList, &psData->sNode);
+	gbPendingTimeline = psData->psTimeline ? IMG_TRUE : gbPendingTimeline;
+	guiPendingDevmemSize += psData->uiSize;
+
+	/* Advance the system-wide CacheOp common sequence value */
+	*psSeqNum = OSAtomicIncrement(&ghCommonCacheOpSeqNum);
+	if (! *psSeqNum)
+	{
+		/* Zero is _not_ a valid sequence value, doing so 
+		   simplifies subsequent fence checking when no
+		   cache maintenance operation is outstanding as
+		   in this case a fence value of zero is supplied */
+		*psSeqNum = OSAtomicIncrement(&ghCommonCacheOpSeqNum);
+	}
+	psData->ui32OpSeqNum = *psSeqNum;
+
+	OSLockRelease(psPVRSRVData->hCacheOpThreadWorkListLock);
+
+	return PVRSRV_OK;
+}
+
+static INLINE DLLIST_NODE *CacheOpDequeue(PVRSRV_DATA *psPVRSRVData,
+										  IMG_UINT64 *uiQueueDevmemSize,
+										  IMG_BOOL   *bHasTimeline)
+{
+	DLLIST_NODE *psListNode = NULL;
+
+	OSLockAcquire(psPVRSRVData->hCacheOpThreadWorkListLock);
+
+	if (! dllist_is_empty(&psPVRSRVData->sCacheOpThreadWorkList))
+	{
+		/* Replace entire pending list with a (re)initialized list */
+		psListNode = psPVRSRVData->sCacheOpThreadWorkList.psNextNode;
+		dllist_remove_node(&psPVRSRVData->sCacheOpThreadWorkList);
+		dllist_init(&psPVRSRVData->sCacheOpThreadWorkList);
+
+		/* These capture information about this dequeued list */
+		*uiQueueDevmemSize = (IMG_UINT64) guiPendingDevmemSize;
+		guiPendingDevmemSize = (IMG_DEVMEM_SIZE_T) 0;
+		*bHasTimeline = gbPendingTimeline;
+		gbPendingTimeline = IMG_FALSE;
+	}
+
+	OSLockRelease(psPVRSRVData->hCacheOpThreadWorkListLock);
+
+	return psListNode;
+}
+
+static PVRSRV_ERROR CacheOpExecGlobal(PVRSRV_DATA *psPVRSRVData,
+										DLLIST_NODE *psListNode)
+{
+	PVRSRV_ERROR eError;
+	IMG_UINT32 ui32CacheOpSeqNum;
+	CACHEOP_WORK_ITEM *psCacheOpWorkItem;
+	DLLIST_NODE *psCurrentNode, *psNextNode;
+#if defined(CACHEOP_DEBUG)
+	IMG_UINT64 uiTimeNow;
+#endif
+
+	eError = OSCPUOperation(PVRSRV_CACHE_OP_FLUSH);
+	if (eError != PVRSRV_OK)
+	{
+		return eError;
+	}
+
+#if defined(CACHEOP_DEBUG)
+	uiTimeNow = OSClockns64();
+#endif
+
+	/* The head node is a _valid_ CacheOp work item so process it first */
+	psCacheOpWorkItem = IMG_CONTAINER_OF(psListNode, CACHEOP_WORK_ITEM, sNode);
+#if defined(CACHEOP_DEBUG)
+	psCacheOpWorkItem->ui64ExecuteTime = uiTimeNow;
+	psCacheOpWorkItem->bRBF = IMG_FALSE;
+	psCacheOpWorkItem->bUMF = IMG_FALSE;
+#endif
+
+	/* Process other queue CacheOp work items if present */
+	dllist_foreach_node (psListNode, psCurrentNode, psNextNode)
+	{
+		psCacheOpWorkItem = IMG_CONTAINER_OF(psCurrentNode, CACHEOP_WORK_ITEM, sNode);
+#if defined(CACHEOP_DEBUG)
+		psCacheOpWorkItem->ui64ExecuteTime = uiTimeNow;
+		psCacheOpWorkItem->bRBF = IMG_FALSE;
+		psCacheOpWorkItem->bUMF = IMG_FALSE;
+#endif
+	}
+
+	/* Last CacheOp item updates ghCompletedCacheOpSeqNum */
+	ui32CacheOpSeqNum = psCacheOpWorkItem->ui32OpSeqNum;
+	OSAtomicWrite(&ghCompletedCacheOpSeqNum, ui32CacheOpSeqNum);
+
+	/* Signal any waiting threads blocked on CacheOp fence checks;
+	   update completed sequence number to last queue work item */
+	eError = OSEventObjectSignal(psPVRSRVData->hCacheOpUpdateEventObject);
+	PVR_LOG_IF_ERROR(eError, "OSEventObjectSignal");
+
+	return eError;
+}
+
+static PVRSRV_ERROR CacheOpExecRangeBased(PVRSRV_DATA *psPVRSRVData,
+										  DLLIST_NODE *psListNode)
+{
+	PVRSRV_ERROR eError = PVRSRV_OK;
+	CACHEOP_WORK_ITEM *psCacheOpWorkItem;
+	DLLIST_NODE *psNodeIter = psListNode;
+	IMG_BOOL bSkipRemainingCacheOps = IMG_FALSE;
+#if defined(CACHEOP_DEBUG)
+	CACHEOP_WORK_ITEM *psPrevWorkItem = NULL;
+#endif
+
+	do
+	{
+		/* Lookup corresponding work item & perform cache maintenance operation if
+		   it is a non-timeline work-item (i.e. pmr is null) else notify timeline */
+		psCacheOpWorkItem = IMG_CONTAINER_OF(psNodeIter, CACHEOP_WORK_ITEM, sNode);
+		if (psCacheOpWorkItem->psPMR != NULL)
+		{
+			if (bSkipRemainingCacheOps == IMG_FALSE)
+			{
+				eError = CacheOpRangeBased(psCacheOpWorkItem->psPMR,
+										   psCacheOpWorkItem->uiOffset,
+										   psCacheOpWorkItem->uiSize,
+										   psCacheOpWorkItem->uiCacheOp,
+										   &bSkipRemainingCacheOps);
+				if (eError != PVRSRV_OK)
+				{
+					/* This _should_ not fail but if it does, not much
+					   we can do about it; for now we log it but still
+					   increment the completed CacheOp seq number */
+					PVR_DPF((CACHEOP_DPFL, 
+							 "CacheOp failed: PMR:%p Offset:%llx Size:%llx CacheOp:%d",
+							 psCacheOpWorkItem->psPMR,
+							 psCacheOpWorkItem->uiOffset,
+							 psCacheOpWorkItem->uiSize,
+							 psCacheOpWorkItem->uiCacheOp));
+					PVR_ASSERT(0);
+				}
+			}
+
+#if defined(CACHEOP_DEBUG)
+			psCacheOpWorkItem->ui64ExecuteTime = bSkipRemainingCacheOps ?
+				(psPrevWorkItem ? psPrevWorkItem->ui64ExecuteTime : OSClockns64()) : OSClockns64();
+			psCacheOpWorkItem->bRBF = !bSkipRemainingCacheOps;
+			psCacheOpWorkItem->bUMF = IMG_FALSE;
+			psPrevWorkItem = psCacheOpWorkItem;
+#endif
+
+			/* Currently executed CacheOp item updates ghCompletedCacheOpSeqNum */
+			OSAtomicWrite(&ghCompletedCacheOpSeqNum, psCacheOpWorkItem->ui32OpSeqNum);
+
+			if (psCacheOpWorkItem->bSignalEventObject == IMG_TRUE)
+			{
+				/* It is possible that multiple CacheOp work items from two or more
+				   threads might be present within processed queue so we have to
+				   signal when these CacheOps are  processed to unblock waiting threads */
+				eError = OSEventObjectSignal(psPVRSRVData->hCacheOpUpdateEventObject);
+				PVR_LOG_IF_ERROR(eError, "OSEventObjectSignal");
+			}
+		}
+		else
+		{
+			PVR_ASSERT(psCacheOpWorkItem->psTimeline != NULL);
+
+			OSAtomicWrite(&ghCompletedCacheOpSeqNum, psCacheOpWorkItem->ui32OpSeqNum);
+
+#if defined(SUPPORT_NATIVE_FENCE_SYNC) && defined(CONFIG_SW_SYNC)
+			sw_sync_timeline_inc(psCacheOpWorkItem->psTimeline->private_data, 1);
+			fput(psCacheOpWorkItem->psTimeline);
+#endif
+
+#if defined(CACHEOP_DEBUG)
+			psCacheOpWorkItem->ui64ExecuteTime = OSClockns64();
+#endif
+		}
+
+		/* This terminates on NULL or 1 item queue */
+		psNodeIter = dllist_get_next_node(psNodeIter);
+	} while (psNodeIter && psNodeIter != psListNode);
+
+	return eError;
+}
+
+static void CacheOpExecQueuedList(PVRSRV_DATA *psPVRSRVData)
+{
+	PVRSRV_ERROR eError;
+	DLLIST_NODE *psListNode;
+	IMG_BOOL bUseGlobalCachOp;
+	IMG_BOOL bHasTimeline = IMG_FALSE;
+	IMG_UINT64 ui64Size = (IMG_UINT64) 0;
+	IMG_UINT64 ui64FlushThreshold = PVR_DIRTY_BYTES_FLUSH_THRESHOLD;
+
+	/* Obtain the current queue of pending CacheOps, this also provides
+	   information pertaining to the queue such as if one or more 
+	   CacheOps in the queue is a timeline request and the total
+	   CacheOp size */
+	psListNode = CacheOpDequeue(psPVRSRVData, &ui64Size, &bHasTimeline);
+	if (psListNode == NULL)
+	{
+		/* This should _not_ happen but if it does, wake-up waiting threads */
+		eError = OSEventObjectSignal(psPVRSRVData->hCacheOpUpdateEventObject);
+		PVR_LOG_IF_ERROR(eError, "OSEventObjectSignal");
+		return;
+	}
+
+	/* Perform a global cache operation if queue size (in pages)
+	   qualifies and there is no work item in the queue which is a
+	   timeline request */
+	bUseGlobalCachOp = ui64Size >= ui64FlushThreshold;
+	if (bUseGlobalCachOp == IMG_TRUE && bHasTimeline == IMG_FALSE)
+	{
+		eError = CacheOpExecGlobal(psPVRSRVData, psListNode);
+		if (eError == PVRSRV_OK)
+		{
+			goto e0;
+		}
+	}
+
+	/* Else use range-based cache maintenance per queue item */
+	eError = CacheOpExecRangeBased(psPVRSRVData, psListNode);
+
+e0:
+#if defined(CACHEOP_DEBUG)
+	eError = CacheOpStatExecLog(psListNode);
+#endif
+
+	/* Once done, defer CacheOp cleanup */
+	eError = CacheOpCleanup(psListNode);
+}
+
+static void CacheOpThread(void *pvData)
+{
+	PVRSRV_DATA *psPVRSRVData = pvData;
+	IMG_HANDLE  hOSEvent;
+	PVRSRV_ERROR eError;
+
+	PVR_DPF((CACHEOP_DPFL, "%s: thread starting...", __FUNCTION__));
+
+	/* Store the process id (pid) of the CacheOp-up thread */
+	psPVRSRVData->CacheOpThreadPid = OSGetCurrentProcessID();
+
+	/* Open CacheOp thread event object, abort driver if event object open fails */
+	eError = OSEventObjectOpen(psPVRSRVData->hCacheOpThreadEventObject, &hOSEvent);
+	PVR_ASSERT(eError == PVRSRV_OK);
+
+	/* While driver is in good state and not being unloaded, perform pending cache maintenance */
+	while ((psPVRSRVData->eServicesState == PVRSRV_SERVICES_STATE_OK) && (!psPVRSRVData->bUnload))
+	{
+		/* Wait here until when signalled for queued (pending) CacheOp work items */
+		eError = OSEventObjectWaitTimeout(hOSEvent, CACHEOP_THREAD_WAIT_TIMEOUT);
+		if (eError == PVRSRV_ERROR_TIMEOUT)
+		{
+			PVR_DPF((CACHEOP_DPFL, "%s: wait timeout", __FUNCTION__));
+		}
+		else if (eError == PVRSRV_OK)
+		{
+			PVR_DPF((CACHEOP_DPFL, "%s: wait OK, signal received", __FUNCTION__));
+		}
+		else
+		{
+			PVR_DPF((PVR_DBG_ERROR, "%s: wait error %d", __FUNCTION__, eError));
+		}
+
+		CacheOpExecQueuedList(psPVRSRVData);
+	}
+
+	eError = OSEventObjectClose(hOSEvent);
+	PVR_LOG_IF_ERROR(eError, "OSEventObjectClose");
+
+	PVR_DPF((CACHEOP_DPFL, "%s: thread terminating...", __FUNCTION__));
+}
+
+static PVRSRV_ERROR CacheOpExecQueue (PMR **ppsPMR,
+									  IMG_DEVMEM_OFFSET_T *puiOffset,
+									  IMG_DEVMEM_SIZE_T *puiSize,
+									  PVRSRV_CACHE_OP *puiCacheOp,
+									  IMG_UINT32 ui32NumCacheOps,
+									  IMG_UINT32 *pui32OpSeqNum)
+{
+	IMG_UINT32 ui32Idx;
+	PVRSRV_ERROR eError = PVRSRV_OK;
+	PVRSRV_DATA *psPVRSRVData = PVRSRVGetPVRSRVData();
+
+	if (psPVRSRVData->bUnload)
+	{
+		PVR_DPF((CACHEOP_DPFL, 
+				"%s: driver unloading, performing CacheOp synchronously",
+				__FUNCTION__));
+
+		for (ui32Idx = 0; ui32Idx < ui32NumCacheOps; ui32Idx++)
+		{
+			(void)CacheOpExec(ppsPMR[ui32Idx],
+							  puiOffset[ui32Idx],
+							  puiSize[ui32Idx],
+							  puiCacheOp[ui32Idx]);
+		}
+
+		/* No CacheOp fence dependencies */
+		*pui32OpSeqNum = 0;
+	}
+	else
+	{
+		IMG_DEVMEM_SIZE_T uiLogicalSize;
+		CACHEOP_WORK_ITEM *psCacheOpWorkItem = NULL;
+
+		for (ui32Idx = 0; ui32Idx < ui32NumCacheOps; ui32Idx++)
+		{
+			/* As PVRSRV_CACHE_OP_INVALIDATE is used to transfer
+			   device memory buffer ownership back to processor
+			   we cannot defer it so must action it immediately */
+			if (puiCacheOp[ui32Idx] & PVRSRV_CACHE_OP_INVALIDATE)
+			{
+				eError = CacheOpExec (ppsPMR[ui32Idx],
+									  puiOffset[ui32Idx],
+									  puiSize[ui32Idx],
+									  puiCacheOp[ui32Idx]);
+				if (eError != PVRSRV_OK)
+				{
+					PVR_DPF((CACHEOP_DPFL,
+							"%s: PVRSRV_CACHE_OP_INVALIDATE failed (%u)",
+							__FUNCTION__, eError));
+				}
+
+				/* Clear CacheOp fence dependencies if single entry; in a
+				   multiple entry batch, preserve fence dependency update */
+				*pui32OpSeqNum = (ui32Idx == 0) ? 0 : *pui32OpSeqNum;
+				continue;
+			}
+
+			/* Ensure request is valid before deferring to CacheOp thread */
+			eError = PMR_LogicalSize(ppsPMR[ui32Idx], &uiLogicalSize);
+			if (eError != PVRSRV_OK)
+			{
+				PVR_DPF((CACHEOP_DPFL,
+						"%s: PMR_LogicalSize failed (%u), cannot defer CacheOp",
+						__FUNCTION__, eError));
+
+				/* Signal the CacheOp thread to ensure queued items get processed */
+				(void) OSEventObjectSignal(psPVRSRVData->hCacheOpThreadEventObject);
+				PVR_LOG_IF_ERROR(eError, "OSEventObjectSignal");
+
+				return eError;
+			}
+			else if ((puiOffset[ui32Idx]+puiSize[ui32Idx]) > uiLogicalSize)
+			{
+				PVR_DPF((CACHEOP_DPFL,
+						"%s: Invalid parameters, cannot defer CacheOp",
+						__FUNCTION__));
+
+				/* Signal the CacheOp thread to ensure queued items get processed */
+				(void) OSEventObjectSignal(psPVRSRVData->hCacheOpThreadEventObject);
+				PVR_LOG_IF_ERROR(eError, "OSEventObjectSignal");
+
+				return PVRSRV_ERROR_INVALID_PARAMS;;
+			}
+
+			/* For now use dynamic alloc, static CCB _might_ be faster */
+			psCacheOpWorkItem = OSAllocMem(sizeof(CACHEOP_WORK_ITEM));
+			if (psCacheOpWorkItem == NULL)
+			{
+				PVR_DPF((CACHEOP_DPFL, "%s: OSAllocMem failed (%u)",
+						__FUNCTION__, eError));
+
+				/* Signal the CacheOp thread to ensure whatever was enqueued thus
+				   far (if any) gets processed even though we fail the request */
+				eError = OSEventObjectSignal(psPVRSRVData->hCacheOpThreadEventObject);
+				PVR_LOG_IF_ERROR(eError, "OSEventObjectSignal");
+
+				return PVRSRV_ERROR_OUT_OF_MEMORY;
+			}
+
+			/* For safety, take reference here in user context; to speed
+			   up deferred cache management we drop reference as late as
+			   possible (during cleanup) */
+			eError = PMRLockSysPhysAddresses(ppsPMR[ui32Idx]);
+			if (eError != PVRSRV_OK)
+			{
+				PVR_DPF((CACHEOP_DPFL, "%s: PMRLockSysPhysAddresses failed (%u)",
+						__FUNCTION__, eError));
+
+				OSFreeMem(psCacheOpWorkItem);
+				psCacheOpWorkItem = NULL;
+
+				/* Signal the CacheOp thread to ensure whatever was enqueued thus
+				   far (if any) gets processed even though we fail the request */
+				eError = OSEventObjectSignal(psPVRSRVData->hCacheOpThreadEventObject);
+				PVR_LOG_IF_ERROR(eError, "OSEventObjectSignal");
+
+				return eError;
+			}
+
+			/* Prepare & enqueue CacheOp work item */
+#if defined(CACHEOP_DEBUG)
+			psCacheOpWorkItem->pid = OSGetCurrentClientProcessIDKM();
+			psCacheOpWorkItem->ui64QueuedTime = OSClockns64();
+#endif
+			psCacheOpWorkItem->bSignalEventObject = IMG_FALSE;
+			psCacheOpWorkItem->uiCacheOp = puiCacheOp[ui32Idx];
+			psCacheOpWorkItem->uiOffset = puiOffset[ui32Idx];
+			psCacheOpWorkItem->uiSize = puiSize[ui32Idx];
+			psCacheOpWorkItem->psPMR = ppsPMR[ui32Idx];
+			psCacheOpWorkItem->psTimeline = NULL;
+
+			if (ui32Idx == (ui32NumCacheOps - 1))
+			{
+				/* The idea here is to track the last CacheOp in a
+				   batch queue so that we only wake-up stalled threads
+				   waiting on fence checks when such CacheOp has been
+				   processed; this serves to reduce spurious thread
+				   wake-up */
+				psCacheOpWorkItem->bSignalEventObject = IMG_TRUE;
+			}
+
+			eError = CacheOpEnqueue(psPVRSRVData, psCacheOpWorkItem, pui32OpSeqNum);
+			PVR_LOG_IF_ERROR(eError, "CacheOpEnqueue");
+		}
+
+		if (psCacheOpWorkItem != NULL)
+		{
+			/* Signal the CacheOp thread to ensure this item gets processed */
+			eError = OSEventObjectSignal(psPVRSRVData->hCacheOpThreadEventObject);
+			PVR_LOG_IF_ERROR(eError, "OSEventObjectSignal");
+		}
+	}
+
+	return eError;
+}
+#else /* defined(SUPPORT_RANGEBASED_CACHEFLUSH_DEFERRED) */
+static PVRSRV_ERROR CacheOpExecQueue(PMR **ppsPMR,
+									IMG_DEVMEM_OFFSET_T *puiOffset,
+									IMG_DEVMEM_SIZE_T *puiSize,
+									PVRSRV_CACHE_OP *puiCacheOp,
+									IMG_UINT32 ui32NumCacheOps,
+									IMG_UINT32 *pui32OpSeqNum)
+{
+	IMG_UINT32 ui32Idx;
+	PVRSRV_ERROR eError = PVRSRV_OK;
+
+	for (ui32Idx = 0; ui32Idx < ui32NumCacheOps; ui32Idx++)
+	{
+		PVRSRV_ERROR eError2 = CacheOpExec(ppsPMR[ui32Idx],
+										   puiOffset[ui32Idx],
+										   puiSize[ui32Idx],
+										   puiCacheOp[ui32Idx]);
+		if (eError2 != PVRSRV_OK)
+		{
+			eError = eError2;
+			PVR_DPF((CACHEOP_DPFL,
+					"%s: CacheOpExec failed (%u)",
+					__FUNCTION__, eError));
+		}
+	}
+
+	/* For immediate RBF, common/completed are identical */
+	*pui32OpSeqNum = OSAtomicRead(&ghCommonCacheOpSeqNum);
+	OSAtomicWrite(&ghCompletedCacheOpSeqNum, *pui32OpSeqNum);
+
+	return eError;
+}
+#endif
+
+PVRSRV_ERROR CacheOpQueue (IMG_UINT32 ui32NumCacheOps,
+						   PMR **ppsPMR,
+						   IMG_DEVMEM_OFFSET_T *puiOffset,
+						   IMG_DEVMEM_SIZE_T *puiSize,
+						   PVRSRV_CACHE_OP *puiCacheOp,
+						   IMG_UINT32 *pui32OpSeqNum)
+{
+	return CacheOpExecQueue(ppsPMR,
+							puiOffset,
+							puiSize,
+							puiCacheOp,
+							ui32NumCacheOps,
+							pui32OpSeqNum);
+}
+
+PVRSRV_ERROR CacheOpFence (RGXFWIF_DM eFenceOpType,
+						   IMG_UINT32 ui32FenceOpSeqNum)
+{
+	PVRSRV_ERROR eError = PVRSRV_OK;
+	IMG_UINT32 ui32CompletedOpSeqNum;
+	IMG_BOOL b1stCacheOpFenceCheckPass;
+#if defined(CACHEOP_DEBUG)
+	CACHEOP_WORK_ITEM sCacheOpWorkItem;
+	IMG_UINT64 uiTimeNow = OSClockns64();
+	IMG_UINT32 ui32RetryCount = 0;
+
+	dllist_init(&sCacheOpWorkItem.sNode);
+
+	/* No PMR/timeline for fence CacheOp */
+	sCacheOpWorkItem.psPMR = NULL;
+	sCacheOpWorkItem.psTimeline = NULL;
+	sCacheOpWorkItem.ui64QueuedTime = uiTimeNow;
+	sCacheOpWorkItem.ui32OpSeqNum = ui32FenceOpSeqNum;
+	sCacheOpWorkItem.pid = OSGetCurrentClientProcessIDKM();
+#if defined(PVR_RI_DEBUG)
+	sCacheOpWorkItem.eFenceOpType = eFenceOpType;
+#endif
+#endif
+
+	PVR_UNREFERENCED_PARAMETER(eFenceOpType);
+
+	ui32CompletedOpSeqNum = OSAtomicRead(&ghCompletedCacheOpSeqNum);
+	b1stCacheOpFenceCheckPass = CacheOpFenceCheck(ui32CompletedOpSeqNum, ui32FenceOpSeqNum);
+
+#if defined(SUPPORT_RANGEBASED_CACHEFLUSH_DEFERRED)
+	/* If initial fence check fails, then wait-and-retry in loop */
+	if (b1stCacheOpFenceCheckPass == IMG_FALSE)
+	{
+		IMG_HANDLE hOSEvent;
+		PVRSRV_DATA *psPVRSRVData = PVRSRVGetPVRSRVData();
+
+		/* Open CacheOp update event object, if event object open fails return error */
+		eError = OSEventObjectOpen(psPVRSRVData->hCacheOpUpdateEventObject, &hOSEvent);
+		if (eError != PVRSRV_OK)
+		{
+			PVR_DPF((CACHEOP_DPFL,
+					"%s: failed to open update event object",
+					__FUNCTION__));
+			goto e0;
+		}
+
+		/* (Re)read completed cache op sequence number before wait */
+		ui32CompletedOpSeqNum = OSAtomicRead(&ghCompletedCacheOpSeqNum);
+
+		/* Check if the CacheOp dependencies for this thread are met */
+		eError = CacheOpFenceCheck(ui32CompletedOpSeqNum, ui32FenceOpSeqNum) ?
+				PVRSRV_OK : PVRSRV_ERROR_FAILED_DEPENDENCIES;
+
+		while (eError != PVRSRV_OK)
+		{
+			/* Wait here until signalled that update has occurred by CacheOp thread */
+			eError = OSEventObjectWaitTimeout(hOSEvent, CACHEOP_FENCE_WAIT_TIMEOUT);
+			if (eError == PVRSRV_ERROR_TIMEOUT)
+			{
+				PVR_DPF((CACHEOP_DPFL, "%s: wait timeout", __FUNCTION__));
+#if defined(CACHEOP_DEBUG)
+				/* This is a more accurate notion of fence check retries */
+				ui32RetryCount += 1;
+#endif
+			}
+			else if (eError == PVRSRV_OK)
+			{
+				PVR_DPF((CACHEOP_DPFL, "%s: wait OK, signal received", __FUNCTION__));
+			}
+			else
+			{
+				PVR_DPF((PVR_DBG_ERROR, "%s: wait error %d", __FUNCTION__, eError));
+			}
+
+			/* (Re)read latest completed CacheOp sequence number to fence */
+			ui32CompletedOpSeqNum = OSAtomicRead(&ghCompletedCacheOpSeqNum);
+
+			/* Check if the CacheOp dependencies for this thread are met */
+			eError = CacheOpFenceCheck(ui32CompletedOpSeqNum, ui32FenceOpSeqNum) ?
+								PVRSRV_OK : PVRSRV_ERROR_FAILED_DEPENDENCIES;
+		}
+
+#if defined(CACHEOP_DEBUG)
+		uiTimeNow = OSClockns64();
+#endif
+
+		eError = OSEventObjectClose(hOSEvent);
+		PVR_LOG_IF_ERROR(eError, "OSEventObjectClose");
+	}
+
+e0:
+#if defined(CACHEOP_DEBUG)
+	if (b1stCacheOpFenceCheckPass == IMG_FALSE)
+	{
+		/* This log gives an indication of how badly deferred
+		   cache maintenance is doing and provides data for
+		   possible dynamic spawning of multiple CacheOpThreads;
+		   currently not implemented in the framework but such
+		   an extension would require a monitoring thread to
+		   scan the gasCacheOpStatStalled table and spawn/kill a 
+		   new CacheOpThread if certain conditions are met */
+		CacheOpStatStallLogWrite(ui32FenceOpSeqNum,
+								 sCacheOpWorkItem.ui64QueuedTime,
+								 uiTimeNow,
+								 ui32RetryCount);
+	}
+#endif
+#else /* defined(SUPPORT_RANGEBASED_CACHEFLUSH_DEFERRED) */
+#if defined(CACHEOP_DEBUG)
+	PVR_UNREFERENCED_PARAMETER(ui32RetryCount);
+#endif
+	/* Fence checks _cannot_ fail in immediate RBF */
+	PVR_UNREFERENCED_PARAMETER(b1stCacheOpFenceCheckPass);
+	PVR_ASSERT(b1stCacheOpFenceCheckPass == IMG_TRUE);
+#endif
+
+#if defined(CACHEOP_DEBUG)
+	sCacheOpWorkItem.ui64ExecuteTime = uiTimeNow;
+	sCacheOpWorkItem.uiCacheOp = PVRSRV_CACHE_OP_NONE;
+	eError = CacheOpStatExecLog(&sCacheOpWorkItem.sNode);
+#endif
+
+	return eError;
+}
+
+PVRSRV_ERROR CacheOpSetTimeline (IMG_INT32 i32Timeline)
+{
+	PVRSRV_ERROR eError;
+
+#if defined(SUPPORT_RANGEBASED_CACHEFLUSH_DEFERRED)
+	PVRSRV_DATA *psPVRSRVData = PVRSRVGetPVRSRVData();
+	CACHEOP_WORK_ITEM *psCacheOpWorkItem;
+	IMG_UINT32 ui32OpSeqNum;
+
+	if (i32Timeline < 0)
+	{
+		return PVRSRV_OK;
+	}
+
+	psCacheOpWorkItem = OSAllocMem(sizeof(CACHEOP_WORK_ITEM));
+	if (psCacheOpWorkItem == NULL)
+	{
+		return PVRSRV_ERROR_OUT_OF_MEMORY;
+	}
+
+	/* Prepare & enqueue a timeline CacheOp work item */
+	psCacheOpWorkItem->psPMR = NULL;
+#if defined(CACHEOP_DEBUG)
+	psCacheOpWorkItem->ui64QueuedTime = OSClockns64();
+	psCacheOpWorkItem->pid = OSGetCurrentClientProcessIDKM();
+#endif
+
+#if defined(SUPPORT_NATIVE_FENCE_SYNC) && defined(CONFIG_SW_SYNC)
+	psCacheOpWorkItem->psTimeline = fget(i32Timeline);
+	if (!psCacheOpWorkItem->psTimeline || 
+		!psCacheOpWorkItem->psTimeline->private_data)
+	{
+		OSFreeMem(psCacheOpWorkItem);
+		return PVRSRV_ERROR_INVALID_PARAMS;
+	}
+
+	/* Enqueue timeline work-item, notifies timeline FD when executed */
+	eError = CacheOpEnqueue(psPVRSRVData, psCacheOpWorkItem, &ui32OpSeqNum);
+	PVR_LOG_IF_ERROR(eError, "CacheOpEnqueue");
+
+	/* Signal the CacheOp thread to ensure this item gets processed */
+	eError = OSEventObjectSignal(psPVRSRVData->hCacheOpThreadEventObject);
+	PVR_LOG_IF_ERROR(eError, "OSEventObjectSignal");
+#else
+	PVR_UNREFERENCED_PARAMETER(psPVRSRVData);
+	PVR_UNREFERENCED_PARAMETER(ui32OpSeqNum);
+	eError = PVRSRV_ERROR_NOT_SUPPORTED;
+	PVR_ASSERT(0);
+#endif
+#else /* defined(SUPPORT_RANGEBASED_CACHEFLUSH_DEFERRED) */
+	struct file *psFile;
+
+	if (i32Timeline < 0)
+	{
+		return PVRSRV_OK;
+	}
+
+#if defined(SUPPORT_NATIVE_FENCE_SYNC) && defined(CONFIG_SW_SYNC)
+	psFile = fget(i32Timeline);
+	if (!psFile || !psFile->private_data)
+	{
+		return PVRSRV_ERROR_INVALID_PARAMS;
+	}
+
+	sw_sync_timeline_inc(psFile->private_data, 1);
+	fput(psFile);
+
+	eError = PVRSRV_OK;
+#else
+	PVR_UNREFERENCED_PARAMETER(psFile);
+	eError = PVRSRV_ERROR_NOT_SUPPORTED;
+	PVR_ASSERT(0);
+#endif
+#endif
+
+	return eError;
+}
+#else /* defined(SUPPORT_RANGEBASED_CACHEFLUSH) */
+PVRSRV_ERROR CacheOpQueue (IMG_UINT32 ui32NumCacheOps,
+						   PMR **ppsPMR,
+						   IMG_DEVMEM_OFFSET_T *puiOffset,
+						   IMG_DEVMEM_SIZE_T *puiSize,
+						   PVRSRV_CACHE_OP *puiCacheOp,
+						   IMG_UINT32 *pui32OpSeqNum)
+{
+	IMG_UINT32 ui32Idx;
+	PVRSRV_ERROR eError = PVRSRV_OK;
+	IMG_BOOL bHasInvalidate = IMG_FALSE;
+	PVRSRV_DATA *psPVRSRVData = PVRSRVGetPVRSRVData();
+	PVRSRV_CACHE_OP uiCacheOp = PVRSRV_CACHE_OP_NONE;
+#if	defined(CACHEOP_DEBUG)
+	CACHEOP_WORK_ITEM sCacheOpWorkItem;
+	dllist_init(&sCacheOpWorkItem.sNode);
+
+	sCacheOpWorkItem.psPMR = ppsPMR[0];
+	sCacheOpWorkItem.bRBF = IMG_FALSE;
+	sCacheOpWorkItem.bUMF = IMG_FALSE;
+	sCacheOpWorkItem.psTimeline = NULL;
+	sCacheOpWorkItem.uiOffset = puiOffset[0];
+	sCacheOpWorkItem.ui64QueuedTime = (IMG_UINT64)0;
+	sCacheOpWorkItem.ui64ExecuteTime = (IMG_UINT64)0;
+	sCacheOpWorkItem.uiSize = (IMG_DEVMEM_OFFSET_T)0;
+	sCacheOpWorkItem.pid = OSGetCurrentClientProcessIDKM();
+#endif
+
+	/* Coalesce all requests into a single superset request */
+	for (ui32Idx = 0; ui32Idx < ui32NumCacheOps; ui32Idx++)
+	{
+		uiCacheOp = SetCacheOp(uiCacheOp, puiCacheOp[ui32Idx]);
+		if (puiCacheOp[ui32Idx] & PVRSRV_CACHE_OP_INVALIDATE)
+		{
+			/* Cannot be deferred, action now */
+			bHasInvalidate = IMG_TRUE;
+#if	!defined(CACHEOP_DEBUG)
+			break;
+#endif
+		}
+#if	defined(CACHEOP_DEBUG)
+		/* For debug, we _want_ to know how many items are in batch */
+		sCacheOpWorkItem.uiSize += puiSize[ui32Idx];
+		*pui32OpSeqNum = OSAtomicIncrement(&ghCommonCacheOpSeqNum);
+		*pui32OpSeqNum = !*pui32OpSeqNum ?
+			OSAtomicIncrement(&ghCommonCacheOpSeqNum) : *pui32OpSeqNum;
+#endif
+	}
+
+#if	!defined(CACHEOP_DEBUG)
+	/* For release, we don't care, so use per-batch sequencing */
+	*pui32OpSeqNum = OSAtomicIncrement(&ghCommonCacheOpSeqNum);
+	*pui32OpSeqNum = !*pui32OpSeqNum ?
+			OSAtomicIncrement(&ghCommonCacheOpSeqNum) : *pui32OpSeqNum;
+#endif
+
+	if (bHasInvalidate == IMG_TRUE)
+	{
+		psPVRSRVData->uiCacheOp = PVRSRV_CACHE_OP_NONE;
+
+#if	defined(CACHEOP_DEBUG)
+		sCacheOpWorkItem.ui64QueuedTime = OSClockns64();
+#endif
+
+		/* Perform global cache maintenance operation */
+		eError = OSCPUOperation(PVRSRV_CACHE_OP_FLUSH);
+		if (eError != PVRSRV_OK)
+		{
+			PVR_DPF((PVR_DBG_ERROR, "%s: OSCPUOperation failed (%u)",
+					__FUNCTION__, eError));
+			goto e0;
+		}
+
+#if	defined(CACHEOP_DEBUG)
+		sCacheOpWorkItem.ui64ExecuteTime = OSClockns64();
+#endif
+
+		/* Having completed the invalidate, note sequence number */
+		OSAtomicWrite(&ghCompletedCacheOpSeqNum, *pui32OpSeqNum);
+	}
+	else
+	{
+		/* NOTE: Possible race condition, CacheOp value set here using SetCacheOp()
+		   might be over-written during read-modify-write sequence in CacheOpFence() */
+		psPVRSRVData->uiCacheOp = SetCacheOp(psPVRSRVData->uiCacheOp, uiCacheOp);
+	}
+
+#if	defined(CACHEOP_DEBUG)
+	sCacheOpWorkItem.uiCacheOp = uiCacheOp;
+	sCacheOpWorkItem.ui32OpSeqNum = *pui32OpSeqNum;
+	eError = CacheOpStatExecLog(&sCacheOpWorkItem.sNode);
+#endif
+
+e0:
+	return eError;
+}
+
+PVRSRV_ERROR CacheOpFence (RGXFWIF_DM eFenceOpType,
+						   IMG_UINT32 ui32FenceOpSeqNum)
+{
+	PVRSRV_ERROR eError = PVRSRV_OK;
+	PVRSRV_DATA *psPVRSRVData = PVRSRVGetPVRSRVData();
+	IMG_BOOL b1stCacheOpFenceCheckPass;
+	IMG_UINT32 ui32CacheOpSeqNum;
+	PVRSRV_CACHE_OP uiCacheOp;
+#if defined(CACHEOP_DEBUG)
+	CACHEOP_WORK_ITEM sCacheOpWorkItem;
+	sCacheOpWorkItem.ui64QueuedTime = (IMG_UINT64)0;
+	sCacheOpWorkItem.ui64ExecuteTime = (IMG_UINT64)0;
+	sCacheOpWorkItem.uiCacheOp = PVRSRV_CACHE_OP_NONE;
+#endif
+
+	ui32CacheOpSeqNum = OSAtomicRead(&ghCompletedCacheOpSeqNum);
+	b1stCacheOpFenceCheckPass = CacheOpFenceCheck(ui32CacheOpSeqNum, ui32FenceOpSeqNum);
+
+	/* Flush if there is pending CacheOp that affects this fence */
+	if (b1stCacheOpFenceCheckPass == IMG_FALSE)
+	{
+		/* After global CacheOp, requests before this sequence are met */
+		ui32CacheOpSeqNum = OSAtomicIncrement(&ghCommonCacheOpSeqNum);
+		ui32CacheOpSeqNum = !ui32CacheOpSeqNum ?
+				OSAtomicIncrement(&ghCommonCacheOpSeqNum) : ui32CacheOpSeqNum;
+
+		uiCacheOp = psPVRSRVData->uiCacheOp;
+		psPVRSRVData->uiCacheOp = PVRSRV_CACHE_OP_NONE;
+
+#if	defined(CACHEOP_DEBUG)
+		sCacheOpWorkItem.ui64QueuedTime = OSClockns64();
+#endif
+
+		/* Perform global cache maintenance operation */
+		eError = OSCPUOperation(uiCacheOp);
+		if (eError != PVRSRV_OK)
+		{
+			PVR_DPF((PVR_DBG_ERROR, "%s: OSCPUOperation failed (%u)",
+					__FUNCTION__, eError));
+			goto e0;
+		}
+
+#if	defined(CACHEOP_DEBUG)
+		sCacheOpWorkItem.ui64ExecuteTime = OSClockns64();
+		sCacheOpWorkItem.uiCacheOp = uiCacheOp;
+#endif
+
+		/* Having completed global CacheOp, note sequence number */
+		OSAtomicWrite(&ghCompletedCacheOpSeqNum, ui32CacheOpSeqNum);
+	}
+
+#if defined(CACHEOP_DEBUG)
+	dllist_init(&sCacheOpWorkItem.sNode);
+
+	sCacheOpWorkItem.psPMR = NULL;
+	sCacheOpWorkItem.psTimeline = NULL;
+	sCacheOpWorkItem.ui32OpSeqNum = ui32FenceOpSeqNum;
+	sCacheOpWorkItem.pid = OSGetCurrentClientProcessIDKM();
+#if defined(PVR_RI_DEBUG)
+	sCacheOpWorkItem.eFenceOpType = eFenceOpType;
+#endif
+
+	eError = CacheOpStatExecLog(&sCacheOpWorkItem.sNode);
+#endif
+
+e0:
+	return eError;
+}
+
+PVRSRV_ERROR CacheOpSetTimeline (IMG_INT32 i32Timeline)
+{
+	PVRSRV_ERROR eError;
+	struct file *psFile;
+	PVRSRV_CACHE_OP uiCacheOp;
+	PVRSRV_DATA *psPVRSRVData;
+
+	if (i32Timeline < 0)
+	{
+		return PVRSRV_OK;
+	}
+
+#if defined(SUPPORT_NATIVE_FENCE_SYNC) && defined(CONFIG_SW_SYNC)
+	psFile = fget(i32Timeline);
+	if (!psFile || !psFile->private_data)
+	{
+		return PVRSRV_ERROR_INVALID_PARAMS;
+	}
+
+	psPVRSRVData = PVRSRVGetPVRSRVData();
+	uiCacheOp = psPVRSRVData->uiCacheOp;
+	psPVRSRVData->uiCacheOp = PVRSRV_CACHE_OP_NONE;
+
+	/* Perform global cache maintenance operation */
+	eError = OSCPUOperation(uiCacheOp);
+	if (eError != PVRSRV_OK)
+	{
+		PVR_DPF((PVR_DBG_ERROR, "%s: OSCPUOperation failed (%u)",
+				__FUNCTION__, eError));
+		goto e0;
+	}
+
+	sw_sync_timeline_inc(psFile->private_data, 1);
+	fput(psFile);
+e0:
+#else
+	PVR_UNREFERENCED_PARAMETER(psFile);
+	PVR_UNREFERENCED_PARAMETER(uiCacheOp);
+	PVR_UNREFERENCED_PARAMETER(psPVRSRVData);
+	eError = PVRSRV_ERROR_NOT_SUPPORTED;
+	PVR_ASSERT(0);
+#endif
+
+	return eError;
+}
+#endif /* defined(SUPPORT_RANGEBASED_CACHEFLUSH) */
+
+PVRSRV_ERROR CacheOpExec (PMR *psPMR,
+						  IMG_DEVMEM_OFFSET_T uiOffset,
+						  IMG_DEVMEM_SIZE_T uiSize,
+						  PVRSRV_CACHE_OP uiCacheOp)
+{
+	PVRSRV_ERROR eError;
+	IMG_DEVMEM_SIZE_T uiLogicalSize;
+	IMG_BOOL bUsedGlobalFlush = IMG_FALSE;
+#if	defined(CACHEOP_DEBUG)
+	/* This interface is always synchronous and not deferred;
+	   during debug build, use work-item to capture debug logs */
+	CACHEOP_WORK_ITEM sCacheOpWorkItem;
+	dllist_init(&sCacheOpWorkItem.sNode);
+
+	sCacheOpWorkItem.psPMR = psPMR;
+	sCacheOpWorkItem.uiSize = uiSize;
+	sCacheOpWorkItem.psTimeline = NULL;
+	sCacheOpWorkItem.uiOffset = uiOffset;
+	sCacheOpWorkItem.uiCacheOp = uiCacheOp;
+	sCacheOpWorkItem.ui64QueuedTime = OSClockns64();
+	sCacheOpWorkItem.pid = OSGetCurrentClientProcessIDKM();
+	sCacheOpWorkItem.ui32OpSeqNum = OSAtomicIncrement(&ghCommonCacheOpSeqNum);
+	sCacheOpWorkItem.ui32OpSeqNum = !sCacheOpWorkItem.ui32OpSeqNum ?
+		OSAtomicIncrement(&ghCommonCacheOpSeqNum) : sCacheOpWorkItem.ui32OpSeqNum;
+#endif
+
+	eError = PMR_LogicalSize(psPMR, &uiLogicalSize);
+	if (eError != PVRSRV_OK)
+	{
+		PVR_DPF((CACHEOP_DPFL,
+				"%s: PMR_LogicalSize failed (%u)",
+				__FUNCTION__, eError));
+		goto e0;
+	}
+	else if ((uiOffset+uiSize) > uiLogicalSize)
+	{
+		PVR_DPF((CACHEOP_DPFL,
+				"%s: Invalid parameters",
+				__FUNCTION__));
+		eError = PVRSRV_ERROR_INVALID_PARAMS;
+		goto e0;
+	}
+
+	/* Perform range-based cache maintenance operation */
+	eError = PMRLockSysPhysAddresses(psPMR);
+	if (eError != PVRSRV_OK)
+	{
+		PVR_DPF((CACHEOP_DPFL,
+				"%s: PMRLockSysPhysAddresses failed (%u)",
+				__FUNCTION__, eError));
+		goto e0;
+	}
+
+	eError = CacheOpRangeBased(psPMR, uiOffset, uiSize, uiCacheOp, &bUsedGlobalFlush);
+#if	defined(CACHEOP_DEBUG)
+	sCacheOpWorkItem.bUMF = IMG_FALSE;
+	sCacheOpWorkItem.bRBF = !bUsedGlobalFlush;
+	sCacheOpWorkItem.ui64ExecuteTime = OSClockns64();
+	eError = CacheOpStatExecLog(&sCacheOpWorkItem.sNode);
+#endif
+
+	PMRUnlockSysPhysAddresses(psPMR);
+e0:
+	return eError;
+}
+
+PVRSRV_ERROR CacheOpLog (PMR *psPMR,
+						 IMG_DEVMEM_OFFSET_T uiOffset,
+						 IMG_DEVMEM_SIZE_T uiSize,
+						 IMG_UINT64 ui64QueuedTimeUs,
+						 IMG_UINT64 ui64ExecuteTimeUs,
+						 PVRSRV_CACHE_OP uiCacheOp)
+{
+#if defined(CACHEOP_DEBUG)
+	CACHEOP_WORK_ITEM sCacheOpWorkItem;
+	dllist_init(&sCacheOpWorkItem.sNode);
+
+	sCacheOpWorkItem.psPMR = psPMR;
+	sCacheOpWorkItem.uiSize = uiSize;
+	sCacheOpWorkItem.psTimeline = NULL;
+	sCacheOpWorkItem.uiOffset = uiOffset;
+	sCacheOpWorkItem.uiCacheOp = uiCacheOp;
+	sCacheOpWorkItem.pid = OSGetCurrentClientProcessIDKM();
+	sCacheOpWorkItem.ui32OpSeqNum = OSAtomicIncrement(&ghCommonCacheOpSeqNum);
+	sCacheOpWorkItem.ui32OpSeqNum = !sCacheOpWorkItem.ui32OpSeqNum ?
+		OSAtomicIncrement(&ghCommonCacheOpSeqNum) : sCacheOpWorkItem.ui32OpSeqNum;
+
+	/* All UM cache maintenance is range-based */
+	sCacheOpWorkItem.ui64ExecuteTime = ui64ExecuteTimeUs;
+	sCacheOpWorkItem.ui64QueuedTime = ui64QueuedTimeUs;
+	sCacheOpWorkItem.bUMF = IMG_TRUE;
+	sCacheOpWorkItem.bRBF = IMG_TRUE;
+
+	CacheOpStatExecLogWrite(&sCacheOpWorkItem.sNode);
+#else /* defined(CACHEOP_DEBUG) */
+	PVR_UNREFERENCED_PARAMETER(psPMR);
+	PVR_UNREFERENCED_PARAMETER(uiSize);
+	PVR_UNREFERENCED_PARAMETER(uiOffset);
+	PVR_UNREFERENCED_PARAMETER(ui64QueuedTimeUs);
+	PVR_UNREFERENCED_PARAMETER(ui64ExecuteTimeUs);
+	PVR_UNREFERENCED_PARAMETER(uiCacheOp);
+#endif
+	return PVRSRV_OK;
+}
+
+PVRSRV_ERROR CacheOpGetLineSize (IMG_UINT32 *pui32L1DataCacheLineSize)
+{
+	*pui32L1DataCacheLineSize = guiCacheLineSize;
+	PVR_ASSERT(guiCacheLineSize != 0);
+	return PVRSRV_OK;
+}
+
+PVRSRV_ERROR CacheOpInit (void)
+{
+	PVRSRV_ERROR eError;
+	PVRSRV_DATA *psPVRSRVData;
+
+	/* DDK initialisation is anticipated to be performed on the boot
+	   processor (little core in big/little systems) though this may
+	   not always be the case. If so, the value cached here is the 
+	   system wide safe (i.e. smallest) L1 d-cache line size value 
+	   on platforms with mismatched d-cache line sizes */
+	guiCacheLineSize = OSCPUCacheAttributeSize(PVR_DCACHE_LINE_SIZE);
+	PVR_ASSERT(guiCacheLineSize != 0);
+
+	guiOSPageSize = OSGetPageSize();
+	PVR_ASSERT(guiOSPageSize != 0);
+
+	OSAtomicWrite(&ghCommonCacheOpSeqNum, 0);
+	OSAtomicWrite(&ghCompletedCacheOpSeqNum, 0);
+
+#if defined(SUPPORT_RANGEBASED_CACHEFLUSH_DEFERRED)
+	psPVRSRVData = PVRSRVGetPVRSRVData();
+
+	/* Create an event object for pending CacheOp work items */
+	eError = OSEventObjectCreate("PVRSRV_CACHEOP_EVENTOBJECT", &psPVRSRVData->hCacheOpThreadEventObject);
+	PVR_ASSERT(eError == PVRSRV_OK);
+
+	/* Create an event object for updating pending fence checks on CacheOp */
+	eError = OSEventObjectCreate("PVRSRV_CACHEOP_EVENTOBJECT", &psPVRSRVData->hCacheOpUpdateEventObject);
+	PVR_ASSERT(eError == PVRSRV_OK);
+
+	/* Create a lock to police list of pending CacheOp work items */
+	eError = OSLockCreate((POS_LOCK*)&psPVRSRVData->hCacheOpThreadWorkListLock, LOCK_TYPE_PASSIVE);
+	PVR_ASSERT(eError == PVRSRV_OK);
+
+	/* Initialise pending CacheOp list & seq number */
+	dllist_init(&psPVRSRVData->sCacheOpThreadWorkList);
+	guiPendingDevmemSize = (IMG_DEVMEM_SIZE_T) 0;
+	gbPendingTimeline = IMG_FALSE;
+
+#if defined(CACHEOP_DEBUG)
+	gi32CacheOpStatExecWriteIdx = 0;
+	gi32CacheOpStatStallWriteIdx = 0;
+
+	OSCachedMemSet(gasCacheOpStatExecuted, 0, sizeof(gasCacheOpStatExecuted));
+	OSCachedMemSet(gasCacheOpStatStalled, 0, sizeof(gasCacheOpStatStalled));
+
+	eError = OSLockCreate((POS_LOCK*)&ghCacheOpStatExecLock, LOCK_TYPE_PASSIVE);
+	PVR_ASSERT(eError == PVRSRV_OK);
+
+	eError = OSLockCreate((POS_LOCK*)&ghCacheOpStatStallLock, LOCK_TYPE_PASSIVE);
+	PVR_ASSERT(eError == PVRSRV_OK);
+
+	pvCacheOpStatExecEntry = OSCreateStatisticEntry("cache_ops_exec",
+												NULL,
+												CacheOpStatExecLogRead,
+												NULL,
+												NULL,
+												NULL);
+	PVR_ASSERT(pvCacheOpStatExecEntry != NULL);
+
+	pvCacheOpStatStallEntry = OSCreateStatisticEntry("cache_ops_stall",
+												NULL,
+												CacheOpStatStallLogRead,
+												NULL,
+												NULL,
+												NULL);
+	PVR_ASSERT(pvCacheOpStatStallEntry != NULL);
+#endif
+
+	/* Create a thread which is used to do the deferred CacheOp */
+	eError = OSThreadCreatePriority(&psPVRSRVData->hCacheOpThread,
+							"pvr_cache_ops",
+							CacheOpThread, 
+							psPVRSRVData,
+							OS_THREAD_HIGHEST_PRIORITY);
+	if (eError != PVRSRV_OK)
+	{
+		PVR_DPF((PVR_DBG_ERROR,"CacheOpInit: failed to create CacheOp thread"));
+		return CacheOpDeInit();
+	}
+#else /* defined(SUPPORT_RANGEBASED_CACHEFLUSH_DEFERRED) */
+	PVR_UNREFERENCED_PARAMETER(psPVRSRVData);
+#if defined(CACHEOP_DEBUG)
+	gi32CacheOpStatExecWriteIdx = 0;
+
+	OSCachedMemSet(gasCacheOpStatExecuted, 0, sizeof(gasCacheOpStatExecuted));
+
+	eError = OSLockCreate((POS_LOCK*)&ghCacheOpStatExecLock, LOCK_TYPE_PASSIVE);
+	PVR_ASSERT(eError == PVRSRV_OK);
+
+	pvCacheOpStatExecEntry = OSCreateStatisticEntry("cache_ops_exec",
+												NULL,
+												CacheOpStatExecLogRead,
+												NULL,
+												NULL,
+												NULL);
+	PVR_ASSERT(pvCacheOpStatExecEntry != NULL);
+#endif
+	eError = PVRSRV_OK;
+#endif
+
+	return eError;
+}
+
+PVRSRV_ERROR CacheOpDeInit (void)
+{
+	PVRSRV_ERROR eError = PVRSRV_OK;
+	PVRSRV_DATA *psPVRSRVData;
+
+#if defined(SUPPORT_RANGEBASED_CACHEFLUSH_DEFERRED)
+	psPVRSRVData = PVRSRVGetPVRSRVData();
+
+#if defined(CACHEOP_DEBUG)
+	OSLockDestroy(ghCacheOpStatExecLock);
+	OSRemoveStatisticEntry(pvCacheOpStatExecEntry);
+	OSRemoveStatisticEntry(pvCacheOpStatStallEntry);
+#endif
+
+	if (psPVRSRVData->hCacheOpThread)
+	{
+		if (psPVRSRVData->hCacheOpThreadEventObject)
+		{
+			eError = OSEventObjectSignal(psPVRSRVData->hCacheOpThreadEventObject);
+			PVR_LOG_IF_ERROR(eError, "OSEventObjectSignal");
+		}
+
+		if (psPVRSRVData->hCacheOpUpdateEventObject)
+		{
+			eError = OSEventObjectSignal(psPVRSRVData->hCacheOpUpdateEventObject);
+			PVR_LOG_IF_ERROR(eError, "OSEventObjectSignal");
+		}
+
+		LOOP_UNTIL_TIMEOUT(OS_THREAD_DESTROY_TIMEOUT_US)
+		{
+			eError = OSThreadDestroy(psPVRSRVData->hCacheOpThread);
+			if (PVRSRV_OK == eError)
+			{
+				psPVRSRVData->hCacheOpThread = NULL;
+				break;
+			}
+			OSWaitus(OS_THREAD_DESTROY_TIMEOUT_US/OS_THREAD_DESTROY_RETRY_COUNT);
+		} END_LOOP_UNTIL_TIMEOUT();
+		PVR_LOG_IF_ERROR(eError, "OSThreadDestroy");
+	}
+
+	OSLockDestroy(psPVRSRVData->hCacheOpThreadWorkListLock);
+	psPVRSRVData->hCacheOpThreadWorkListLock = NULL;
+
+	if (psPVRSRVData->hCacheOpUpdateEventObject)
+	{
+		eError = OSEventObjectDestroy(psPVRSRVData->hCacheOpUpdateEventObject);
+		PVR_LOG_IF_ERROR(eError, "OSEventObjectDestroy");
+		psPVRSRVData->hCacheOpUpdateEventObject = NULL;
+	}
+
+	if (psPVRSRVData->hCacheOpThreadEventObject)
+	{
+		eError = OSEventObjectDestroy(psPVRSRVData->hCacheOpThreadEventObject);
+		PVR_LOG_IF_ERROR(eError, "OSEventObjectDestroy");
+		psPVRSRVData->hCacheOpThreadEventObject = NULL;
+	}
+
+	eError = PVRSRV_OK;
+#else /* defined(SUPPORT_RANGEBASED_CACHEFLUSH_DEFERRED) */
+	PVR_UNREFERENCED_PARAMETER(psPVRSRVData);
+#if defined(CACHEOP_DEBUG)
+	OSLockDestroy(ghCacheOpStatExecLock);
+	OSRemoveStatisticEntry(pvCacheOpStatExecEntry);
+#endif
+	eError = PVRSRV_OK;
+#endif
+
+	return eError;
+}
diff --git a/drivers/staging/imgtec/rogue/cache_km.h b/drivers/staging/imgtec/rogue/cache_km.h
new file mode 100644
index 0000000..a06af5e
--- /dev/null
+++ b/drivers/staging/imgtec/rogue/cache_km.h
@@ -0,0 +1,146 @@
+/*************************************************************************/ /*!
+@File           cache.h
+@Title          CPU cache management header
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#ifndef _CACHE_KM_H_
+#define _CACHE_KM_H_
+
+#if defined(LINUX)
+#include <linux/version.h>
+#endif
+
+#include "pvrsrv_error.h"
+#include "img_types.h"
+#include "cache_ops.h"
+#include "device.h"
+#include "pmr.h"
+
+typedef IMG_UINT32 PVRSRV_CACHE_OP_ADDR_TYPE;	/*!< Type represents address required for cache op. */
+#define PVRSRV_CACHE_OP_ADDR_TYPE_VIRTUAL	0x1	/*!< Operation requires virtual address only */
+#define PVRSRV_CACHE_OP_ADDR_TYPE_PHYSICAL	0x2	/*!< Operation requires physical address only */
+#define PVRSRV_CACHE_OP_ADDR_TYPE_BOTH		0x3	/*!< Operation requires both virtual & physical addresses */
+
+#define CACHEFLUSH_KM_RANGEBASED_DEFERRED	0x1	/*!< Services KM using deferred (i.e asynchronous) range-based flush */
+#define CACHEFLUSH_KM_RANGEBASED			0x2	/*!< Services KM using immediate (i.e synchronous) range-based flush */
+#define CACHEFLUSH_KM_GLOBAL				0x3	/*!< Services KM using global flush */
+#ifndef CACHEFLUSH_KM_TYPE						/*!< Type represents cache maintenance operation method */
+	#if defined(__x86__)
+		/* Default for x86/x86_64 is global */
+		#define CACHEFLUSH_KM_TYPE CACHEFLUSH_KM_GLOBAL
+	#elif defined(__aarch64__)
+		#if defined(LINUX) && (LINUX_VERSION_CODE >= KERNEL_VERSION(4,2,0))
+			/* Default here is range-based (i.e. no linux global flush) */
+			#define CACHEFLUSH_KM_TYPE CACHEFLUSH_KM_RANGEBASED
+		#else
+			/* Default here is global (i.e. OS supports global flush) */
+			#define CACHEFLUSH_KM_TYPE CACHEFLUSH_KM_GLOBAL
+		#endif
+	#else
+		/* Default for other architecture is range-based */
+		#define CACHEFLUSH_KM_TYPE CACHEFLUSH_KM_RANGEBASED
+	#endif
+#else
+	#if (CACHEFLUSH_KM_TYPE == CACHEFLUSH_KM_GLOBAL)
+		#if defined(__mips__) 
+			/* Architecture does not support global cache maintenance */
+			#error "CACHEFLUSH_KM_GLOBAL is not supported on architecture"
+		#elif defined(__aarch64__)
+			#if defined(LINUX) && (LINUX_VERSION_CODE >= KERNEL_VERSION(4,2,0))
+				/* Linux revisions does not support global cache maintenance */
+				#error "CACHEFLUSH_KM_GLOBAL is not supported on Linux v4.2 onwards"
+			#endif
+		#endif
+	#endif
+#endif
+
+/*
+	If we get multiple cache operations before the operation which will
+	trigger the operation to happen then we need to make sure we do
+	the right thing. Used for global cache maintenance
+*/
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(SetCacheOp)
+#endif
+static INLINE PVRSRV_CACHE_OP SetCacheOp(PVRSRV_CACHE_OP uiCurrent, PVRSRV_CACHE_OP uiNew)
+{
+	PVRSRV_CACHE_OP uiRet;
+	uiRet = uiCurrent | uiNew;
+	return uiRet;
+}
+
+/*
+	Cache maintenance framework API
+*/
+PVRSRV_ERROR CacheOpInit(void);
+PVRSRV_ERROR CacheOpDeInit(void);
+
+/* This interface is always guaranteed to be synchronous */
+PVRSRV_ERROR CacheOpExec (PMR *psPMR,
+						IMG_DEVMEM_OFFSET_T uiOffset,
+						IMG_DEVMEM_SIZE_T uiSize,
+						PVRSRV_CACHE_OP uiCacheOp);
+
+/* This interface _may_ defer cache-ops (i.e. asynchronous) */
+PVRSRV_ERROR CacheOpQueue (IMG_UINT32 ui32OpCount,
+						PMR **ppsPMR,
+						IMG_DEVMEM_OFFSET_T *puiOffset,
+						IMG_DEVMEM_SIZE_T *puiSize,
+						PVRSRV_CACHE_OP *puiCacheOp,
+						IMG_UINT32 *pui32OpSeqNum);
+
+/* This interface is used to log user-mode cache-ops */
+PVRSRV_ERROR CacheOpLog (PMR *psPMR,
+						IMG_DEVMEM_OFFSET_T uiOffset,
+						IMG_DEVMEM_SIZE_T uiSize,
+						IMG_UINT64 ui64QueuedTimeMs,
+						IMG_UINT64 ui64ExecuteTimeMs,
+						PVRSRV_CACHE_OP uiCacheOp);
+
+/* This interface must be used to fence for pending cache-ops before kicks */
+PVRSRV_ERROR CacheOpFence (RGXFWIF_DM eOpType, IMG_UINT32 ui32OpSeqNum);
+
+/* This interface is used for notification of completed cache-ops */
+PVRSRV_ERROR CacheOpSetTimeline (IMG_INT32 i32OpTimeline);
+
+/* This interface is used for retrieving the processor d-cache line size */
+PVRSRV_ERROR CacheOpGetLineSize (IMG_UINT32 *pui32L1DataCacheLineSize);
+#endif	/* _CACHE_KM_H_ */
+
diff --git a/drivers/staging/imgtec/rogue/cache_external.h b/drivers/staging/imgtec/rogue/cache_ops.h
similarity index 67%
rename from drivers/staging/imgtec/rogue/cache_external.h
rename to drivers/staging/imgtec/rogue/cache_ops.h
index 134845b..95ca76c 100644
--- a/drivers/staging/imgtec/rogue/cache_external.h
+++ b/drivers/staging/imgtec/rogue/cache_ops.h
@@ -42,40 +42,29 @@
 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */ /**************************************************************************/
 
-#ifndef _CACHE_EXTERNAL_H_
-#define _CACHE_EXTERNAL_H_
+#ifndef _CACHE_OPS_H_
+#define _CACHE_OPS_H_
 #include "img_types.h"
 
-typedef IMG_UINT32 PVRSRV_CACHE_OP;
+typedef IMG_UINT32 PVRSRV_CACHE_OP;				/*!< Type represents cache maintenance operation */
+#define PVRSRV_CACHE_OP_NONE				0x0	/*!< No operation */
+#define PVRSRV_CACHE_OP_CLEAN				0x1	/*!< Flush w/o invalidate */
+#define PVRSRV_CACHE_OP_INVALIDATE			0x2	/*!< Invalidate w/o flush */
+#define PVRSRV_CACHE_OP_FLUSH				0x3	/*!< Flush w/ invalidate */
 
-#define PVRSRV_CACHE_OP_NONE		0x0			/*!< No operation */
-#define PVRSRV_CACHE_OP_CLEAN		0x1			/*!< Flush w/o invalidate */
-#define PVRSRV_CACHE_OP_INVALIDATE	0x2			/*!< Invalidate w/o flush */
-#define PVRSRV_CACHE_OP_FLUSH		0x3			/*!< Flush w/ invalidate */
-
-typedef IMG_UINT32 PVRSRV_CACHE_OP_ADDR_TYPE;
-
-#define PVRSRV_CACHE_OP_ADDR_TYPE_VIRTUAL	0x1	/*!< Operation requires virtual address only */
-#define PVRSRV_CACHE_OP_ADDR_TYPE_PHYSICAL	0x2	/*!< Operation requires physical address only */
-#define PVRSRV_CACHE_OP_ADDR_TYPE_BOTH		0x3	/*!< Operation requires both virtual & physical addresses */
-
-/*
-	If we get multiple cache operations before the operation which will
-	trigger the operation to happen then we need to make sure we do
-	the right thing.
-
-	Note: PVRSRV_CACHE_OP_INVALIDATE should never be passed into here
-*/
-#ifdef INLINE_IS_PRAGMA
-#pragma inline(SetCacheOp)
+#define CACHEFLUSH_UM_X86					0x1	/*!< Intel x86/x64 specific UM range-based cache flush */
+#define CACHEFLUSH_UM_ARM64					0x2	/*!< ARM Aarch64 specific UM range-based cache flush */
+#define CACHEFLUSH_UM_GENERIC				0x3	/*!< Generic UM/KM cache flush (i.e. CACHEFLUSH_KM_TYPE) */
+#define CACHEFLUSH_UM_X86_ONLY				0x4	/*!< Force x86/x64 UM flush exclusively */
+#define CACHEFLUSH_UM_ARM64_ONLY			0x5	/*!< Force ARM Aarch64 UM flush exclusively */
+#ifndef CACHEFLUSH_UM_TYPE
+	#if defined(__i386__) || defined(__x86_64__)
+		#define CACHEFLUSH_UM_TYPE CACHEFLUSH_UM_X86
+	#elif defined(__aarch64__)
+		#define CACHEFLUSH_UM_TYPE CACHEFLUSH_UM_ARM64
+	#else
+		#define CACHEFLUSH_UM_TYPE CACHEFLUSH_UM_GENERIC
+	#endif
 #endif
-static INLINE PVRSRV_CACHE_OP SetCacheOp(PVRSRV_CACHE_OP uiCurrent,
-										 PVRSRV_CACHE_OP uiNew)
-{
-	PVRSRV_CACHE_OP uiRet;
 
-	uiRet = uiCurrent | uiNew;
-	return uiRet;
-}
-
-#endif	/* _CACHE_EXTERNAL_H_ */
+#endif	/* _CACHE_OPS_H_ */
diff --git a/drivers/staging/imgtec/rogue/connection_server.c b/drivers/staging/imgtec/rogue/connection_server.c
index ec0dab4..9bc8e9b 100644
--- a/drivers/staging/imgtec/rogue/connection_server.c
+++ b/drivers/staging/imgtec/rogue/connection_server.c
@@ -52,6 +52,8 @@
 #include "process_stats.h"
 #include "pdump_km.h"
 #include "lists.h"
+#include "osfunc.h"
+#include "tlstream.h"
 
 /* PID associated with Connection currently being purged by Cleanup thread */
 static IMG_PID gCurrentPurgeConnectionPid = 0;
@@ -59,6 +61,19 @@
 static PVRSRV_ERROR ConnectionDataDestroy(CONNECTION_DATA *psConnection)
 {
 	PVRSRV_ERROR eError;
+	PROCESS_HANDLE_BASE *psProcessHandleBase;
+	IMG_UINT64 ui64MaxBridgeTime;
+	PVRSRV_DATA *psPVRSRVData = PVRSRVGetPVRSRVData();
+
+	if(psPVRSRVData->bUnload)
+	{
+		/* driver is unloading so do not allow the bridge lock to be released */
+		ui64MaxBridgeTime = 0;
+	}
+	else
+	{
+		ui64MaxBridgeTime = CONNECTION_DEFERRED_CLEANUP_TIMESLICE_NS;
+	}
 
 	if (psConnection == NULL)
 	{
@@ -76,25 +91,60 @@
 	}
 #endif
 
+	/* Close HWPerfClient stream here even though we created it in
+	 * PVRSRVConnectKM(). */
+	if (psConnection->hClientTLStream)
+	{
+		TLStreamClose(psConnection->hClientTLStream);
+		psConnection->hClientTLStream = NULL;
+		PVR_DPF((PVR_DBG_MESSAGE, "Destroyed private stream."));
+	}
+
+	/* Get process handle base to decrement the refcount */
+	psProcessHandleBase = psConnection->psProcessHandleBase;
+
+	if (psProcessHandleBase != NULL)
+	{
+		/* In case the refcount becomes 0 we can remove the process handle base */
+		if (OSAtomicDecrement(&psProcessHandleBase->iRefCount) == 0)
+		{
+			uintptr_t uiHashValue;
+
+			OSLockAcquire(psPVRSRVData->hProcessHandleBase_Lock);
+			uiHashValue = HASH_Remove(psPVRSRVData->psProcessHandleBase_Table, psConnection->pid);
+			OSLockRelease(psPVRSRVData->hProcessHandleBase_Lock);
+
+			if (!uiHashValue)
+			{
+				PVR_DPF((PVR_DBG_ERROR,
+						"%s: Failed to remove handle base from hash table.",
+						__func__));
+				return PVRSRV_ERROR_UNABLE_TO_REMOVE_HASH_VALUE;
+			}
+
+			eError = PVRSRVFreeHandleBase(psProcessHandleBase->psHandleBase, ui64MaxBridgeTime);
+			if (eError != PVRSRV_OK)
+			{
+				if (eError != PVRSRV_ERROR_RETRY)
+				{
+					PVR_DPF((PVR_DBG_ERROR,
+						 "ConnectionDataDestroy: Couldn't free handle base for process (%d)",
+						 eError));
+				}
+
+				return eError;
+			}
+
+			OSFreeMem(psProcessHandleBase);
+		}
+
+		psConnection->psProcessHandleBase = NULL;
+	}
+
 	/* Free handle base for this connection */
 	if (psConnection->psHandleBase != NULL)
 	{
-		PVRSRV_DATA *psPVRSRVData = PVRSRVGetPVRSRVData();
-		IMG_UINT64 ui64MaxBridgeTime;
-
-		if(psPVRSRVData->bUnload)
-		{
-			/* driver is unloading so do not allow the bridge lock to be released */
-			ui64MaxBridgeTime = 0;
-		}
-		else
-		{
-			ui64MaxBridgeTime = CONNECTION_DEFERRED_CLEANUP_TIMESLICE_NS;
-		}
-
-		PMRLock();
 		eError = PVRSRVFreeHandleBase(psConnection->psHandleBase, ui64MaxBridgeTime);
-		PMRUnlock();
 		if (eError != PVRSRV_OK)
 		{
 			if (eError != PVRSRV_ERROR_RETRY)
@@ -147,6 +197,8 @@
 {
 	CONNECTION_DATA *psConnection;
 	PVRSRV_ERROR eError;
+	PROCESS_HANDLE_BASE *psProcessHandleBase;
+	PVRSRV_DATA *psPVRSRVData = PVRSRVGetPVRSRVData();
 
 	/* Allocate connection data area */
 	psConnection = OSAllocZMem(sizeof(*psConnection));
@@ -192,7 +244,8 @@
 	}
 
 	/* Allocate handle base for this connection */
-	eError = PVRSRVAllocHandleBase(&psConnection->psHandleBase);
+	eError = PVRSRVAllocHandleBase(&psConnection->psHandleBase,
+	                               PVRSRV_HANDLE_BASE_TYPE_CONNECTION);
 	if (eError != PVRSRV_OK)
 	{
 		PVR_DPF((PVR_DBG_ERROR,
@@ -201,6 +254,57 @@
 		goto failure;
 	}
 
+	/* Try to get process handle base if it already exists */
+	OSLockAcquire(psPVRSRVData->hProcessHandleBase_Lock);
+	psProcessHandleBase = (PROCESS_HANDLE_BASE*) HASH_Retrieve(PVRSRVGetPVRSRVData()->psProcessHandleBase_Table,
+	                                                           psConnection->pid);
+
+	/* In case there is none we are going to allocate one */
+	if (psProcessHandleBase == NULL)
+	{
+		psProcessHandleBase = OSAllocZMem(sizeof(PROCESS_HANDLE_BASE));
+		if (psProcessHandleBase == NULL)
+		{
+			PVR_DPF((PVR_DBG_ERROR,
+					"%s: Failed to allocate handle base, oom.",
+					__func__));
+			eError = PVRSRV_ERROR_OUT_OF_MEMORY;
+			goto failureLock;
+		}
+
+		/* Allocate handle base for this process */
+		eError = PVRSRVAllocHandleBase(&psProcessHandleBase->psHandleBase,
+		                               PVRSRV_HANDLE_BASE_TYPE_PROCESS);
+		if (eError != PVRSRV_OK)
+		{
+			PVR_DPF((PVR_DBG_ERROR,
+			         "%s: Couldn't allocate handle base for process (%d)",
+			         __func__,
+			         eError));
+			OSFreeMem(psProcessHandleBase);
+			goto failureLock;
+		}
+
+		/* Insert the handle base into the global hash table */
+		if (!HASH_Insert(PVRSRVGetPVRSRVData()->psProcessHandleBase_Table,
+		                 psConnection->pid,
+		                 (uintptr_t) psProcessHandleBase))
+		{
+
+			eError = PVRSRV_ERROR_UNABLE_TO_INSERT_HASH_VALUE;
+
+			PVRSRVFreeHandleBase(psProcessHandleBase->psHandleBase, 0);
+
+			OSFreeMem(psProcessHandleBase);
+			goto failureLock;
+		}
+	}
+	OSLockRelease(psPVRSRVData->hProcessHandleBase_Lock);
+
+	psConnection->psProcessHandleBase = psProcessHandleBase;
+
+	OSAtomicIncrement(&psProcessHandleBase->iRefCount);
+
 	/* Allocate process statistics */
 #if defined(PVRSRV_ENABLE_PROCESS_STATS) && !defined(PVRSRV_DEBUG_LINUX_MEMORY_STATS)
 	eError = PVRSRVStatsRegisterProcess(&psConnection->hProcessStats);
@@ -217,6 +321,8 @@
 
 	return eError;
 
+failureLock:
+	OSLockRelease(psPVRSRVData->hProcessHandleBase_Lock);
 failure:
 	ConnectionDataDestroy(psConnection);
 
@@ -275,22 +381,17 @@
 	{
 		PDumpDisconnectionNotify();
 	}
-
-	/* Defer the release of the connection data */
-	psConnectionData->sCleanupThreadFn.pfnFree = _CleanupThreadPurgeConnectionData;
-	psConnectionData->sCleanupThreadFn.pvData = psConnectionData;
-	psConnectionData->sCleanupThreadFn.ui32RetryCount = CLEANUP_THREAD_RETRY_COUNT_DEFAULT;
-	PVRSRVCleanupThreadAddWork(&psConnectionData->sCleanupThreadFn);
-}
-
-PVRSRV_ERROR PVRSRVConnectionInit(void)
-{
-	return PVRSRV_OK;
-}
-
-PVRSRV_ERROR PVRSRVConnectionDeInit(void)
-{
-	return PVRSRV_OK;
+#if defined(PVRSRV_FORCE_UNLOAD_IF_BAD_STATE)
+	if (PVRSRVGetPVRSRVData()->eServicesState == PVRSRV_SERVICES_STATE_OK)
+#endif
+	{
+		/* Defer the release of the connection data */
+		psConnectionData->sCleanupThreadFn.pfnFree = _CleanupThreadPurgeConnectionData;
+		psConnectionData->sCleanupThreadFn.pvData = psConnectionData;
+		psConnectionData->sCleanupThreadFn.ui32RetryCount = CLEANUP_THREAD_RETRY_COUNT_DEFAULT;
+		psConnectionData->sCleanupThreadFn.bDependsOnHW = IMG_FALSE;
+		PVRSRVCleanupThreadAddWork(&psConnectionData->sCleanupThreadFn);
+	}
 }
 
 IMG_PID PVRSRVGetPurgeConnectionPid(void)
diff --git a/drivers/staging/imgtec/rogue/connection_server.h b/drivers/staging/imgtec/rogue/connection_server.h
index 2bbc623..481a07a 100644
--- a/drivers/staging/imgtec/rogue/connection_server.h
+++ b/drivers/staging/imgtec/rogue/connection_server.h
@@ -59,6 +59,7 @@
 typedef struct _CONNECTION_DATA_
 {
 	PVRSRV_HANDLE_BASE		*psHandleBase;
+	PROCESS_HANDLE_BASE		*psProcessHandleBase;
 	struct _SYNC_CONNECTION_DATA_	*psSyncConnectionData;
 	struct _PDUMP_CONNECTION_DATA_	*psPDumpConnectionData;
 
@@ -78,6 +79,8 @@
 
 	IMG_HANDLE			hProcessStats;
 
+	IMG_HANDLE			hClientTLStream;
+
 	/* Structure which is hooked into the cleanup thread work list */
 	PVRSRV_CLEANUP_THREAD_WORK sCleanupThreadFn;
 
@@ -91,9 +94,6 @@
 PVRSRV_ERROR PVRSRVConnectionConnect(void **ppvPrivData, void *pvOSData);
 void PVRSRVConnectionDisconnect(void *pvPrivData);
 
-PVRSRV_ERROR PVRSRVConnectionInit(void);
-PVRSRV_ERROR PVRSRVConnectionDeInit(void);
-
 IMG_PID PVRSRVGetPurgeConnectionPid(void);
 
 #ifdef INLINE_IS_PRAGMA
diff --git a/drivers/staging/imgtec/rogue/dbgdriv.c b/drivers/staging/imgtec/rogue/dbgdriv.c
index 0cbe704..935efc9 100644
--- a/drivers/staging/imgtec/rogue/dbgdriv.c
+++ b/drivers/staging/imgtec/rogue/dbgdriv.c
@@ -57,7 +57,7 @@
 #include <linux/string.h>
 #endif
 
-#if defined (__QNXNTO__)
+#if defined (__QNXNTO__) || defined (INTEGRITY_OS)
 #include <string.h>
 #endif
 
@@ -78,8 +78,6 @@
  Types
 ******************************************************************************/
 
-#define DBG_STREAM_NAME_MAX		30
-
 /*
 	Per-buffer control structure.
 */
@@ -98,7 +96,7 @@
 
 	IMG_UINT32 ui32InitPhaseWOff;	/*!< snapshot offset for init phase end for follow-on pdump */
 
-	IMG_CHAR   szName[DBG_STREAM_NAME_MAX];			/* Give this a size, some compilers don't like [] */
+	IMG_CHAR   szName[DEBUG_STREAM_NAME_MAX];			/* Give this a size, some compilers don't like [] */
 } DBG_STREAM;
 
 /* Check 4xDBG_STREAM will fit in one page */
@@ -166,7 +164,7 @@
 {
 	IMG_BOOL pvRet;
 
-	/* Aquire API Mutex */
+	/* Acquire API Mutex */
 	HostAquireMutex(g_pvAPIMutex);
 
 	pvRet=DBGDrivCreateStream(pszName, ui32Flags, ui32Size, phInit, phMain, phDeinit);
@@ -182,7 +180,7 @@
  */
 void IMG_CALLCONV ExtDBGDrivDestroyStream(IMG_HANDLE hInit,IMG_HANDLE hMain, IMG_HANDLE hDeinit)
 {
-	/* Aquire API Mutex */
+	/* Acquire API Mutex */
 	HostAquireMutex(g_pvAPIMutex);
 
 	DBGDrivDestroyStream(hInit, hMain, hDeinit);
@@ -200,7 +198,7 @@
 {
 	void *	pvRet;
 
-	/* Aquire API Mutex */
+	/* Acquire API Mutex */
 	HostAquireMutex(g_pvAPIMutex);
 
 	pvRet=DBGDrivFindStream(pszName, bResetStream);
@@ -223,7 +221,7 @@
 {
 	IMG_UINT32 ui32Ret;
 
-	/* Aquire API Mutex */
+	/* Acquire API Mutex */
 	HostAquireMutex(g_pvAPIMutex);
 
 	ui32Ret=DBGDrivRead(psStream, ui32BufID, ui32OutBuffSize, pui8OutBuf);
@@ -241,7 +239,7 @@
 {
 	IMG_UINT32	ui32Ret;
 
-	/* Aquire API Mutex */
+	/* Acquire API Mutex */
 	HostAquireMutex(g_pvAPIMutex);
 
 	ui32Ret=DBGDrivWrite2(psStream, pui8InBuf, ui32InBuffSize);
@@ -257,7 +255,7 @@
  */
 void IMG_CALLCONV ExtDBGDrivSetMarker(PDBG_STREAM psStream, IMG_UINT32 ui32Marker)
 {
-	/* Aquire API Mutex */
+	/* Acquire API Mutex */
 	HostAquireMutex(g_pvAPIMutex);
 
 	DBGDrivSetMarker(psStream, ui32Marker);
@@ -275,7 +273,7 @@
 {
 	IMG_UINT32	ui32Marker;
 
-	/* Aquire API Mutex */
+	/* Acquire API Mutex */
 	HostAquireMutex(g_pvAPIMutex);
 
 	ui32Marker = DBGDrivGetMarker(psStream);
@@ -306,7 +304,7 @@
 {
 	IMG_UINT32 ui32State = 0;
 
-	/* Aquire API Mutex */
+	/* Acquire API Mutex */
 	HostAquireMutex(g_pvAPIMutex);
 
 	ui32State = DBGDrivGetCtrlState(psStream, ui32StateID);
@@ -324,7 +322,7 @@
 {
 	IMG_UINT32 ui32Frame = 0;
 
-	/* Aquire API Mutex */
+	/* Acquire API Mutex */
 	HostAquireMutex(g_pvAPIMutex);
 
 	ui32Frame = DBGDrivGetFrame();
@@ -340,7 +338,7 @@
  */
 void IMG_CALLCONV ExtDBGDrivSetFrame(IMG_UINT32 ui32Frame)
 {
-	/* Aquire API Mutex */
+	/* Acquire API Mutex */
 	HostAquireMutex(g_pvAPIMutex);
 
 	DBGDrivSetFrame(ui32Frame);
@@ -662,7 +660,7 @@
 									 IMG_CHAR* pszExt)
 {
 	IMG_CHAR* pCh = psStream->szName;
-	IMG_CHAR* pChEnd = psStream->szName+DBG_STREAM_NAME_MAX-8;
+	IMG_CHAR* pChEnd = psStream->szName+DEBUG_STREAM_NAME_MAX-8;
 	IMG_CHAR* pSrcCh;
 	IMG_CHAR* pSrcChEnd;
 
@@ -966,7 +964,7 @@
 
 		if (strlen(psThis->szName) == strlen(pszName))
 		{
-			while ((ui32Off < DBG_STREAM_NAME_MAX) && (psThis->szName[ui32Off] != 0) && (pszName[ui32Off] != 0) && bAreSame)
+			while ((ui32Off < DEBUG_STREAM_NAME_MAX) && (psThis->szName[ui32Off] != 0) && (pszName[ui32Off] != 0) && bAreSame)
 			{
 				if (psThis->szName[ui32Off] != pszName[ui32Off])
 				{
@@ -1310,22 +1308,6 @@
 }
 #endif
 
-/*	Use PVR_DPF() to avoid state messages in release build */
-#if defined(PVR_DISABLE_LOGGING) || !defined(DEBUG)
-#define PVR_LOG(...)
-#else
-
-extern void PVRSRVDebugPrintf(IMG_UINT32	ui32DebugLevel,
-						const IMG_CHAR*	pszFileName,
-						IMG_UINT32	ui32Line,
-						const IMG_CHAR*	pszFormat,
-						...	);
-/* Reproduce the PVR_LOG macro here but direct it to DPF */
-#define PVR_LOG(...)	PVRSRVDebugPrintf( DBGPRIV_CALLTRACE, __FILE__, __LINE__ , __VA_ARGS__);
-
-#endif
-
-
 /*!****************************************************************************
  @name		DBGDrivGetCtrlState
  @brief		Gets a state value from the debug driver or stream
@@ -1346,34 +1328,43 @@
 	{
 	case DBG_GET_STATE_FLAG_IS_READONLY:
 		return ((psStream->ui32Flags & DEBUG_FLAGS_READONLY) != 0);
-		break;
 
 	case 0xFE: /* Dump the current stream state */
-		PVR_LOG("------ PDUMP DBGDriv: psStream( %p ) ( -- %s -- ) ui32Flags( %x )",
-				psStream, psStream->szName, psStream->ui32Flags);
-		PVR_LOG("------ PDUMP DBGDriv: psStream->pvBase( %p ) psStream->ui32Size( %u )",
-				psStream->pvBase, psStream->ui32Size);
-		PVR_LOG("------ PDUMP DBGDriv: psStream->ui32RPtr( %u ) psStream->ui32WPtr( %u )",
-				psStream->ui32RPtr, psStream->ui32WPtr);
-		PVR_LOG("------ PDUMP DBGDriv: psStream->ui32Marker( %u ) psStream->ui32InitPhaseWOff( %u )",
-				psStream->ui32Marker, psStream->ui32InitPhaseWOff);
+		PVR_DPF((PVR_DBG_CALLTRACE,
+				 "------ PDUMP DBGDriv: psStream( %p ) ( -- %s -- ) ui32Flags( %x )",
+				 psStream, psStream->szName, psStream->ui32Flags));
+		PVR_DPF((PVR_DBG_CALLTRACE,
+				 "------ PDUMP DBGDriv: psStream->pvBase( %p ) psStream->ui32Size( %u )",
+				 psStream->pvBase, psStream->ui32Size));
+		PVR_DPF((PVR_DBG_CALLTRACE,
+				 "------ PDUMP DBGDriv: psStream->ui32RPtr( %u ) psStream->ui32WPtr( %u )",
+				 psStream->ui32RPtr, psStream->ui32WPtr));
+		PVR_DPF((PVR_DBG_CALLTRACE,
+				 "------ PDUMP DBGDriv: psStream->ui32Marker( %u ) psStream->ui32InitPhaseWOff( %u )",
+				 psStream->ui32Marker, psStream->ui32InitPhaseWOff));
 		if (psStream->psInitStream)
 		{
-			PVR_LOG("-------- PDUMP DBGDriv: psInitStream( %p ) ( -- %s -- ) ui32Flags( %x )",
-					psStream->psInitStream, psStream->psInitStream->szName, psStream->ui32Flags);
-			PVR_LOG("-------- PDUMP DBGDriv: psInitStream->pvBase( %p ) psInitStream->ui32Size( %u )",
-					psStream->psInitStream->pvBase, psStream->psInitStream->ui32Size);
-			PVR_LOG("-------- PDUMP DBGDriv: psInitStream->ui32RPtr( %u ) psInitStream->ui32WPtr( %u )",
-					psStream->psInitStream->ui32RPtr, psStream->psInitStream->ui32WPtr);
-			PVR_LOG("-------- PDUMP DBGDriv: psInitStream->ui32Marker( %u ) psInitStream->ui32InitPhaseWOff( %u ) ",
-					psStream->psInitStream->ui32Marker, psStream->psInitStream->ui32InitPhaseWOff);
+			PVR_DPF((PVR_DBG_CALLTRACE,
+					 "-------- PDUMP DBGDriv: psInitStream( %p ) ( -- %s -- ) ui32Flags( %x )",
+					 psStream->psInitStream, psStream->psInitStream->szName, psStream->ui32Flags));
+			PVR_DPF((PVR_DBG_CALLTRACE,
+					 "-------- PDUMP DBGDriv: psInitStream->pvBase( %p ) psInitStream->ui32Size( %u )",
+					 psStream->psInitStream->pvBase, psStream->psInitStream->ui32Size));
+			PVR_DPF((PVR_DBG_CALLTRACE,
+					 "-------- PDUMP DBGDriv: psInitStream->ui32RPtr( %u ) psInitStream->ui32WPtr( %u )",
+					 psStream->psInitStream->ui32RPtr, psStream->psInitStream->ui32WPtr));
+			PVR_DPF((PVR_DBG_CALLTRACE,
+					 "-------- PDUMP DBGDriv: psInitStream->ui32Marker( %u ) psInitStream->ui32InitPhaseWOff( %u ) ",
+					 psStream->psInitStream->ui32Marker, psStream->psInitStream->ui32InitPhaseWOff));
 		}
 
 		break;
 
 	case 0xFF: /* Dump driver state not in a stream */
 		{
-			PVR_LOG("------ PDUMP DBGDriv: g_psStreamList( head %p ) g_pvAPIMutex( %p ) g_PDumpCurrentFrameNo( %u )", g_psStreamList, g_pvAPIMutex, g_PDumpCurrentFrameNo);
+			PVR_DPF((PVR_DBG_CALLTRACE,
+					 "------ PDUMP DBGDriv: g_psStreamList( head %p ) g_pvAPIMutex( %p ) g_PDumpCurrentFrameNo( %u )",
+					 g_psStreamList, g_pvAPIMutex, g_PDumpCurrentFrameNo));
 		}
 		break;
 
@@ -1477,7 +1468,7 @@
 					(void *)(IMG_PBYTE)psStream->pvBase,
 					psStream->ui32WPtr);
 		}
-		ui32NewROffset = 0;
+		ui32NewROffset = 0; 
 	}
 	else
 	{
diff --git a/drivers/staging/imgtec/rogue/dbgdriv.h b/drivers/staging/imgtec/rogue/dbgdriv.h
index be1da26..f310b42 100644
--- a/drivers/staging/imgtec/rogue/dbgdriv.h
+++ b/drivers/staging/imgtec/rogue/dbgdriv.h
@@ -53,8 +53,14 @@
 #define DBGDRIV_MONOBASE	0x000B0000
 
 
+/*****************************************************************************
+ * OS-specific declarations and init/cleanup functions
+*****************************************************************************/
 extern void *	g_pvAPIMutex;
 
+extern IMG_INT dbgdrv_init(void);
+extern void dbgdrv_cleanup(void);
+
 /*****************************************************************************
  Internal debug driver core functions
 *****************************************************************************/
diff --git a/drivers/staging/imgtec/rogue/dbgdrvif_srv5.h b/drivers/staging/imgtec/rogue/dbgdrvif_srv5.h
index a060d0c..87f303e 100644
--- a/drivers/staging/imgtec/rogue/dbgdrvif_srv5.h
+++ b/drivers/staging/imgtec/rogue/dbgdrvif_srv5.h
@@ -63,6 +63,8 @@
 
 #endif
 
+#include "img_defs.h"
+
 
 /*****************************************************************************
  Stream mode stuff.
@@ -76,6 +78,9 @@
 #define DEBUG_FLAGS_WRITEONLY			0x00000010UL
 #define DEBUG_FLAGS_CIRCULAR			0x00000020UL
 
+/* Stream name maximum length */
+#define DEBUG_STREAM_NAME_MAX			32
+
 /*****************************************************************************
  IOCTL values.
 *****************************************************************************/
@@ -121,12 +126,6 @@
 #define DBGDRV_WINCE_DEVICE_NAME			L"DBD1:"
 #endif
 
-#ifdef __GNUC__
-#define DBG_ALIGN(n) __attribute__ ((aligned (n)))
-#else
-#define DBG_ALIGN(n)
-#endif
-
 /* A pointer type which is at least 64 bits wide. The fixed width ensures
  * consistency in structures between 32 and 64-bit code.
  * The UM code (be it 32 or 64 bit) can simply write to the native pointer type (pvPtr).
@@ -147,7 +146,7 @@
 	IMG_UINT32 ui32Ptr;
 	/* force the union width */
 	IMG_UINT64 ui64Ptr;
-} DBG_WIDEPTR DBG_ALIGN(8);
+} DBG_WIDEPTR __aligned(8);
 
 /* Helper macro for dbgdriv (KM) to get the pointer value from the WIDEPTR type,
  * depending on whether the client is 32 or 64-bit.
@@ -197,7 +196,7 @@
 
 typedef struct _DBG_IN_FINDSTREAM_
 {
-	DBG_WIDEPTR pszName;
+	IMG_CHAR pszName[DEBUG_STREAM_NAME_MAX];
 	IMG_BOOL bResetStream;
 }DBG_IN_FINDSTREAM, *PDBG_IN_FINDSTREAM;
 
diff --git a/drivers/staging/imgtec/rogue/dc_common.h b/drivers/staging/imgtec/rogue/dc_common.h
deleted file mode 100644
index f5ef848..0000000
--- a/drivers/staging/imgtec/rogue/dc_common.h
+++ /dev/null
@@ -1,73 +0,0 @@
-/*************************************************************************/ /*!
-@File
-@Title          Common Display Class header
-@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
-@Description    Defines DC specific structures which are shared within services
-                only
-@License        Dual MIT/GPLv2
-
-The contents of this file are subject to the MIT license as set out below.
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-Alternatively, the contents of this file may be used under the terms of
-the GNU General Public License Version 2 ("GPL") in which case the provisions
-of GPL are applicable instead of those above.
-
-If you wish to allow use of your version of this file only under the terms of
-GPL, and not to allow others to use your version of this file under the terms
-of the MIT license, indicate your decision by deleting the provisions above
-and replace them with the notice and other provisions required by GPL as set
-out in the file called "GPL-COPYING" included in this distribution. If you do
-not delete the provisions above, a recipient may use your version of this file
-under the terms of either the MIT license or GPL.
-
-This License is also included in this distribution in the file called
-"MIT-COPYING".
-
-EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
-PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
-BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
-PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
-COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
-IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
-CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-*/ /**************************************************************************/
-#include "img_types.h"
-
-#ifndef _DC_COMMON_H_
-#define _DC_COMMON_H_
-
-typedef struct _DC_FBC_CREATE_INFO_
-{
-	IMG_UINT32		ui32FBCWidth;	/*!< Pixel width that the FBC module is working on */
-	IMG_UINT32		ui32FBCHeight;	/*!< Pixel height that the FBC module is working on */
-	IMG_UINT32		ui32FBCStride;	/*!< Pixel stride that the FBC module is working on */
-	IMG_UINT32		ui32Size;		/*!< Size of the buffer to create */
-} DC_FBC_CREATE_INFO;
-
-typedef struct _DC_CREATE_INFO_
-{
-	union {
-		DC_FBC_CREATE_INFO sFBC;
-	} u;
-} DC_CREATE_INFO;
-
-typedef struct _DC_BUFFER_CREATE_INFO_
-{
-	PVRSRV_SURFACE_INFO   	sSurface;	/*!< Surface properies, specificed by user */
-	IMG_UINT32            	ui32BPP;	/*!< Bits per pixel */
-	union {
-		DC_FBC_CREATE_INFO 	sFBC;		/*!< Frame buffer compressed specific data */
-	} u;
-} DC_BUFFER_CREATE_INFO;
-
-#endif /* _DC_COMMON_H_ */
diff --git a/drivers/staging/imgtec/rogue/dc_external.h b/drivers/staging/imgtec/rogue/dc_external.h
index dd64225..ad5a69e 100644
--- a/drivers/staging/imgtec/rogue/dc_external.h
+++ b/drivers/staging/imgtec/rogue/dc_external.h
@@ -1,10 +1,10 @@
 /*************************************************************************/ /*!
 @File
-@Title          Device class external
-@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Title          Display class external
 @Description    Defines DC specific structures which are externally visible
                 (i.e. visible to clients of services), but are also required
                 within services.
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
 @License        Dual MIT/GPLv2
 
 The contents of this file are subject to the MIT license as set out below.
@@ -48,24 +48,73 @@
 
 #include "img_types.h"
 
+/*!
+ * Maximum size of the display name in DC_DISPLAY_INFO
+ */
 #define DC_NAME_SIZE	50
+
+/*!
+ * This contains information about a display.
+ * The structure can be queried by services from the display driver via a
+ * registered callback.
+ *
+ *   Structure: #_DC_DISPLAY_INFO_
+ *   Typedef: ::DC_DISPLAY_INFO
+ */
 typedef struct _DC_DISPLAY_INFO_
 {
-	IMG_CHAR		szDisplayName[DC_NAME_SIZE];
-	IMG_UINT32		ui32MinDisplayPeriod;
-	IMG_UINT32		ui32MaxDisplayPeriod;
-	IMG_UINT32		ui32MaxPipes;
-	IMG_BOOL		bUnlatchedSupported;
+	IMG_CHAR		szDisplayName[DC_NAME_SIZE];	/*!< Display identifier string */
+	IMG_UINT32		ui32MinDisplayPeriod;			/*!< Minimum number of VSync periods */
+	IMG_UINT32		ui32MaxDisplayPeriod;			/*!< Maximum number of VSync periods */
+	IMG_UINT32		ui32MaxPipes;					/*!< Maximum number of pipes for this display */
+	IMG_BOOL		bUnlatchedSupported;			/*!< Can the device be unlatched? */
 } DC_DISPLAY_INFO;
 
+/*!
+ * When services imports a buffer from the display driver it has to fill
+ * this structure to inform services about the buffer properties.
+ *
+ *   Structure: #_DC_BUFFER_IMPORT_INFO_
+ *   Typedef: ::DC_BUFFER_IMPORT_INFO
+ */
 typedef struct _DC_BUFFER_IMPORT_INFO_
 {
-	IMG_UINT32		ePixFormat;
-	IMG_UINT32		ui32BPP;
-	IMG_UINT32		ui32Width[3];
-	IMG_UINT32		ui32Height[3];
-	IMG_UINT32		ui32ByteStride[3];
-	IMG_UINT32		ui32PrivData[3];
+	IMG_UINT32		ePixFormat;			/*!< Enum value of type IMG_PIXFMT for the pixel format */
+	IMG_UINT32		ui32BPP;			/*!< Bits per pixel */
+	IMG_UINT32		ui32Width[3];		/*!< Width of the different channels (defined by ePixFormat) */
+	IMG_UINT32		ui32Height[3];		/*!< Height of the different channels (defined by ePixFormat) */
+	IMG_UINT32		ui32ByteStride[3];	/*!< Byte stride of the different channels (defined by ePixFormat) */
+	IMG_UINT32		ui32PrivData[3];	/*!< Private data of the display for each of the channels */
 } DC_BUFFER_IMPORT_INFO;
 
+
+/*!
+ * Configuration details of the frame buffer compression module
+ *
+ *   Structure: #_DC_FBC_CREATE_INFO_
+ *   Typedef: ::DC_FBC_CREATE_INFO
+ */
+typedef struct _DC_FBC_CREATE_INFO_
+{
+	IMG_UINT32		ui32FBCWidth;	/*!< Pixel width that the FBC module is working on */
+	IMG_UINT32		ui32FBCHeight;	/*!< Pixel height that the FBC module is working on */
+	IMG_UINT32		ui32FBCStride;	/*!< Pixel stride that the FBC module is working on */
+	IMG_UINT32		ui32Size;		/*!< Size of the buffer to create */
+} DC_FBC_CREATE_INFO;
+
+/*!
+ * DC buffer details like frame buffer compression and surface properties
+ *
+ *   Structure: #_DC_BUFFER_CREATE_INFO_
+ *   Typedef: ::DC_BUFFER_CREATE_INFO
+ */
+typedef struct _DC_BUFFER_CREATE_INFO_
+{
+	PVRSRV_SURFACE_INFO		sSurface;	/*!< Surface properties, specified by user */
+	IMG_UINT32				ui32BPP;	/*!< Bits per pixel */
+	union {
+		DC_FBC_CREATE_INFO 	sFBC;
+	} u;								/*!< Frame buffer compressed specific data */
+} DC_BUFFER_CREATE_INFO;
+
 #endif /* _DC_EXTERNAL_H_ */
diff --git a/drivers/staging/imgtec/rogue/dc_server.c b/drivers/staging/imgtec/rogue/dc_server.c
index de198579..aef3c95 100644
--- a/drivers/staging/imgtec/rogue/dc_server.c
+++ b/drivers/staging/imgtec/rogue/dc_server.c
@@ -50,11 +50,11 @@
 #include "dc_server.h"
 #include "kerneldisplay.h"
 #include "pvr_debug.h"
+#include "pvr_notifier.h"
 #include "pmr.h"
-#include "pdump_physmem.h"
 #include "sync_server.h"
 #include "pvrsrv.h"
-#include "debug_request_ids.h"
+#include "process_stats.h"
 
 #if defined(PVR_RI_DEBUG)
 #include "ri_server.h"
@@ -85,6 +85,7 @@
 
 struct _DC_DEVICE_
 {
+	PVRSRV_DEVICE_NODE			*psDevNode;
 	const DC_DEVICE_FUNCTIONS	*psFuncTable;
 	IMG_UINT32					ui32MaxConfigsInFlight;
 	IMG_HANDLE					hDeviceData;
@@ -161,18 +162,15 @@
 	IMG_DEVMEM_LOG2ALIGN_T	uiLog2PageSize;		/*!< Log 2 of the buffers pagesize */
 	IMG_UINT32				ui32PageCount;		/*!< Number of pages in this buffer */
 	PHYS_HEAP				*psPhysHeap;		/*!< The physical heap the memory resides on */
-	IMG_DEV_PHYADDR			*pasDevPAddr;		/*!< Pointer to an array of device physcial addresses */
+	IMG_DEV_PHYADDR			*pasDevPAddr;		/*!< Pointer to an array of device physical addresses */
 	void					*pvLinAddr;			/*!< CPU virtual pointer or NULL if the DC driver didn't have one */
-
-	IMG_HANDLE				hPDumpAllocInfo;	/*!< Handle to PDump alloc data */
-	IMG_BOOL				bPDumpMalloced;		/*!< Did we get as far as PDump alloc? */
 } DC_BUFFER_PMR_DATA;
 
-POS_LOCK g_hDCListLock;
+static POS_LOCK g_hDCListLock;
 
-DC_DEVICE *g_psDCDeviceList;
-IMG_UINT32 g_ui32DCDeviceCount;
-IMG_UINT32 g_ui32DCNextIndex;
+static DC_DEVICE *g_psDCDeviceList;
+static IMG_UINT32 g_ui32DCDeviceCount;
+static IMG_UINT32 g_ui32DCNextIndex;
 static DLLIST_NODE g_sDisplayContextsList;
 
 
@@ -234,7 +232,7 @@
 			{
 				psTmp = psTmp->psNext;
 			}
-			psTmp->psNext = g_psDCDeviceList->psNext;
+			psTmp->psNext = psDevice->psNext;
 		}
 	
 		g_ui32DCDeviceCount--;
@@ -427,12 +425,11 @@
 	IMG_UINT32 i;
 
 	/* Create an array of the DC's private Buffer handles */
-	ahDeviceBuffers = OSAllocMem(sizeof(IMG_HANDLE) * ui32BufferCount);
+	ahDeviceBuffers = OSAllocZMem(sizeof(IMG_HANDLE) * ui32BufferCount);
 	if (ahDeviceBuffers == NULL)
 	{
 		return PVRSRV_ERROR_OUT_OF_MEMORY;
 	}
-	OSMemSet(ahDeviceBuffers, 0, sizeof(IMG_HANDLE) * ui32BufferCount);
 
 	for (i=0;i<ui32BufferCount;i++)
 	{
@@ -474,7 +471,7 @@
 	DC_DISPLAY_CONTEXT *psDisplayContext = psCompleteData->psDisplayContext;
 
 	PVR_DPF((PVR_DBG_ERROR, "Timeout fired for operation %d", psCompleteData->ui32Token));
-	SCPDumpStatus(psDisplayContext->psSCPContext);
+	SCPDumpStatus(psDisplayContext->psSCPContext, NULL);
 
 	OSDisableTimer(psDisplayContext->hTimer);
 	OSRemoveTimer(psDisplayContext->hTimer);
@@ -570,21 +567,14 @@
 	As we acquire the display memory at PMR create time there is nothing
 	to do here.
 */
-static PVRSRV_ERROR _DCPMRLockPhysAddresses(PMR_IMPL_PRIVDATA pvPriv,
-											IMG_UINT32 uiLog2DevPageSize)
+static PVRSRV_ERROR _DCPMRLockPhysAddresses(PMR_IMPL_PRIVDATA pvPriv)
 {
 	DC_BUFFER_PMR_DATA *psPMRPriv = pvPriv;
 	DC_BUFFER *psBuffer = psPMRPriv->psBuffer;
 	DC_DEVICE *psDevice = psBuffer->psDisplayContext->psDevice;
 	PVRSRV_ERROR eError;
 
-	if (uiLog2DevPageSize < psPMRPriv->uiLog2PageSize)
-	{
-		eError = PVRSRV_ERROR_PMR_INCOMPATIBLE_CONTIGUITY;
-		goto fail_contigcheck;
-	}
-
-	psPMRPriv->pasDevPAddr = OSAllocMem(sizeof(IMG_DEV_PHYADDR) *
+	psPMRPriv->pasDevPAddr = OSAllocZMem(sizeof(IMG_DEV_PHYADDR) *
 							 psPMRPriv->ui32PageCount);
 	if (psPMRPriv->pasDevPAddr == NULL)
 	{
@@ -592,10 +582,6 @@
 		goto fail_alloc;
 	}
 
-	OSMemSet(psPMRPriv->pasDevPAddr,
-			 0,
-			 sizeof(IMG_DEV_PHYADDR) * psPMRPriv->ui32PageCount);
-
 	eError = psDevice->psFuncTable->pfnBufferAcquire(psBuffer->hBuffer,
 													 psPMRPriv->pasDevPAddr,
 													 &psPMRPriv->pvLinAddr);
@@ -604,12 +590,46 @@
 		goto fail_query;
 	}
 
+#if defined(PVRSRV_ENABLE_PROCESS_STATS)
+#if defined(PVRSRV_ENABLE_MEMORY_STATS)
+	{
+		IMG_UINT32 i;
+		for (i = 0; i < psPMRPriv->ui32PageCount; i++)
+		{
+			IMG_CPU_PHYADDR sCPUPhysAddr;
+			PVRSRV_MEM_ALLOC_TYPE eAllocType;
+#if defined(LMA)
+			eAllocType = PVRSRV_MEM_ALLOC_TYPE_ALLOC_LMA_PAGES;
+#else
+			eAllocType = PVRSRV_MEM_ALLOC_TYPE_ALLOC_UMA_PAGES;
+#endif
+			sCPUPhysAddr.uiAddr = ((uintptr_t)psPMRPriv->pvLinAddr) + i * (1 << psPMRPriv->uiLog2PageSize);
+			PVRSRVStatsAddMemAllocRecord(eAllocType,
+			                             NULL,
+			                             sCPUPhysAddr,
+			                             1 << psPMRPriv->uiLog2PageSize,
+			                             NULL);
+		}
+	}
+#else
+	{
+		PVRSRV_MEM_ALLOC_TYPE eAllocType;
+#if defined(LMA)
+		eAllocType = PVRSRV_MEM_ALLOC_TYPE_ALLOC_LMA_PAGES;
+#else
+		eAllocType = PVRSRV_MEM_ALLOC_TYPE_ALLOC_UMA_PAGES;
+#endif
+		PVRSRVStatsIncrMemAllocStat(eAllocType,
+		                            psPMRPriv->ui32PageCount * (1 << psPMRPriv->uiLog2PageSize));
+	}
+#endif
+#endif
+
 	return PVRSRV_OK;
 
 fail_query:
 	OSFreeMem(psPMRPriv->pasDevPAddr);
 fail_alloc:
-fail_contigcheck:
 	return eError;
 }
 
@@ -619,6 +639,41 @@
 	DC_BUFFER *psBuffer = psPMRPriv->psBuffer;
 	DC_DEVICE *psDevice = psBuffer->psDisplayContext->psDevice;
 
+#if defined(PVRSRV_ENABLE_PROCESS_STATS)
+#if !defined(PVRSRV_ENABLE_MEMORY_STATS)
+	{
+		PVRSRV_MEM_ALLOC_TYPE eAllocType;
+#if defined(LMA)
+		eAllocType = PVRSRV_MEM_ALLOC_TYPE_ALLOC_LMA_PAGES;
+#else
+		eAllocType = PVRSRV_MEM_ALLOC_TYPE_ALLOC_UMA_PAGES;
+#endif
+		PVRSRVStatsDecrMemAllocStat(eAllocType,
+		                            psPMRPriv->ui32PageCount * (1 << psPMRPriv->uiLog2PageSize));
+	}
+#else
+	{
+		PVRSRV_MEM_ALLOC_TYPE eAllocType;
+		IMG_UINT32 i;
+
+#if defined(LMA)
+		eAllocType = PVRSRV_MEM_ALLOC_TYPE_ALLOC_LMA_PAGES;
+#else
+		eAllocType = PVRSRV_MEM_ALLOC_TYPE_ALLOC_UMA_PAGES;
+#endif
+
+		for(i = 0; i < psPMRPriv->ui32PageCount; i++)
+		{
+			IMG_CPU_PHYADDR sCPUPhysAddr;
+
+			sCPUPhysAddr.uiAddr = ((uintptr_t)psPMRPriv->pvLinAddr) + i * (1 << psPMRPriv->uiLog2PageSize);
+			PVRSRVStatsRemoveMemAllocRecord(eAllocType,
+			                                sCPUPhysAddr.uiAddr);
+		}
+	}
+#endif
+#endif
+
 	psDevice->psFuncTable->pfnBufferRelease(psBuffer->hBuffer);
 	OSFreeMem(psPMRPriv->pasDevPAddr);
 
@@ -626,6 +681,7 @@
 }
 
 static PVRSRV_ERROR _DCPMRDevPhysAddr(PMR_IMPL_PRIVDATA pvPriv,
+									  IMG_UINT32 ui32Log2PageSize,
 									  IMG_UINT32 ui32NumOfPages,
 									  IMG_DEVMEM_OFFSET_T *puiOffset,
 									  IMG_BOOL *pbValid,
@@ -633,24 +689,28 @@
 {
 	DC_BUFFER_PMR_DATA *psPMRPriv = pvPriv;
     IMG_UINT32 uiNumPages = psPMRPriv->ui32PageCount;
-    IMG_UINT32 uiLog2PageSize = psPMRPriv->uiLog2PageSize;
-    IMG_UINT32 uiPageSize = 1ULL << uiLog2PageSize;
+    IMG_UINT32 uiPageSize = 1ULL << ui32Log2PageSize;
     IMG_UINT32 uiPageIndex;
     IMG_UINT32 uiInPageOffset;
     IMG_DEV_PHYADDR sDevAddr;
     IMG_UINT32 idx;
 
+	if (psPMRPriv->uiLog2PageSize != ui32Log2PageSize)
+	{
+		return PVRSRV_ERROR_INVALID_PARAMS;
+	}
+
 	for (idx=0; idx < ui32NumOfPages; idx++)
 	{
 		if (pbValid[idx])
 		{
 			/* verify the cast
 			   N.B.  Strictly... this could be triggered by an illegal uiOffset arg too. */
-			uiPageIndex = (IMG_UINT32)(puiOffset[idx] >> uiLog2PageSize);
-			PVR_ASSERT((IMG_DEVMEM_OFFSET_T)uiPageIndex << uiLog2PageSize == puiOffset[idx]);
+			uiPageIndex = (IMG_UINT32)(puiOffset[idx] >> ui32Log2PageSize);
+			PVR_ASSERT((IMG_DEVMEM_OFFSET_T)uiPageIndex << ui32Log2PageSize == puiOffset[idx]);
 		
-			uiInPageOffset = (IMG_UINT32)(puiOffset[idx] - ((IMG_DEVMEM_OFFSET_T)uiPageIndex << uiLog2PageSize));		
-			PVR_ASSERT(puiOffset[idx] == ((IMG_DEVMEM_OFFSET_T)uiPageIndex << uiLog2PageSize) + uiInPageOffset);
+			uiInPageOffset = (IMG_UINT32)(puiOffset[idx] - ((IMG_DEVMEM_OFFSET_T)uiPageIndex << ui32Log2PageSize));		
+			PVR_ASSERT(puiOffset[idx] == ((IMG_DEVMEM_OFFSET_T)uiPageIndex << ui32Log2PageSize) + uiInPageOffset);
 			PVR_ASSERT(uiPageIndex < uiNumPages);
 			PVR_ASSERT(uiInPageOffset < uiPageSize);
 
@@ -665,17 +725,116 @@
     return PVRSRV_OK;
 }
 
+#if defined(INTEGRITY_OS)
+static PVRSRV_ERROR _DCPMRAcquireKernelMappingData(PMR_IMPL_PRIVDATA pvPriv,
+												   size_t uiOffset,
+												   size_t uiSize,
+												   void **ppvKernelAddressOut,
+												   IMG_HANDLE *phHandleOut,
+												   PMR_FLAGS_T ulFlags)
+{
+	DC_BUFFER_PMR_DATA *psPMRPriv = (DC_BUFFER_PMR_DATA *)pvPriv;
+	DC_BUFFER          *psBuffer = NULL;
+	DC_DEVICE          *psDevice = NULL;
+	IMG_HANDLE          hMapping = NULL;
+	void	           *pvKernelAddr = NULL;
+	PVRSRV_ERROR        eError = PVRSRV_OK;
+
+	if (psPMRPriv == NULL)
+	{
+		PVR_DPF((PVR_DBG_ERROR, "_DCPMRAcquireKernelMappingData: Invalid parameters."));
+		eError = PVRSRV_ERROR_INVALID_PARAMS;
+	}
+	else
+	{
+		psBuffer = psPMRPriv->psBuffer;
+		psDevice = psBuffer->psDisplayContext->psDevice;
+
+		eError = psDevice->psFuncTable->pfnAcquireKernelMappingData(psBuffer->hBuffer, &hMapping, &pvKernelAddr);
+		if (eError != PVRSRV_OK)
+		{
+			PVR_DPF((PVR_DBG_ERROR, "_DCPMRAcquireKernelMappingData: AcquireKernelMappingData failed."));
+		}
+		else
+		{
+			*phHandleOut = (IMG_HANDLE)psPMRPriv;
+			*ppvKernelAddressOut = pvKernelAddr;
+		}
+	}
+
+	return eError;
+}
+
+static void _DCPMRReleaseKernelMappingData(PMR_IMPL_PRIVDATA pvPriv,
+										   IMG_HANDLE hHandle)
+{
+	PVR_UNREFERENCED_PARAMETER(pvPriv);
+	PVR_UNREFERENCED_PARAMETER(hHandle);
+}
+
+static PVRSRV_ERROR _DCPMRMapMemoryObject(PMR_IMPL_PRIVDATA pvPriv, IMG_HANDLE *phMemObj)
+{
+	DC_BUFFER_PMR_DATA *psPMRPriv = (DC_BUFFER_PMR_DATA *)pvPriv;
+	DC_BUFFER          *psBuffer = NULL;
+	DC_DEVICE          *psDevice = NULL;
+	PVRSRV_ERROR        eError = PVRSRV_OK;
+
+	if ((psPMRPriv == NULL) || (phMemObj == NULL))
+	{
+		PVR_DPF((PVR_DBG_ERROR, "_DCPMRMapMemoryObject: Invalid parameters."));
+		eError = PVRSRV_ERROR_INVALID_PARAMS;
+	}
+	else
+	{
+		psBuffer = psPMRPriv->psBuffer;
+		psDevice = psBuffer->psDisplayContext->psDevice;
+		eError = psDevice->psFuncTable->pfnMapMemoryObject(psBuffer->hBuffer, phMemObj);
+	}
+
+	return eError;
+}
+
+static PVRSRV_ERROR _DCPMRUnmapMemoryObject(PMR_IMPL_PRIVDATA pvPriv)
+{
+	DC_BUFFER_PMR_DATA *psPMRPriv = (DC_BUFFER_PMR_DATA *)pvPriv;
+	DC_BUFFER          *psBuffer = NULL;
+	DC_DEVICE          *psDevice = NULL;
+	PVRSRV_ERROR        eError = PVRSRV_OK;
+
+	if (psPMRPriv == NULL)
+	{
+		PVR_DPF((PVR_DBG_ERROR, "_DCPMRUnmapMemoryObject: Invalid parameters."));
+		eError = PVRSRV_ERROR_INVALID_PARAMS;
+	}
+	else
+	{
+		psBuffer = psPMRPriv->psBuffer;
+		psDevice = psBuffer->psDisplayContext->psDevice;
+		eError = psDevice->psFuncTable->pfnUnmapMemoryObject(psBuffer->hBuffer);
+	}
+
+	return eError;
+}
+
+#if defined(USING_HYPERVISOR)
+static IMG_HANDLE _DCPMRGetPmr(PMR_IMPL_PRIVDATA pvPriv, size_t ulOffset)
+{
+	DC_BUFFER_PMR_DATA *psPMRPriv = pvPriv;
+	DC_BUFFER          *psBuffer = NULL;
+	DC_DEVICE          *psDevice = NULL;
+	
+	psBuffer = psPMRPriv->psBuffer;
+	psDevice = psBuffer->psDisplayContext->psDevice;
+	
+	return psDevice->psFuncTable->pfnGetPmr(psBuffer->hBuffer, ulOffset);
+}
+#endif
+#endif
+
 static PVRSRV_ERROR _DCPMRFinalize(PMR_IMPL_PRIVDATA pvPriv)
 {
 	DC_BUFFER_PMR_DATA *psPMRPriv = pvPriv;
 
-	/* Conditionally do the PDump free, because if CreatePMR failed we
-	   won't have done the PDump MALLOC.  */
-	if (psPMRPriv->bPDumpMalloced)
-	{
-		PDumpFree(psPMRPriv->hPDumpAllocInfo);
-	}
-
 	PhysHeapRelease(psPMRPriv->psPhysHeap);
 	_DCBufferReleaseRef(psPMRPriv->psBuffer);
 	OSFreeMem(psPMRPriv);
@@ -704,7 +863,7 @@
 	if (psPMRPriv->pvLinAddr)
 	{
 		pcKernelPointer = psPMRPriv->pvLinAddr;
-		OSMemCopy(pcBuffer, &pcKernelPointer[uiOffset], uiBufSz);
+		OSDeviceMemCopy(pcBuffer, &pcKernelPointer[uiOffset], uiBufSz);
 		*puiNumBytes = uiBufSz;
 		return PVRSRV_OK;
 	}
@@ -726,11 +885,12 @@
 
         pvMapping = OSMapPhysToLin(sCpuPAddr,
 								   1 << psPMRPriv->uiLog2PageSize,
-								   0);
+								   PVRSRV_MEMALLOCFLAG_CPU_UNCACHED);
         PVR_ASSERT(pvMapping != NULL);
         pcKernelPointer = pvMapping;
-        OSMemCopy(&pcBuffer[uiBufferOffset], &pcKernelPointer[uiInPageOffset], uiBytesCopyableFromPage);
-        OSUnMapPhysToLin(pvMapping, 1 << psPMRPriv->uiLog2PageSize, 0);
+        OSDeviceMemCopy(&pcBuffer[uiBufferOffset], &pcKernelPointer[uiInPageOffset], uiBytesCopyableFromPage);
+        OSUnMapPhysToLin(pvMapping, 1 << psPMRPriv->uiLog2PageSize,
+						 PVRSRV_MEMALLOCFLAG_CPU_UNCACHED);
 
         uiBufferOffset += uiBytesCopyableFromPage;
         uiBytesToCopy -= uiBytesCopyableFromPage;
@@ -746,9 +906,18 @@
 	_DCPMRLockPhysAddresses,	/* .pfnLockPhysAddresses */
 	_DCPMRUnlockPhysAddresses,	/* .pfnUnlockPhysAddresses */
 	_DCPMRDevPhysAddr,			/* .pfnDevPhysAddr */
-	NULL,					/* .pfnPDumpSymbolicAddr	*/
+#if !defined(INTEGRITY_OS)
 	NULL,					/* .pfnAcquireKernelMappingData	*/
 	NULL,					/* .pfnReleaseKernelMappingData */
+#else
+	_DCPMRAcquireKernelMappingData,	/* .pfnAcquireKernelMappingData	*/
+	_DCPMRReleaseKernelMappingData,	/* .pfnReleaseKernelMappingData */
+	_DCPMRMapMemoryObject,			/* .pfnMapMemoryObject */
+	_DCPMRUnmapMemoryObject,		/* .pfnUnmapMemoryObject */
+#if defined(USING_HYPERVISOR)
+	_DCPMRGetPmr,				/* .pfnGetPmr */
+#endif
+#endif
 	_DCPMRReadBytes,			/* .pfnReadBytes */
 	NULL,					/* .pfnWriteBytes */
 	NULL,					/* .pfnUnpinMem */
@@ -759,7 +928,8 @@
 	_DCPMRFinalize				/* .pfnFinalize */
 };
 
-static PVRSRV_ERROR _DCCreatePMR(IMG_DEVMEM_LOG2ALIGN_T uiLog2PageSize,
+static PVRSRV_ERROR _DCCreatePMR(PVRSRV_DEVICE_NODE *psDevNode,
+								 IMG_DEVMEM_LOG2ALIGN_T uiLog2PageSize,
 								 IMG_UINT32 ui32PageCount,
 								 IMG_UINT32 ui32PhysHeapID,
 								 DC_BUFFER *psBuffer,
@@ -768,26 +938,23 @@
 	DC_BUFFER_PMR_DATA *psPMRPriv;
 	PHYS_HEAP *psPhysHeap;
 	IMG_DEVMEM_SIZE_T uiBufferSize;
-	IMG_HANDLE hPDumpAllocInfo;
 	PVRSRV_ERROR eError;
-	IMG_BOOL bMappingTable = IMG_TRUE;
+	IMG_UINT32 uiMappingTable = 0;
 
 	/*
 		Create the PMR for this buffer.
 
 		Note: At this stage we don't need to know the physical pages just
 		the page size and the size of the PMR. The 1st call that needs the
-		physcial pages will cause a request into the DC driver (pfnBufferQuery)
+		physical pages will cause a request into the DC driver (pfnBufferQuery)
 	*/
-	psPMRPriv = OSAllocMem(sizeof(DC_BUFFER_PMR_DATA));
+	psPMRPriv = OSAllocZMem(sizeof(DC_BUFFER_PMR_DATA));
 	if (psPMRPriv == NULL)
 	{
 		eError = PVRSRV_ERROR_OUT_OF_MEMORY;
 		goto fail_privalloc;
 	}
 
-	OSMemSet(psPMRPriv, 0, sizeof(DC_BUFFER_PMR_DATA));
-
 	/* Acquire the physical heap the memory is on */
 	eError = PhysHeapAcquire(ui32PhysHeapID, &psPhysHeap);
 	if (eError != PVRSRV_OK)
@@ -808,19 +975,20 @@
 	uiBufferSize = (1 << uiLog2PageSize) * ui32PageCount;
 
 	/* Create the PMR for the MM layer */
-	eError = PMRCreatePMR(psPhysHeap,
+	eError = PMRCreatePMR(psDevNode,
+						  psPhysHeap,
 						  uiBufferSize,
 						  uiBufferSize,
 						  1,
 						  1,
-						  &bMappingTable,
+						  &uiMappingTable,
 						  uiLog2PageSize,
 						  PVRSRV_MEMALLOCFLAG_WRITE_COMBINE,
-						  "DISPLAY",
+				          "DC_BUFFER",
 						  &sDCPMRFuncTab,
 						  psPMRPriv,
+						  PMR_TYPE_DC,
 						  ppsPMR,
-						  &hPDumpAllocInfo,
 						  IMG_TRUE);
 
 	if (eError != PVRSRV_OK)
@@ -828,10 +996,6 @@
 		goto fail_pmrcreate;
 	}
 
-#if defined(PDUMP)
-	psPMRPriv->hPDumpAllocInfo = hPDumpAllocInfo;
-	psPMRPriv->bPDumpMalloced = IMG_TRUE;
-#endif
 	return PVRSRV_OK;
 
 fail_pmrcreate:
@@ -882,39 +1046,38 @@
 	return PVRSRV_OK;
 }
 
-PVRSRV_ERROR DCDevicesEnumerate(IMG_UINT32 ui32DeviceArraySize,
+PVRSRV_ERROR DCDevicesEnumerate(CONNECTION_DATA *psConnection,
+								PVRSRV_DEVICE_NODE *psDevNode,
+								IMG_UINT32 ui32DeviceArraySize,
 								IMG_UINT32 *pui32DeviceCount,
 								IMG_UINT32 *paui32DeviceIndex)
 {
-	IMG_UINT32 i;
-	IMG_UINT32 ui32LoopCount;
-	DC_DEVICE *psTmp = g_psDCDeviceList;
+	DC_DEVICE *psTmp;
+	IMG_UINT32 ui32DeviceCount;
+
+	PVR_UNREFERENCED_PARAMETER(psConnection);
 
 	OSLockAcquire(g_hDCListLock);
 
-	if (g_ui32DCDeviceCount > ui32DeviceArraySize)
+	for (psTmp = g_psDCDeviceList, ui32DeviceCount = 0;
+		 psTmp && ui32DeviceCount < ui32DeviceArraySize;
+		 psTmp = psTmp->psNext)
 	{
-		ui32LoopCount = ui32DeviceArraySize;
-	}
-	else
-	{
-		ui32LoopCount = g_ui32DCDeviceCount;
-	}
-	
-	for (i=0;i<ui32LoopCount;i++)
-	{
-		PVR_ASSERT(psTmp != NULL);
-		paui32DeviceIndex[i] = psTmp->ui32Index;
-		psTmp = psTmp->psNext;
+		if (psTmp->psDevNode == psDevNode)
+		{
+			paui32DeviceIndex[ui32DeviceCount++] = psTmp->ui32Index;
+		}
 	}
 
-	*pui32DeviceCount = ui32LoopCount;
+	*pui32DeviceCount = ui32DeviceCount;
 	OSLockRelease(g_hDCListLock);
 
 	return PVRSRV_OK;
 }
 
-PVRSRV_ERROR DCDeviceAcquire(IMG_UINT32 ui32DeviceIndex,
+PVRSRV_ERROR DCDeviceAcquire(CONNECTION_DATA *psConnection,
+							 PVRSRV_DEVICE_NODE *psDevNode,
+							 IMG_UINT32 ui32DeviceIndex,
 							 DC_DEVICE **ppsDevice)
 {
 	DC_DEVICE *psDevice = g_psDCDeviceList;
@@ -927,7 +1090,7 @@
 	while(psDevice->ui32Index != ui32DeviceIndex)
 	{
 		psDevice = psDevice->psNext;
-		if (psDevice == NULL)
+		if (psDevice == NULL || psDevice->psDevNode != psDevNode)
 		{
 			return PVRSRV_ERROR_NO_DC_DEVICES_FOUND;
 		}
@@ -1066,15 +1229,13 @@
 		goto fail_nopfn;
 	}
 
-	psNew = OSAllocMem(sizeof(DC_BUFFER));
+	psNew = OSAllocZMem(sizeof(DC_BUFFER));
 	if (psNew == NULL)
 	{
 		eError = PVRSRV_ERROR_OUT_OF_MEMORY;
 		goto fail_alloc;
 	}
 
-	OSMemSet(psNew, 0, sizeof(DC_BUFFER));
-
 	eError = OSLockCreate(&psNew->hLock, LOCK_TYPE_NONE);
 	if (eError != PVRSRV_OK)
 	{
@@ -1127,7 +1288,8 @@
 			PMRUnrefPMR(psDevice->psSystemBufferPMR);
 		}
 
-		eError = _DCCreatePMR(uiLog2PageSize,
+		eError = _DCCreatePMR(psDevice->psDevNode,
+							  uiLog2PageSize,
 							  ui32PageCount,
 							  ui32PhysHeapID,
 							  psNew,
@@ -1288,6 +1450,7 @@
 
 	/* Register our debug request notify callback */
 	eError = PVRSRVRegisterDbgRequestNotify(&psDisplayContext->hDebugNotify,
+											psDevice->psDevNode,
 											_DCDebugRequest,
 											DEBUG_REQUEST_DC,
 											psDisplayContext);
@@ -1409,15 +1572,15 @@
 	 * Calling SCPRun first, ensures that any call to SCPRun from the MISR
 	 * context completes before we insert any NULL flush direct to the DC.
 	 * SCPRun returns PVRSRV_OK (0) if the run command (Configure) executes OR there
-	 * is no work to do OR it consumes a padding command.
+	 * is no work to be done OR it consumes a padding command.
 	 * By counting a "good" SCPRun for each of the ui32NumConfigsInSCP we ensure
 	 * that all Configs currently in the SCP are flushed to the DC.
 	 *
 	 * In the case where we fail dependencies (PVRSRV_ERROR_FAILED_DEPENDENCIES (15))
 	 * but there are outstanding ui32ConfigsInFlight that may satisfy them,
 	 * we just loop and try again.
-	 * In the case where there is still work to do but the DC is full
-	 * (PVRSRV_ERROR_NOT_READY (254)) we just loop and try again
+	 * In the case where there is still more work but the DC is full
+	 * (PVRSRV_ERROR_NOT_READY (254)), we just loop and try again.
 	 *
 	 * During a flush, NULL flips may be inserted if waiting for the 3D (not
 	 * actually deadlocked), but this should be benign
@@ -1596,8 +1759,8 @@
 				goto FailMapBuffer;
 			}
 			ui32BuffersMapped++;
-		}
-	}
+		}    
+    }
 
 	ui32CmdRdySize = sizeof(DC_CMD_RDY_DATA) +  
 					 ((sizeof(IMG_HANDLE) + sizeof(PVRSRV_SURFACE_CONFIG_INFO))
@@ -1639,7 +1802,7 @@
 	{
 		psReadyData->pasSurfAttrib = (PVRSRV_SURFACE_CONFIG_INFO *)pui8ReadyData;
 		ui32CopySize = sizeof(PVRSRV_SURFACE_CONFIG_INFO) * ui32PipeCount;
-		OSMemCopy(psReadyData->pasSurfAttrib, pasSurfAttrib, ui32CopySize);
+		OSCachedMemCopy(psReadyData->pasSurfAttrib, pasSurfAttrib, ui32CopySize);
 		pui8ReadyData = pui8ReadyData + ui32CopySize;
 	}
 	else
@@ -1652,7 +1815,7 @@
 	{
 		psReadyData->pahBuffer = (IMG_HANDLE)pui8ReadyData;
 		ui32CopySize = sizeof(IMG_HANDLE) * ui32PipeCount;
-		OSMemCopy(psReadyData->pahBuffer, ahBuffers, ui32CopySize);
+		OSCachedMemCopy(psReadyData->pahBuffer, ahBuffers, ui32CopySize);
 	}
 	else
 	{
@@ -1788,12 +1951,11 @@
 	IMG_UINT32 ui32PageCount;
 	IMG_UINT32 ui32PhysHeapID;
 
-	psNew = OSAllocMem(sizeof(DC_BUFFER));
+	psNew = OSAllocZMem(sizeof(DC_BUFFER));
 	if (psNew == NULL)
 	{
 		return PVRSRV_ERROR_OUT_OF_MEMORY;
 	}
-	OSMemSet(psNew, 0, sizeof(DC_BUFFER));
 
 	eError = OSLockCreate(&psNew->hLock, LOCK_TYPE_NONE);
 	if (eError != PVRSRV_OK)
@@ -1828,7 +1990,8 @@
 	psNew->ui32MapCount = 0;
 	psNew->ui32RefCount = 1;
 
-	eError = _DCCreatePMR(uiLog2PageSize,
+	eError = _DCCreatePMR(psDevice->psDevNode,
+						  uiLog2PageSize,
 						  ui32PageCount,
 						  ui32PhysHeapID,
 						  psNew,
@@ -1914,13 +2077,12 @@
 		goto FailEarlyError;
 	}
 
-	psNew = OSAllocMem(sizeof(DC_BUFFER));
+	psNew = OSAllocZMem(sizeof(DC_BUFFER));
 	if (psNew == NULL)
 	{
 		eError = PVRSRV_ERROR_OUT_OF_MEMORY;
 		goto FailEarlyError;
 	}
-	OSMemSet(psNew, 0, sizeof(DC_BUFFER));
 
 	eError = OSLockCreate(&psNew->hLock, LOCK_TYPE_NONE);
 	if (eError != PVRSRV_OK)
@@ -2037,9 +2199,15 @@
 							  IMG_HANDLE hDeviceData,
 							  IMG_HANDLE *phSrvHandle)
 {
+	PVRSRV_DATA *psPVRSRVData = PVRSRVGetPVRSRVData();
 	DC_DEVICE *psNew;
 	PVRSRV_ERROR eError;
 
+	if (!psPVRSRVData || !psPVRSRVData->psDeviceNodeList)
+	{
+		return PVRSRV_ERROR_RETRY;
+	}
+
 	psNew = OSAllocMem(sizeof(DC_DEVICE));
 	if (psNew == NULL)
 	{
@@ -2053,11 +2221,12 @@
 		goto FailLockCreate;
 	}
 
+	/* Associate display devices to the first device node */
+	psNew->psDevNode = psPVRSRVData->psDeviceNodeList;
 	psNew->psFuncTable = psFuncTable;
 	psNew->ui32MaxConfigsInFlight = ui32MaxConfigsInFlight;
 	psNew->hDeviceData = hDeviceData;
 	psNew->ui32RefCount = 1;
-	psNew->hSystemBuffer = NULL;
 	psNew->ui32Index = g_ui32DCNextIndex++;
 	eError = OSEventObjectCreate("DC_EVENT_OBJ", &psNew->psEventList);
 	if (eError != PVRSRV_OK)
@@ -2069,7 +2238,7 @@
 	psNew->hSystemBuffer = NULL;
 	psNew->psSystemBufferPMR = NULL;
 	psNew->sSystemContext.psDevice = psNew;
-	psNew->sSystemContext.hDisplayContext = hDeviceData;
+	psNew->sSystemContext.hDisplayContext = hDeviceData;	/* FIXME: Is this the correct thing to do? */
 
 	OSLockAcquire(g_hDCListLock);
 	psNew->psNext = g_psDCDeviceList;
@@ -2104,9 +2273,7 @@
 	*/
 	if (psDevice->psSystemBufferPMR)
 	{
-		PMRLock();
 		PMRUnrefPMR(psDevice->psSystemBufferPMR);
-		PMRUnlock();
 	}
 
 	/*
@@ -2210,8 +2377,11 @@
 		to ensure that we're not the last to hold the reference as
 		we can't destroy the display context from the MISR which we
 		can be called from.
+		 
+		Ignore any fence checks if doing a null flip (e.g. when trying to unblock
+		stalled applications).
 	*/
-	SCPCommandComplete(psDisplayContext->psSCPContext);
+	SCPCommandComplete(psDisplayContext->psSCPContext, psData->bDirectNullFlip);
 
 	/* Notify devices (including ourself) in case some item has been unblocked */
 	PVRSRVCheckStatus(NULL);
@@ -2268,7 +2438,7 @@
 	}
 
 	/* Lock the pages */
-	eError = PMRLockSysPhysAddresses(psPMR, uiLog2PageSize);
+	eError = PMRLockSysPhysAddresses(psPMR);
 	if (eError != PVRSRV_OK)
 	{
 		goto e2;
@@ -2317,6 +2487,51 @@
 	OSFreeMem(pasDevPAddr);
 }
 
+#if defined(INTEGRITY_OS)
+IMG_HANDLE DCDisplayContextGetHandle(DC_DISPLAY_CONTEXT *psDisplayContext)
+{
+	PVR_ASSERT(psDisplayContext);
+	return psDisplayContext->hDisplayContext;
+}
+
+IMG_UINT32 DCDeviceGetIndex(IMG_HANDLE hDeviceData)
+{
+	DC_DEVICE *psDevice = g_psDCDeviceList;
+	IMG_UINT32 ui32Index = 0;
+
+	while (psDevice != NULL)
+	{
+		if (psDevice->hDeviceData == hDeviceData)
+		{
+			ui32Index = psDevice->ui32Index;
+			break;
+		}
+		psDevice = psDevice->psNext;
+	}
+
+	return ui32Index;
+}
+
+IMG_HANDLE DCDeviceGetDeviceAtIndex(IMG_UINT32 ui32DeviceIndex)
+{
+	IMG_HANDLE hDeviceData = NULL;
+	DC_DEVICE *psDevice = g_psDCDeviceList;
+
+	while (psDevice != NULL)
+	{
+		if (psDevice->ui32Index == ui32DeviceIndex)
+		{
+			hDeviceData = psDevice->hDeviceData;
+			break;
+		}
+		psDevice = psDevice->psNext;
+	}
+
+	return hDeviceData;
+}
+
+#endif
+
 /*****************************************************************************
  *                Public interface functions for services                    *
  *****************************************************************************/
@@ -2341,3 +2556,5 @@
 
 	return PVRSRV_OK;
 }
+
+
diff --git a/drivers/staging/imgtec/rogue/dc_server.h b/drivers/staging/imgtec/rogue/dc_server.h
index 4d9892c..f27b33c 100644
--- a/drivers/staging/imgtec/rogue/dc_server.h
+++ b/drivers/staging/imgtec/rogue/dc_server.h
@@ -44,7 +44,7 @@
 
 #include "img_types.h"
 #include "pvrsrv_error.h"
-#include "sync_external.h"
+#include <powervr/sync_external.h>
 #include "pvrsrv_surface.h"
 #include "pmr.h"
 #include "kerneldisplay.h"
@@ -57,11 +57,15 @@
 
 PVRSRV_ERROR DCDevicesQueryCount(IMG_UINT32 *pui32DeviceCount);
 
-PVRSRV_ERROR DCDevicesEnumerate(IMG_UINT32 ui32DeviceArraySize,
+PVRSRV_ERROR DCDevicesEnumerate(CONNECTION_DATA *psConnection,
+								PVRSRV_DEVICE_NODE *psDevNode,
+								IMG_UINT32 ui32DeviceArraySize,
 								IMG_UINT32 *pui32DeviceCount,
 								IMG_UINT32 *paui32DeviceIndex);
 
-PVRSRV_ERROR DCDeviceAcquire(IMG_UINT32 ui32DeviceIndex,
+PVRSRV_ERROR DCDeviceAcquire(CONNECTION_DATA *psConnection,
+							 PVRSRV_DEVICE_NODE *psDevNode,
+							 IMG_UINT32 ui32DeviceIndex,
 							 DC_DEVICE **ppsDevice);
 
 PVRSRV_ERROR DCDeviceRelease(DC_DEVICE *psDevice);
@@ -153,4 +157,16 @@
 PVRSRV_ERROR DCInit(void);
 PVRSRV_ERROR DCDeInit(void);
 
+#if defined(INTEGRITY_OS)
+IMG_HANDLE DCDisplayContextGetHandle(DC_DISPLAY_CONTEXT *psDisplayContext);
+IMG_UINT32 DCDeviceGetIndex(IMG_HANDLE hDevice);
+IMG_HANDLE DCDeviceGetDeviceAtIndex(IMG_UINT32 ui32DeviceIndex);
+#endif
+
+#if defined(SUPPORT_DRM_EXT)
+/* FIXME: Temporary workaround. Awaiting buildpkg refresh. */
+#define OSMemCopy(a,b,c) memcpy(a,b,c)
+#endif
+
 #endif /*_DC_SERVER_H_  */
+
diff --git a/drivers/staging/imgtec/rogue/debugmisc_server.c b/drivers/staging/imgtec/rogue/debugmisc_server.c
index c1e54d8..aa71482 100644
--- a/drivers/staging/imgtec/rogue/debugmisc_server.c
+++ b/drivers/staging/imgtec/rogue/debugmisc_server.c
@@ -72,7 +72,8 @@
 	                            RGXFWIF_DM_GP,
 	                            &sSLCBPCtlCmd,
 	                            sizeof(sSLCBPCtlCmd),
-	                            IMG_TRUE);
+	                            0,
+	                            PDUMP_FLAGS_CONTINUOUS);
 	if(eError != PVRSRV_OK)
 	{
 		PVR_DPF((PVR_DBG_ERROR, "PVRSRVDebugMiscSLCSetEnableStateKM: RGXScheduleCommandfailed. Error:%u", eError));
@@ -80,7 +81,7 @@
 	else
 	{
 		/* Wait for the SLC flush to complete */
-		eError = RGXWaitForFWOp(psDeviceNode->pvDevice, RGXFWIF_DM_GP, psDeviceNode->psSyncPrim, IMG_TRUE);
+		eError = RGXWaitForFWOp(psDeviceNode->pvDevice, RGXFWIF_DM_GP, psDeviceNode->psSyncPrim, PDUMP_FLAGS_CONTINUOUS);
 		if (eError != PVRSRV_OK)
 		{
 			PVR_DPF((PVR_DBG_ERROR,"PVRSRVDebugMiscSLCSetEnableStateKM: Waiting for value aborted with error (%u)", eError));
@@ -91,9 +92,43 @@
 }
 
 IMG_EXPORT PVRSRV_ERROR
+PVRSRVRGXDebugMiscQueryFWLogKM(
+	const CONNECTION_DATA *psConnection,
+	const PVRSRV_DEVICE_NODE *psDeviceNode,
+	IMG_UINT32 *pui32RGXFWLogType)
+{
+	PVRSRV_RGXDEV_INFO *psDevInfo;
+
+	PVR_UNREFERENCED_PARAMETER(psConnection);
+
+#if defined(PVRSRV_GPUVIRT_GUESTDRV)
+	/* Guest drivers do not support tracebuf */
+	PVR_UNREFERENCED_PARAMETER(psDevInfo);
+	PVR_UNREFERENCED_PARAMETER(pui32RGXFWLogType);
+	return PVRSRV_ERROR_NOT_IMPLEMENTED;
+#else
+	if (!psDeviceNode || !pui32RGXFWLogType)
+	{
+		return PVRSRV_ERROR_INVALID_PARAMS;
+	}
+
+	psDevInfo = psDeviceNode->pvDevice;
+
+	if (!psDevInfo || !psDevInfo->psRGXFWIfTraceBuf)
+	{
+		return PVRSRV_ERROR_INVALID_PARAMS;
+	}
+
+	*pui32RGXFWLogType = psDevInfo->psRGXFWIfTraceBuf->ui32LogType;
+	return PVRSRV_OK;
+#endif
+}
+
+
+IMG_EXPORT PVRSRV_ERROR
 PVRSRVRGXDebugMiscSetFWLogKM(
-	CONNECTION_DATA * psConnection,
-	PVRSRV_DEVICE_NODE *psDeviceNode,
+	const CONNECTION_DATA * psConnection,
+	const PVRSRV_DEVICE_NODE *psDeviceNode,
 	IMG_UINT32  ui32RGXFWLogType)
 {
 	RGXFWIF_KCCB_CMD sLogTypeUpdateCmd;
@@ -129,7 +164,8 @@
 	                            RGXFWIF_DM_GP,
 	                            &sLogTypeUpdateCmd,
 	                            sizeof(sLogTypeUpdateCmd),
-	                            IMG_TRUE);
+	                            0,
+	                            PDUMP_FLAGS_CONTINUOUS);
 	if(eError != PVRSRV_OK)
 	{
 		PVR_DPF((PVR_DBG_ERROR, "%s: RGXScheduleCommandfailed. Error:%u", __FUNCTION__, eError));
@@ -137,7 +173,7 @@
 	else
 	{
 		/* Wait for the LogType value to be updated */
-		eError = RGXWaitForFWOp(psDevInfo, RGXFWIF_DM_GP, psDeviceNode->psSyncPrim, IMG_TRUE);
+		eError = RGXWaitForFWOp(psDevInfo, RGXFWIF_DM_GP, psDeviceNode->psSyncPrim, PDUMP_FLAGS_CONTINUOUS);
 		if (eError != PVRSRV_OK)
 		{
 			PVR_DPF((PVR_DBG_ERROR,"%s: Waiting for value aborted with error (%u)", __FUNCTION__, eError));
@@ -149,8 +185,51 @@
 }
 
 IMG_EXPORT PVRSRV_ERROR
+PVRSRVRGXDebugMiscSetHCSDeadlineKM(
+	CONNECTION_DATA *psConnection,
+	PVRSRV_DEVICE_NODE *psDeviceNode,
+	IMG_UINT32  ui32HCSDeadlineMS)
+{
+	PVRSRV_RGXDEV_INFO* psDevInfo = psDeviceNode->pvDevice;
+	PVR_UNREFERENCED_PARAMETER(psConnection);
+	
+	return RGXFWSetHCSDeadline(psDevInfo, ui32HCSDeadlineMS);
+}
+
+IMG_EXPORT PVRSRV_ERROR
+PVRSRVRGXDebugMiscSetOSidPriorityKM(
+	CONNECTION_DATA *psConnection,
+	PVRSRV_DEVICE_NODE *psDeviceNode,
+	IMG_UINT32  ui32OSid,
+	IMG_UINT32  ui32OSidPriority)
+{
+	PVRSRV_RGXDEV_INFO* psDevInfo = psDeviceNode->pvDevice;
+	PVR_UNREFERENCED_PARAMETER(psConnection);
+
+	return RGXFWChangeOSidPriority(psDevInfo, ui32OSid, ui32OSidPriority);
+}
+
+IMG_EXPORT PVRSRV_ERROR
+PVRSRVRGXDebugMiscSetOSNewOnlineStateKM(
+	CONNECTION_DATA *psConnection,
+	PVRSRV_DEVICE_NODE *psDeviceNode,
+	IMG_UINT32  ui32OSid,
+	IMG_UINT32  ui32OSNewState)
+{
+	PVRSRV_RGXDEV_INFO* psDevInfo = psDeviceNode->pvDevice;
+	PVR_UNREFERENCED_PARAMETER(psConnection);
+
+	if (ui32OSNewState)
+	{
+		return RGXFWSetVMOnlineState(psDevInfo, ui32OSid, RGXFWIF_OS_ONLINE);
+	}
+
+	return RGXFWSetVMOnlineState(psDevInfo, ui32OSid, RGXFWIF_OS_OFFLINE);
+}
+
+IMG_EXPORT PVRSRV_ERROR
 PVRSRVRGXDebugMiscDumpFreelistPageListKM(
-	CONNECTION_DATA * psConnection,	
+	CONNECTION_DATA * psConnection,
 	PVRSRV_DEVICE_NODE *psDeviceNode)
 {
 	PVRSRV_RGXDEV_INFO* psDevInfo = psDeviceNode->pvDevice;
diff --git a/drivers/staging/imgtec/rogue/debugmisc_server.h b/drivers/staging/imgtec/rogue/debugmisc_server.h
index 0ab835a..af20f3f 100644
--- a/drivers/staging/imgtec/rogue/debugmisc_server.h
+++ b/drivers/staging/imgtec/rogue/debugmisc_server.h
@@ -69,10 +69,36 @@
 	IMG_UINT64 ui64FWSigLen);
 
 IMG_EXPORT PVRSRV_ERROR
+PVRSRVRGXDebugMiscQueryFWLogKM(
+	const CONNECTION_DATA *psConnection,
+	const PVRSRV_DEVICE_NODE *psDeviceNode,
+	IMG_UINT32 *pui32RGXFWLogType);
+
+IMG_EXPORT PVRSRV_ERROR
 PVRSRVRGXDebugMiscSetFWLogKM(
+	const CONNECTION_DATA *psConnection,
+	const PVRSRV_DEVICE_NODE *psDeviceNode,
+	IMG_UINT32  ui32RGXFWLogType);
+
+IMG_EXPORT PVRSRV_ERROR
+PVRSRVRGXDebugMiscSetHCSDeadlineKM(
 	CONNECTION_DATA *psConnection,
 	PVRSRV_DEVICE_NODE *psDeviceNode,
-	IMG_UINT32  ui32RGXFWLogType);
+	IMG_UINT32  ui32HCSDeadlineMS);
+
+IMG_EXPORT PVRSRV_ERROR
+PVRSRVRGXDebugMiscSetOSidPriorityKM(
+	CONNECTION_DATA *psConnection,
+	PVRSRV_DEVICE_NODE *psDeviceNode,
+	IMG_UINT32  ui32OSid,
+	IMG_UINT32  ui32OSidPriority);
+
+IMG_EXPORT PVRSRV_ERROR
+PVRSRVRGXDebugMiscSetOSNewOnlineStateKM(
+	CONNECTION_DATA *psConnection,
+	PVRSRV_DEVICE_NODE *psDeviceNode,
+	IMG_UINT32  ui32OSid,
+	IMG_UINT32  ui32OSNewState);
 
 IMG_EXPORT PVRSRV_ERROR
 PVRSRVRGXDebugMiscDumpFreelistPageListKM(
diff --git a/drivers/staging/imgtec/rogue/device.h b/drivers/staging/imgtec/rogue/device.h
index 0c91f25..854cf6b 100644
--- a/drivers/staging/imgtec/rogue/device.h
+++ b/drivers/staging/imgtec/rogue/device.h
@@ -50,11 +50,11 @@
 #include "ra.h"  		/* RA_ARENA */
 #include "pvrsrv_device.h"
 #include "srvkm.h"
-#include "devicemem.h"
 #include "physheap.h"
-#include "sync.h"
+#include <powervr/sync_external.h>
+#include "sysinfo.h"
 #include "dllist.h"
-#include "cache_external.h"
+#include "cache_km.h"
 
 #include "lock.h"
 
@@ -62,8 +62,15 @@
 #include "virt_validation_defs.h"
 #endif
 
-/* BM context forward reference */
-typedef struct _BM_CONTEXT_ BM_CONTEXT;
+#if defined(SUPPORT_BUFFER_SYNC)
+struct pvr_buffer_sync_context;
+#endif
+
+typedef struct _PVRSRV_POWER_DEV_TAG_ PVRSRV_POWER_DEV;
+
+#if defined(PVRSRV_ENABLE_FULL_SYNC_TRACKING)
+struct SYNC_RECORD;
+#endif
 
 /*********************************************************************/ /*!
  @Function      AllocUFOCallback
@@ -97,27 +104,18 @@
 typedef void (*FreeUFOBlockCallback)(struct _PVRSRV_DEVICE_NODE_ *psDeviceNode,
 									 DEVMEM_MEMDESC *psMemDesc);
 
+typedef struct _PVRSRV_DEVICE_IDENTIFIER_
+{
+	/* Pdump memory and register bank names */
+	IMG_CHAR				*pszPDumpDevName;
+	IMG_CHAR				*pszPDumpRegName;
+} PVRSRV_DEVICE_IDENTIFIER;
 
 typedef struct _DEVICE_MEMORY_INFO_
 {
-	/* size of address space, as log2 */
-	IMG_UINT32				ui32AddressSpaceSizeLog2;
-
-	/* 
-		flags, includes physical memory resource types available to the system.  
-		Allows for validation at heap creation, define PVRSRV_BACKINGSTORE_XXX 
-	*/
-	IMG_UINT32				ui32Flags;
-
 	/* heap count.  Doesn't include additional heaps from PVRSRVCreateDeviceMemHeap */
 	IMG_UINT32				ui32HeapCount;
 
-	/* BM kernel context for the device */
-    BM_CONTEXT				*pBMKernelContext;
-
-	/* BM context list for the device*/
-    BM_CONTEXT				*pBMContext;
-
     /* Blueprints for creating new device memory contexts */
     IMG_UINT32              uiNumHeapConfigs;
     DEVMEM_HEAP_CONFIG      *psDeviceMemoryHeapConfigArray;
@@ -158,6 +156,7 @@
 	PVRSRV_DEVICE_STATE_INIT,
 	PVRSRV_DEVICE_STATE_ACTIVE,
 	PVRSRV_DEVICE_STATE_DEINIT,
+	PVRSRV_DEVICE_STATE_BAD,
 } PVRSRV_DEVICE_STATE;
 
 typedef enum _PVRSRV_DEVICE_HEALTH_STATUS_
@@ -185,20 +184,29 @@
 										IMG_UINT32 *pui32MappingTable,
 										IMG_UINT32 uiLog2PageSize,
 										PVRSRV_MEMALLOCFLAGS_T uiFlags,
+										const IMG_CHAR *pszAnnotation,
 										PMR **ppsPMRPtr);
+
 typedef struct _PVRSRV_DEVICE_NODE_
 {
 	PVRSRV_DEVICE_IDENTIFIER	sDevId;
 
 	PVRSRV_DEVICE_STATE			eDevState;
-	PVRSRV_DEVICE_HEALTH_STATUS eHealthStatus;
-	PVRSRV_DEVICE_HEALTH_REASON eHealthReason;
+	ATOMIC_T					eHealthStatus; /* Holds values from PVRSRV_DEVICE_HEALTH_STATUS */
+	ATOMIC_T					eHealthReason; /* Holds values from PVRSRV_DEVICE_HEALTH_REASON */
+
+	IMG_HANDLE						*hDebugTable;
 
 	/* device specific MMU attributes */
    	MMU_DEVICEATTRIBS      *psMMUDevAttrs;
 	/* device specific MMU firmware atrributes, used only in some devices*/
 	MMU_DEVICEATTRIBS      *psFirmwareMMUDevAttrs;
 
+	/* lock for power state transitions */
+	POS_LOCK				hPowerLock;
+	/* current system device power state */
+	PVRSRV_SYS_POWER_STATE	eCurrentSysPowerState;
+	PVRSRV_POWER_DEV		*psPowerDev;
 
 	/*
 		callbacks the device must support:
@@ -218,20 +226,24 @@
 	void (*pfnDevPxUnMap)(struct _PVRSRV_DEVICE_NODE_ *psDevNode,
 						  PG_HANDLE *psMemHandle, void *pvPtr);
 
-	PVRSRV_ERROR (*pfnDevPxClean)(PG_HANDLE *pshMemHandle,
+	PVRSRV_ERROR (*pfnDevPxClean)(struct _PVRSRV_DEVICE_NODE_ *psDevNode,
+								PG_HANDLE *pshMemHandle,
 								IMG_UINT32 uiOffset,
 								IMG_UINT32 uiLength);
 
 	IMG_UINT32 uiMMUPxLog2AllocGran;
-	IMG_CHAR				*pszMMUPxPDumpMemSpaceName;
 
 	void (*pfnMMUCacheInvalidate)(struct _PVRSRV_DEVICE_NODE_ *psDevNode,
 								  IMG_HANDLE hDeviceData,
 								  MMU_LEVEL eLevel,
 								  IMG_BOOL bUnmap);
 
-	PVRSRV_ERROR (*pfnSLCCacheInvalidateRequest)(struct _PVRSRV_DEVICE_NODE_ *psDevNode,
-										PMR *psPmr);
+	PVRSRV_ERROR (*pfnMMUCacheInvalidateKick)(struct _PVRSRV_DEVICE_NODE_ *psDevNode,
+	                                          IMG_UINT32 *pui32NextMMUInvalidateUpdate,
+	                                          IMG_BOOL bInterrupt);
+
+	IMG_UINT32 (*pfnMMUCacheGetInvalidateCounter)(struct _PVRSRV_DEVICE_NODE_ *psDevNode);
+
 
 	void (*pfnDumpDebugInfo)(struct _PVRSRV_DEVICE_NODE_ *psDevNode);
 
@@ -249,30 +261,49 @@
 
 	PVRSRV_ERROR (*pfnSoftReset)(struct _PVRSRV_DEVICE_NODE_ *psDevNode, IMG_UINT64 ui64ResetValue1, IMG_UINT64 ui64ResetValue2);
 
+#if defined(SUPPORT_KERNEL_SRVINIT) && defined(RGXFW_ALIGNCHECKS)
+	PVRSRV_ERROR (*pfnAlignmentCheck)(struct _PVRSRV_DEVICE_NODE_ *psDevNode, IMG_UINT32 ui32FWAlignChecksSize, IMG_UINT32 aui32FWAlignChecks[]);
+#endif
+	IMG_BOOL	(*pfnCheckDeviceFeature)(struct _PVRSRV_DEVICE_NODE_ *psDevNode, IMG_UINT64 ui64FeatureMask);
+
+	IMG_INT32	(*pfnGetDeviceFeatureValue)(struct _PVRSRV_DEVICE_NODE_ *psDevNode, IMG_UINT64 ui64FeatureMask);
+
 	PVRSRV_DEVICE_CONFIG	*psDevConfig;
 
 	/* device post-finalise compatibility check */
-	PVRSRV_ERROR			(*pfnInitDeviceCompatCheck) (struct _PVRSRV_DEVICE_NODE_*,IMG_UINT32 ui32ClientBuildOptions);
+	PVRSRV_ERROR			(*pfnInitDeviceCompatCheck) (struct _PVRSRV_DEVICE_NODE_*);
 
 	/* information about the device's address space and heaps */
 	DEVICE_MEMORY_INFO		sDevMemoryInfo;
 
+	/* device's shared-virtual-memory heap max virtual address */
+	IMG_UINT64				ui64GeneralSVMHeapTopVA;
+
 	/* private device information */
 	void					*pvDevice;
 
-	IMG_CHAR				szRAName[50];
+
 
 #if defined(SUPPORT_GPUVIRT_VALIDATION)
 	RA_ARENA                *psOSidSubArena[GPUVIRT_VALIDATION_NUM_OS];
 #endif
 
-	RA_ARENA				*psLocalDevMemArena;
+
+#define PVRSRV_MAX_RA_NAME_LENGTH (50)
+	RA_ARENA				**apsLocalDevMemArenas;
+	IMG_CHAR				**apszRANames;
+	IMG_UINT32				ui32NumOfLocalMemArenas;
+
 #if defined(SUPPORT_PVRSRV_GPUVIRT)
-	IMG_CHAR				szKernelFwRAName[RGXFW_NUM_OS][50];
+	IMG_CHAR				szKernelFwRAName[RGXFW_NUM_OS][PVRSRV_MAX_RA_NAME_LENGTH];
 	RA_ARENA				*psKernelFwMemArena[RGXFW_NUM_OS];
 	IMG_UINT32				uiKernelFwRAIdx;
+	RA_BASE_T				ui64RABase[RGXFW_NUM_OS];
 #endif
 
+	IMG_UINT32				ui32RegisteredPhysHeaps;
+	PHYS_HEAP				**papsRegisteredPhysHeaps;
+
 	/*
 	 * Pointers to the device's physical memory heap(s)
 	 * The first entry (apsPhysHeap[PVRSRV_DEVICE_PHYS_HEAP_GPU_LOCAL]) will be used for allocations
@@ -299,17 +330,43 @@
 														IMG_HANDLE					*hPrivData);
 	void					(*pfnUnregisterMemoryContext)(IMG_HANDLE hPrivData);
 
-	/* Funtions for allocation/freeing of UFOs */
+	/* Functions for allocation/freeing of UFOs */
 	AllocUFOBlockCallback	pfnAllocUFOBlock;	/*!< Callback for allocation of a block of UFO memory */
 	FreeUFOBlockCallback	pfnFreeUFOBlock;	/*!< Callback for freeing of a block of UFO memory */
 
+#if defined(SUPPORT_BUFFER_SYNC)
+	struct pvr_buffer_sync_context *psBufferSyncContext;
+#endif
+
+	IMG_HANDLE				hSyncServerNotify;
+	POS_LOCK				hSyncServerListLock;
+	DLLIST_NODE				sSyncServerSyncsList;
+
+#if defined(PVRSRV_ENABLE_FULL_SYNC_TRACKING)
+	IMG_HANDLE				hSyncServerRecordNotify;
+	POS_LOCK				hSyncServerRecordLock;
+	DLLIST_NODE				sSyncServerRecordList;
+	struct SYNC_RECORD		*apsSyncServerRecordsFreed[PVRSRV_FULL_SYNC_TRACKING_HISTORY_LEN];
+	IMG_UINT32				uiSyncServerRecordFreeIdx;
+#endif
+
 	PSYNC_PRIM_CONTEXT		hSyncPrimContext;
 
-	PVRSRV_CLIENT_SYNC_PRIM *psSyncPrim;
+	PVRSRV_CLIENT_SYNC_PRIM	*psSyncPrim;
+	/* With this sync-prim we make sure the MMU cache is flushed
+	 * before we free the page table memory */
+	PVRSRV_CLIENT_SYNC_PRIM	*psMMUCacheSyncPrim;
+	IMG_UINT32				ui32NextMMUInvalidateUpdate;
 
 	IMG_HANDLE				hCmdCompNotify;
 	IMG_HANDLE				hDbgReqNotify;
+	IMG_HANDLE				hHtbDbgReqNotify;
+	IMG_HANDLE				hAppHintDbgReqNotify;
+
 	PVRSRV_DUMMY_PAGE		sDummyPage;
+
+	DLLIST_NODE				sMemoryContextPageFaultNotifyListHead;
+
 #if defined(PDUMP)
 	/* 	device-level callback which is called when pdump.exe starts.
 	 *	Should be implemented in device-specific init code, e.g. rgxinit.c
@@ -320,11 +377,12 @@
 #endif
 } PVRSRV_DEVICE_NODE;
 
-PVRSRV_ERROR IMG_CALLCONV PVRSRVFinaliseSystem(IMG_BOOL bInitSuccesful,
-														IMG_UINT32 ui32ClientBuildOptions);
+PVRSRV_ERROR IMG_CALLCONV PVRSRVDeviceFinalise(PVRSRV_DEVICE_NODE *psDeviceNode,
+											   IMG_BOOL bInitSuccessful);
 
-PVRSRV_ERROR IMG_CALLCONV PVRSRVDevInitCompatCheck(PVRSRV_DEVICE_NODE *psDeviceNode,
-														IMG_UINT32 ui32ClientBuildOptions);
+PVRSRV_ERROR IMG_CALLCONV PVRSRVDevInitCompatCheck(PVRSRV_DEVICE_NODE *psDeviceNode);
+
+PVRSRV_ERROR IMG_CALLCONV RGXClientConnectCompatCheck_ClientAgainstFW(PVRSRV_DEVICE_NODE * psDeviceNode, IMG_UINT32 ui32ClientBuildOptions);
 
 	
 #endif /* __DEVICE_H__ */
diff --git a/drivers/staging/imgtec/rogue/device_connection.h b/drivers/staging/imgtec/rogue/device_connection.h
index 3f000a4..715833b 100644
--- a/drivers/staging/imgtec/rogue/device_connection.h
+++ b/drivers/staging/imgtec/rogue/device_connection.h
@@ -41,16 +41,35 @@
 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */ /**************************************************************************/
 
-#if defined(__KERNEL__)
-#include "device.h"
-#endif
+#if !defined(__DEVICE_CONNECTION_H__)
+#define __DEVICE_CONNECTION_H__
+
+#include "img_types.h"
 
 #if defined(__KERNEL__)
-typedef struct _PVRSRV_DEVICE_NODE_* SHARED_DEV_CONNECTION;
+typedef struct _PVRSRV_DEVICE_NODE_ *SHARED_DEV_CONNECTION;
 #else
 typedef IMG_HANDLE SHARED_DEV_CONNECTION;
 #endif
 
-/**************************************************************************//**
-End of file (device_connection.h)
-******************************************************************************/
+/******************************************************************************
+ * Device capability flags and masks
+ *****************************************************************************/
+
+/* Flag to be passed over the bridge during connection stating whether CPU cache coherent is available*/
+#define PVRSRV_CACHE_COHERENT_SHIFT (0)
+#define	PVRSRV_CACHE_COHERENT_DEVICE_FLAG (1U << PVRSRV_CACHE_COHERENT_SHIFT)
+#define	PVRSRV_CACHE_COHERENT_CPU_FLAG (2U << PVRSRV_CACHE_COHERENT_SHIFT)
+#define PVRSRV_CACHE_COHERENT_MASK (3U << PVRSRV_CACHE_COHERENT_SHIFT)
+
+/* Flag to be passed over the bridge during connection stating whether CPU non-mappable memory is present */
+#define PVRSRV_NONMAPPABLE_MEMORY_PRESENT_SHIFT (3)
+#define PVRSRV_NONMAPPABLE_MEMORY_PRESENT_FLAG (1U << PVRSRV_NONMAPPABLE_MEMORY_PRESENT_SHIFT)
+
+/* Flag to be passed over the bridge during connection stating SVM allocation availability */
+#define PVRSRV_DEVMEM_SVM_ALLOC_SHIFT (4)
+#define PVRSRV_DEVMEM_SVM_ALLOC_UNSUPPORTED (1U << PVRSRV_DEVMEM_SVM_ALLOC_SHIFT)
+#define PVRSRV_DEVMEM_SVM_ALLOC_SUPPORTED (2U << PVRSRV_DEVMEM_SVM_ALLOC_SHIFT)
+#define PVRSRV_DEVMEM_SVM_ALLOC_CANFAIL (4U << PVRSRV_DEVMEM_SVM_ALLOC_SHIFT)
+
+#endif /* !defined(__DEVICE_CONNECTION_H__) */
diff --git a/drivers/staging/imgtec/rogue/devicemem.c b/drivers/staging/imgtec/rogue/devicemem.c
index 40444cd..9eccef9 100644
--- a/drivers/staging/imgtec/rogue/devicemem.c
+++ b/drivers/staging/imgtec/rogue/devicemem.c
@@ -51,23 +51,32 @@
 #include "allocmem.h"
 #include "ra.h"
 #include "osfunc.h"
-#include "devicemem_mmap.h"
+#include "osmmap.h"
 #include "devicemem_utils.h"
 #include "client_mm_bridge.h"
-#include "client_cachegeneric_bridge.h"
+#include "client_cache_bridge.h"
+#include "services_km.h"
+
 #if defined(PDUMP)
+#if defined(__KERNEL__)
+#include "pdump_km.h"
+#else
+#include "client_pdump_bridge.h"
+#endif
 #include "devicemem_pdump.h"
 #endif
 #if defined(PVR_RI_DEBUG)
 #include "client_ri_bridge.h"
-#endif 
+#endif
 #if defined(SUPPORT_PAGE_FAULT_DEBUG)
 #include "client_devicememhistory_bridge.h"
 #endif
 
+#include "rgx_heaps.h"
 #if defined(__KERNEL__)
-#include "rgxdefs_km.h"
 #include "pvrsrv.h"
+#include "rgxdefs_km.h"
+#include "rgx_bvnc_defs_km.h"
 #if defined(LINUX)
 #include "linux/kernel.h"
 #endif
@@ -75,11 +84,9 @@
 #include "rgxdefs.h"
 #endif
 
-/** Page size.
- *  Should be initialised to the correct value at driver init time.
- *  Use macros from devicemem.h to access from outside this module.
- */
-IMG_UINT32 g_uiLog2PageSize = 0;
+#if defined(__KERNEL__) && defined(PVR_RI_DEBUG)
+extern PVRSRV_ERROR RIDumpAllKM(void);
+#endif
 
 /*****************************************************************************
  *                    Sub allocation internals                               *
@@ -96,6 +103,7 @@
                       IMG_DEVMEM_ALIGN_T uiAlign,
                       DEVMEM_FLAGS_T uiFlags,
                       IMG_BOOL bExportable,
+                      const IMG_CHAR *pszAnnotation,
                       DEVMEM_IMPORT **ppsImport)
 {
 	DEVMEM_IMPORT *psImport;
@@ -123,7 +131,19 @@
                                           pui32MappingTable,
                                           uiLog2Quantum,
                                           uiPMRFlags,
+#if defined(PDUMP)
+                                          OSStringLength(pszAnnotation) + 1,
+                                          pszAnnotation,
                                           &hPMR);
+#else
+                                          1,
+                                          "",
+                                          &hPMR);
+
+	PVR_UNREFERENCED_PARAMETER(pszAnnotation);
+#endif
+
+
     if (eError != PVRSRV_OK)
     {
         /* Our check above should have ensured this the "not page
@@ -158,26 +178,25 @@
 
 IMG_INTERNAL PVRSRV_ERROR
 DeviceMemChangeSparse(DEVMEM_MEMDESC *psMemDesc,
-					  IMG_UINT32 ui32AllocPageCount,
-					  IMG_UINT32 *paui32AllocPageIndices,
-					  IMG_UINT32 ui32FreePageCount,
-					  IMG_UINT32 *pauiFreePageIndices,
-					  SPARSE_MEM_RESIZE_FLAGS uiSparseFlags,
-					  IMG_UINT32 *pui32Status)
+                      IMG_UINT32 ui32AllocPageCount,
+                      IMG_UINT32 *paui32AllocPageIndices,
+                      IMG_UINT32 ui32FreePageCount,
+                      IMG_UINT32 *pauiFreePageIndices,
+                      SPARSE_MEM_RESIZE_FLAGS uiSparseFlags)
 {
-	PVRSRV_ERROR eError=-1;
-	IMG_UINT32	ui32Status;
-	DEVMEM_IMPORT *psImport=psMemDesc->psImport;
+	PVRSRV_ERROR eError = PVRSRV_ERROR_INVALID_PARAMS;
+	DEVMEM_IMPORT *psImport = psMemDesc->psImport;
 	SHARED_DEV_CONNECTION hDevConnection;
-	IMG_HANDLE	hPMR, hSrvDevMemHeap;
+	IMG_HANDLE hPMR;
+	IMG_HANDLE hSrvDevMemHeap;
 	POS_LOCK hLock;
 	IMG_DEV_VIRTADDR sDevVAddr;
 	IMG_CPU_VIRTADDR sCpuVAddr;
 
-	if(NULL == psImport)
+	if (NULL == psImport)
 	{
-		PVR_DPF((PVR_DBG_ERROR,"%s: Invalid Sparse memory import",__func__));
-		goto ChangeSparseError;
+		PVR_DPF((PVR_DBG_ERROR, "%s: Invalid Sparse memory import", __func__));
+		goto e0;
 	}
 
 	hDevConnection = psImport->hDevConnection;
@@ -186,69 +205,114 @@
 	sDevVAddr = psImport->sDeviceImport.sDevVAddr;
 	sCpuVAddr = psImport->sCPUImport.pvCPUVAddr;
 
-	if(NULL == hDevConnection)
+	if (NULL == hDevConnection)
 	{
-		PVR_DPF((PVR_DBG_ERROR,"%s: Invalid Bridge handle",__func__));
-		goto ChangeSparseError;
+		PVR_DPF((PVR_DBG_ERROR, "%s: Invalid Bridge handle", __func__));
+		goto e0;
 	}
 
-	if(NULL == hPMR)
+	if (NULL == hPMR)
 	{
-		PVR_DPF((PVR_DBG_ERROR,"%s: Invalid PMR handle",__func__));
-		goto ChangeSparseError;
+		PVR_DPF((PVR_DBG_ERROR, "%s: Invalid PMR handle", __func__));
+		goto e0;
 	}
 
-	if((uiSparseFlags & SPARSE_RESIZE_BOTH) && (0 == sDevVAddr.uiAddr))
+	if ((uiSparseFlags & SPARSE_RESIZE_BOTH) && (0 == sDevVAddr.uiAddr))
 	{
-		PVR_DPF((PVR_DBG_ERROR,"%s: Invalid Device Virtual Map",__func__));
-		goto ChangeSparseError;
+		PVR_DPF((PVR_DBG_ERROR, "%s: Invalid Device Virtual Map", __func__));
+		goto e0;
 	}
 
-	if((uiSparseFlags & SPARSE_MAP_CPU_ADDR) && (0 == sCpuVAddr))
+	if ((uiSparseFlags & SPARSE_MAP_CPU_ADDR) && (0 == sCpuVAddr))
 	{
-		PVR_DPF((PVR_DBG_ERROR,"%s: Invalid CPU Virtual Map",__func__));
-		goto ChangeSparseError;
+		PVR_DPF((PVR_DBG_ERROR, "%s: Invalid CPU Virtual Map", __func__));
+		goto e0;
 	}
 
-	hSrvDevMemHeap  = psImport->sDeviceImport.psHeap->hDevMemServerHeap;
+	if (psMemDesc->psImport->uiProperties & DEVMEM_PROPERTIES_SECURE)
+	{
+		PVR_DPF((PVR_DBG_ERROR,
+				"%s: Secure buffers currently do not support sparse changes",
+				__func__));
+		eError = PVRSRV_ERROR_INVALID_PARAMS;
+		goto e0;
+	}
+
+	hSrvDevMemHeap = psImport->sDeviceImport.psHeap->hDevMemServerHeap;
 
 	OSLockAcquire(hLock);
 
 	eError = BridgeChangeSparseMem(hDevConnection,
-										hSrvDevMemHeap,
-										hPMR,
-										ui32AllocPageCount,
-										paui32AllocPageIndices,
-										ui32FreePageCount,
-										pauiFreePageIndices,
-										uiSparseFlags,
-										psImport->uiFlags,
-										sDevVAddr,
-										(IMG_UINT64)((uintptr_t)sCpuVAddr),
-										&ui32Status);
+	                               hSrvDevMemHeap,
+	                               hPMR,
+	                               ui32AllocPageCount,
+	                               paui32AllocPageIndices,
+	                               ui32FreePageCount,
+	                               pauiFreePageIndices,
+	                               uiSparseFlags,
+	                               psImport->uiFlags,
+	                               sDevVAddr,
+	                               (IMG_UINT64)((uintptr_t)sCpuVAddr));
 
 	 OSLockRelease(hLock);
-	 *pui32Status = ui32Status;
 
 #if defined(PVR_RI_DEBUG)
-	BridgeRIUpdateMEMDESCBacking(psImport->hDevConnection,
-	                             psMemDesc->hRIHandle,
-	                             ((IMG_INT32) ui32AllocPageCount - (IMG_INT32) ui32FreePageCount)
-	                              * (1 << psImport->sDeviceImport.psHeap->uiLog2Quantum));
+	if(PVRSRVIsBridgeEnabled(psImport->hDevConnection, PVRSRV_BRIDGE_RI))
+	{
+		BridgeRIUpdateMEMDESCBacking(psImport->hDevConnection,
+		                             psMemDesc->hRIHandle,
+		                             ((IMG_INT32) ui32AllocPageCount - (IMG_INT32) ui32FreePageCount)
+		                              * (1 << psImport->sDeviceImport.psHeap->uiLog2Quantum));
+	}
+#endif
+
+#if defined(SUPPORT_PAGE_FAULT_DEBUG)
+	if(PVRSRVIsBridgeEnabled(psMemDesc->psImport->hDevConnection, PVRSRV_BRIDGE_DEVICEMEMHISTORY))
+	{
+		static IMG_BOOL bHaveNewAPI = IMG_TRUE;
+		PVRSRV_ERROR eError;
+
+		if(bHaveNewAPI)
+		{
+			eError = BridgeDevicememHistorySparseChange(psMemDesc->psImport->hDevConnection,
+								psMemDesc->psImport->hPMR,
+								psMemDesc->uiOffset,
+								psMemDesc->sDeviceMemDesc.sDevVAddr,
+								psMemDesc->uiAllocSize,
+								psMemDesc->sTraceData.szText,
+								DevmemGetHeapLog2PageSize(psImport->sDeviceImport.psHeap),
+								ui32AllocPageCount,
+								paui32AllocPageIndices,
+								ui32FreePageCount,
+								pauiFreePageIndices,
+								psMemDesc->sTraceData.ui32AllocationIndex,
+								&psMemDesc->sTraceData.ui32AllocationIndex);
+
+			 if(eError == PVRSRV_ERROR_BRIDGE_CALL_FAILED)
+			 {
+			 	bHaveNewAPI = IMG_FALSE;
+			 }
+		}
+
+		/* no fallback required here.
+		 * the old version of devicememhistory doesn't have entry
+		 * points for SparseChange
+		 */
+	}
 #endif
 
 #ifdef PVRSRV_UNMAP_ON_SPARSE_CHANGE
-	 if((PVRSRV_OK == eError) && (psMemDesc->sCPUMemDesc.ui32RefCount))
-	 {
-		 /*
-		  * Release the CPU Virtual mapping here
-		  * the caller is supposed to map entire range again
-		  */
-		 DevmemReleaseCpuVirtAddr(psMemDesc);
-	 }
+	if ((PVRSRV_OK == eError) && (psMemDesc->sCPUMemDesc.ui32RefCount))
+	{
+		/*
+		 * Release the CPU Virtual mapping here
+		 * the caller is supposed to map entire range again
+		 */
+		DevmemReleaseCpuVirtAddr(psMemDesc);
+	}
 #endif
 
-ChangeSparseError:
+e0:
 	return eError;
 }
 
@@ -258,40 +322,51 @@
 	_DevmemImportStructRelease(psImport);
 }
 
-static IMG_BOOL
+static PVRSRV_ERROR
 _SubAllocImportAlloc(RA_PERARENA_HANDLE hArena,
                      RA_LENGTH_T uiSize,
                      RA_FLAGS_T _flags,
+                     const IMG_CHAR *pszAnnotation,
                      /* returned data */
                      RA_BASE_T *puiBase,
                      RA_LENGTH_T *puiActualSize,
                      RA_PERISPAN_HANDLE *phImport)
 {
-    /* When suballocations need a new lump of memory, the RA calls
-       back here.  Later, in the kernel, we must construct a new PMR
-       and a pairing between the new lump of virtual memory and the
-       PMR (whether or not such PMR is backed by physical memory) */
-    DEVMEM_HEAP *psHeap;
-    DEVMEM_IMPORT *psImport;
-    IMG_DEVMEM_ALIGN_T uiAlign;
-    DEVMEM_FLAGS_T uiFlags;
-    PVRSRV_ERROR eError;
-    IMG_UINT32 ui32MappingTable = 0;
+	/* When suballocations need a new lump of memory, the RA calls
+	   back here.  Later, in the kernel, we must construct a new PMR
+	   and a pairing between the new lump of virtual memory and the
+	   PMR (whether or not such PMR is backed by physical memory) */
+	DEVMEM_HEAP *psHeap;
+	DEVMEM_IMPORT *psImport;
+	IMG_DEVMEM_ALIGN_T uiAlign;
+	PVRSRV_ERROR eError;
+	IMG_UINT32 ui32MappingTable = 0;
+	DEVMEM_FLAGS_T uiFlags = (DEVMEM_FLAGS_T) _flags;
+	IMG_UINT64 ui64OptionalMapAddress = DEVICEMEM_UTILS_NO_ADDRESS;
 
-    uiFlags = (DEVMEM_FLAGS_T) _flags;
+	/* Per-arena private handle is, for us, the heap */
+	psHeap = hArena;
 
-    /* Per-arena private handle is, for us, the heap */
-    psHeap = hArena;
+	/* align to the l.s.b. of the size...  e.g. 96kiB aligned to
+	   32kiB. NB: There is an argument to say that the RA should never
+	   ask us for Non-power-of-2 size anyway, but I don't want to make
+	   that restriction arbitrarily now */
+	uiAlign = uiSize & ~(uiSize-1);
+#if defined(SUPPORT_PVRSRV_GPUVIRT)
+	/* Technically this is only required for guest drivers due to
+	   fw heaps being pre-allocated and pre-mapped resulting in
+	   a 1:1 (i.e. virtual : physical) offset correlation but we
+	   force this behaviour for all drivers to maintain consistency
+	   (i.e. heap->VA uiAlign <= heap->PA uiLog2Quantum) */
+	if (uiAlign > (IMG_DEVMEM_ALIGN_T)(1 << psHeap->uiLog2Quantum))
+	{
+		uiAlign = (IMG_DEVMEM_ALIGN_T)(1 << psHeap->uiLog2Quantum);
+	}
+#endif
 
-    /* align to the l.s.b. of the size...  e.g. 96kiB aligned to
-       32kiB. NB: There is an argument to say that the RA should never
-       ask us for Non-power-of-2 size anyway, but I don't want to make
-       that restriction arbitrarily now */
-    uiAlign = uiSize & ~(uiSize-1);
-
-    /* The RA should not have invoked us with a size that is not a
-       multiple of the quantum anyway */
-    PVR_ASSERT((uiSize & ((1ULL<<psHeap->uiLog2Quantum)-1)) == 0);
+	/* The RA should not have invoked us with a size that is not a
+	   multiple of the quantum anyway */
+	PVR_ASSERT((uiSize & ((1ULL<<psHeap->uiLog2Quantum)-1)) == 0);
 
 	eError = _AllocateDeviceMemory(psHeap->psCtx->hDevConnection,
 	                               psHeap->uiLog2Quantum,
@@ -303,13 +378,26 @@
 	                               uiAlign,
 	                               uiFlags,
 	                               IMG_FALSE,
+	                               pszAnnotation,
 	                               &psImport);
 	if (eError != PVRSRV_OK)
 	{
 		goto failAlloc;
 	}
 
+#if defined (PDUMP)
+	/* Keep the annotation in the Devmem layer so we know where suballocations were done from*/
+	psImport->pszAnnotation = OSAllocMem(OSStringLength(pszAnnotation)+1);
+	if (psImport->pszAnnotation == NULL)
+	{
+		eError = PVRSRV_ERROR_OUT_OF_MEMORY;
+		goto failAllocMem;
+	}
+	OSStringNCopy(psImport->pszAnnotation, pszAnnotation, OSStringLength(pszAnnotation)+1);
+#endif
+
 #if defined(PVR_RI_DEBUG)
+	if(PVRSRVIsBridgeEnabled(psImport->hDevConnection, PVRSRV_BRIDGE_RI))
 	{
 		eError = BridgeRIWritePMREntry (psImport->hDevConnection,
 										psImport->hPMR,
@@ -322,6 +410,7 @@
 		}
 	}
 #endif
+
 	/*
 		Suballocations always get mapped into the device was we need to
 		key the RA off something and as we can't export suballocations
@@ -330,30 +419,39 @@
 	eError = _DevmemImportStructDevMap(psHeap,
 									   IMG_TRUE,
 									   psImport,
-									   DEVICEMEM_UTILS_NO_ADDRESS);
+									   ui64OptionalMapAddress);
 	if (eError != PVRSRV_OK)
 	{
 		goto failMap;
 	}
 
-	/* Mark this import struct as clean so we can save some PDump LDBs
-	 * and do not have to CPU map + memset + flush*/
+	/* Mark this import struct as zeroed so we can save some PDump LDBs
+	 * and do not have to CPU map + memset()*/
+	if (uiFlags & PVRSRV_MEMALLOCFLAG_ZERO_ON_ALLOC)
+	{
+		psImport->uiProperties |= DEVMEM_PROPERTIES_IMPORT_IS_ZEROED;
+	}
 	psImport->uiProperties |= DEVMEM_PROPERTIES_IMPORT_IS_CLEAN;
 
 	*puiBase = psImport->sDeviceImport.sDevVAddr.uiAddr;
 	*puiActualSize = uiSize;
 	*phImport = psImport;
 
-    return IMG_TRUE;
+	return PVRSRV_OK;
 
-    /*
-      error exit paths follow
-    */
+	/*
+	  error exit paths follow
+	*/
 failMap:
-    _FreeDeviceMemory(psImport);
+#if defined(PDUMP)
+failAllocMem:
+	OSFreeMem(psImport->pszAnnotation);
+	psImport->pszAnnotation = NULL;
+#endif
+	_FreeDeviceMemory(psImport);
 failAlloc:
 
-    return IMG_FALSE;
+	return eError;
 }
 
 static void
@@ -361,13 +459,13 @@
                     RA_BASE_T uiBase,
                     RA_PERISPAN_HANDLE hImport)
 {
-    DEVMEM_IMPORT *psImport = hImport;
+	DEVMEM_IMPORT *psImport = hImport;
 
-    PVR_ASSERT(psImport != NULL);
-    PVR_ASSERT(hArena == psImport->sDeviceImport.psHeap);
-    PVR_ASSERT(uiBase == psImport->sDeviceImport.sDevVAddr.uiAddr);
+	PVR_ASSERT(psImport != NULL);
+	PVR_ASSERT(hArena == psImport->sDeviceImport.psHeap);
+	PVR_ASSERT(uiBase == psImport->sDeviceImport.sDevVAddr.uiAddr);
 
-    _DevmemImportStructDevUnmap(psImport);  
+	_DevmemImportStructDevUnmap(psImport);
 	_DevmemImportStructRelease(psImport);
 }
 
@@ -379,17 +477,18 @@
 _PopulateContextFromBlueprint(struct _DEVMEM_CONTEXT_ *psCtx,
                               DEVMEM_HEAPCFGID uiHeapBlueprintID)
 {
-    PVRSRV_ERROR eError;
-    PVRSRV_ERROR eError2;
-    struct _DEVMEM_HEAP_ **ppsHeapArray;
-    IMG_UINT32 uiNumHeaps;
-    IMG_UINT32 uiHeapsToUnwindOnError;
-    IMG_UINT32 uiHeapIndex;
-    IMG_DEV_VIRTADDR sDevVAddrBase;
-    IMG_CHAR aszHeapName[DEVMEM_HEAPNAME_MAXLENGTH];
-    IMG_DEVMEM_SIZE_T uiHeapLength;
-    IMG_DEVMEM_LOG2ALIGN_T uiLog2DataPageSize;
-    IMG_DEVMEM_LOG2ALIGN_T uiLog2ImportAlignment;
+	PVRSRV_ERROR eError;
+	PVRSRV_ERROR eError2;
+	struct _DEVMEM_HEAP_ **ppsHeapArray;
+	IMG_UINT32 uiNumHeaps;
+	IMG_UINT32 uiHeapsToUnwindOnError;
+	IMG_UINT32 uiHeapIndex;
+	IMG_DEV_VIRTADDR sDevVAddrBase;
+	IMG_CHAR aszHeapName[DEVMEM_HEAPNAME_MAXLENGTH];
+	IMG_DEVMEM_SIZE_T uiHeapLength;
+	IMG_DEVMEM_LOG2ALIGN_T uiLog2DataPageSize;
+	IMG_DEVMEM_LOG2ALIGN_T uiLog2ImportAlignment;
+	IMG_DEVMEM_LOG2ALIGN_T uiLog2TilingStrideFactor;
 
     eError = DevmemHeapCount(psCtx->hDevConnection,
                              uiHeapBlueprintID,
@@ -425,7 +524,8 @@
                                    &sDevVAddrBase,
                                    &uiHeapLength,
                                    &uiLog2DataPageSize,
-                                   &uiLog2ImportAlignment);
+                                   &uiLog2ImportAlignment,
+                                   &uiLog2TilingStrideFactor);
         if (eError != PVRSRV_OK)
         {
             goto e1;
@@ -436,6 +536,7 @@
                                   uiHeapLength,
                                   uiLog2DataPageSize,
                                   uiLog2ImportAlignment,
+                                  uiLog2TilingStrideFactor,
                                   aszHeapName,
                                   uiHeapBlueprintID,
                                   &ppsHeapArray[uiHeapIndex]);
@@ -475,40 +576,47 @@
     return eError;
 }
 
-static void
+static PVRSRV_ERROR
 _UnpopulateContextFromBlueprint(struct _DEVMEM_CONTEXT_ *psCtx)
 {
-    PVRSRV_ERROR eError2;
-    IMG_UINT32 uiHeapIndex;
-    IMG_BOOL bDoCheck = IMG_TRUE;
+	PVRSRV_ERROR eReturn = PVRSRV_OK;
+	PVRSRV_ERROR eError2;
+	IMG_UINT32 uiHeapIndex;
+	IMG_BOOL bDoCheck = IMG_TRUE;
 #if defined(__KERNEL__)
-    PVRSRV_DATA *psPVRSRVData = PVRSRVGetPVRSRVData();
-    if (psPVRSRVData->eServicesState != PVRSRV_SERVICES_STATE_OK)
-    {
-    	bDoCheck = IMG_FALSE;
-    }
+	PVRSRV_DATA *psPVRSRVData = PVRSRVGetPVRSRVData();
+	if (psPVRSRVData->eServicesState != PVRSRV_SERVICES_STATE_OK)
+	{
+		bDoCheck = IMG_FALSE;
+	}
 #endif
 
-    PVR_ASSERT(psCtx->uiNumHeaps >= psCtx->uiAutoHeapCount);
+	for (uiHeapIndex = 0; uiHeapIndex < psCtx->uiAutoHeapCount; uiHeapIndex++)
+	{
+		if (!psCtx->ppsAutoHeapArray[uiHeapIndex])
+		{
+			continue;
+		}
 
-    for (uiHeapIndex = 0; uiHeapIndex < psCtx->uiAutoHeapCount; uiHeapIndex++)
-    {
-        eError2 = DevmemDestroyHeap(psCtx->ppsAutoHeapArray[uiHeapIndex]);
-        if (bDoCheck)
-        {
-        	PVR_ASSERT(eError2 == PVRSRV_OK);
-        }
-    }
+		eError2 = DevmemDestroyHeap(psCtx->ppsAutoHeapArray[uiHeapIndex]);
+		if (eError2 != PVRSRV_OK)
+		{
+			eReturn = eError2;
+		}
+		else
+		{
+			psCtx->ppsAutoHeapArray[uiHeapIndex] = NULL;
+		}
+	}
 
-    if (psCtx->uiAutoHeapCount != 0)
-    {
-        OSFreeMem(psCtx->ppsAutoHeapArray);
-        psCtx->ppsAutoHeapArray = NULL;
-    }
-    psCtx->uiAutoHeapCount = 0;
+	if ((!bDoCheck || (eReturn == PVRSRV_OK)) && psCtx->ppsAutoHeapArray)
+	{
+		OSFreeMem(psCtx->ppsAutoHeapArray);
+		psCtx->ppsAutoHeapArray = NULL;
+		psCtx->uiAutoHeapCount = 0;
+	}
 
-    PVR_ASSERT(psCtx->uiAutoHeapCount == 0);
-    PVR_ASSERT(psCtx->ppsAutoHeapArray == NULL);
+	return eReturn;
 }
 
 
@@ -547,22 +655,11 @@
     psCtx->hDevConnection = hDevConnection;
 
     /* Create (server-side) Device Memory context */
-    eError = BridgeDevmemIntCtxCreateCLS(psCtx->hDevConnection,
-                                         bHeapCfgMetaId,
-                                         &hDevMemServerContext,
-                                         &hPrivData,
-                                         &psCtx->ui32CPUCacheLineSize);
-
-    if (eError == PVRSRV_ERROR_BRIDGE_CALL_FAILED)
-    {
-
-        psCtx->ui32CPUCacheLineSize = 0;
-        eError = BridgeDevmemIntCtxCreate(psCtx->hDevConnection,
-                                          bHeapCfgMetaId,
-                                          &hDevMemServerContext,
-                                          &hPrivData);
-    }
-
+    eError = BridgeDevmemIntCtxCreate(psCtx->hDevConnection,
+                                      bHeapCfgMetaId,
+                                      &hDevMemServerContext,
+                                      &hPrivData,
+                                      &psCtx->ui32CPUCacheLineSize);
     if (eError != PVRSRV_OK)
     {
         goto e1;
@@ -667,45 +764,56 @@
 IMG_INTERNAL PVRSRV_ERROR
 DevmemDestroyContext(DEVMEM_CONTEXT *psCtx)
 {
-    PVRSRV_ERROR eError;
-    IMG_BOOL bDoCheck = IMG_TRUE;
+	PVRSRV_ERROR eError;
+	IMG_BOOL bDoCheck = IMG_TRUE;
 
 #if defined(__KERNEL__)
-    PVRSRV_DATA *psPVRSRVData = PVRSRVGetPVRSRVData();
-    if (psPVRSRVData->eServicesState != PVRSRV_SERVICES_STATE_OK)
-    {
-    	bDoCheck = IMG_FALSE;
-    }
+	PVRSRV_DATA *psPVRSRVData = PVRSRVGetPVRSRVData();
+	if (psPVRSRVData->eServicesState != PVRSRV_SERVICES_STATE_OK)
+	{
+		bDoCheck = IMG_FALSE;
+	}
 #endif
 
-    if (psCtx == NULL)
-    {
-        return PVRSRV_ERROR_INVALID_PARAMS;
-    }
+	if (psCtx == NULL)
+	{
+		return PVRSRV_ERROR_INVALID_PARAMS;
+	}
 
-    /* should be only the automagically instantiated heaps left */
-    if (psCtx->uiNumHeaps != psCtx->uiAutoHeapCount)
-    {
-        return PVRSRV_ERROR_DEVICEMEM_ALLOCATIONS_REMAIN_IN_HEAP;
-    }
+	eError = _UnpopulateContextFromBlueprint(psCtx);
+	if (bDoCheck && eError != PVRSRV_OK)
+	{
+		PVR_DPF((PVR_DBG_ERROR,
+		         "%s: _UnpopulateContextFromBlueprint failed (%d) leaving %d heaps",
+		          __func__, eError, psCtx->uiNumHeaps));
+		goto e1;
+	}
 
-    _UnpopulateContextFromBlueprint(psCtx);
+	eError = BridgeDevmemIntCtxDestroy(psCtx->hDevConnection,
+	                                   psCtx->hDevMemServerContext);
+	if (bDoCheck && eError != PVRSRV_OK)
+	{
+		PVR_DPF((PVR_DBG_ERROR,
+		         "%s: BridgeDevmemIntCtxDestroy failed (%d)",
+		          __func__, eError));
+		goto e1;
+	}
 
-    if (bDoCheck)
-    {
-		PVR_ASSERT(psCtx->uiAutoHeapCount == 0);
-		PVR_ASSERT(psCtx->uiNumHeaps == 0);
-    }
-    eError = BridgeDevmemIntCtxDestroy(psCtx->hDevConnection,
-                                       psCtx->hDevMemServerContext);
-    if (bDoCheck)
-    {
-    	PVR_ASSERT (eError == PVRSRV_OK);
-    }
+	/* should be no more heaps left */
+	if (bDoCheck && psCtx->uiNumHeaps)
+	{
+		PVR_DPF((PVR_DBG_ERROR,
+		         "%s: Additional heaps remain in DEVMEM_CONTEXT",
+		          __func__));
+		eError = PVRSRV_ERROR_DEVICEMEM_ADDITIONAL_HEAPS_IN_CONTEXT;
+		goto e1;
+	}
 
-    OSFreeMem(psCtx);
+	OSDeviceMemSet(psCtx, 0, sizeof(*psCtx));
+	OSFreeMem(psCtx);
 
-    return PVRSRV_OK;
+e1:
+	return eError;
 }
 
 /*****************************************************************************
@@ -760,7 +868,8 @@
                   IMG_DEV_VIRTADDR *psDevVAddrBaseOut,
                   IMG_DEVMEM_SIZE_T *puiHeapLengthOut,
                   IMG_UINT32 *puiLog2DataPageSizeOut,
-                  IMG_UINT32 *puiLog2ImportAlignmentOut)
+                  IMG_UINT32 *puiLog2ImportAlignmentOut,
+                  IMG_UINT32 *puiLog2TilingStrideFactor)
 {
     PVRSRV_ERROR eError;
 
@@ -774,6 +883,23 @@
                                       puiLog2DataPageSizeOut,
                                       puiLog2ImportAlignmentOut);
 
+    /* REL/1.8 maintain bridge compatibility
+     *     4:0 - uiLog2ImportAlignment (13--20)
+     *   18:16 - uiLog2TilingStrideFactor (3--4)
+     */
+    *puiLog2TilingStrideFactor = (*puiLog2ImportAlignmentOut >> 16);
+    *puiLog2ImportAlignmentOut &= 0xffff;
+
+    /* NB: *puiLog2TilingStrideFactor is either 3 or 4 (tiling mode 1 or 0).
+     * If reading from an older KM, *puiLog2TilingStrideFactor will not be set.
+     * If so force to 4 (tiling mode 0), which was the original assumption
+     * before puiLog2TilingStrideFactor was queried.
+     */
+    if (!*puiLog2TilingStrideFactor)
+    {
+        *puiLog2TilingStrideFactor = 4;
+    }
+
     VG_MARK_INITIALIZED(pszHeapNameOut,uiHeapNameBufSz);
 
     return eError;
@@ -782,7 +908,19 @@
 /*****************************************************************************
  *                    Devmem heap functions                                  *
  *****************************************************************************/
- 
+
+IMG_INTERNAL PVRSRV_ERROR
+DevmemGetHeapInt(DEVMEM_HEAP *psHeap,
+				 IMG_HANDLE *phDevmemHeap)
+{
+	if (psHeap == NULL)
+	{
+		return PVRSRV_ERROR_INVALID_PARAMS;
+	}
+	*phDevmemHeap  = psHeap->hDevMemServerHeap;
+	return PVRSRV_OK;
+}
+
 /* See devicemem.h for important notes regarding the arguments
    to this function */
 IMG_INTERNAL PVRSRV_ERROR
@@ -791,6 +929,7 @@
                  IMG_DEVMEM_SIZE_T uiLength,
                  IMG_UINT32 ui32Log2Quantum,
                  IMG_UINT32 ui32Log2ImportAlignment,
+                 IMG_UINT32 ui32Log2TilingStrideFactor,
                  const IMG_CHAR *pszName,
                  DEVMEM_HEAPCFGID uiHeapBlueprintID,
                  DEVMEM_HEAP **ppsHeapPtr)
@@ -830,6 +969,7 @@
     OSStringCopy(pszStr, pszName);
     psHeap->pszName = pszStr;
 
+    psHeap->uiSize = uiLength;
     psHeap->sBaseAddress = sBaseAddress;
     OSAtomicWrite(&psHeap->hImportCount,0);
 
@@ -882,45 +1022,57 @@
         goto e3;
     }
 
-    psHeap->uiLog2ImportAlignment = ui32Log2ImportAlignment;
-    psHeap->uiLog2Quantum = ui32Log2Quantum;
+	psHeap->uiLog2ImportAlignment = ui32Log2ImportAlignment;
+	psHeap->uiLog2TilingStrideFactor = ui32Log2TilingStrideFactor;
+	psHeap->uiLog2Quantum = ui32Log2Quantum;
 
-    OSSNPrintf(aszBuf, sizeof(aszBuf),
-               "NDM heap '%s' (QVM) ctx:%p",
-               pszName, psCtx);
-    pszStr = OSAllocMem(OSStringLength(aszBuf)+1);
-    if (pszStr == NULL)
-    {
+	if (! OSStringCompare(pszName, RGX_GENERAL_SVM_HEAP_IDENT))
+	{
+		/* The SVM heap normally starts out as this type though
+		   it may transition to DEVMEM_HEAP_TYPE_USER_MANAGED
+		   on platforms with more processor virtual address
+		   bits than device virtual address bits */
+		psHeap->eHeapType = DEVMEM_HEAP_TYPE_KERNEL_MANAGED;
+	}
+	else
+	{
+		psHeap->eHeapType = DEVMEM_HEAP_TYPE_UNKNOWN;
+	}
+
+	OSSNPrintf(aszBuf, sizeof(aszBuf),
+				"NDM heap '%s' (QVM) ctx:%p",
+				pszName, psCtx);
+	pszStr = OSAllocMem(OSStringLength(aszBuf)+1);
+	if (pszStr == NULL)
+	{
 		eError = PVRSRV_ERROR_OUT_OF_MEMORY;
-        goto e4;
-    }
-    OSStringCopy(pszStr, aszBuf);
-    psHeap->pszQuantizedVMRAName = pszStr;
+		goto e4;
+	}
+	OSStringCopy(pszStr, aszBuf);
+	psHeap->pszQuantizedVMRAName = pszStr;
 
-    psHeap->psQuantizedVMRA = RA_Create(psHeap->pszQuantizedVMRAName,
-                       /* Subsequent import: */
-                                       0, RA_LOCKCLASS_1, NULL, NULL,
-                       (RA_PERARENA_HANDLE) psHeap,
-                       IMG_FALSE);
-
-    if (psHeap->psQuantizedVMRA == NULL)
-    {
-        eError = PVRSRV_ERROR_DEVICEMEM_UNABLE_TO_CREATE_ARENA;
-        goto e5;
-    }
+	psHeap->psQuantizedVMRA = RA_Create(psHeap->pszQuantizedVMRAName,
+					   /* Subsequent import: */
+									   0, RA_LOCKCLASS_1, NULL, NULL,
+					   (RA_PERARENA_HANDLE) psHeap,
+					   IMG_FALSE);
+	if (psHeap->psQuantizedVMRA == NULL)
+	{
+		eError = PVRSRV_ERROR_DEVICEMEM_UNABLE_TO_CREATE_ARENA;
+		goto e5;
+	}
 
 	if (!RA_Add(psHeap->psQuantizedVMRA,
-                       (RA_BASE_T)sBaseAddress.uiAddr,
-                       (RA_LENGTH_T)uiLength,
-                       (RA_FLAGS_T)0, /* This RA doesn't use or need flags */
+					   (RA_BASE_T)sBaseAddress.uiAddr,
+					   (RA_LENGTH_T)uiLength,
+					   (RA_FLAGS_T)0, /* This RA doesn't use or need flags */
 				NULL /* per ispan handle */))
 	{
 		RA_Delete(psHeap->psQuantizedVMRA);
-        eError = PVRSRV_ERROR_DEVICEMEM_UNABLE_TO_CREATE_ARENA;
-        goto e5;
+		eError = PVRSRV_ERROR_DEVICEMEM_UNABLE_TO_CREATE_ARENA;
+		goto e5;
 	}
 
-
     psHeap->psCtx = psCtx;
 
 
@@ -943,8 +1095,6 @@
 		goto e7;
 	}
 
-	psHeap->eHeapType = DEVMEM_HEAP_TYPE_UNKNOWN;
-
     psHeap->psCtx->uiNumHeaps ++;
     *ppsHeapPtr = psHeap;
 
@@ -962,9 +1112,11 @@
                                        psHeap->hDevMemServerHeap);
     PVR_ASSERT (eError2 == PVRSRV_OK);
  e6:
-    RA_Delete(psHeap->psQuantizedVMRA);
+    if (psHeap->psQuantizedVMRA)
+		RA_Delete(psHeap->psQuantizedVMRA);
  e5:
-    OSFreeMem(psHeap->pszQuantizedVMRAName);
+    if (psHeap->pszQuantizedVMRAName)
+		OSFreeMem(psHeap->pszQuantizedVMRAName);
  e4:
     RA_Delete(psHeap->psSubAllocRA);
  e3:
@@ -993,20 +1145,12 @@
 }
 
 IMG_INTERNAL void
-DevmemExportalignAdjustSizeAndAlign(DEVMEM_HEAP *psHeap, IMG_DEVMEM_SIZE_T *puiSize, IMG_DEVMEM_ALIGN_T *puiAlign)
+DevmemExportalignAdjustSizeAndAlign(IMG_UINT32 uiLog2Quantum,
+                                    IMG_DEVMEM_SIZE_T *puiSize,
+                                    IMG_DEVMEM_ALIGN_T *puiAlign)
 {
 	IMG_DEVMEM_SIZE_T uiSize = *puiSize;
 	IMG_DEVMEM_ALIGN_T uiAlign = *puiAlign;
-	IMG_UINT32 uiLog2Quantum;
-
-	if (psHeap)
-	{
-		uiLog2Quantum = psHeap->uiLog2Quantum;
-	}
-	else
-	{
-		uiLog2Quantum = GET_LOG2_PAGESIZE();
-	}
 
     if ((1ULL << uiLog2Quantum) > uiAlign)
     {
@@ -1022,41 +1166,82 @@
 IMG_INTERNAL PVRSRV_ERROR
 DevmemDestroyHeap(DEVMEM_HEAP *psHeap)
 {
-    PVRSRV_ERROR eError;
+	PVRSRV_ERROR eError;
 	IMG_INT uiImportCount;
+#if defined(PVRSRV_FORCE_UNLOAD_IF_BAD_STATE)
+	IMG_BOOL bDoCheck = IMG_TRUE;
+#if defined(__KERNEL__)
+	if (PVRSRVGetPVRSRVData()->eServicesState != PVRSRV_SERVICES_STATE_OK)
+	{
+		bDoCheck = IMG_FALSE;
+	}
+#endif
+#endif
 
-    if (psHeap == NULL)
-    {
-        return PVRSRV_ERROR_INVALID_PARAMS;
-    }
+	if (psHeap == NULL)
+	{
+		return PVRSRV_ERROR_INVALID_PARAMS;
+	}
 
 	uiImportCount = OSAtomicRead(&psHeap->hImportCount);
-    if (uiImportCount > 0)
-    {
-        PVR_DPF((PVR_DBG_ERROR, "%d(%s) leaks remain", uiImportCount, psHeap->pszName));
-        return PVRSRV_ERROR_DEVICEMEM_ALLOCATIONS_REMAIN_IN_HEAP;
-    }
+	if (uiImportCount > 0)
+	{
+		PVR_DPF((PVR_DBG_ERROR, "%d(%s) leaks remain", uiImportCount, psHeap->pszName));
+#if defined(__KERNEL__)
+#if defined(PVR_RI_DEBUG)
+		PVR_DPF((PVR_DBG_ERROR, "Details of remaining allocated device memory (for all processes):"));
+		RIDumpAllKM();
+#else
+		PVR_DPF((PVR_DBG_ERROR, "Compile with PVR_RI_DEBUG=1 to get a full "
+				"list of all driver allocations."));
+#endif
+#endif
+#if defined(PVRSRV_FORCE_UNLOAD_IF_BAD_STATE)
+		if (bDoCheck)
+#endif
+		{
+			return PVRSRV_ERROR_DEVICEMEM_ALLOCATIONS_REMAIN_IN_HEAP;
+		}
+	}
+
+	eError = BridgeDevmemIntHeapDestroy(psHeap->psCtx->hDevConnection,
+	                                    psHeap->hDevMemServerHeap);
+#if defined(PVRSRV_FORCE_UNLOAD_IF_BAD_STATE)
+	if (bDoCheck)
+#endif
+	{
+		if (eError != PVRSRV_OK)
+		{
+			PVR_DPF((PVR_DBG_ERROR,
+			         "%s: BridgeDevmemIntHeapDestroy failed (%d)",
+			          __func__, eError));
+			return eError;
+		}
+	}
+
+	PVR_ASSERT(psHeap->psCtx->uiNumHeaps > 0);
+	psHeap->psCtx->uiNumHeaps--;
 
 	OSLockDestroy(psHeap->hLock);
 
-    PVR_ASSERT(psHeap->psCtx->uiNumHeaps > 0);
-    psHeap->psCtx->uiNumHeaps --;
+	if (psHeap->psQuantizedVMRA)
+	{
+		RA_Delete(psHeap->psQuantizedVMRA);
+	}
+	if (psHeap->pszQuantizedVMRAName)
+	{
+		OSFreeMem(psHeap->pszQuantizedVMRAName);
+	}
 
-    eError = BridgeDevmemIntHeapDestroy(psHeap->psCtx->hDevConnection,
-                                        psHeap->hDevMemServerHeap);
-    PVR_ASSERT (eError == PVRSRV_OK);
+	RA_Delete(psHeap->psSubAllocRA);
+	OSFreeMem(psHeap->pszSubAllocRAName);
 
-    RA_Delete(psHeap->psQuantizedVMRA);
-    OSFreeMem(psHeap->pszQuantizedVMRAName);
+	OSFreeMem(psHeap->pszName);
 
-    RA_Delete(psHeap->psSubAllocRA);
-    OSFreeMem(psHeap->pszSubAllocRAName);
+	OSDeviceMemSet(psHeap, 0, sizeof(*psHeap));
+	OSFreeMem(psHeap);
 
-    OSFreeMem(psHeap->pszName);
-
-    OSFreeMem(psHeap);
-
-    return PVRSRV_OK;
+	return PVRSRV_OK;
 }
 
 /*****************************************************************************
@@ -1069,21 +1254,29 @@
                   IMG_DEVMEM_SIZE_T uiSize,
                   IMG_DEVMEM_ALIGN_T uiAlign,
                   DEVMEM_FLAGS_T uiFlags,
-                  const IMG_PCHAR pszText,
+                  const IMG_CHAR *pszText,
                   DEVMEM_MEMDESC **ppsMemDescPtr)
 {
-    IMG_BOOL bStatus; /* eError for RA */
-    RA_BASE_T uiAllocatedAddr;
-    RA_LENGTH_T uiAllocatedSize;
-    RA_PERISPAN_HANDLE hImport; /* the "import" from which this sub-allocation came */
-    RA_FLAGS_T uiFlagsForRA;
-    PVRSRV_ERROR eError;
-    DEVMEM_MEMDESC *psMemDesc = NULL;
+	RA_BASE_T uiAllocatedAddr;
+	RA_LENGTH_T uiAllocatedSize;
+	RA_PERISPAN_HANDLE hImport; /* the "import" from which this sub-allocation came */
+	PVRSRV_ERROR eError;
+	DEVMEM_MEMDESC *psMemDesc = NULL;
 	IMG_DEVMEM_OFFSET_T uiOffset = 0;
 	DEVMEM_IMPORT *psImport;
 	IMG_UINT32 ui32CPUCacheLineSize;
 	void *pvAddr;
 
+	IMG_BOOL bImportClean;
+	IMG_BOOL bCPUCleanFlag = PVRSRV_CHECK_CPU_CACHE_CLEAN(uiFlags);
+	IMG_BOOL bZero = PVRSRV_CHECK_ZERO_ON_ALLOC(uiFlags);
+	IMG_BOOL bCPUCached = (PVRSRV_CHECK_CPU_CACHE_COHERENT(uiFlags)   ||
+	                       PVRSRV_CHECK_CPU_CACHE_INCOHERENT(uiFlags));
+	IMG_BOOL bGPUCached = (PVRSRV_CHECK_GPU_CACHE_COHERENT(uiFlags)   ||
+	                       PVRSRV_CHECK_GPU_CACHE_INCOHERENT(uiFlags));
+	PVRSRV_CACHE_OP eOp = PVRSRV_CACHE_OP_INVALIDATE;
+	IMG_UINT32	ui32CacheLineSize;
+
 	if (uiFlags & PVRSRV_MEMALLOCFLAG_NO_OSPAGES_ON_ALLOC)
 	{
 		/* Deferred Allocation not supported on SubAllocs*/
@@ -1091,12 +1284,24 @@
 		goto failParams;
 	}
 
-    if (psHeap == NULL || psHeap->psCtx == NULL || ppsMemDescPtr == NULL)
-    {
-        eError = PVRSRV_ERROR_INVALID_PARAMS;
-        goto failParams;
-    }
+	if (psHeap == NULL || psHeap->psCtx == NULL ||ppsMemDescPtr == NULL)
+	{
+		eError = PVRSRV_ERROR_INVALID_PARAMS;
+		goto failParams;
+	}
 
+#if defined(__KERNEL__)
+	{
+		/* The hDevConnection holds two different types of pointers depending on the
+		 * address space in which it is used.
+		 * In this instance the variable points to the device node in server */
+		PVRSRV_DEVICE_NODE *psDevNode = (PVRSRV_DEVICE_NODE *)psHeap->psCtx->hDevConnection;
+		ui32CacheLineSize = GET_ROGUE_CACHE_LINE_SIZE(psDevNode->pfnGetDeviceFeatureValue(psDevNode, \
+				RGX_FEATURE_SLC_CACHE_LINE_SIZE_BITS_BIT_MASK));
+	}
+#else
+	ui32CacheLineSize = ROGUE_CACHE_LINE_SIZE;
+#endif
 
 	/* The following logic makes sure that any cached memory is aligned to both the CPU and GPU.
 	 * To be aligned on both you have to take the Lowest Common Multiple (LCM) of the cache line sizes of each.
@@ -1104,12 +1309,12 @@
 	 * Therefore this algorithm just picks the highest from the CPU, GPU and given alignments.
 	 */
 	ui32CPUCacheLineSize = psHeap->psCtx->ui32CPUCacheLineSize;
-	 /* If the CPU cache line size is larger than the alignment given then it is the lowest common multiple
+	/* If the CPU cache line size is larger than the alignment given then it is the lowest common multiple
 	 * Also checking if the allocation is going to be cached on the CPU
 	 * Currently there is no check for the validity of the cache coherent option.
 	 * In this case, the alignment could be applied but the mode could still fall back to uncached.
 	 */
-	if(ui32CPUCacheLineSize > uiAlign && (((uiFlags & PVRSRV_MEMALLOCFLAG_CPU_CACHE_MODE_MASK) == PVRSRV_MEMALLOCFLAG_CPU_CACHE_COHERENT) || ((uiFlags & PVRSRV_MEMALLOCFLAG_CPU_CACHE_MODE_MASK) == PVRSRV_MEMALLOCFLAG_CPU_CACHE_INCOHERENT) || ((uiFlags & PVRSRV_MEMALLOCFLAG_CPU_CACHE_MODE_MASK) == PVRSRV_MEMALLOCFLAG_CPU_CACHED_CACHE_COHERENT)))
+	if (ui32CPUCacheLineSize > uiAlign && bCPUCached)
 	{
 		uiAlign = ui32CPUCacheLineSize;
 	}
@@ -1119,55 +1324,37 @@
 	 * Currently there is no check for the validity of the cache coherent option.
 	 * In this case, the alignment could be applied but the mode could still fall back to uncached.
 	 */
-	if(ROGUE_CACHE_LINE_SIZE > uiAlign && (((uiFlags & PVRSRV_MEMALLOCFLAG_GPU_CACHE_MODE_MASK) == PVRSRV_MEMALLOCFLAG_GPU_CACHE_COHERENT) || ((uiFlags & PVRSRV_MEMALLOCFLAG_GPU_CACHE_MODE_MASK) == PVRSRV_MEMALLOCFLAG_GPU_CACHE_INCOHERENT) || ((uiFlags & PVRSRV_MEMALLOCFLAG_GPU_CACHE_MODE_MASK) == PVRSRV_MEMALLOCFLAG_GPU_CACHED_CACHE_COHERENT)))
+	if (ui32CacheLineSize > uiAlign && bGPUCached)
 	{
-		uiAlign = ROGUE_CACHE_LINE_SIZE;
+		uiAlign = ui32CacheLineSize;
 	}
 
 	eError = _DevmemValidateParams(uiSize,
-								   uiAlign,
-								   uiFlags);
+	                               uiAlign,
+	                               &uiFlags);
 	if (eError != PVRSRV_OK)
 	{
 		goto failParams;
 	}
 
 	eError =_DevmemMemDescAlloc(&psMemDesc);
-    if (eError != PVRSRV_OK)
-    {
-        goto failMemDescAlloc;
-    }
-
-    /*
-        If zero flag is set we have to have write access to the page.
-    */
-    uiFlags |= (uiFlags & PVRSRV_MEMALLOCFLAG_ZERO_ON_ALLOC) ? PVRSRV_MEMALLOCFLAG_CPU_WRITEABLE : 0;
-
-	/*
-		No request for exportable memory so use the RA
-	*/
-    uiFlagsForRA = (RA_FLAGS_T)(uiFlags & PVRSRV_MEMALLOCFLAGS_RA_DIFFERENTIATION_MASK);
-    /* Check that the cast didn't lose any flags due to different integer widths */
-    PVR_ASSERT(uiFlagsForRA == (uiFlags & PVRSRV_MEMALLOCFLAGS_RA_DIFFERENTIATION_MASK));
-
-	/* 
-	   When the RA suballocates memory from a Span it does not zero it. It only zeroes the
-	   memory if it allocates a new Span; but we don't know what is going to happen for this
-	   RA_Alloc call. Therefore, we zero the mem after the allocation below.
-	*/
-	uiFlagsForRA &= ~PVRSRV_MEMALLOCFLAG_ZERO_ON_ALLOC;
-	
-	bStatus = RA_Alloc(psHeap->psSubAllocRA,
-					   uiSize,
-					   uiPreAllocMultiplier,
-					   uiFlagsForRA,
-					   uiAlign,
-					   &uiAllocatedAddr,
-					   &uiAllocatedSize,
-					   &hImport);
-	if (!bStatus)
+	if (eError != PVRSRV_OK)
 	{
-		eError = PVRSRV_ERROR_OUT_OF_MEMORY;
+		goto failMemDescAlloc;
+	}
+
+	/* No request for exportable memory so use the RA */
+	eError = RA_Alloc(psHeap->psSubAllocRA,
+	                  uiSize,
+	                  uiPreAllocMultiplier,
+	                  uiFlags,
+	                  uiAlign,
+	                  pszText,
+	                  &uiAllocatedAddr,
+	                  &uiAllocatedSize,
+	                  &hImport);
+	if (PVRSRV_OK != eError)
+	{
 		goto failDeviceMemAlloc;
 	}
 
@@ -1176,84 +1363,118 @@
 	/* This assignment is assuming the RA returns an hImport where suballocations
 	 * can be made from if uiSize is NOT a page multiple of the passed heap.
 	 *
-	 * So we check if uiSize is a page multiple and mark it as suballocatable
+	 * So we check if uiSize is a page multiple and mark it as exportable
 	 * if it is not.
 	 * */
-	if (uiSize & ((1 << psHeap->uiLog2Quantum) - 1) )
+	if (!(uiSize & ((1 << psHeap->uiLog2Quantum) - 1)) &&
+	     (uiPreAllocMultiplier == RA_NO_IMPORT_MULTIPLIER) )
 	{
-		psImport->uiProperties |= DEVMEM_PROPERTIES_SUBALLOCATABLE;
+		psImport->uiProperties |= DEVMEM_PROPERTIES_EXPORTABLE;
 	}
+	psImport->uiProperties |= DEVMEM_PROPERTIES_SUBALLOCATABLE;
 
 	uiOffset = uiAllocatedAddr - psImport->sDeviceImport.sDevVAddr.uiAddr;
 
-	_DevmemMemDescInit(psMemDesc,
-					   uiOffset,
-					   psImport,
-					   uiSize);
-
-	/* zero the memory */
-	if (uiFlags & PVRSRV_MEMALLOCFLAG_ZERO_ON_ALLOC)
-
+#if defined(PDUMP)
+#if defined(__KERNEL__)
+	PDumpCommentWithFlags(PDUMP_NONE,
+	                      "Suballocated %u Byte for \"%s\" from physical allocation \"%s\"",
+	                      (IMG_UINT32) uiSize, pszText, psImport->pszAnnotation);
+#else
 	{
-		eError = DevmemAcquireCpuVirtAddr(psMemDesc, &pvAddr);
-		if (eError != PVRSRV_OK)
-		{
-			goto failZero;
-		}
+		IMG_CHAR pszComment[PVRSRV_PDUMP_MAX_COMMENT_SIZE];
+		OSSNPrintf(pszComment,
+	                   PVRSRV_PDUMP_MAX_COMMENT_SIZE,
+	                   "Suballocated %u Byte for \"%s\" from physical allocation \"%s\"",
+	                   (IMG_UINT32) uiSize,
+	                   pszText,
+	                   psImport->pszAnnotation);
 
-#if (defined(_WIN32) && !defined(_WIN64)) || (defined(LINUX) && defined(__i386__))
-		PVR_ASSERT(uiSize<IMG_UINT32_MAX);
+		BridgePVRSRVPDumpComment(psHeap->psCtx->hDevConnection, pszComment, IMG_FALSE);
+	}
+#endif
 #endif
 
-		OSDeviceMemSet(pvAddr, 0x0, (size_t) uiSize);
-	    
-		DevmemReleaseCpuVirtAddr(psMemDesc);
+	_DevmemMemDescInit(psMemDesc,
+	                   uiOffset,
+	                   psImport,
+	                   uiSize);
+
+	bImportClean = ((psMemDesc->psImport->uiProperties & DEVMEM_PROPERTIES_IMPORT_IS_CLEAN) != 0);
+
+	/* Zero the memory */
+	if (bZero)
+	{
+		/* Has the import been zeroed on allocation and were no suballocations returned to it so far? */
+		bImportClean = bImportClean && ((psMemDesc->psImport->uiProperties & DEVMEM_PROPERTIES_IMPORT_IS_ZEROED) != 0);
+
+		if(!bImportClean)
+		{
+			eOp = PVRSRV_CACHE_OP_FLUSH;
+
+			eError = DevmemAcquireCpuVirtAddr(psMemDesc, &pvAddr);
+			if (eError != PVRSRV_OK)
+			{
+				goto failMaintenance;
+			}
+
+			/* uiSize is a 64-bit quantity whereas the 3rd argument
+			 * to OSDeviceMemSet is a 32-bit quantity on 32-bit systems
+			 * hence a compiler warning of implicit cast and loss of data.
+			 * Added explicit cast and assert to remove warning.
+			 */
+			PVR_ASSERT(uiSize < IMG_UINT32_MAX);
+
+			OSDeviceMemSet(pvAddr, 0x0, (size_t) uiSize);
+
+			DevmemReleaseCpuVirtAddr(psMemDesc);
 
 #if defined(PDUMP)
-		DevmemPDumpLoadZeroMem(psMemDesc, 0, uiSize, PDUMP_FLAGS_CONTINUOUS);
+			DevmemPDumpLoadZeroMem(psMemDesc, 0, uiSize, PDUMP_FLAGS_CONTINUOUS);
 #endif
+		}
 	}
 
-	/* Flush if (cached && (!clean || zeroed) */
-	if (PVRSRV_CPU_CACHE_MODE(uiFlags) == PVRSRV_MEMALLOCFLAG_CPU_CACHE_INCOHERENT)
+	/* Flush or invalidate */
+	if (bCPUCached && !bImportClean && (bZero || bCPUCleanFlag))
 	{
-		PVRSRV_CACHE_OP eOp = PVRSRV_CACHE_OP_NONE;
-
-		if (uiFlags & PVRSRV_MEMALLOCFLAG_ZERO_ON_ALLOC)
-			eOp = PVRSRV_CACHE_OP_FLUSH;
-		else if (!(psMemDesc->psImport->uiProperties & DEVMEM_PROPERTIES_IMPORT_IS_CLEAN))
-			eOp = PVRSRV_CACHE_OP_INVALIDATE;
-
-		if (eOp != PVRSRV_CACHE_OP_NONE)
+		/* BridgeCacheOpQueue _may_ be deferred so use BridgeCacheOpExec
+		   to ensure this cache maintenance is actioned immediately */
+		eError = BridgeCacheOpExec (psMemDesc->psImport->hDevConnection,
+		                            psMemDesc->psImport->hPMR,
+		                            psMemDesc->uiOffset,
+		                            psMemDesc->uiAllocSize,
+		                            eOp);
+		if (eError != PVRSRV_OK)
 		{
-			BridgeCacheOpQueue (psMemDesc->psImport->hDevConnection,
-								psMemDesc->psImport->hPMR,
-								psMemDesc->uiOffset,
-								psMemDesc->uiAllocSize,
-								eOp);
+			goto failMaintenance;
 		}
 	}
 
 #if defined(SUPPORT_PAGE_FAULT_DEBUG)
-	/* copy the allocation descriptive name and size so it can be passed to DevicememHistory when
-	 * the allocation gets mapped/unmapped
-	 */
-	OSStringNCopy(psMemDesc->sTraceData.szText, pszText, sizeof(psMemDesc->sTraceData.szText) - 1);
+	if(PVRSRVIsBridgeEnabled(psMemDesc->psImport->hDevConnection, PVRSRV_BRIDGE_DEVICEMEMHISTORY))
+	{
+		/* copy the allocation descriptive name and size so it can be passed to DevicememHistory when
+		 * the allocation gets mapped/unmapped
+		 */
+		OSStringNCopy(psMemDesc->sTraceData.szText, pszText, sizeof(psMemDesc->sTraceData.szText) - 1);
+	}
 #endif
 
 #if defined(PVR_RI_DEBUG)
+	if(PVRSRVIsBridgeEnabled(psMemDesc->psImport->hDevConnection, PVRSRV_BRIDGE_RI))
 	{
 		/* Attach RI information */
 		eError = BridgeRIWriteMEMDESCEntry (psMemDesc->psImport->hDevConnection,
-											psMemDesc->psImport->hPMR,
-											OSStringNLength(pszText, RI_MAX_TEXT_LEN),
-											pszText,
-											psMemDesc->uiOffset,
-											uiAllocatedSize,
-											uiAllocatedSize,
-											IMG_FALSE,
-											IMG_FALSE,
-											&(psMemDesc->hRIHandle));
+		                                    psMemDesc->psImport->hPMR,
+		                                    OSStringNLength(pszText, RI_MAX_TEXT_LEN),
+		                                    pszText,
+		                                    psMemDesc->uiOffset,
+		                                    uiAllocatedSize,
+		                                    uiAllocatedSize,
+		                                    IMG_FALSE,
+		                                    IMG_FALSE,
+		                                    &(psMemDesc->hRIHandle));
 		if( eError != PVRSRV_OK)
 		{
 			PVR_DPF((PVR_DBG_ERROR, "%s: call to BridgeRIWriteMEMDESCEntry failed (eError=%d)", __func__, eError));
@@ -1265,105 +1486,107 @@
 
 	*ppsMemDescPtr = psMemDesc;
 
-    return PVRSRV_OK;
+	return PVRSRV_OK;
 
-    /*
-      error exit paths follow
-    */
+	/*
+	  error exit paths follow
+	 */
 
-failZero:
+failMaintenance:
 	_DevmemMemDescRelease(psMemDesc);
 	psMemDesc = NULL;	/* Make sure we don't do a discard after the release */
 failDeviceMemAlloc:
 	if (psMemDesc)
+	{
 		_DevmemMemDescDiscard(psMemDesc);
+	}
 failMemDescAlloc:
 failParams:
-    PVR_ASSERT(eError != PVRSRV_OK);
+	PVR_ASSERT(eError != PVRSRV_OK);
 	PVR_DPF((PVR_DBG_ERROR,
 			"%s: Failed! Error is %s. Allocation size: %#llX",
 			__func__,
 			PVRSRVGETERRORSTRING(eError),
 			(unsigned long long) uiSize));
-    return eError;
+	return eError;
 }
 
 
 
 IMG_INTERNAL PVRSRV_ERROR
 DevmemAllocateExportable(SHARED_DEV_CONNECTION hDevConnection,
-						 IMG_DEVMEM_SIZE_T uiSize,
-						 IMG_DEVMEM_ALIGN_T uiAlign,
-						 DEVMEM_FLAGS_T uiFlags,
-						 const IMG_PCHAR pszText,
-						 DEVMEM_MEMDESC **ppsMemDescPtr)
+                         IMG_DEVMEM_SIZE_T uiSize,
+                         IMG_DEVMEM_ALIGN_T uiAlign,
+                         IMG_UINT32 uiLog2HeapPageSize,
+                         DEVMEM_FLAGS_T uiFlags,
+                         const IMG_CHAR *pszText,
+                         DEVMEM_MEMDESC **ppsMemDescPtr)
 {
-    PVRSRV_ERROR eError;
-    DEVMEM_MEMDESC *psMemDesc = NULL;
+	PVRSRV_ERROR eError;
+	DEVMEM_MEMDESC *psMemDesc = NULL;
 	DEVMEM_IMPORT *psImport;
-    IMG_UINT32 ui32MappingTable = 0;
+	IMG_UINT32 ui32MappingTable = 0;
 
-	DevmemExportalignAdjustSizeAndAlign(NULL,
-										&uiSize,
-										&uiAlign);
+	DevmemExportalignAdjustSizeAndAlign(uiLog2HeapPageSize,
+	                                    &uiSize,
+	                                    &uiAlign);
 
 	eError = _DevmemValidateParams(uiSize,
-								   uiAlign,
-								   uiFlags);
+	                               uiAlign,
+	                               &uiFlags);
 	if (eError != PVRSRV_OK)
 	{
 		goto failParams;
 	}
 
-
 	eError =_DevmemMemDescAlloc(&psMemDesc);
-    if (eError != PVRSRV_OK)
-    {
-        goto failMemDescAlloc;
-    }
+	if (eError != PVRSRV_OK)
+	{
+		goto failMemDescAlloc;
+	}
 
-	/*
-		Note:
-		In the case of exportable memory we have no heap to
-		query the pagesize from, so we assume host pagesize.
-	*/
 	eError = _AllocateDeviceMemory(hDevConnection,
-								   GET_LOG2_PAGESIZE(),
-								   uiSize,
-								   uiSize,
-								   1,
-								   1,
-								   &ui32MappingTable,
-								   uiAlign,
-								   uiFlags,
-								   IMG_TRUE,
-								   &psImport);
+	                               uiLog2HeapPageSize,
+	                               uiSize,
+	                               uiSize,
+	                               1,
+	                               1,
+	                               &ui32MappingTable,
+	                               uiAlign,
+	                               uiFlags,
+	                               IMG_TRUE,
+	                               pszText,
+	                               &psImport);
 	if (eError != PVRSRV_OK)
 	{
 		goto failDeviceMemAlloc;
 	}
 
 	_DevmemMemDescInit(psMemDesc,
-					   0,
-					   psImport,
-					   uiSize);
+	                   0,
+	                   psImport,
+	                   uiSize);
 
     *ppsMemDescPtr = psMemDesc;
 
 #if defined(SUPPORT_PAGE_FAULT_DEBUG)
-	/* copy the allocation descriptive name and size so it can be passed to DevicememHistory when
-	 * the allocation gets mapped/unmapped
-	 */
-	OSStringNCopy(psMemDesc->sTraceData.szText, pszText, sizeof(psMemDesc->sTraceData.szText) - 1);
+	if(PVRSRVIsBridgeEnabled(psImport->hDevConnection, PVRSRV_BRIDGE_DEVICEMEMHISTORY))
+	{
+		/* copy the allocation descriptive name and size so it can be passed to DevicememHistory when
+		 * the allocation gets mapped/unmapped
+		 */
+		OSStringNCopy(psMemDesc->sTraceData.szText, pszText, sizeof(psMemDesc->sTraceData.szText) - 1);
+	}
 #endif
 
 #if defined(PVR_RI_DEBUG)
+	if(PVRSRVIsBridgeEnabled(psImport->hDevConnection, PVRSRV_BRIDGE_RI))
 	{
 		eError = BridgeRIWritePMREntry (psImport->hDevConnection,
-										psImport->hPMR,
-										OSStringNLength(pszText, RI_MAX_TEXT_LEN),
-										(IMG_CHAR *)pszText,
-										psImport->uiSize);
+		                                psImport->hPMR,
+		                                OSStringNLength(pszText, RI_MAX_TEXT_LEN),
+		                                (IMG_CHAR *)pszText,
+		                                psImport->uiSize);
 		if( eError != PVRSRV_OK)
 		{
 			PVR_DPF((PVR_DBG_ERROR, "%s: call to BridgeRIWritePMREntry failed (eError=%d)", __func__, eError));
@@ -1371,15 +1594,15 @@
 
 		 /* Attach RI information */
 		eError = BridgeRIWriteMEMDESCEntry (psImport->hDevConnection,
-											psImport->hPMR,
-											sizeof("^"),
-											"^",
-											psMemDesc->uiOffset,
-											uiSize,
-											uiSize,
-											IMG_FALSE,
-											IMG_TRUE,
-											&psMemDesc->hRIHandle);
+		                                    psImport->hPMR,
+		                                    sizeof("^"),
+		                                    "^",
+		                                    psMemDesc->uiOffset,
+		                                    uiSize,
+		                                    uiSize,
+		                                    IMG_FALSE,
+		                                    IMG_TRUE,
+		                                    &psMemDesc->hRIHandle);
 		if( eError != PVRSRV_OK)
 		{
 			PVR_DPF((PVR_DBG_ERROR, "%s: call to BridgeRIWriteMEMDESCEntry failed (eError=%d)", __func__, eError));
@@ -1389,116 +1612,133 @@
 	PVR_UNREFERENCED_PARAMETER (pszText);
 #endif /* if defined(PVR_RI_DEBUG) */
 
-    return PVRSRV_OK;
+	return PVRSRV_OK;
 
-    /*
-      error exit paths follow
-    */
+	/*
+	  error exit paths follow
+	 */
 
 failDeviceMemAlloc:
-    _DevmemMemDescDiscard(psMemDesc);
+	_DevmemMemDescDiscard(psMemDesc);
 
 failMemDescAlloc:
 failParams:
-    PVR_ASSERT(eError != PVRSRV_OK);
+	PVR_ASSERT(eError != PVRSRV_OK);
 	PVR_DPF((PVR_DBG_ERROR,
-		"%s: Failed! Error is %s. Allocation size: %#llX",
-		__func__,
-		PVRSRVGETERRORSTRING(eError),
-		(unsigned long long) uiSize));
-    return eError;
+			"%s: Failed! Error is %s. Allocation size: %#llX",
+			__func__,
+			PVRSRVGETERRORSTRING(eError),
+			(unsigned long long) uiSize));
+	return eError;
 }
 
 IMG_INTERNAL PVRSRV_ERROR
 DevmemAllocateSparse(SHARED_DEV_CONNECTION hDevConnection,
-					 IMG_DEVMEM_SIZE_T uiSize,
-					 IMG_DEVMEM_SIZE_T uiChunkSize,
-					 IMG_UINT32 ui32NumPhysChunks,
-					 IMG_UINT32 ui32NumVirtChunks,
-					 IMG_UINT32 *pui32MappingTable,
-					 IMG_DEVMEM_ALIGN_T uiAlign,
-					 DEVMEM_FLAGS_T uiFlags,
-					 const IMG_PCHAR pszText,
-					 DEVMEM_MEMDESC **ppsMemDescPtr)
+                     IMG_DEVMEM_SIZE_T uiSize,
+                     IMG_DEVMEM_SIZE_T uiChunkSize,
+                     IMG_UINT32 ui32NumPhysChunks,
+                     IMG_UINT32 ui32NumVirtChunks,
+                     IMG_UINT32 *pui32MappingTable,
+                     IMG_DEVMEM_ALIGN_T uiAlign,
+                     IMG_UINT32 uiLog2HeapPageSize,
+                     DEVMEM_FLAGS_T uiFlags,
+                     const IMG_CHAR *pszText,
+                     DEVMEM_MEMDESC **ppsMemDescPtr)
 {
-    PVRSRV_ERROR eError;
-    DEVMEM_MEMDESC *psMemDesc = NULL;
+	PVRSRV_ERROR eError;
+	DEVMEM_MEMDESC *psMemDesc = NULL;
 	DEVMEM_IMPORT *psImport;
+	IMG_UINT32 i;
 
-	DevmemExportalignAdjustSizeAndAlign(NULL,
-										&uiSize,
-										&uiAlign);
+	for (i = 0; i < ui32NumPhysChunks; i++)
+	{
+		if (!(pui32MappingTable[i] < ui32NumVirtChunks))
+		{
+			PVR_DPF((PVR_DBG_ERROR,
+					"A mapping table index exceeds the size of the allocation:"
+					" pui32MappingTable[%u] %u, ui32NumVirtChunks %u ",
+					i,
+					pui32MappingTable[i],
+					ui32NumVirtChunks));
+			eError = PVRSRV_ERROR_INVALID_PARAMS;
+			goto failMemDescAlloc;
+		}
+	}
+
+	DevmemExportalignAdjustSizeAndAlign(uiLog2HeapPageSize,
+	                                    &uiSize,
+	                                    &uiAlign);
 
 	eError = _DevmemValidateParams(uiSize,
-								   uiAlign,
-								   uiFlags);
+	                               uiAlign,
+	                               &uiFlags);
 	if (eError != PVRSRV_OK)
 	{
 		goto failParams;
 	}
 
 	eError =_DevmemMemDescAlloc(&psMemDesc);
-    if (eError != PVRSRV_OK)
-    {
-        goto failMemDescAlloc;
-    }
+	if (eError != PVRSRV_OK)
+	{
+		goto failMemDescAlloc;
+	}
 
-	/*
-		Note:
-		In the case of sparse memory we have no heap to
-		query the pagesize from, so we assume host pagesize.
-	*/
-    eError = _AllocateDeviceMemory(hDevConnection,
-								   GET_LOG2_PAGESIZE(),
-								   uiSize,
-								   uiChunkSize,
-								   ui32NumPhysChunks,
-								   ui32NumVirtChunks,
-								   pui32MappingTable,
-								   uiAlign,
-								   uiFlags,
-								   IMG_TRUE,
-								   &psImport);
+	eError = _AllocateDeviceMemory(hDevConnection,
+	                               uiLog2HeapPageSize,
+	                               uiSize,
+	                               uiChunkSize,
+	                               ui32NumPhysChunks,
+	                               ui32NumVirtChunks,
+	                               pui32MappingTable,
+	                               uiAlign,
+	                               uiFlags,
+	                               IMG_TRUE,
+	                               pszText,
+	                               &psImport);
 	if (eError != PVRSRV_OK)
 	{
 		goto failDeviceMemAlloc;
 	}
 
 	_DevmemMemDescInit(psMemDesc,
-					   0,
-					   psImport,
-					   uiSize);
+	                   0,
+	                   psImport,
+	                   uiSize);
 
 #if defined(SUPPORT_PAGE_FAULT_DEBUG)
-	/* copy the allocation descriptive name and size so it can be passed to DevicememHistory when
-	 * the allocation gets mapped/unmapped
-	 */
-	OSStringNCopy(psMemDesc->sTraceData.szText, pszText, sizeof(psMemDesc->sTraceData.szText) - 1);
+	if(PVRSRVIsBridgeEnabled(psImport->hDevConnection, PVRSRV_BRIDGE_DEVICEMEMHISTORY))
+	{
+		/* copy the allocation descriptive name and size so it can be passed to DevicememHistory when
+		 * the allocation gets mapped/unmapped
+		 */
+		OSStringNCopy(psMemDesc->sTraceData.szText, pszText, sizeof(psMemDesc->sTraceData.szText) - 1);
+	}
 #endif
 
 #if defined(PVR_RI_DEBUG)
+	if(PVRSRVIsBridgeEnabled(psImport->hDevConnection, PVRSRV_BRIDGE_RI))
 	{
 		eError = BridgeRIWritePMREntry (psImport->hDevConnection,
-										psImport->hPMR,
-										OSStringNLength(pszText, RI_MAX_TEXT_LEN),
-										(IMG_CHAR *)pszText,
-										psImport->uiSize);
+		                                psImport->hPMR,
+		                                OSStringNLength(pszText, RI_MAX_TEXT_LEN),
+		                                (IMG_CHAR *)pszText,
+		                                psImport->uiSize);
 		if( eError != PVRSRV_OK)
 		{
 			PVR_DPF((PVR_DBG_ERROR, "%s: call to BridgeRIWritePMREntry failed (eError=%d)", __func__, eError));
 		}
 
 		/* Attach RI information */
-    	eError = BridgeRIWriteMEMDESCEntry (psMemDesc->psImport->hDevConnection,
-											psMemDesc->psImport->hPMR,
-											sizeof("^"),
-											"^",
-											psMemDesc->uiOffset,
-											uiSize,
-											ui32NumPhysChunks * uiChunkSize,
-											IMG_FALSE,
-											IMG_TRUE,
-											&psMemDesc->hRIHandle);
+		eError = BridgeRIWriteMEMDESCEntry (psMemDesc->psImport->hDevConnection,
+		                                    psMemDesc->psImport->hPMR,
+		                                    sizeof("^"),
+		                                    "^",
+		                                    psMemDesc->uiOffset,
+		                                    uiSize,
+		                                    ui32NumPhysChunks * uiChunkSize,
+		                                    IMG_FALSE,
+		                                    IMG_TRUE,
+		                                    &psMemDesc->hRIHandle);
 		if( eError != PVRSRV_OK)
 		{
 			PVR_DPF((PVR_DBG_ERROR, "%s: call to BridgeRIWriteMEMDESCEntry failed (eError=%d)", __func__, eError));
@@ -1510,24 +1750,24 @@
 
 	*ppsMemDescPtr = psMemDesc;
 
-    return PVRSRV_OK;
+	return PVRSRV_OK;
 
-    /*
-      error exit paths follow
-    */
+	/*
+	  error exit paths follow
+	 */
 
 failDeviceMemAlloc:
-    _DevmemMemDescDiscard(psMemDesc);
+	_DevmemMemDescDiscard(psMemDesc);
 
 failMemDescAlloc:
 failParams:
-    PVR_ASSERT(eError != PVRSRV_OK);
+	PVR_ASSERT(eError != PVRSRV_OK);
 	PVR_DPF((PVR_DBG_ERROR,
 		"%s: Failed! Error is %s. Allocation size: %#llX",
 		__func__,
 		PVRSRVGETERRORSTRING(eError),
 		(unsigned long long) uiSize));
-    return eError;
+	return eError;
 }
 
 IMG_INTERNAL PVRSRV_ERROR
@@ -1705,23 +1945,23 @@
 
 	eError = _DevmemImportStructAlloc(hDevConnection,
 									  &psImport);
-    if (eError != PVRSRV_OK)
-    {
-        eError = PVRSRV_ERROR_OUT_OF_MEMORY;
-        goto failImportAlloc;
-    }
+	if (eError != PVRSRV_OK)
+	{
+		eError = PVRSRV_ERROR_OUT_OF_MEMORY;
+		goto failImportAlloc;
+	}
 
-    /* Get a handle to the PMR (inc refcount) */
+	/* Get a handle to the PMR (inc refcount) */
     eError = BridgePMRImportPMR(hDevConnection,
                                 psCookie->hPMRExportHandle,
                                 psCookie->uiPMRExportPassword,
                                 psCookie->uiSize, /* not trusted - just for sanity checks */
                                 psCookie->uiLog2ContiguityGuarantee, /* not trusted - just for sanity checks */
                                 &hPMR);
-    if (eError != PVRSRV_OK)
-    {
-        goto failImport;
-    }
+	if (eError != PVRSRV_OK)
+	{
+		goto failImport;
+	}
 
 	_DevmemImportStructInit(psImport,
 							psCookie->uiSize,
@@ -1739,6 +1979,7 @@
     *ppsMemDescPtr = psMemDesc;
 
 #if defined(PVR_RI_DEBUG)
+	if(PVRSRVIsBridgeEnabled(psMemDesc->psImport->hDevConnection, PVRSRV_BRIDGE_RI))
 	{
 		/* Attach RI information */
 		eError = BridgeRIWriteMEMDESCEntry (psMemDesc->psImport->hDevConnection,
@@ -1787,7 +2028,7 @@
 	DEVMEM_IMPORT *psImport = psMemDesc->psImport;
 
 	/* Stop if the allocation might have suballocations. */
-	if (psImport->uiProperties & DEVMEM_PROPERTIES_SUBALLOCATABLE)
+	if (!(psImport->uiProperties & DEVMEM_PROPERTIES_EXPORTABLE))
 	{
 		eError = PVRSRV_ERROR_INVALID_PARAMS;
 		PVR_DPF((PVR_DBG_ERROR,
@@ -1838,19 +2079,22 @@
 	{
 		psImport->uiProperties |= DEVMEM_PROPERTIES_UNPINNED;
 #if defined(PVR_RI_DEBUG)
-		if (psMemDesc->hRIHandle)
+		if(PVRSRVIsBridgeEnabled(psMemDesc->psImport->hDevConnection, PVRSRV_BRIDGE_RI))
 		{
-			PVRSRV_ERROR eError2;
-
-			eError2 = BridgeRIUpdateMEMDESCPinning(psMemDesc->psImport->hDevConnection,
-			                                       psMemDesc->hRIHandle,
-			                                       IMG_FALSE);
-
-			if( eError2 != PVRSRV_OK)
+			if (psMemDesc->hRIHandle)
 			{
-				PVR_DPF((PVR_DBG_ERROR, "%s: call to BridgeRIUpdateMEMDESCPinningKM failed (eError=%d)",
-				         __func__,
-				         eError));
+				PVRSRV_ERROR eError2;
+
+				eError2 = BridgeRIUpdateMEMDESCPinning(psMemDesc->psImport->hDevConnection,
+				                                       psMemDesc->hRIHandle,
+				                                       IMG_FALSE);
+
+				if( eError2 != PVRSRV_OK)
+				{
+					PVR_DPF((PVR_DBG_ERROR, "%s: call to BridgeRIUpdateMEMDESCPinningKM failed (eError=%d)",
+					         __func__,
+					         eError));
+				}
 			}
 		}
 #endif
@@ -1898,19 +2142,22 @@
 	{
 		psImport->uiProperties &= ~DEVMEM_PROPERTIES_UNPINNED;
 #if defined(PVR_RI_DEBUG)
-		if (psMemDesc->hRIHandle)
+		if(PVRSRVIsBridgeEnabled(psMemDesc->psImport->hDevConnection, PVRSRV_BRIDGE_RI))
 		{
-			PVRSRV_ERROR eError2;
-
-			eError2 = BridgeRIUpdateMEMDESCPinning(psMemDesc->psImport->hDevConnection,
-			                                       psMemDesc->hRIHandle,
-			                                       IMG_TRUE);
-
-			if( eError2 != PVRSRV_OK)
+			if (psMemDesc->hRIHandle)
 			{
-				PVR_DPF((PVR_DBG_ERROR, "%s: call to BridgeRIUpdateMEMDESCPinningKM failed (eError=%d)",
-				         __func__,
-				         eError));
+				PVRSRV_ERROR eError2;
+
+				eError2 = BridgeRIUpdateMEMDESCPinning(psMemDesc->psImport->hDevConnection,
+								       psMemDesc->hRIHandle,
+								       IMG_TRUE);
+
+				if( eError2 != PVRSRV_OK)
+				{
+					PVR_DPF((PVR_DBG_ERROR, "%s: call to BridgeRIUpdateMEMDESCPinningKM failed (eError=%d)",
+						 __func__,
+						 eError));
+				}
 			}
 		}
 #endif
@@ -1927,22 +2174,44 @@
 	return eError;
 }
 
+
+IMG_INTERNAL PVRSRV_ERROR
+DevmemGetSize(DEVMEM_MEMDESC *psMemDesc, IMG_DEVMEM_SIZE_T* puiSize)
+{
+	PVRSRV_ERROR eError = PVRSRV_OK;
+
+	*puiSize = psMemDesc->uiAllocSize;
+
+	return eError;
+}
+
 /*
 	This function is called for freeing any class of memory
 */
 IMG_INTERNAL void
 DevmemFree(DEVMEM_MEMDESC *psMemDesc)
 {
-#if defined(PVR_RI_DEBUG)
-	if (psMemDesc->hRIHandle)
+	if (psMemDesc->psImport->uiProperties & DEVMEM_PROPERTIES_SECURE)
 	{
-	    PVRSRV_ERROR eError;
+		PVR_DPF((PVR_DBG_ERROR,
+				"%s: Please use methods dedicated to secure buffers.",
+				__func__));
+		return;
+	}
 
-	    eError = BridgeRIDeleteMEMDESCEntry(psMemDesc->psImport->hDevConnection,
-					   	   	   	   psMemDesc->hRIHandle);
-		if( eError != PVRSRV_OK)
+#if defined(PVR_RI_DEBUG)
+	if(PVRSRVIsBridgeEnabled(psMemDesc->psImport->hDevConnection, PVRSRV_BRIDGE_RI))
+	{
+		if (psMemDesc->hRIHandle)
 		{
-			PVR_DPF((PVR_DBG_ERROR, "%s: call to BridgeRIDeleteMEMDESCEntry failed (eError=%d)", __func__, eError));
+		    PVRSRV_ERROR eError;
+
+		    eError = BridgeRIDeleteMEMDESCEntry(psMemDesc->psImport->hDevConnection,
+									   psMemDesc->hRIHandle);
+			if( eError != PVRSRV_OK)
+			{
+				PVR_DPF((PVR_DBG_ERROR, "%s: call to BridgeRIDeleteMEMDESCEntry failed (eError=%d)", __func__, eError));
+			}
 		}
 	}
 #endif  /* if defined(PVR_RI_DEBUG) */
@@ -2014,21 +2283,51 @@
     OSLockRelease(psMemDesc->sDeviceMemDesc.hLock);
 
 #if defined(SUPPORT_PAGE_FAULT_DEBUG)
-	BridgeDevicememHistoryMap(psMemDesc->psImport->hDevConnection,
-						psMemDesc->sDeviceMemDesc.sDevVAddr,
-						psMemDesc->uiAllocSize,
-						psMemDesc->sTraceData.szText);
+	if(PVRSRVIsBridgeEnabled(psMemDesc->psImport->hDevConnection, PVRSRV_BRIDGE_DEVICEMEMHISTORY))
+	{
+		static IMG_BOOL bHaveNewAPI = IMG_TRUE;
+		PVRSRV_ERROR eError;
+
+		if(bHaveNewAPI)
+		{
+			eError = BridgeDevicememHistoryMapNew(psMemDesc->psImport->hDevConnection,
+								psMemDesc->psImport->hPMR,
+								psMemDesc->uiOffset,
+								psMemDesc->sDeviceMemDesc.sDevVAddr,
+								psMemDesc->uiAllocSize,
+								psMemDesc->sTraceData.szText,
+								DevmemGetHeapLog2PageSize(psHeap),
+								psMemDesc->sTraceData.ui32AllocationIndex,
+								&psMemDesc->sTraceData.ui32AllocationIndex);
+
+			if(eError == PVRSRV_ERROR_BRIDGE_CALL_FAILED)
+			{
+				bHaveNewAPI = IMG_FALSE;
+			}
+		}
+
+		if(!bHaveNewAPI)
+		{
+			BridgeDevicememHistoryMap(psMemDesc->psImport->hDevConnection,
+								psMemDesc->sDeviceMemDesc.sDevVAddr,
+								psMemDesc->uiAllocSize,
+								psMemDesc->sTraceData.szText);
+		}
+	}
 #endif
 
 #if defined(PVR_RI_DEBUG)
-	if (psMemDesc->hRIHandle)
-    {
-		 eError = BridgeRIUpdateMEMDESCAddr(psImport->hDevConnection,
-    									   psMemDesc->hRIHandle,
-    									   psImport->sDeviceImport.sDevVAddr);
-		if( eError != PVRSRV_OK)
+	if(PVRSRVIsBridgeEnabled(psImport->hDevConnection, PVRSRV_BRIDGE_RI))
+	{
+		if (psMemDesc->hRIHandle)
 		{
-			PVR_DPF((PVR_DBG_ERROR, "%s: call to BridgeRIUpdateMEMDESCAddr failed (eError=%d)", __func__, eError));
+			 eError = BridgeRIUpdateMEMDESCAddr(psImport->hDevConnection,
+											   psMemDesc->hRIHandle,
+											   psImport->sDeviceImport.sDevVAddr);
+			if( eError != PVRSRV_OK)
+			{
+				PVR_DPF((PVR_DBG_ERROR, "%s: call to BridgeRIUpdateMEMDESCAddr failed (eError=%d)", __func__, eError));
+			}
 		}
 	}
 #endif
@@ -2109,21 +2408,51 @@
     OSLockRelease(psMemDesc->sDeviceMemDesc.hLock);
 
 #if defined(SUPPORT_PAGE_FAULT_DEBUG)
-	BridgeDevicememHistoryMap(psMemDesc->psImport->hDevConnection,
-						psMemDesc->sDeviceMemDesc.sDevVAddr,
-						psMemDesc->uiAllocSize,
-						psMemDesc->sTraceData.szText);
+	if(PVRSRVIsBridgeEnabled(psMemDesc->psImport->hDevConnection, PVRSRV_BRIDGE_DEVICEMEMHISTORY))
+	{
+		static IMG_BOOL bHaveNewAPI = IMG_TRUE;
+		PVRSRV_ERROR eError;
+
+		if(bHaveNewAPI)
+		{
+			eError = BridgeDevicememHistoryMapNew(psMemDesc->psImport->hDevConnection,
+								psMemDesc->psImport->hPMR,
+								psMemDesc->uiOffset,
+								psMemDesc->sDeviceMemDesc.sDevVAddr,
+								psMemDesc->uiAllocSize,
+								psMemDesc->sTraceData.szText,
+								DevmemGetHeapLog2PageSize(psHeap),
+								psMemDesc->sTraceData.ui32AllocationIndex,
+								&psMemDesc->sTraceData.ui32AllocationIndex);
+
+			if(eError == PVRSRV_ERROR_BRIDGE_CALL_FAILED)
+			{
+				bHaveNewAPI = IMG_FALSE;
+			}
+		}
+
+		if(!bHaveNewAPI)
+		{
+			BridgeDevicememHistoryMap(psMemDesc->psImport->hDevConnection,
+								psMemDesc->sDeviceMemDesc.sDevVAddr,
+								psMemDesc->uiAllocSize,
+								psMemDesc->sTraceData.szText);
+		}
+	}
 #endif
 
 #if defined(PVR_RI_DEBUG)
-	if (psMemDesc->hRIHandle)
-    {
-		 eError = BridgeRIUpdateMEMDESCAddr(psImport->hDevConnection,
-    									   psMemDesc->hRIHandle,
-    									   psImport->sDeviceImport.sDevVAddr);
-		if( eError != PVRSRV_OK)
+	if(PVRSRVIsBridgeEnabled(psImport->hDevConnection, PVRSRV_BRIDGE_RI))
+	{
+		if (psMemDesc->hRIHandle)
 		{
-			PVR_DPF((PVR_DBG_ERROR, "%s: call to BridgeRIUpdateMEMDESCAddr failed (eError=%d)", __func__, eError));
+			 eError = BridgeRIUpdateMEMDESCAddr(psImport->hDevConnection,
+											   psMemDesc->hRIHandle,
+											   psImport->sDeviceImport.sDevVAddr);
+			if( eError != PVRSRV_OK)
+			{
+				PVR_DPF((PVR_DBG_ERROR, "%s: call to BridgeRIUpdateMEMDESCAddr failed (eError=%d)", __func__, eError));
+			}
 		}
 	}
 #endif
@@ -2197,10 +2526,37 @@
 	if (--psMemDesc->sDeviceMemDesc.ui32RefCount == 0)
 	{
 #if defined(SUPPORT_PAGE_FAULT_DEBUG)
-		BridgeDevicememHistoryUnmap(psMemDesc->psImport->hDevConnection,
-							psMemDesc->sDeviceMemDesc.sDevVAddr,
-							psMemDesc->uiAllocSize,
-							psMemDesc->sTraceData.szText);
+		if(PVRSRVIsBridgeEnabled(psMemDesc->psImport->hDevConnection, PVRSRV_BRIDGE_DEVICEMEMHISTORY))
+		{
+			static IMG_BOOL bHaveNewAPI = IMG_TRUE;
+			PVRSRV_ERROR eError;
+
+			if(bHaveNewAPI)
+			{
+				eError = BridgeDevicememHistoryUnmapNew(psMemDesc->psImport->hDevConnection,
+									psMemDesc->psImport->hPMR,
+									psMemDesc->uiOffset,
+									psMemDesc->sDeviceMemDesc.sDevVAddr,
+									psMemDesc->uiAllocSize,
+									psMemDesc->sTraceData.szText,
+									DevmemGetHeapLog2PageSize(psMemDesc->psImport->sDeviceImport.psHeap),
+									psMemDesc->sTraceData.ui32AllocationIndex,
+									&psMemDesc->sTraceData.ui32AllocationIndex);
+
+				if(eError == PVRSRV_ERROR_BRIDGE_CALL_FAILED)
+				{
+					bHaveNewAPI = IMG_FALSE;
+				}
+			}
+
+			if(!bHaveNewAPI)
+			{
+				BridgeDevicememHistoryUnmap(psMemDesc->psImport->hDevConnection,
+									psMemDesc->sDeviceMemDesc.sDevVAddr,
+									psMemDesc->uiAllocSize,
+									psMemDesc->sTraceData.szText);
+			}
+		}
 #endif
 		_DevmemImportStructDevUnmap(psMemDesc->psImport);
 		OSLockRelease(psMemDesc->sDeviceMemDesc.hLock);
@@ -2219,9 +2575,13 @@
 {
 	PVRSRV_ERROR eError;
 
-	/* Do not try to map unpinned memory */
-	if (psMemDesc->psImport->uiProperties & DEVMEM_PROPERTIES_UNPINNED)
+	if ( psMemDesc->psImport->uiProperties &
+	    (DEVMEM_PROPERTIES_UNPINNED | DEVMEM_PROPERTIES_SECURE) )
 	{
+		PVR_DPF((PVR_DBG_ERROR,
+				"%s: Allocation is currently unpinned or a secure buffer. "
+				"Not possible to map to CPU!",
+				__func__));
 		eError = PVRSRV_ERROR_INVALID_MAP_REQUEST;
 		goto failFlags;
 	}
@@ -2367,12 +2727,19 @@
 	return PVRSRV_OK;
 }
 
+IMG_INTERNAL IMG_HANDLE
+DevmemGetConnection(DEVMEM_MEMDESC *psMemDesc)
+{
+	return psMemDesc->psImport->hDevConnection;
+}
+
 IMG_INTERNAL PVRSRV_ERROR
 DevmemLocalImport(IMG_HANDLE hBridge,
 				  IMG_HANDLE hExtHandle,
 				  DEVMEM_FLAGS_T uiFlags,
 				  DEVMEM_MEMDESC **ppsMemDescPtr,
-				  IMG_DEVMEM_SIZE_T *puiSizePtr)
+				  IMG_DEVMEM_SIZE_T *puiSizePtr,
+				  const IMG_CHAR *pszAnnotation)
 {
     DEVMEM_MEMDESC *psMemDesc = NULL;
     DEVMEM_IMPORT *psImport;
@@ -2385,7 +2752,7 @@
     {
         eError = PVRSRV_ERROR_INVALID_PARAMS;
         goto failParams;
-    }	
+    }
 
 	eError =_DevmemMemDescAlloc(&psMemDesc);
     if (eError != PVRSRV_OK)
@@ -2401,7 +2768,7 @@
         goto failImportAlloc;
     }
 
-	/* Get the PMR handle and it's size from the server */
+	/* Get the PMR handle and its size from the server */
 	eError = BridgePMRLocalImportPMR(hBridge,
 									 hExtHandle,
 									 &hPMR,
@@ -2430,15 +2797,18 @@
 		*puiSizePtr = uiSize;
 
 #if defined(PVR_RI_DEBUG)
+	if(PVRSRVIsBridgeEnabled(psMemDesc->psImport->hDevConnection, PVRSRV_BRIDGE_RI))
 	{
-		/* Attach RI information */
+		/* Attach RI information.
+		 * Set backed size to 0 since this allocation has been allocated
+		 * by the same process and has been accounted for. */
 		eError = BridgeRIWriteMEMDESCEntry (psMemDesc->psImport->hDevConnection,
 											psMemDesc->psImport->hPMR,
 											sizeof("^"),
 											"^",
 											psMemDesc->uiOffset,
 											psMemDesc->psImport->uiSize,
-											psMemDesc->psImport->uiSize,
+											0,
 											IMG_TRUE,
 											IMG_FALSE,
 											&(psMemDesc->hRIHandle));
@@ -2448,6 +2818,19 @@
 		}
 	}
 #endif /* if defined(PVR_RI_DEBUG) */
+
+#if defined(SUPPORT_PAGE_FAULT_DEBUG)
+	if(PVRSRVIsBridgeEnabled(psMemDesc->psImport->hDevConnection, PVRSRV_BRIDGE_DEVICEMEMHISTORY))
+	{
+		/* copy the allocation descriptive name and size so it can be passed to DevicememHistory when
+		* the allocation gets mapped/unmapped
+		*/
+		OSStringNCopy(psMemDesc->sTraceData.szText, pszAnnotation, sizeof(psMemDesc->sTraceData.szText) - 1);
+	}
+#else
+	PVR_UNREFERENCED_PARAMETER(pszAnnotation);
+#endif
+
 	return PVRSRV_OK;
 
 failImport:
@@ -2477,8 +2860,45 @@
 }
 
 IMG_INTERNAL IMG_UINT32
-DevmemGetHeapLog2ImportAlignment(DEVMEM_HEAP *psHeap)
+DevmemGetHeapTilingProperties(DEVMEM_HEAP *psHeap,
+                              IMG_UINT32 *puiLog2ImportAlignment,
+                              IMG_UINT32 *puiLog2TilingStrideFactor)
 {
-	return psHeap->uiLog2ImportAlignment;
+	*puiLog2ImportAlignment = psHeap->uiLog2ImportAlignment;
+	*puiLog2TilingStrideFactor = psHeap->uiLog2TilingStrideFactor;
+	return PVRSRV_OK;
 }
 
+/**************************************************************************/ /*!
+@Function       RegisterDevMemPFNotify
+@Description    Registers that the application wants to be signaled when a page
+                fault occurs.
+
+@Input          psContext      Memory context the process that would like to
+                               be notified about.
+@Input          ui32PID        The PID  of the calling process.
+@Input          bRegister      If true, register. If false, de-register.
+@Return         PVRSRV_ERROR:  PVRSRV_OK on success. Otherwise, a PVRSRV_
+                               error code
+*/ /***************************************************************************/
+IMG_INTERNAL PVRSRV_ERROR
+RegisterDevmemPFNotify(DEVMEM_CONTEXT *psContext,
+                       IMG_UINT32     ui32PID,
+                       IMG_BOOL       bRegister)
+{
+	PVRSRV_ERROR eError;
+
+	eError = BridgeDevmemIntRegisterPFNotifyKM(psContext->hDevConnection,
+	                                           psContext->hDevMemServerContext,
+	                                           ui32PID,
+	                                           bRegister);
+	if (eError == PVRSRV_ERROR_BRIDGE_CALL_FAILED)
+	{
+		PVR_DPF((PVR_DBG_ERROR,
+		         "%s: Bridge Call Failed: This could suggest a UM/KM miss-match (%d)",
+		         __func__,
+		         (IMG_INT)(eError)));
+	}
+
+	return eError;
+}
diff --git a/drivers/staging/imgtec/rogue/devicemem.h b/drivers/staging/imgtec/rogue/devicemem.h
index 9fbf918..bcbf5a6 100644
--- a/drivers/staging/imgtec/rogue/devicemem.h
+++ b/drivers/staging/imgtec/rogue/devicemem.h
@@ -112,16 +112,6 @@
 #include "device_connection.h"
 
 
-/* Use GET and SET function to access this */
-IMG_INTERNAL extern IMG_UINT32  g_uiLog2PageSize;
-
-#define GET_LOG2_PAGESIZE() ( (const IMG_UINT32) g_uiLog2PageSize )
-#define SET_LOG2_PAGESIZE(ui32Log2PageSize) \
-	{ \
-		PVR_ASSERT( (ui32Log2PageSize > 11) && (ui32Log2PageSize < 22) ); \
-		g_uiLog2PageSize = (IMG_UINT32) ui32Log2PageSize; \
-	}
-
 typedef IMG_UINT32 DEVMEM_HEAPCFGID;
 #define DEVMEM_HEAPCFG_FORCLIENTS 0
 #define DEVMEM_HEAPCFG_META 1
@@ -173,6 +163,13 @@
 IMG_INTERNAL PVRSRV_ERROR
 DevmemPin(DEVMEM_MEMDESC *psMemDesc);
 
+IMG_INTERNAL PVRSRV_ERROR
+DevmemGetHeapInt(DEVMEM_HEAP *psHeap,
+				 IMG_HANDLE *phDevmemHeap);
+
+IMG_INTERNAL PVRSRV_ERROR
+DevmemGetSize(DEVMEM_MEMDESC *psMemDesc,
+			  IMG_DEVMEM_SIZE_T* puiSize);
 
 /*
  * DevmemCreateContext()
@@ -275,6 +272,9 @@
                  IMG_UINT32 ui32Log2Quantum,
                  /* The minimum import alignment for this heap */
                  IMG_UINT32 ui32Log2ImportAlignment,
+                 /* (For tiling heaps) the factor to use to convert
+                    alignment to optimum buffer stride */
+                 IMG_UINT32 ui32Log2TilingStrideFactor,
                  /* Name of heap for debug */
                  /* N.B.  Okay to exist on caller's stack - this
                     func takes a copy if it needs it. */
@@ -297,7 +297,9 @@
  * Compute the Size and Align passed to avoid suballocations (used when allocation with PVRSRV_MEMALLOCFLAG_EXPORTALIGN)
  */
 IMG_INTERNAL void
-DevmemExportalignAdjustSizeAndAlign(DEVMEM_HEAP *psHeap, IMG_DEVMEM_SIZE_T *puiSize, IMG_DEVMEM_ALIGN_T *puiAlign);
+DevmemExportalignAdjustSizeAndAlign(IMG_UINT32 uiLog2Quantum,
+                                    IMG_DEVMEM_SIZE_T *puiSize,
+                                    IMG_DEVMEM_ALIGN_T *puiAlign);
 
 /*
  * DevmemSubAllocate()
@@ -332,7 +334,7 @@
                   IMG_DEVMEM_SIZE_T uiSize,
                   IMG_DEVMEM_ALIGN_T uiAlign,
                   DEVMEM_FLAGS_T uiFlags,
-                  const IMG_PCHAR pszText,
+                  const IMG_CHAR *pszText,
                   DEVMEM_MEMDESC **ppsMemDescPtr);
 
 #define DevmemAllocate(...) \
@@ -340,32 +342,33 @@
 
 PVRSRV_ERROR
 DevmemAllocateExportable(SHARED_DEV_CONNECTION hDevConnection,
-						 IMG_DEVMEM_SIZE_T uiSize,
-						 IMG_DEVMEM_ALIGN_T uiAlign,
-						 DEVMEM_FLAGS_T uiFlags,
-						 const IMG_PCHAR pszText,
-						 DEVMEM_MEMDESC **ppsMemDescPtr);
+                         IMG_DEVMEM_SIZE_T uiSize,
+                         IMG_DEVMEM_ALIGN_T uiAlign,
+                         IMG_UINT32 uiLog2HeapPageSize,
+                         DEVMEM_FLAGS_T uiFlags,
+                         const IMG_CHAR *pszText,
+                         DEVMEM_MEMDESC **ppsMemDescPtr);
 
 PVRSRV_ERROR
 DeviceMemChangeSparse(DEVMEM_MEMDESC *psMemDesc,
-					  IMG_UINT32 ui32AllocPageCount,
-					  IMG_UINT32 *paui32AllocPageIndices,
-					  IMG_UINT32 ui32FreePageCount,
-					  IMG_UINT32 *pauiFreePageIndices,
-					  SPARSE_MEM_RESIZE_FLAGS uiFlags,
-					  IMG_UINT32 *pui32Status);
+                      IMG_UINT32 ui32AllocPageCount,
+                      IMG_UINT32 *paui32AllocPageIndices,
+                      IMG_UINT32 ui32FreePageCount,
+                      IMG_UINT32 *pauiFreePageIndices,
+                      SPARSE_MEM_RESIZE_FLAGS uiFlags);
 
 PVRSRV_ERROR
 DevmemAllocateSparse(SHARED_DEV_CONNECTION hDevConnection,
-					 IMG_DEVMEM_SIZE_T uiSize,
-					 IMG_DEVMEM_SIZE_T uiChunkSize,
-					 IMG_UINT32 ui32NumPhysChunks,
-					 IMG_UINT32 ui32NumVirtChunks,
-					 IMG_UINT32 *pui32MappingTable,
-					 IMG_DEVMEM_ALIGN_T uiAlign,
-					 DEVMEM_FLAGS_T uiFlags,
-					 const IMG_PCHAR pszText,
-					 DEVMEM_MEMDESC **ppsMemDescPtr);
+                     IMG_DEVMEM_SIZE_T uiSize,
+                     IMG_DEVMEM_SIZE_T uiChunkSize,
+                     IMG_UINT32 ui32NumPhysChunks,
+                     IMG_UINT32 ui32NumVirtChunks,
+                     IMG_UINT32 *pui32MappingTable,
+                     IMG_DEVMEM_ALIGN_T uiAlign,
+                     IMG_UINT32 uiLog2HeapPageSize,
+                     DEVMEM_FLAGS_T uiFlags,
+                     const IMG_CHAR *pszText,
+                     DEVMEM_MEMDESC **ppsMemDescPtr);
 
 /*
  * DevmemFree()
@@ -551,7 +554,8 @@
                   IMG_DEV_VIRTADDR *psDevVAddrBaseOut,
                   IMG_DEVMEM_SIZE_T *puiHeapLengthOut,
                   IMG_UINT32 *puiLog2DataPageSize,
-                  IMG_UINT32 *puiLog2ImportAlignmentOut);
+                  IMG_UINT32 *puiLog2ImportAlignmentOut,
+                  IMG_UINT32 *puiLog2TilingStrideFactor);
 
 /*
  * Devmem_FindHeapByName()
@@ -596,12 +600,16 @@
 DevmemGetFlags(DEVMEM_MEMDESC *psMemDesc,
 				DEVMEM_FLAGS_T *puiFlags);
 
+IMG_INTERNAL IMG_HANDLE
+DevmemGetConnection(DEVMEM_MEMDESC *psMemDesc);
+
 PVRSRV_ERROR
 DevmemLocalImport(IMG_HANDLE hBridge,
 				  IMG_HANDLE hExtHandle,
 				  DEVMEM_FLAGS_T uiFlags,
 				  DEVMEM_MEMDESC **ppsMemDescPtr,
-				  IMG_DEVMEM_SIZE_T *puiSizePtr);
+				  IMG_DEVMEM_SIZE_T *puiSizePtr,
+				  const IMG_CHAR *pszAnnotation);
 
 IMG_INTERNAL PVRSRV_ERROR
 DevmemIsDevVirtAddrValid(DEVMEM_CONTEXT *psContext,
@@ -614,11 +622,30 @@
 IMG_UINT32
 DevmemGetHeapLog2PageSize(DEVMEM_HEAP *psHeap);
 
-/* DevmemGetHeapLog2ImportAlignment()
+/* DevmemGetHeapTilingProperties()
  *
- * Get the import alignment used for a certain heap.
+ * Get the import alignment and tiling stride factor used for a certain heap.
  */
 IMG_UINT32
-DevmemGetHeapLog2ImportAlignment(DEVMEM_HEAP *psHeap);
+DevmemGetHeapTilingProperties(DEVMEM_HEAP *psHeap,
+                              IMG_UINT32 *puiLog2ImportAlignment,
+                              IMG_UINT32 *puiLog2TilingStrideFactor);
+
+/**************************************************************************/ /*!
+@Function       RegisterDevMemPFNotify
+@Description    Registers that the application wants to be signaled when a page
+                fault occurs.
+
+@Input          psContext      Memory context the process that would like to
+                               be notified about.
+@Input          ui32PID        The PID  of the calling process.
+@Input          bRegister      If true, register. If false, de-register.
+@Return         PVRSRV_ERROR:  PVRSRV_OK on success. Otherwise, a PVRSRV_
+                               error code
+*/ /***************************************************************************/
+IMG_INTERNAL PVRSRV_ERROR
+RegisterDevmemPFNotify(DEVMEM_CONTEXT *psContext,
+                       IMG_UINT32     ui32PID,
+                       IMG_BOOL       bRegister);
 
 #endif /* #ifndef SRVCLIENT_DEVICEMEM_CLIENT_H */
diff --git a/drivers/staging/imgtec/rogue/devicemem_heapcfg.c b/drivers/staging/imgtec/rogue/devicemem_heapcfg.c
index d14be4d..bb5f566 100644
--- a/drivers/staging/imgtec/rogue/devicemem_heapcfg.c
+++ b/drivers/staging/imgtec/rogue/devicemem_heapcfg.c
@@ -134,5 +134,11 @@
     *puiLog2DataPageSizeOut = psHeapBlueprint->uiLog2DataPageSize;
     *puiLog2ImportAlignmentOut = psHeapBlueprint->uiLog2ImportAlignment;
 
-    return PVRSRV_OK;    
+    /* REL/1.8 maintain bridge compatibility
+     *   4:0 - uiLog2ImportAlignment (13--20)
+     * 18:16 - uiLog2TilingStrideFactor (3--4)
+     */
+    *puiLog2ImportAlignmentOut |= (psHeapBlueprint->uiLog2TilingStrideFactor << 16);
+
+    return PVRSRV_OK;
 }
diff --git a/drivers/staging/imgtec/rogue/devicemem_heapcfg.h b/drivers/staging/imgtec/rogue/devicemem_heapcfg.h
index c74ddd8..f8a42bf 100644
--- a/drivers/staging/imgtec/rogue/devicemem_heapcfg.h
+++ b/drivers/staging/imgtec/rogue/devicemem_heapcfg.h
@@ -44,12 +44,16 @@
 #ifndef __DEVICEMEMHEAPCFG_H__
 #define __DEVICEMEMHEAPCFG_H__
 
+#include <powervr/mem_types.h>
+
 #include "img_types.h"
 #include "pvrsrv_error.h"
 
 
 
+/* FIXME: Find a better way of defining _PVRSRV_DEVICE_NODE_ */
 struct _PVRSRV_DEVICE_NODE_;
+/* FIXME: Find a better way of defining _CONNECTION_DATA_ */
 struct _CONNECTION_DATA_;
 
 
@@ -66,40 +70,45 @@
 /* blueprint for a single heap */
 typedef struct _DEVMEM_HEAP_BLUEPRINT_
 {
-    /* Name of this heap - for debug purposes, and perhaps for lookup
-       by name? */
-    const IMG_CHAR *pszName;
+	/* Name of this heap - for debug purposes, and perhaps for lookup
+	by name? */
+	const IMG_CHAR *pszName;
 
-    /* Virtual address of the beginning of the heap.  This _must_ be a
-       multiple of the data page size for the heap.  It is
-       _recommended_ that it be coarser than that - especially, it
-       should begin on a boundary appropriate to the MMU for the
-       device.  For Rogue, this is a Page Directory boundary, or 1GB
-       (virtual address a multiple of 0x0040000000). */
-    IMG_DEV_VIRTADDR sHeapBaseAddr;
+	/* Virtual address of the beginning of the heap.  This _must_ be a
+	multiple of the data page size for the heap.  It is
+	_recommended_ that it be coarser than that - especially, it
+	should begin on a boundary appropriate to the MMU for the
+	device.  For Rogue, this is a Page Directory boundary, or 1GB
+	(virtual address a multiple of 0x0040000000). */
+	IMG_DEV_VIRTADDR sHeapBaseAddr;
 
-    /* Length of the heap.  Given that the END address of the heap has
-       a similar restriction to that of the _beginning_ of the heap.
-       That is the heap length _must_ be a whole number of data pages.
-       Again, the recommendation is that it ends on a 1GB boundary.
-       Again, this is not essential, but we do know that (at the time
-       of writing) the current implementation of mmu_common.c is such
-       that no two heaps may share a page directory, thus the
-       remaining virtual space would be wasted if the length were not
-       a multiple of 1GB */
-    IMG_DEVMEM_SIZE_T uiHeapLength;
+	/* Length of the heap.  Given that the END address of the heap has
+	a similar restriction to that of the _beginning_ of the heap.
+	That is the heap length _must_ be a whole number of data pages.
+	Again, the recommendation is that it ends on a 1GB boundary.
+	Again, this is not essential, but we do know that (at the time
+	of writing) the current implementation of mmu_common.c is such
+	that no two heaps may share a page directory, thus the
+	remaining virtual space would be wasted if the length were not
+	a multiple of 1GB */
+	IMG_DEVMEM_SIZE_T uiHeapLength;
 
-    /* Data page size.  This is the page size that is going to get
-       programmed into the MMU, so it needs to be a valid one for the
-       device.  Importantly, the start address and length _must_ be
-       multiples of this page size.  Note that the page size is
-       specified as the log 2 relative to 1 byte (e.g. 12 indicates
-       4kB) */
-    IMG_UINT32 uiLog2DataPageSize;
+	/* Data page size.  This is the page size that is going to get
+	programmed into the MMU, so it needs to be a valid one for the
+	device.  Importantly, the start address and length _must_ be
+	multiples of this page size.  Note that the page size is
+	specified as the log 2 relative to 1 byte (e.g. 12 indicates
+	4kB) */
+	IMG_UINT32 uiLog2DataPageSize;
 
-    /* Import alignment.  Force imports to this heap to be
-       aligned to at least this value */
-    IMG_UINT32 uiLog2ImportAlignment;
+	/* Import alignment.  Force imports to this heap to be
+	aligned to at least this value */
+	IMG_UINT32 uiLog2ImportAlignment;
+
+	/* Tiled heaps have an optimum byte-stride, this can be derived from
+	the heap alignment and tiling mode. This is abstracted here such that
+	Log2ByteStride = Log2Alignment - Log2TilingStrideFactor */
+	IMG_UINT32 uiLog2TilingStrideFactor;
 } DEVMEM_HEAP_BLUEPRINT;
 
 /* entire named heap config */
diff --git a/drivers/staging/imgtec/rogue/devicemem_history_server.c b/drivers/staging/imgtec/rogue/devicemem_history_server.c
index 60c8b5b..e6d1d35 100644
--- a/drivers/staging/imgtec/rogue/devicemem_history_server.c
+++ b/drivers/staging/imgtec/rogue/devicemem_history_server.c
@@ -46,35 +46,156 @@
 #include "pvrsrv.h"
 #include "pvrsrv_device.h"
 #include "pvr_debug.h"
-#include "dllist.h"
-#include "syscommon.h"
 #include "devicemem_server.h"
 #include "lock.h"
 #include "devicemem_history_server.h"
+#include "pdump_km.h"
 
-/* a device memory allocation */
-typedef struct _DEVICEMEM_HISTORY_ALLOCATION_
+#define ALLOCATION_LIST_NUM_ENTRIES 10000
+
+/* data type to hold an allocation index.
+ * we make it 16 bits wide if possible
+ */
+#if ALLOCATION_LIST_NUM_ENTRIES <= 0xFFFF
+typedef uint16_t ALLOC_INDEX_T;
+#else
+typedef uint32_t ALLOC_INDEX_T;
+#endif
+
+/* a record describing a single allocation known to DeviceMemHistory.
+ * this is an element in a doubly linked list of allocations
+ */
+typedef struct _RECORD_ALLOCATION_
 {
+	/* time when this RECORD_ALLOCATION was created/initialised */
+	IMG_UINT64 ui64CreationTime;
+	/* serial number of the PMR relating to this allocation */
+	IMG_UINT64 ui64Serial;
+	/* base DevVAddr of this allocation */
 	IMG_DEV_VIRTADDR sDevVAddr;
+	/* size in bytes of this allocation */
 	IMG_DEVMEM_SIZE_T uiSize;
-	IMG_CHAR szString[DEVICEMEM_HISTORY_TEXT_BUFSZ];
-	IMG_UINT64 ui64Time;
-	/* FALSE if this allocation has been freed */
-	IMG_BOOL bAllocated;
+	/* Log2 page size of this allocation's GPU pages */
+	IMG_UINT32 ui32Log2PageSize;
+	/* Process ID (PID) this allocation belongs to */
 	IMG_PID uiPID;
-} DEVICEMEM_HISTORY_ALLOCATION;
+	/* index of previous allocation in the list */
+	ALLOC_INDEX_T ui32Prev;
+	/* index of next allocation in the list */
+	ALLOC_INDEX_T ui32Next;
+	/* annotation/name of this allocation */
+	IMG_CHAR szName[DEVICEMEM_HISTORY_TEXT_BUFSZ];
+} RECORD_ALLOCATION;
 
-/* this number of entries makes the history buffer allocation just under 2MB */
-#define DEVICEMEM_HISTORY_ALLOCATION_HISTORY_LEN 29127
+/* each command in the circular buffer is prefixed with an 8-bit value
+ * denoting the command type
+ */
+typedef enum _COMMAND_TYPE_
+{
+	COMMAND_TYPE_NONE,
+	COMMAND_TYPE_TIMESTAMP,
+	COMMAND_TYPE_MAP_ALL,
+	COMMAND_TYPE_UNMAP_ALL,
+	COMMAND_TYPE_MAP_RANGE,
+	COMMAND_TYPE_UNMAP_RANGE,
+	/* sentinel value */
+	COMMAND_TYPE_COUNT,
+} COMMAND_TYPE;
 
-#define DECREMENT_WITH_WRAP(value, sz) ((value) ? ((value) - 1) : ((sz) - 1))
+/* Timestamp command:
+ * This command is inserted into the circular buffer to provide an updated
+ * timestamp.
+ * The nanosecond-accuracy timestamp is packed into a 56-bit integer, in order
+ * for the whole command to fit into 8 bytes.
+ */
+typedef struct _COMMAND_TIMESTAMP_
+{
+	IMG_UINT8 aui8TimeNs[7];
+} COMMAND_TIMESTAMP;
+
+/* MAP_ALL command:
+ * This command denotes the allocation at the given index was wholly mapped
+ * in to the GPU MMU
+ */
+typedef struct _COMMAND_MAP_ALL_
+{
+	ALLOC_INDEX_T uiAllocIndex;
+} COMMAND_MAP_ALL;
+
+/* UNMAP_ALL command:
+ * This command denotes the allocation at the given index was wholly unmapped
+ * from the GPU MMU
+ * Note: COMMAND_MAP_ALL and COMMAND_UNMAP_ALL commands have the same layout.
+ */
+typedef COMMAND_MAP_ALL COMMAND_UNMAP_ALL;
+
+/* packing attributes for the MAP_RANGE command */
+#define MAP_RANGE_MAX_START ((1 << 18) - 1)
+#define MAP_RANGE_MAX_RANGE ((1 << 12) - 1)
+
+/* MAP_RANGE command:
+ * Denotes a range of pages within the given allocation being mapped.
+ * The range is expressed as [Page Index] + [Page Count]
+ * This information is packed into a 40-bit integer, in order to make
+ * the command size 8 bytes.
+ */
+
+typedef struct _COMMAND_MAP_RANGE_
+{
+	IMG_UINT8 aui8Data[5];
+	ALLOC_INDEX_T uiAllocIndex;
+} COMMAND_MAP_RANGE;
+
+/* UNMAP_RANGE command:
+ * Denotes a range of pages within the given allocation being mapped.
+ * The range is expressed as [Page Index] + [Page Count]
+ * This information is packed into a 40-bit integer, in order to make
+ * the command size 8 bytes.
+ * Note: COMMAND_MAP_RANGE and COMMAND_UNMAP_RANGE commands have the same layout.
+ */
+typedef COMMAND_MAP_RANGE COMMAND_UNMAP_RANGE;
+
+/* wrapper structure for a command */
+typedef struct _COMMAND_WRAPPER_
+{
+	IMG_UINT8 ui8Type;
+	union {
+		COMMAND_TIMESTAMP sTimeStamp;
+		COMMAND_MAP_ALL sMapAll;
+		COMMAND_UNMAP_ALL sUnmapAll;
+		COMMAND_MAP_RANGE sMapRange;
+		COMMAND_UNMAP_RANGE sUnmapRange;
+	} u;
+} COMMAND_WRAPPER;
+
+/* target size for the circular buffer of commands */
+#define CIRCULAR_BUFFER_SIZE_KB 2048
+/* turn the circular buffer target size into a number of commands */
+#define CIRCULAR_BUFFER_NUM_COMMANDS ((CIRCULAR_BUFFER_SIZE_KB * 1024) / sizeof(COMMAND_WRAPPER))
+
+/* index value denoting the end of a list */
+#define END_OF_LIST 0xFFFFFFFF
+#define ALLOC_INDEX_TO_PTR(idx) (&(gsDevicememHistoryData.sRecords.pasAllocations[idx]))
+#define CHECK_ALLOC_INDEX(idx) (idx < ALLOCATION_LIST_NUM_ENTRIES)
+
+/* wrapper structure for the allocation records and the commands circular buffer */
+typedef struct _RECORDS_
+{
+	RECORD_ALLOCATION *pasAllocations;
+	IMG_UINT32 ui32AllocationsListHead;
+
+	IMG_UINT32 ui32Head;
+	IMG_UINT32 ui32Tail;
+	COMMAND_WRAPPER *pasCircularBuffer;;
+} RECORDS;
 
 typedef struct _DEVICEMEM_HISTORY_DATA_
 {
-	IMG_UINT32 ui32Head;
-	DEVICEMEM_HISTORY_ALLOCATION *psAllocations;
-	POS_LOCK hLock;
+	/* debugfs entry */
 	void *pvStatsEntry;
+
+	RECORDS sRecords;
+	POS_LOCK hLock;
 } DEVICEMEM_HISTORY_DATA;
 
 static DEVICEMEM_HISTORY_DATA gsDevicememHistoryData = { 0 };
@@ -89,13 +210,11 @@
 	OSLockRelease(gsDevicememHistoryData.hLock);
 }
 
-/* given a time stamp, calculate the age in nanoseconds (relative to now) */
-static IMG_UINT64 _CalculateAge(IMG_UINT64 ui64Then)
+/* given a time stamp, calculate the age in nanoseconds */
+static IMG_UINT64 _CalculateAge(IMG_UINT64 ui64Now,
+						IMG_UINT64 ui64Then,
+						IMG_UINT64 ui64Max)
 {
-	IMG_UINT64 ui64Now;
-
-	ui64Now = OSClockns64();
-
 	if(ui64Now >= ui64Then)
 	{
 		/* no clock wrap */
@@ -104,30 +223,1544 @@
 	else
 	{
 		/* clock has wrapped */
-		return ((~(IMG_UINT64) 0) - ui64Then) + ui64Now + 1;
+		return (ui64Max - ui64Then) + ui64Now + 1;
 	}
 }
 
-static void DeviceMemHistoryFmt(IMG_UINT32 ui32Off, IMG_CHAR szBuffer[PVR_MAX_DEBUG_MESSAGE_LEN])
+/* AcquireCBSlot:
+ * Acquire the next slot in the circular buffer and
+ * move the circular buffer head along by one
+ * Returns a pointer to the acquired slot.
+ */
+static COMMAND_WRAPPER *AcquireCBSlot(void)
 {
-	DEVICEMEM_HISTORY_ALLOCATION *psAlloc;
+	COMMAND_WRAPPER *psSlot;
 
-	psAlloc = &gsDevicememHistoryData.psAllocations[ui32Off % DEVICEMEM_HISTORY_ALLOCATION_HISTORY_LEN];
+	psSlot = &gsDevicememHistoryData.sRecords.pasCircularBuffer[gsDevicememHistoryData.sRecords.ui32Head];
+
+	gsDevicememHistoryData.sRecords.ui32Head =
+		(gsDevicememHistoryData.sRecords.ui32Head + 1)
+				% CIRCULAR_BUFFER_NUM_COMMANDS;
+
+	return psSlot;
+}
+
+/* TimeStampPack:
+ * Packs the given timestamp value into the COMMAND_TIMESTAMP structure.
+ * This takes a 64-bit nanosecond timestamp and packs it in to a 56-bit
+ * integer in the COMMAND_TIMESTAMP command.
+ */
+static void TimeStampPack(COMMAND_TIMESTAMP *psTimeStamp, IMG_UINT64 ui64Now)
+{
+	IMG_UINT32 i;
+
+	for(i = 0; i < IMG_ARR_NUM_ELEMS(psTimeStamp->aui8TimeNs); i++)
+	{
+		psTimeStamp->aui8TimeNs[i] = ui64Now & 0xFF;
+		ui64Now >>= 8;
+	}
+}
+
+/* packing a 64-bit nanosecond into a 7-byte integer loses the
+ * top 8 bits of data. This must be taken into account when
+ * comparing a full timestamp against an unpacked timestamp
+ */
+#define TIME_STAMP_MASK ((1LLU << 56) - 1)
+#define DO_TIME_STAMP_MASK(ns64) (ns64 & TIME_STAMP_MASK)
+
+/* TimeStampUnpack:
+ * Unpack the timestamp value from the given COMMAND_TIMESTAMP command
+ */
+static IMG_UINT64 TimeStampUnpack(COMMAND_TIMESTAMP *psTimeStamp)
+{
+	IMG_UINT64 ui64TimeNs = 0;
+	IMG_UINT32 i;
+
+	for(i = IMG_ARR_NUM_ELEMS(psTimeStamp->aui8TimeNs); i > 0; i--)
+	{
+		ui64TimeNs <<= 8;
+		ui64TimeNs |= psTimeStamp->aui8TimeNs[i - 1];
+	}
+
+	return ui64TimeNs;
+}
+
+#if defined(PDUMP)
+
+static void EmitPDumpAllocation(IMG_UINT32 ui32AllocationIndex,
+					RECORD_ALLOCATION *psAlloc)
+{
+	PDUMPCOMMENT("[SrvPFD] Allocation: %u"
+			" Addr: " IMG_DEV_VIRTADDR_FMTSPEC
+			" Size: " IMG_DEVMEM_SIZE_FMTSPEC
+			" Page size: %u"
+			" PID: %u"
+			" Process: %s"
+			" Name: %s",
+			ui32AllocationIndex,
+			psAlloc->sDevVAddr.uiAddr,
+			psAlloc->uiSize,
+			1U << psAlloc->ui32Log2PageSize,
+			psAlloc->uiPID,
+			OSGetCurrentClientProcessNameKM(),
+			psAlloc->szName);
+}
+
+static void EmitPDumpMapUnmapAll(COMMAND_TYPE eType,
+					IMG_UINT32 ui32AllocationIndex)
+{
+	const IMG_CHAR *pszOpName;
+
+	switch(eType)
+	{
+		case COMMAND_TYPE_MAP_ALL:
+			pszOpName = "MAP_ALL";
+			break;
+		case COMMAND_TYPE_UNMAP_ALL:
+			pszOpName = "UNMAP_ALL";
+			break;
+		default:
+			PVR_DPF((PVR_DBG_ERROR, "EmitPDumpMapUnmapAll: Invalid type: %u",
+										eType));
+			return;
+
+	}
+
+	PDUMPCOMMENT("[SrvPFD] Op: %s Allocation: %u",
+								pszOpName,
+								ui32AllocationIndex);
+}
+
+static void EmitPDumpMapUnmapRange(COMMAND_TYPE eType,
+					IMG_UINT32 ui32AllocationIndex,
+					IMG_UINT32 ui32StartPage,
+					IMG_UINT32 ui32Count)
+{
+	const IMG_CHAR *pszOpName;
+
+	switch(eType)
+	{
+		case COMMAND_TYPE_MAP_RANGE:
+			pszOpName = "MAP_RANGE";
+			break;
+		case COMMAND_TYPE_UNMAP_RANGE:
+			pszOpName = "UNMAP_RANGE";
+			break;
+		default:
+			PVR_DPF((PVR_DBG_ERROR, "EmitPDumpMapUnmapRange: Invalid type: %u",
+										eType));
+			return;
+	}
+
+	PDUMPCOMMENT("[SrvPFD] Op: %s Allocation: %u Start Page: %u Count: %u",
+									pszOpName,
+									ui32AllocationIndex,
+									ui32StartPage,
+									ui32Count);
+}
+
+#endif
+
+/* InsertTimeStampCommand:
+ * Insert a timestamp command into the circular buffer.
+ */
+static void InsertTimeStampCommand(IMG_UINT64 ui64Now)
+{
+	COMMAND_WRAPPER *psCommand;
+
+	psCommand = AcquireCBSlot();
+
+	psCommand->ui8Type = COMMAND_TYPE_TIMESTAMP;
+
+	TimeStampPack(&psCommand->u.sTimeStamp, ui64Now);
+}
+
+/* InsertMapAllCommand:
+ * Insert a "MAP_ALL" command for the given allocation into the circular buffer
+ */
+static void InsertMapAllCommand(IMG_UINT32 ui32AllocIndex)
+{
+	COMMAND_WRAPPER *psCommand;
+
+	psCommand = AcquireCBSlot();
+
+	psCommand->ui8Type = COMMAND_TYPE_MAP_ALL;
+	psCommand->u.sMapAll.uiAllocIndex = ui32AllocIndex;
+
+#if defined(PDUMP)
+	EmitPDumpMapUnmapAll(COMMAND_TYPE_MAP_ALL, ui32AllocIndex);
+#endif
+}
+
+/* InsertUnmapAllCommand:
+ * Insert a "UNMAP_ALL" command for the given allocation into the circular buffer
+ */
+static void InsertUnmapAllCommand(IMG_UINT32 ui32AllocIndex)
+{
+	COMMAND_WRAPPER *psCommand;
+
+	psCommand = AcquireCBSlot();
+
+	psCommand->ui8Type = COMMAND_TYPE_UNMAP_ALL;
+	psCommand->u.sUnmapAll.uiAllocIndex = ui32AllocIndex;
+
+#if defined(PDUMP)
+	EmitPDumpMapUnmapAll(COMMAND_TYPE_UNMAP_ALL, ui32AllocIndex);
+#endif
+}
+
+/* MapRangePack:
+ * Pack the given StartPage and Count values into the 40-bit representation
+ * in the MAP_RANGE command.
+ */
+static void MapRangePack(COMMAND_MAP_RANGE *psMapRange,
+						IMG_UINT32 ui32StartPage,
+						IMG_UINT32 ui32Count)
+{
+	IMG_UINT64 ui64Data;
+	IMG_UINT32 i;
+
+	/* we must encode the data into 40 bits:
+	 *   18 bits for the start page index
+	 *   12 bits for the range
+	*/
+
+	PVR_ASSERT(ui32StartPage <= MAP_RANGE_MAX_START);
+	PVR_ASSERT(ui32Count <= MAP_RANGE_MAX_RANGE);
+
+	ui64Data = (((IMG_UINT64) ui32StartPage) << 12) | ui32Count;
+
+	for(i = 0; i < IMG_ARR_NUM_ELEMS(psMapRange->aui8Data); i++)
+	{
+		psMapRange->aui8Data[i] = ui64Data & 0xFF;
+		ui64Data >>= 8;
+	}
+}
+
+/* MapRangePack:
+ * Unpack the StartPage and Count values from the 40-bit representation
+ * in the MAP_RANGE command.
+ */
+static void MapRangeUnpack(COMMAND_MAP_RANGE *psMapRange,
+						IMG_UINT32 *pui32StartPage,
+						IMG_UINT32 *pui32Count)
+{
+	IMG_UINT64 ui64Data = 0;
+	IMG_UINT32 i;
+
+	for(i = IMG_ARR_NUM_ELEMS(psMapRange->aui8Data); i > 0; i--)
+	{
+		ui64Data <<= 8;
+		ui64Data |= psMapRange->aui8Data[i - 1];
+	}
+
+	*pui32StartPage = (ui64Data >> 12);
+	*pui32Count = ui64Data & ((1 << 12) - 1);
+}
+
+/* InsertMapRangeCommand:
+ * Insert a MAP_RANGE command into the circular buffer with the given
+ * StartPage and Count values.
+ */
+static void InsertMapRangeCommand(IMG_UINT32 ui32AllocIndex,
+						IMG_UINT32 ui32StartPage,
+						IMG_UINT32 ui32Count)
+{
+	COMMAND_WRAPPER *psCommand;
+
+	psCommand = AcquireCBSlot();
+
+	psCommand->ui8Type = COMMAND_TYPE_MAP_RANGE;
+	psCommand->u.sMapRange.uiAllocIndex = ui32AllocIndex;
+
+	MapRangePack(&psCommand->u.sMapRange, ui32StartPage, ui32Count);
+
+#if defined(PDUMP)
+	EmitPDumpMapUnmapRange(COMMAND_TYPE_MAP_RANGE,
+							ui32AllocIndex,
+							ui32StartPage,
+							ui32Count);
+#endif
+}
+
+/* InsertUnmapRangeCommand:
+ * Insert a UNMAP_RANGE command into the circular buffer with the given
+ * StartPage and Count values.
+ */
+static void InsertUnmapRangeCommand(IMG_UINT32 ui32AllocIndex,
+						IMG_UINT32 ui32StartPage,
+						IMG_UINT32 ui32Count)
+{
+	COMMAND_WRAPPER *psCommand;
+
+	psCommand = AcquireCBSlot();
+
+	psCommand->ui8Type = COMMAND_TYPE_UNMAP_RANGE;
+	psCommand->u.sMapRange.uiAllocIndex = ui32AllocIndex;
+
+	MapRangePack(&psCommand->u.sMapRange, ui32StartPage, ui32Count);
+
+#if defined(PDUMP)
+	EmitPDumpMapUnmapRange(COMMAND_TYPE_UNMAP_RANGE,
+							ui32AllocIndex,
+							ui32StartPage,
+							ui32Count);
+#endif
+}
+
+/* InsertAllocationToList:
+ * Helper function for the allocation list.
+ * Inserts the given allocation at the head of the list, whose current head is
+ * pointed to by pui32ListHead
+ */
+static void InsertAllocationToList(IMG_UINT32 *pui32ListHead, IMG_UINT32 ui32Alloc)
+{
+	RECORD_ALLOCATION *psAlloc;
+
+	psAlloc = ALLOC_INDEX_TO_PTR(ui32Alloc);
+
+	if(*pui32ListHead == END_OF_LIST)
+	{
+		/* list is currently empty, so just replace it */
+		*pui32ListHead = ui32Alloc;
+		psAlloc->ui32Next = psAlloc->ui32Prev = *pui32ListHead;
+	}
+	else
+	{
+		RECORD_ALLOCATION *psHeadAlloc;
+		RECORD_ALLOCATION *psTailAlloc;
+
+		psHeadAlloc = ALLOC_INDEX_TO_PTR(*pui32ListHead);
+		psTailAlloc = ALLOC_INDEX_TO_PTR(psHeadAlloc->ui32Prev);
+
+		/* make the new alloc point forwards to the previous head */
+		psAlloc->ui32Next = *pui32ListHead;
+		/* make the new alloc point backwards to the previous tail */
+		psAlloc->ui32Prev = psHeadAlloc->ui32Prev;
+
+		/* the head is now our new alloc */
+		*pui32ListHead = ui32Alloc;
+
+		/* the old head now points back to the new head */
+		psHeadAlloc->ui32Prev = *pui32ListHead;
+
+		/* the tail now points forward to the new head */
+		psTailAlloc->ui32Next = ui32Alloc;
+	}
+}
+
+static void InsertAllocationToBusyList(IMG_UINT32 ui32Alloc)
+{
+	InsertAllocationToList(&gsDevicememHistoryData.sRecords.ui32AllocationsListHead, ui32Alloc);
+}
+
+/* RemoveAllocationFromList:
+ * Helper function for the allocation list.
+ * Removes the given allocation from the list, whose head is
+ * pointed to by pui32ListHead
+ */
+static void RemoveAllocationFromList(IMG_UINT32 *pui32ListHead, IMG_UINT32 ui32Alloc)
+{
+	RECORD_ALLOCATION *psAlloc;
+
+	psAlloc = ALLOC_INDEX_TO_PTR(ui32Alloc);
+
+	/* if this is the only element in the list then just make the list empty */
+	if((*pui32ListHead == ui32Alloc) && (psAlloc->ui32Next == ui32Alloc))
+	{
+		*pui32ListHead = END_OF_LIST;
+	}
+	else
+	{
+		RECORD_ALLOCATION *psPrev, *psNext;
+
+		psPrev = ALLOC_INDEX_TO_PTR(psAlloc->ui32Prev);
+		psNext = ALLOC_INDEX_TO_PTR(psAlloc->ui32Next);
+
+		/* remove the allocation from the list */
+		psPrev->ui32Next = psAlloc->ui32Next;
+		psNext->ui32Prev = psAlloc->ui32Prev;
+
+		/* if this allocation is the head then update the head */
+		if(*pui32ListHead == ui32Alloc)
+		{
+			*pui32ListHead = psAlloc->ui32Prev;
+		}
+	}
+}
+
+static void RemoveAllocationFromBusyList(IMG_UINT32 ui32Alloc)
+{
+	RemoveAllocationFromList(&gsDevicememHistoryData.sRecords.ui32AllocationsListHead, ui32Alloc);
+}
+
+/* TouchBusyAllocation:
+ * Move the given allocation to the head of the list
+ */
+static void TouchBusyAllocation(IMG_UINT32 ui32Alloc)
+{
+	RemoveAllocationFromBusyList(ui32Alloc);
+	InsertAllocationToBusyList(ui32Alloc);
+}
+
+static INLINE IMG_BOOL IsAllocationListEmpty(IMG_UINT32 ui32ListHead)
+{
+	return ui32ListHead == END_OF_LIST;
+}
+
+/* GetOldestBusyAllocation:
+ * Returns the index of the oldest allocation in the MRU list
+ */
+static IMG_UINT32 GetOldestBusyAllocation(void)
+{
+	IMG_UINT32 ui32Alloc;
+	RECORD_ALLOCATION *psAlloc;
+
+	ui32Alloc = gsDevicememHistoryData.sRecords.ui32AllocationsListHead;
+
+	if(ui32Alloc == END_OF_LIST)
+	{
+		return END_OF_LIST;
+	}
+
+	psAlloc = ALLOC_INDEX_TO_PTR(ui32Alloc);
+
+	return psAlloc->ui32Prev;
+}
+
+static IMG_UINT32 GetFreeAllocation(void)
+{
+	IMG_UINT32 ui32Alloc;
+
+	ui32Alloc = GetOldestBusyAllocation();
+
+	return ui32Alloc;
+}
+
+/* FindAllocation:
+ * Searches the list of allocations and returns the index if an allocation
+ * is found which matches the given properties
+ */
+static IMG_UINT32 FindAllocation(const IMG_CHAR *pszName,
+							IMG_UINT64 ui64Serial,
+							IMG_PID uiPID,
+							IMG_DEV_VIRTADDR sDevVAddr,
+							IMG_DEVMEM_SIZE_T uiSize)
+{
+	IMG_UINT32 ui32Head, ui32Index;
+	RECORD_ALLOCATION *psAlloc;
+
+	ui32Head = ui32Index = gsDevicememHistoryData.sRecords.ui32AllocationsListHead;
+
+	if(IsAllocationListEmpty(ui32Index))
+	{
+		goto not_found;
+	}
+
+	do
+	{
+		psAlloc = &gsDevicememHistoryData.sRecords.pasAllocations[ui32Index];
+
+		if(	(psAlloc->ui64Serial == ui64Serial) &&
+			(psAlloc->sDevVAddr.uiAddr == sDevVAddr.uiAddr) &&
+			(psAlloc->uiSize == uiSize) &&
+			(strcmp(psAlloc->szName, pszName) == 0))
+		{
+			goto found;
+		}
+
+		ui32Index = psAlloc->ui32Next;
+	} while(ui32Index != ui32Head);
+
+not_found:
+	/* not found */
+	ui32Index = END_OF_LIST;
+
+found:
+	/* if the allocation was not found then we return END_OF_LIST.
+	 * otherwise, we return the index of the allocation
+	 */
+
+	return ui32Index;
+}
+
+/* InitialiseAllocation:
+ * Initialise the given allocation structure with the given properties
+ */
+static void InitialiseAllocation(RECORD_ALLOCATION *psAlloc,
+							const IMG_CHAR *pszName,
+							IMG_UINT64 ui64Serial,
+							IMG_PID uiPID,
+							IMG_DEV_VIRTADDR sDevVAddr,
+							IMG_DEVMEM_SIZE_T uiSize,
+							IMG_UINT32 ui32Log2PageSize)
+{
+	OSStringNCopy(psAlloc->szName, pszName, sizeof(psAlloc->szName));
+	psAlloc->szName[sizeof(psAlloc->szName) - 1] = '\0';
+	psAlloc->ui64Serial = ui64Serial;
+	psAlloc->uiPID = uiPID;
+	psAlloc->sDevVAddr = sDevVAddr;
+	psAlloc->uiSize = uiSize;
+	psAlloc->ui32Log2PageSize = ui32Log2PageSize;
+	psAlloc->ui64CreationTime = OSClockns64();
+}
+
+/* CreateAllocation:
+ * Creates a new allocation with the given properties then outputs the
+ * index of the allocation
+ */
+static PVRSRV_ERROR CreateAllocation(const IMG_CHAR *pszName,
+							IMG_UINT64 ui64Serial,
+							IMG_PID uiPID,
+							IMG_DEV_VIRTADDR sDevVAddr,
+							IMG_DEVMEM_SIZE_T uiSize,
+							IMG_UINT32 ui32Log2PageSize,
+							IMG_BOOL bAutoPurge,
+							IMG_UINT32 *puiAllocationIndex)
+{
+	IMG_UINT32 ui32Alloc;
+	RECORD_ALLOCATION *psAlloc;
+
+	ui32Alloc = GetFreeAllocation();
+
+	psAlloc = ALLOC_INDEX_TO_PTR(ui32Alloc);
+
+	InitialiseAllocation(ALLOC_INDEX_TO_PTR(ui32Alloc),
+						pszName,
+						ui64Serial,
+						uiPID,
+						sDevVAddr,
+						uiSize,
+						ui32Log2PageSize);
+
+	/* put the newly initialised allocation at the front of the MRU list */
+	TouchBusyAllocation(ui32Alloc);
+
+	*puiAllocationIndex = ui32Alloc;
+
+#if defined(PDUMP)
+	EmitPDumpAllocation(ui32Alloc, psAlloc);
+#endif
+
+	return PVRSRV_OK;
+}
+
+/* MatchAllocation:
+ * Tests if the allocation at the given index matches the supplied properties.
+ * Returns IMG_TRUE if it is a match, otherwise IMG_FALSE.
+ */
+static IMG_BOOL MatchAllocation(IMG_UINT32 ui32AllocationIndex,
+						IMG_UINT64 ui64Serial,
+						IMG_DEV_VIRTADDR sDevVAddr,
+						IMG_DEVMEM_SIZE_T uiSize,
+						const IMG_CHAR *pszName,
+						IMG_UINT32 ui32Log2PageSize,
+						IMG_PID uiPID)
+{
+	RECORD_ALLOCATION *psAlloc;
+
+	psAlloc = ALLOC_INDEX_TO_PTR(ui32AllocationIndex);
+
+	return 	(psAlloc->ui64Serial == ui64Serial) &&
+			(psAlloc->sDevVAddr.uiAddr == sDevVAddr.uiAddr) &&
+			(psAlloc->uiSize == uiSize) &&
+			(psAlloc->ui32Log2PageSize == ui32Log2PageSize) &&
+			(strcmp(psAlloc->szName, pszName) == 0);
+}
+
+/* FindOrCreateAllocation:
+ * Convenience function.
+ * Given a set of allocation properties (serial, DevVAddr, size, name, etc),
+ * this function will look for an existing record of this allocation and
+ * create the allocation if there is no existing record
+ */
+static PVRSRV_ERROR FindOrCreateAllocation(IMG_UINT32 ui32AllocationIndexHint,
+							IMG_UINT64 ui64Serial,
+							IMG_DEV_VIRTADDR sDevVAddr,
+							IMG_DEVMEM_SIZE_T uiSize,
+							const char *pszName,
+							IMG_UINT32 ui32Log2PageSize,
+							IMG_PID uiPID,
+							IMG_BOOL bSparse,
+							IMG_UINT32 *pui32AllocationIndexOut,
+							IMG_BOOL *pbCreated)
+{
+	IMG_UINT32 ui32AllocationIndex;
+
+	if(ui32AllocationIndexHint != DEVICEMEM_HISTORY_ALLOC_INDEX_NONE)
+	{
+		IMG_BOOL bHaveAllocation;
+
+		/* first, try to match against the index given by the client */
+		bHaveAllocation = MatchAllocation(ui32AllocationIndexHint,
+								ui64Serial,
+								sDevVAddr,
+								uiSize,
+								pszName,
+								ui32Log2PageSize,
+								uiPID);
+		if(bHaveAllocation)
+		{
+			*pbCreated = IMG_FALSE;
+			*pui32AllocationIndexOut = ui32AllocationIndexHint;
+			return PVRSRV_OK;
+		}
+	}
+
+	/* if matching against the client-supplied index fails then check
+	 * if the allocation exists in the list
+	 */
+	ui32AllocationIndex = FindAllocation(pszName,
+						ui64Serial,
+						uiPID,
+						sDevVAddr,
+						uiSize);
+
+	/* if there is no record of the allocation then we
+	 * create it now
+	 */
+	if(ui32AllocationIndex == END_OF_LIST)
+	{
+		PVRSRV_ERROR eError;
+		eError = CreateAllocation(pszName,
+						ui64Serial,
+						uiPID,
+						sDevVAddr,
+						uiSize,
+						ui32Log2PageSize,
+						IMG_TRUE,
+						&ui32AllocationIndex);
+
+		if(eError == PVRSRV_OK)
+		{
+			*pui32AllocationIndexOut = ui32AllocationIndex;
+			*pbCreated = IMG_TRUE;
+		}
+		else
+		{
+			PVR_DPF((PVR_DBG_ERROR,
+				"%s: Failed to create record for allocation %s",
+									__func__,
+									pszName));
+		}
+
+		return eError;
+	}
+	else
+	{
+		/* found existing record */
+		*pui32AllocationIndexOut = ui32AllocationIndex;
+		*pbCreated = IMG_FALSE;
+		return PVRSRV_OK;
+	}
+
+}
+
+/* GenerateMapUnmapCommandsForSparsePMR:
+ * Generate the MAP_RANGE or UNMAP_RANGE commands for the sparse PMR, using the PMR's
+ * current mapping table
+ *
+ * PMR: The PMR whose mapping table to read.
+ * ui32AllocIndex: The allocation to attribute the MAP_RANGE/UNMAP range commands to.
+ * bMap: Set to TRUE for mapping or IMG_FALSE for unmapping
+ *
+ * This function goes through every page in the PMR's mapping table and looks for
+ * virtually contiguous ranges to record as being mapped or unmapped.
+ */
+static void GenerateMapUnmapCommandsForSparsePMR(PMR *psPMR,
+							IMG_UINT32 ui32AllocIndex,
+							IMG_BOOL bMap)
+{
+	PMR_MAPPING_TABLE *psMappingTable;
+	IMG_UINT32 ui32DonePages = 0;
+	IMG_UINT32 ui32NumPages;
+	IMG_UINT32 i;
+	IMG_BOOL bInARun = IMG_FALSE;
+	IMG_UINT32 ui32CurrentStart = 0;
+	IMG_UINT32 ui32RunCount = 0;
+
+	psMappingTable = PMR_GetMappigTable(psPMR);
+	ui32NumPages = psMappingTable->ui32NumPhysChunks;
+
+	if(ui32NumPages == 0)
+	{
+		/* nothing to do */
+		return;
+	}
+
+	for(i = 0; i < psMappingTable->ui32NumVirtChunks; i++)
+	{
+		if(psMappingTable->aui32Translation[i] != TRANSLATION_INVALID)
+		{
+			if(!bInARun)
+			{
+				bInARun = IMG_TRUE;
+				ui32CurrentStart = i;
+				ui32RunCount = 1;
+			}
+			else
+			{
+				ui32RunCount++;
+			}
+		}
+
+		if(bInARun)
+		{
+			/* test if we need to end this current run and generate the command,
+			 * either because the next page is not virtually contiguous
+			 * to the current page, we have reached the maximum range,
+			 * or this is the last page in the mapping table
+			 */
+			if((psMappingTable->aui32Translation[i] == TRANSLATION_INVALID) ||
+						(ui32RunCount == MAP_RANGE_MAX_RANGE) ||
+						(i == (psMappingTable->ui32NumVirtChunks - 1)))
+			{
+				if(bMap)
+				{
+					InsertMapRangeCommand(ui32AllocIndex,
+										ui32CurrentStart,
+										ui32RunCount);
+				}
+				else
+				{
+					InsertUnmapRangeCommand(ui32AllocIndex,
+										ui32CurrentStart,
+										ui32RunCount);
+				}
+
+				ui32DonePages += ui32RunCount;
+
+				if(ui32DonePages == ui32NumPages)
+				{
+					 break;
+				}
+
+				bInARun = IMG_FALSE;
+			}
+		}
+	}
+
+}
+
+/* GenerateMapUnmapCommandsForChangeList:
+ * Generate the MAP_RANGE or UNMAP_RANGE commands for the sparse PMR, using the
+ * list of page change (page map or page unmap) indices given.
+ *
+ * ui32NumPages: Number of pages which have changed.
+ * pui32PageList: List of indices of the pages which have changed.
+ * ui32AllocIndex: The allocation to attribute the MAP_RANGE/UNMAP range commands to.
+ * bMap: Set to TRUE for mapping or IMG_FALSE for unmapping
+ *
+ * This function goes through every page in the list and looks for
+ * virtually contiguous ranges to record as being mapped or unmapped.
+ */
+static void GenerateMapUnmapCommandsForChangeList(IMG_UINT32 ui32NumPages,
+							IMG_UINT32 *pui32PageList,
+							IMG_UINT32 ui32AllocIndex,
+							IMG_BOOL bMap)
+{
+	IMG_UINT32 i;
+	IMG_BOOL bInARun = IMG_FALSE;
+	IMG_UINT32 ui32CurrentStart = 0;
+	IMG_UINT32 ui32RunCount = 0;
+
+	for(i = 0; i < ui32NumPages; i++)
+	{
+		if(!bInARun)
+		{
+			bInARun = IMG_TRUE;
+			ui32CurrentStart = pui32PageList[i];
+		}
+
+		ui32RunCount++;
+
+		 /* we flush if:
+		 * - the next page in the list is not one greater than the current page
+		 * - this is the last page in the list
+		 * - we have reached the maximum range size
+		 */
+		if((i == (ui32NumPages - 1)) ||
+			((pui32PageList[i] + 1) != pui32PageList[i + 1]) ||
+			(ui32RunCount == MAP_RANGE_MAX_RANGE))
+		{
+			if(bMap)
+			{
+				InsertMapRangeCommand(ui32AllocIndex,
+									ui32CurrentStart,
+									ui32RunCount);
+			}
+			else
+			{
+				InsertUnmapRangeCommand(ui32AllocIndex,
+									ui32CurrentStart,
+									ui32RunCount);
+			}
+
+			bInARun = IMG_FALSE;
+			ui32RunCount = 0;
+		}
+	}
+}
+
+/* DevicememHistoryMapKM:
+ * Entry point for when an allocation is mapped into the MMU GPU
+ *
+ * psPMR: The PMR to which the allocation belongs.
+ * ui32Offset: The offset within the PMR at which the allocation begins.
+ * sDevVAddr: The DevVAddr at which the allocation begins.
+ * szName: Annotation/name for the allocation.
+ * ui32Log2PageSize: Page size of the allocation, expressed in log2 form.
+ * ui32AllocationIndex: Allocation index as provided by the client.
+ *                      We will use this as a short-cut to find the allocation
+ *                      in our records.
+ * pui32AllocationIndexOut: An updated allocation index for the client.
+ *                          This may be a new value if we just created the
+ *                          allocation record.
+ */
+PVRSRV_ERROR DevicememHistoryMapNewKM(PMR *psPMR,
+							IMG_UINT32 ui32Offset,
+							IMG_DEV_VIRTADDR sDevVAddr,
+							IMG_DEVMEM_SIZE_T uiSize,
+							const char szName[DEVICEMEM_HISTORY_TEXT_BUFSZ],
+							IMG_UINT32 ui32Log2PageSize,
+							IMG_UINT32 ui32AllocationIndex,
+							IMG_UINT32 *pui32AllocationIndexOut)
+{
+	IMG_BOOL bSparse = PMR_IsSparse(psPMR);
+	IMG_UINT64 ui64Serial;
+	IMG_PID uiPID = OSGetCurrentProcessID();
+	PVRSRV_ERROR eError;
+	IMG_BOOL bCreated;
+
+	if((ui32AllocationIndex != DEVICEMEM_HISTORY_ALLOC_INDEX_NONE) &&
+				!CHECK_ALLOC_INDEX(ui32AllocationIndex))
+	{
+		PVR_DPF((PVR_DBG_ERROR, "%s: Invalid allocation index: %u",
+								__func__,
+								ui32AllocationIndex));
+		return PVRSRV_ERROR_INVALID_PARAMS;
+	}
+
+	PMRGetUID(psPMR, &ui64Serial);
+
+	DevicememHistoryLock();
+
+	eError = FindOrCreateAllocation(ui32AllocationIndex,
+						ui64Serial,
+						sDevVAddr,
+						uiSize,
+						szName,
+						ui32Log2PageSize,
+						uiPID,
+						bSparse,
+						&ui32AllocationIndex,
+						&bCreated);
+
+	if((eError == PVRSRV_OK) && !bCreated)
+	{
+		/* touch the allocation so it goes to the head of our MRU list */
+		TouchBusyAllocation(ui32AllocationIndex);
+	}
+	else if(eError != PVRSRV_OK)
+	{
+		PVR_DPF((PVR_DBG_ERROR, "%s: Failed to Find or Create allocation %s (%s)",
+									__func__,
+									szName,
+									PVRSRVGETERRORSTRING(eError)));
+		goto out_unlock;
+	}
+
+	if(!bSparse)
+	{
+		InsertMapAllCommand(ui32AllocationIndex);
+	}
+	else
+	{
+		GenerateMapUnmapCommandsForSparsePMR(psPMR,
+								ui32AllocationIndex,
+								IMG_TRUE);
+	}
+
+	InsertTimeStampCommand(OSClockns64());
+
+	*pui32AllocationIndexOut = ui32AllocationIndex;
+
+out_unlock:
+	DevicememHistoryUnlock();
+
+	return eError;
+}
+
+static void VRangeInsertMapUnmapCommands(IMG_BOOL bMap,
+							IMG_UINT32 ui32AllocationIndex,
+							IMG_DEV_VIRTADDR sBaseDevVAddr,
+							IMG_UINT32 ui32StartPage,
+							IMG_UINT32 ui32NumPages,
+							const IMG_CHAR *pszName)
+{
+	while(ui32NumPages > 0)
+	{
+		IMG_UINT32 ui32PagesToAdd;
+
+		ui32PagesToAdd = MIN(ui32NumPages, MAP_RANGE_MAX_RANGE);
+
+		if(ui32StartPage > MAP_RANGE_MAX_START)
+		{
+			PVR_DPF((PVR_DBG_WARNING, "Cannot record %s range beginning at page "
+									"%u on allocation %s",
+									bMap ? "map" : "unmap",
+									ui32StartPage,
+									pszName));
+			return;
+		}
+
+		if(bMap)
+		{
+			InsertMapRangeCommand(ui32AllocationIndex,
+								ui32StartPage,
+								ui32PagesToAdd);
+		}
+		else
+		{
+			InsertUnmapRangeCommand(ui32AllocationIndex,
+								ui32StartPage,
+								ui32PagesToAdd);
+		}
+
+		ui32StartPage += ui32PagesToAdd;
+		ui32NumPages -= ui32PagesToAdd;
+	}
+}
+
+PVRSRV_ERROR DevicememHistoryMapVRangeKM(IMG_DEV_VIRTADDR sBaseDevVAddr,
+						IMG_UINT32 ui32StartPage,
+						IMG_UINT32 ui32NumPages,
+						IMG_DEVMEM_SIZE_T uiAllocSize,
+						const IMG_CHAR szName[DEVICEMEM_HISTORY_TEXT_BUFSZ],
+						IMG_UINT32 ui32Log2PageSize,
+						IMG_UINT32 ui32AllocationIndex,
+						IMG_UINT32 *pui32AllocationIndexOut)
+{
+	IMG_PID uiPID = OSGetCurrentProcessID();
+	PVRSRV_ERROR eError;
+	IMG_BOOL bCreated;
+
+	if((ui32AllocationIndex != DEVICEMEM_HISTORY_ALLOC_INDEX_NONE) &&
+				!CHECK_ALLOC_INDEX(ui32AllocationIndex))
+	{
+		PVR_DPF((PVR_DBG_ERROR, "%s: Invalid allocation index: %u",
+								__func__,
+							ui32AllocationIndex));
+		return PVRSRV_ERROR_INVALID_PARAMS;
+	}
+
+	DevicememHistoryLock();
+
+	eError = FindOrCreateAllocation(ui32AllocationIndex,
+						0,
+						sBaseDevVAddr,
+						uiAllocSize,
+						szName,
+						ui32Log2PageSize,
+						uiPID,
+						IMG_FALSE,
+						&ui32AllocationIndex,
+						&bCreated);
+
+	if((eError == PVRSRV_OK) && !bCreated)
+	{
+		/* touch the allocation so it goes to the head of our MRU list */
+		TouchBusyAllocation(ui32AllocationIndex);
+	}
+	else if(eError != PVRSRV_OK)
+	{
+		PVR_DPF((PVR_DBG_ERROR, "%s: Failed to Find or Create allocation %s (%s)",
+									__func__,
+									szName,
+									PVRSRVGETERRORSTRING(eError)));
+		goto out_unlock;
+	}
+
+	VRangeInsertMapUnmapCommands(IMG_TRUE,
+						ui32AllocationIndex,
+						sBaseDevVAddr,
+						ui32StartPage,
+						ui32NumPages,
+						szName);
+
+	*pui32AllocationIndexOut = ui32AllocationIndex;
+
+out_unlock:
+	DevicememHistoryUnlock();
+
+	return eError;
+
+}
+
+PVRSRV_ERROR DevicememHistoryUnmapVRangeKM(IMG_DEV_VIRTADDR sBaseDevVAddr,
+						IMG_UINT32 ui32StartPage,
+						IMG_UINT32 ui32NumPages,
+						IMG_DEVMEM_SIZE_T uiAllocSize,
+						const IMG_CHAR szName[DEVICEMEM_HISTORY_TEXT_BUFSZ],
+						IMG_UINT32 ui32Log2PageSize,
+						IMG_UINT32 ui32AllocationIndex,
+						IMG_UINT32 *pui32AllocationIndexOut)
+{
+	IMG_PID uiPID = OSGetCurrentProcessID();
+	PVRSRV_ERROR eError;
+	IMG_BOOL bCreated;
+
+	if((ui32AllocationIndex != DEVICEMEM_HISTORY_ALLOC_INDEX_NONE) &&
+				!CHECK_ALLOC_INDEX(ui32AllocationIndex))
+	{
+		PVR_DPF((PVR_DBG_ERROR, "%s: Invalid allocation index: %u",
+								__func__,
+							ui32AllocationIndex));
+		return PVRSRV_ERROR_INVALID_PARAMS;
+	}
+
+	DevicememHistoryLock();
+
+	eError = FindOrCreateAllocation(ui32AllocationIndex,
+						0,
+						sBaseDevVAddr,
+						uiAllocSize,
+						szName,
+						ui32Log2PageSize,
+						uiPID,
+						IMG_FALSE,
+						&ui32AllocationIndex,
+						&bCreated);
+
+	if((eError == PVRSRV_OK) && !bCreated)
+	{
+		/* touch the allocation so it goes to the head of our MRU list */
+		TouchBusyAllocation(ui32AllocationIndex);
+	}
+	else if(eError != PVRSRV_OK)
+	{
+		PVR_DPF((PVR_DBG_ERROR, "%s: Failed to Find or Create allocation %s (%s)",
+									__func__,
+									szName,
+									PVRSRVGETERRORSTRING(eError)));
+		goto out_unlock;
+	}
+
+	VRangeInsertMapUnmapCommands(IMG_FALSE,
+						ui32AllocationIndex,
+						sBaseDevVAddr,
+						ui32StartPage,
+						ui32NumPages,
+						szName);
+
+	*pui32AllocationIndexOut = ui32AllocationIndex;
+
+out_unlock:
+	DevicememHistoryUnlock();
+
+	return eError;
+}
+
+
+
+/* DevicememHistoryUnmapKM:
+ * Entry point for when an allocation is unmapped from the MMU GPU
+ *
+ * psPMR: The PMR to which the allocation belongs.
+ * ui32Offset: The offset within the PMR at which the allocation begins.
+ * sDevVAddr: The DevVAddr at which the allocation begins.
+ * szName: Annotation/name for the allocation.
+ * ui32Log2PageSize: Page size of the allocation, expressed in log2 form.
+ * ui32AllocationIndex: Allocation index as provided by the client.
+ *                      We will use this as a short-cut to find the allocation
+ *                      in our records.
+ * pui32AllocationIndexOut: An updated allocation index for the client.
+ *                          This may be a new value if we just created the
+ *                          allocation record.
+ */
+PVRSRV_ERROR DevicememHistoryUnmapNewKM(PMR *psPMR,
+							IMG_UINT32 ui32Offset,
+							IMG_DEV_VIRTADDR sDevVAddr,
+							IMG_DEVMEM_SIZE_T uiSize,
+							const char szName[DEVICEMEM_HISTORY_TEXT_BUFSZ],
+							IMG_UINT32 ui32Log2PageSize,
+							IMG_UINT32 ui32AllocationIndex,
+							IMG_UINT32 *pui32AllocationIndexOut)
+{
+	IMG_BOOL bSparse = PMR_IsSparse(psPMR);
+	IMG_UINT64 ui64Serial;
+	IMG_PID uiPID = OSGetCurrentProcessID();
+	PVRSRV_ERROR eError;
+	IMG_BOOL bCreated;
+
+	if((ui32AllocationIndex != DEVICEMEM_HISTORY_ALLOC_INDEX_NONE) &&
+				!CHECK_ALLOC_INDEX(ui32AllocationIndex))
+	{
+		PVR_DPF((PVR_DBG_ERROR, "%s: Invalid allocation index: %u",
+								__func__,
+								ui32AllocationIndex));
+		return PVRSRV_ERROR_INVALID_PARAMS;
+	}
+
+	PMRGetUID(psPMR, &ui64Serial);
+
+	DevicememHistoryLock();
+
+	eError = FindOrCreateAllocation(ui32AllocationIndex,
+						ui64Serial,
+						sDevVAddr,
+						uiSize,
+						szName,
+						ui32Log2PageSize,
+						uiPID,
+						bSparse,
+						&ui32AllocationIndex,
+						&bCreated);
+
+	if((eError == PVRSRV_OK) && !bCreated)
+	{
+		/* touch the allocation so it goes to the head of our MRU list */
+		TouchBusyAllocation(ui32AllocationIndex);
+	}
+	else if(eError != PVRSRV_OK)
+	{
+		PVR_DPF((PVR_DBG_ERROR, "%s: Failed to Find or Create allocation %s (%s)",
+									__func__,
+									szName,
+									PVRSRVGETERRORSTRING(eError)));
+		goto out_unlock;
+	}
+
+	if(!bSparse)
+	{
+		InsertUnmapAllCommand(ui32AllocationIndex);
+	}
+	else
+	{
+		GenerateMapUnmapCommandsForSparsePMR(psPMR,
+								ui32AllocationIndex,
+								IMG_FALSE);
+	}
+
+	InsertTimeStampCommand(OSClockns64());
+
+	*pui32AllocationIndexOut = ui32AllocationIndex;
+
+out_unlock:
+	DevicememHistoryUnlock();
+
+	return eError;
+}
+
+/* DevicememHistorySparseChangeKM:
+ * Entry point for when a sparse allocation is changed, such that some of the
+ * pages within the sparse allocation are mapped or unmapped.
+ *
+ * psPMR: The PMR to which the allocation belongs.
+ * ui32Offset: The offset within the PMR at which the allocation begins.
+ * sDevVAddr: The DevVAddr at which the allocation begins.
+ * szName: Annotation/name for the allocation.
+ * ui32Log2PageSize: Page size of the allocation, expressed in log2 form.
+ * ui32AllocPageCount: Number of pages which have been mapped.
+ * paui32AllocPageIndices: Indices of pages which have been mapped.
+ * ui32FreePageCount: Number of pages which have been unmapped.
+ * paui32FreePageIndices: Indices of pages which have been unmapped.
+ * ui32AllocationIndex: Allocation index as provided by the client.
+ *                      We will use this as a short-cut to find the allocation
+ *                      in our records.
+ * pui32AllocationIndexOut: An updated allocation index for the client.
+ *                          This may be a new value if we just created the
+ *                          allocation record.
+ */
+PVRSRV_ERROR DevicememHistorySparseChangeKM(PMR *psPMR,
+							IMG_UINT32 ui32Offset,
+							IMG_DEV_VIRTADDR sDevVAddr,
+							IMG_DEVMEM_SIZE_T uiSize,
+							const char szName[DEVICEMEM_HISTORY_TEXT_BUFSZ],
+							IMG_UINT32 ui32Log2PageSize,
+							IMG_UINT32 ui32AllocPageCount,
+							IMG_UINT32 *paui32AllocPageIndices,
+							IMG_UINT32 ui32FreePageCount,
+							IMG_UINT32 *paui32FreePageIndices,
+							IMG_UINT32 ui32AllocationIndex,
+							IMG_UINT32 *pui32AllocationIndexOut)
+{
+	IMG_UINT64 ui64Serial;
+	IMG_PID uiPID = OSGetCurrentProcessID();
+	PVRSRV_ERROR eError;
+	IMG_BOOL bCreated;
+
+	if((ui32AllocationIndex != DEVICEMEM_HISTORY_ALLOC_INDEX_NONE) &&
+				!CHECK_ALLOC_INDEX(ui32AllocationIndex))
+	{
+		PVR_DPF((PVR_DBG_ERROR, "%s: Invalid allocation index: %u",
+								__func__,
+								ui32AllocationIndex));
+		return PVRSRV_ERROR_INVALID_PARAMS;
+	}
+
+	PMRGetUID(psPMR, &ui64Serial);
+
+	DevicememHistoryLock();
+
+	eError = FindOrCreateAllocation(ui32AllocationIndex,
+						ui64Serial,
+						sDevVAddr,
+						uiSize,
+						szName,
+						ui32Log2PageSize,
+						uiPID,
+						IMG_TRUE /* bSparse */,
+						&ui32AllocationIndex,
+						&bCreated);
+
+	if((eError == PVRSRV_OK) && !bCreated)
+	{
+		/* touch the allocation so it goes to the head of our MRU list */
+		TouchBusyAllocation(ui32AllocationIndex);
+	}
+	else if(eError != PVRSRV_OK)
+	{
+		PVR_DPF((PVR_DBG_ERROR, "%s: Failed to Find or Create allocation %s (%s)",
+									__func__,
+									szName,
+									PVRSRVGETERRORSTRING(eError)));
+		goto out_unlock;
+	}
+
+	GenerateMapUnmapCommandsForChangeList(ui32AllocPageCount,
+							paui32AllocPageIndices,
+							ui32AllocationIndex,
+							IMG_TRUE);
+
+	GenerateMapUnmapCommandsForChangeList(ui32FreePageCount,
+							paui32FreePageIndices,
+							ui32AllocationIndex,
+							IMG_FALSE);
+
+	InsertTimeStampCommand(OSClockns64());
+
+	*pui32AllocationIndexOut = ui32AllocationIndex;
+
+out_unlock:
+	DevicememHistoryUnlock();
+
+	return eError;
+
+}
+
+/* CircularBufferIterateStart:
+ * Initialise local state for iterating over the circular buffer
+ */
+static void CircularBufferIterateStart(IMG_UINT32 *pui32Head, IMG_UINT32 *pui32Iter)
+{
+	*pui32Head = gsDevicememHistoryData.sRecords.ui32Head;
+
+	if(*pui32Head != 0)
+	{
+		*pui32Iter = *pui32Head - 1;
+	}
+	else
+	{
+		*pui32Iter = CIRCULAR_BUFFER_NUM_COMMANDS - 1;
+	}
+}
+
+/* CircularBufferIteratePrevious:
+ * Iterate to the previous item in the circular buffer.
+ * This is called repeatedly to iterate over the whole circular buffer.
+ */
+static COMMAND_WRAPPER *CircularBufferIteratePrevious(IMG_UINT32 ui32Head,
+							IMG_UINT32 *pui32Iter,
+							COMMAND_TYPE *peType,
+							IMG_BOOL *pbLast)
+{
+	IMG_UINT8 *pui8Header;
+	COMMAND_WRAPPER *psOut = NULL;
+
+	psOut = gsDevicememHistoryData.sRecords.pasCircularBuffer + *pui32Iter;
+
+	pui8Header = (IMG_UINT8 *) psOut;
+
+	/* sanity check the command looks valid.
+	 * this condition should never happen, but check for it anyway
+	 * and try to handle it
+	 */
+	if(*pui8Header >= COMMAND_TYPE_COUNT)
+	{
+		/* invalid header detected. Circular buffer corrupted? */
+		PVR_DPF((PVR_DBG_ERROR, "CircularBufferIteratePrevious: "
+							"Invalid header: %u",
+							*pui8Header));
+		*pbLast = IMG_TRUE;
+		return NULL;
+	}
+
+	*peType = *pui8Header;
+
+	if(*pui32Iter != 0)
+	{
+		(*pui32Iter)--;
+	}
+	else
+	{
+		*pui32Iter = CIRCULAR_BUFFER_NUM_COMMANDS - 1;
+	}
+
+
+	/* inform the caller this is the last command if either we have reached
+	 * the head (where we started) or if we have reached an empty command,
+	 * which means we have covered all populated entries
+	 */
+	if((*pui32Iter == ui32Head) || (*peType == COMMAND_TYPE_NONE))
+	{
+		/* this is the final iteration */
+		*pbLast = IMG_TRUE;
+	}
+
+	return psOut;
+}
+
+/* MapUnmapCommandGetInfo:
+ * Helper function to get the address and mapping information from a MAP_ALL, UNMAP_ALL,
+ * MAP_RANGE or UNMAP_RANGE command
+ */
+static void MapUnmapCommandGetInfo(COMMAND_WRAPPER *psCommand,
+					COMMAND_TYPE eType,
+					IMG_DEV_VIRTADDR *psDevVAddrStart,
+					IMG_DEV_VIRTADDR *psDevVAddrEnd,
+					IMG_BOOL *pbMap,
+					IMG_UINT32 *pui32AllocIndex)
+{
+	if((eType == COMMAND_TYPE_MAP_ALL) || ((eType == COMMAND_TYPE_UNMAP_ALL)))
+	{
+		COMMAND_MAP_ALL *psMapAll = &psCommand->u.sMapAll;
+		RECORD_ALLOCATION *psAlloc;
+
+		*pbMap = (eType == COMMAND_TYPE_MAP_ALL);
+		*pui32AllocIndex = psMapAll->uiAllocIndex;
+
+		psAlloc = ALLOC_INDEX_TO_PTR(psMapAll->uiAllocIndex);
+
+		*psDevVAddrStart = psAlloc->sDevVAddr;
+		psDevVAddrEnd->uiAddr = psDevVAddrStart->uiAddr + psAlloc->uiSize - 1;
+	}
+	else if((eType == COMMAND_TYPE_MAP_RANGE) || ((eType == COMMAND_TYPE_UNMAP_RANGE)))
+	{
+		COMMAND_MAP_RANGE *psMapRange = &psCommand->u.sMapRange;
+		RECORD_ALLOCATION *psAlloc;
+		IMG_UINT32 ui32StartPage, ui32Count;
+
+		*pbMap = (eType == COMMAND_TYPE_MAP_RANGE);
+		*pui32AllocIndex = psMapRange->uiAllocIndex;
+
+		psAlloc = ALLOC_INDEX_TO_PTR(psMapRange->uiAllocIndex);
+
+		MapRangeUnpack(psMapRange, &ui32StartPage, &ui32Count);
+
+		psDevVAddrStart->uiAddr = psAlloc->sDevVAddr.uiAddr +
+				((1U << psAlloc->ui32Log2PageSize) * ui32StartPage);
+
+		psDevVAddrEnd->uiAddr = psDevVAddrStart->uiAddr +
+				((1U << psAlloc->ui32Log2PageSize) * ui32Count) - 1;
+	}
+	else
+	{
+		PVR_DPF((PVR_DBG_ERROR, "%s: Invalid command type: %u",
+								__func__,
+								eType));
+	}
+}
+
+/* DevicememHistoryQuery:
+ * Entry point for rgxdebug to look up addresses relating to a page fault
+ */
+IMG_BOOL DevicememHistoryQuery(DEVICEMEM_HISTORY_QUERY_IN *psQueryIn,
+                               DEVICEMEM_HISTORY_QUERY_OUT *psQueryOut,
+                               IMG_UINT32 ui32PageSizeBytes,
+                               IMG_BOOL bMatchAnyAllocInPage)
+{
+	IMG_UINT32 ui32Head, ui32Iter;
+	COMMAND_TYPE eType = COMMAND_TYPE_NONE;
+	COMMAND_WRAPPER *psCommand = NULL;
+	IMG_BOOL bLast = IMG_FALSE;
+	IMG_UINT64 ui64StartTime = OSClockns64();
+	IMG_UINT64 ui64TimeNs = 0;
+
+	/* initialise the results count for the caller */
+	psQueryOut->ui32NumResults = 0;
+
+	DevicememHistoryLock();
+
+	/* if the search is constrained to a particular PID then we
+	 * first search the list of allocations to see if this
+	 * PID is known to us
+	 */
+	if(psQueryIn->uiPID != DEVICEMEM_HISTORY_PID_ANY)
+	{
+		IMG_UINT32 ui32Alloc;
+		ui32Alloc = gsDevicememHistoryData.sRecords.ui32AllocationsListHead;
+
+		while(ui32Alloc != END_OF_LIST)
+		{
+			RECORD_ALLOCATION *psAlloc;
+
+			psAlloc = ALLOC_INDEX_TO_PTR(ui32Alloc);
+
+			if(psAlloc->uiPID == psQueryIn->uiPID)
+			{
+				goto found_pid;
+			}
+
+			if(ui32Alloc == gsDevicememHistoryData.sRecords.ui32AllocationsListHead)
+			{
+				/* gone through whole list */
+				break;
+			}
+		}
+
+		/* PID not found, so we do not have any suitable data for this
+		 * page fault
+		 */
+		 goto out_unlock;
+	}
+
+found_pid:
+
+	CircularBufferIterateStart(&ui32Head, &ui32Iter);
+
+	while(!bLast)
+	{
+		psCommand = CircularBufferIteratePrevious(ui32Head, &ui32Iter, &eType, &bLast);
+
+		if(eType == COMMAND_TYPE_TIMESTAMP)
+		{
+			ui64TimeNs = TimeStampUnpack(&psCommand->u.sTimeStamp);
+			continue;
+		}
+
+		if((eType == COMMAND_TYPE_MAP_ALL) ||
+			(eType == COMMAND_TYPE_UNMAP_ALL) ||
+			(eType == COMMAND_TYPE_MAP_RANGE) ||
+			(eType == COMMAND_TYPE_UNMAP_RANGE))
+		{
+			RECORD_ALLOCATION *psAlloc;
+			IMG_DEV_VIRTADDR sAllocStartAddrOrig, sAllocEndAddrOrig;
+			IMG_DEV_VIRTADDR sAllocStartAddr, sAllocEndAddr;
+			IMG_BOOL bMap;
+			IMG_UINT32 ui32AllocIndex;
+
+			MapUnmapCommandGetInfo(psCommand,
+							eType,
+							&sAllocStartAddrOrig,
+							&sAllocEndAddrOrig,
+							&bMap,
+							&ui32AllocIndex);
+
+			sAllocStartAddr = sAllocStartAddrOrig;
+			sAllocEndAddr = sAllocEndAddrOrig;
+
+			psAlloc = ALLOC_INDEX_TO_PTR(ui32AllocIndex);
+
+			/* skip this command if we need to search within
+			 * a particular PID, and this allocation is not from
+			 * that PID
+			 */
+			if((psQueryIn->uiPID != DEVICEMEM_HISTORY_PID_ANY) &&
+				(psAlloc->uiPID != psQueryIn->uiPID))
+			{
+				continue;
+			}
+
+			/* if the allocation was created after this event, then this
+			 * event must be for an old/removed allocation, so skip it
+			 */
+			if(DO_TIME_STAMP_MASK(psAlloc->ui64CreationTime) > ui64TimeNs)
+			{
+				continue;
+			}
+
+			/* if the caller wants us to match any allocation in the
+			 * same page as the allocation then tweak the real start/end
+			 * addresses of the allocation here
+			 */
+			if(bMatchAnyAllocInPage)
+			{
+				sAllocStartAddr.uiAddr = sAllocStartAddr.uiAddr & ~(IMG_UINT64) (ui32PageSizeBytes - 1);
+				sAllocEndAddr.uiAddr = (sAllocEndAddr.uiAddr + ui32PageSizeBytes - 1) & ~(IMG_UINT64) (ui32PageSizeBytes - 1);
+			}
+
+			if((psQueryIn->sDevVAddr.uiAddr >= sAllocStartAddr.uiAddr) &&
+				(psQueryIn->sDevVAddr.uiAddr <  sAllocEndAddr.uiAddr))
+			{
+				DEVICEMEM_HISTORY_QUERY_OUT_RESULT *psResult = &psQueryOut->sResults[psQueryOut->ui32NumResults];
+
+				OSStringNCopy(psResult->szString, psAlloc->szName, sizeof(psResult->szString));
+				psResult->szString[DEVICEMEM_HISTORY_TEXT_BUFSZ - 1] = '\0';
+				psResult->sBaseDevVAddr = psAlloc->sDevVAddr;
+				psResult->uiSize = psAlloc->uiSize;
+				psResult->bMap = bMap;
+				psResult->ui64Age = _CalculateAge(ui64StartTime, ui64TimeNs, TIME_STAMP_MASK);
+				psResult->ui64When = ui64TimeNs;
+				/* write the responsible PID in the placeholder */
+				psResult->sProcessInfo.uiPID = psAlloc->uiPID;
+
+				if((eType == COMMAND_TYPE_MAP_ALL) || (eType == COMMAND_TYPE_UNMAP_ALL))
+				{
+					psResult->bRange = IMG_FALSE;
+					psResult->bAll = IMG_TRUE;
+				}
+				else
+				{
+					psResult->bRange = IMG_TRUE;
+					MapRangeUnpack(&psCommand->u.sMapRange,
+										&psResult->ui32StartPage,
+										&psResult->ui32PageCount);
+					psResult->bAll = (psResult->ui32PageCount * (1U << psAlloc->ui32Log2PageSize))
+											== psAlloc->uiSize;
+					psResult->sMapStartAddr = sAllocStartAddrOrig;
+					psResult->sMapEndAddr = sAllocEndAddrOrig;
+				}
+
+				psQueryOut->ui32NumResults++;
+
+				if(psQueryOut->ui32NumResults == DEVICEMEM_HISTORY_QUERY_OUT_MAX_RESULTS)
+				{
+					break;
+				}
+			}
+		}
+	}
+
+out_unlock:
+	DevicememHistoryUnlock();
+
+	return psQueryOut->ui32NumResults > 0;
+}
+
+static void DeviceMemHistoryFmt(IMG_CHAR szBuffer[PVR_MAX_DEBUG_MESSAGE_LEN],
+							IMG_PID uiPID,
+							const IMG_CHAR *pszName,
+							const IMG_CHAR *pszAction,
+							IMG_DEV_VIRTADDR sDevVAddrStart,
+							IMG_DEV_VIRTADDR sDevVAddrEnd,
+							IMG_UINT64 ui64TimeNs)
+{
 
 	szBuffer[PVR_MAX_DEBUG_MESSAGE_LEN - 1] = '\0';
 	OSSNPrintf(szBuffer, PVR_MAX_DEBUG_MESSAGE_LEN,
 				/* PID NAME MAP/UNMAP MIN-MAX SIZE AbsUS AgeUS*/
-				"%04u %-40s %-6s "
-				IMG_DEV_VIRTADDR_FMTSPEC "-" IMG_DEV_VIRTADDR_FMTSPEC" "
+				"%04u %-40s %-10s "
+				IMG_DEV_VIRTADDR_FMTSPEC "-" IMG_DEV_VIRTADDR_FMTSPEC " "
 				"0x%08llX "
 				"%013llu", /* 13 digits is over 2 hours of ns */
-				psAlloc->uiPID,
-				psAlloc->szString,
-				psAlloc->bAllocated ? "MAP" : "UNMAP",
-				psAlloc->sDevVAddr.uiAddr,
-				psAlloc->sDevVAddr.uiAddr + psAlloc->uiSize - 1,
-				psAlloc->uiSize,
-				psAlloc->ui64Time);
+				uiPID,
+				pszName,
+				pszAction,
+				sDevVAddrStart.uiAddr,
+				sDevVAddrEnd.uiAddr,
+				sDevVAddrEnd.uiAddr - sDevVAddrStart.uiAddr,
+				ui64TimeNs);
 }
 
 static void DeviceMemHistoryFmtHeader(IMG_CHAR szBuffer[PVR_MAX_DEBUG_MESSAGE_LEN])
@@ -143,37 +1776,93 @@
 				"ABS NS");
 }
 
+static const char *CommandTypeToString(COMMAND_TYPE eType)
+{
+	switch(eType)
+	{
+		case COMMAND_TYPE_MAP_ALL:
+			return "MapAll";
+		case COMMAND_TYPE_UNMAP_ALL:
+			return "UnmapAll";
+		case COMMAND_TYPE_MAP_RANGE:
+			return "MapRange";
+		case COMMAND_TYPE_UNMAP_RANGE:
+			return "UnmapRange";
+		case COMMAND_TYPE_TIMESTAMP:
+			return "TimeStamp";
+		default:
+			return "???";
+	}
+}
+
 static void DevicememHistoryPrintAll(void *pvFilePtr, OS_STATS_PRINTF_FUNC* pfnOSStatsPrintf)
 {
 	IMG_CHAR szBuffer[PVR_MAX_DEBUG_MESSAGE_LEN];
 	IMG_UINT32 ui32Iter;
+	IMG_UINT32 ui32Head;
+	IMG_BOOL bLast = IMG_FALSE;
+	IMG_UINT64 ui64TimeNs = 0;
+	IMG_UINT64 ui64StartTime = OSClockns64();
 
 	DeviceMemHistoryFmtHeader(szBuffer);
 	pfnOSStatsPrintf(pvFilePtr, "%s\n", szBuffer);
 
-	for(ui32Iter = DECREMENT_WITH_WRAP(gsDevicememHistoryData.ui32Head, DEVICEMEM_HISTORY_ALLOCATION_HISTORY_LEN);
-			;
-			ui32Iter = DECREMENT_WITH_WRAP(ui32Iter, DEVICEMEM_HISTORY_ALLOCATION_HISTORY_LEN))
+	CircularBufferIterateStart(&ui32Head, &ui32Iter);
+
+	while(!bLast)
 	{
-		DEVICEMEM_HISTORY_ALLOCATION *psAlloc;
+		COMMAND_WRAPPER *psCommand;
+		COMMAND_TYPE eType = COMMAND_TYPE_NONE;
 
-		psAlloc = &gsDevicememHistoryData.psAllocations[ui32Iter];
+		psCommand = CircularBufferIteratePrevious(ui32Head, &ui32Iter, &eType, &bLast);
 
-		/* no more written elements */
-		if(psAlloc->sDevVAddr.uiAddr == 0)
+		if(eType == COMMAND_TYPE_TIMESTAMP)
 		{
-			break;
+			ui64TimeNs = TimeStampUnpack(&psCommand->u.sTimeStamp);
+			continue;
 		}
 
-		DeviceMemHistoryFmt(ui32Iter, szBuffer);
-pfnOSStatsPrintf(pvFilePtr, "%s\n", szBuffer);
 
-		if(ui32Iter == gsDevicememHistoryData.ui32Head)
+		if((eType == COMMAND_TYPE_MAP_ALL) ||
+			(eType == COMMAND_TYPE_UNMAP_ALL) ||
+			(eType == COMMAND_TYPE_MAP_RANGE) ||
+			(eType == COMMAND_TYPE_UNMAP_RANGE))
 		{
-			break;
+			RECORD_ALLOCATION *psAlloc;
+			IMG_DEV_VIRTADDR sDevVAddrStart, sDevVAddrEnd;
+			IMG_BOOL bMap;
+			IMG_UINT32 ui32AllocIndex;
+
+			MapUnmapCommandGetInfo(psCommand,
+								eType,
+								&sDevVAddrStart,
+								&sDevVAddrEnd,
+								&bMap,
+								&ui32AllocIndex);
+
+			psAlloc = ALLOC_INDEX_TO_PTR(ui32AllocIndex);
+
+			if(DO_TIME_STAMP_MASK(psAlloc->ui64CreationTime) > ui64TimeNs)
+			{
+				/* if this event relates to an allocation we
+				 * are no longer tracking then do not print it
+				 */
+				continue;
+			}
+
+			DeviceMemHistoryFmt(szBuffer,
+								psAlloc->uiPID,
+								psAlloc->szName,
+								CommandTypeToString(eType),
+								sDevVAddrStart,
+								sDevVAddrEnd,
+								ui64TimeNs);
+
+			pfnOSStatsPrintf(pvFilePtr, "%s\n", szBuffer);
 		}
 	}
-	pfnOSStatsPrintf(pvFilePtr, "\nTimestamp reference: %013llu\n", OSClockns64());
+
+	pfnOSStatsPrintf(pvFilePtr, "\nTimestamp reference: %013llu\n", ui64StartTime);
 }
 
 static void DevicememHistoryPrintAllWrapper(void *pvFilePtr, void *pvData, OS_STATS_PRINTF_FUNC* pfnOSStatsPrintf)
@@ -184,6 +1873,61 @@
 	DevicememHistoryUnlock();
 }
 
+static PVRSRV_ERROR CreateRecords(void)
+{
+	gsDevicememHistoryData.sRecords.pasAllocations =
+			OSAllocMem(sizeof(RECORD_ALLOCATION) * ALLOCATION_LIST_NUM_ENTRIES);
+
+	if(gsDevicememHistoryData.sRecords.pasAllocations == NULL)
+	{
+		return PVRSRV_ERROR_OUT_OF_MEMORY;
+	}
+
+	gsDevicememHistoryData.sRecords.pasCircularBuffer =
+			OSAllocMem(sizeof(COMMAND_WRAPPER) * CIRCULAR_BUFFER_NUM_COMMANDS);
+
+	if(gsDevicememHistoryData.sRecords.pasCircularBuffer == NULL)
+	{
+		OSFreeMem(gsDevicememHistoryData.sRecords.pasAllocations);
+		return PVRSRV_ERROR_OUT_OF_MEMORY;
+	}
+
+	return PVRSRV_OK;
+}
+
+static void DestroyRecords(void)
+{
+	OSFreeMem(gsDevicememHistoryData.sRecords.pasCircularBuffer);
+	OSFreeMem(gsDevicememHistoryData.sRecords.pasAllocations);
+}
+
+static void InitialiseRecords(void)
+{
+	IMG_UINT32 i;
+
+	/* initialise the allocations list */
+
+	gsDevicememHistoryData.sRecords.pasAllocations[0].ui32Prev = ALLOCATION_LIST_NUM_ENTRIES - 1;
+	gsDevicememHistoryData.sRecords.pasAllocations[0].ui32Next = 1;
+
+	for(i = 1; i < ALLOCATION_LIST_NUM_ENTRIES; i++)
+	{
+		gsDevicememHistoryData.sRecords.pasAllocations[i].ui32Prev = i - 1;
+		gsDevicememHistoryData.sRecords.pasAllocations[i].ui32Next = i + 1;
+	}
+
+	gsDevicememHistoryData.sRecords.pasAllocations[ALLOCATION_LIST_NUM_ENTRIES - 1].ui32Next = 0;
+
+	gsDevicememHistoryData.sRecords.ui32AllocationsListHead = 0;
+
+	/* initialise the circular buffer with zeros so every command
+	 * is initialised as a command of type COMMAND_TYPE_NONE
+	 */
+	OSCachedMemSet(gsDevicememHistoryData.sRecords.pasCircularBuffer,
+								COMMAND_TYPE_NONE,
+			sizeof(gsDevicememHistoryData.sRecords.pasCircularBuffer[0]) * CIRCULAR_BUFFER_NUM_COMMANDS);
+}
+
 PVRSRV_ERROR DevicememHistoryInitKM(void)
 {
 	PVRSRV_ERROR eError;
@@ -196,14 +1940,16 @@
 		goto err_lock;
 	}
 
-	gsDevicememHistoryData.psAllocations = OSAllocZMem(sizeof(DEVICEMEM_HISTORY_ALLOCATION) * DEVICEMEM_HISTORY_ALLOCATION_HISTORY_LEN);
+	eError = CreateRecords();
 
-	if(gsDevicememHistoryData.psAllocations == NULL)
+	if(eError != PVRSRV_OK)
 	{
-		PVR_DPF((PVR_DBG_ERROR, "DevicememHistoryInitKM: Failed to allocate space for allocations list"));
+		PVR_DPF((PVR_DBG_ERROR, "DevicememHistoryInitKM: Failed to create records"));
 		goto err_allocations;
 	}
 
+	InitialiseRecords();
+
 	gsDevicememHistoryData.pvStatsEntry = OSCreateStatisticEntry("devicemem_history",
 						NULL,
 						DevicememHistoryPrintAllWrapper,
@@ -225,93 +1971,54 @@
 	{
 		OSRemoveStatisticEntry(gsDevicememHistoryData.pvStatsEntry);
 	}
-	OSFREEMEM(gsDevicememHistoryData.psAllocations);
+
+	DestroyRecords();
+
 	OSLockDestroy(gsDevicememHistoryData.hLock);
 }
 
-static PVRSRV_ERROR DevicememHistoryWrite(IMG_DEV_VIRTADDR sDevVAddr, size_t uiSize,
-						const char szString[DEVICEMEM_HISTORY_TEXT_BUFSZ],
-						IMG_BOOL bAlloc)
-{
-	DEVICEMEM_HISTORY_ALLOCATION *psAlloc;
-
-	PVR_ASSERT(gsDevicememHistoryData.psAllocations != NULL);
-
-	DevicememHistoryLock();
-
-	psAlloc = &gsDevicememHistoryData.psAllocations[gsDevicememHistoryData.ui32Head];
-	PVR_ASSERT(gsDevicememHistoryData.ui32Head < DEVICEMEM_HISTORY_ALLOCATION_HISTORY_LEN);
-
-	gsDevicememHistoryData.ui32Head = (gsDevicememHistoryData.ui32Head + 1) % DEVICEMEM_HISTORY_ALLOCATION_HISTORY_LEN;
-
-	psAlloc->sDevVAddr = sDevVAddr;
-	psAlloc->uiSize = uiSize;
-	psAlloc->uiPID = OSGetCurrentProcessID();
-	OSStringNCopy(psAlloc->szString, szString, sizeof(psAlloc->szString));
-	psAlloc->szString[sizeof(psAlloc->szString) - 1] = '\0';
-	psAlloc->bAllocated = bAlloc;
-	psAlloc->ui64Time = OSClockns64();
-
-	DevicememHistoryUnlock();
-
-	return PVRSRV_OK;
-}
-
 PVRSRV_ERROR DevicememHistoryMapKM(IMG_DEV_VIRTADDR sDevVAddr, size_t uiSize, const char szString[DEVICEMEM_HISTORY_TEXT_BUFSZ])
 {
-	return DevicememHistoryWrite(sDevVAddr, uiSize, szString, IMG_TRUE);
+	IMG_UINT32 ui32AllocationIndex = DEVICEMEM_HISTORY_ALLOC_INDEX_NONE;
+	IMG_UINT32 ui32Log2PageSize;
+	IMG_UINT32 ui32StartPage;
+	IMG_UINT32 ui32NumPages;
+
+	/* assume 4K page size */
+	ui32Log2PageSize = 12;
+
+	ui32StartPage = 0;
+	ui32NumPages = (uiSize + 4095) / 4096;
+
+	return DevicememHistoryMapVRangeKM(sDevVAddr,
+								ui32StartPage,
+								ui32NumPages,
+								uiSize,
+								szString,
+								ui32Log2PageSize,
+								ui32AllocationIndex,
+								&ui32AllocationIndex);
 }
 
 PVRSRV_ERROR DevicememHistoryUnmapKM(IMG_DEV_VIRTADDR sDevVAddr, size_t uiSize, const char szString[DEVICEMEM_HISTORY_TEXT_BUFSZ])
 {
-	return DevicememHistoryWrite(sDevVAddr, uiSize, szString, IMG_FALSE);
-}
+	IMG_UINT32 ui32AllocationIndex = DEVICEMEM_HISTORY_ALLOC_INDEX_NONE;
+	IMG_UINT32 ui32Log2PageSize;
+	IMG_UINT32 ui32StartPage;
+	IMG_UINT32 ui32NumPages;
 
-IMG_BOOL DevicememHistoryQuery(DEVICEMEM_HISTORY_QUERY_IN *psQueryIn, DEVICEMEM_HISTORY_QUERY_OUT *psQueryOut)
-{
-	IMG_UINT32 ui32Entry;
+	/* assume 4K page size */
+	ui32Log2PageSize = 12;
 
-	/* initialise the results count for the caller */
-	psQueryOut->ui32NumResults = 0;
+	ui32StartPage = 0;
+	ui32NumPages = (uiSize + 4095) / 4096;
 
-	DevicememHistoryLock();
-
-	/* search from newest to oldest */
-
-	ui32Entry = gsDevicememHistoryData.ui32Head;
-
-	do
-	{
-		DEVICEMEM_HISTORY_ALLOCATION *psAlloc;
-
-		/* searching backwards (from newest to oldest)
-		 * wrap around backwards when going past zero
-		 */
-		ui32Entry = (ui32Entry != 0) ? ui32Entry - 1 : DEVICEMEM_HISTORY_ALLOCATION_HISTORY_LEN - 1;
-		psAlloc = &gsDevicememHistoryData.psAllocations[ui32Entry];
-
-		if(((psAlloc->uiPID == psQueryIn->uiPID) || (psQueryIn->uiPID == DEVICEMEM_HISTORY_PID_ANY)) &&
-			(psQueryIn->sDevVAddr.uiAddr >= psAlloc->sDevVAddr.uiAddr) &&
-			(psQueryIn->sDevVAddr.uiAddr < psAlloc->sDevVAddr.uiAddr + psAlloc->uiSize))
-		{
-				DEVICEMEM_HISTORY_QUERY_OUT_RESULT *psResult = &psQueryOut->sResults[psQueryOut->ui32NumResults];
-
-				OSStringNCopy(psResult->szString, psAlloc->szString, sizeof(psResult->szString));
-				psResult->szString[DEVICEMEM_HISTORY_TEXT_BUFSZ - 1] = '\0';
-				psResult->sBaseDevVAddr = psAlloc->sDevVAddr;
-				psResult->uiSize = psAlloc->uiSize;
-				psResult->bAllocated = psAlloc->bAllocated;
-				psResult->ui64Age = _CalculateAge(psAlloc->ui64Time);
-				psResult->ui64When = psAlloc->ui64Time;
-				/* write the responsible PID in the placeholder */
-				psResult->sProcessInfo.uiPID = psAlloc->uiPID;
-
-				psQueryOut->ui32NumResults++;
-		}
-	} while((psQueryOut->ui32NumResults < DEVICEMEM_HISTORY_QUERY_OUT_MAX_RESULTS) &&
-						(ui32Entry != gsDevicememHistoryData.ui32Head));
-
-	DevicememHistoryUnlock();
-
-	return psQueryOut->ui32NumResults > 0;
+	return DevicememHistoryUnmapVRangeKM(sDevVAddr,
+								ui32StartPage,
+								ui32NumPages,
+								uiSize,
+								szString,
+								ui32Log2PageSize,
+								ui32AllocationIndex,
+								&ui32AllocationIndex);
 }
diff --git a/drivers/staging/imgtec/rogue/devicemem_history_server.h b/drivers/staging/imgtec/rogue/devicemem_history_server.h
index 9341567..a0e4dc5 100644
--- a/drivers/staging/imgtec/rogue/devicemem_history_server.h
+++ b/drivers/staging/imgtec/rogue/devicemem_history_server.h
@@ -61,6 +61,56 @@
 extern PVRSRV_ERROR
 DevicememHistoryUnmapKM(IMG_DEV_VIRTADDR sDevVAddr, size_t uiSize, const char szText[DEVICEMEM_HISTORY_TEXT_BUFSZ]);
 
+
+PVRSRV_ERROR DevicememHistoryMapNewKM(PMR *psPMR,
+							IMG_UINT32 ui32Offset,
+							IMG_DEV_VIRTADDR sDevVAddr,
+							IMG_DEVMEM_SIZE_T uiSize,
+							const char szName[DEVICEMEM_HISTORY_TEXT_BUFSZ],
+							IMG_UINT32 ui32PageSize,
+							IMG_UINT32 ui32AllocationIndex,
+							IMG_UINT32 *pui32AllocationIndexOut);
+
+PVRSRV_ERROR DevicememHistoryUnmapNewKM(PMR *psPMR,
+							IMG_UINT32 ui32Offset,
+							IMG_DEV_VIRTADDR sDevVAddr,
+							IMG_DEVMEM_SIZE_T uiSize,
+							const char szName[DEVICEMEM_HISTORY_TEXT_BUFSZ],
+							IMG_UINT32 ui32PageSize,
+							IMG_UINT32 ui32AllocationIndex,
+							IMG_UINT32 *pui32AllocationIndexOut);
+
+PVRSRV_ERROR DevicememHistoryMapVRangeKM(IMG_DEV_VIRTADDR sBaseDevVAddr,
+							IMG_UINT32 ui32StartPage,
+							IMG_UINT32 ui32NumPages,
+							IMG_DEVMEM_SIZE_T uiAllocSize,
+							const IMG_CHAR szName[DEVICEMEM_HISTORY_TEXT_BUFSZ],
+							IMG_UINT32 ui32Log2PageSize,
+							IMG_UINT32 ui32AllocationIndex,
+							IMG_UINT32 *ui32AllocationIndexOut);
+
+PVRSRV_ERROR DevicememHistoryUnmapVRangeKM(IMG_DEV_VIRTADDR sBaseDevVAddr,
+							IMG_UINT32 ui32StartPage,
+							IMG_UINT32 ui32NumPages,
+							IMG_DEVMEM_SIZE_T uiAllocSize,
+							const IMG_CHAR szName[DEVICEMEM_HISTORY_TEXT_BUFSZ],
+							IMG_UINT32 ui32Log2PageSize,
+							IMG_UINT32 ui32AllocationIndex,
+							IMG_UINT32 *ui32AllocationIndexOut);
+
+PVRSRV_ERROR DevicememHistorySparseChangeKM(PMR *psPMR,
+							IMG_UINT32 ui32Offset,
+							IMG_DEV_VIRTADDR sDevVAddr,
+							IMG_DEVMEM_SIZE_T uiSize,
+							const char szName[DEVICEMEM_HISTORY_TEXT_BUFSZ],
+							IMG_UINT32 ui32PageSize,
+							IMG_UINT32 ui32AllocPageCount,
+							IMG_UINT32 *paui32AllocPageIndices,
+							IMG_UINT32 ui32FreePageCount,
+							IMG_UINT32 *pauiFreePageIndices,
+							IMG_UINT32 AllocationIndex,
+							IMG_UINT32 *pui32AllocationIndexOut);
+
 /* used when the PID does not matter */
 #define DEVICEMEM_HISTORY_PID_ANY 0xFFFFFFFE
 
@@ -70,20 +120,28 @@
 	IMG_DEV_VIRTADDR sDevVAddr;
 } DEVICEMEM_HISTORY_QUERY_IN;
 
-/* store up to 2 results for a lookup. in the case of the faulting page being
+/* Store up to 4 results for a lookup. In the case of the faulting page being
  * re-mapped between the page fault occurring on HW and the page fault analysis
- * being done, the second result entry will show the allocation being unmapped
+ * being done, the second result entry will show the allocation being unmapped.
+ * A further 2 entries are added to cater for multiple buffers in the same page.
  */
-#define DEVICEMEM_HISTORY_QUERY_OUT_MAX_RESULTS 2
+#define DEVICEMEM_HISTORY_QUERY_OUT_MAX_RESULTS 4
 
 typedef struct _DEVICEMEM_HISTORY_QUERY_OUT_RESULT_
 {
 	IMG_CHAR szString[DEVICEMEM_HISTORY_TEXT_BUFSZ];
 	IMG_DEV_VIRTADDR sBaseDevVAddr;
 	size_t uiSize;
-	IMG_BOOL bAllocated;
+	IMG_BOOL bMap;
+	IMG_BOOL bRange;
+	IMG_BOOL bAll;
 	IMG_UINT64 ui64When;
 	IMG_UINT64 ui64Age;
+	/* info for sparse map/unmap operations (i.e. bRange=IMG_TRUE) */
+	IMG_UINT32 ui32StartPage;
+	IMG_UINT32 ui32PageCount;
+	IMG_DEV_VIRTADDR sMapStartAddr;
+	IMG_DEV_VIRTADDR sMapEndAddr;
 	RGXMEM_PROCESS_INFO sProcessInfo;
 } DEVICEMEM_HISTORY_QUERY_OUT_RESULT;
 
@@ -95,6 +153,9 @@
 } DEVICEMEM_HISTORY_QUERY_OUT;
 
 extern IMG_BOOL
-DevicememHistoryQuery(DEVICEMEM_HISTORY_QUERY_IN *psQueryIn, DEVICEMEM_HISTORY_QUERY_OUT *psQueryOut);
+DevicememHistoryQuery(DEVICEMEM_HISTORY_QUERY_IN *psQueryIn,
+                      DEVICEMEM_HISTORY_QUERY_OUT *psQueryOut,
+                      IMG_UINT32 ui32PageSizeBytes,
+                      IMG_BOOL bMatchAnyAllocInPage);
 
 #endif
diff --git a/drivers/staging/imgtec/rogue/devicemem_history_shared.h b/drivers/staging/imgtec/rogue/devicemem_history_shared.h
index 2ad35db..03f1765 100644
--- a/drivers/staging/imgtec/rogue/devicemem_history_shared.h
+++ b/drivers/staging/imgtec/rogue/devicemem_history_shared.h
@@ -51,6 +51,7 @@
 typedef struct _DEVICEMEM_HISTORY_MEMDESC_DATA_
 {
 	IMG_CHAR szText[DEVICEMEM_HISTORY_TEXT_BUFSZ];
+	IMG_UINT32 ui32AllocationIndex;
 } DEVICEMEM_HISTORY_MEMDESC_DATA;
 
 #endif
diff --git a/drivers/staging/imgtec/rogue/devicemem_mmap.h b/drivers/staging/imgtec/rogue/devicemem_mmap.h
deleted file mode 100644
index 2b88b6a..0000000
--- a/drivers/staging/imgtec/rogue/devicemem_mmap.h
+++ /dev/null
@@ -1,102 +0,0 @@
-/*************************************************************************/ /*!
-@File
-@Title          Device Memory Management
-@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
-@Description    OS abstraction for the mmap2 interface for mapping PMRs into
-                User Mode memory
-@License        Dual MIT/GPLv2
-
-The contents of this file are subject to the MIT license as set out below.
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-Alternatively, the contents of this file may be used under the terms of
-the GNU General Public License Version 2 ("GPL") in which case the provisions
-of GPL are applicable instead of those above.
-
-If you wish to allow use of your version of this file only under the terms of
-GPL, and not to allow others to use your version of this file under the terms
-of the MIT license, indicate your decision by deleting the provisions above
-and replace them with the notice and other provisions required by GPL as set
-out in the file called "GPL-COPYING" included in this distribution. If you do
-not delete the provisions above, a recipient may use your version of this file
-under the terms of either the MIT license or GPL.
-
-This License is also included in this distribution in the file called
-"MIT-COPYING".
-
-EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
-PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
-BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
-PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
-COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
-IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
-CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-*/ /**************************************************************************/
-
-#ifndef _DEVICEMEM_MMAP_H_
-#define _DEVICEMEM_MMAP_H_
-
-#include "img_types.h"
-#include "pvrsrv_error.h"
-
-/*
- *
- * OSMMapPMR
- *
- * Causes this PMR to be mapped into CPU memory that the user process
- * may access.
- *
- * Whether the memory is mapped readonly, readwrite, or not at all, is
- * dependent on the PMR itself.
- *
- * The PMR handle is opaque to the user, and lower levels of this
- * stack ensure that the handle is private to this process, such that
- * this API cannot be abused to gain access to other people's PMRs.
- *
- * The OS implementation of this function should return the virtual
- * address and length for the User to use.  The "PrivData" is to be
- * stored opaquely by the caller (N.B. he should make no assumptions,
- * in particular, NULL is a valid handle) and given back to the
- * call to OSMunmapPMR.
- *
- * The OS implementation is free to use the PrivData handle for any
- * purpose it sees fit.
- */
-
-extern PVRSRV_ERROR
-OSMMapPMR(IMG_HANDLE hBridge,
-          IMG_HANDLE hPMR,
-          IMG_DEVMEM_SIZE_T uiPMRLength,
-          IMG_UINT32 uiFlags,
-          IMG_HANDLE *phOSMMapPrivDataOut,
-          void **ppvMappingAddressOut,
-          size_t *puiMappingLengthOut);
-
-/*
- *
- * OSMUnmapPMR
- *
- * The reverse of OSMMapPMR
- *
- * The caller is required to pass the PMR handle back in along with
- * the same 3-tuple of information as was returned by the call to
- * OSMMapPMR
- *
- */
-extern void
-OSMUnmapPMR(IMG_HANDLE hBridge,
-            IMG_HANDLE hPMR,
-            IMG_HANDLE hOSMMapPrivData,
-            void *pvMappingAddress,
-            size_t uiMappingLength);
-
-#endif
diff --git a/drivers/staging/imgtec/rogue/devicemem_pdump.c b/drivers/staging/imgtec/rogue/devicemem_pdump.c
index e9a6d1f..acbc53d 100644
--- a/drivers/staging/imgtec/rogue/devicemem_pdump.c
+++ b/drivers/staging/imgtec/rogue/devicemem_pdump.c
@@ -48,9 +48,16 @@
 #include "img_types.h"
 #include "pvrsrv_error.h"
 #include "pdump.h"
+#include "devicemem.h"
 #include "devicemem_utils.h"
 #include "devicemem_pdump.h"
 #include "client_pdumpmm_bridge.h"
+#if defined(LINUX) && !defined(__KERNEL__)
+#include <stdio.h>
+#if defined(SUPPORT_ANDROID_PLATFORM)
+#include "android_utils.h"
+#endif
+#endif
 
 IMG_INTERNAL void
 DevmemPDumpLoadMem(DEVMEM_MEMDESC *psMemDesc,
@@ -149,6 +156,7 @@
     PVR_ASSERT(eError == PVRSRV_OK);
 }
 
+/* FIXME: This should be server side only */
 IMG_INTERNAL PVRSRV_ERROR
 DevmemPDumpPageCatBaseToSAddr(DEVMEM_MEMDESC		*psMemDesc,
 							  IMG_DEVMEM_OFFSET_T	*puiMemOffset,
@@ -212,6 +220,7 @@
 
 
 
+/* FIXME: Remove? */
 IMG_INTERNAL void
 DevmemPDumpSaveToFileVirtual(DEVMEM_MEMDESC *psMemDesc,
                              IMG_DEVMEM_OFFSET_T uiOffset,
diff --git a/drivers/staging/imgtec/rogue/devicemem_server.c b/drivers/staging/imgtec/rogue/devicemem_server.c
index 9b6bb00..b455b11 100644
--- a/drivers/staging/imgtec/rogue/devicemem_server.c
+++ b/drivers/staging/imgtec/rogue/devicemem_server.c
@@ -59,6 +59,8 @@
 #include "osfunc.h"
 #include "lock.h"
 
+#include "rgx_bvnc_defs_km.h"
+
 #if defined(SUPPORT_BUFFER_SYNC)
 #include <linux/sched.h>
 #include "pvr_buffer_sync.h"
@@ -81,6 +83,12 @@
        memory context is created and they need to store private data that
        is associated with the context. */
     IMG_HANDLE hPrivData;
+
+	/* The following tracks UM applications that need to be notified of a
+	 * page fault */
+	DLLIST_NODE sProcessNotifyListHead;
+	/* The following is a node for the list of registered devmem contexts */
+	DLLIST_NODE sPageFaultNotifyListElem;
 };
 
 struct _DEVMEMINT_CTX_EXPORT_ 
@@ -112,6 +120,12 @@
     IMG_UINT32 uiNumPages;
 };
 
+struct _DEVMEMINT_PF_NOTIFY_
+{
+	IMG_UINT32  ui32PID;
+	DLLIST_NODE sProcessNotifyListElem;
+};
+
 /*************************************************************************/ /*!
 @Function       _DevmemIntCtxAcquire
 @Description    Acquire a reference to the provided device memory context.
@@ -135,7 +149,25 @@
 	{
 		/* The last reference has gone, destroy the context */
 		PVRSRV_DEVICE_NODE *psDevNode = psDevmemCtx->psDevNode;
-	
+		DLLIST_NODE *psNode, *psNodeNext;
+
+		/* If there are any PIDs registered for page fault notification.
+		 * Loop through the registered PIDs and free each one */
+		dllist_foreach_node(&(psDevmemCtx->sProcessNotifyListHead), psNode, psNodeNext)
+		{
+			DEVMEMINT_PF_NOTIFY *psNotifyNode =
+				IMG_CONTAINER_OF(psNode, DEVMEMINT_PF_NOTIFY, sProcessNotifyListElem);
+			dllist_remove_node(psNode);
+			OSFreeMem(psNotifyNode);
+		}
+
+		/* If this context is in the list registered for a debugger, remove
+		 * from that list */
+		if (dllist_node_is_in_list(&psDevmemCtx->sPageFaultNotifyListElem))
+		{
+			dllist_remove_node(&psDevmemCtx->sPageFaultNotifyListElem);
+		}
+
 		if (psDevNode->pfnUnregisterMemoryContext)
 		{
 			psDevNode->pfnUnregisterMemoryContext(psDevmemCtx->hPrivData);
@@ -312,20 +344,25 @@
                    PVRSRV_DEVICE_NODE *psDeviceNode,
                    IMG_BOOL bKernelMemoryCtx,
                    DEVMEMINT_CTX **ppsDevmemCtxPtr,
-                   IMG_HANDLE *hPrivData)
+                   IMG_HANDLE *hPrivData,
+                   IMG_UINT32 *pui32CPUCacheLineSize
+                   )
 {
 	PVRSRV_ERROR eError;
 	DEVMEMINT_CTX *psDevmemCtx;
 	IMG_HANDLE hPrivDataInt = NULL;
 	MMU_DEVICEATTRIBS      *psMMUDevAttrs;
 
-#if defined(RGX_FEATURE_META)
-	psMMUDevAttrs = psDeviceNode->psMMUDevAttrs;
-	PVR_UNREFERENCED_PARAMETER(bKernelMemoryCtx);
-#else
-	psMMUDevAttrs = bKernelMemoryCtx ? psDeviceNode->psFirmwareMMUDevAttrs:
-									   psDeviceNode->psMMUDevAttrs;
-#endif
+	if((psDeviceNode->pfnCheckDeviceFeature) && \
+			psDeviceNode->pfnCheckDeviceFeature(psDeviceNode, RGX_FEATURE_MIPS_BIT_MASK))
+	{
+		psMMUDevAttrs = bKernelMemoryCtx ? psDeviceNode->psFirmwareMMUDevAttrs:
+											psDeviceNode->psMMUDevAttrs;
+	}else
+	{
+		psMMUDevAttrs = psDeviceNode->psMMUDevAttrs;
+		PVR_UNREFERENCED_PARAMETER(bKernelMemoryCtx);
+	}
 
 
 	PVR_DPF((PVR_DBG_MESSAGE, "%s", __FUNCTION__));
@@ -337,17 +374,17 @@
 	{
 		eError = PVRSRV_ERROR_OUT_OF_MEMORY;
 		PVR_DPF ((PVR_DBG_ERROR, "%s: Alloc failed", __FUNCTION__));
-        	goto fail_alloc;
+		goto fail_alloc;
 	}
 
 	OSAtomicWrite(&psDevmemCtx->hRefCount, 1);
-   	psDevmemCtx->psDevNode = psDeviceNode;
+	psDevmemCtx->psDevNode = psDeviceNode;
 
 	/* Call down to MMU context creation */
 
-   	eError = MMU_ContextCreate(psDeviceNode,
-                                   &psDevmemCtx->psMMUContext,
-                                   psMMUDevAttrs);
+	eError = MMU_ContextCreate(psDeviceNode,
+	                           &psDevmemCtx->psMMUContext,
+	                           psMMUDevAttrs);
 	if (eError != PVRSRV_OK)
 	{
 		PVR_DPF((PVR_DBG_ERROR, "%s: MMU_ContextCreate failed", __FUNCTION__));
@@ -370,39 +407,23 @@
 	*hPrivData = hPrivDataInt;
 	*ppsDevmemCtxPtr = psDevmemCtx;
 
-	return PVRSRV_OK;
-
-fail_register:
-    MMU_ContextDestroy(psDevmemCtx->psMMUContext);
-fail_mmucontext:
-	OSFREEMEM(psDevmemCtx);
-fail_alloc:
-    PVR_ASSERT(eError != PVRSRV_OK);
-    return eError;
-}
-
-/*************************************************************************/ /*!
-@Function       DevmemIntCtxCreateCLS
-@Description    Creates and initialises a device memory context.
-@Return         valid Device Memory context handle - Success
-                PVRSRV_ERROR failure code
-*/ /**************************************************************************/
-PVRSRV_ERROR
-DevmemIntCtxCreateCLS(CONNECTION_DATA *psConnection,
-                      PVRSRV_DEVICE_NODE *psDeviceNode,
-                      IMG_BOOL bKernelMemoryCtx,
-                      DEVMEMINT_CTX **ppsDevmemCtxPtr,
-                      IMG_HANDLE *hPrivData,
-                      IMG_UINT32 *pui32CPUCacheLineSize)
-{
 	/* Pass the CPU cache line size through the bridge to the user mode as it can't be queried in user mode.*/
 	*pui32CPUCacheLineSize = OSCPUCacheAttributeSize(PVR_DCACHE_LINE_SIZE);
 
-	return DevmemIntCtxCreate(psConnection,
-	                          psDeviceNode,
-	                          bKernelMemoryCtx,
-	                          ppsDevmemCtxPtr,
-	                          hPrivData);
+	/* Initialise the PID notify list */
+	dllist_init(&(psDevmemCtx->sProcessNotifyListHead));
+	psDevmemCtx->sPageFaultNotifyListElem.psNextNode = NULL;
+	psDevmemCtx->sPageFaultNotifyListElem.psPrevNode = NULL;
+
+	return PVRSRV_OK;
+
+fail_register:
+	MMU_ContextDestroy(psDevmemCtx->psMMUContext);
+fail_mmucontext:
+	OSFreeMem(psDevmemCtx);
+fail_alloc:
+	PVR_ASSERT(eError != PVRSRV_OK);
+	return eError;
 }
 
 /*************************************************************************/ /*!
@@ -488,7 +509,7 @@
 				u8Value,
 				bInitPage,
 #if	defined(PDUMP)
-				psDevNode->pszMMUPxPDumpMemSpaceName,
+				psDevNode->psMMUDevAttrs->pszMMUPxPDumpMemSpaceName,
 				DUMMY_PAGE,
 				&psDevNode->sDummyPage.hPdumpDummyPg,
 #endif
@@ -558,6 +579,18 @@
 {
 	PVRSRV_ERROR eError;
 
+	if (psReservation->psDevmemHeap->uiLog2PageSize > PMR_GetLog2Contiguity(psPMR))
+	{
+		PVR_DPF ((PVR_DBG_ERROR,
+				"%s: Device heap and PMR have incompatible Log2Contiguity (%u - %u). "
+				"PMR contiguity must be a multiple of the heap contiguity!",
+				__func__,
+				psReservation->psDevmemHeap->uiLog2PageSize,
+				PMR_GetLog2Contiguity(psPMR) ));
+		eError = PVRSRV_ERROR_INVALID_PARAMS;
+		goto e0;
+	}
+
 	eError = MMU_MapPages(psReservation->psDevmemHeap->psDevmemCtx->psMMUContext,
 	                      uiFlags,
 	                      sDevVAddrBase,
@@ -567,6 +600,7 @@
 	                      NULL,
 	                      psReservation->psDevmemHeap->uiLog2PageSize);
 
+e0:
 	return eError;
 }
 
@@ -607,6 +641,17 @@
 	PVRSRV_DEVICE_NODE *psDevNode;
 	 PMR_FLAGS_T uiPMRFlags;
 
+	if (uiLog2Contiguity > PMR_GetLog2Contiguity(psPMR))
+	{
+		PVR_DPF ((PVR_DBG_ERROR,
+				"%s: Device heap and PMR have incompatible contiguity (%u - %u). "
+				"Heap contiguity must be a multiple of the heap contiguity!",
+				__func__,
+				uiLog2Contiguity,
+				PMR_GetLog2Contiguity(psPMR) ));
+		eError = PVRSRV_ERROR_INVALID_PARAMS;
+		goto e0;
+	}
 	psDevNode = psDevmemHeap->psDevmemCtx->psDevNode;
 
 	/* allocate memory to record the mapping info */
@@ -624,8 +669,7 @@
     ui32NumDevPages = 0xffffffffU & ( ( (uiAllocationSize - 1) >> uiLog2Contiguity) + 1);
     PVR_ASSERT(ui32NumDevPages << uiLog2Contiguity == uiAllocationSize);
 
-    eError = PMRLockSysPhysAddresses(psPMR,
-                                     uiLog2Contiguity);
+    eError = PMRLockSysPhysAddresses(psPMR);
     if (eError != PVRSRV_OK)
 	{
         goto e2;
@@ -647,11 +691,11 @@
 			 * As the allocation fails we need to fail the map request and
 			 * return appropriate error
 			 *
-			 * Wondering if we do dummy allocation first and then physically lock pages later.
-			 * But on further thought failure of dummy allocation has lesser chance than
-			 * failing of physically locking down of the pages.
-			 * Hence we unlock the locked pages if dummy allocation fails. yes this is 
-			 * time consuming but very unlikely to occur */
+			 * Allocation of dummy page is done after locking the pages for PMR physically
+			 * By implementing this way, the best case path of dummy page being most likely to be
+			 * allocated after physically locking down pages, is considered.
+			 * If the dummy page allocation fails, we do unlock the physical address and the impact
+			 * is a bit more in on demand mode of operation */
 			eError = DevmemIntAllocDummyPage(psDevmemHeap);
 			if(PVRSRV_OK != eError)
 			{
@@ -729,21 +773,22 @@
 DevmemIntUnmapPMR(DEVMEMINT_MAPPING *psMapping)
 {
     PVRSRV_ERROR eError;
-    DEVMEMINT_HEAP *psDevmemHeap;
+    DEVMEMINT_HEAP *psDevmemHeap = psMapping->psReservation->psDevmemHeap;
     /* device virtual address of start of allocation */
     IMG_DEV_VIRTADDR sAllocationDevVAddr;
     /* number of pages (device pages) that allocation spans */
     IMG_UINT32 ui32NumDevPages;
     IMG_BOOL bIsSparse = IMG_FALSE, bNeedBacking = IMG_FALSE;
-	PVRSRV_DEVICE_NODE *psDevNode;
 	PMR_FLAGS_T uiPMRFlags;
 #if defined(SUPPORT_BUFFER_SYNC)
+	PVRSRV_DEVICE_NODE *psDevNode = psDevmemHeap->psDevmemCtx->psDevNode;
 	bool bInterruptible = true;
 	unsigned long ulTimeout = MAX_SCHEDULE_TIMEOUT;
 	IMG_INT iErr;
 
 retry:
-	iErr = pvr_buffer_sync_wait(psMapping->psPMR, bInterruptible, ulTimeout);
+	iErr = pvr_buffer_sync_wait(psDevNode->psBufferSyncContext,
+								psMapping->psPMR, bInterruptible, ulTimeout);
 	if (iErr)
 	{
 		if (iErr == -ERESTARTSYS)
@@ -761,9 +806,6 @@
 	}
 #endif
 
-    psDevmemHeap = psMapping->psReservation->psDevmemHeap;
-	psDevNode = psDevmemHeap->psDevmemCtx->psDevNode;
-
     ui32NumDevPages = psMapping->uiNumPages;
     sAllocationDevVAddr = psMapping->psReservation->sBase;
 
@@ -925,26 +967,25 @@
 }
 
 PVRSRV_ERROR
-DeviceMemChangeSparseServer(DEVMEMINT_HEAP *psDevmemHeap,
-					PMR *psPMR,
-					IMG_UINT32 ui32AllocPageCount,
-					IMG_UINT32 *pai32AllocIndices,
-					IMG_UINT32 ui32FreePageCount,
-					IMG_UINT32 *pai32FreeIndices,
-					SPARSE_MEM_RESIZE_FLAGS uiSparseFlags,
-					PVRSRV_MEMALLOCFLAGS_T uiFlags,
-					IMG_DEV_VIRTADDR sDevVAddrBase,
-					IMG_UINT64 sCpuVAddrBase,
-					IMG_UINT32 *pui32Status)
+DevmemIntChangeSparse(DEVMEMINT_HEAP *psDevmemHeap,
+                      PMR *psPMR,
+                      IMG_UINT32 ui32AllocPageCount,
+                      IMG_UINT32 *pai32AllocIndices,
+                      IMG_UINT32 ui32FreePageCount,
+                      IMG_UINT32 *pai32FreeIndices,
+                      SPARSE_MEM_RESIZE_FLAGS uiSparseFlags,
+                      PVRSRV_MEMALLOCFLAGS_T uiFlags,
+                      IMG_DEV_VIRTADDR sDevVAddrBase,
+                      IMG_UINT64 sCpuVAddrBase)
 {
-	PVRSRV_ERROR eError = ~PVRSRV_OK;
+	PVRSRV_ERROR eError;
 
-	IMG_UINT32 uiLog2PageSize = GET_LOG2_PAGESIZE(),uiPageSize=0;
+	IMG_UINT32 uiLog2PageSize = PMR_GetLog2Contiguity(psPMR);
 
-	uiPageSize = (1 << uiLog2PageSize);
 	/*
 	 * The order of steps in which this request is done is given below. The order of
-	 * operations is very important in this case
+	 * operations is very important in this case:
+	 *
 	 * 1. The parameters are validated in function PMR_ChangeSparseMem below.
 	 * 	   A successful response indicates all the parameters are correct.
 	 * 	   In failure case we bail out from here with out processing further.
@@ -952,125 +993,125 @@
 	 *    and the corresponding PMR status changes.
 	 *    when this call fails, it is ensured that the state of the PMR before is
 	 *    not disturbed. If it succeeds, then we can go ahead with the subsequent steps.
-	 * 3. Dewire the GPU page table entries for the pages to be freed.
+	 * 3. Invalidate the GPU page table entries for the pages to be freed.
 	 * 4. Write the GPU page table entries for the pages that got allocated.
 	 * 5. Change the corresponding CPU space map.
 	 *
 	 * The above steps can be selectively controlled using flags.
 	 */
-	*pui32Status = PVRSRV_OK;
 
 	{
-		if(uiSparseFlags & (SPARSE_REMAP_MEM | SPARSE_RESIZE_BOTH))
+		if (uiSparseFlags & (SPARSE_REMAP_MEM | SPARSE_RESIZE_BOTH))
 		{
-			/*
-			 * Do the PMR specific changes first
-			 */
+			/* Do the PMR specific changes first */
 			eError = PMR_ChangeSparseMem(psPMR,
-					ui32AllocPageCount,
-					pai32AllocIndices,
-					ui32FreePageCount,
-					pai32FreeIndices,
-					uiSparseFlags,
-					pui32Status);
-			if(PVRSRV_OK != eError)
+			                             ui32AllocPageCount,
+			                             pai32AllocIndices,
+			                             ui32FreePageCount,
+			                             pai32FreeIndices,
+			                             uiSparseFlags);
+			if (PVRSRV_OK != eError)
 			{
-				PVR_DPF((PVR_DBG_MESSAGE,"%s: Failed to do PMR specific changes......",__func__));
-				goto SparseChangeError;
+				PVR_DPF((PVR_DBG_MESSAGE,
+				        "%s: Failed to do PMR specific changes.",
+				        __func__));
+				goto e0;
 			}
 
-			/*
-			 * Dewire the page table entries for the free pages
-			 * Optimization later would be not to touch the ones that gets re-mapped
-			 */
-			if((0 != ui32FreePageCount) && (uiSparseFlags & SPARSE_RESIZE_FREE))
+			/* Invalidate the page table entries for the free pages.
+			 * Optimisation later would be not to touch the ones that gets re-mapped */
+			if ((0 != ui32FreePageCount) && (uiSparseFlags & SPARSE_RESIZE_FREE))
 			{
 				PMR_FLAGS_T uiPMRFlags;
 				IMG_BOOL bNeedBacking = IMG_FALSE;
+
 				/*Get the flags*/
 				uiPMRFlags = PMR_Flags(psPMR);
 				bNeedBacking = PVRSRV_IS_SPARSE_DUMMY_BACKING_REQUIRED(uiPMRFlags);
 
-				if(SPARSE_REMAP_MEM != (uiSparseFlags & SPARSE_REMAP_MEM))
+				if (SPARSE_REMAP_MEM != (uiSparseFlags & SPARSE_REMAP_MEM))
 				{
-					/*Unmap the pages and mark them invalid in the MMU PTE */
+					/* Unmap the pages and mark them invalid in the MMU PTE */
 					MMU_UnmapPages (psDevmemHeap->psDevmemCtx->psMMUContext,
-							uiFlags,
-							sDevVAddrBase,
-							ui32FreePageCount,
-							pai32FreeIndices,
-							uiLog2PageSize,
-							bNeedBacking);
+					                uiFlags,
+					                sDevVAddrBase,
+					                ui32FreePageCount,
+					                pai32FreeIndices,
+					                uiLog2PageSize,
+					                bNeedBacking);
 				}
 			}
 
-			/*
-			 *  Wire the pages tables that got allocated
-			 */
-			if((0 != ui32AllocPageCount) && (uiSparseFlags & SPARSE_RESIZE_ALLOC))
+			/* Wire the pages tables that got allocated */
+			if ((0 != ui32AllocPageCount) && (uiSparseFlags & SPARSE_RESIZE_ALLOC))
 			{
-				/*Map the pages and mark them Valid in the MMU PTE */
+				/* Map the pages and mark them Valid in the MMU PTE */
 				eError = MMU_MapPages (psDevmemHeap->psDevmemCtx->psMMUContext,
-						uiFlags,
-						sDevVAddrBase,
-						psPMR,
-						0,
-						ui32AllocPageCount,
-						pai32AllocIndices,
-						uiLog2PageSize);
+				                       uiFlags,
+				                       sDevVAddrBase,
+				                       psPMR,
+				                       0,
+				                       ui32AllocPageCount,
+				                       pai32AllocIndices,
+				                       uiLog2PageSize);
 
-				if(PVRSRV_OK != eError)
+				if (PVRSRV_OK != eError)
 				{
-					PVR_DPF((PVR_DBG_MESSAGE,"%s: Failed to map alloc indices......",__func__));
-					goto SparseChangeError;
+					PVR_DPF((PVR_DBG_MESSAGE,
+					        "%s: Failed to map alloc indices.",
+					        __func__));
+					goto e0;
 				}
 			}
 			
-			/*Should this be a debug feature or ever used in real scenario */
-			if(SPARSE_REMAP_MEM == (uiSparseFlags & SPARSE_REMAP_MEM))
+			/* Currently only used for debug */
+			if (SPARSE_REMAP_MEM == (uiSparseFlags & SPARSE_REMAP_MEM))
 			{
 				eError = MMU_MapPages (psDevmemHeap->psDevmemCtx->psMMUContext,
-						uiFlags,
-						sDevVAddrBase,
-						psPMR,
-						0,
-						ui32AllocPageCount,
-						pai32FreeIndices,
-						uiLog2PageSize);
-				if(PVRSRV_OK != eError)
+				                       uiFlags,
+				                       sDevVAddrBase,
+				                       psPMR,
+				                       0,
+				                       ui32AllocPageCount,
+				                       pai32FreeIndices,
+				                       uiLog2PageSize);
+				if (PVRSRV_OK != eError)
 				{
-					PVR_DPF((PVR_DBG_MESSAGE,"%s: Failed to map Free indices......",__func__));
-					goto SparseChangeError;
+					PVR_DPF((PVR_DBG_MESSAGE,
+					        "%s: Failed to map Free indices.",
+					        __func__));
+					goto e0;
 				}
 			}
 		}
 
 	}
 #ifndef PVRSRV_UNMAP_ON_SPARSE_CHANGE
-	/*
-	 * Do the changes in sparse on to the CPU virtual map accordingly
-	 */
-
-	if(uiSparseFlags & SPARSE_MAP_CPU_ADDR)
+	/* Do the changes in sparse on to the CPU virtual map accordingly */
+	if (uiSparseFlags & SPARSE_MAP_CPU_ADDR)
 	{
-		if(sCpuVAddrBase != 0)
+		if (sCpuVAddrBase != 0)
 		{
 			eError = PMR_ChangeSparseMemCPUMap(psPMR,
-												sCpuVAddrBase,
-												ui32AllocPageCount,
-												pai32AllocIndices,
-												ui32FreePageCount,
-												pai32FreeIndices,
-												pui32Status);
-			if(PVRSRV_OK != eError)
+			                                   sCpuVAddrBase,
+			                                   ui32AllocPageCount,
+			                                   pai32AllocIndices,
+			                                   ui32FreePageCount,
+			                                   pai32FreeIndices);
+			if (PVRSRV_OK != eError)
 			{
-				PVR_DPF((PVR_DBG_MESSAGE,"%s: Failed to map to CPU addr space......",__func__));
-				goto SparseChangeError;
+				PVR_DPF((PVR_DBG_MESSAGE,
+				        "%s: Failed to map to CPU addr space.",
+				        __func__));
+				goto e0;
 			}
 		}
 	}
 #endif
-	SparseChangeError:
+
+	return PVRSRV_OK;
+
+e0:
 	return eError;	
 }
 
@@ -1099,12 +1140,48 @@
 	return PVRSRV_OK;
 }
 
-PVRSRV_ERROR DevmemIntIsVDevAddrValid(DEVMEMINT_CTX *psDevMemContext,
+PVRSRV_ERROR DevmemIntIsVDevAddrValid(CONNECTION_DATA * psConnection,
+                                      PVRSRV_DEVICE_NODE *psDevNode,
+                                      DEVMEMINT_CTX *psDevMemContext,
                                       IMG_DEV_VIRTADDR sDevAddr)
 {
-    return MMU_IsVDevAddrValid(psDevMemContext->psMMUContext,
-                               GET_LOG2_PAGESIZE(),
-                               sDevAddr) ? PVRSRV_OK : PVRSRV_ERROR_INVALID_GPU_ADDR;
+	IMG_UINT32 i, j, uiLog2HeapPageSize = 0;
+	DEVICE_MEMORY_INFO *psDinfo = &psDevNode->sDevMemoryInfo;
+	DEVMEM_HEAP_CONFIG *psConfig = psDinfo->psDeviceMemoryHeapConfigArray;
+
+	IMG_BOOL bFound = IMG_FALSE;
+
+	for (i = 0;
+	     i < psDinfo->uiNumHeapConfigs && !bFound;
+	     i++)
+	{
+		for (j = 0;
+		     j < psConfig[i].uiNumHeaps  && !bFound;
+		     j++)
+		{
+			IMG_DEV_VIRTADDR uiBase =
+					psConfig[i].psHeapBlueprintArray[j].sHeapBaseAddr;
+			IMG_DEVMEM_SIZE_T uiSize =
+					psConfig[i].psHeapBlueprintArray[j].uiHeapLength;
+
+			if ( (sDevAddr.uiAddr >= uiBase.uiAddr) &&
+			     (sDevAddr.uiAddr < (uiBase.uiAddr + uiSize)))
+			{
+				uiLog2HeapPageSize =
+						psConfig[i].psHeapBlueprintArray[j].uiLog2DataPageSize;
+				bFound = IMG_TRUE;
+			}
+		}
+	}
+
+	if (uiLog2HeapPageSize == 0)
+	{
+		return PVRSRV_ERROR_INVALID_GPU_ADDR;
+	}
+
+	return MMU_IsVDevAddrValid(psDevMemContext->psMMUContext,
+	                           uiLog2HeapPageSize,
+	                           sDevAddr) ? PVRSRV_OK : PVRSRV_ERROR_INVALID_GPU_ADDR;
 }
 
 
@@ -1195,19 +1272,179 @@
 }
 
 /*************************************************************************/ /*!
-@Function       DevmemSLCFlushInvalRequest
-@Description    Requests a SLC Flush and Invalidate
-@Input          psDeviceNode    Device node
-@Input          psPmr           PMR
-@Return         PVRSRV_OK
+@Function       DevmemIntRegisterPFNotify
+@Description    Registers a PID to be notified when a page fault occurs on a
+                specific device memory context.
+@Input          psDevmemCtx    The context to be notified about.
+@Input          ui32PID        The PID of the process that would like to be
+                               notified.
+@Input          bRegister      If true, register. If false, de-register.
+@Return         PVRSRV_ERROR.
 */ /**************************************************************************/
-PVRSRV_ERROR
-DevmemSLCFlushInvalRequest(PVRSRV_DEVICE_NODE *psDeviceNode,
-							PMR *psPmr)
+PVRSRV_ERROR DevmemIntRegisterPFNotifyKM(DEVMEMINT_CTX *psDevmemCtx,
+                                         IMG_INT32     ui32PID,
+                                         IMG_BOOL      bRegister)
 {
+	PVRSRV_DEVICE_NODE *psDevNode;
+	DLLIST_NODE         *psNode, *psNodeNext;
+	DEVMEMINT_PF_NOTIFY *psNotifyNode;
+	IMG_BOOL            bPresent = IMG_FALSE;
 
-	/* invoke SLC flush and invalidate request */
-	psDeviceNode->pfnSLCCacheInvalidateRequest(psDeviceNode, psPmr);
+	if (psDevmemCtx == NULL)
+	{
+		PVR_ASSERT(!"Devmem Context Missing");
+		return PVRSRV_ERROR_INVALID_PARAMS;
+	}
+
+	psDevNode = psDevmemCtx->psDevNode;
+
+	if (bRegister)
+	{
+		/* If this is the first PID in the list, the device memory context
+		 * needs to be registered for notification */
+		if (dllist_is_empty(&psDevmemCtx->sProcessNotifyListHead))
+		{
+			dllist_add_to_tail(&psDevNode->sMemoryContextPageFaultNotifyListHead,
+			                   &psDevmemCtx->sPageFaultNotifyListElem);
+		}
+	}
+
+	/* Loop through the registered PIDs and check whether this one is
+	 * present */
+	dllist_foreach_node(&(psDevmemCtx->sProcessNotifyListHead), psNode, psNodeNext)
+	{
+		psNotifyNode = IMG_CONTAINER_OF(psNode, DEVMEMINT_PF_NOTIFY, sProcessNotifyListElem);
+
+		if (psNotifyNode->ui32PID == ui32PID)
+		{
+			bPresent = IMG_TRUE;
+			break;
+		}
+	}
+
+	if (bRegister == IMG_TRUE)
+	{
+		if (bPresent)
+		{
+			PVR_DPF((PVR_DBG_ERROR,
+			         "%s: Trying to register a PID that is already registered",
+			         __func__));
+			return PVRSRV_ERROR_PID_ALREADY_REGISTERED;
+		}
+
+		psNotifyNode = OSAllocMem(sizeof(*psNotifyNode));
+		if (psNotifyNode == NULL)
+		{
+			PVR_DPF((PVR_DBG_ERROR,
+			         "%s: Unable to allocate memory for the notify list",
+			          __func__));
+			return PVRSRV_ERROR_OUT_OF_MEMORY;
+		}
+		psNotifyNode->ui32PID = ui32PID;
+		dllist_add_to_tail(&(psDevmemCtx->sProcessNotifyListHead), &(psNotifyNode->sProcessNotifyListElem));
+	}
+	else
+	{
+		if (!bPresent)
+		{
+			PVR_DPF((PVR_DBG_ERROR,
+			         "%s: Trying to unregister a PID that is not registered",
+			         __func__));
+			return PVRSRV_ERROR_PID_NOT_REGISTERED;
+		}
+		dllist_remove_node(psNode);
+		psNotifyNode = IMG_CONTAINER_OF(psNode, DEVMEMINT_PF_NOTIFY, sProcessNotifyListElem);
+		OSFreeMem(psNotifyNode);
+	}
+
+	if (!bRegister)
+	{
+		/* If the last process in the list is being unregistered, then also
+		 * unregister the device memory context from the notify list. */
+		if (dllist_is_empty(&psDevmemCtx->sProcessNotifyListHead))
+		{
+			dllist_remove_node(&psDevmemCtx->sPageFaultNotifyListElem);
+		}
+	}
+
+	return PVRSRV_OK;
+}
+
+/*************************************************************************/ /*!
+@Function       DevmemIntPFNotify
+@Description    Notifies any processes that have registered themselves to be
+                notified when a page fault happens on a specific device memory
+                context.
+@Input          *psDevNode           The device node.
+@Input          ui64FaultedPCAddress The page catalogue address that faulted.
+@Return         PVRSRV_ERROR
+*/ /**************************************************************************/
+PVRSRV_ERROR DevmemIntPFNotify(PVRSRV_DEVICE_NODE *psDevNode,
+                               IMG_UINT64         ui64FaultedPCAddress)
+{
+	DLLIST_NODE         *psNode, *psNodeNext;
+	DEVMEMINT_PF_NOTIFY *psNotifyNode;
+	PVRSRV_ERROR        eError;
+	DEVMEMINT_CTX       *psDevmemCtx = NULL;
+	IMG_BOOL            bFailed = IMG_FALSE;
+
+	if (dllist_is_empty(&(psDevNode->sMemoryContextPageFaultNotifyListHead)))
+	{
+		return PVRSRV_OK;
+	}
+
+	dllist_foreach_node(&(psDevNode->sMemoryContextPageFaultNotifyListHead), psNode, psNodeNext)
+	{
+		DEVMEMINT_CTX *psThisContext =
+			IMG_CONTAINER_OF(psNode, DEVMEMINT_CTX, sPageFaultNotifyListElem);
+		IMG_DEV_PHYADDR sPCDevPAddr;
+
+		eError = MMU_AcquireBaseAddr(psThisContext->psMMUContext, &sPCDevPAddr);
+		if (eError != PVRSRV_OK)
+		{
+			PVR_DPF((PVR_DBG_ERROR,
+			         "%s: Failed to Acquire Base Address (%s)",
+			         __func__,
+			         PVRSRVGetErrorStringKM(eError)));
+			return eError;
+		}
+
+		if (sPCDevPAddr.uiAddr == ui64FaultedPCAddress)
+		{
+			psDevmemCtx = psThisContext;
+			break;
+		}
+	}
+
+	if (psDevmemCtx == NULL)
+	{
+		/* Not found, just return */
+		return PVRSRV_OK;
+	}
+
+	/* Loop through each registered PID and send a signal to the process */
+	dllist_foreach_node(&(psDevmemCtx->sProcessNotifyListHead), psNode, psNodeNext)
+	{
+		psNotifyNode = IMG_CONTAINER_OF(psNode, DEVMEMINT_PF_NOTIFY, sProcessNotifyListElem);
+
+		eError = OSDebugSignalPID(psNotifyNode->ui32PID);
+		if (eError != PVRSRV_OK)
+		{
+			PVR_DPF((PVR_DBG_ERROR,
+			         "%s: Unable to signal process for PID: %u",
+			         __func__,
+			         psNotifyNode->ui32PID));
+
+			PVR_ASSERT(!"Unable to signal process");
+
+			bFailed = IMG_TRUE;
+		}
+	}
+
+	if (bFailed)
+	{
+		return PVRSRV_ERROR_SIGNAL_FAILED;
+	}
 
 	return PVRSRV_OK;
 }
diff --git a/drivers/staging/imgtec/rogue/devicemem_server.h b/drivers/staging/imgtec/rogue/devicemem_server.h
index 2ed0677..9025a01 100644
--- a/drivers/staging/imgtec/rogue/devicemem_server.h
+++ b/drivers/staging/imgtec/rogue/devicemem_server.h
@@ -60,6 +60,7 @@
 
 typedef struct _DEVMEMINT_RESERVATION_ DEVMEMINT_RESERVATION;
 typedef struct _DEVMEMINT_MAPPING_ DEVMEMINT_MAPPING;
+typedef struct _DEVMEMINT_PF_NOTIFY_ DEVMEMINT_PF_NOTIFY;
 
 
 /**************************************************************************/ /*!
@@ -175,18 +176,8 @@
                    /* devnode / perproc etc */
                    IMG_BOOL bKernelMemoryCtx,
                    DEVMEMINT_CTX **ppsDevmemCtxPtr,
-                   IMG_HANDLE *hPrivData);
-
-/* Same as DevmemIntCtxCreate but additionally carries the
- * CPU cache line size back to the user */
-extern PVRSRV_ERROR
-DevmemIntCtxCreateCLS(CONNECTION_DATA *psConnection,
-                      PVRSRV_DEVICE_NODE *psDeviceNode,
-                      IMG_BOOL bKernelMemoryCtx,
-                      DEVMEMINT_CTX **ppsDevmemCtxPtr,
-                      IMG_HANDLE *hPrivData,
-                      IMG_UINT32 *pui32CPUCacheLineSize);
-
+                   IMG_HANDLE *hPrivData,
+                   IMG_UINT32 *pui32CPUCacheLineSize);
 /*
  * DevmemIntCtxDestroy()
  *
@@ -337,9 +328,9 @@
 DevmemIntUnreserveRange(DEVMEMINT_RESERVATION *psDevmemReservation);
 
 /*************************************************************************/ /*!
-@Function       DeviceMemChangeSparseServer
+@Function       DevmemIntChangeSparse
 @Description    Changes the sparse allocations of a PMR by allocating and freeing
-				pages and changing their corresponding CPU and GPU mappings.
+                pages and changing their corresponding CPU and GPU mappings.
 
 @input          psDevmemHeap          Pointer to the heap we map on
 @input          psPMR                 The PMR we want to map
@@ -360,32 +351,50 @@
 @Return         PVRSRV_ERROR failure code
 */ /**************************************************************************/
 extern PVRSRV_ERROR
-DeviceMemChangeSparseServer(DEVMEMINT_HEAP *psDevmemHeap,
-					PMR *psPMR,
-					IMG_UINT32 ui32AllocPageCount,
-					IMG_UINT32 *pai32AllocIndices,
-					IMG_UINT32 ui32FreePageCount,
-					IMG_UINT32 *pai32FreeIndices,
-					SPARSE_MEM_RESIZE_FLAGS uiSparseFlags,
-					PVRSRV_MEMALLOCFLAGS_T uiFlags,
-					IMG_DEV_VIRTADDR sDevVAddrBase,
-					IMG_UINT64 sCpuVAddrBase,
-					IMG_UINT32 *pui32Status);
-
-/*
- * SLCFlushInvalRequest()
- *
- * Schedules an SLC Flush & Invalidate on the firmware if required.
- * If the request is performed depends on the caching attributes
- * of the allocation and hence depends on the underlying PMR
- */
-extern PVRSRV_ERROR
-DevmemSLCFlushInvalRequest(PVRSRV_DEVICE_NODE *psDeviceNode, PMR *psPmr);
+DevmemIntChangeSparse(DEVMEMINT_HEAP *psDevmemHeap,
+                      PMR *psPMR,
+                      IMG_UINT32 ui32AllocPageCount,
+                      IMG_UINT32 *pai32AllocIndices,
+                      IMG_UINT32 ui32FreePageCount,
+                      IMG_UINT32 *pai32FreeIndices,
+                      SPARSE_MEM_RESIZE_FLAGS uiSparseFlags,
+                      PVRSRV_MEMALLOCFLAGS_T uiFlags,
+                      IMG_DEV_VIRTADDR sDevVAddrBase,
+                      IMG_UINT64 sCpuVAddrBase);
 
 extern PVRSRV_ERROR
-DevmemIntIsVDevAddrValid(DEVMEMINT_CTX *psDevMemContext,
+DevmemIntIsVDevAddrValid(CONNECTION_DATA * psConnection,
+                         PVRSRV_DEVICE_NODE *psDevNode,
+                         DEVMEMINT_CTX *psDevMemContext,
                          IMG_DEV_VIRTADDR sDevAddr);
 
+/*************************************************************************/ /*!
+@Function       DevmemIntRegisterPFNotify
+@Description    Registers a PID to be notified when a page fault occurs on a
+                specific device memory context.
+@Input          psDevmemCtx    The context to be notified about.
+@Input          ui32PID        The PID of the process that would like to be
+                               notified.
+@Input          bRegister      If true, register. If false, de-register.
+@Return         PVRSRV_ERROR.
+*/ /**************************************************************************/
+IMG_EXPORT PVRSRV_ERROR
+DevmemIntRegisterPFNotifyKM(DEVMEMINT_CTX *psDevmemCtx,
+                            IMG_INT32     ui32PID,
+                            IMG_BOOL      bRegister);
+
+/*************************************************************************/ /*!
+@Function       DevmemIntPFNotify
+@Description    Notifies any processes that have registered themselves to be
+                notified when a page fault happens on a specific device memory
+                context.
+@Input          *psDevNode           The device node.
+@Input          ui64FaultedPCAddress The page catalogue address that faulted.
+@Return         PVRSRV_ERROR
+*/ /**************************************************************************/
+PVRSRV_ERROR DevmemIntPFNotify(PVRSRV_DEVICE_NODE *psDevNode,
+                               IMG_UINT64         ui64FaultedPCAddress);
+
 #if defined(PDUMP)
 /*
  * DevmemIntPDumpSaveToFileVirtual()
@@ -393,14 +402,16 @@
  * Writes out PDump "SAB" commands with the data found in memory at
  * the given virtual address.
  */
+/* FIXME: uiArraySize shouldn't be here, and is an
+   artefact of the bridging */
 extern PVRSRV_ERROR
 DevmemIntPDumpSaveToFileVirtual(DEVMEMINT_CTX *psDevmemCtx,
                                 IMG_DEV_VIRTADDR sDevAddrStart,
                                 IMG_DEVMEM_SIZE_T uiSize,
                                 IMG_UINT32 uiArraySize,
                                 const IMG_CHAR *pszFilename,
-								IMG_UINT32 ui32FileOffset,
-								IMG_UINT32 ui32PDumpFlags);
+                                IMG_UINT32 ui32FileOffset,
+                                IMG_UINT32 ui32PDumpFlags);
 
 extern IMG_UINT32
 DevmemIntMMUContextID(DEVMEMINT_CTX *psDevMemContext);
diff --git a/drivers/staging/imgtec/rogue/devicemem_server_utils.h b/drivers/staging/imgtec/rogue/devicemem_server_utils.h
index f492040..632eba1 100644
--- a/drivers/staging/imgtec/rogue/devicemem_server_utils.h
+++ b/drivers/staging/imgtec/rogue/devicemem_server_utils.h
@@ -43,15 +43,17 @@
 
 #include "img_defs.h"
 #include "img_types.h"
+#include "device.h"
 #include "pvrsrv_memallocflags.h"
 #include "pvrsrv.h"
 
-static INLINE IMG_UINT32 DevmemCPUCacheMode(PVRSRV_MEMALLOCFLAGS_T ulFlags)
+static INLINE IMG_UINT32 DevmemCPUCacheMode(PVRSRV_DEVICE_NODE *psDeviceNode,
+											PVRSRV_MEMALLOCFLAGS_T ulFlags)
 {
-	IMG_UINT32 ui32CPUCacheMode = ulFlags & PVRSRV_MEMALLOCFLAG_CPU_CACHE_MODE_MASK;
+	IMG_UINT32 ui32CPUCacheMode = PVRSRV_CPU_CACHE_MODE(ulFlags);
 	IMG_UINT32 ui32Ret;
 
-	PVR_ASSERT(ui32CPUCacheMode == (ulFlags & PVRSRV_MEMALLOCFLAG_CPU_CACHE_MODE_MASK));
+	PVR_ASSERT(ui32CPUCacheMode == PVRSRV_CPU_CACHE_MODE(ulFlags));
 
 	switch (ui32CPUCacheMode)
 	{
@@ -68,25 +70,26 @@
 			break;
 
 		case PVRSRV_MEMALLOCFLAG_CPU_CACHE_COHERENT:
-			/* Fall through */
-		case PVRSRV_MEMALLOCFLAG_CPU_CACHED_CACHE_COHERENT:
+
 			/*
-				If the allocation needs to be coherent what we end up doing
-				depends on the snooping features of the system
+			 * If system has no coherency but coherency has been requested for CPU
+			 * and GPU we currently have to fall back to uncached.
+			 *
+			 * Usually the first case here should return an error but as long as a lot
+			 * of services allocations using both CPU/GPU coherency flags and rely on
+			 * the UNCACHED fallback we have to leave it here.
 			*/
-			if (PVRSRVSystemSnoopingOfCPUCache())
+			if ( (PVRSRV_GPU_CACHE_MODE(ulFlags) == PVRSRV_MEMALLOCFLAG_GPU_CACHE_COHERENT) &&
+				!(PVRSRVSystemSnoopingOfCPUCache(psDeviceNode->psDevConfig) && PVRSRVSystemSnoopingOfDeviceCache(psDeviceNode->psDevConfig)) )
 			{
-				/*
-					If the system has CPU cache snooping (tested above)
-					then the allocation should be cached ...
-				*/
-				ui32Ret = PVRSRV_MEMALLOCFLAG_CPU_CACHED;
+				ui32Ret = PVRSRV_MEMALLOCFLAG_CPU_UNCACHED;
 			}
 			else
 			{
-				/* ... otherwise it should be uncached */
-				ui32Ret = PVRSRV_MEMALLOCFLAG_CPU_UNCACHED;
+				ui32Ret = PVRSRV_MEMALLOCFLAG_CPU_CACHED;
 			}
+
+			break;
 			break;
 
 		default:
@@ -103,12 +106,13 @@
 	return ui32Ret;
 }
 
-static INLINE IMG_UINT32 DevmemDeviceCacheMode(PVRSRV_MEMALLOCFLAGS_T ulFlags)
+static INLINE IMG_UINT32 DevmemDeviceCacheMode(PVRSRV_DEVICE_NODE *psDeviceNode,
+											   PVRSRV_MEMALLOCFLAGS_T ulFlags)
 {
-	IMG_UINT32 ui32DeviceCacheMode = ulFlags & PVRSRV_MEMALLOCFLAG_GPU_CACHE_MODE_MASK;
+	IMG_UINT32 ui32DeviceCacheMode = PVRSRV_GPU_CACHE_MODE(ulFlags);
 	IMG_UINT32 ui32Ret;
 
-	PVR_ASSERT(ui32DeviceCacheMode == (ulFlags & PVRSRV_MEMALLOCFLAG_GPU_CACHE_MODE_MASK));
+	PVR_ASSERT(ui32DeviceCacheMode == PVRSRV_GPU_CACHE_MODE(ulFlags));
 
 	switch (ui32DeviceCacheMode)
 	{
@@ -125,25 +129,25 @@
 			break;
 
 		case PVRSRV_MEMALLOCFLAG_GPU_CACHE_COHERENT:
-			/* Fall through */
-		case PVRSRV_MEMALLOCFLAG_GPU_CACHED_CACHE_COHERENT:
+
 			/*
-				If the allocation needs to be coherent what we end up doing
-				depends on the snooping features of the system
+			 * If system has no coherency but coherency has been requested for CPU
+			 * and GPU we currently have to fall back to uncached.
+			 *
+			 * Usually the first case here should return an error but as long as a lot
+			 * of services allocations using both CPU/GPU coherency flags and rely on
+			 * the UNCACHED fallback we have to leave it here.
 			*/
-			if (PVRSRVSystemSnoopingOfDeviceCache())
+			if ( (PVRSRV_CPU_CACHE_MODE(ulFlags) == PVRSRV_MEMALLOCFLAG_CPU_CACHE_COHERENT) &&
+				!(PVRSRVSystemSnoopingOfCPUCache(psDeviceNode->psDevConfig) && PVRSRVSystemSnoopingOfDeviceCache(psDeviceNode->psDevConfig)) )
 			{
-				/*
-					If the system has GPU cache snooping (tested above)
-					then the allocation should be cached ...
-				*/
-				ui32Ret = PVRSRV_MEMALLOCFLAG_GPU_CACHED;
+				ui32Ret = PVRSRV_MEMALLOCFLAG_GPU_UNCACHED;
 			}
 			else
 			{
-				/* ... otherwise it should be uncached */
-				ui32Ret = PVRSRV_MEMALLOCFLAG_GPU_UNCACHED;
+				ui32Ret = PVRSRV_MEMALLOCFLAG_GPU_CACHED;
 			}
+
 			break;
 
 		default:
@@ -160,32 +164,32 @@
 	return ui32Ret;
 }
 
-static INLINE IMG_BOOL DevmemCPUCacheCoherency(PVRSRV_MEMALLOCFLAGS_T ulFlags)
+static INLINE IMG_BOOL DevmemCPUCacheCoherency(PVRSRV_DEVICE_NODE *psDeviceNode,
+											   PVRSRV_MEMALLOCFLAGS_T ulFlags)
 {
-	IMG_UINT32 ui32CPUCacheMode = ulFlags & PVRSRV_MEMALLOCFLAG_CPU_CACHE_MODE_MASK;
+	IMG_UINT32 ui32CPUCacheMode = PVRSRV_CPU_CACHE_MODE(ulFlags);
 	IMG_BOOL bRet = IMG_FALSE;
 
-	PVR_ASSERT(ui32CPUCacheMode == (ulFlags & PVRSRV_MEMALLOCFLAG_CPU_CACHE_MODE_MASK));
+	PVR_ASSERT(ui32CPUCacheMode == PVRSRV_CPU_CACHE_MODE(ulFlags));
 
-	if ((ui32CPUCacheMode == PVRSRV_MEMALLOCFLAG_CPU_CACHE_COHERENT) ||
-		(ui32CPUCacheMode == PVRSRV_MEMALLOCFLAG_CPU_CACHED_CACHE_COHERENT))
+	if (ui32CPUCacheMode == PVRSRV_MEMALLOCFLAG_CPU_CACHE_COHERENT)
 	{
-		bRet = PVRSRVSystemSnoopingOfDeviceCache();
+		bRet = PVRSRVSystemSnoopingOfDeviceCache(psDeviceNode->psDevConfig);
 	}
 	return bRet;
 }
 
-static INLINE IMG_BOOL DevmemDeviceCacheCoherency(PVRSRV_MEMALLOCFLAGS_T ulFlags)
+static INLINE IMG_BOOL DevmemDeviceCacheCoherency(PVRSRV_DEVICE_NODE *psDeviceNode,
+												  PVRSRV_MEMALLOCFLAGS_T ulFlags)
 {
-	IMG_UINT32 ui32DeviceCacheMode = ulFlags & PVRSRV_MEMALLOCFLAG_GPU_CACHE_MODE_MASK;
+	IMG_UINT32 ui32DeviceCacheMode = PVRSRV_GPU_CACHE_MODE(ulFlags);
 	IMG_BOOL bRet = IMG_FALSE;
 
-	PVR_ASSERT(ui32DeviceCacheMode == (ulFlags & PVRSRV_MEMALLOCFLAG_GPU_CACHE_MODE_MASK));
+	PVR_ASSERT(ui32DeviceCacheMode == PVRSRV_GPU_CACHE_MODE(ulFlags));
 
-	if ((ui32DeviceCacheMode == PVRSRV_MEMALLOCFLAG_GPU_CACHE_COHERENT) ||
-		(ui32DeviceCacheMode == PVRSRV_MEMALLOCFLAG_GPU_CACHED_CACHE_COHERENT))
+	if (ui32DeviceCacheMode == PVRSRV_MEMALLOCFLAG_GPU_CACHE_COHERENT)
 	{
-		bRet = PVRSRVSystemSnoopingOfCPUCache();
+		bRet = PVRSRVSystemSnoopingOfCPUCache(psDeviceNode->psDevConfig);
 	}
 	return bRet;
 }
diff --git a/drivers/staging/imgtec/rogue/devicemem_typedefs.h b/drivers/staging/imgtec/rogue/devicemem_typedefs.h
index 9e4d974..e4611b1 100644
--- a/drivers/staging/imgtec/rogue/devicemem_typedefs.h
+++ b/drivers/staging/imgtec/rogue/devicemem_typedefs.h
@@ -47,19 +47,20 @@
 #ifndef DEVICEMEM_TYPEDEFS_H
 #define DEVICEMEM_TYPEDEFS_H
 
+#include <powervr/mem_types.h>
 #include "img_types.h"
 #include "pvrsrv_memallocflags.h"
 
-typedef struct _DEVMEM_CONTEXT_ DEVMEM_CONTEXT;     /*!< Convenience typedef for struct _DEVMEM_CONTEXT_ */
-typedef struct _DEVMEM_HEAP_ DEVMEM_HEAP;           /*!< Convenience typedef for struct _DEVMEM_HEAP_ */
-typedef struct _DEVMEM_MEMDESC_ DEVMEM_MEMDESC;     /*!< Convenience typedef for struct _DEVMEM_MEMDESC_ */
+typedef struct _DEVMEM_CONTEXT_ DEVMEM_CONTEXT;		/*!< Convenience typedef for struct _DEVMEM_CONTEXT_ */
+typedef struct _DEVMEM_HEAP_ DEVMEM_HEAP;			/*!< Convenience typedef for struct _DEVMEM_HEAP_ */
+typedef struct _DEVMEM_MEMDESC_ DEVMEM_MEMDESC;		/*!< Convenience typedef for struct _DEVMEM_MEMDESC_ */
 typedef struct _DEVMEM_PAGELIST_ DEVMEM_PAGELIST;	/*!< Convenience typedef for struct _DEVMEM_PAGELIST_ */
-typedef PVRSRV_MEMALLOCFLAGS_T DEVMEM_FLAGS_T;      /*!< Conveneince typedef for PVRSRV_MEMALLOCFLAGS_T */
+typedef PVRSRV_MEMALLOCFLAGS_T DEVMEM_FLAGS_T;		/*!< Conveneince typedef for PVRSRV_MEMALLOCFLAGS_T */
 
-typedef IMG_HANDLE DEVMEM_EXPORTHANDLE;                             /*!< Typedef for DeviceMem Export Handle */
+typedef IMG_HANDLE /* FIXME: should be a SID */ DEVMEM_EXPORTHANDLE; /*!< Typedef for DeviceMem Export Handle */
 typedef IMG_UINT64 DEVMEM_EXPORTKEY;                                /*!< Typedef for DeviceMem Export Key */
 typedef IMG_DEVMEM_SIZE_T DEVMEM_SIZE_T;                            /*!< Typedef for DeviceMem SIZE_T */
-typedef IMG_DEVMEM_LOG2ALIGN_T DEVMEM_LOG2ALIGN_T;                  /*!< Typdef for DeviceMem LOG2 Alignment */
+typedef IMG_DEVMEM_LOG2ALIGN_T DEVMEM_LOG2ALIGN_T;                  /*!< Typedef for DeviceMem LOG2 Alignment */
 
 typedef struct _DEVMEMX_PHYS_MEMDESC_ DEVMEMX_PHYSDESC;    /*!< Convenience typedef for DevmemX physical */
 typedef struct _DEVMEMX_VIRT_MEMDESC_ DEVMEMX_VIRTDESC;    /*!< Convenience typedef for DevmemX virtual */
@@ -67,7 +68,9 @@
 /*! calling code needs all the info in this struct, to be able to pass it around */
 typedef struct
 {
-    /*! A handle to the PMR. */
+    /*! A handle to the PMR.  Should be a SID.  FIXME: decide whether
+       this is right... as the PMR would have to be a cross-process
+       handle */
     IMG_HANDLE hPMRExportHandle;
     /*! The "key" to prove we have authorization to use this PMR */
     IMG_UINT64 uiPMRExportPassword;
@@ -100,23 +103,31 @@
     IMG_DEVMEM_LOG2ALIGN_T uiLog2ContiguityGuarantee;
 } DEVMEM_EXPORTCOOKIE;
 
-/*enum that describes the operation associated with changing sparse memory*/
+/* Enum that describes the operation associated with changing sparse memory*/
 typedef enum Resize {
-	SPARSE_RESIZE_NONE=0,
-	SPARSE_RESIZE_ALLOC=1, /*This is should be set to indicate, the change needs allocation */
-	SPARSE_RESIZE_FREE=2, /*This is should be set to indicate, the change needs free */
-	SPARSE_RESIZE_BOTH=(SPARSE_RESIZE_ALLOC | SPARSE_RESIZE_FREE),
-	SPARSE_REMAP_MEM=4, /*  This is should be set to silently swap underlying physical memory
-	                     *  with out disturbing its device or cpu virtual maps
-	                     *  This flag is not supported in the case of PDUMP and could lead to
-	                     *  PDUMP panic when used
-	                     */
-	SPARSE_MAP_CPU_ADDR=8 /*should be set to get the sparse changes appear in cpu virtual map */
+	SPARSE_RESIZE_NONE = 0,
+
+	/* This should be set to indicate the change needs allocation */
+	SPARSE_RESIZE_ALLOC = 1,
+
+	/* This should be set to indicate the change needs free */
+	SPARSE_RESIZE_FREE = 2,
+
+	SPARSE_RESIZE_BOTH = (SPARSE_RESIZE_ALLOC | SPARSE_RESIZE_FREE),
+
+	/* This should be set to silently swap underlying physical memory
+	 * without disturbing its device or cpu virtual maps
+	 * This flag is not supported in the case of PDUMP and could lead to
+	 * PDUMP panic when used */
+	SPARSE_REMAP_MEM = 4,
+
+	/* Should be set to get the sparse changes appear in cpu virtual map */
+	SPARSE_MAP_CPU_ADDR = 8
 }SPARSE_MEM_RESIZE_FLAGS;
 
 /* To use with DevmemSubAllocate() as the default factor if no
  * over-allocation is desired. */
 #define DEVMEM_NO_PRE_ALLOCATE_MULTIPLIER 1
 
-#endif /* #ifndef SRVCLIENT_NEW_DEVMEM_ALLOCATION_TYPEDEFS_H */
+#endif /* #ifndef DEVICEMEM_TYPEDEFS_H */
 
diff --git a/drivers/staging/imgtec/rogue/devicemem_utils.c b/drivers/staging/imgtec/rogue/devicemem_utils.c
index 285caed..8cb94fa 100644
--- a/drivers/staging/imgtec/rogue/devicemem_utils.c
+++ b/drivers/staging/imgtec/rogue/devicemem_utils.c
@@ -50,6 +50,267 @@
 #include "client_mm_bridge.h"
 
 /*
+	SVM heap management support functions for CPU (un)mapping
+*/
+#define DEVMEM_MAP_SVM_USER_MANAGED_RETRY				2
+
+static inline PVRSRV_ERROR 
+_DevmemCPUMapSVMKernelManaged(DEVMEM_HEAP *psHeap,
+							  DEVMEM_IMPORT *psImport,
+							  IMG_UINT64 *ui64MapAddress)
+{
+	PVRSRV_ERROR eError;
+	IMG_UINT64 ui64SvmMapAddr;
+	IMG_UINT64 ui64SvmMapAddrEnd;
+	IMG_UINT64 ui64SvmHeapAddrEnd;
+
+	/* SVM heap management is always XXX_KERNEL_MANAGED unless we
+	   have triggered the fall back code-path in which case we
+	   should not be calling into this code-path */
+	PVR_ASSERT(psHeap->eHeapType == DEVMEM_HEAP_TYPE_KERNEL_MANAGED);
+
+	/* By acquiring the CPU virtual address here, it essentially
+	   means we lock-down the virtual address for the duration
+	   of the life-cycle of the allocation until a de-allocation
+	   request comes in. Thus the allocation is guaranteed not to
+	   change its virtual address on the CPU during its life-time. 
+	   NOTE: Import might have already been CPU Mapped before now,
+	   normally this is not a problem, see fall back */
+	eError = _DevmemImportStructCPUMap(psImport);
+	if (eError != PVRSRV_OK)
+	{
+		PVR_DPF((PVR_DBG_ERROR,
+				"%s: Unable to CPU map (lock-down) device memory for SVM use",
+				__func__));
+		eError = PVRSRV_ERROR_DEVICEMEM_MAP_FAILED;
+		goto failSVM;
+	}
+
+	/* Supplied kernel mmap virtual address is also device virtual address;
+	   calculate the heap & kernel supplied mmap virtual address limits */
+	ui64SvmMapAddr = (IMG_UINT64)(uintptr_t)psImport->sCPUImport.pvCPUVAddr;
+	ui64SvmHeapAddrEnd = psHeap->sBaseAddress.uiAddr + psHeap->uiSize;
+	ui64SvmMapAddrEnd = ui64SvmMapAddr + psImport->uiSize;
+	PVR_ASSERT(ui64SvmMapAddr != (IMG_UINT64)0);
+
+	/* SVM limit test may fail if processor has more virtual address bits than device */
+	if (ui64SvmMapAddr >= ui64SvmHeapAddrEnd || ui64SvmMapAddrEnd > ui64SvmHeapAddrEnd)
+	{
+		/* Unmap incompatible SVM virtual address, this
+		   may not release address if it was elsewhere
+		   CPU Mapped before call into this function */
+		_DevmemImportStructCPUUnmap(psImport);
+
+		/* Flag incompatible SVM mapping */
+		eError = PVRSRV_ERROR_BAD_MAPPING;
+		goto failSVM;
+	}
+
+	*ui64MapAddress = ui64SvmMapAddr;
+failSVM:
+	/* either OK, MAP_FAILED or BAD_MAPPING */
+	return eError;
+}
+
+static inline void 
+_DevmemCPUUnmapSVMKernelManaged(DEVMEM_HEAP *psHeap, DEVMEM_IMPORT *psImport)
+{
+	PVR_UNREFERENCED_PARAMETER(psHeap);
+	_DevmemImportStructCPUUnmap(psImport);
+}
+
+static inline PVRSRV_ERROR 
+_DevmemCPUMapSVMUserManaged(DEVMEM_HEAP *psHeap,
+							DEVMEM_IMPORT *psImport,
+							IMG_UINT uiAlign,
+							IMG_UINT64 *ui64MapAddress)
+{
+	RA_LENGTH_T uiAllocatedSize;
+	RA_BASE_T uiAllocatedAddr;
+	IMG_UINT64 ui64SvmMapAddr;
+	IMG_UINT uiRetry = 0;
+	PVRSRV_ERROR eError;
+
+	/* If SVM heap management has transitioned to XXX_USER_MANAGED,
+	   this is essentially a fall back approach that ensures we
+	   continue to satisfy SVM alloc. This approach is not without
+	   hazards in that we may specify a virtual address that is
+	   already in use by the user process */
+	PVR_ASSERT(psHeap->eHeapType == DEVMEM_HEAP_TYPE_USER_MANAGED);
+
+	/* Normally, for SVM heap allocations, CPUMap _must_  be done
+	   before DevMap; ideally the initial CPUMap should be done by
+	   SVM functions though this is not a hard requirement as long
+	   as the prior elsewhere obtained CPUMap virtual address meets
+	   SVM address requirements. This is a fall-back code-pathway
+	   so we have to test that this assumption holds before we 
+	   progress any further */
+	OSLockAcquire(psImport->sCPUImport.hLock);
+
+	if (psImport->sCPUImport.ui32RefCount)
+	{
+		/* Already CPU Mapped SVM heap allocation, this prior elsewhere
+		   obtained virtual address is  responsible for the above 
+		   XXX_KERNEL_MANAGED failure. As we are not responsible for 
+		   this, we cannot progress any further so need to fail */
+		PVR_DPF((PVR_DBG_ERROR,
+				"%s: Previously obtained CPU map address not SVM compatible"
+				, __func__));
+
+		/* Revert SVM heap to DEVMEM_HEAP_TYPE_KERNEL_MANAGED */
+		psHeap->eHeapType = DEVMEM_HEAP_TYPE_KERNEL_MANAGED;
+		PVR_DPF((PVR_DBG_MESSAGE,
+				"%s: Reverting SVM heap back to kernel managed",
+				__func__));
+
+		OSLockRelease(psImport->sCPUImport.hLock);
+
+		/* Do we need a more specific error code here */
+		eError = PVRSRV_ERROR_DEVICEMEM_ALREADY_MAPPED;
+		goto failSVM;
+	}
+
+	OSLockRelease(psImport->sCPUImport.hLock);
+
+	do
+	{
+		/* Next we proceed to instruct the kernel to use the RA_Alloc supplied
+		   virtual address to map-in this SVM import suballocation; there is no
+		   guarantee that this RA_Alloc virtual address may not collide with an
+		   already in-use VMA range in the process */
+		eError = RA_Alloc(psHeap->psQuantizedVMRA,
+						psImport->uiSize,
+						RA_NO_IMPORT_MULTIPLIER,
+						0, /* flags: this RA doesn't use flags*/
+						uiAlign,
+						"SVM_Virtual_Alloc",
+						&uiAllocatedAddr,
+						&uiAllocatedSize,
+						NULL /* don't care about per-import priv data */);
+		if (eError != PVRSRV_OK)
+		{
+			PVR_DPF((PVR_DBG_ERROR,
+					"%s: Cannot RA allocate SVM compatible address",
+					__func__));
+			goto failSVM;
+		}
+
+		/* No reason for allocated virtual size to be different from
+		   the PMR's size */
+		psImport->sCPUImport.pvCPUVAddr = (void*)(uintptr_t)uiAllocatedAddr;
+		PVR_ASSERT(uiAllocatedSize == psImport->uiSize);
+			
+		/* Map the import or allocation using the RA_Alloc virtual address;
+		   the kernel may fail the request if the supplied virtual address
+		   is already in-use in which case we re-try using another virtual
+		   address obtained from the RA_Alloc */
+		eError = _DevmemImportStructCPUMap(psImport);
+		if (eError != PVRSRV_OK)
+		{
+			/* For now we simply discard failed RA_Alloc() obtained virtual 
+			   address (i.e. plenty of virtual space), this prevents us from
+			   re-using these and furthermore essentially blacklists these
+			   addresses from future SVM consideration; We exit fall-back
+			   attempt if retry exceeds the fall-back retry limit */
+			if (uiRetry++ > DEVMEM_MAP_SVM_USER_MANAGED_RETRY)
+			{
+				PVR_DPF((PVR_DBG_ERROR,
+						"%s: Cannot find SVM compatible address, bad mapping",
+						__func__));
+				eError = PVRSRV_ERROR_BAD_MAPPING;
+				goto failSVM;
+			}
+		}
+		else
+		{
+			/* Found compatible SVM virtual address, set as device virtual address */
+			ui64SvmMapAddr = (IMG_UINT64)(uintptr_t)psImport->sCPUImport.pvCPUVAddr;
+		}
+	} while (eError != PVRSRV_OK);
+
+	*ui64MapAddress = ui64SvmMapAddr;
+failSVM:	
+	return eError;
+}
+
+static inline void 
+_DevmemCPUUnmapSVMUserManaged(DEVMEM_HEAP *psHeap, DEVMEM_IMPORT *psImport)
+{
+	RA_BASE_T uiAllocatedAddr;
+
+	/* We only free SVM compatible addresses, all addresses in
+	   the blacklist are essentially excluded from future RA_Alloc */
+	uiAllocatedAddr = psImport->sDeviceImport.sDevVAddr.uiAddr;
+	RA_Free(psHeap->psQuantizedVMRA, uiAllocatedAddr);
+
+	_DevmemImportStructCPUUnmap(psImport);
+}
+
+static inline PVRSRV_ERROR 
+_DevmemImportStructDevMapSVM(DEVMEM_HEAP *psHeap,
+							 DEVMEM_IMPORT *psImport,
+							 IMG_UINT uiAlign,
+							 IMG_UINT64 *ui64MapAddress)
+{
+	PVRSRV_ERROR eError;
+
+	switch(psHeap->eHeapType)
+	{
+		case DEVMEM_HEAP_TYPE_KERNEL_MANAGED:
+			eError = _DevmemCPUMapSVMKernelManaged(psHeap,
+												   psImport,
+												   ui64MapAddress);
+			if (eError == PVRSRV_ERROR_BAD_MAPPING)
+			{
+				/* If the SVM map address is outside of SVM heap limits,
+				   change heap type to DEVMEM_HEAP_TYPE_USER_MANAGED */
+				psHeap->eHeapType = DEVMEM_HEAP_TYPE_USER_MANAGED;
+				PVR_DPF((PVR_DBG_MESSAGE,
+					"%s: Kernel managed SVM heap is now user managed",
+					__func__));
+
+				/* Retry using user managed fall-back approach */
+				eError = _DevmemCPUMapSVMUserManaged(psHeap,
+													 psImport,
+													 uiAlign,
+													 ui64MapAddress);
+			}
+			break;
+
+		case DEVMEM_HEAP_TYPE_USER_MANAGED:
+			eError = _DevmemCPUMapSVMUserManaged(psHeap,
+												 psImport,
+												 uiAlign,
+												 ui64MapAddress);
+			break;
+
+		default:
+			eError = PVRSRV_ERROR_INVALID_PARAMS;
+			break;
+	}
+
+	return eError;
+}
+
+static inline void 
+_DevmemImportStructDevUnmapSVM(DEVMEM_HEAP *psHeap, DEVMEM_IMPORT *psImport)
+{
+	switch(psHeap->eHeapType)
+	{
+		case DEVMEM_HEAP_TYPE_KERNEL_MANAGED:
+			_DevmemCPUUnmapSVMKernelManaged(psHeap, psImport);
+			break;
+
+		case DEVMEM_HEAP_TYPE_USER_MANAGED:
+			_DevmemCPUUnmapSVMUserManaged(psHeap, psImport);
+			break;
+
+		default:
+			break;
+	}
+}
+
+/*
 	The Devmem import structure is the structure we use
 	to manage memory that is "imported" (which is page
 	granular) from the server into our process, this
@@ -94,6 +355,9 @@
 		OSLockDestroy(psImport->sCPUImport.hLock);
 		OSLockDestroy(psImport->sDeviceImport.hLock);
 		OSLockDestroy(psImport->hLock);
+#if defined(PDUMP)
+		OSFreeMem(psImport->pszAnnotation);
+#endif
 		OSFreeMem(psImport);
 	}
 }
@@ -180,6 +444,11 @@
 	psMemDesc->sDeviceMemDesc.ui32RefCount = 0;
 	psMemDesc->sCPUMemDesc.ui32RefCount = 0;
 	psMemDesc->uiAllocSize = uiSize;
+	psMemDesc->hPrivData = NULL;
+
+#if defined(SUPPORT_PAGE_FAULT_DEBUG)
+	psMemDesc->sTraceData.ui32AllocationIndex = DEVICEMEM_HISTORY_ALLOC_INDEX_NONE;
+#endif
 
 	OSAtomicWrite(&psMemDesc->hRefCount, 1);
 }
@@ -187,8 +456,7 @@
 IMG_INTERNAL
 void _DevmemMemDescAcquire(DEVMEM_MEMDESC *psMemDesc)
 {
-	IMG_INT iRefCount;
-	PVR_UNREFERENCED_PARAMETER(iRefCount);
+	IMG_INT iRefCount = 0;
 
 	iRefCount = OSAtomicIncrement(&psMemDesc->hRefCount);
 	DEVMEM_REFCOUNT_PRINT("%s (%p) %d->%d",
@@ -215,21 +483,23 @@
 
 	if (iRefCount == 0)
 	{
-		if (psMemDesc->psImport->uiProperties & DEVMEM_PROPERTIES_EXPORTABLE)
-		{
-			_DevmemImportStructRelease(psMemDesc->psImport);
-		}
-		else
+		if (psMemDesc->psImport->uiProperties & DEVMEM_PROPERTIES_SUBALLOCATABLE)
 		{
 			/* As soon as the first sub-allocation on the psImport is freed
 			 * we might get dirty memory when reusing it.
-			 * We have to delete the CLEAN flag */
+			 * We have to delete the ZEROED & CLEAN flag */
+
+			psMemDesc->psImport->uiProperties &= ~DEVMEM_PROPERTIES_IMPORT_IS_ZEROED;
 			psMemDesc->psImport->uiProperties &= ~DEVMEM_PROPERTIES_IMPORT_IS_CLEAN;
 
 			RA_Free(psMemDesc->psImport->sDeviceImport.psHeap->psSubAllocRA,
 					psMemDesc->psImport->sDeviceImport.sDevVAddr.uiAddr +
 					psMemDesc->uiOffset);
 		}
+		else
+		{
+			_DevmemImportStructRelease(psMemDesc->psImport);
+		}
 
 		OSLockDestroy(psMemDesc->sCPUMemDesc.hLock);
 		OSLockDestroy(psMemDesc->sDeviceMemDesc.hLock);
@@ -252,35 +522,42 @@
 
 IMG_INTERNAL
 PVRSRV_ERROR _DevmemValidateParams(IMG_DEVMEM_SIZE_T uiSize,
-								   IMG_DEVMEM_ALIGN_T uiAlign,
-								   DEVMEM_FLAGS_T uiFlags)
+                                   IMG_DEVMEM_ALIGN_T uiAlign,
+                                   DEVMEM_FLAGS_T *puiFlags)
 {
-    if ((uiFlags & PVRSRV_MEMALLOCFLAG_ZERO_ON_ALLOC) &&
-        (uiFlags & PVRSRV_MEMALLOCFLAG_POISON_ON_ALLOC))
-    {
+	if ((*puiFlags & PVRSRV_MEMALLOCFLAG_ZERO_ON_ALLOC) &&
+	    (*puiFlags & PVRSRV_MEMALLOCFLAG_POISON_ON_ALLOC))
+	{
 		PVR_DPF((PVR_DBG_ERROR,
 		         "%s: Zero on Alloc and Poison on Alloc are mutually exclusive.",
 		         __FUNCTION__));
-        return PVRSRV_ERROR_INVALID_PARAMS;
-    }
+		return PVRSRV_ERROR_INVALID_PARAMS;
+	}
 
-    if (uiAlign & (uiAlign-1))
-    {
+	if (uiAlign & (uiAlign-1))
+	{
 		PVR_DPF((PVR_DBG_ERROR,
 		         "%s: The requested alignment is not a power of two.",
 		         __FUNCTION__));
-        return PVRSRV_ERROR_INVALID_PARAMS;
-    }
+		return PVRSRV_ERROR_INVALID_PARAMS;
+ 	}
 
-    if (uiSize == 0)
-    {
+	if (uiSize == 0)
+	{
 		PVR_DPF((PVR_DBG_ERROR,
 		         "%s: Please request a non-zero size value.",
 		         __FUNCTION__));
-        return PVRSRV_ERROR_INVALID_PARAMS;
-    }
+		return PVRSRV_ERROR_INVALID_PARAMS;
+	}
 
-    return PVRSRV_OK;
+	/* If zero flag is set we have to have write access to the page. */
+	if (PVRSRV_CHECK_ZERO_ON_ALLOC(*puiFlags) || PVRSRV_CHECK_CPU_WRITEABLE(*puiFlags))
+	{
+		(*puiFlags) |= PVRSRV_MEMALLOCFLAG_CPU_WRITEABLE |
+		             PVRSRV_MEMALLOCFLAG_CPU_READABLE;
+	}
+
+	return PVRSRV_OK;
 }
 
 /*
@@ -299,6 +576,11 @@
         return PVRSRV_ERROR_OUT_OF_MEMORY;
     }
 
+#if defined (PDUMP)
+	/* Make sure this points nowhere as long as we don't need it */
+	psImport->pszAnnotation = NULL;
+#endif
+
 	/* Setup some known bad values for things we don't have yet */
 	psImport->sDeviceImport.hReservation = LACK_OF_RESERVATION_POISON;
     psImport->sDeviceImport.hMapping = LACK_OF_MAPPING_POISON;
@@ -383,17 +665,16 @@
 */
 IMG_INTERNAL
 PVRSRV_ERROR _DevmemImportStructDevMap(DEVMEM_HEAP *psHeap,
-									   IMG_BOOL bMap,
-									   DEVMEM_IMPORT *psImport,
-									   IMG_UINT64 uiOptionalMapAddress)
+                                       IMG_BOOL bMap,
+                                       DEVMEM_IMPORT *psImport,
+                                       IMG_UINT64 ui64OptionalMapAddress)
 {
 	DEVMEM_DEVICE_IMPORT *psDeviceImport;
-	IMG_BOOL bStatus;
-    RA_BASE_T uiAllocatedAddr;
-    RA_LENGTH_T uiAllocatedSize;
-    IMG_DEV_VIRTADDR sBase;
-    IMG_HANDLE hReservation;
-    PVRSRV_ERROR eError;
+	RA_BASE_T uiAllocatedAddr;
+	RA_LENGTH_T uiAllocatedSize;
+	IMG_DEV_VIRTADDR sBase;
+	IMG_HANDLE hReservation;
+	PVRSRV_ERROR eError;
 	IMG_UINT uiAlign;
 
 	/* Round the provided import alignment to the configured heap alignment */
@@ -415,30 +696,50 @@
 
 		OSAtomicIncrement(&psHeap->hImportCount);
 
-		if (uiOptionalMapAddress == 0)
+		if (PVRSRV_CHECK_SVM_ALLOC(psImport->uiFlags))
 		{
-			if (psHeap->eHeapType == DEVMEM_HEAP_TYPE_USER_MANAGED)
+			/*  SVM (shared virtual memory) imports or allocations always
+				need to acquire CPU virtual address first as address is
+				used to map the allocation into the device virtual address
+				space; i.e. the virtual address of the allocation for both
+				the CPU/GPU must be identical. */
+			eError = _DevmemImportStructDevMapSVM(psHeap,
+												  psImport,
+												  uiAlign,
+												  &ui64OptionalMapAddress);
+			if (eError != PVRSRV_OK)
+			{
+				goto failVMRAAlloc;
+			}
+		}
+
+		if (ui64OptionalMapAddress == 0)
+		{
+			if (psHeap->eHeapType == DEVMEM_HEAP_TYPE_USER_MANAGED ||
+				psHeap->eHeapType == DEVMEM_HEAP_TYPE_KERNEL_MANAGED)
 			{
 				PVR_DPF((PVR_DBG_ERROR,
-						"%s: This heap is managed by the user application itself, "
-						"please continue to use PVRSRVMapToDeviceAddress()."
-						, __func__));
+						psHeap->eHeapType == DEVMEM_HEAP_TYPE_USER_MANAGED ?
+						"%s: Heap is user managed, please use PVRSRVMapToDeviceAddress().":
+						"%s: Heap is kernel managed, use right allocation flags (e.g. SVM).",
+						__func__));
 				eError = PVRSRV_ERROR_INVALID_PARAMS;
 				goto failVMRAAlloc;
 			}
 			psHeap->eHeapType = DEVMEM_HEAP_TYPE_RA_MANAGED;
 
 			/* Allocate space in the VM */
-			bStatus = RA_Alloc(psHeap->psQuantizedVMRA,
-							   psImport->uiSize,
-							   RA_NO_IMPORT_MULTIPLIER,
-							   0, /* flags: this RA doesn't use flags*/
-							   uiAlign,
-							   &uiAllocatedAddr,
-							   &uiAllocatedSize,
-							   NULL /* don't care about per-import priv data */
-							   );
-			if (!bStatus)
+			eError = RA_Alloc(psHeap->psQuantizedVMRA,
+			                  psImport->uiSize,
+			                  RA_NO_IMPORT_MULTIPLIER,
+			                  0, /* flags: this RA doesn't use flags*/
+			                  uiAlign,
+			                  "Virtual_Alloc",
+			                  &uiAllocatedAddr,
+			                  &uiAllocatedSize,
+			                  NULL /* don't care about per-import priv data */
+			                  );
+			if (PVRSRV_OK != eError)
 			{
 				eError = PVRSRV_ERROR_DEVICEMEM_OUT_OF_DEVICE_VM;
 				goto failVMRAAlloc;
@@ -453,18 +754,60 @@
 		}
 		else
 		{
-			if (psHeap->eHeapType == DEVMEM_HEAP_TYPE_RA_MANAGED)
+			IMG_UINT64 uiHeapAddrEnd;
+
+			switch (psHeap->eHeapType)
+			{
+				case DEVMEM_HEAP_TYPE_UNKNOWN:
+					/* DEVMEM_HEAP_TYPE_USER_MANAGED can apply to _any_
+					   heap and can only be determined here. This heap
+					   type transitions from DEVMEM_HEAP_TYPE_UNKNOWN
+					   to DEVMEM_HEAP_TYPE_USER_MANAGED on 1st alloc */
+					psHeap->eHeapType = DEVMEM_HEAP_TYPE_USER_MANAGED;
+					break;
+
+				case DEVMEM_HEAP_TYPE_USER_MANAGED:
+				case DEVMEM_HEAP_TYPE_KERNEL_MANAGED:
+					if (! psHeap->uiSize)
+					{
+						PVR_DPF((PVR_DBG_ERROR,
+							psHeap->eHeapType == DEVMEM_HEAP_TYPE_USER_MANAGED ?
+							"%s: Heap DEVMEM_HEAP_TYPE_USER_MANAGED is disabled.":
+							"%s: Heap DEVMEM_HEAP_TYPE_KERNEL_MANAGED is disabled."
+							, __func__));
+						eError = PVRSRV_ERROR_INVALID_HEAP;
+						goto failVMRAAlloc;
+					}
+					break;
+
+				case DEVMEM_HEAP_TYPE_RA_MANAGED:
+					PVR_DPF((PVR_DBG_ERROR,
+						"%s: This heap is managed by an RA, please use PVRSRVMapToDevice()"
+						" and don't use allocation flags that assume differently (e.g. SVM)."
+						, __func__));
+					eError = PVRSRV_ERROR_INVALID_PARAMS;
+					goto failVMRAAlloc;
+
+				default:
+					break;
+			}
+
+			/* Ensure supplied ui64OptionalMapAddress is within heap range */
+			uiHeapAddrEnd = psHeap->sBaseAddress.uiAddr + psHeap->uiSize;
+			if (ui64OptionalMapAddress >= uiHeapAddrEnd ||
+				ui64OptionalMapAddress + psImport->uiSize > uiHeapAddrEnd)
 			{
 				PVR_DPF((PVR_DBG_ERROR,
-						"%s: This heap is managed by an RA, please use PVRSRVMapToDevice()."
-						, __func__));
+						"%s: ui64OptionalMapAddress %p is outside of heap limits <%p:%p>."
+						, __func__
+						, (void*)(uintptr_t)ui64OptionalMapAddress
+						, (void*)(uintptr_t)psHeap->sBaseAddress.uiAddr
+						, (void*)(uintptr_t)uiHeapAddrEnd));
 				eError = PVRSRV_ERROR_INVALID_PARAMS;
 				goto failVMRAAlloc;
 			}
-			psHeap->eHeapType = DEVMEM_HEAP_TYPE_USER_MANAGED;
 
-
-			if (uiOptionalMapAddress & ((1 << psHeap->uiLog2Quantum) - 1))
+			if (ui64OptionalMapAddress & ((1 << psHeap->uiLog2Quantum) - 1))
 			{
 				PVR_DPF((PVR_DBG_ERROR,
 						"%s: Invalid address to map to. Please prove an address aligned to"
@@ -473,7 +816,8 @@
 				eError = PVRSRV_ERROR_INVALID_PARAMS;
 				goto failVMRAAlloc;
 			}
-			uiAllocatedAddr = uiOptionalMapAddress;
+
+			uiAllocatedAddr = ui64OptionalMapAddress;
 
 			if (psImport->uiSize & ((1 << psHeap->uiLog2Quantum) - 1))
 			{
@@ -489,15 +833,15 @@
 		}
 	
 		/* Setup page tables for the allocated VM space */
-	    eError = BridgeDevmemIntReserveRange(psHeap->psCtx->hDevConnection,
+		eError = BridgeDevmemIntReserveRange(psHeap->psCtx->hDevConnection,
 											 psHeap->hDevMemServerHeap,
 											 sBase,
 											 uiAllocatedSize,
 											 &hReservation);
-	    if (eError != PVRSRV_OK)
-	    {
-	        goto failReserve;
-	    }
+		if (eError != PVRSRV_OK)
+		{
+			goto failReserve;
+		}
 
 		if (bMap)
 		{
@@ -544,7 +888,7 @@
 	BridgeDevmemIntUnreserveRange(psHeap->psCtx->hDevConnection,
 								  hReservation);
 failReserve:
-	if (uiOptionalMapAddress == 0)
+	if (ui64OptionalMapAddress == 0)
 	{
 		RA_Free(psHeap->psQuantizedVMRA,
 				uiAllocatedAddr);
@@ -596,8 +940,16 @@
 	    psDeviceImport->hMapping = LACK_OF_MAPPING_POISON;
 	    psDeviceImport->hReservation = LACK_OF_RESERVATION_POISON;
 
-	    RA_Free(psHeap->psQuantizedVMRA,
-	            psDeviceImport->sDevVAddr.uiAddr);
+		if (psHeap->eHeapType == DEVMEM_HEAP_TYPE_RA_MANAGED)
+		{
+			RA_Free(psHeap->psQuantizedVMRA,
+					psDeviceImport->sDevVAddr.uiAddr);
+		}
+
+		if (PVRSRV_CHECK_SVM_ALLOC(psImport->uiFlags))
+		{
+			_DevmemImportStructDevUnmapSVM(psHeap, psImport);
+		}
 
 	    OSLockRelease(psDeviceImport->hLock);
 
@@ -680,15 +1032,19 @@
 
 	if (--psCPUImport->ui32RefCount == 0)
 	{
+		/* FIXME: psImport->uiSize is a 64-bit quantity where as the 5th
+		 * argument to OSUnmapPMR is a 32-bit quantity on 32-bit systems
+		 * hence a compiler warning of implicit cast and loss of data.
+		 * Added explicit cast and assert to remove warning.
+		 */
 #if (defined(_WIN32) && !defined(_WIN64)) || (defined(LINUX) && defined(__i386__))
 		PVR_ASSERT(psImport->uiSize<IMG_UINT32_MAX);
 #endif
-
 		OSMUnmapPMR(psImport->hDevConnection,
-		            psImport->hPMR,
-		            psCPUImport->hOSMMapData,
-		            psCPUImport->pvCPUVAddr,
-		            (size_t)psImport->uiSize);
+					psImport->hPMR,
+					psCPUImport->hOSMMapData,
+					psCPUImport->pvCPUVAddr,
+					psImport->uiSize);
 
 		OSLockRelease(psCPUImport->hLock);
 
diff --git a/drivers/staging/imgtec/rogue/devicemem_utils.h b/drivers/staging/imgtec/rogue/devicemem_utils.h
index fa10867..884ab49 100644
--- a/drivers/staging/imgtec/rogue/devicemem_utils.h
+++ b/drivers/staging/imgtec/rogue/devicemem_utils.h
@@ -53,7 +53,7 @@
 #include "ra.h"
 #include "osfunc.h"
 #include "lock.h"
-#include "devicemem_mmap.h"
+#include "osmmap.h"
 #include "devicemem_utils.h"
 #if defined(SUPPORT_PAGE_FAULT_DEBUG)
 #include "mm_common.h"
@@ -106,8 +106,8 @@
     /* The cache line size for use when allocating memory, as it is not queryable on the client side */
     IMG_UINT32 ui32CPUCacheLineSize;
 
-    /* Private data handle for device specific data */
-    IMG_HANDLE hPrivData;
+	/* Private data handle for device specific data */
+	IMG_HANDLE hPrivData;
 };
 
 
@@ -115,55 +115,62 @@
 {
 	DEVMEM_HEAP_TYPE_UNKNOWN = 0,
 	DEVMEM_HEAP_TYPE_USER_MANAGED,
-	DEVMEM_HEAP_TYPE_RA_MANAGED
+	DEVMEM_HEAP_TYPE_KERNEL_MANAGED,
+	DEVMEM_HEAP_TYPE_RA_MANAGED,
 }DEVMEM_HEAP_TYPE;
 
 struct _DEVMEM_HEAP_ {
-    /* Name of heap - for debug and lookup purposes. */
-    IMG_CHAR *pszName;
+	/* Name of heap - for debug and lookup purposes. */
+	IMG_CHAR *pszName;
 
-    /* Number of live imports in the heap */
-    ATOMIC_T hImportCount;
+	/* Number of live imports in the heap */
+	ATOMIC_T hImportCount;
 
-    /*
-     * Base address of heap, required by clients due to some requesters
-     * not being full range 
-     */
-    IMG_DEV_VIRTADDR sBaseAddress;
+	/*
+	* Base address and size of heap, required by clients due to some requesters
+	* not being full range
+	*/
+	IMG_DEV_VIRTADDR sBaseAddress;
+	DEVMEM_SIZE_T uiSize;
 
-    /* The heap type, describing if the space is managed by the user or an RA*/
-    DEVMEM_HEAP_TYPE eHeapType;
+	/* The heap type, describing if the space is managed by the user or an RA*/
+	DEVMEM_HEAP_TYPE eHeapType;
 
-    /* This RA is for managing sub-allocations in virtual space.  Two
-       more RA's will be used under the Hood for managing the coarser
-       allocation of virtual space from the heap, and also for
-       managing the physical backing storage. */
-    RA_ARENA *psSubAllocRA;
-    IMG_CHAR *pszSubAllocRAName;
-    /*
-      This RA is for the coarse allocation of virtual space from the heap
-    */
-    RA_ARENA *psQuantizedVMRA;
-    IMG_CHAR *pszQuantizedVMRAName;
+	/* This RA is for managing sub-allocations in virtual space.  Two
+	more RA's will be used under the Hood for managing the coarser
+	allocation of virtual space from the heap, and also for
+	managing the physical backing storage. */
+	RA_ARENA *psSubAllocRA;
+	IMG_CHAR *pszSubAllocRAName;
+	/*
+	This RA is for the coarse allocation of virtual space from the heap
+	*/
+	RA_ARENA *psQuantizedVMRA;
+	IMG_CHAR *pszQuantizedVMRAName;
 
-    /* We also need to store a copy of the quantum size in order to
-       feed this down to the server */
-    IMG_UINT32 uiLog2Quantum;
+	/* We also need to store a copy of the quantum size in order to
+	feed this down to the server */
+	IMG_UINT32 uiLog2Quantum;
 
-    /* Store a copy of the minimum import alignment */
-    IMG_UINT32 uiLog2ImportAlignment;
+	/* Store a copy of the minimum import alignment */
+	IMG_UINT32 uiLog2ImportAlignment;
 
-    /* The parent memory context for this heap */
-    struct _DEVMEM_CONTEXT_ *psCtx;
+	/* The relationship between tiled heap alignment and heap byte-stride
+	 * (dependent on tiling mode, abstracted here) */
+	IMG_UINT32 uiLog2TilingStrideFactor;
 
-	POS_LOCK hLock;							/*!< Lock to protect this structure */
+	/* The parent memory context for this heap */
+	struct _DEVMEM_CONTEXT_ *psCtx;
 
-    /*
-      Each "DEVMEM_HEAP" has a counterpart in the server,
-      which is responsible for handling the mapping into device MMU.
-      We have a handle to that here.
-    */
-    IMG_HANDLE hDevMemServerHeap;
+	/* Lock to protect this structure */
+	POS_LOCK hLock;
+
+	/*
+	Each "DEVMEM_HEAP" has a counterpart in the server,
+	which is responsible for handling the mapping into device MMU.
+	We have a handle to that here.
+	*/
+	IMG_HANDLE hDevMemServerHeap;
 };
 
 typedef IMG_UINT32 DEVMEM_PROPERTIES_T;                 /*!< Typedef for Devicemem properties */
@@ -171,7 +178,10 @@
 #define DEVMEM_PROPERTIES_IMPORTED          (1UL<<1)    /*!< Is it imported from another process? */
 #define DEVMEM_PROPERTIES_SUBALLOCATABLE    (1UL<<2)    /*!< Is it suballocatable? */
 #define DEVMEM_PROPERTIES_UNPINNED          (1UL<<3)    /*!< Is it currently pinned? */
-#define DEVMEM_PROPERTIES_IMPORT_IS_CLEAN   (1UL<<4)    /*!< Is the import clean, e.g. properly zeroed and cache clean? */
+#define DEVMEM_PROPERTIES_IMPORT_IS_ZEROED  (1UL<<4)	/*!< Is the memory fully zeroed? */
+#define DEVMEM_PROPERTIES_IMPORT_IS_CLEAN   (1UL<<5)	/*!< Is the memory clean, i.e. not been used before? */
+#define DEVMEM_PROPERTIES_SECURE            (1UL<<6)    /*!< Is it a special secure buffer? No CPU maps allowed! */
+
 
 typedef struct _DEVMEM_DEVICE_IMPORT_ {
 	DEVMEM_HEAP *psHeap;			/*!< Heap this import is bound to */
@@ -203,6 +213,9 @@
 
 	DEVMEM_DEVICE_IMPORT sDeviceImport;	/*!< Device specifics of the import */
 	DEVMEM_CPU_IMPORT sCPUImport;		/*!< CPU specifics of the import */
+#if defined(PDUMP)
+	IMG_CHAR *pszAnnotation;
+#endif
 } DEVMEM_IMPORT;
 
 typedef struct _DEVMEM_DEVICE_MEMDESC_ {
@@ -223,6 +236,7 @@
 	IMG_DEVMEM_SIZE_T uiAllocSize;          /*!< Size of the allocation */
     ATOMIC_T hRefCount;						/*!< Refcount of the memdesc */
     POS_LOCK hLock;							/*!< Lock to protect memdesc */
+    IMG_HANDLE hPrivData;
 
 	DEVMEM_DEVICE_MEMDESC sDeviceMemDesc;	/*!< Device specifics of the memdesc */
 	DEVMEM_CPU_MEMDESC sCPUMemDesc;		/*!< CPU specifics of the memdesc */
@@ -272,12 +286,12 @@
 
 @Input          uiSize      Size of the import.
 @Input          uiAlign     Alignment of the import.
-@Input          uiFlags     Flags for the import.
+@Input          puiFlags    Pointer to the flags for the import.
 @return         PVRSRV_ERROR
 ******************************************************************************/
 PVRSRV_ERROR _DevmemValidateParams(IMG_DEVMEM_SIZE_T uiSize,
-								   IMG_DEVMEM_ALIGN_T uiAlign,
-								   DEVMEM_FLAGS_T uiFlags);
+                                   IMG_DEVMEM_ALIGN_T uiAlign,
+                                   DEVMEM_FLAGS_T *puiFlags);
 
 /******************************************************************************
 @Function       _DevmemImportStructAlloc
diff --git a/drivers/staging/imgtec/rogue/devicememx.h b/drivers/staging/imgtec/rogue/devicememx.h
index b25f5bf..75d58a6 100644
--- a/drivers/staging/imgtec/rogue/devicememx.h
+++ b/drivers/staging/imgtec/rogue/devicememx.h
@@ -62,7 +62,7 @@
                     IMG_UINT32 uiNumPages,
                     IMG_UINT32 uiLog2PageSize,
                     DEVMEM_FLAGS_T uiFlags,
-                    const IMG_PCHAR pszText,
+                    const IMG_CHAR *pszText,
                     DEVMEMX_PHYSDESC **ppsPhysDesc);
 
 /* DevmemXReleasePhysical()
@@ -82,7 +82,7 @@
 DevmemXAllocVirtual(DEVMEM_HEAP* hHeap,
                    IMG_UINT32 uiNumPages,
                    DEVMEM_FLAGS_T uiFlags,
-                   const IMG_PCHAR pszText,
+                   const IMG_CHAR *pszText,
                    DEVMEMX_VIRTDESC **ppsVirtDesc,
                    IMG_DEV_VIRTADDR *psVirtAddr);
 
@@ -141,8 +141,7 @@
  */
 
 PVRSRV_ERROR
-DevmemXCreateDevmemMemDesc(DEVMEMX_PHYSDESC *psPhysDesc,
-                            DEVMEMX_VIRTDESC *psVirtDesc,
+DevmemXCreateDevmemMemDesc(DEVMEMX_VIRTDESC *psVirtDesc,
                             DEVMEM_MEMDESC **ppsMemDesc);
 
 /* DevmemXFreeDevmemMemDesc()
@@ -156,4 +155,22 @@
 PVRSRV_ERROR
 DevmemXFreeDevmemMemDesc(DEVMEM_MEMDESC *psMemDesc);
 
+PVRSRV_ERROR
+_DevmemXFlagCompatibilityCheck(IMG_UINT32 uiPhysFlags,
+                              IMG_UINT32 uiVirtFlags);
+
+PVRSRV_ERROR
+_DevmemXPhysDescAlloc(DEVMEMX_PHYSDESC **ppsPhysDesc);
+
+void
+_DevmemXPhysDescInit(DEVMEMX_PHYSDESC *psPhysDesc,
+                    IMG_HANDLE hPMR,
+                    IMG_UINT32 uiNumPages,
+                    IMG_UINT32 uiLog2PageSize,
+                    PVRSRV_MEMALLOCFLAGS_T uiFlags,
+                    IMG_HANDLE hBridge);
+
+void
+_DevmemXPhysDescFree(DEVMEMX_PHYSDESC *psPhysDesc);
+
 #endif /* DEVICEMEMX_H */
diff --git a/drivers/staging/imgtec/rogue/dllist.h b/drivers/staging/imgtec/rogue/dllist.h
index 13d5805..f1ab383 100644
--- a/drivers/staging/imgtec/rogue/dllist.h
+++ b/drivers/staging/imgtec/rogue/dllist.h
@@ -91,7 +91,6 @@
 	psListHead->psNextNode = psListHead;
 }
 
-
 /*************************************************************************/ /*!
 @Function       dllist_is_empty
 
@@ -104,11 +103,10 @@
 static INLINE
 IMG_BOOL dllist_is_empty(PDLLIST_NODE psListHead)
 {
-	return ((psListHead->psPrevNode == psListHead) 
-				&& (psListHead->psNextNode == psListHead));
+	return (IMG_BOOL) ((psListHead->psPrevNode == psListHead)
+	                   && (psListHead->psNextNode == psListHead));
 }
 
-
 /*************************************************************************/ /*!
 @Function       dllist_add_to_head
 
@@ -158,7 +156,6 @@
 	psNewNode->psNextNode = psListHead;
 }
 
-
 /*************************************************************************/ /*!
 @Function       dllist_node_is_in_list
 
@@ -171,10 +168,9 @@
 static INLINE
 IMG_BOOL dllist_node_is_in_list(PDLLIST_NODE psNode)
 {
-	return (psNode->psNextNode != 0);
+	return (IMG_BOOL) (psNode->psNextNode != 0);
 }
 
-
 /*************************************************************************/ /*!
 @Function       dllist_get_next_node
 
@@ -219,6 +215,43 @@
 	psListNode->psNextNode = 0;
 }
 
+/*************************************************************************/ /*!
+@Function       dllist_replace_head
+
+@Description    Moves the list from psOldHead to psNewHead
+
+@Input          psOldHead       List node to be replaced. Will become a head
+                                node of an empty list.
+@Input          psNewHead       List node to be inserted. Must be an empty list
+                                head.
+
+*/
+/*****************************************************************************/
+static INLINE
+void dllist_replace_head(PDLLIST_NODE psOldHead, PDLLIST_NODE psNewHead)
+{
+	if (dllist_is_empty(psOldHead))
+	{
+		psNewHead->psNextNode = psNewHead;
+		psNewHead->psPrevNode = psNewHead;
+	}
+	else
+	{
+		/* Change the neighbouring nodes */
+		psOldHead->psNextNode->psPrevNode = psNewHead;
+		psOldHead->psPrevNode->psNextNode = psNewHead;
+
+		/* Copy the old data to the new node */
+		psNewHead->psNextNode = psOldHead->psNextNode;
+		psNewHead->psPrevNode = psOldHead->psPrevNode;
+
+		/* Remove links to the previous list */
+		psOldHead->psNextNode = psOldHead;
+		psOldHead->psPrevNode = psOldHead;
+	}
+
+
+}
 
 /*************************************************************************/ /*!
 @Function       dllist_foreach_node
diff --git a/drivers/staging/imgtec/rogue/driverlock.h b/drivers/staging/imgtec/rogue/driverlock.h
deleted file mode 100644
index 1c3db37..0000000
--- a/drivers/staging/imgtec/rogue/driverlock.h
+++ /dev/null
@@ -1,66 +0,0 @@
-/*************************************************************************/ /*!
-@File           driverlock.h
-@Title          Main driver lock
-@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
-@Description    The main driver lock, held in most places in
-                the driver.
-@License        Dual MIT/GPLv2
-
-The contents of this file are subject to the MIT license as set out below.
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-Alternatively, the contents of this file may be used under the terms of
-the GNU General Public License Version 2 ("GPL") in which case the provisions
-of GPL are applicable instead of those above.
-
-If you wish to allow use of your version of this file only under the terms of
-GPL, and not to allow others to use your version of this file under the terms
-of the MIT license, indicate your decision by deleting the provisions above
-and replace them with the notice and other provisions required by GPL as set
-out in the file called "GPL-COPYING" included in this distribution. If you do
-not delete the provisions above, a recipient may use your version of this file
-under the terms of either the MIT license or GPL.
-
-This License is also included in this distribution in the file called
-"MIT-COPYING".
-
-EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
-PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
-BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
-PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
-COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
-IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
-CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-*/ /**************************************************************************/
-#ifndef __DRIVERLOCK_H__
-#define __DRIVERLOCK_H__
-
-/*
- * Main driver lock, used to ensure driver code is single threaded.
- * There are some places where this lock must not be taken, such as
- * in the mmap related deriver entry points.
- */
-extern struct mutex gPVRSRVLock;
-
-/*
- * This Lock is used to protect the sequence of operation used in MMapPMR and in
- * the memory management bridge. This makes it possible avoid the use of the bridge
- * lock in mmap.c
- * The global bridge lock can not be taken in the mmap entry point due to a
- * AB-BA deadlock risk with the Linux mmap semaphore.
- */
-extern struct mutex gGlobalLookupPMRLock;
-
-#endif /* __DRIVERLOCK_H__ */
-/*****************************************************************************
- End of file (driverlock.h)
-*****************************************************************************/
diff --git a/drivers/staging/imgtec/rogue/drm_pci_module.c b/drivers/staging/imgtec/rogue/drm_pci_module.c
deleted file mode 100644
index d777d1a..0000000
--- a/drivers/staging/imgtec/rogue/drm_pci_module.c
+++ /dev/null
@@ -1,418 +0,0 @@
-/*************************************************************************/ /*!
-@File
-@Title          Linux module setup
-@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
-@License        Dual MIT/GPLv2
-
-The contents of this file are subject to the MIT license as set out below.
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-Alternatively, the contents of this file may be used under the terms of
-the GNU General Public License Version 2 ("GPL") in which case the provisions
-of GPL are applicable instead of those above.
-
-If you wish to allow use of your version of this file only under the terms of
-GPL, and not to allow others to use your version of this file under the terms
-of the MIT license, indicate your decision by deleting the provisions above
-and replace them with the notice and other provisions required by GPL as set
-out in the file called "GPL-COPYING" included in this distribution. If you do
-not delete the provisions above, a recipient may use your version of this file
-under the terms of either the MIT license or GPL.
-
-This License is also included in this distribution in the file called
-"MIT-COPYING".
-
-EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
-PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
-BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
-PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
-COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
-IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
-CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-*/ /**************************************************************************/
-
-#include <linux/version.h>
-#include <linux/module.h>
-#include <linux/device.h>
-#include <drm/drmP.h>
-#include "pvr_debug.h"
-#include "srvkm.h"
-#include "pvrmodule.h"
-#include "linkage.h"
-#include "sysinfo.h"
-#include "module_common.h"
-#include "syscommon.h"
-
-#if defined(SUPPORT_DRM_EXT)
-#include "pvr_drm_ext.h"
-#endif
-
-#include "pvr_drm.h"
-
-#if defined(SUPPORT_SHARED_SLC)
-#include "rgxapi_km.h"
-#endif
-
-/*
- * DRVNAME is the name we use to register our driver.
- * DEVNAME is the name we use to register actual device nodes.
- */
-#define	DRVNAME		PVR_LDM_DRIVER_REGISTRATION_NAME
-#define DEVNAME		PVRSRV_MODNAME
-
-/*
- * This is all module configuration stuff required by the linux kernel.
- */
-MODULE_SUPPORTED_DEVICE(DEVNAME);
-
-#if defined(SUPPORT_SHARED_SLC)
-EXPORT_SYMBOL(RGXInitSLC);
-#endif
-
-#define	LDM_DRV	struct pci_driver
-
-static void PVRSRVDriverRemove(struct pci_dev *device);
-static int PVRSRVDriverProbe(struct pci_dev *device, const struct pci_device_id *id);
-
-/* This structure is used by the Linux module code */
-struct pci_device_id powervr_id_table[] __devinitdata = {
-	{PCI_DEVICE(SYS_RGX_DEV_VENDOR_ID, SYS_RGX_DEV_DEVICE_ID)},
-#if defined (SYS_RGX_DEV1_DEVICE_ID)
-	{PCI_DEVICE(SYS_RGX_DEV_VENDOR_ID, SYS_RGX_DEV1_DEVICE_ID)},
-#endif
-	{0}
-};
-#if !defined(SUPPORT_DRM_EXT)
-MODULE_DEVICE_TABLE(pci, powervr_id_table);
-#endif
-
-static struct dev_pm_ops powervr_dev_pm_ops = {
-	.suspend	= PVRSRVDriverSuspend,
-	.resume		= PVRSRVDriverResume,
-};
-
-static LDM_DRV powervr_driver = {
-	.name		= DRVNAME,
-	.driver.pm	= &powervr_dev_pm_ops,
-	.id_table	= powervr_id_table,
-	.probe		= PVRSRVDriverProbe,
-	.remove		= __devexit_p(PVRSRVDriverRemove),
-	.shutdown	= PVRSRVDriverShutdown,
-};
-
-static IMG_BOOL bCalledSysInit = IMG_FALSE;
-static IMG_BOOL	bDriverProbeSucceeded = IMG_FALSE;
-
-/*!
-******************************************************************************
-
- @Function		PVRSRVSystemInit
-
- @Description
-
- Wrapper for PVRSRVInit.
-
- @input pDevice - the device for which a probe is requested
-
- @Return 0 for success or <0 for an error.
-
-*****************************************************************************/
-int PVRSRVSystemInit(struct drm_device *pDrmDevice)
-{
-	struct pci_dev *pDevice = pDrmDevice->pdev;
-
-	PVR_TRACE(("PVRSRVSystemInit (pDevice=%p)", pDevice));
-
-	/* PVRSRVInit is only designed to be called once */
-	if (bCalledSysInit == IMG_FALSE)
-	{
-		gpsPVRLDMDev = pDevice;
-		bCalledSysInit = IMG_TRUE;
-
-		if (PVRSRVInit(pDevice) != PVRSRV_OK)
-		{
-			return -ENODEV;
-		}
-	}
-
-	return 0;
-}
-
-/*!
-******************************************************************************
-
- @Function		PVRSRVSystemDeInit
-
- @Description
-
- Wrapper for PVRSRVDeInit.
-
- @input pDevice - the device for which driver detachment is happening
- @Return nothing.
-
-*****************************************************************************/
-void PVRSRVSystemDeInit(struct pci_dev *pDevice)
-{
-	PVR_TRACE(("PVRSRVSystemDeInit"));
-
-	PVRSRVDeInit(pDevice);
-
-	gpsPVRLDMDev = NULL;
-}
-
-/*!
-******************************************************************************
-
- @Function		PVRSRVDriverProbe
-
- @Description
-
- See whether a given device is really one we can drive.
-
- @input pDevice - the device for which a probe is requested
-
- @Return 0 for success or <0 for an error.
-
-*****************************************************************************/
-static int __devinit PVRSRVDriverProbe(struct pci_dev *pDevice, const struct pci_device_id *pID)
-{
-	int result = 0;
-
-	PVR_TRACE(("PVRSRVDriverProbe (pDevice=%p)", pDevice));
-
-#if !defined(SUPPORT_DRM_EXT)
-	result = drm_get_pci_dev(pDevice, pID, &sPVRDRMDriver);
-#endif
-
-	bDriverProbeSucceeded = (result == 0);
-	return result;
-}
-
-
-/*!
-******************************************************************************
-
- @Function		PVRSRVDriverRemove
-
- @Description
-
- This call is the opposite of the probe call; it is called when the device is
- being removed from the driver's control.
-
- @input pDevice - the device for which driver detachment is happening
-
- @Return 0, or no return value at all, depending on the device type.
-
-*****************************************************************************/
-static void __devexit PVRSRVDriverRemove(struct pci_dev *pDevice)
-{
-	PVR_TRACE(("PVRSRVDriverRemove (pDevice=%p)", pDevice));
-
-#if !defined(SUPPORT_DRM_EXT)
-	drm_put_dev(pci_get_drvdata(pDevice));
-#else	/* !defined(SUPPORT_DRM_EXT) */
-	PVRSRVSystemDeInit(pDevice);
-#endif	/* !defined(SUPPORT_DRM_EXT) */
-}
-
-/*!
-******************************************************************************
-
- @Function		PVRSRVOpen
-
- @Description
-
- Open the PVR services node.
-
- @input pInode - the inode for the file being openeded.
- @input dev    - the DRM device corresponding to this driver.
-
- @input pFile - the file handle data for the actual file being opened
-
- @Return 0 for success or <0 for an error.
-
-*****************************************************************************/
-int PVRSRVOpen(struct drm_device unref__ *dev, struct drm_file *pDRMFile)
-{
-	int err;
-
-	struct file *pFile = PVR_FILE_FROM_DRM_FILE(pDRMFile);
-
-	if (!try_module_get(THIS_MODULE))
-	{
-		PVR_DPF((PVR_DBG_ERROR, "Failed to get module"));
-		return -ENOENT;
-	}
-
-	if ((err = PVRSRVCommonOpen(pFile)) != 0)
-	{
-		module_put(THIS_MODULE);
-	}
-
-	return err;
-}
-
-/*!
-******************************************************************************
-
- @Function		PVRSRVRelease
-
- @Description
-
- Release access the PVR services node - called when a file is closed, whether
- at exit or using close(2) system call.
-
- @input pInode - the inode for the file being released
- @input pvPrivData - driver private data
-
- @input pFile - the file handle data for the actual file being released
-
- @Return 0 for success or <0 for an error.
-
-*****************************************************************************/
-void PVRSRVRelease(struct drm_device unref__ *dev, struct drm_file *pDRMFile)
-{
-	struct file *pFile = PVR_FILE_FROM_DRM_FILE(pDRMFile);
-
-	PVRSRVCommonRelease(pFile);
-
-	module_put(THIS_MODULE);
-}
-
-/*!
-******************************************************************************
-
- @Function		PVRCore_Init
-
- @Description
-
- Insert the driver into the kernel.
-
- Readable and/or writable debugfs entries under /sys/kernel/debug/pvr are
- created with PVRDebugFSCreateEntry().  These can be read at runtime to get
- information about the device (eg. 'cat /sys/kernel/debug/pvr/nodes')
-
- __init places the function in a special memory section that the kernel frees
- once the function has been run.  Refer also to module_init() macro call below.
-
- @input none
-
- @Return none
-
-*****************************************************************************/
-#if defined(SUPPORT_DRM_EXT)
-int PVRCore_Init(void)
-#else
-static int __init PVRCore_Init(void)
-#endif
-{
-	int error = 0;
-
-	PVR_TRACE(("PVRCore_Init"));
-
-#if defined(PDUMP)
-	error = dbgdrv_init();
-	if (error != 0)
-	{
-		return error;
-	}
-#endif
-
-	if ((error = PVRSRVDriverInit()) != 0)
-	{
-		return error;
-	}
-
-#if !defined(SUPPORT_DRM_EXT)
-	error = drm_pci_init(&sPVRDRMDriver, &powervr_driver);
-	if (error != 0)
-	{
-		PVR_DPF((PVR_DBG_ERROR, "PVRCore_Init: unable to register PCI driver (%d)", error));
-		return error;
-	}
-#else
-	if (!bDriverProbeSucceeded)
-	{
-		error = PVRSRVInit(gpsPVRLDMDev);
-		if (error != 0)
-		{
-			PVR_DPF((PVR_DBG_ERROR, "PVRSRVSystemInit: unable to init PVR service (%d)", error));
-			return error;
-		}
-		bDriverProbeSucceeded = IMG_TRUE;
-	}
-#endif /* defined(SUPPORT_DRM_EXT) */
-
-	if (!bDriverProbeSucceeded)
-	{
-		PVR_TRACE(("PVRCore_Init: PVRSRVDriverProbe has not been called or did not succeed - check that hardware is detected"));
-		return error;
-	}
-
-	return PVRSRVDeviceInit();
-}
-
-
-/*!
-*****************************************************************************
-
- @Function		PVRCore_Cleanup
-
- @Description	
-
- Remove the driver from the kernel.
-
- There's no way we can get out of being unloaded other than panicking; we
- just do everything and plough on regardless of error.
-
- __exit places the function in a special memory section that the kernel frees
- once the function has been run.  Refer also to module_exit() macro call below.
-
- @input none
-
- @Return none
-
-*****************************************************************************/
-#if defined(SUPPORT_DRM_EXT)
-void PVRCore_Cleanup(void)
-#else
-static void __exit PVRCore_Cleanup(void)
-#endif
-{
-	PVR_TRACE(("PVRCore_Cleanup"));
-
-	PVRSRVDeviceDeinit();
-	
-#if !defined(SUPPORT_DRM_EXT)
-	drm_pci_exit(&sPVRDRMDriver, &powervr_driver);
-#else
-	pci_unregister_driver(&powervr_driver);
-#endif
-
-	PVRSRVDriverDeinit();
-
-#if defined(PDUMP)
-	dbgdrv_cleanup();
-#endif
-	PVR_TRACE(("PVRCore_Cleanup: unloading"));
-}
-
-/*
- * These macro calls define the initialisation and removal functions of the
- * driver.  Although they are prefixed `module_', they apply when compiling
- * statically as well; in both cases they define the function the kernel will
- * run to start/stop the driver.
-*/
-#if !defined(SUPPORT_DRM_EXT)
-module_init(PVRCore_Init);
-module_exit(PVRCore_Cleanup);
-#endif
diff --git a/drivers/staging/imgtec/rogue/env_connection.h b/drivers/staging/imgtec/rogue/env_connection.h
index 5bf9948..46b98e2 100644
--- a/drivers/staging/imgtec/rogue/env_connection.h
+++ b/drivers/staging/imgtec/rogue/env_connection.h
@@ -45,6 +45,7 @@
 #define _ENV_CONNECTION_H_
 
 #include <linux/list.h>
+#include <linux/types.h>
 
 #include "handle.h"
 #include "pvr_debug.h"
@@ -76,6 +77,8 @@
 
 typedef struct _ENV_CONNECTION_DATA_
 {
+	pid_t owner;
+
 	struct file *psFile;
 	PVRSRV_DEVICE_NODE *psDevNode;
 
diff --git a/drivers/staging/imgtec/rogue/env_data.h b/drivers/staging/imgtec/rogue/env_data.h
deleted file mode 100644
index 7e5eb03..0000000
--- a/drivers/staging/imgtec/rogue/env_data.h
+++ /dev/null
@@ -1,56 +0,0 @@
-/*************************************************************************/ /*!
-@File
-@Title          Environmental Data header file
-@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
-@Description    Linux-specific part of system data.
-@License        Dual MIT/GPLv2
-
-The contents of this file are subject to the MIT license as set out below.
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-Alternatively, the contents of this file may be used under the terms of
-the GNU General Public License Version 2 ("GPL") in which case the provisions
-of GPL are applicable instead of those above.
-
-If you wish to allow use of your version of this file only under the terms of
-GPL, and not to allow others to use your version of this file under the terms
-of the MIT license, indicate your decision by deleting the provisions above
-and replace them with the notice and other provisions required by GPL as set
-out in the file called "GPL-COPYING" included in this distribution. If you do
-not delete the provisions above, a recipient may use your version of this file
-under the terms of either the MIT license or GPL.
-
-This License is also included in this distribution in the file called
-"MIT-COPYING".
-
-EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
-PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
-BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
-PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
-COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
-IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
-CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-*/ /**************************************************************************/
-#ifndef _ENV_DATA_
-#define _ENV_DATA_
-
-#include <linux/interrupt.h>
-#include <linux/pci.h>
-
-#if defined(PVR_LINUX_MISR_USING_WORKQUEUE) || defined(PVR_LINUX_MISR_USING_PRIVATE_WORKQUEUE)
-#include <linux/workqueue.h>
-#endif
-
-#endif /* _ENV_DATA_ */
-/*****************************************************************************
- End of file (env_data.h)
-*****************************************************************************/
diff --git a/drivers/staging/imgtec/rogue/event.c b/drivers/staging/imgtec/rogue/event.c
index d2c0002..86fc2eb 100644
--- a/drivers/staging/imgtec/rogue/event.c
+++ b/drivers/staging/imgtec/rogue/event.c
@@ -40,12 +40,8 @@
 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */ /**************************************************************************/
 
-#include <linux/version.h>
 #include <asm/io.h>
 #include <asm/page.h>
-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22) && (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0)) )
-#include <asm/system.h>
-#endif
 #include <linux/mm.h>
 #include <linux/slab.h>
 #include <linux/delay.h>
@@ -62,9 +58,6 @@
 #include "img_types.h"
 #include "pvrsrv_error.h"
 #include "allocmem.h"
-#include "mm.h"
-#include "env_data.h"
-#include "driverlock.h"
 #include "event.h"
 #include "pvr_debug.h"
 #include "pvrsrv.h"
@@ -73,7 +66,9 @@
 
 /* Returns pointer to task_struct that belongs to thread which acquired
  * bridge lock. */
-extern struct task_struct *OSGetBridgeLockOwner(void);
+extern struct task_struct *BridgeLockGetOwner(void);
+extern IMG_BOOL BridgeLockIsLocked(void);
+
 
 typedef struct PVRSRV_LINUX_EVENT_OBJECT_LIST_TAG
 {
@@ -113,7 +108,7 @@
 {
 	PVRSRV_LINUX_EVENT_OBJECT_LIST *psEvenObjectList;
 
-	psEvenObjectList = OSAllocMem(sizeof(PVRSRV_LINUX_EVENT_OBJECT_LIST));
+	psEvenObjectList = OSAllocMem(sizeof(*psEvenObjectList));
 	if (psEvenObjectList == NULL)
 	{
 		PVR_DPF((PVR_DBG_ERROR, "LinuxEventObjectCreate: failed to allocate memory for event list"));
@@ -220,7 +215,7 @@
 	PVRSRV_LINUX_EVENT_OBJECT_LIST *psLinuxEventObjectList = (PVRSRV_LINUX_EVENT_OBJECT_LIST*)hOSEventObjectList;
 
 	/* allocate completion variable */
-	psLinuxEventObject = OSAllocMem(sizeof(PVRSRV_LINUX_EVENT_OBJECT));
+	psLinuxEventObject = OSAllocMem(sizeof(*psLinuxEventObject));
 	if (psLinuxEventObject == NULL)
 	{
 		PVR_DPF((PVR_DBG_ERROR, "LinuxEventObjectAdd: failed to allocate memory "));
@@ -295,28 +290,36 @@
 
  @Input    hOSEventObject : Event object handle
 
- @Input   ui32MSTimeout : Time out value in msec
+ @Input   ui64Timeoutus : Time out value in usec
 
  @Return   PVRSRV_ERROR  :  Error code
 
 ******************************************************************************/
-PVRSRV_ERROR LinuxEventObjectWait(IMG_HANDLE hOSEventObject, IMG_UINT32 ui32MSTimeout, IMG_BOOL bHoldBridgeLock)
+PVRSRV_ERROR LinuxEventObjectWait(IMG_HANDLE hOSEventObject, IMG_UINT64 ui64Timeoutus, IMG_BOOL bHoldBridgeLock)
 {
 	IMG_UINT32 ui32TimeStamp;
 	IMG_BOOL bReleasePVRLock;
 	PVRSRV_DATA *psPVRSRVData = PVRSRVGetPVRSRVData();
+	IMG_UINT32 ui32Remainder;
+	long timeOutJiffies;
 	DEFINE_WAIT(sWait);
 
 	PVRSRV_LINUX_EVENT_OBJECT *psLinuxEventObject = (PVRSRV_LINUX_EVENT_OBJECT *) hOSEventObject;
 
-	IMG_UINT32 ui32TimeOutJiffies = msecs_to_jiffies(ui32MSTimeout);
-
 	/* Check if the driver is good shape */
 	if (psPVRSRVData->eServicesState != PVRSRV_SERVICES_STATE_OK)
 	{
 		return PVRSRV_ERROR_TIMEOUT;
 	}
 
+	/* usecs_to_jiffies only takes an uint. So if our timeout is bigger than an
+	 * uint use the msec version. With such a long timeout we really don't need
+	 * the high resolution of usecs. */
+	if (ui64Timeoutus > 0xffffffffULL)
+		timeOutJiffies = msecs_to_jiffies(OSDivide64(ui64Timeoutus, 1000, &ui32Remainder));
+	else
+		timeOutJiffies = usecs_to_jiffies(ui64Timeoutus);
+
 	do
 	{
 		prepare_to_wait(&psLinuxEventObject->sWait, &sWait, TASK_INTERRUPTIBLE);
@@ -331,13 +334,13 @@
 		 * 'release before deschedule' behaviour. Some threads choose not to
 		 * hold the bridge lock in their implementation.
 		 */
-		bReleasePVRLock = (!bHoldBridgeLock && mutex_is_locked(&gPVRSRVLock) && current == OSGetBridgeLockOwner());
+		bReleasePVRLock = (!bHoldBridgeLock && BridgeLockIsLocked() && current == BridgeLockGetOwner());
 		if (bReleasePVRLock == IMG_TRUE)
 		{
 			OSReleaseBridgeLock();
 		}
 
-		ui32TimeOutJiffies = (IMG_UINT32)schedule_timeout((IMG_INT32)ui32TimeOutJiffies);
+		timeOutJiffies = schedule_timeout(timeOutJiffies);
 
 		if (bReleasePVRLock == IMG_TRUE)
 		{
@@ -349,12 +352,12 @@
 #endif
 
 
-	} while (ui32TimeOutJiffies);
+	} while (timeOutJiffies);
 
 	finish_wait(&psLinuxEventObject->sWait, &sWait);
 
 	psLinuxEventObject->ui32TimeStampPrevious = ui32TimeStamp;
 
-	return ui32TimeOutJiffies ? PVRSRV_OK : PVRSRV_ERROR_TIMEOUT;
+	return timeOutJiffies ? PVRSRV_OK : PVRSRV_ERROR_TIMEOUT;
 
 }
diff --git a/drivers/staging/imgtec/rogue/event.h b/drivers/staging/imgtec/rogue/event.h
index 9063f88..5b14cec 100644
--- a/drivers/staging/imgtec/rogue/event.h
+++ b/drivers/staging/imgtec/rogue/event.h
@@ -45,4 +45,4 @@
 PVRSRV_ERROR LinuxEventObjectAdd(IMG_HANDLE hOSEventObjectList, IMG_HANDLE *phOSEventObject);
 PVRSRV_ERROR LinuxEventObjectDelete(IMG_HANDLE hOSEventObject);
 PVRSRV_ERROR LinuxEventObjectSignal(IMG_HANDLE hOSEventObjectList);
-PVRSRV_ERROR LinuxEventObjectWait(IMG_HANDLE hOSEventObject, IMG_UINT32 ui32MSTimeout, IMG_BOOL bHoldBridgeLock);
+PVRSRV_ERROR LinuxEventObjectWait(IMG_HANDLE hOSEventObject, IMG_UINT64 ui64Timeoutus, IMG_BOOL bHoldBridgeLock);
diff --git a/drivers/staging/imgtec/rogue/generated/breakpoint_bridge/common_breakpoint_bridge.h b/drivers/staging/imgtec/rogue/generated/breakpoint_bridge/common_breakpoint_bridge.h
index 75d7dd0..28d3fd2 100644
--- a/drivers/staging/imgtec/rogue/generated/breakpoint_bridge/common_breakpoint_bridge.h
+++ b/drivers/staging/imgtec/rogue/generated/breakpoint_bridge/common_breakpoint_bridge.h
@@ -2,8 +2,8 @@
 @File
 @Title          Common bridge header for breakpoint
 @Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
-@Description    Declares common defines and structures that are used by both
-                the client and sever side of the bridge for breakpoint
+@Description    Declares common defines and structures used by both the client
+                and server side of the bridge for breakpoint
 @License        Dual MIT/GPLv2
 
 The contents of this file are subject to the MIT license as set out below.
@@ -45,6 +45,8 @@
 #ifndef COMMON_BREAKPOINT_BRIDGE_H
 #define COMMON_BREAKPOINT_BRIDGE_H
 
+#include <powervr/mem_types.h>
+
 #include "img_types.h"
 #include "pvrsrv_error.h"
 
diff --git a/drivers/staging/imgtec/rogue/generated/breakpoint_bridge/server_breakpoint_bridge.c b/drivers/staging/imgtec/rogue/generated/breakpoint_bridge/server_breakpoint_bridge.c
index a316661f..a6de6ae 100644
--- a/drivers/staging/imgtec/rogue/generated/breakpoint_bridge/server_breakpoint_bridge.c
+++ b/drivers/staging/imgtec/rogue/generated/breakpoint_bridge/server_breakpoint_bridge.c
@@ -63,6 +63,9 @@
 
 
 
+#if !defined(EXCLUDE_BREAKPOINT_BRIDGE)
+
+
 
 /* ***************************************************************************
  * Server-side bridge entry points
@@ -74,6 +77,7 @@
 					  PVRSRV_BRIDGE_OUT_RGXSETBREAKPOINT *psRGXSetBreakpointOUT,
 					 CONNECTION_DATA *psConnection)
 {
+	IMG_HANDLE hPrivData = psRGXSetBreakpointIN->hPrivData;
 	IMG_HANDLE hPrivDataInt = NULL;
 
 
@@ -82,19 +86,29 @@
 
 
 
+	/* Lock over handle lookup. */
+	LockHandle();
+
+
+
+
+
 				{
 					/* Look up the address from the handle */
 					psRGXSetBreakpointOUT->eError =
-						PVRSRVLookupHandle(psConnection->psHandleBase,
+						PVRSRVLookupHandleUnlocked(psConnection->psHandleBase,
 											(void **) &hPrivDataInt,
-											psRGXSetBreakpointIN->hPrivData,
-											PVRSRV_HANDLE_TYPE_DEV_PRIV_DATA);
+											hPrivData,
+											PVRSRV_HANDLE_TYPE_DEV_PRIV_DATA,
+											IMG_TRUE);
 					if(psRGXSetBreakpointOUT->eError != PVRSRV_OK)
 					{
+						UnlockHandle();
 						goto RGXSetBreakpoint_exit;
 					}
 				}
-
+	/* Release now we have looked up handles. */
+	UnlockHandle();
 
 	psRGXSetBreakpointOUT->eError =
 		PVRSRVRGXSetBreakpointKM(psConnection, OSGetDevData(psConnection),
@@ -109,15 +123,38 @@
 
 RGXSetBreakpoint_exit:
 
+	/* Lock over handle lookup cleanup. */
+	LockHandle();
+
+
+
+
+
+
+				{
+					/* Unreference the previously looked up handle */
+						if(hPrivDataInt)
+						{
+							PVRSRVReleaseHandleUnlocked(psConnection->psHandleBase,
+											hPrivData,
+											PVRSRV_HANDLE_TYPE_DEV_PRIV_DATA);
+						}
+				}
+	/* Release now we have cleaned up look up handles. */
+	UnlockHandle();
+
+
 	return 0;
 }
 
+
 static IMG_INT
 PVRSRVBridgeRGXClearBreakpoint(IMG_UINT32 ui32DispatchTableEntry,
 					  PVRSRV_BRIDGE_IN_RGXCLEARBREAKPOINT *psRGXClearBreakpointIN,
 					  PVRSRV_BRIDGE_OUT_RGXCLEARBREAKPOINT *psRGXClearBreakpointOUT,
 					 CONNECTION_DATA *psConnection)
 {
+	IMG_HANDLE hPrivData = psRGXClearBreakpointIN->hPrivData;
 	IMG_HANDLE hPrivDataInt = NULL;
 
 
@@ -126,19 +163,29 @@
 
 
 
+	/* Lock over handle lookup. */
+	LockHandle();
+
+
+
+
+
 				{
 					/* Look up the address from the handle */
 					psRGXClearBreakpointOUT->eError =
-						PVRSRVLookupHandle(psConnection->psHandleBase,
+						PVRSRVLookupHandleUnlocked(psConnection->psHandleBase,
 											(void **) &hPrivDataInt,
-											psRGXClearBreakpointIN->hPrivData,
-											PVRSRV_HANDLE_TYPE_DEV_PRIV_DATA);
+											hPrivData,
+											PVRSRV_HANDLE_TYPE_DEV_PRIV_DATA,
+											IMG_TRUE);
 					if(psRGXClearBreakpointOUT->eError != PVRSRV_OK)
 					{
+						UnlockHandle();
 						goto RGXClearBreakpoint_exit;
 					}
 				}
-
+	/* Release now we have looked up handles. */
+	UnlockHandle();
 
 	psRGXClearBreakpointOUT->eError =
 		PVRSRVRGXClearBreakpointKM(psConnection, OSGetDevData(psConnection),
@@ -149,15 +196,38 @@
 
 RGXClearBreakpoint_exit:
 
+	/* Lock over handle lookup cleanup. */
+	LockHandle();
+
+
+
+
+
+
+				{
+					/* Unreference the previously looked up handle */
+						if(hPrivDataInt)
+						{
+							PVRSRVReleaseHandleUnlocked(psConnection->psHandleBase,
+											hPrivData,
+											PVRSRV_HANDLE_TYPE_DEV_PRIV_DATA);
+						}
+				}
+	/* Release now we have cleaned up look up handles. */
+	UnlockHandle();
+
+
 	return 0;
 }
 
+
 static IMG_INT
 PVRSRVBridgeRGXEnableBreakpoint(IMG_UINT32 ui32DispatchTableEntry,
 					  PVRSRV_BRIDGE_IN_RGXENABLEBREAKPOINT *psRGXEnableBreakpointIN,
 					  PVRSRV_BRIDGE_OUT_RGXENABLEBREAKPOINT *psRGXEnableBreakpointOUT,
 					 CONNECTION_DATA *psConnection)
 {
+	IMG_HANDLE hPrivData = psRGXEnableBreakpointIN->hPrivData;
 	IMG_HANDLE hPrivDataInt = NULL;
 
 
@@ -166,19 +236,29 @@
 
 
 
+	/* Lock over handle lookup. */
+	LockHandle();
+
+
+
+
+
 				{
 					/* Look up the address from the handle */
 					psRGXEnableBreakpointOUT->eError =
-						PVRSRVLookupHandle(psConnection->psHandleBase,
+						PVRSRVLookupHandleUnlocked(psConnection->psHandleBase,
 											(void **) &hPrivDataInt,
-											psRGXEnableBreakpointIN->hPrivData,
-											PVRSRV_HANDLE_TYPE_DEV_PRIV_DATA);
+											hPrivData,
+											PVRSRV_HANDLE_TYPE_DEV_PRIV_DATA,
+											IMG_TRUE);
 					if(psRGXEnableBreakpointOUT->eError != PVRSRV_OK)
 					{
+						UnlockHandle();
 						goto RGXEnableBreakpoint_exit;
 					}
 				}
-
+	/* Release now we have looked up handles. */
+	UnlockHandle();
 
 	psRGXEnableBreakpointOUT->eError =
 		PVRSRVRGXEnableBreakpointKM(psConnection, OSGetDevData(psConnection),
@@ -189,15 +269,38 @@
 
 RGXEnableBreakpoint_exit:
 
+	/* Lock over handle lookup cleanup. */
+	LockHandle();
+
+
+
+
+
+
+				{
+					/* Unreference the previously looked up handle */
+						if(hPrivDataInt)
+						{
+							PVRSRVReleaseHandleUnlocked(psConnection->psHandleBase,
+											hPrivData,
+											PVRSRV_HANDLE_TYPE_DEV_PRIV_DATA);
+						}
+				}
+	/* Release now we have cleaned up look up handles. */
+	UnlockHandle();
+
+
 	return 0;
 }
 
+
 static IMG_INT
 PVRSRVBridgeRGXDisableBreakpoint(IMG_UINT32 ui32DispatchTableEntry,
 					  PVRSRV_BRIDGE_IN_RGXDISABLEBREAKPOINT *psRGXDisableBreakpointIN,
 					  PVRSRV_BRIDGE_OUT_RGXDISABLEBREAKPOINT *psRGXDisableBreakpointOUT,
 					 CONNECTION_DATA *psConnection)
 {
+	IMG_HANDLE hPrivData = psRGXDisableBreakpointIN->hPrivData;
 	IMG_HANDLE hPrivDataInt = NULL;
 
 
@@ -206,19 +309,29 @@
 
 
 
+	/* Lock over handle lookup. */
+	LockHandle();
+
+
+
+
+
 				{
 					/* Look up the address from the handle */
 					psRGXDisableBreakpointOUT->eError =
-						PVRSRVLookupHandle(psConnection->psHandleBase,
+						PVRSRVLookupHandleUnlocked(psConnection->psHandleBase,
 											(void **) &hPrivDataInt,
-											psRGXDisableBreakpointIN->hPrivData,
-											PVRSRV_HANDLE_TYPE_DEV_PRIV_DATA);
+											hPrivData,
+											PVRSRV_HANDLE_TYPE_DEV_PRIV_DATA,
+											IMG_TRUE);
 					if(psRGXDisableBreakpointOUT->eError != PVRSRV_OK)
 					{
+						UnlockHandle();
 						goto RGXDisableBreakpoint_exit;
 					}
 				}
-
+	/* Release now we have looked up handles. */
+	UnlockHandle();
 
 	psRGXDisableBreakpointOUT->eError =
 		PVRSRVRGXDisableBreakpointKM(psConnection, OSGetDevData(psConnection),
@@ -229,9 +342,31 @@
 
 RGXDisableBreakpoint_exit:
 
+	/* Lock over handle lookup cleanup. */
+	LockHandle();
+
+
+
+
+
+
+				{
+					/* Unreference the previously looked up handle */
+						if(hPrivDataInt)
+						{
+							PVRSRVReleaseHandleUnlocked(psConnection->psHandleBase,
+											hPrivData,
+											PVRSRV_HANDLE_TYPE_DEV_PRIV_DATA);
+						}
+				}
+	/* Release now we have cleaned up look up handles. */
+	UnlockHandle();
+
+
 	return 0;
 }
 
+
 static IMG_INT
 PVRSRVBridgeRGXOverallocateBPRegisters(IMG_UINT32 ui32DispatchTableEntry,
 					  PVRSRV_BRIDGE_IN_RGXOVERALLOCATEBPREGISTERS *psRGXOverallocateBPRegistersIN,
@@ -245,6 +380,7 @@
 
 
 
+
 	psRGXOverallocateBPRegistersOUT->eError =
 		PVRSRVRGXOverallocateBPRegistersKM(psConnection, OSGetDevData(psConnection),
 					psRGXOverallocateBPRegistersIN->ui32TempRegs,
@@ -254,17 +390,23 @@
 
 
 
+
+
+
 	return 0;
 }
 
 
 
+
 /* *************************************************************************** 
  * Server bridge dispatch related glue 
  */
 
 static IMG_BOOL bUseLock = IMG_TRUE;
+#endif /* EXCLUDE_BREAKPOINT_BRIDGE */
 
+#if !defined(EXCLUDE_BREAKPOINT_BRIDGE)
 PVRSRV_ERROR InitBREAKPOINTBridge(void);
 PVRSRV_ERROR DeinitBREAKPOINTBridge(void);
 
@@ -300,4 +442,14 @@
 {
 	return PVRSRV_OK;
 }
+#else /* EXCLUDE_BREAKPOINT_BRIDGE */
+/* This bridge is conditional on EXCLUDE_BREAKPOINT_BRIDGE - when defined,
+ * do not populate the dispatch table with its functions
+ */
+#define InitBREAKPOINTBridge() \
+	PVRSRV_OK
 
+#define DeinitBREAKPOINTBridge() \
+	PVRSRV_OK
+
+#endif /* EXCLUDE_BREAKPOINT_BRIDGE */
diff --git a/drivers/staging/imgtec/rogue/generated/cachegeneric_bridge/client_cachegeneric_bridge.h b/drivers/staging/imgtec/rogue/generated/cache_bridge/client_cache_bridge.h
similarity index 67%
copy from drivers/staging/imgtec/rogue/generated/cachegeneric_bridge/client_cachegeneric_bridge.h
copy to drivers/staging/imgtec/rogue/generated/cache_bridge/client_cache_bridge.h
index 839a17a..815c0b8 100644
--- a/drivers/staging/imgtec/rogue/generated/cachegeneric_bridge/client_cachegeneric_bridge.h
+++ b/drivers/staging/imgtec/rogue/generated/cache_bridge/client_cache_bridge.h
@@ -1,8 +1,8 @@
 /*************************************************************************/ /*!
 @File
-@Title          Client bridge header for cachegeneric
+@Title          Client bridge header for cache
 @Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
-@Description    Exports the client bridge functions for cachegeneric
+@Description    Exports the client bridge functions for cache
 @License        Dual MIT/GPLv2
 
 The contents of this file are subject to the MIT license as set out below.
@@ -41,8 +41,8 @@
 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */ /**************************************************************************/
 
-#ifndef CLIENT_CACHEGENERIC_BRIDGE_H
-#define CLIENT_CACHEGENERIC_BRIDGE_H
+#ifndef CLIENT_CACHE_BRIDGE_H
+#define CLIENT_CACHE_BRIDGE_H
 
 #include "img_defs.h"
 #include "pvrsrv_error.h"
@@ -52,13 +52,35 @@
 #include "pvr_bridge.h"
 #endif
 
-#include "common_cachegeneric_bridge.h"
+#include "common_cache_bridge.h"
 
 IMG_INTERNAL PVRSRV_ERROR IMG_CALLCONV BridgeCacheOpQueue(IMG_HANDLE hBridge,
-							  IMG_HANDLE hPMR,
-							  IMG_DEVMEM_OFFSET_T uiOffset,
-							  IMG_DEVMEM_SIZE_T uiSize,
-							  PVRSRV_CACHE_OP iuCacheOp);
+							  IMG_UINT32 ui32NumCacheOps,
+							  IMG_HANDLE *phPMR,
+							  IMG_DEVMEM_OFFSET_T *puiOffset,
+							  IMG_DEVMEM_SIZE_T *puiSize,
+							  PVRSRV_CACHE_OP *piuCacheOp,
+							  IMG_UINT32 *pui32CacheOpSeqNum);
+
+IMG_INTERNAL PVRSRV_ERROR IMG_CALLCONV BridgeCacheOpExec(IMG_HANDLE hBridge,
+							 IMG_HANDLE hPMR,
+							 IMG_DEVMEM_OFFSET_T uiOffset,
+							 IMG_DEVMEM_SIZE_T uiSize,
+							 PVRSRV_CACHE_OP iuCacheOp);
+
+IMG_INTERNAL PVRSRV_ERROR IMG_CALLCONV BridgeCacheOpSetTimeline(IMG_HANDLE hBridge,
+								IMG_INT32 i32OpTimeline);
+
+IMG_INTERNAL PVRSRV_ERROR IMG_CALLCONV BridgeCacheOpLog(IMG_HANDLE hBridge,
+							IMG_HANDLE hPMR,
+							IMG_DEVMEM_OFFSET_T uiOffset,
+							IMG_DEVMEM_SIZE_T uiSize,
+							IMG_INT64 i64QueuedTimeUs,
+							IMG_INT64 i64ExecuteTimeUs,
+							PVRSRV_CACHE_OP iuCacheOp);
+
+IMG_INTERNAL PVRSRV_ERROR IMG_CALLCONV BridgeCacheOpGetLineSize(IMG_HANDLE hBridge,
+								IMG_UINT32 *pui32L1DataCacheLineSize);
 
 
-#endif /* CLIENT_CACHEGENERIC_BRIDGE_H */
+#endif /* CLIENT_CACHE_BRIDGE_H */
diff --git a/drivers/staging/imgtec/rogue/generated/cache_bridge/client_cache_direct_bridge.c b/drivers/staging/imgtec/rogue/generated/cache_bridge/client_cache_direct_bridge.c
new file mode 100644
index 0000000..69837fc
--- /dev/null
+++ b/drivers/staging/imgtec/rogue/generated/cache_bridge/client_cache_direct_bridge.c
@@ -0,0 +1,153 @@
+/*************************************************************************/ /*!
+@Title          Direct client bridge for cache
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#include "client_cache_bridge.h"
+#include "img_defs.h"
+#include "pvr_debug.h"
+
+/* Module specific includes */
+#include "cache_ops.h"
+
+#include "cache_km.h"
+
+
+IMG_INTERNAL PVRSRV_ERROR IMG_CALLCONV BridgeCacheOpQueue(IMG_HANDLE hBridge,
+							  IMG_UINT32 ui32NumCacheOps,
+							  IMG_HANDLE *phPMR,
+							  IMG_DEVMEM_OFFSET_T *puiOffset,
+							  IMG_DEVMEM_SIZE_T *puiSize,
+							  PVRSRV_CACHE_OP *piuCacheOp,
+							  IMG_UINT32 *pui32CacheOpSeqNum)
+{
+	PVRSRV_ERROR eError;
+	PMR * *psPMRInt;
+	PVR_UNREFERENCED_PARAMETER(hBridge);
+
+	psPMRInt = (PMR **) phPMR;
+
+	eError =
+		CacheOpQueue(
+					ui32NumCacheOps,
+					psPMRInt,
+					puiOffset,
+					puiSize,
+					piuCacheOp,
+					pui32CacheOpSeqNum);
+
+	return eError;
+}
+
+IMG_INTERNAL PVRSRV_ERROR IMG_CALLCONV BridgeCacheOpExec(IMG_HANDLE hBridge,
+							 IMG_HANDLE hPMR,
+							 IMG_DEVMEM_OFFSET_T uiOffset,
+							 IMG_DEVMEM_SIZE_T uiSize,
+							 PVRSRV_CACHE_OP iuCacheOp)
+{
+	PVRSRV_ERROR eError;
+	PMR * psPMRInt;
+	PVR_UNREFERENCED_PARAMETER(hBridge);
+
+	psPMRInt = (PMR *) hPMR;
+
+	eError =
+		CacheOpExec(
+					psPMRInt,
+					uiOffset,
+					uiSize,
+					iuCacheOp);
+
+	return eError;
+}
+
+IMG_INTERNAL PVRSRV_ERROR IMG_CALLCONV BridgeCacheOpSetTimeline(IMG_HANDLE hBridge,
+								IMG_INT32 i32OpTimeline)
+{
+	PVRSRV_ERROR eError;
+	PVR_UNREFERENCED_PARAMETER(hBridge);
+
+
+	eError =
+		CacheOpSetTimeline(
+					i32OpTimeline);
+
+	return eError;
+}
+
+IMG_INTERNAL PVRSRV_ERROR IMG_CALLCONV BridgeCacheOpLog(IMG_HANDLE hBridge,
+							IMG_HANDLE hPMR,
+							IMG_DEVMEM_OFFSET_T uiOffset,
+							IMG_DEVMEM_SIZE_T uiSize,
+							IMG_INT64 i64QueuedTimeUs,
+							IMG_INT64 i64ExecuteTimeUs,
+							PVRSRV_CACHE_OP iuCacheOp)
+{
+	PVRSRV_ERROR eError;
+	PMR * psPMRInt;
+	PVR_UNREFERENCED_PARAMETER(hBridge);
+
+	psPMRInt = (PMR *) hPMR;
+
+	eError =
+		CacheOpLog(
+					psPMRInt,
+					uiOffset,
+					uiSize,
+					i64QueuedTimeUs,
+					i64ExecuteTimeUs,
+					iuCacheOp);
+
+	return eError;
+}
+
+IMG_INTERNAL PVRSRV_ERROR IMG_CALLCONV BridgeCacheOpGetLineSize(IMG_HANDLE hBridge,
+								IMG_UINT32 *pui32L1DataCacheLineSize)
+{
+	PVRSRV_ERROR eError;
+	PVR_UNREFERENCED_PARAMETER(hBridge);
+
+
+	eError =
+		CacheOpGetLineSize(
+					pui32L1DataCacheLineSize);
+
+	return eError;
+}
+
diff --git a/drivers/staging/imgtec/rogue/generated/cache_bridge/common_cache_bridge.h b/drivers/staging/imgtec/rogue/generated/cache_bridge/common_cache_bridge.h
new file mode 100644
index 0000000..e5c6e9c
--- /dev/null
+++ b/drivers/staging/imgtec/rogue/generated/cache_bridge/common_cache_bridge.h
@@ -0,0 +1,164 @@
+/*************************************************************************/ /*!
+@File
+@Title          Common bridge header for cache
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description    Declares common defines and structures used by both the client
+                and server side of the bridge for cache
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#ifndef COMMON_CACHE_BRIDGE_H
+#define COMMON_CACHE_BRIDGE_H
+
+#include <powervr/mem_types.h>
+
+#include "img_types.h"
+#include "pvrsrv_error.h"
+
+#include "cache_ops.h"
+
+
+#define PVRSRV_BRIDGE_CACHE_CMD_FIRST			0
+#define PVRSRV_BRIDGE_CACHE_CACHEOPQUEUE			PVRSRV_BRIDGE_CACHE_CMD_FIRST+0
+#define PVRSRV_BRIDGE_CACHE_CACHEOPEXEC			PVRSRV_BRIDGE_CACHE_CMD_FIRST+1
+#define PVRSRV_BRIDGE_CACHE_CACHEOPSETTIMELINE			PVRSRV_BRIDGE_CACHE_CMD_FIRST+2
+#define PVRSRV_BRIDGE_CACHE_CACHEOPLOG			PVRSRV_BRIDGE_CACHE_CMD_FIRST+3
+#define PVRSRV_BRIDGE_CACHE_CACHEOPGETLINESIZE			PVRSRV_BRIDGE_CACHE_CMD_FIRST+4
+#define PVRSRV_BRIDGE_CACHE_CMD_LAST			(PVRSRV_BRIDGE_CACHE_CMD_FIRST+4)
+
+
+/*******************************************
+            CacheOpQueue          
+ *******************************************/
+
+/* Bridge in structure for CacheOpQueue */
+typedef struct PVRSRV_BRIDGE_IN_CACHEOPQUEUE_TAG
+{
+	IMG_UINT32 ui32NumCacheOps;
+	IMG_HANDLE * phPMR;
+	IMG_DEVMEM_OFFSET_T * puiOffset;
+	IMG_DEVMEM_SIZE_T * puiSize;
+	PVRSRV_CACHE_OP * piuCacheOp;
+} __attribute__((packed)) PVRSRV_BRIDGE_IN_CACHEOPQUEUE;
+
+/* Bridge out structure for CacheOpQueue */
+typedef struct PVRSRV_BRIDGE_OUT_CACHEOPQUEUE_TAG
+{
+	IMG_UINT32 ui32CacheOpSeqNum;
+	PVRSRV_ERROR eError;
+} __attribute__((packed)) PVRSRV_BRIDGE_OUT_CACHEOPQUEUE;
+
+
+/*******************************************
+            CacheOpExec          
+ *******************************************/
+
+/* Bridge in structure for CacheOpExec */
+typedef struct PVRSRV_BRIDGE_IN_CACHEOPEXEC_TAG
+{
+	IMG_HANDLE hPMR;
+	IMG_DEVMEM_OFFSET_T uiOffset;
+	IMG_DEVMEM_SIZE_T uiSize;
+	PVRSRV_CACHE_OP iuCacheOp;
+} __attribute__((packed)) PVRSRV_BRIDGE_IN_CACHEOPEXEC;
+
+/* Bridge out structure for CacheOpExec */
+typedef struct PVRSRV_BRIDGE_OUT_CACHEOPEXEC_TAG
+{
+	PVRSRV_ERROR eError;
+} __attribute__((packed)) PVRSRV_BRIDGE_OUT_CACHEOPEXEC;
+
+
+/*******************************************
+            CacheOpSetTimeline          
+ *******************************************/
+
+/* Bridge in structure for CacheOpSetTimeline */
+typedef struct PVRSRV_BRIDGE_IN_CACHEOPSETTIMELINE_TAG
+{
+	IMG_INT32 i32OpTimeline;
+} __attribute__((packed)) PVRSRV_BRIDGE_IN_CACHEOPSETTIMELINE;
+
+/* Bridge out structure for CacheOpSetTimeline */
+typedef struct PVRSRV_BRIDGE_OUT_CACHEOPSETTIMELINE_TAG
+{
+	PVRSRV_ERROR eError;
+} __attribute__((packed)) PVRSRV_BRIDGE_OUT_CACHEOPSETTIMELINE;
+
+
+/*******************************************
+            CacheOpLog          
+ *******************************************/
+
+/* Bridge in structure for CacheOpLog */
+typedef struct PVRSRV_BRIDGE_IN_CACHEOPLOG_TAG
+{
+	IMG_HANDLE hPMR;
+	IMG_DEVMEM_OFFSET_T uiOffset;
+	IMG_DEVMEM_SIZE_T uiSize;
+	IMG_INT64 i64QueuedTimeUs;
+	IMG_INT64 i64ExecuteTimeUs;
+	PVRSRV_CACHE_OP iuCacheOp;
+} __attribute__((packed)) PVRSRV_BRIDGE_IN_CACHEOPLOG;
+
+/* Bridge out structure for CacheOpLog */
+typedef struct PVRSRV_BRIDGE_OUT_CACHEOPLOG_TAG
+{
+	PVRSRV_ERROR eError;
+} __attribute__((packed)) PVRSRV_BRIDGE_OUT_CACHEOPLOG;
+
+
+/*******************************************
+            CacheOpGetLineSize          
+ *******************************************/
+
+/* Bridge in structure for CacheOpGetLineSize */
+typedef struct PVRSRV_BRIDGE_IN_CACHEOPGETLINESIZE_TAG
+{
+	 IMG_UINT32 ui32EmptyStructPlaceholder;
+} __attribute__((packed)) PVRSRV_BRIDGE_IN_CACHEOPGETLINESIZE;
+
+/* Bridge out structure for CacheOpGetLineSize */
+typedef struct PVRSRV_BRIDGE_OUT_CACHEOPGETLINESIZE_TAG
+{
+	IMG_UINT32 ui32L1DataCacheLineSize;
+	PVRSRV_ERROR eError;
+} __attribute__((packed)) PVRSRV_BRIDGE_OUT_CACHEOPGETLINESIZE;
+
+
+#endif /* COMMON_CACHE_BRIDGE_H */
diff --git a/drivers/staging/imgtec/rogue/generated/cache_bridge/server_cache_bridge.c b/drivers/staging/imgtec/rogue/generated/cache_bridge/server_cache_bridge.c
new file mode 100644
index 0000000..cfb98fb
--- /dev/null
+++ b/drivers/staging/imgtec/rogue/generated/cache_bridge/server_cache_bridge.c
@@ -0,0 +1,543 @@
+/*************************************************************************/ /*!
+@File
+@Title          Server bridge for cache
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description    Implements the server side of the bridge for cache
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#include <stddef.h>
+#include <asm/uaccess.h>
+
+#include "img_defs.h"
+
+#include "cache_km.h"
+
+
+#include "common_cache_bridge.h"
+
+#include "allocmem.h"
+#include "pvr_debug.h"
+#include "connection_server.h"
+#include "pvr_bridge.h"
+#include "rgx_bridge.h"
+#include "srvcore.h"
+#include "handle.h"
+
+#include <linux/slab.h>
+
+
+
+
+
+
+/* ***************************************************************************
+ * Server-side bridge entry points
+ */
+ 
+static IMG_INT
+PVRSRVBridgeCacheOpQueue(IMG_UINT32 ui32DispatchTableEntry,
+					  PVRSRV_BRIDGE_IN_CACHEOPQUEUE *psCacheOpQueueIN,
+					  PVRSRV_BRIDGE_OUT_CACHEOPQUEUE *psCacheOpQueueOUT,
+					 CONNECTION_DATA *psConnection)
+{
+	PMR * *psPMRInt = NULL;
+	IMG_HANDLE *hPMRInt2 = NULL;
+	IMG_DEVMEM_OFFSET_T *uiOffsetInt = NULL;
+	IMG_DEVMEM_SIZE_T *uiSizeInt = NULL;
+	PVRSRV_CACHE_OP *iuCacheOpInt = NULL;
+
+	IMG_UINT32 ui32NextOffset = 0;
+	IMG_BYTE   *pArrayArgsBuffer = NULL;
+#if !defined(INTEGRITY_OS)
+	IMG_BOOL bHaveEnoughSpace = IMG_FALSE;
+#endif
+
+	IMG_UINT32 ui32BufferSize = 
+			(psCacheOpQueueIN->ui32NumCacheOps * sizeof(PMR *)) +
+			(psCacheOpQueueIN->ui32NumCacheOps * sizeof(IMG_HANDLE)) +
+			(psCacheOpQueueIN->ui32NumCacheOps * sizeof(IMG_DEVMEM_OFFSET_T)) +
+			(psCacheOpQueueIN->ui32NumCacheOps * sizeof(IMG_DEVMEM_SIZE_T)) +
+			(psCacheOpQueueIN->ui32NumCacheOps * sizeof(PVRSRV_CACHE_OP)) +
+			0;
+
+
+
+
+
+	if (ui32BufferSize != 0)
+	{
+#if !defined(INTEGRITY_OS)
+		/* Try to use remainder of input buffer for copies if possible, word-aligned for safety. */
+		IMG_UINT32 ui32InBufferOffset = PVR_ALIGN(sizeof(*psCacheOpQueueIN), sizeof(unsigned long));
+		IMG_UINT32 ui32InBufferExcessSize = ui32InBufferOffset >= PVRSRV_MAX_BRIDGE_IN_SIZE ? 0 :
+			PVRSRV_MAX_BRIDGE_IN_SIZE - ui32InBufferOffset;
+
+		bHaveEnoughSpace = ui32BufferSize <= ui32InBufferExcessSize;
+		if (bHaveEnoughSpace)
+		{
+			IMG_BYTE *pInputBuffer = (IMG_BYTE *)psCacheOpQueueIN;
+
+			pArrayArgsBuffer = &pInputBuffer[ui32InBufferOffset];		}
+		else
+#endif
+		{
+			pArrayArgsBuffer = OSAllocMemNoStats(ui32BufferSize);
+
+			if(!pArrayArgsBuffer)
+			{
+				psCacheOpQueueOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
+				goto CacheOpQueue_exit;
+			}
+		}
+	}
+
+	if (psCacheOpQueueIN->ui32NumCacheOps != 0)
+	{
+		psPMRInt = (PMR **)(((IMG_UINT8 *)pArrayArgsBuffer) + ui32NextOffset);
+		ui32NextOffset += psCacheOpQueueIN->ui32NumCacheOps * sizeof(PMR *);
+		hPMRInt2 = (IMG_HANDLE *)(((IMG_UINT8 *)pArrayArgsBuffer) + ui32NextOffset); 
+		ui32NextOffset += psCacheOpQueueIN->ui32NumCacheOps * sizeof(IMG_HANDLE);
+	}
+
+			/* Copy the data over */
+			if (psCacheOpQueueIN->ui32NumCacheOps * sizeof(IMG_HANDLE) > 0)
+			{
+				if ( OSCopyFromUser(NULL, hPMRInt2, psCacheOpQueueIN->phPMR, psCacheOpQueueIN->ui32NumCacheOps * sizeof(IMG_HANDLE)) != PVRSRV_OK )
+				{
+					psCacheOpQueueOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
+
+					goto CacheOpQueue_exit;
+				}
+			}
+	if (psCacheOpQueueIN->ui32NumCacheOps != 0)
+	{
+		uiOffsetInt = (IMG_DEVMEM_OFFSET_T*)(((IMG_UINT8 *)pArrayArgsBuffer) + ui32NextOffset);
+		ui32NextOffset += psCacheOpQueueIN->ui32NumCacheOps * sizeof(IMG_DEVMEM_OFFSET_T);
+	}
+
+			/* Copy the data over */
+			if (psCacheOpQueueIN->ui32NumCacheOps * sizeof(IMG_DEVMEM_OFFSET_T) > 0)
+			{
+				if ( OSCopyFromUser(NULL, uiOffsetInt, psCacheOpQueueIN->puiOffset, psCacheOpQueueIN->ui32NumCacheOps * sizeof(IMG_DEVMEM_OFFSET_T)) != PVRSRV_OK )
+				{
+					psCacheOpQueueOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
+
+					goto CacheOpQueue_exit;
+				}
+			}
+	if (psCacheOpQueueIN->ui32NumCacheOps != 0)
+	{
+		uiSizeInt = (IMG_DEVMEM_SIZE_T*)(((IMG_UINT8 *)pArrayArgsBuffer) + ui32NextOffset);
+		ui32NextOffset += psCacheOpQueueIN->ui32NumCacheOps * sizeof(IMG_DEVMEM_SIZE_T);
+	}
+
+			/* Copy the data over */
+			if (psCacheOpQueueIN->ui32NumCacheOps * sizeof(IMG_DEVMEM_SIZE_T) > 0)
+			{
+				if ( OSCopyFromUser(NULL, uiSizeInt, psCacheOpQueueIN->puiSize, psCacheOpQueueIN->ui32NumCacheOps * sizeof(IMG_DEVMEM_SIZE_T)) != PVRSRV_OK )
+				{
+					psCacheOpQueueOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
+
+					goto CacheOpQueue_exit;
+				}
+			}
+	if (psCacheOpQueueIN->ui32NumCacheOps != 0)
+	{
+		iuCacheOpInt = (PVRSRV_CACHE_OP*)(((IMG_UINT8 *)pArrayArgsBuffer) + ui32NextOffset);
+		ui32NextOffset += psCacheOpQueueIN->ui32NumCacheOps * sizeof(PVRSRV_CACHE_OP);
+	}
+
+			/* Copy the data over */
+			if (psCacheOpQueueIN->ui32NumCacheOps * sizeof(PVRSRV_CACHE_OP) > 0)
+			{
+				if ( OSCopyFromUser(NULL, iuCacheOpInt, psCacheOpQueueIN->piuCacheOp, psCacheOpQueueIN->ui32NumCacheOps * sizeof(PVRSRV_CACHE_OP)) != PVRSRV_OK )
+				{
+					psCacheOpQueueOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
+
+					goto CacheOpQueue_exit;
+				}
+			}
+
+	/* Lock over handle lookup. */
+	LockHandle();
+
+
+
+
+
+	{
+		IMG_UINT32 i;
+
+		for (i=0;i<psCacheOpQueueIN->ui32NumCacheOps;i++)
+		{
+				{
+					/* Look up the address from the handle */
+					psCacheOpQueueOUT->eError =
+						PVRSRVLookupHandleUnlocked(psConnection->psHandleBase,
+											(void **) &psPMRInt[i],
+											hPMRInt2[i],
+											PVRSRV_HANDLE_TYPE_PHYSMEM_PMR,
+											IMG_TRUE);
+					if(psCacheOpQueueOUT->eError != PVRSRV_OK)
+					{
+						UnlockHandle();
+						goto CacheOpQueue_exit;
+					}
+				}
+		}
+	}
+	/* Release now we have looked up handles. */
+	UnlockHandle();
+
+	psCacheOpQueueOUT->eError =
+		CacheOpQueue(
+					psCacheOpQueueIN->ui32NumCacheOps,
+					psPMRInt,
+					uiOffsetInt,
+					uiSizeInt,
+					iuCacheOpInt,
+					&psCacheOpQueueOUT->ui32CacheOpSeqNum);
+
+
+
+
+CacheOpQueue_exit:
+
+	/* Lock over handle lookup cleanup. */
+	LockHandle();
+
+
+
+
+
+
+
+	if (hPMRInt2)
+	{
+		IMG_UINT32 i;
+
+		for (i=0;i<psCacheOpQueueIN->ui32NumCacheOps;i++)
+		{
+				{
+					/* Unreference the previously looked up handle */
+						if(psPMRInt[i])
+						{
+							PVRSRVReleaseHandleUnlocked(psConnection->psHandleBase,
+											hPMRInt2[i],
+											PVRSRV_HANDLE_TYPE_PHYSMEM_PMR);
+						}
+				}
+		}
+	}
+	/* Release now we have cleaned up look up handles. */
+	UnlockHandle();
+
+	/* Allocated space should be equal to the last updated offset */
+	PVR_ASSERT(ui32BufferSize == ui32NextOffset);
+
+#if defined(INTEGRITY_OS)
+	if(pArrayArgsBuffer)
+#else
+	if(!bHaveEnoughSpace && pArrayArgsBuffer)
+#endif
+		OSFreeMemNoStats(pArrayArgsBuffer);
+
+
+	return 0;
+}
+
+
+static IMG_INT
+PVRSRVBridgeCacheOpExec(IMG_UINT32 ui32DispatchTableEntry,
+					  PVRSRV_BRIDGE_IN_CACHEOPEXEC *psCacheOpExecIN,
+					  PVRSRV_BRIDGE_OUT_CACHEOPEXEC *psCacheOpExecOUT,
+					 CONNECTION_DATA *psConnection)
+{
+	IMG_HANDLE hPMR = psCacheOpExecIN->hPMR;
+	PMR * psPMRInt = NULL;
+
+
+
+
+
+
+
+	/* Lock over handle lookup. */
+	LockHandle();
+
+
+
+
+
+				{
+					/* Look up the address from the handle */
+					psCacheOpExecOUT->eError =
+						PVRSRVLookupHandleUnlocked(psConnection->psHandleBase,
+											(void **) &psPMRInt,
+											hPMR,
+											PVRSRV_HANDLE_TYPE_PHYSMEM_PMR,
+											IMG_TRUE);
+					if(psCacheOpExecOUT->eError != PVRSRV_OK)
+					{
+						UnlockHandle();
+						goto CacheOpExec_exit;
+					}
+				}
+	/* Release now we have looked up handles. */
+	UnlockHandle();
+
+	psCacheOpExecOUT->eError =
+		CacheOpExec(
+					psPMRInt,
+					psCacheOpExecIN->uiOffset,
+					psCacheOpExecIN->uiSize,
+					psCacheOpExecIN->iuCacheOp);
+
+
+
+
+CacheOpExec_exit:
+
+	/* Lock over handle lookup cleanup. */
+	LockHandle();
+
+
+
+
+
+
+				{
+					/* Unreference the previously looked up handle */
+						if(psPMRInt)
+						{
+							PVRSRVReleaseHandleUnlocked(psConnection->psHandleBase,
+											hPMR,
+											PVRSRV_HANDLE_TYPE_PHYSMEM_PMR);
+						}
+				}
+	/* Release now we have cleaned up look up handles. */
+	UnlockHandle();
+
+
+	return 0;
+}
+
+
+static IMG_INT
+PVRSRVBridgeCacheOpSetTimeline(IMG_UINT32 ui32DispatchTableEntry,
+					  PVRSRV_BRIDGE_IN_CACHEOPSETTIMELINE *psCacheOpSetTimelineIN,
+					  PVRSRV_BRIDGE_OUT_CACHEOPSETTIMELINE *psCacheOpSetTimelineOUT,
+					 CONNECTION_DATA *psConnection)
+{
+
+
+
+	PVR_UNREFERENCED_PARAMETER(psConnection);
+
+
+
+
+
+	psCacheOpSetTimelineOUT->eError =
+		CacheOpSetTimeline(
+					psCacheOpSetTimelineIN->i32OpTimeline);
+
+
+
+
+
+
+
+
+	return 0;
+}
+
+
+static IMG_INT
+PVRSRVBridgeCacheOpLog(IMG_UINT32 ui32DispatchTableEntry,
+					  PVRSRV_BRIDGE_IN_CACHEOPLOG *psCacheOpLogIN,
+					  PVRSRV_BRIDGE_OUT_CACHEOPLOG *psCacheOpLogOUT,
+					 CONNECTION_DATA *psConnection)
+{
+	IMG_HANDLE hPMR = psCacheOpLogIN->hPMR;
+	PMR * psPMRInt = NULL;
+
+
+
+
+
+
+
+	/* Lock over handle lookup. */
+	LockHandle();
+
+
+
+
+
+				{
+					/* Look up the address from the handle */
+					psCacheOpLogOUT->eError =
+						PVRSRVLookupHandleUnlocked(psConnection->psHandleBase,
+											(void **) &psPMRInt,
+											hPMR,
+											PVRSRV_HANDLE_TYPE_PHYSMEM_PMR,
+											IMG_TRUE);
+					if(psCacheOpLogOUT->eError != PVRSRV_OK)
+					{
+						UnlockHandle();
+						goto CacheOpLog_exit;
+					}
+				}
+	/* Release now we have looked up handles. */
+	UnlockHandle();
+
+	psCacheOpLogOUT->eError =
+		CacheOpLog(
+					psPMRInt,
+					psCacheOpLogIN->uiOffset,
+					psCacheOpLogIN->uiSize,
+					psCacheOpLogIN->i64QueuedTimeUs,
+					psCacheOpLogIN->i64ExecuteTimeUs,
+					psCacheOpLogIN->iuCacheOp);
+
+
+
+
+CacheOpLog_exit:
+
+	/* Lock over handle lookup cleanup. */
+	LockHandle();
+
+
+
+
+
+
+				{
+					/* Unreference the previously looked up handle */
+						if(psPMRInt)
+						{
+							PVRSRVReleaseHandleUnlocked(psConnection->psHandleBase,
+											hPMR,
+											PVRSRV_HANDLE_TYPE_PHYSMEM_PMR);
+						}
+				}
+	/* Release now we have cleaned up look up handles. */
+	UnlockHandle();
+
+
+	return 0;
+}
+
+
+static IMG_INT
+PVRSRVBridgeCacheOpGetLineSize(IMG_UINT32 ui32DispatchTableEntry,
+					  PVRSRV_BRIDGE_IN_CACHEOPGETLINESIZE *psCacheOpGetLineSizeIN,
+					  PVRSRV_BRIDGE_OUT_CACHEOPGETLINESIZE *psCacheOpGetLineSizeOUT,
+					 CONNECTION_DATA *psConnection)
+{
+
+
+
+	PVR_UNREFERENCED_PARAMETER(psConnection);
+	PVR_UNREFERENCED_PARAMETER(psCacheOpGetLineSizeIN);
+
+
+
+
+
+	psCacheOpGetLineSizeOUT->eError =
+		CacheOpGetLineSize(
+					&psCacheOpGetLineSizeOUT->ui32L1DataCacheLineSize);
+
+
+
+
+
+
+
+
+	return 0;
+}
+
+
+
+
+/* *************************************************************************** 
+ * Server bridge dispatch related glue 
+ */
+
+static IMG_BOOL bUseLock = IMG_TRUE;
+
+PVRSRV_ERROR InitCACHEBridge(void);
+PVRSRV_ERROR DeinitCACHEBridge(void);
+
+/*
+ * Register all CACHE functions with services
+ */
+PVRSRV_ERROR InitCACHEBridge(void)
+{
+
+	SetDispatchTableEntry(PVRSRV_BRIDGE_CACHE, PVRSRV_BRIDGE_CACHE_CACHEOPQUEUE, PVRSRVBridgeCacheOpQueue,
+					NULL, bUseLock);
+
+	SetDispatchTableEntry(PVRSRV_BRIDGE_CACHE, PVRSRV_BRIDGE_CACHE_CACHEOPEXEC, PVRSRVBridgeCacheOpExec,
+					NULL, bUseLock);
+
+	SetDispatchTableEntry(PVRSRV_BRIDGE_CACHE, PVRSRV_BRIDGE_CACHE_CACHEOPSETTIMELINE, PVRSRVBridgeCacheOpSetTimeline,
+					NULL, bUseLock);
+
+	SetDispatchTableEntry(PVRSRV_BRIDGE_CACHE, PVRSRV_BRIDGE_CACHE_CACHEOPLOG, PVRSRVBridgeCacheOpLog,
+					NULL, bUseLock);
+
+	SetDispatchTableEntry(PVRSRV_BRIDGE_CACHE, PVRSRV_BRIDGE_CACHE_CACHEOPGETLINESIZE, PVRSRVBridgeCacheOpGetLineSize,
+					NULL, bUseLock);
+
+
+	return PVRSRV_OK;
+}
+
+/*
+ * Unregister all cache functions with services
+ */
+PVRSRV_ERROR DeinitCACHEBridge(void)
+{
+	return PVRSRV_OK;
+}
diff --git a/drivers/staging/imgtec/rogue/generated/cachegeneric_bridge/server_cachegeneric_bridge.c b/drivers/staging/imgtec/rogue/generated/cachegeneric_bridge/server_cachegeneric_bridge.c
deleted file mode 100644
index 69f13b2..0000000
--- a/drivers/staging/imgtec/rogue/generated/cachegeneric_bridge/server_cachegeneric_bridge.c
+++ /dev/null
@@ -1,145 +0,0 @@
-/*************************************************************************/ /*!
-@File
-@Title          Server bridge for cachegeneric
-@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
-@Description    Implements the server side of the bridge for cachegeneric
-@License        Dual MIT/GPLv2
-
-The contents of this file are subject to the MIT license as set out below.
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-Alternatively, the contents of this file may be used under the terms of
-the GNU General Public License Version 2 ("GPL") in which case the provisions
-of GPL are applicable instead of those above.
-
-If you wish to allow use of your version of this file only under the terms of
-GPL, and not to allow others to use your version of this file under the terms
-of the MIT license, indicate your decision by deleting the provisions above
-and replace them with the notice and other provisions required by GPL as set
-out in the file called "GPL-COPYING" included in this distribution. If you do
-not delete the provisions above, a recipient may use your version of this file
-under the terms of either the MIT license or GPL.
-
-This License is also included in this distribution in the file called
-"MIT-COPYING".
-
-EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
-PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
-BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
-PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
-COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
-IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
-CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-*/ /**************************************************************************/
-
-#include <stddef.h>
-#include <asm/uaccess.h>
-
-#include "img_defs.h"
-
-#include "cache_generic.h"
-
-
-#include "common_cachegeneric_bridge.h"
-
-#include "allocmem.h"
-#include "pvr_debug.h"
-#include "connection_server.h"
-#include "pvr_bridge.h"
-#include "rgx_bridge.h"
-#include "srvcore.h"
-#include "handle.h"
-
-#include <linux/slab.h>
-
-
-
-
-/* ***************************************************************************
- * Server-side bridge entry points
- */
- 
-static IMG_INT
-PVRSRVBridgeCacheOpQueue(IMG_UINT32 ui32DispatchTableEntry,
-					  PVRSRV_BRIDGE_IN_CACHEOPQUEUE *psCacheOpQueueIN,
-					  PVRSRV_BRIDGE_OUT_CACHEOPQUEUE *psCacheOpQueueOUT,
-					 CONNECTION_DATA *psConnection)
-{
-	PMR * psPMRInt = NULL;
-
-
-
-
-
-
-
-				{
-					/* Look up the address from the handle */
-					psCacheOpQueueOUT->eError =
-						PVRSRVLookupHandle(psConnection->psHandleBase,
-											(void **) &psPMRInt,
-											psCacheOpQueueIN->hPMR,
-											PVRSRV_HANDLE_TYPE_PHYSMEM_PMR);
-					if(psCacheOpQueueOUT->eError != PVRSRV_OK)
-					{
-						goto CacheOpQueue_exit;
-					}
-				}
-
-
-	psCacheOpQueueOUT->eError =
-		CacheOpQueue(
-					psPMRInt,
-					psCacheOpQueueIN->uiOffset,
-					psCacheOpQueueIN->uiSize,
-					psCacheOpQueueIN->iuCacheOp);
-
-
-
-
-CacheOpQueue_exit:
-
-	return 0;
-}
-
-
-
-/* *************************************************************************** 
- * Server bridge dispatch related glue 
- */
-
-static IMG_BOOL bUseLock = IMG_TRUE;
-
-PVRSRV_ERROR InitCACHEGENERICBridge(void);
-PVRSRV_ERROR DeinitCACHEGENERICBridge(void);
-
-/*
- * Register all CACHEGENERIC functions with services
- */
-PVRSRV_ERROR InitCACHEGENERICBridge(void)
-{
-
-	SetDispatchTableEntry(PVRSRV_BRIDGE_CACHEGENERIC, PVRSRV_BRIDGE_CACHEGENERIC_CACHEOPQUEUE, PVRSRVBridgeCacheOpQueue,
-					NULL, bUseLock);
-
-
-	return PVRSRV_OK;
-}
-
-/*
- * Unregister all cachegeneric functions with services
- */
-PVRSRV_ERROR DeinitCACHEGENERICBridge(void)
-{
-	return PVRSRV_OK;
-}
-
diff --git a/drivers/staging/imgtec/rogue/generated/cmm_bridge/common_cmm_bridge.h b/drivers/staging/imgtec/rogue/generated/cmm_bridge/common_cmm_bridge.h
index 79ce42a..4ca9bc5 100644
--- a/drivers/staging/imgtec/rogue/generated/cmm_bridge/common_cmm_bridge.h
+++ b/drivers/staging/imgtec/rogue/generated/cmm_bridge/common_cmm_bridge.h
@@ -2,8 +2,8 @@
 @File
 @Title          Common bridge header for cmm
 @Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
-@Description    Declares common defines and structures that are used by both
-                the client and sever side of the bridge for cmm
+@Description    Declares common defines and structures used by both the client
+                and server side of the bridge for cmm
 @License        Dual MIT/GPLv2
 
 The contents of this file are subject to the MIT license as set out below.
@@ -45,6 +45,8 @@
 #ifndef COMMON_CMM_BRIDGE_H
 #define COMMON_CMM_BRIDGE_H
 
+#include <powervr/mem_types.h>
+
 #include "img_types.h"
 #include "pvrsrv_error.h"
 
diff --git a/drivers/staging/imgtec/rogue/generated/cmm_bridge/server_cmm_bridge.c b/drivers/staging/imgtec/rogue/generated/cmm_bridge/server_cmm_bridge.c
index 3895dae..d18c691 100644
--- a/drivers/staging/imgtec/rogue/generated/cmm_bridge/server_cmm_bridge.c
+++ b/drivers/staging/imgtec/rogue/generated/cmm_bridge/server_cmm_bridge.c
@@ -64,6 +64,9 @@
 
 
 
+#if !defined(EXCLUDE_CMM_BRIDGE)
+
+
 
 /* ***************************************************************************
  * Server-side bridge entry points
@@ -75,7 +78,9 @@
 					  PVRSRV_BRIDGE_OUT_DEVMEMINTEXPORTCTX *psDevmemIntExportCtxOUT,
 					 CONNECTION_DATA *psConnection)
 {
+	IMG_HANDLE hContext = psDevmemIntExportCtxIN->hContext;
 	DEVMEMINT_CTX * psContextInt = NULL;
+	IMG_HANDLE hPMR = psDevmemIntExportCtxIN->hPMR;
 	PMR * psPMRInt = NULL;
 	DEVMEMINT_CTX_EXPORT * psContextExportInt = NULL;
 
@@ -83,38 +88,50 @@
 
 
 
-	PMRLock();
+
+
+	/* Lock over handle lookup. */
+	LockHandle();
+
+
+
 
 
 				{
 					/* Look up the address from the handle */
 					psDevmemIntExportCtxOUT->eError =
-						PVRSRVLookupHandle(psConnection->psHandleBase,
+						PVRSRVLookupHandleUnlocked(psConnection->psHandleBase,
 											(void **) &psContextInt,
-											psDevmemIntExportCtxIN->hContext,
-											PVRSRV_HANDLE_TYPE_DEVMEMINT_CTX);
+											hContext,
+											PVRSRV_HANDLE_TYPE_DEVMEMINT_CTX,
+											IMG_TRUE);
 					if(psDevmemIntExportCtxOUT->eError != PVRSRV_OK)
 					{
-						PMRUnlock();
+						UnlockHandle();
 						goto DevmemIntExportCtx_exit;
 					}
 				}
 
 
+
+
+
 				{
 					/* Look up the address from the handle */
 					psDevmemIntExportCtxOUT->eError =
-						PVRSRVLookupHandle(psConnection->psHandleBase,
+						PVRSRVLookupHandleUnlocked(psConnection->psHandleBase,
 											(void **) &psPMRInt,
-											psDevmemIntExportCtxIN->hPMR,
-											PVRSRV_HANDLE_TYPE_PHYSMEM_PMR);
+											hPMR,
+											PVRSRV_HANDLE_TYPE_PHYSMEM_PMR,
+											IMG_TRUE);
 					if(psDevmemIntExportCtxOUT->eError != PVRSRV_OK)
 					{
-						PMRUnlock();
+						UnlockHandle();
 						goto DevmemIntExportCtx_exit;
 					}
 				}
-
+	/* Release now we have looked up handles. */
+	UnlockHandle();
 
 	psDevmemIntExportCtxOUT->eError =
 		DevmemIntExportCtx(
@@ -124,13 +141,18 @@
 	/* Exit early if bridged call fails */
 	if(psDevmemIntExportCtxOUT->eError != PVRSRV_OK)
 	{
-		PMRUnlock();
 		goto DevmemIntExportCtx_exit;
 	}
-	PMRUnlock();
+
+	/* Lock over handle creation. */
+	LockHandle();
 
 
-	psDevmemIntExportCtxOUT->eError = PVRSRVAllocHandle(psConnection->psHandleBase,
+
+
+
+	psDevmemIntExportCtxOUT->eError = PVRSRVAllocHandleUnlocked(psConnection->psHandleBase,
+
 							&psDevmemIntExportCtxOUT->hContextExport,
 							(void *) psContextExportInt,
 							PVRSRV_HANDLE_TYPE_DEVMEMINT_CTX_EXPORT,
@@ -138,13 +160,51 @@
 							,(PFN_HANDLE_RELEASE)&DevmemIntUnexportCtx);
 	if (psDevmemIntExportCtxOUT->eError != PVRSRV_OK)
 	{
+		UnlockHandle();
 		goto DevmemIntExportCtx_exit;
 	}
 
+	/* Release now we have created handles. */
+	UnlockHandle();
 
 
 
 DevmemIntExportCtx_exit:
+
+	/* Lock over handle lookup cleanup. */
+	LockHandle();
+
+
+
+
+
+
+				{
+					/* Unreference the previously looked up handle */
+						if(psContextInt)
+						{
+							PVRSRVReleaseHandleUnlocked(psConnection->psHandleBase,
+											hContext,
+											PVRSRV_HANDLE_TYPE_DEVMEMINT_CTX);
+						}
+				}
+
+
+
+
+
+				{
+					/* Unreference the previously looked up handle */
+						if(psPMRInt)
+						{
+							PVRSRVReleaseHandleUnlocked(psConnection->psHandleBase,
+											hPMR,
+											PVRSRV_HANDLE_TYPE_PHYSMEM_PMR);
+						}
+				}
+	/* Release now we have cleaned up look up handles. */
+	UnlockHandle();
+
 	if (psDevmemIntExportCtxOUT->eError != PVRSRV_OK)
 	{
 		if (psContextExportInt)
@@ -157,6 +217,7 @@
 	return 0;
 }
 
+
 static IMG_INT
 PVRSRVBridgeDevmemIntUnexportCtx(IMG_UINT32 ui32DispatchTableEntry,
 					  PVRSRV_BRIDGE_IN_DEVMEMINTUNEXPORTCTX *psDevmemIntUnexportCtxIN,
@@ -168,60 +229,87 @@
 
 
 
-	PMRLock();
+
+
+
+
+	/* Lock over handle destruction. */
+	LockHandle();
+
 
 
 
 
 	psDevmemIntUnexportCtxOUT->eError =
-		PVRSRVReleaseHandle(psConnection->psHandleBase,
+		PVRSRVReleaseHandleUnlocked(psConnection->psHandleBase,
 					(IMG_HANDLE) psDevmemIntUnexportCtxIN->hContextExport,
 					PVRSRV_HANDLE_TYPE_DEVMEMINT_CTX_EXPORT);
-	if ((psDevmemIntUnexportCtxOUT->eError != PVRSRV_OK) && (psDevmemIntUnexportCtxOUT->eError != PVRSRV_ERROR_RETRY))
+	if ((psDevmemIntUnexportCtxOUT->eError != PVRSRV_OK) &&
+	    (psDevmemIntUnexportCtxOUT->eError != PVRSRV_ERROR_RETRY))
 	{
+		PVR_DPF((PVR_DBG_ERROR,
+		        "PVRSRVBridgeDevmemIntUnexportCtx: %s",
+		        PVRSRVGetErrorStringKM(psDevmemIntUnexportCtxOUT->eError)));
 		PVR_ASSERT(0);
-		PMRUnlock();
+		UnlockHandle();
 		goto DevmemIntUnexportCtx_exit;
 	}
 
-	PMRUnlock();
+	/* Release now we have destroyed handles. */
+	UnlockHandle();
+
 
 
 DevmemIntUnexportCtx_exit:
 
+
+
+
 	return 0;
 }
 
+
 static IMG_INT
 PVRSRVBridgeDevmemIntAcquireRemoteCtx(IMG_UINT32 ui32DispatchTableEntry,
 					  PVRSRV_BRIDGE_IN_DEVMEMINTACQUIREREMOTECTX *psDevmemIntAcquireRemoteCtxIN,
 					  PVRSRV_BRIDGE_OUT_DEVMEMINTACQUIREREMOTECTX *psDevmemIntAcquireRemoteCtxOUT,
 					 CONNECTION_DATA *psConnection)
 {
+	IMG_HANDLE hPMR = psDevmemIntAcquireRemoteCtxIN->hPMR;
 	PMR * psPMRInt = NULL;
 	DEVMEMINT_CTX * psContextInt = NULL;
 	IMG_HANDLE hPrivDataInt = NULL;
 
 
 
+
+
 	psDevmemIntAcquireRemoteCtxOUT->hContext = NULL;
 
 
+	/* Lock over handle lookup. */
+	LockHandle();
+
+
+
 
 
 				{
 					/* Look up the address from the handle */
 					psDevmemIntAcquireRemoteCtxOUT->eError =
-						PVRSRVLookupHandle(psConnection->psHandleBase,
+						PVRSRVLookupHandleUnlocked(psConnection->psHandleBase,
 											(void **) &psPMRInt,
-											psDevmemIntAcquireRemoteCtxIN->hPMR,
-											PVRSRV_HANDLE_TYPE_PHYSMEM_PMR);
+											hPMR,
+											PVRSRV_HANDLE_TYPE_PHYSMEM_PMR,
+											IMG_TRUE);
 					if(psDevmemIntAcquireRemoteCtxOUT->eError != PVRSRV_OK)
 					{
+						UnlockHandle();
 						goto DevmemIntAcquireRemoteCtx_exit;
 					}
 				}
-
+	/* Release now we have looked up handles. */
+	UnlockHandle();
 
 	psDevmemIntAcquireRemoteCtxOUT->eError =
 		DevmemIntAcquireRemoteCtx(
@@ -234,8 +322,15 @@
 		goto DevmemIntAcquireRemoteCtx_exit;
 	}
 
+	/* Lock over handle creation. */
+	LockHandle();
 
-	psDevmemIntAcquireRemoteCtxOUT->eError = PVRSRVAllocHandle(psConnection->psHandleBase,
+
+
+
+
+	psDevmemIntAcquireRemoteCtxOUT->eError = PVRSRVAllocHandleUnlocked(psConnection->psHandleBase,
+
 							&psDevmemIntAcquireRemoteCtxOUT->hContext,
 							(void *) psContextInt,
 							PVRSRV_HANDLE_TYPE_DEVMEMINT_CTX,
@@ -243,11 +338,17 @@
 							,(PFN_HANDLE_RELEASE)&DevmemIntCtxDestroy);
 	if (psDevmemIntAcquireRemoteCtxOUT->eError != PVRSRV_OK)
 	{
+		UnlockHandle();
 		goto DevmemIntAcquireRemoteCtx_exit;
 	}
 
 
-	psDevmemIntAcquireRemoteCtxOUT->eError = PVRSRVAllocSubHandle(psConnection->psHandleBase,
+
+
+
+
+	psDevmemIntAcquireRemoteCtxOUT->eError = PVRSRVAllocSubHandleUnlocked(psConnection->psHandleBase,
+
 							&psDevmemIntAcquireRemoteCtxOUT->hPrivData,
 							(void *) hPrivDataInt,
 							PVRSRV_HANDLE_TYPE_DEV_PRIV_DATA,
@@ -255,22 +356,56 @@
 							,psDevmemIntAcquireRemoteCtxOUT->hContext);
 	if (psDevmemIntAcquireRemoteCtxOUT->eError != PVRSRV_OK)
 	{
+		UnlockHandle();
 		goto DevmemIntAcquireRemoteCtx_exit;
 	}
 
+	/* Release now we have created handles. */
+	UnlockHandle();
 
 
 
 DevmemIntAcquireRemoteCtx_exit:
+
+	/* Lock over handle lookup cleanup. */
+	LockHandle();
+
+
+
+
+
+
+				{
+					/* Unreference the previously looked up handle */
+						if(psPMRInt)
+						{
+							PVRSRVReleaseHandleUnlocked(psConnection->psHandleBase,
+											hPMR,
+											PVRSRV_HANDLE_TYPE_PHYSMEM_PMR);
+						}
+				}
+	/* Release now we have cleaned up look up handles. */
+	UnlockHandle();
+
 	if (psDevmemIntAcquireRemoteCtxOUT->eError != PVRSRV_OK)
 	{
+		/* Lock over handle creation cleanup. */
+		LockHandle();
 		if (psDevmemIntAcquireRemoteCtxOUT->hContext)
 		{
-			PVRSRV_ERROR eError = PVRSRVReleaseHandle(psConnection->psHandleBase,
+
+
+			PVRSRV_ERROR eError = PVRSRVReleaseHandleUnlocked(psConnection->psHandleBase,
 						(IMG_HANDLE) psDevmemIntAcquireRemoteCtxOUT->hContext,
 						PVRSRV_HANDLE_TYPE_DEVMEMINT_CTX);
-
-			/* Releasing the handle should free/destroy/release the resource. This should never fail... */
+			if ((eError != PVRSRV_OK) && (eError != PVRSRV_ERROR_RETRY))
+			{
+				PVR_DPF((PVR_DBG_ERROR,
+				        "PVRSRVBridgeDevmemIntAcquireRemoteCtx: %s",
+				        PVRSRVGetErrorStringKM(eError)));
+			}
+			/* Releasing the handle should free/destroy/release the resource.
+			 * This should never fail... */
 			PVR_ASSERT((eError == PVRSRV_OK) || (eError == PVRSRV_ERROR_RETRY));
 
 			/* Avoid freeing/destroying/releasing the resource a second time below */
@@ -278,6 +413,8 @@
 		}
 
 
+		/* Release now we have cleaned up creation handles. */
+		UnlockHandle();
 		if (psContextInt)
 		{
 			DevmemIntCtxDestroy(psContextInt);
@@ -290,12 +427,15 @@
 
 
 
+
 /* *************************************************************************** 
  * Server bridge dispatch related glue 
  */
 
 static IMG_BOOL bUseLock = IMG_TRUE;
+#endif /* EXCLUDE_CMM_BRIDGE */
 
+#if !defined(EXCLUDE_CMM_BRIDGE)
 PVRSRV_ERROR InitCMMBridge(void);
 PVRSRV_ERROR DeinitCMMBridge(void);
 
@@ -325,4 +465,14 @@
 {
 	return PVRSRV_OK;
 }
+#else /* EXCLUDE_CMM_BRIDGE */
+/* This bridge is conditional on EXCLUDE_CMM_BRIDGE - when defined,
+ * do not populate the dispatch table with its functions
+ */
+#define InitCMMBridge() \
+	PVRSRV_OK
 
+#define DeinitCMMBridge() \
+	PVRSRV_OK
+
+#endif /* EXCLUDE_CMM_BRIDGE */
diff --git a/drivers/staging/imgtec/rogue/generated/dc_bridge/common_dc_bridge.h b/drivers/staging/imgtec/rogue/generated/dc_bridge/common_dc_bridge.h
index af3e13b..727f7a5 100644
--- a/drivers/staging/imgtec/rogue/generated/dc_bridge/common_dc_bridge.h
+++ b/drivers/staging/imgtec/rogue/generated/dc_bridge/common_dc_bridge.h
@@ -2,8 +2,8 @@
 @File
 @Title          Common bridge header for dc
 @Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
-@Description    Declares common defines and structures that are used by both
-                the client and sever side of the bridge for dc
+@Description    Declares common defines and structures used by both the client
+                and server side of the bridge for dc
 @License        Dual MIT/GPLv2
 
 The contents of this file are subject to the MIT license as set out below.
@@ -45,12 +45,13 @@
 #ifndef COMMON_DC_BRIDGE_H
 #define COMMON_DC_BRIDGE_H
 
+#include <powervr/mem_types.h>
+
 #include "img_types.h"
 #include "pvrsrv_error.h"
 
 #include "pvrsrv_surface.h"
 #include "dc_external.h"
-#include "dc_common.h"
 
 
 #define PVRSRV_BRIDGE_DC_CMD_FIRST			0
diff --git a/drivers/staging/imgtec/rogue/generated/dc_bridge/server_dc_bridge.c b/drivers/staging/imgtec/rogue/generated/dc_bridge/server_dc_bridge.c
index f463709..5091cce 100644
--- a/drivers/staging/imgtec/rogue/generated/dc_bridge/server_dc_bridge.c
+++ b/drivers/staging/imgtec/rogue/generated/dc_bridge/server_dc_bridge.c
@@ -64,6 +64,8 @@
 
 
 
+
+
 /* ***************************************************************************
  * Server-side bridge entry points
  */
@@ -75,6 +77,8 @@
 					 CONNECTION_DATA *psConnection)
 {
 
+
+
 	PVR_UNREFERENCED_PARAMETER(psConnection);
 	PVR_UNREFERENCED_PARAMETER(psDCDevicesQueryCountIN);
 
@@ -82,7 +86,6 @@
 
 
 
-
 	psDCDevicesQueryCountOUT->eError =
 		DCDevicesQueryCount(
 					&psDCDevicesQueryCountOUT->ui32DeviceCount);
@@ -91,9 +94,13 @@
 
 
 
+
+
+
 	return 0;
 }
 
+
 static IMG_INT
 PVRSRVBridgeDCDevicesEnumerate(IMG_UINT32 ui32DispatchTableEntry,
 					  PVRSRV_BRIDGE_IN_DCDEVICESENUMERATE *psDCDevicesEnumerateIN,
@@ -102,50 +109,95 @@
 {
 	IMG_UINT32 *pui32DeviceIndexInt = NULL;
 
-	PVR_UNREFERENCED_PARAMETER(psConnection);
+	IMG_UINT32 ui32NextOffset = 0;
+	IMG_BYTE   *pArrayArgsBuffer = NULL;
+#if !defined(INTEGRITY_OS)
+	IMG_BOOL bHaveEnoughSpace = IMG_FALSE;
+#endif
+
+	IMG_UINT32 ui32BufferSize = 
+			(psDCDevicesEnumerateIN->ui32DeviceArraySize * sizeof(IMG_UINT32)) +
+			0;
+
+
 
 	psDCDevicesEnumerateOUT->pui32DeviceIndex = psDCDevicesEnumerateIN->pui32DeviceIndex;
 
 
+	if (ui32BufferSize != 0)
+	{
+#if !defined(INTEGRITY_OS)
+		/* Try to use remainder of input buffer for copies if possible, word-aligned for safety. */
+		IMG_UINT32 ui32InBufferOffset = PVR_ALIGN(sizeof(*psDCDevicesEnumerateIN), sizeof(unsigned long));
+		IMG_UINT32 ui32InBufferExcessSize = ui32InBufferOffset >= PVRSRV_MAX_BRIDGE_IN_SIZE ? 0 :
+			PVRSRV_MAX_BRIDGE_IN_SIZE - ui32InBufferOffset;
+
+		bHaveEnoughSpace = ui32BufferSize <= ui32InBufferExcessSize;
+		if (bHaveEnoughSpace)
+		{
+			IMG_BYTE *pInputBuffer = (IMG_BYTE *)psDCDevicesEnumerateIN;
+
+			pArrayArgsBuffer = &pInputBuffer[ui32InBufferOffset];		}
+		else
+#endif
+		{
+			pArrayArgsBuffer = OSAllocMemNoStats(ui32BufferSize);
+
+			if(!pArrayArgsBuffer)
+			{
+				psDCDevicesEnumerateOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
+				goto DCDevicesEnumerate_exit;
+			}
+		}
+	}
+
 	if (psDCDevicesEnumerateIN->ui32DeviceArraySize != 0)
 	{
-		pui32DeviceIndexInt = OSAllocMemNoStats(psDCDevicesEnumerateIN->ui32DeviceArraySize * sizeof(IMG_UINT32));
-		if (!pui32DeviceIndexInt)
-		{
-			psDCDevicesEnumerateOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
-	
-			goto DCDevicesEnumerate_exit;
-		}
+		pui32DeviceIndexInt = (IMG_UINT32*)(((IMG_UINT8 *)pArrayArgsBuffer) + ui32NextOffset);
+		ui32NextOffset += psDCDevicesEnumerateIN->ui32DeviceArraySize * sizeof(IMG_UINT32);
 	}
 
 
 
-
 	psDCDevicesEnumerateOUT->eError =
-		DCDevicesEnumerate(
+		DCDevicesEnumerate(psConnection, OSGetDevData(psConnection),
 					psDCDevicesEnumerateIN->ui32DeviceArraySize,
 					&psDCDevicesEnumerateOUT->ui32DeviceCount,
 					pui32DeviceIndexInt);
 
 
 
-	if ( !OSAccessOK(PVR_VERIFY_WRITE, (void*) psDCDevicesEnumerateOUT->pui32DeviceIndex, (psDCDevicesEnumerateOUT->ui32DeviceCount * sizeof(IMG_UINT32)))
-		|| (OSCopyToUser(NULL, psDCDevicesEnumerateOUT->pui32DeviceIndex, pui32DeviceIndexInt,
-		(psDCDevicesEnumerateOUT->ui32DeviceCount * sizeof(IMG_UINT32))) != PVRSRV_OK) )
+	if ((psDCDevicesEnumerateOUT->ui32DeviceCount * sizeof(IMG_UINT32)) > 0)
 	{
-		psDCDevicesEnumerateOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
+		if ( OSCopyToUser(NULL, psDCDevicesEnumerateOUT->pui32DeviceIndex, pui32DeviceIndexInt,
+			(psDCDevicesEnumerateOUT->ui32DeviceCount * sizeof(IMG_UINT32))) != PVRSRV_OK )
+		{
+			psDCDevicesEnumerateOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
 
-		goto DCDevicesEnumerate_exit;
+			goto DCDevicesEnumerate_exit;
+		}
 	}
 
 
 DCDevicesEnumerate_exit:
-	if (pui32DeviceIndexInt)
-		OSFreeMemNoStats(pui32DeviceIndexInt);
+
+
+
+	/* Allocated space should be equal to the last updated offset */
+	PVR_ASSERT(ui32BufferSize == ui32NextOffset);
+
+#if defined(INTEGRITY_OS)
+	if(pArrayArgsBuffer)
+#else
+	if(!bHaveEnoughSpace && pArrayArgsBuffer)
+#endif
+		OSFreeMemNoStats(pArrayArgsBuffer);
+
 
 	return 0;
 }
 
+
 static IMG_INT
 PVRSRVBridgeDCDeviceAcquire(IMG_UINT32 ui32DispatchTableEntry,
 					  PVRSRV_BRIDGE_IN_DCDEVICEACQUIRE *psDCDeviceAcquireIN,
@@ -160,8 +212,9 @@
 
 
 
+
 	psDCDeviceAcquireOUT->eError =
-		DCDeviceAcquire(
+		DCDeviceAcquire(psConnection, OSGetDevData(psConnection),
 					psDCDeviceAcquireIN->ui32DeviceIndex,
 					&psDeviceInt);
 	/* Exit early if bridged call fails */
@@ -170,8 +223,15 @@
 		goto DCDeviceAcquire_exit;
 	}
 
+	/* Lock over handle creation. */
+	LockHandle();
 
-	psDCDeviceAcquireOUT->eError = PVRSRVAllocHandle(psConnection->psHandleBase,
+
+
+
+
+	psDCDeviceAcquireOUT->eError = PVRSRVAllocHandleUnlocked(psConnection->psHandleBase,
+
 							&psDCDeviceAcquireOUT->hDevice,
 							(void *) psDeviceInt,
 							PVRSRV_HANDLE_TYPE_DC_DEVICE,
@@ -179,13 +239,19 @@
 							,(PFN_HANDLE_RELEASE)&DCDeviceRelease);
 	if (psDCDeviceAcquireOUT->eError != PVRSRV_OK)
 	{
+		UnlockHandle();
 		goto DCDeviceAcquire_exit;
 	}
 
+	/* Release now we have created handles. */
+	UnlockHandle();
 
 
 
 DCDeviceAcquire_exit:
+
+
+
 	if (psDCDeviceAcquireOUT->eError != PVRSRV_OK)
 	{
 		if (psDeviceInt)
@@ -198,6 +264,7 @@
 	return 0;
 }
 
+
 static IMG_INT
 PVRSRVBridgeDCDeviceRelease(IMG_UINT32 ui32DispatchTableEntry,
 					  PVRSRV_BRIDGE_IN_DCDEVICERELEASE *psDCDeviceReleaseIN,
@@ -213,29 +280,49 @@
 
 
 
+	/* Lock over handle destruction. */
+	LockHandle();
+
+
+
+
+
 	psDCDeviceReleaseOUT->eError =
-		PVRSRVReleaseHandle(psConnection->psHandleBase,
+		PVRSRVReleaseHandleUnlocked(psConnection->psHandleBase,
 					(IMG_HANDLE) psDCDeviceReleaseIN->hDevice,
 					PVRSRV_HANDLE_TYPE_DC_DEVICE);
-	if ((psDCDeviceReleaseOUT->eError != PVRSRV_OK) && (psDCDeviceReleaseOUT->eError != PVRSRV_ERROR_RETRY))
+	if ((psDCDeviceReleaseOUT->eError != PVRSRV_OK) &&
+	    (psDCDeviceReleaseOUT->eError != PVRSRV_ERROR_RETRY))
 	{
+		PVR_DPF((PVR_DBG_ERROR,
+		        "PVRSRVBridgeDCDeviceRelease: %s",
+		        PVRSRVGetErrorStringKM(psDCDeviceReleaseOUT->eError)));
 		PVR_ASSERT(0);
+		UnlockHandle();
 		goto DCDeviceRelease_exit;
 	}
 
+	/* Release now we have destroyed handles. */
+	UnlockHandle();
+
 
 
 DCDeviceRelease_exit:
 
+
+
+
 	return 0;
 }
 
+
 static IMG_INT
 PVRSRVBridgeDCGetInfo(IMG_UINT32 ui32DispatchTableEntry,
 					  PVRSRV_BRIDGE_IN_DCGETINFO *psDCGetInfoIN,
 					  PVRSRV_BRIDGE_OUT_DCGETINFO *psDCGetInfoOUT,
 					 CONNECTION_DATA *psConnection)
 {
+	IMG_HANDLE hDevice = psDCGetInfoIN->hDevice;
 	DC_DEVICE * psDeviceInt = NULL;
 
 
@@ -244,19 +331,29 @@
 
 
 
+	/* Lock over handle lookup. */
+	LockHandle();
+
+
+
+
+
 				{
 					/* Look up the address from the handle */
 					psDCGetInfoOUT->eError =
-						PVRSRVLookupHandle(psConnection->psHandleBase,
+						PVRSRVLookupHandleUnlocked(psConnection->psHandleBase,
 											(void **) &psDeviceInt,
-											psDCGetInfoIN->hDevice,
-											PVRSRV_HANDLE_TYPE_DC_DEVICE);
+											hDevice,
+											PVRSRV_HANDLE_TYPE_DC_DEVICE,
+											IMG_TRUE);
 					if(psDCGetInfoOUT->eError != PVRSRV_OK)
 					{
+						UnlockHandle();
 						goto DCGetInfo_exit;
 					}
 				}
-
+	/* Release now we have looked up handles. */
+	UnlockHandle();
 
 	psDCGetInfoOUT->eError =
 		DCGetInfo(
@@ -268,15 +365,38 @@
 
 DCGetInfo_exit:
 
+	/* Lock over handle lookup cleanup. */
+	LockHandle();
+
+
+
+
+
+
+				{
+					/* Unreference the previously looked up handle */
+						if(psDeviceInt)
+						{
+							PVRSRVReleaseHandleUnlocked(psConnection->psHandleBase,
+											hDevice,
+											PVRSRV_HANDLE_TYPE_DC_DEVICE);
+						}
+				}
+	/* Release now we have cleaned up look up handles. */
+	UnlockHandle();
+
+
 	return 0;
 }
 
+
 static IMG_INT
 PVRSRVBridgeDCPanelQueryCount(IMG_UINT32 ui32DispatchTableEntry,
 					  PVRSRV_BRIDGE_IN_DCPANELQUERYCOUNT *psDCPanelQueryCountIN,
 					  PVRSRV_BRIDGE_OUT_DCPANELQUERYCOUNT *psDCPanelQueryCountOUT,
 					 CONNECTION_DATA *psConnection)
 {
+	IMG_HANDLE hDevice = psDCPanelQueryCountIN->hDevice;
 	DC_DEVICE * psDeviceInt = NULL;
 
 
@@ -285,19 +405,29 @@
 
 
 
+	/* Lock over handle lookup. */
+	LockHandle();
+
+
+
+
+
 				{
 					/* Look up the address from the handle */
 					psDCPanelQueryCountOUT->eError =
-						PVRSRVLookupHandle(psConnection->psHandleBase,
+						PVRSRVLookupHandleUnlocked(psConnection->psHandleBase,
 											(void **) &psDeviceInt,
-											psDCPanelQueryCountIN->hDevice,
-											PVRSRV_HANDLE_TYPE_DC_DEVICE);
+											hDevice,
+											PVRSRV_HANDLE_TYPE_DC_DEVICE,
+											IMG_TRUE);
 					if(psDCPanelQueryCountOUT->eError != PVRSRV_OK)
 					{
+						UnlockHandle();
 						goto DCPanelQueryCount_exit;
 					}
 				}
-
+	/* Release now we have looked up handles. */
+	UnlockHandle();
 
 	psDCPanelQueryCountOUT->eError =
 		DCPanelQueryCount(
@@ -309,49 +439,113 @@
 
 DCPanelQueryCount_exit:
 
+	/* Lock over handle lookup cleanup. */
+	LockHandle();
+
+
+
+
+
+
+				{
+					/* Unreference the previously looked up handle */
+						if(psDeviceInt)
+						{
+							PVRSRVReleaseHandleUnlocked(psConnection->psHandleBase,
+											hDevice,
+											PVRSRV_HANDLE_TYPE_DC_DEVICE);
+						}
+				}
+	/* Release now we have cleaned up look up handles. */
+	UnlockHandle();
+
+
 	return 0;
 }
 
+
 static IMG_INT
 PVRSRVBridgeDCPanelQuery(IMG_UINT32 ui32DispatchTableEntry,
 					  PVRSRV_BRIDGE_IN_DCPANELQUERY *psDCPanelQueryIN,
 					  PVRSRV_BRIDGE_OUT_DCPANELQUERY *psDCPanelQueryOUT,
 					 CONNECTION_DATA *psConnection)
 {
+	IMG_HANDLE hDevice = psDCPanelQueryIN->hDevice;
 	DC_DEVICE * psDeviceInt = NULL;
 	PVRSRV_PANEL_INFO *psPanelInfoInt = NULL;
 
+	IMG_UINT32 ui32NextOffset = 0;
+	IMG_BYTE   *pArrayArgsBuffer = NULL;
+#if !defined(INTEGRITY_OS)
+	IMG_BOOL bHaveEnoughSpace = IMG_FALSE;
+#endif
+
+	IMG_UINT32 ui32BufferSize = 
+			(psDCPanelQueryIN->ui32PanelsArraySize * sizeof(PVRSRV_PANEL_INFO)) +
+			0;
+
+
 
 	psDCPanelQueryOUT->psPanelInfo = psDCPanelQueryIN->psPanelInfo;
 
 
-	if (psDCPanelQueryIN->ui32PanelsArraySize != 0)
+	if (ui32BufferSize != 0)
 	{
-		psPanelInfoInt = OSAllocMemNoStats(psDCPanelQueryIN->ui32PanelsArraySize * sizeof(PVRSRV_PANEL_INFO));
-		if (!psPanelInfoInt)
+#if !defined(INTEGRITY_OS)
+		/* Try to use remainder of input buffer for copies if possible, word-aligned for safety. */
+		IMG_UINT32 ui32InBufferOffset = PVR_ALIGN(sizeof(*psDCPanelQueryIN), sizeof(unsigned long));
+		IMG_UINT32 ui32InBufferExcessSize = ui32InBufferOffset >= PVRSRV_MAX_BRIDGE_IN_SIZE ? 0 :
+			PVRSRV_MAX_BRIDGE_IN_SIZE - ui32InBufferOffset;
+
+		bHaveEnoughSpace = ui32BufferSize <= ui32InBufferExcessSize;
+		if (bHaveEnoughSpace)
 		{
-			psDCPanelQueryOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
-	
-			goto DCPanelQuery_exit;
+			IMG_BYTE *pInputBuffer = (IMG_BYTE *)psDCPanelQueryIN;
+
+			pArrayArgsBuffer = &pInputBuffer[ui32InBufferOffset];		}
+		else
+#endif
+		{
+			pArrayArgsBuffer = OSAllocMemNoStats(ui32BufferSize);
+
+			if(!pArrayArgsBuffer)
+			{
+				psDCPanelQueryOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
+				goto DCPanelQuery_exit;
+			}
 		}
 	}
 
+	if (psDCPanelQueryIN->ui32PanelsArraySize != 0)
+	{
+		psPanelInfoInt = (PVRSRV_PANEL_INFO*)(((IMG_UINT8 *)pArrayArgsBuffer) + ui32NextOffset);
+		ui32NextOffset += psDCPanelQueryIN->ui32PanelsArraySize * sizeof(PVRSRV_PANEL_INFO);
+	}
+
+
+	/* Lock over handle lookup. */
+	LockHandle();
+
+
 
 
 
 				{
 					/* Look up the address from the handle */
 					psDCPanelQueryOUT->eError =
-						PVRSRVLookupHandle(psConnection->psHandleBase,
+						PVRSRVLookupHandleUnlocked(psConnection->psHandleBase,
 											(void **) &psDeviceInt,
-											psDCPanelQueryIN->hDevice,
-											PVRSRV_HANDLE_TYPE_DC_DEVICE);
+											hDevice,
+											PVRSRV_HANDLE_TYPE_DC_DEVICE,
+											IMG_TRUE);
 					if(psDCPanelQueryOUT->eError != PVRSRV_OK)
 					{
+						UnlockHandle();
 						goto DCPanelQuery_exit;
 					}
 				}
-
+	/* Release now we have looked up handles. */
+	UnlockHandle();
 
 	psDCPanelQueryOUT->eError =
 		DCPanelQuery(
@@ -362,84 +556,155 @@
 
 
 
-	if ( !OSAccessOK(PVR_VERIFY_WRITE, (void*) psDCPanelQueryOUT->psPanelInfo, (psDCPanelQueryOUT->ui32NumPanels * sizeof(PVRSRV_PANEL_INFO)))
-		|| (OSCopyToUser(NULL, psDCPanelQueryOUT->psPanelInfo, psPanelInfoInt,
-		(psDCPanelQueryOUT->ui32NumPanels * sizeof(PVRSRV_PANEL_INFO))) != PVRSRV_OK) )
+	if ((psDCPanelQueryOUT->ui32NumPanels * sizeof(PVRSRV_PANEL_INFO)) > 0)
 	{
-		psDCPanelQueryOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
+		if ( OSCopyToUser(NULL, psDCPanelQueryOUT->psPanelInfo, psPanelInfoInt,
+			(psDCPanelQueryOUT->ui32NumPanels * sizeof(PVRSRV_PANEL_INFO))) != PVRSRV_OK )
+		{
+			psDCPanelQueryOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
 
-		goto DCPanelQuery_exit;
+			goto DCPanelQuery_exit;
+		}
 	}
 
 
 DCPanelQuery_exit:
-	if (psPanelInfoInt)
-		OSFreeMemNoStats(psPanelInfoInt);
+
+	/* Lock over handle lookup cleanup. */
+	LockHandle();
+
+
+
+
+
+
+				{
+					/* Unreference the previously looked up handle */
+						if(psDeviceInt)
+						{
+							PVRSRVReleaseHandleUnlocked(psConnection->psHandleBase,
+											hDevice,
+											PVRSRV_HANDLE_TYPE_DC_DEVICE);
+						}
+				}
+	/* Release now we have cleaned up look up handles. */
+	UnlockHandle();
+
+	/* Allocated space should be equal to the last updated offset */
+	PVR_ASSERT(ui32BufferSize == ui32NextOffset);
+
+#if defined(INTEGRITY_OS)
+	if(pArrayArgsBuffer)
+#else
+	if(!bHaveEnoughSpace && pArrayArgsBuffer)
+#endif
+		OSFreeMemNoStats(pArrayArgsBuffer);
+
 
 	return 0;
 }
 
+
 static IMG_INT
 PVRSRVBridgeDCFormatQuery(IMG_UINT32 ui32DispatchTableEntry,
 					  PVRSRV_BRIDGE_IN_DCFORMATQUERY *psDCFormatQueryIN,
 					  PVRSRV_BRIDGE_OUT_DCFORMATQUERY *psDCFormatQueryOUT,
 					 CONNECTION_DATA *psConnection)
 {
+	IMG_HANDLE hDevice = psDCFormatQueryIN->hDevice;
 	DC_DEVICE * psDeviceInt = NULL;
 	PVRSRV_SURFACE_FORMAT *psFormatInt = NULL;
 	IMG_UINT32 *pui32SupportedInt = NULL;
 
+	IMG_UINT32 ui32NextOffset = 0;
+	IMG_BYTE   *pArrayArgsBuffer = NULL;
+#if !defined(INTEGRITY_OS)
+	IMG_BOOL bHaveEnoughSpace = IMG_FALSE;
+#endif
+
+	IMG_UINT32 ui32BufferSize = 
+			(psDCFormatQueryIN->ui32NumFormats * sizeof(PVRSRV_SURFACE_FORMAT)) +
+			(psDCFormatQueryIN->ui32NumFormats * sizeof(IMG_UINT32)) +
+			0;
+
+
 
 	psDCFormatQueryOUT->pui32Supported = psDCFormatQueryIN->pui32Supported;
 
 
+	if (ui32BufferSize != 0)
+	{
+#if !defined(INTEGRITY_OS)
+		/* Try to use remainder of input buffer for copies if possible, word-aligned for safety. */
+		IMG_UINT32 ui32InBufferOffset = PVR_ALIGN(sizeof(*psDCFormatQueryIN), sizeof(unsigned long));
+		IMG_UINT32 ui32InBufferExcessSize = ui32InBufferOffset >= PVRSRV_MAX_BRIDGE_IN_SIZE ? 0 :
+			PVRSRV_MAX_BRIDGE_IN_SIZE - ui32InBufferOffset;
+
+		bHaveEnoughSpace = ui32BufferSize <= ui32InBufferExcessSize;
+		if (bHaveEnoughSpace)
+		{
+			IMG_BYTE *pInputBuffer = (IMG_BYTE *)psDCFormatQueryIN;
+
+			pArrayArgsBuffer = &pInputBuffer[ui32InBufferOffset];		}
+		else
+#endif
+		{
+			pArrayArgsBuffer = OSAllocMemNoStats(ui32BufferSize);
+
+			if(!pArrayArgsBuffer)
+			{
+				psDCFormatQueryOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
+				goto DCFormatQuery_exit;
+			}
+		}
+	}
+
 	if (psDCFormatQueryIN->ui32NumFormats != 0)
 	{
-		psFormatInt = OSAllocMemNoStats(psDCFormatQueryIN->ui32NumFormats * sizeof(PVRSRV_SURFACE_FORMAT));
-		if (!psFormatInt)
-		{
-			psDCFormatQueryOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
-	
-			goto DCFormatQuery_exit;
-		}
+		psFormatInt = (PVRSRV_SURFACE_FORMAT*)(((IMG_UINT8 *)pArrayArgsBuffer) + ui32NextOffset);
+		ui32NextOffset += psDCFormatQueryIN->ui32NumFormats * sizeof(PVRSRV_SURFACE_FORMAT);
 	}
 
 			/* Copy the data over */
-			if ( !OSAccessOK(PVR_VERIFY_READ, (void*) psDCFormatQueryIN->psFormat, psDCFormatQueryIN->ui32NumFormats * sizeof(PVRSRV_SURFACE_FORMAT))
-				|| (OSCopyFromUser(NULL, psFormatInt, psDCFormatQueryIN->psFormat,
-				psDCFormatQueryIN->ui32NumFormats * sizeof(PVRSRV_SURFACE_FORMAT)) != PVRSRV_OK) )
+			if (psDCFormatQueryIN->ui32NumFormats * sizeof(PVRSRV_SURFACE_FORMAT) > 0)
 			{
-				psDCFormatQueryOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
+				if ( OSCopyFromUser(NULL, psFormatInt, psDCFormatQueryIN->psFormat, psDCFormatQueryIN->ui32NumFormats * sizeof(PVRSRV_SURFACE_FORMAT)) != PVRSRV_OK )
+				{
+					psDCFormatQueryOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
 
-				goto DCFormatQuery_exit;
+					goto DCFormatQuery_exit;
+				}
 			}
 	if (psDCFormatQueryIN->ui32NumFormats != 0)
 	{
-		pui32SupportedInt = OSAllocMemNoStats(psDCFormatQueryIN->ui32NumFormats * sizeof(IMG_UINT32));
-		if (!pui32SupportedInt)
-		{
-			psDCFormatQueryOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
-	
-			goto DCFormatQuery_exit;
-		}
+		pui32SupportedInt = (IMG_UINT32*)(((IMG_UINT8 *)pArrayArgsBuffer) + ui32NextOffset);
+		ui32NextOffset += psDCFormatQueryIN->ui32NumFormats * sizeof(IMG_UINT32);
 	}
 
 
+	/* Lock over handle lookup. */
+	LockHandle();
+
+
+
 
 
 				{
 					/* Look up the address from the handle */
 					psDCFormatQueryOUT->eError =
-						PVRSRVLookupHandle(psConnection->psHandleBase,
+						PVRSRVLookupHandleUnlocked(psConnection->psHandleBase,
 											(void **) &psDeviceInt,
-											psDCFormatQueryIN->hDevice,
-											PVRSRV_HANDLE_TYPE_DC_DEVICE);
+											hDevice,
+											PVRSRV_HANDLE_TYPE_DC_DEVICE,
+											IMG_TRUE);
 					if(psDCFormatQueryOUT->eError != PVRSRV_OK)
 					{
+						UnlockHandle();
 						goto DCFormatQuery_exit;
 					}
 				}
-
+	/* Release now we have looked up handles. */
+	UnlockHandle();
 
 	psDCFormatQueryOUT->eError =
 		DCFormatQuery(
@@ -450,86 +715,155 @@
 
 
 
-	if ( !OSAccessOK(PVR_VERIFY_WRITE, (void*) psDCFormatQueryOUT->pui32Supported, (psDCFormatQueryIN->ui32NumFormats * sizeof(IMG_UINT32)))
-		|| (OSCopyToUser(NULL, psDCFormatQueryOUT->pui32Supported, pui32SupportedInt,
-		(psDCFormatQueryIN->ui32NumFormats * sizeof(IMG_UINT32))) != PVRSRV_OK) )
+	if ((psDCFormatQueryIN->ui32NumFormats * sizeof(IMG_UINT32)) > 0)
 	{
-		psDCFormatQueryOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
+		if ( OSCopyToUser(NULL, psDCFormatQueryOUT->pui32Supported, pui32SupportedInt,
+			(psDCFormatQueryIN->ui32NumFormats * sizeof(IMG_UINT32))) != PVRSRV_OK )
+		{
+			psDCFormatQueryOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
 
-		goto DCFormatQuery_exit;
+			goto DCFormatQuery_exit;
+		}
 	}
 
 
 DCFormatQuery_exit:
-	if (psFormatInt)
-		OSFreeMemNoStats(psFormatInt);
-	if (pui32SupportedInt)
-		OSFreeMemNoStats(pui32SupportedInt);
+
+	/* Lock over handle lookup cleanup. */
+	LockHandle();
+
+
+
+
+
+
+				{
+					/* Unreference the previously looked up handle */
+						if(psDeviceInt)
+						{
+							PVRSRVReleaseHandleUnlocked(psConnection->psHandleBase,
+											hDevice,
+											PVRSRV_HANDLE_TYPE_DC_DEVICE);
+						}
+				}
+	/* Release now we have cleaned up look up handles. */
+	UnlockHandle();
+
+	/* Allocated space should be equal to the last updated offset */
+	PVR_ASSERT(ui32BufferSize == ui32NextOffset);
+
+#if defined(INTEGRITY_OS)
+	if(pArrayArgsBuffer)
+#else
+	if(!bHaveEnoughSpace && pArrayArgsBuffer)
+#endif
+		OSFreeMemNoStats(pArrayArgsBuffer);
+
 
 	return 0;
 }
 
+
 static IMG_INT
 PVRSRVBridgeDCDimQuery(IMG_UINT32 ui32DispatchTableEntry,
 					  PVRSRV_BRIDGE_IN_DCDIMQUERY *psDCDimQueryIN,
 					  PVRSRV_BRIDGE_OUT_DCDIMQUERY *psDCDimQueryOUT,
 					 CONNECTION_DATA *psConnection)
 {
+	IMG_HANDLE hDevice = psDCDimQueryIN->hDevice;
 	DC_DEVICE * psDeviceInt = NULL;
 	PVRSRV_SURFACE_DIMS *psDimInt = NULL;
 	IMG_UINT32 *pui32SupportedInt = NULL;
 
+	IMG_UINT32 ui32NextOffset = 0;
+	IMG_BYTE   *pArrayArgsBuffer = NULL;
+#if !defined(INTEGRITY_OS)
+	IMG_BOOL bHaveEnoughSpace = IMG_FALSE;
+#endif
+
+	IMG_UINT32 ui32BufferSize = 
+			(psDCDimQueryIN->ui32NumDims * sizeof(PVRSRV_SURFACE_DIMS)) +
+			(psDCDimQueryIN->ui32NumDims * sizeof(IMG_UINT32)) +
+			0;
+
+
 
 	psDCDimQueryOUT->pui32Supported = psDCDimQueryIN->pui32Supported;
 
 
+	if (ui32BufferSize != 0)
+	{
+#if !defined(INTEGRITY_OS)
+		/* Try to use remainder of input buffer for copies if possible, word-aligned for safety. */
+		IMG_UINT32 ui32InBufferOffset = PVR_ALIGN(sizeof(*psDCDimQueryIN), sizeof(unsigned long));
+		IMG_UINT32 ui32InBufferExcessSize = ui32InBufferOffset >= PVRSRV_MAX_BRIDGE_IN_SIZE ? 0 :
+			PVRSRV_MAX_BRIDGE_IN_SIZE - ui32InBufferOffset;
+
+		bHaveEnoughSpace = ui32BufferSize <= ui32InBufferExcessSize;
+		if (bHaveEnoughSpace)
+		{
+			IMG_BYTE *pInputBuffer = (IMG_BYTE *)psDCDimQueryIN;
+
+			pArrayArgsBuffer = &pInputBuffer[ui32InBufferOffset];		}
+		else
+#endif
+		{
+			pArrayArgsBuffer = OSAllocMemNoStats(ui32BufferSize);
+
+			if(!pArrayArgsBuffer)
+			{
+				psDCDimQueryOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
+				goto DCDimQuery_exit;
+			}
+		}
+	}
+
 	if (psDCDimQueryIN->ui32NumDims != 0)
 	{
-		psDimInt = OSAllocMemNoStats(psDCDimQueryIN->ui32NumDims * sizeof(PVRSRV_SURFACE_DIMS));
-		if (!psDimInt)
-		{
-			psDCDimQueryOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
-	
-			goto DCDimQuery_exit;
-		}
+		psDimInt = (PVRSRV_SURFACE_DIMS*)(((IMG_UINT8 *)pArrayArgsBuffer) + ui32NextOffset);
+		ui32NextOffset += psDCDimQueryIN->ui32NumDims * sizeof(PVRSRV_SURFACE_DIMS);
 	}
 
 			/* Copy the data over */
-			if ( !OSAccessOK(PVR_VERIFY_READ, (void*) psDCDimQueryIN->psDim, psDCDimQueryIN->ui32NumDims * sizeof(PVRSRV_SURFACE_DIMS))
-				|| (OSCopyFromUser(NULL, psDimInt, psDCDimQueryIN->psDim,
-				psDCDimQueryIN->ui32NumDims * sizeof(PVRSRV_SURFACE_DIMS)) != PVRSRV_OK) )
+			if (psDCDimQueryIN->ui32NumDims * sizeof(PVRSRV_SURFACE_DIMS) > 0)
 			{
-				psDCDimQueryOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
+				if ( OSCopyFromUser(NULL, psDimInt, psDCDimQueryIN->psDim, psDCDimQueryIN->ui32NumDims * sizeof(PVRSRV_SURFACE_DIMS)) != PVRSRV_OK )
+				{
+					psDCDimQueryOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
 
-				goto DCDimQuery_exit;
+					goto DCDimQuery_exit;
+				}
 			}
 	if (psDCDimQueryIN->ui32NumDims != 0)
 	{
-		pui32SupportedInt = OSAllocMemNoStats(psDCDimQueryIN->ui32NumDims * sizeof(IMG_UINT32));
-		if (!pui32SupportedInt)
-		{
-			psDCDimQueryOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
-	
-			goto DCDimQuery_exit;
-		}
+		pui32SupportedInt = (IMG_UINT32*)(((IMG_UINT8 *)pArrayArgsBuffer) + ui32NextOffset);
+		ui32NextOffset += psDCDimQueryIN->ui32NumDims * sizeof(IMG_UINT32);
 	}
 
 
+	/* Lock over handle lookup. */
+	LockHandle();
+
+
+
 
 
 				{
 					/* Look up the address from the handle */
 					psDCDimQueryOUT->eError =
-						PVRSRVLookupHandle(psConnection->psHandleBase,
+						PVRSRVLookupHandleUnlocked(psConnection->psHandleBase,
 											(void **) &psDeviceInt,
-											psDCDimQueryIN->hDevice,
-											PVRSRV_HANDLE_TYPE_DC_DEVICE);
+											hDevice,
+											PVRSRV_HANDLE_TYPE_DC_DEVICE,
+											IMG_TRUE);
 					if(psDCDimQueryOUT->eError != PVRSRV_OK)
 					{
+						UnlockHandle();
 						goto DCDimQuery_exit;
 					}
 				}
-
+	/* Release now we have looked up handles. */
+	UnlockHandle();
 
 	psDCDimQueryOUT->eError =
 		DCDimQuery(
@@ -540,31 +874,62 @@
 
 
 
-	if ( !OSAccessOK(PVR_VERIFY_WRITE, (void*) psDCDimQueryOUT->pui32Supported, (psDCDimQueryIN->ui32NumDims * sizeof(IMG_UINT32)))
-		|| (OSCopyToUser(NULL, psDCDimQueryOUT->pui32Supported, pui32SupportedInt,
-		(psDCDimQueryIN->ui32NumDims * sizeof(IMG_UINT32))) != PVRSRV_OK) )
+	if ((psDCDimQueryIN->ui32NumDims * sizeof(IMG_UINT32)) > 0)
 	{
-		psDCDimQueryOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
+		if ( OSCopyToUser(NULL, psDCDimQueryOUT->pui32Supported, pui32SupportedInt,
+			(psDCDimQueryIN->ui32NumDims * sizeof(IMG_UINT32))) != PVRSRV_OK )
+		{
+			psDCDimQueryOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
 
-		goto DCDimQuery_exit;
+			goto DCDimQuery_exit;
+		}
 	}
 
 
 DCDimQuery_exit:
-	if (psDimInt)
-		OSFreeMemNoStats(psDimInt);
-	if (pui32SupportedInt)
-		OSFreeMemNoStats(pui32SupportedInt);
+
+	/* Lock over handle lookup cleanup. */
+	LockHandle();
+
+
+
+
+
+
+				{
+					/* Unreference the previously looked up handle */
+						if(psDeviceInt)
+						{
+							PVRSRVReleaseHandleUnlocked(psConnection->psHandleBase,
+											hDevice,
+											PVRSRV_HANDLE_TYPE_DC_DEVICE);
+						}
+				}
+	/* Release now we have cleaned up look up handles. */
+	UnlockHandle();
+
+	/* Allocated space should be equal to the last updated offset */
+	PVR_ASSERT(ui32BufferSize == ui32NextOffset);
+
+#if defined(INTEGRITY_OS)
+	if(pArrayArgsBuffer)
+#else
+	if(!bHaveEnoughSpace && pArrayArgsBuffer)
+#endif
+		OSFreeMemNoStats(pArrayArgsBuffer);
+
 
 	return 0;
 }
 
+
 static IMG_INT
 PVRSRVBridgeDCSetBlank(IMG_UINT32 ui32DispatchTableEntry,
 					  PVRSRV_BRIDGE_IN_DCSETBLANK *psDCSetBlankIN,
 					  PVRSRV_BRIDGE_OUT_DCSETBLANK *psDCSetBlankOUT,
 					 CONNECTION_DATA *psConnection)
 {
+	IMG_HANDLE hDevice = psDCSetBlankIN->hDevice;
 	DC_DEVICE * psDeviceInt = NULL;
 
 
@@ -573,19 +938,29 @@
 
 
 
+	/* Lock over handle lookup. */
+	LockHandle();
+
+
+
+
+
 				{
 					/* Look up the address from the handle */
 					psDCSetBlankOUT->eError =
-						PVRSRVLookupHandle(psConnection->psHandleBase,
+						PVRSRVLookupHandleUnlocked(psConnection->psHandleBase,
 											(void **) &psDeviceInt,
-											psDCSetBlankIN->hDevice,
-											PVRSRV_HANDLE_TYPE_DC_DEVICE);
+											hDevice,
+											PVRSRV_HANDLE_TYPE_DC_DEVICE,
+											IMG_TRUE);
 					if(psDCSetBlankOUT->eError != PVRSRV_OK)
 					{
+						UnlockHandle();
 						goto DCSetBlank_exit;
 					}
 				}
-
+	/* Release now we have looked up handles. */
+	UnlockHandle();
 
 	psDCSetBlankOUT->eError =
 		DCSetBlank(
@@ -597,15 +972,38 @@
 
 DCSetBlank_exit:
 
+	/* Lock over handle lookup cleanup. */
+	LockHandle();
+
+
+
+
+
+
+				{
+					/* Unreference the previously looked up handle */
+						if(psDeviceInt)
+						{
+							PVRSRVReleaseHandleUnlocked(psConnection->psHandleBase,
+											hDevice,
+											PVRSRV_HANDLE_TYPE_DC_DEVICE);
+						}
+				}
+	/* Release now we have cleaned up look up handles. */
+	UnlockHandle();
+
+
 	return 0;
 }
 
+
 static IMG_INT
 PVRSRVBridgeDCSetVSyncReporting(IMG_UINT32 ui32DispatchTableEntry,
 					  PVRSRV_BRIDGE_IN_DCSETVSYNCREPORTING *psDCSetVSyncReportingIN,
 					  PVRSRV_BRIDGE_OUT_DCSETVSYNCREPORTING *psDCSetVSyncReportingOUT,
 					 CONNECTION_DATA *psConnection)
 {
+	IMG_HANDLE hDevice = psDCSetVSyncReportingIN->hDevice;
 	DC_DEVICE * psDeviceInt = NULL;
 
 
@@ -614,19 +1012,29 @@
 
 
 
+	/* Lock over handle lookup. */
+	LockHandle();
+
+
+
+
+
 				{
 					/* Look up the address from the handle */
 					psDCSetVSyncReportingOUT->eError =
-						PVRSRVLookupHandle(psConnection->psHandleBase,
+						PVRSRVLookupHandleUnlocked(psConnection->psHandleBase,
 											(void **) &psDeviceInt,
-											psDCSetVSyncReportingIN->hDevice,
-											PVRSRV_HANDLE_TYPE_DC_DEVICE);
+											hDevice,
+											PVRSRV_HANDLE_TYPE_DC_DEVICE,
+											IMG_TRUE);
 					if(psDCSetVSyncReportingOUT->eError != PVRSRV_OK)
 					{
+						UnlockHandle();
 						goto DCSetVSyncReporting_exit;
 					}
 				}
-
+	/* Release now we have looked up handles. */
+	UnlockHandle();
 
 	psDCSetVSyncReportingOUT->eError =
 		DCSetVSyncReporting(
@@ -638,15 +1046,38 @@
 
 DCSetVSyncReporting_exit:
 
+	/* Lock over handle lookup cleanup. */
+	LockHandle();
+
+
+
+
+
+
+				{
+					/* Unreference the previously looked up handle */
+						if(psDeviceInt)
+						{
+							PVRSRVReleaseHandleUnlocked(psConnection->psHandleBase,
+											hDevice,
+											PVRSRV_HANDLE_TYPE_DC_DEVICE);
+						}
+				}
+	/* Release now we have cleaned up look up handles. */
+	UnlockHandle();
+
+
 	return 0;
 }
 
+
 static IMG_INT
 PVRSRVBridgeDCLastVSyncQuery(IMG_UINT32 ui32DispatchTableEntry,
 					  PVRSRV_BRIDGE_IN_DCLASTVSYNCQUERY *psDCLastVSyncQueryIN,
 					  PVRSRV_BRIDGE_OUT_DCLASTVSYNCQUERY *psDCLastVSyncQueryOUT,
 					 CONNECTION_DATA *psConnection)
 {
+	IMG_HANDLE hDevice = psDCLastVSyncQueryIN->hDevice;
 	DC_DEVICE * psDeviceInt = NULL;
 
 
@@ -655,19 +1086,29 @@
 
 
 
+	/* Lock over handle lookup. */
+	LockHandle();
+
+
+
+
+
 				{
 					/* Look up the address from the handle */
 					psDCLastVSyncQueryOUT->eError =
-						PVRSRVLookupHandle(psConnection->psHandleBase,
+						PVRSRVLookupHandleUnlocked(psConnection->psHandleBase,
 											(void **) &psDeviceInt,
-											psDCLastVSyncQueryIN->hDevice,
-											PVRSRV_HANDLE_TYPE_DC_DEVICE);
+											hDevice,
+											PVRSRV_HANDLE_TYPE_DC_DEVICE,
+											IMG_TRUE);
 					if(psDCLastVSyncQueryOUT->eError != PVRSRV_OK)
 					{
+						UnlockHandle();
 						goto DCLastVSyncQuery_exit;
 					}
 				}
-
+	/* Release now we have looked up handles. */
+	UnlockHandle();
 
 	psDCLastVSyncQueryOUT->eError =
 		DCLastVSyncQuery(
@@ -679,15 +1120,38 @@
 
 DCLastVSyncQuery_exit:
 
+	/* Lock over handle lookup cleanup. */
+	LockHandle();
+
+
+
+
+
+
+				{
+					/* Unreference the previously looked up handle */
+						if(psDeviceInt)
+						{
+							PVRSRVReleaseHandleUnlocked(psConnection->psHandleBase,
+											hDevice,
+											PVRSRV_HANDLE_TYPE_DC_DEVICE);
+						}
+				}
+	/* Release now we have cleaned up look up handles. */
+	UnlockHandle();
+
+
 	return 0;
 }
 
+
 static IMG_INT
 PVRSRVBridgeDCSystemBufferAcquire(IMG_UINT32 ui32DispatchTableEntry,
 					  PVRSRV_BRIDGE_IN_DCSYSTEMBUFFERACQUIRE *psDCSystemBufferAcquireIN,
 					  PVRSRV_BRIDGE_OUT_DCSYSTEMBUFFERACQUIRE *psDCSystemBufferAcquireOUT,
 					 CONNECTION_DATA *psConnection)
 {
+	IMG_HANDLE hDevice = psDCSystemBufferAcquireIN->hDevice;
 	DC_DEVICE * psDeviceInt = NULL;
 	DC_BUFFER * psBufferInt = NULL;
 
@@ -695,23 +1159,31 @@
 
 
 
-	PMRLock();
+
+
+	/* Lock over handle lookup. */
+	LockHandle();
+
+
+
 
 
 				{
 					/* Look up the address from the handle */
 					psDCSystemBufferAcquireOUT->eError =
-						PVRSRVLookupHandle(psConnection->psHandleBase,
+						PVRSRVLookupHandleUnlocked(psConnection->psHandleBase,
 											(void **) &psDeviceInt,
-											psDCSystemBufferAcquireIN->hDevice,
-											PVRSRV_HANDLE_TYPE_DC_DEVICE);
+											hDevice,
+											PVRSRV_HANDLE_TYPE_DC_DEVICE,
+											IMG_TRUE);
 					if(psDCSystemBufferAcquireOUT->eError != PVRSRV_OK)
 					{
-						PMRUnlock();
+						UnlockHandle();
 						goto DCSystemBufferAcquire_exit;
 					}
 				}
-
+	/* Release now we have looked up handles. */
+	UnlockHandle();
 
 	psDCSystemBufferAcquireOUT->eError =
 		DCSystemBufferAcquire(
@@ -721,13 +1193,18 @@
 	/* Exit early if bridged call fails */
 	if(psDCSystemBufferAcquireOUT->eError != PVRSRV_OK)
 	{
-		PMRUnlock();
 		goto DCSystemBufferAcquire_exit;
 	}
-	PMRUnlock();
+
+	/* Lock over handle creation. */
+	LockHandle();
 
 
-	psDCSystemBufferAcquireOUT->eError = PVRSRVAllocHandle(psConnection->psHandleBase,
+
+
+
+	psDCSystemBufferAcquireOUT->eError = PVRSRVAllocHandleUnlocked(psConnection->psHandleBase,
+
 							&psDCSystemBufferAcquireOUT->hBuffer,
 							(void *) psBufferInt,
 							PVRSRV_HANDLE_TYPE_DC_BUFFER,
@@ -735,13 +1212,37 @@
 							,(PFN_HANDLE_RELEASE)&DCSystemBufferRelease);
 	if (psDCSystemBufferAcquireOUT->eError != PVRSRV_OK)
 	{
+		UnlockHandle();
 		goto DCSystemBufferAcquire_exit;
 	}
 
+	/* Release now we have created handles. */
+	UnlockHandle();
 
 
 
 DCSystemBufferAcquire_exit:
+
+	/* Lock over handle lookup cleanup. */
+	LockHandle();
+
+
+
+
+
+
+				{
+					/* Unreference the previously looked up handle */
+						if(psDeviceInt)
+						{
+							PVRSRVReleaseHandleUnlocked(psConnection->psHandleBase,
+											hDevice,
+											PVRSRV_HANDLE_TYPE_DC_DEVICE);
+						}
+				}
+	/* Release now we have cleaned up look up handles. */
+	UnlockHandle();
+
 	if (psDCSystemBufferAcquireOUT->eError != PVRSRV_OK)
 	{
 		if (psBufferInt)
@@ -754,6 +1255,7 @@
 	return 0;
 }
 
+
 static IMG_INT
 PVRSRVBridgeDCSystemBufferRelease(IMG_UINT32 ui32DispatchTableEntry,
 					  PVRSRV_BRIDGE_IN_DCSYSTEMBUFFERRELEASE *psDCSystemBufferReleaseIN,
@@ -769,29 +1271,49 @@
 
 
 
+	/* Lock over handle destruction. */
+	LockHandle();
+
+
+
+
+
 	psDCSystemBufferReleaseOUT->eError =
-		PVRSRVReleaseHandle(psConnection->psHandleBase,
+		PVRSRVReleaseHandleUnlocked(psConnection->psHandleBase,
 					(IMG_HANDLE) psDCSystemBufferReleaseIN->hBuffer,
 					PVRSRV_HANDLE_TYPE_DC_BUFFER);
-	if ((psDCSystemBufferReleaseOUT->eError != PVRSRV_OK) && (psDCSystemBufferReleaseOUT->eError != PVRSRV_ERROR_RETRY))
+	if ((psDCSystemBufferReleaseOUT->eError != PVRSRV_OK) &&
+	    (psDCSystemBufferReleaseOUT->eError != PVRSRV_ERROR_RETRY))
 	{
+		PVR_DPF((PVR_DBG_ERROR,
+		        "PVRSRVBridgeDCSystemBufferRelease: %s",
+		        PVRSRVGetErrorStringKM(psDCSystemBufferReleaseOUT->eError)));
 		PVR_ASSERT(0);
+		UnlockHandle();
 		goto DCSystemBufferRelease_exit;
 	}
 
+	/* Release now we have destroyed handles. */
+	UnlockHandle();
+
 
 
 DCSystemBufferRelease_exit:
 
+
+
+
 	return 0;
 }
 
+
 static IMG_INT
 PVRSRVBridgeDCDisplayContextCreate(IMG_UINT32 ui32DispatchTableEntry,
 					  PVRSRV_BRIDGE_IN_DCDISPLAYCONTEXTCREATE *psDCDisplayContextCreateIN,
 					  PVRSRV_BRIDGE_OUT_DCDISPLAYCONTEXTCREATE *psDCDisplayContextCreateOUT,
 					 CONNECTION_DATA *psConnection)
 {
+	IMG_HANDLE hDevice = psDCDisplayContextCreateIN->hDevice;
 	DC_DEVICE * psDeviceInt = NULL;
 	DC_DISPLAY_CONTEXT * psDisplayContextInt = NULL;
 
@@ -801,19 +1323,29 @@
 
 
 
+	/* Lock over handle lookup. */
+	LockHandle();
+
+
+
+
+
 				{
 					/* Look up the address from the handle */
 					psDCDisplayContextCreateOUT->eError =
-						PVRSRVLookupHandle(psConnection->psHandleBase,
+						PVRSRVLookupHandleUnlocked(psConnection->psHandleBase,
 											(void **) &psDeviceInt,
-											psDCDisplayContextCreateIN->hDevice,
-											PVRSRV_HANDLE_TYPE_DC_DEVICE);
+											hDevice,
+											PVRSRV_HANDLE_TYPE_DC_DEVICE,
+											IMG_TRUE);
 					if(psDCDisplayContextCreateOUT->eError != PVRSRV_OK)
 					{
+						UnlockHandle();
 						goto DCDisplayContextCreate_exit;
 					}
 				}
-
+	/* Release now we have looked up handles. */
+	UnlockHandle();
 
 	psDCDisplayContextCreateOUT->eError =
 		DCDisplayContextCreate(
@@ -825,8 +1357,15 @@
 		goto DCDisplayContextCreate_exit;
 	}
 
+	/* Lock over handle creation. */
+	LockHandle();
 
-	psDCDisplayContextCreateOUT->eError = PVRSRVAllocHandle(psConnection->psHandleBase,
+
+
+
+
+	psDCDisplayContextCreateOUT->eError = PVRSRVAllocHandleUnlocked(psConnection->psHandleBase,
+
 							&psDCDisplayContextCreateOUT->hDisplayContext,
 							(void *) psDisplayContextInt,
 							PVRSRV_HANDLE_TYPE_DC_DISPLAY_CONTEXT,
@@ -834,13 +1373,37 @@
 							,(PFN_HANDLE_RELEASE)&DCDisplayContextDestroy);
 	if (psDCDisplayContextCreateOUT->eError != PVRSRV_OK)
 	{
+		UnlockHandle();
 		goto DCDisplayContextCreate_exit;
 	}
 
+	/* Release now we have created handles. */
+	UnlockHandle();
 
 
 
 DCDisplayContextCreate_exit:
+
+	/* Lock over handle lookup cleanup. */
+	LockHandle();
+
+
+
+
+
+
+				{
+					/* Unreference the previously looked up handle */
+						if(psDeviceInt)
+						{
+							PVRSRVReleaseHandleUnlocked(psConnection->psHandleBase,
+											hDevice,
+											PVRSRV_HANDLE_TYPE_DC_DEVICE);
+						}
+				}
+	/* Release now we have cleaned up look up handles. */
+	UnlockHandle();
+
 	if (psDCDisplayContextCreateOUT->eError != PVRSRV_OK)
 	{
 		if (psDisplayContextInt)
@@ -853,84 +1416,123 @@
 	return 0;
 }
 
+
 static IMG_INT
 PVRSRVBridgeDCDisplayContextConfigureCheck(IMG_UINT32 ui32DispatchTableEntry,
 					  PVRSRV_BRIDGE_IN_DCDISPLAYCONTEXTCONFIGURECHECK *psDCDisplayContextConfigureCheckIN,
 					  PVRSRV_BRIDGE_OUT_DCDISPLAYCONTEXTCONFIGURECHECK *psDCDisplayContextConfigureCheckOUT,
 					 CONNECTION_DATA *psConnection)
 {
+	IMG_HANDLE hDisplayContext = psDCDisplayContextConfigureCheckIN->hDisplayContext;
 	DC_DISPLAY_CONTEXT * psDisplayContextInt = NULL;
 	PVRSRV_SURFACE_CONFIG_INFO *psSurfInfoInt = NULL;
 	DC_BUFFER * *psBuffersInt = NULL;
 	IMG_HANDLE *hBuffersInt2 = NULL;
 
+	IMG_UINT32 ui32NextOffset = 0;
+	IMG_BYTE   *pArrayArgsBuffer = NULL;
+#if !defined(INTEGRITY_OS)
+	IMG_BOOL bHaveEnoughSpace = IMG_FALSE;
+#endif
+
+	IMG_UINT32 ui32BufferSize = 
+			(psDCDisplayContextConfigureCheckIN->ui32PipeCount * sizeof(PVRSRV_SURFACE_CONFIG_INFO)) +
+			(psDCDisplayContextConfigureCheckIN->ui32PipeCount * sizeof(DC_BUFFER *)) +
+			(psDCDisplayContextConfigureCheckIN->ui32PipeCount * sizeof(IMG_HANDLE)) +
+			0;
 
 
 
-	if (psDCDisplayContextConfigureCheckIN->ui32PipeCount != 0)
+
+
+	if (ui32BufferSize != 0)
 	{
-		psSurfInfoInt = OSAllocMemNoStats(psDCDisplayContextConfigureCheckIN->ui32PipeCount * sizeof(PVRSRV_SURFACE_CONFIG_INFO));
-		if (!psSurfInfoInt)
+#if !defined(INTEGRITY_OS)
+		/* Try to use remainder of input buffer for copies if possible, word-aligned for safety. */
+		IMG_UINT32 ui32InBufferOffset = PVR_ALIGN(sizeof(*psDCDisplayContextConfigureCheckIN), sizeof(unsigned long));
+		IMG_UINT32 ui32InBufferExcessSize = ui32InBufferOffset >= PVRSRV_MAX_BRIDGE_IN_SIZE ? 0 :
+			PVRSRV_MAX_BRIDGE_IN_SIZE - ui32InBufferOffset;
+
+		bHaveEnoughSpace = ui32BufferSize <= ui32InBufferExcessSize;
+		if (bHaveEnoughSpace)
 		{
-			psDCDisplayContextConfigureCheckOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
-	
-			goto DCDisplayContextConfigureCheck_exit;
+			IMG_BYTE *pInputBuffer = (IMG_BYTE *)psDCDisplayContextConfigureCheckIN;
+
+			pArrayArgsBuffer = &pInputBuffer[ui32InBufferOffset];		}
+		else
+#endif
+		{
+			pArrayArgsBuffer = OSAllocMemNoStats(ui32BufferSize);
+
+			if(!pArrayArgsBuffer)
+			{
+				psDCDisplayContextConfigureCheckOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
+				goto DCDisplayContextConfigureCheck_exit;
+			}
 		}
 	}
 
-			/* Copy the data over */
-			if ( !OSAccessOK(PVR_VERIFY_READ, (void*) psDCDisplayContextConfigureCheckIN->psSurfInfo, psDCDisplayContextConfigureCheckIN->ui32PipeCount * sizeof(PVRSRV_SURFACE_CONFIG_INFO))
-				|| (OSCopyFromUser(NULL, psSurfInfoInt, psDCDisplayContextConfigureCheckIN->psSurfInfo,
-				psDCDisplayContextConfigureCheckIN->ui32PipeCount * sizeof(PVRSRV_SURFACE_CONFIG_INFO)) != PVRSRV_OK) )
-			{
-				psDCDisplayContextConfigureCheckOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
-
-				goto DCDisplayContextConfigureCheck_exit;
-			}
 	if (psDCDisplayContextConfigureCheckIN->ui32PipeCount != 0)
 	{
-		psBuffersInt = OSAllocMemNoStats(psDCDisplayContextConfigureCheckIN->ui32PipeCount * sizeof(DC_BUFFER *));
-		if (!psBuffersInt)
-		{
-			psDCDisplayContextConfigureCheckOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
-	
-			goto DCDisplayContextConfigureCheck_exit;
-		}
-		hBuffersInt2 = OSAllocMemNoStats(psDCDisplayContextConfigureCheckIN->ui32PipeCount * sizeof(IMG_HANDLE));
-		if (!hBuffersInt2)
-		{
-			psDCDisplayContextConfigureCheckOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
-	
-			goto DCDisplayContextConfigureCheck_exit;
-		}
+		psSurfInfoInt = (PVRSRV_SURFACE_CONFIG_INFO*)(((IMG_UINT8 *)pArrayArgsBuffer) + ui32NextOffset);
+		ui32NextOffset += psDCDisplayContextConfigureCheckIN->ui32PipeCount * sizeof(PVRSRV_SURFACE_CONFIG_INFO);
 	}
 
 			/* Copy the data over */
-			if ( !OSAccessOK(PVR_VERIFY_READ, (void*) psDCDisplayContextConfigureCheckIN->phBuffers, psDCDisplayContextConfigureCheckIN->ui32PipeCount * sizeof(IMG_HANDLE))
-				|| (OSCopyFromUser(NULL, hBuffersInt2, psDCDisplayContextConfigureCheckIN->phBuffers,
-				psDCDisplayContextConfigureCheckIN->ui32PipeCount * sizeof(IMG_HANDLE)) != PVRSRV_OK) )
+			if (psDCDisplayContextConfigureCheckIN->ui32PipeCount * sizeof(PVRSRV_SURFACE_CONFIG_INFO) > 0)
 			{
-				psDCDisplayContextConfigureCheckOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
+				if ( OSCopyFromUser(NULL, psSurfInfoInt, psDCDisplayContextConfigureCheckIN->psSurfInfo, psDCDisplayContextConfigureCheckIN->ui32PipeCount * sizeof(PVRSRV_SURFACE_CONFIG_INFO)) != PVRSRV_OK )
+				{
+					psDCDisplayContextConfigureCheckOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
 
-				goto DCDisplayContextConfigureCheck_exit;
+					goto DCDisplayContextConfigureCheck_exit;
+				}
 			}
+	if (psDCDisplayContextConfigureCheckIN->ui32PipeCount != 0)
+	{
+		psBuffersInt = (DC_BUFFER **)(((IMG_UINT8 *)pArrayArgsBuffer) + ui32NextOffset);
+		ui32NextOffset += psDCDisplayContextConfigureCheckIN->ui32PipeCount * sizeof(DC_BUFFER *);
+		hBuffersInt2 = (IMG_HANDLE *)(((IMG_UINT8 *)pArrayArgsBuffer) + ui32NextOffset); 
+		ui32NextOffset += psDCDisplayContextConfigureCheckIN->ui32PipeCount * sizeof(IMG_HANDLE);
+	}
+
+			/* Copy the data over */
+			if (psDCDisplayContextConfigureCheckIN->ui32PipeCount * sizeof(IMG_HANDLE) > 0)
+			{
+				if ( OSCopyFromUser(NULL, hBuffersInt2, psDCDisplayContextConfigureCheckIN->phBuffers, psDCDisplayContextConfigureCheckIN->ui32PipeCount * sizeof(IMG_HANDLE)) != PVRSRV_OK )
+				{
+					psDCDisplayContextConfigureCheckOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
+
+					goto DCDisplayContextConfigureCheck_exit;
+				}
+			}
+
+	/* Lock over handle lookup. */
+	LockHandle();
+
+
 
 
 
 				{
 					/* Look up the address from the handle */
 					psDCDisplayContextConfigureCheckOUT->eError =
-						PVRSRVLookupHandle(psConnection->psHandleBase,
+						PVRSRVLookupHandleUnlocked(psConnection->psHandleBase,
 											(void **) &psDisplayContextInt,
-											psDCDisplayContextConfigureCheckIN->hDisplayContext,
-											PVRSRV_HANDLE_TYPE_DC_DISPLAY_CONTEXT);
+											hDisplayContext,
+											PVRSRV_HANDLE_TYPE_DC_DISPLAY_CONTEXT,
+											IMG_TRUE);
 					if(psDCDisplayContextConfigureCheckOUT->eError != PVRSRV_OK)
 					{
+						UnlockHandle();
 						goto DCDisplayContextConfigureCheck_exit;
 					}
 				}
 
 
+
+
+
 	{
 		IMG_UINT32 i;
 
@@ -939,18 +1541,21 @@
 				{
 					/* Look up the address from the handle */
 					psDCDisplayContextConfigureCheckOUT->eError =
-						PVRSRVLookupHandle(psConnection->psHandleBase,
+						PVRSRVLookupHandleUnlocked(psConnection->psHandleBase,
 											(void **) &psBuffersInt[i],
 											hBuffersInt2[i],
-											PVRSRV_HANDLE_TYPE_DC_BUFFER);
+											PVRSRV_HANDLE_TYPE_DC_BUFFER,
+											IMG_TRUE);
 					if(psDCDisplayContextConfigureCheckOUT->eError != PVRSRV_OK)
 					{
+						UnlockHandle();
 						goto DCDisplayContextConfigureCheck_exit;
 					}
 				}
-
 		}
 	}
+	/* Release now we have looked up handles. */
+	UnlockHandle();
 
 	psDCDisplayContextConfigureCheckOUT->eError =
 		DCDisplayContextConfigureCheck(
@@ -963,22 +1568,72 @@
 
 
 DCDisplayContextConfigureCheck_exit:
-	if (psSurfInfoInt)
-		OSFreeMemNoStats(psSurfInfoInt);
-	if (psBuffersInt)
-		OSFreeMemNoStats(psBuffersInt);
+
+	/* Lock over handle lookup cleanup. */
+	LockHandle();
+
+
+
+
+
+
+				{
+					/* Unreference the previously looked up handle */
+						if(psDisplayContextInt)
+						{
+							PVRSRVReleaseHandleUnlocked(psConnection->psHandleBase,
+											hDisplayContext,
+											PVRSRV_HANDLE_TYPE_DC_DISPLAY_CONTEXT);
+						}
+				}
+
+
+
+
+
+
 	if (hBuffersInt2)
-		OSFreeMemNoStats(hBuffersInt2);
+	{
+		IMG_UINT32 i;
+
+		for (i=0;i<psDCDisplayContextConfigureCheckIN->ui32PipeCount;i++)
+		{
+				{
+					/* Unreference the previously looked up handle */
+						if(psBuffersInt[i])
+						{
+							PVRSRVReleaseHandleUnlocked(psConnection->psHandleBase,
+											hBuffersInt2[i],
+											PVRSRV_HANDLE_TYPE_DC_BUFFER);
+						}
+				}
+		}
+	}
+	/* Release now we have cleaned up look up handles. */
+	UnlockHandle();
+
+	/* Allocated space should be equal to the last updated offset */
+	PVR_ASSERT(ui32BufferSize == ui32NextOffset);
+
+#if defined(INTEGRITY_OS)
+	if(pArrayArgsBuffer)
+#else
+	if(!bHaveEnoughSpace && pArrayArgsBuffer)
+#endif
+		OSFreeMemNoStats(pArrayArgsBuffer);
+
 
 	return 0;
 }
 
+
 static IMG_INT
 PVRSRVBridgeDCDisplayContextConfigure(IMG_UINT32 ui32DispatchTableEntry,
 					  PVRSRV_BRIDGE_IN_DCDISPLAYCONTEXTCONFIGURE *psDCDisplayContextConfigureIN,
 					  PVRSRV_BRIDGE_OUT_DCDISPLAYCONTEXTCONFIGURE *psDCDisplayContextConfigureOUT,
 					 CONNECTION_DATA *psConnection)
 {
+	IMG_HANDLE hDisplayContext = psDCDisplayContextConfigureIN->hDisplayContext;
 	DC_DISPLAY_CONTEXT * psDisplayContextInt = NULL;
 	PVRSRV_SURFACE_CONFIG_INFO *psSurfInfoInt = NULL;
 	DC_BUFFER * *psBuffersInt = NULL;
@@ -987,120 +1642,147 @@
 	IMG_HANDLE *hSyncInt2 = NULL;
 	IMG_BOOL *bUpdateInt = NULL;
 
+	IMG_UINT32 ui32NextOffset = 0;
+	IMG_BYTE   *pArrayArgsBuffer = NULL;
+#if !defined(INTEGRITY_OS)
+	IMG_BOOL bHaveEnoughSpace = IMG_FALSE;
+#endif
+
+	IMG_UINT32 ui32BufferSize = 
+			(psDCDisplayContextConfigureIN->ui32PipeCount * sizeof(PVRSRV_SURFACE_CONFIG_INFO)) +
+			(psDCDisplayContextConfigureIN->ui32PipeCount * sizeof(DC_BUFFER *)) +
+			(psDCDisplayContextConfigureIN->ui32PipeCount * sizeof(IMG_HANDLE)) +
+			(psDCDisplayContextConfigureIN->ui32SyncCount * sizeof(SERVER_SYNC_PRIMITIVE *)) +
+			(psDCDisplayContextConfigureIN->ui32SyncCount * sizeof(IMG_HANDLE)) +
+			(psDCDisplayContextConfigureIN->ui32SyncCount * sizeof(IMG_BOOL)) +
+			0;
 
 
 
+
+
+	if (ui32BufferSize != 0)
+	{
+#if !defined(INTEGRITY_OS)
+		/* Try to use remainder of input buffer for copies if possible, word-aligned for safety. */
+		IMG_UINT32 ui32InBufferOffset = PVR_ALIGN(sizeof(*psDCDisplayContextConfigureIN), sizeof(unsigned long));
+		IMG_UINT32 ui32InBufferExcessSize = ui32InBufferOffset >= PVRSRV_MAX_BRIDGE_IN_SIZE ? 0 :
+			PVRSRV_MAX_BRIDGE_IN_SIZE - ui32InBufferOffset;
+
+		bHaveEnoughSpace = ui32BufferSize <= ui32InBufferExcessSize;
+		if (bHaveEnoughSpace)
+		{
+			IMG_BYTE *pInputBuffer = (IMG_BYTE *)psDCDisplayContextConfigureIN;
+
+			pArrayArgsBuffer = &pInputBuffer[ui32InBufferOffset];		}
+		else
+#endif
+		{
+			pArrayArgsBuffer = OSAllocMemNoStats(ui32BufferSize);
+
+			if(!pArrayArgsBuffer)
+			{
+				psDCDisplayContextConfigureOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
+				goto DCDisplayContextConfigure_exit;
+			}
+		}
+	}
+
 	if (psDCDisplayContextConfigureIN->ui32PipeCount != 0)
 	{
-		psSurfInfoInt = OSAllocMemNoStats(psDCDisplayContextConfigureIN->ui32PipeCount * sizeof(PVRSRV_SURFACE_CONFIG_INFO));
-		if (!psSurfInfoInt)
-		{
-			psDCDisplayContextConfigureOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
-	
-			goto DCDisplayContextConfigure_exit;
-		}
+		psSurfInfoInt = (PVRSRV_SURFACE_CONFIG_INFO*)(((IMG_UINT8 *)pArrayArgsBuffer) + ui32NextOffset);
+		ui32NextOffset += psDCDisplayContextConfigureIN->ui32PipeCount * sizeof(PVRSRV_SURFACE_CONFIG_INFO);
 	}
 
 			/* Copy the data over */
-			if ( !OSAccessOK(PVR_VERIFY_READ, (void*) psDCDisplayContextConfigureIN->psSurfInfo, psDCDisplayContextConfigureIN->ui32PipeCount * sizeof(PVRSRV_SURFACE_CONFIG_INFO))
-				|| (OSCopyFromUser(NULL, psSurfInfoInt, psDCDisplayContextConfigureIN->psSurfInfo,
-				psDCDisplayContextConfigureIN->ui32PipeCount * sizeof(PVRSRV_SURFACE_CONFIG_INFO)) != PVRSRV_OK) )
+			if (psDCDisplayContextConfigureIN->ui32PipeCount * sizeof(PVRSRV_SURFACE_CONFIG_INFO) > 0)
 			{
-				psDCDisplayContextConfigureOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
+				if ( OSCopyFromUser(NULL, psSurfInfoInt, psDCDisplayContextConfigureIN->psSurfInfo, psDCDisplayContextConfigureIN->ui32PipeCount * sizeof(PVRSRV_SURFACE_CONFIG_INFO)) != PVRSRV_OK )
+				{
+					psDCDisplayContextConfigureOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
 
-				goto DCDisplayContextConfigure_exit;
+					goto DCDisplayContextConfigure_exit;
+				}
 			}
 	if (psDCDisplayContextConfigureIN->ui32PipeCount != 0)
 	{
-		psBuffersInt = OSAllocMemNoStats(psDCDisplayContextConfigureIN->ui32PipeCount * sizeof(DC_BUFFER *));
-		if (!psBuffersInt)
-		{
-			psDCDisplayContextConfigureOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
-	
-			goto DCDisplayContextConfigure_exit;
-		}
-		hBuffersInt2 = OSAllocMemNoStats(psDCDisplayContextConfigureIN->ui32PipeCount * sizeof(IMG_HANDLE));
-		if (!hBuffersInt2)
-		{
-			psDCDisplayContextConfigureOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
-	
-			goto DCDisplayContextConfigure_exit;
-		}
+		psBuffersInt = (DC_BUFFER **)(((IMG_UINT8 *)pArrayArgsBuffer) + ui32NextOffset);
+		ui32NextOffset += psDCDisplayContextConfigureIN->ui32PipeCount * sizeof(DC_BUFFER *);
+		hBuffersInt2 = (IMG_HANDLE *)(((IMG_UINT8 *)pArrayArgsBuffer) + ui32NextOffset); 
+		ui32NextOffset += psDCDisplayContextConfigureIN->ui32PipeCount * sizeof(IMG_HANDLE);
 	}
 
 			/* Copy the data over */
-			if ( !OSAccessOK(PVR_VERIFY_READ, (void*) psDCDisplayContextConfigureIN->phBuffers, psDCDisplayContextConfigureIN->ui32PipeCount * sizeof(IMG_HANDLE))
-				|| (OSCopyFromUser(NULL, hBuffersInt2, psDCDisplayContextConfigureIN->phBuffers,
-				psDCDisplayContextConfigureIN->ui32PipeCount * sizeof(IMG_HANDLE)) != PVRSRV_OK) )
+			if (psDCDisplayContextConfigureIN->ui32PipeCount * sizeof(IMG_HANDLE) > 0)
 			{
-				psDCDisplayContextConfigureOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
+				if ( OSCopyFromUser(NULL, hBuffersInt2, psDCDisplayContextConfigureIN->phBuffers, psDCDisplayContextConfigureIN->ui32PipeCount * sizeof(IMG_HANDLE)) != PVRSRV_OK )
+				{
+					psDCDisplayContextConfigureOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
 
-				goto DCDisplayContextConfigure_exit;
+					goto DCDisplayContextConfigure_exit;
+				}
 			}
 	if (psDCDisplayContextConfigureIN->ui32SyncCount != 0)
 	{
-		psSyncInt = OSAllocMemNoStats(psDCDisplayContextConfigureIN->ui32SyncCount * sizeof(SERVER_SYNC_PRIMITIVE *));
-		if (!psSyncInt)
-		{
-			psDCDisplayContextConfigureOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
-	
-			goto DCDisplayContextConfigure_exit;
-		}
-		hSyncInt2 = OSAllocMemNoStats(psDCDisplayContextConfigureIN->ui32SyncCount * sizeof(IMG_HANDLE));
-		if (!hSyncInt2)
-		{
-			psDCDisplayContextConfigureOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
-	
-			goto DCDisplayContextConfigure_exit;
-		}
+		psSyncInt = (SERVER_SYNC_PRIMITIVE **)(((IMG_UINT8 *)pArrayArgsBuffer) + ui32NextOffset);
+		ui32NextOffset += psDCDisplayContextConfigureIN->ui32SyncCount * sizeof(SERVER_SYNC_PRIMITIVE *);
+		hSyncInt2 = (IMG_HANDLE *)(((IMG_UINT8 *)pArrayArgsBuffer) + ui32NextOffset); 
+		ui32NextOffset += psDCDisplayContextConfigureIN->ui32SyncCount * sizeof(IMG_HANDLE);
 	}
 
 			/* Copy the data over */
-			if ( !OSAccessOK(PVR_VERIFY_READ, (void*) psDCDisplayContextConfigureIN->phSync, psDCDisplayContextConfigureIN->ui32SyncCount * sizeof(IMG_HANDLE))
-				|| (OSCopyFromUser(NULL, hSyncInt2, psDCDisplayContextConfigureIN->phSync,
-				psDCDisplayContextConfigureIN->ui32SyncCount * sizeof(IMG_HANDLE)) != PVRSRV_OK) )
+			if (psDCDisplayContextConfigureIN->ui32SyncCount * sizeof(IMG_HANDLE) > 0)
 			{
-				psDCDisplayContextConfigureOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
+				if ( OSCopyFromUser(NULL, hSyncInt2, psDCDisplayContextConfigureIN->phSync, psDCDisplayContextConfigureIN->ui32SyncCount * sizeof(IMG_HANDLE)) != PVRSRV_OK )
+				{
+					psDCDisplayContextConfigureOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
 
-				goto DCDisplayContextConfigure_exit;
+					goto DCDisplayContextConfigure_exit;
+				}
 			}
 	if (psDCDisplayContextConfigureIN->ui32SyncCount != 0)
 	{
-		bUpdateInt = OSAllocMemNoStats(psDCDisplayContextConfigureIN->ui32SyncCount * sizeof(IMG_BOOL));
-		if (!bUpdateInt)
-		{
-			psDCDisplayContextConfigureOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
-	
-			goto DCDisplayContextConfigure_exit;
-		}
+		bUpdateInt = (IMG_BOOL*)(((IMG_UINT8 *)pArrayArgsBuffer) + ui32NextOffset);
+		ui32NextOffset += psDCDisplayContextConfigureIN->ui32SyncCount * sizeof(IMG_BOOL);
 	}
 
 			/* Copy the data over */
-			if ( !OSAccessOK(PVR_VERIFY_READ, (void*) psDCDisplayContextConfigureIN->pbUpdate, psDCDisplayContextConfigureIN->ui32SyncCount * sizeof(IMG_BOOL))
-				|| (OSCopyFromUser(NULL, bUpdateInt, psDCDisplayContextConfigureIN->pbUpdate,
-				psDCDisplayContextConfigureIN->ui32SyncCount * sizeof(IMG_BOOL)) != PVRSRV_OK) )
+			if (psDCDisplayContextConfigureIN->ui32SyncCount * sizeof(IMG_BOOL) > 0)
 			{
-				psDCDisplayContextConfigureOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
+				if ( OSCopyFromUser(NULL, bUpdateInt, psDCDisplayContextConfigureIN->pbUpdate, psDCDisplayContextConfigureIN->ui32SyncCount * sizeof(IMG_BOOL)) != PVRSRV_OK )
+				{
+					psDCDisplayContextConfigureOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
 
-				goto DCDisplayContextConfigure_exit;
+					goto DCDisplayContextConfigure_exit;
+				}
 			}
 
+	/* Lock over handle lookup. */
+	LockHandle();
+
+
+
 
 
 				{
 					/* Look up the address from the handle */
 					psDCDisplayContextConfigureOUT->eError =
-						PVRSRVLookupHandle(psConnection->psHandleBase,
+						PVRSRVLookupHandleUnlocked(psConnection->psHandleBase,
 											(void **) &psDisplayContextInt,
-											psDCDisplayContextConfigureIN->hDisplayContext,
-											PVRSRV_HANDLE_TYPE_DC_DISPLAY_CONTEXT);
+											hDisplayContext,
+											PVRSRV_HANDLE_TYPE_DC_DISPLAY_CONTEXT,
+											IMG_TRUE);
 					if(psDCDisplayContextConfigureOUT->eError != PVRSRV_OK)
 					{
+						UnlockHandle();
 						goto DCDisplayContextConfigure_exit;
 					}
 				}
 
 
+
+
+
 	{
 		IMG_UINT32 i;
 
@@ -1109,19 +1791,24 @@
 				{
 					/* Look up the address from the handle */
 					psDCDisplayContextConfigureOUT->eError =
-						PVRSRVLookupHandle(psConnection->psHandleBase,
+						PVRSRVLookupHandleUnlocked(psConnection->psHandleBase,
 											(void **) &psBuffersInt[i],
 											hBuffersInt2[i],
-											PVRSRV_HANDLE_TYPE_DC_BUFFER);
+											PVRSRV_HANDLE_TYPE_DC_BUFFER,
+											IMG_TRUE);
 					if(psDCDisplayContextConfigureOUT->eError != PVRSRV_OK)
 					{
+						UnlockHandle();
 						goto DCDisplayContextConfigure_exit;
 					}
 				}
-
 		}
 	}
 
+
+
+
+
 	{
 		IMG_UINT32 i;
 
@@ -1130,18 +1817,21 @@
 				{
 					/* Look up the address from the handle */
 					psDCDisplayContextConfigureOUT->eError =
-						PVRSRVLookupHandle(psConnection->psHandleBase,
+						PVRSRVLookupHandleUnlocked(psConnection->psHandleBase,
 											(void **) &psSyncInt[i],
 											hSyncInt2[i],
-											PVRSRV_HANDLE_TYPE_SERVER_SYNC_PRIMITIVE);
+											PVRSRV_HANDLE_TYPE_SERVER_SYNC_PRIMITIVE,
+											IMG_TRUE);
 					if(psDCDisplayContextConfigureOUT->eError != PVRSRV_OK)
 					{
+						UnlockHandle();
 						goto DCDisplayContextConfigure_exit;
 					}
 				}
-
 		}
 	}
+	/* Release now we have looked up handles. */
+	UnlockHandle();
 
 	psDCDisplayContextConfigureOUT->eError =
 		DCDisplayContextConfigure(
@@ -1161,22 +1851,88 @@
 
 
 DCDisplayContextConfigure_exit:
-	if (psSurfInfoInt)
-		OSFreeMemNoStats(psSurfInfoInt);
-	if (psBuffersInt)
-		OSFreeMemNoStats(psBuffersInt);
+
+	/* Lock over handle lookup cleanup. */
+	LockHandle();
+
+
+
+
+
+
+				{
+					/* Unreference the previously looked up handle */
+						if(psDisplayContextInt)
+						{
+							PVRSRVReleaseHandleUnlocked(psConnection->psHandleBase,
+											hDisplayContext,
+											PVRSRV_HANDLE_TYPE_DC_DISPLAY_CONTEXT);
+						}
+				}
+
+
+
+
+
+
 	if (hBuffersInt2)
-		OSFreeMemNoStats(hBuffersInt2);
-	if (psSyncInt)
-		OSFreeMemNoStats(psSyncInt);
+	{
+		IMG_UINT32 i;
+
+		for (i=0;i<psDCDisplayContextConfigureIN->ui32PipeCount;i++)
+		{
+				{
+					/* Unreference the previously looked up handle */
+						if(psBuffersInt[i])
+						{
+							PVRSRVReleaseHandleUnlocked(psConnection->psHandleBase,
+											hBuffersInt2[i],
+											PVRSRV_HANDLE_TYPE_DC_BUFFER);
+						}
+				}
+		}
+	}
+
+
+
+
+
+
 	if (hSyncInt2)
-		OSFreeMemNoStats(hSyncInt2);
-	if (bUpdateInt)
-		OSFreeMemNoStats(bUpdateInt);
+	{
+		IMG_UINT32 i;
+
+		for (i=0;i<psDCDisplayContextConfigureIN->ui32SyncCount;i++)
+		{
+				{
+					/* Unreference the previously looked up handle */
+						if(psSyncInt[i])
+						{
+							PVRSRVReleaseHandleUnlocked(psConnection->psHandleBase,
+											hSyncInt2[i],
+											PVRSRV_HANDLE_TYPE_SERVER_SYNC_PRIMITIVE);
+						}
+				}
+		}
+	}
+	/* Release now we have cleaned up look up handles. */
+	UnlockHandle();
+
+	/* Allocated space should be equal to the last updated offset */
+	PVR_ASSERT(ui32BufferSize == ui32NextOffset);
+
+#if defined(INTEGRITY_OS)
+	if(pArrayArgsBuffer)
+#else
+	if(!bHaveEnoughSpace && pArrayArgsBuffer)
+#endif
+		OSFreeMemNoStats(pArrayArgsBuffer);
+
 
 	return 0;
 }
 
+
 static IMG_INT
 PVRSRVBridgeDCDisplayContextDestroy(IMG_UINT32 ui32DispatchTableEntry,
 					  PVRSRV_BRIDGE_IN_DCDISPLAYCONTEXTDESTROY *psDCDisplayContextDestroyIN,
@@ -1192,29 +1948,49 @@
 
 
 
+	/* Lock over handle destruction. */
+	LockHandle();
+
+
+
+
+
 	psDCDisplayContextDestroyOUT->eError =
-		PVRSRVReleaseHandle(psConnection->psHandleBase,
+		PVRSRVReleaseHandleUnlocked(psConnection->psHandleBase,
 					(IMG_HANDLE) psDCDisplayContextDestroyIN->hDisplayContext,
 					PVRSRV_HANDLE_TYPE_DC_DISPLAY_CONTEXT);
-	if ((psDCDisplayContextDestroyOUT->eError != PVRSRV_OK) && (psDCDisplayContextDestroyOUT->eError != PVRSRV_ERROR_RETRY))
+	if ((psDCDisplayContextDestroyOUT->eError != PVRSRV_OK) &&
+	    (psDCDisplayContextDestroyOUT->eError != PVRSRV_ERROR_RETRY))
 	{
+		PVR_DPF((PVR_DBG_ERROR,
+		        "PVRSRVBridgeDCDisplayContextDestroy: %s",
+		        PVRSRVGetErrorStringKM(psDCDisplayContextDestroyOUT->eError)));
 		PVR_ASSERT(0);
+		UnlockHandle();
 		goto DCDisplayContextDestroy_exit;
 	}
 
+	/* Release now we have destroyed handles. */
+	UnlockHandle();
+
 
 
 DCDisplayContextDestroy_exit:
 
+
+
+
 	return 0;
 }
 
+
 static IMG_INT
 PVRSRVBridgeDCBufferAlloc(IMG_UINT32 ui32DispatchTableEntry,
 					  PVRSRV_BRIDGE_IN_DCBUFFERALLOC *psDCBufferAllocIN,
 					  PVRSRV_BRIDGE_OUT_DCBUFFERALLOC *psDCBufferAllocOUT,
 					 CONNECTION_DATA *psConnection)
 {
+	IMG_HANDLE hDisplayContext = psDCBufferAllocIN->hDisplayContext;
 	DC_DISPLAY_CONTEXT * psDisplayContextInt = NULL;
 	DC_BUFFER * psBufferInt = NULL;
 
@@ -1224,19 +2000,29 @@
 
 
 
+	/* Lock over handle lookup. */
+	LockHandle();
+
+
+
+
+
 				{
 					/* Look up the address from the handle */
 					psDCBufferAllocOUT->eError =
-						PVRSRVLookupHandle(psConnection->psHandleBase,
+						PVRSRVLookupHandleUnlocked(psConnection->psHandleBase,
 											(void **) &psDisplayContextInt,
-											psDCBufferAllocIN->hDisplayContext,
-											PVRSRV_HANDLE_TYPE_DC_DISPLAY_CONTEXT);
+											hDisplayContext,
+											PVRSRV_HANDLE_TYPE_DC_DISPLAY_CONTEXT,
+											IMG_TRUE);
 					if(psDCBufferAllocOUT->eError != PVRSRV_OK)
 					{
+						UnlockHandle();
 						goto DCBufferAlloc_exit;
 					}
 				}
-
+	/* Release now we have looked up handles. */
+	UnlockHandle();
 
 	psDCBufferAllocOUT->eError =
 		DCBufferAlloc(
@@ -1250,8 +2036,15 @@
 		goto DCBufferAlloc_exit;
 	}
 
+	/* Lock over handle creation. */
+	LockHandle();
 
-	psDCBufferAllocOUT->eError = PVRSRVAllocHandle(psConnection->psHandleBase,
+
+
+
+
+	psDCBufferAllocOUT->eError = PVRSRVAllocHandleUnlocked(psConnection->psHandleBase,
+
 							&psDCBufferAllocOUT->hBuffer,
 							(void *) psBufferInt,
 							PVRSRV_HANDLE_TYPE_DC_BUFFER,
@@ -1259,13 +2052,37 @@
 							,(PFN_HANDLE_RELEASE)&DCBufferFree);
 	if (psDCBufferAllocOUT->eError != PVRSRV_OK)
 	{
+		UnlockHandle();
 		goto DCBufferAlloc_exit;
 	}
 
+	/* Release now we have created handles. */
+	UnlockHandle();
 
 
 
 DCBufferAlloc_exit:
+
+	/* Lock over handle lookup cleanup. */
+	LockHandle();
+
+
+
+
+
+
+				{
+					/* Unreference the previously looked up handle */
+						if(psDisplayContextInt)
+						{
+							PVRSRVReleaseHandleUnlocked(psConnection->psHandleBase,
+											hDisplayContext,
+											PVRSRV_HANDLE_TYPE_DC_DISPLAY_CONTEXT);
+						}
+				}
+	/* Release now we have cleaned up look up handles. */
+	UnlockHandle();
+
 	if (psDCBufferAllocOUT->eError != PVRSRV_OK)
 	{
 		if (psBufferInt)
@@ -1278,66 +2095,106 @@
 	return 0;
 }
 
+
 static IMG_INT
 PVRSRVBridgeDCBufferImport(IMG_UINT32 ui32DispatchTableEntry,
 					  PVRSRV_BRIDGE_IN_DCBUFFERIMPORT *psDCBufferImportIN,
 					  PVRSRV_BRIDGE_OUT_DCBUFFERIMPORT *psDCBufferImportOUT,
 					 CONNECTION_DATA *psConnection)
 {
+	IMG_HANDLE hDisplayContext = psDCBufferImportIN->hDisplayContext;
 	DC_DISPLAY_CONTEXT * psDisplayContextInt = NULL;
 	PMR * *psImportInt = NULL;
 	IMG_HANDLE *hImportInt2 = NULL;
 	DC_BUFFER * psBufferInt = NULL;
 
+	IMG_UINT32 ui32NextOffset = 0;
+	IMG_BYTE   *pArrayArgsBuffer = NULL;
+#if !defined(INTEGRITY_OS)
+	IMG_BOOL bHaveEnoughSpace = IMG_FALSE;
+#endif
+
+	IMG_UINT32 ui32BufferSize = 
+			(psDCBufferImportIN->ui32NumPlanes * sizeof(PMR *)) +
+			(psDCBufferImportIN->ui32NumPlanes * sizeof(IMG_HANDLE)) +
+			0;
 
 
 
-	if (psDCBufferImportIN->ui32NumPlanes != 0)
+
+
+	if (ui32BufferSize != 0)
 	{
-		psImportInt = OSAllocMemNoStats(psDCBufferImportIN->ui32NumPlanes * sizeof(PMR *));
-		if (!psImportInt)
+#if !defined(INTEGRITY_OS)
+		/* Try to use remainder of input buffer for copies if possible, word-aligned for safety. */
+		IMG_UINT32 ui32InBufferOffset = PVR_ALIGN(sizeof(*psDCBufferImportIN), sizeof(unsigned long));
+		IMG_UINT32 ui32InBufferExcessSize = ui32InBufferOffset >= PVRSRV_MAX_BRIDGE_IN_SIZE ? 0 :
+			PVRSRV_MAX_BRIDGE_IN_SIZE - ui32InBufferOffset;
+
+		bHaveEnoughSpace = ui32BufferSize <= ui32InBufferExcessSize;
+		if (bHaveEnoughSpace)
 		{
-			psDCBufferImportOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
-	
-			goto DCBufferImport_exit;
-		}
-		hImportInt2 = OSAllocMemNoStats(psDCBufferImportIN->ui32NumPlanes * sizeof(IMG_HANDLE));
-		if (!hImportInt2)
+			IMG_BYTE *pInputBuffer = (IMG_BYTE *)psDCBufferImportIN;
+
+			pArrayArgsBuffer = &pInputBuffer[ui32InBufferOffset];		}
+		else
+#endif
 		{
-			psDCBufferImportOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
-	
-			goto DCBufferImport_exit;
+			pArrayArgsBuffer = OSAllocMemNoStats(ui32BufferSize);
+
+			if(!pArrayArgsBuffer)
+			{
+				psDCBufferImportOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
+				goto DCBufferImport_exit;
+			}
 		}
 	}
 
-			/* Copy the data over */
-			if ( !OSAccessOK(PVR_VERIFY_READ, (void*) psDCBufferImportIN->phImport, psDCBufferImportIN->ui32NumPlanes * sizeof(IMG_HANDLE))
-				|| (OSCopyFromUser(NULL, hImportInt2, psDCBufferImportIN->phImport,
-				psDCBufferImportIN->ui32NumPlanes * sizeof(IMG_HANDLE)) != PVRSRV_OK) )
-			{
-				psDCBufferImportOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
+	if (psDCBufferImportIN->ui32NumPlanes != 0)
+	{
+		psImportInt = (PMR **)(((IMG_UINT8 *)pArrayArgsBuffer) + ui32NextOffset);
+		ui32NextOffset += psDCBufferImportIN->ui32NumPlanes * sizeof(PMR *);
+		hImportInt2 = (IMG_HANDLE *)(((IMG_UINT8 *)pArrayArgsBuffer) + ui32NextOffset); 
+		ui32NextOffset += psDCBufferImportIN->ui32NumPlanes * sizeof(IMG_HANDLE);
+	}
 
-				goto DCBufferImport_exit;
+			/* Copy the data over */
+			if (psDCBufferImportIN->ui32NumPlanes * sizeof(IMG_HANDLE) > 0)
+			{
+				if ( OSCopyFromUser(NULL, hImportInt2, psDCBufferImportIN->phImport, psDCBufferImportIN->ui32NumPlanes * sizeof(IMG_HANDLE)) != PVRSRV_OK )
+				{
+					psDCBufferImportOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
+
+					goto DCBufferImport_exit;
+				}
 			}
 
-	PMRLock();
+	/* Lock over handle lookup. */
+	LockHandle();
+
+
+
 
 
 				{
 					/* Look up the address from the handle */
 					psDCBufferImportOUT->eError =
-						PVRSRVLookupHandle(psConnection->psHandleBase,
+						PVRSRVLookupHandleUnlocked(psConnection->psHandleBase,
 											(void **) &psDisplayContextInt,
-											psDCBufferImportIN->hDisplayContext,
-											PVRSRV_HANDLE_TYPE_DC_DISPLAY_CONTEXT);
+											hDisplayContext,
+											PVRSRV_HANDLE_TYPE_DC_DISPLAY_CONTEXT,
+											IMG_TRUE);
 					if(psDCBufferImportOUT->eError != PVRSRV_OK)
 					{
-						PMRUnlock();
+						UnlockHandle();
 						goto DCBufferImport_exit;
 					}
 				}
 
 
+
+
+
 	{
 		IMG_UINT32 i;
 
@@ -1346,19 +2203,21 @@
 				{
 					/* Look up the address from the handle */
 					psDCBufferImportOUT->eError =
-						PVRSRVLookupHandle(psConnection->psHandleBase,
+						PVRSRVLookupHandleUnlocked(psConnection->psHandleBase,
 											(void **) &psImportInt[i],
 											hImportInt2[i],
-											PVRSRV_HANDLE_TYPE_PHYSMEM_PMR);
+											PVRSRV_HANDLE_TYPE_PHYSMEM_PMR,
+											IMG_TRUE);
 					if(psDCBufferImportOUT->eError != PVRSRV_OK)
 					{
-						PMRUnlock();
+						UnlockHandle();
 						goto DCBufferImport_exit;
 					}
 				}
-
 		}
 	}
+	/* Release now we have looked up handles. */
+	UnlockHandle();
 
 	psDCBufferImportOUT->eError =
 		DCBufferImport(
@@ -1370,13 +2229,18 @@
 	/* Exit early if bridged call fails */
 	if(psDCBufferImportOUT->eError != PVRSRV_OK)
 	{
-		PMRUnlock();
 		goto DCBufferImport_exit;
 	}
-	PMRUnlock();
+
+	/* Lock over handle creation. */
+	LockHandle();
 
 
-	psDCBufferImportOUT->eError = PVRSRVAllocHandle(psConnection->psHandleBase,
+
+
+
+	psDCBufferImportOUT->eError = PVRSRVAllocHandleUnlocked(psConnection->psHandleBase,
+
 							&psDCBufferImportOUT->hBuffer,
 							(void *) psBufferInt,
 							PVRSRV_HANDLE_TYPE_DC_BUFFER,
@@ -1384,13 +2248,60 @@
 							,(PFN_HANDLE_RELEASE)&DCBufferFree);
 	if (psDCBufferImportOUT->eError != PVRSRV_OK)
 	{
+		UnlockHandle();
 		goto DCBufferImport_exit;
 	}
 
+	/* Release now we have created handles. */
+	UnlockHandle();
 
 
 
 DCBufferImport_exit:
+
+	/* Lock over handle lookup cleanup. */
+	LockHandle();
+
+
+
+
+
+
+				{
+					/* Unreference the previously looked up handle */
+						if(psDisplayContextInt)
+						{
+							PVRSRVReleaseHandleUnlocked(psConnection->psHandleBase,
+											hDisplayContext,
+											PVRSRV_HANDLE_TYPE_DC_DISPLAY_CONTEXT);
+						}
+				}
+
+
+
+
+
+
+	if (hImportInt2)
+	{
+		IMG_UINT32 i;
+
+		for (i=0;i<psDCBufferImportIN->ui32NumPlanes;i++)
+		{
+				{
+					/* Unreference the previously looked up handle */
+						if(psImportInt[i])
+						{
+							PVRSRVReleaseHandleUnlocked(psConnection->psHandleBase,
+											hImportInt2[i],
+											PVRSRV_HANDLE_TYPE_PHYSMEM_PMR);
+						}
+				}
+		}
+	}
+	/* Release now we have cleaned up look up handles. */
+	UnlockHandle();
+
 	if (psDCBufferImportOUT->eError != PVRSRV_OK)
 	{
 		if (psBufferInt)
@@ -1399,14 +2310,21 @@
 		}
 	}
 
-	if (psImportInt)
-		OSFreeMemNoStats(psImportInt);
-	if (hImportInt2)
-		OSFreeMemNoStats(hImportInt2);
+	/* Allocated space should be equal to the last updated offset */
+	PVR_ASSERT(ui32BufferSize == ui32NextOffset);
+
+#if defined(INTEGRITY_OS)
+	if(pArrayArgsBuffer)
+#else
+	if(!bHaveEnoughSpace && pArrayArgsBuffer)
+#endif
+		OSFreeMemNoStats(pArrayArgsBuffer);
+
 
 	return 0;
 }
 
+
 static IMG_INT
 PVRSRVBridgeDCBufferFree(IMG_UINT32 ui32DispatchTableEntry,
 					  PVRSRV_BRIDGE_IN_DCBUFFERFREE *psDCBufferFreeIN,
@@ -1418,30 +2336,46 @@
 
 
 
-	PMRLock();
+
+
+
+
+	/* Lock over handle destruction. */
+	LockHandle();
+
 
 
 
 
 	psDCBufferFreeOUT->eError =
-		PVRSRVReleaseHandle(psConnection->psHandleBase,
+		PVRSRVReleaseHandleUnlocked(psConnection->psHandleBase,
 					(IMG_HANDLE) psDCBufferFreeIN->hBuffer,
 					PVRSRV_HANDLE_TYPE_DC_BUFFER);
-	if ((psDCBufferFreeOUT->eError != PVRSRV_OK) && (psDCBufferFreeOUT->eError != PVRSRV_ERROR_RETRY))
+	if ((psDCBufferFreeOUT->eError != PVRSRV_OK) &&
+	    (psDCBufferFreeOUT->eError != PVRSRV_ERROR_RETRY))
 	{
+		PVR_DPF((PVR_DBG_ERROR,
+		        "PVRSRVBridgeDCBufferFree: %s",
+		        PVRSRVGetErrorStringKM(psDCBufferFreeOUT->eError)));
 		PVR_ASSERT(0);
-		PMRUnlock();
+		UnlockHandle();
 		goto DCBufferFree_exit;
 	}
 
-	PMRUnlock();
+	/* Release now we have destroyed handles. */
+	UnlockHandle();
+
 
 
 DCBufferFree_exit:
 
+
+
+
 	return 0;
 }
 
+
 static IMG_INT
 PVRSRVBridgeDCBufferUnimport(IMG_UINT32 ui32DispatchTableEntry,
 					  PVRSRV_BRIDGE_IN_DCBUFFERUNIMPORT *psDCBufferUnimportIN,
@@ -1453,36 +2387,53 @@
 
 
 
-	PMRLock();
+
+
+
+
+	/* Lock over handle destruction. */
+	LockHandle();
+
 
 
 
 
 	psDCBufferUnimportOUT->eError =
-		PVRSRVReleaseHandle(psConnection->psHandleBase,
+		PVRSRVReleaseHandleUnlocked(psConnection->psHandleBase,
 					(IMG_HANDLE) psDCBufferUnimportIN->hBuffer,
 					PVRSRV_HANDLE_TYPE_DC_BUFFER);
-	if ((psDCBufferUnimportOUT->eError != PVRSRV_OK) && (psDCBufferUnimportOUT->eError != PVRSRV_ERROR_RETRY))
+	if ((psDCBufferUnimportOUT->eError != PVRSRV_OK) &&
+	    (psDCBufferUnimportOUT->eError != PVRSRV_ERROR_RETRY))
 	{
+		PVR_DPF((PVR_DBG_ERROR,
+		        "PVRSRVBridgeDCBufferUnimport: %s",
+		        PVRSRVGetErrorStringKM(psDCBufferUnimportOUT->eError)));
 		PVR_ASSERT(0);
-		PMRUnlock();
+		UnlockHandle();
 		goto DCBufferUnimport_exit;
 	}
 
-	PMRUnlock();
+	/* Release now we have destroyed handles. */
+	UnlockHandle();
+
 
 
 DCBufferUnimport_exit:
 
+
+
+
 	return 0;
 }
 
+
 static IMG_INT
 PVRSRVBridgeDCBufferPin(IMG_UINT32 ui32DispatchTableEntry,
 					  PVRSRV_BRIDGE_IN_DCBUFFERPIN *psDCBufferPinIN,
 					  PVRSRV_BRIDGE_OUT_DCBUFFERPIN *psDCBufferPinOUT,
 					 CONNECTION_DATA *psConnection)
 {
+	IMG_HANDLE hBuffer = psDCBufferPinIN->hBuffer;
 	DC_BUFFER * psBufferInt = NULL;
 	DC_PIN_HANDLE hPinHandleInt = NULL;
 
@@ -1492,19 +2443,29 @@
 
 
 
+	/* Lock over handle lookup. */
+	LockHandle();
+
+
+
+
+
 				{
 					/* Look up the address from the handle */
 					psDCBufferPinOUT->eError =
-						PVRSRVLookupHandle(psConnection->psHandleBase,
+						PVRSRVLookupHandleUnlocked(psConnection->psHandleBase,
 											(void **) &psBufferInt,
-											psDCBufferPinIN->hBuffer,
-											PVRSRV_HANDLE_TYPE_DC_BUFFER);
+											hBuffer,
+											PVRSRV_HANDLE_TYPE_DC_BUFFER,
+											IMG_TRUE);
 					if(psDCBufferPinOUT->eError != PVRSRV_OK)
 					{
+						UnlockHandle();
 						goto DCBufferPin_exit;
 					}
 				}
-
+	/* Release now we have looked up handles. */
+	UnlockHandle();
 
 	psDCBufferPinOUT->eError =
 		DCBufferPin(
@@ -1516,8 +2477,15 @@
 		goto DCBufferPin_exit;
 	}
 
+	/* Lock over handle creation. */
+	LockHandle();
 
-	psDCBufferPinOUT->eError = PVRSRVAllocHandle(psConnection->psHandleBase,
+
+
+
+
+	psDCBufferPinOUT->eError = PVRSRVAllocHandleUnlocked(psConnection->psHandleBase,
+
 							&psDCBufferPinOUT->hPinHandle,
 							(void *) hPinHandleInt,
 							PVRSRV_HANDLE_TYPE_DC_PIN_HANDLE,
@@ -1525,13 +2493,37 @@
 							,(PFN_HANDLE_RELEASE)&DCBufferUnpin);
 	if (psDCBufferPinOUT->eError != PVRSRV_OK)
 	{
+		UnlockHandle();
 		goto DCBufferPin_exit;
 	}
 
+	/* Release now we have created handles. */
+	UnlockHandle();
 
 
 
 DCBufferPin_exit:
+
+	/* Lock over handle lookup cleanup. */
+	LockHandle();
+
+
+
+
+
+
+				{
+					/* Unreference the previously looked up handle */
+						if(psBufferInt)
+						{
+							PVRSRVReleaseHandleUnlocked(psConnection->psHandleBase,
+											hBuffer,
+											PVRSRV_HANDLE_TYPE_DC_BUFFER);
+						}
+				}
+	/* Release now we have cleaned up look up handles. */
+	UnlockHandle();
+
 	if (psDCBufferPinOUT->eError != PVRSRV_OK)
 	{
 		if (hPinHandleInt)
@@ -1544,6 +2536,7 @@
 	return 0;
 }
 
+
 static IMG_INT
 PVRSRVBridgeDCBufferUnpin(IMG_UINT32 ui32DispatchTableEntry,
 					  PVRSRV_BRIDGE_IN_DCBUFFERUNPIN *psDCBufferUnpinIN,
@@ -1559,29 +2552,49 @@
 
 
 
+	/* Lock over handle destruction. */
+	LockHandle();
+
+
+
+
+
 	psDCBufferUnpinOUT->eError =
-		PVRSRVReleaseHandle(psConnection->psHandleBase,
+		PVRSRVReleaseHandleUnlocked(psConnection->psHandleBase,
 					(IMG_HANDLE) psDCBufferUnpinIN->hPinHandle,
 					PVRSRV_HANDLE_TYPE_DC_PIN_HANDLE);
-	if ((psDCBufferUnpinOUT->eError != PVRSRV_OK) && (psDCBufferUnpinOUT->eError != PVRSRV_ERROR_RETRY))
+	if ((psDCBufferUnpinOUT->eError != PVRSRV_OK) &&
+	    (psDCBufferUnpinOUT->eError != PVRSRV_ERROR_RETRY))
 	{
+		PVR_DPF((PVR_DBG_ERROR,
+		        "PVRSRVBridgeDCBufferUnpin: %s",
+		        PVRSRVGetErrorStringKM(psDCBufferUnpinOUT->eError)));
 		PVR_ASSERT(0);
+		UnlockHandle();
 		goto DCBufferUnpin_exit;
 	}
 
+	/* Release now we have destroyed handles. */
+	UnlockHandle();
+
 
 
 DCBufferUnpin_exit:
 
+
+
+
 	return 0;
 }
 
+
 static IMG_INT
 PVRSRVBridgeDCBufferAcquire(IMG_UINT32 ui32DispatchTableEntry,
 					  PVRSRV_BRIDGE_IN_DCBUFFERACQUIRE *psDCBufferAcquireIN,
 					  PVRSRV_BRIDGE_OUT_DCBUFFERACQUIRE *psDCBufferAcquireOUT,
 					 CONNECTION_DATA *psConnection)
 {
+	IMG_HANDLE hBuffer = psDCBufferAcquireIN->hBuffer;
 	DC_BUFFER * psBufferInt = NULL;
 	PMR * psExtMemInt = NULL;
 
@@ -1589,23 +2602,31 @@
 
 
 
-	PMRLock();
+
+
+	/* Lock over handle lookup. */
+	LockHandle();
+
+
+
 
 
 				{
 					/* Look up the address from the handle */
 					psDCBufferAcquireOUT->eError =
-						PVRSRVLookupHandle(psConnection->psHandleBase,
+						PVRSRVLookupHandleUnlocked(psConnection->psHandleBase,
 											(void **) &psBufferInt,
-											psDCBufferAcquireIN->hBuffer,
-											PVRSRV_HANDLE_TYPE_DC_BUFFER);
+											hBuffer,
+											PVRSRV_HANDLE_TYPE_DC_BUFFER,
+											IMG_TRUE);
 					if(psDCBufferAcquireOUT->eError != PVRSRV_OK)
 					{
-						PMRUnlock();
+						UnlockHandle();
 						goto DCBufferAcquire_exit;
 					}
 				}
-
+	/* Release now we have looked up handles. */
+	UnlockHandle();
 
 	psDCBufferAcquireOUT->eError =
 		DCBufferAcquire(
@@ -1614,13 +2635,18 @@
 	/* Exit early if bridged call fails */
 	if(psDCBufferAcquireOUT->eError != PVRSRV_OK)
 	{
-		PMRUnlock();
 		goto DCBufferAcquire_exit;
 	}
-	PMRUnlock();
+
+	/* Lock over handle creation. */
+	LockHandle();
 
 
-	psDCBufferAcquireOUT->eError = PVRSRVAllocHandle(psConnection->psHandleBase,
+
+
+
+	psDCBufferAcquireOUT->eError = PVRSRVAllocHandleUnlocked(psConnection->psHandleBase,
+
 							&psDCBufferAcquireOUT->hExtMem,
 							(void *) psExtMemInt,
 							PVRSRV_HANDLE_TYPE_DEVMEM_MEM_IMPORT,
@@ -1628,13 +2654,37 @@
 							,(PFN_HANDLE_RELEASE)&DCBufferRelease);
 	if (psDCBufferAcquireOUT->eError != PVRSRV_OK)
 	{
+		UnlockHandle();
 		goto DCBufferAcquire_exit;
 	}
 
+	/* Release now we have created handles. */
+	UnlockHandle();
 
 
 
 DCBufferAcquire_exit:
+
+	/* Lock over handle lookup cleanup. */
+	LockHandle();
+
+
+
+
+
+
+				{
+					/* Unreference the previously looked up handle */
+						if(psBufferInt)
+						{
+							PVRSRVReleaseHandleUnlocked(psConnection->psHandleBase,
+											hBuffer,
+											PVRSRV_HANDLE_TYPE_DC_BUFFER);
+						}
+				}
+	/* Release now we have cleaned up look up handles. */
+	UnlockHandle();
+
 	if (psDCBufferAcquireOUT->eError != PVRSRV_OK)
 	{
 		if (psExtMemInt)
@@ -1647,6 +2697,7 @@
 	return 0;
 }
 
+
 static IMG_INT
 PVRSRVBridgeDCBufferRelease(IMG_UINT32 ui32DispatchTableEntry,
 					  PVRSRV_BRIDGE_IN_DCBUFFERRELEASE *psDCBufferReleaseIN,
@@ -1658,32 +2709,48 @@
 
 
 
-	PMRLock();
+
+
+
+
+	/* Lock over handle destruction. */
+	LockHandle();
+
 
 
 
 
 	psDCBufferReleaseOUT->eError =
-		PVRSRVReleaseHandle(psConnection->psHandleBase,
+		PVRSRVReleaseHandleUnlocked(psConnection->psHandleBase,
 					(IMG_HANDLE) psDCBufferReleaseIN->hExtMem,
 					PVRSRV_HANDLE_TYPE_DEVMEM_MEM_IMPORT);
-	if ((psDCBufferReleaseOUT->eError != PVRSRV_OK) && (psDCBufferReleaseOUT->eError != PVRSRV_ERROR_RETRY))
+	if ((psDCBufferReleaseOUT->eError != PVRSRV_OK) &&
+	    (psDCBufferReleaseOUT->eError != PVRSRV_ERROR_RETRY))
 	{
+		PVR_DPF((PVR_DBG_ERROR,
+		        "PVRSRVBridgeDCBufferRelease: %s",
+		        PVRSRVGetErrorStringKM(psDCBufferReleaseOUT->eError)));
 		PVR_ASSERT(0);
-		PMRUnlock();
+		UnlockHandle();
 		goto DCBufferRelease_exit;
 	}
 
-	PMRUnlock();
+	/* Release now we have destroyed handles. */
+	UnlockHandle();
+
 
 
 DCBufferRelease_exit:
 
+
+
+
 	return 0;
 }
 
 
 
+
 /* *************************************************************************** 
  * Server bridge dispatch related glue 
  */
@@ -1788,4 +2855,3 @@
 {
 	return PVRSRV_OK;
 }
-
diff --git a/drivers/staging/imgtec/rogue/generated/debugmisc_bridge/common_debugmisc_bridge.h b/drivers/staging/imgtec/rogue/generated/debugmisc_bridge/common_debugmisc_bridge.h
index b2a5501..23656ae 100644
--- a/drivers/staging/imgtec/rogue/generated/debugmisc_bridge/common_debugmisc_bridge.h
+++ b/drivers/staging/imgtec/rogue/generated/debugmisc_bridge/common_debugmisc_bridge.h
@@ -2,8 +2,8 @@
 @File
 @Title          Common bridge header for debugmisc
 @Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
-@Description    Declares common defines and structures that are used by both
-                the client and sever side of the bridge for debugmisc
+@Description    Declares common defines and structures used by both the client
+                and server side of the bridge for debugmisc
 @License        Dual MIT/GPLv2
 
 The contents of this file are subject to the MIT license as set out below.
@@ -45,6 +45,8 @@
 #ifndef COMMON_DEBUGMISC_BRIDGE_H
 #define COMMON_DEBUGMISC_BRIDGE_H
 
+#include <powervr/mem_types.h>
+
 #include "img_types.h"
 #include "pvrsrv_error.h"
 
@@ -58,7 +60,10 @@
 #define PVRSRV_BRIDGE_DEBUGMISC_RGXDEBUGMISCSETFWLOG			PVRSRV_BRIDGE_DEBUGMISC_CMD_FIRST+1
 #define PVRSRV_BRIDGE_DEBUGMISC_RGXDEBUGMISCDUMPFREELISTPAGELIST			PVRSRV_BRIDGE_DEBUGMISC_CMD_FIRST+2
 #define PVRSRV_BRIDGE_DEBUGMISC_PHYSMEMIMPORTSECBUF			PVRSRV_BRIDGE_DEBUGMISC_CMD_FIRST+3
-#define PVRSRV_BRIDGE_DEBUGMISC_CMD_LAST			(PVRSRV_BRIDGE_DEBUGMISC_CMD_FIRST+3)
+#define PVRSRV_BRIDGE_DEBUGMISC_RGXDEBUGMISCSETHCSDEADLINE			PVRSRV_BRIDGE_DEBUGMISC_CMD_FIRST+4
+#define PVRSRV_BRIDGE_DEBUGMISC_RGXDEBUGMISCSETOSIDPRIORITY			PVRSRV_BRIDGE_DEBUGMISC_CMD_FIRST+5
+#define PVRSRV_BRIDGE_DEBUGMISC_RGXDEBUGMISCSETOSNEWONLINESTATE			PVRSRV_BRIDGE_DEBUGMISC_CMD_FIRST+6
+#define PVRSRV_BRIDGE_DEBUGMISC_CMD_LAST			(PVRSRV_BRIDGE_DEBUGMISC_CMD_FIRST+6)
 
 
 /*******************************************
@@ -121,17 +126,70 @@
 typedef struct PVRSRV_BRIDGE_IN_PHYSMEMIMPORTSECBUF_TAG
 {
 	IMG_DEVMEM_SIZE_T uiSize;
+	IMG_UINT32 ui32Log2Align;
 	PVRSRV_MEMALLOCFLAGS_T uiFlags;
 } __attribute__((packed)) PVRSRV_BRIDGE_IN_PHYSMEMIMPORTSECBUF;
 
 /* Bridge out structure for PhysmemImportSecBuf */
 typedef struct PVRSRV_BRIDGE_OUT_PHYSMEMIMPORTSECBUF_TAG
 {
-	IMG_UINT32 ui32Align;
 	IMG_HANDLE hPMRPtr;
 	IMG_UINT64 ui64SecBufHandle;
 	PVRSRV_ERROR eError;
 } __attribute__((packed)) PVRSRV_BRIDGE_OUT_PHYSMEMIMPORTSECBUF;
 
 
+/*******************************************
+            RGXDebugMiscSetHCSDeadline          
+ *******************************************/
+
+/* Bridge in structure for RGXDebugMiscSetHCSDeadline */
+typedef struct PVRSRV_BRIDGE_IN_RGXDEBUGMISCSETHCSDEADLINE_TAG
+{
+	IMG_UINT32 ui32RGXHCSDeadline;
+} __attribute__((packed)) PVRSRV_BRIDGE_IN_RGXDEBUGMISCSETHCSDEADLINE;
+
+/* Bridge out structure for RGXDebugMiscSetHCSDeadline */
+typedef struct PVRSRV_BRIDGE_OUT_RGXDEBUGMISCSETHCSDEADLINE_TAG
+{
+	PVRSRV_ERROR eError;
+} __attribute__((packed)) PVRSRV_BRIDGE_OUT_RGXDEBUGMISCSETHCSDEADLINE;
+
+
+/*******************************************
+            RGXDebugMiscSetOSidPriority          
+ *******************************************/
+
+/* Bridge in structure for RGXDebugMiscSetOSidPriority */
+typedef struct PVRSRV_BRIDGE_IN_RGXDEBUGMISCSETOSIDPRIORITY_TAG
+{
+	IMG_UINT32 ui32OSid;
+	IMG_UINT32 ui32Priority;
+} __attribute__((packed)) PVRSRV_BRIDGE_IN_RGXDEBUGMISCSETOSIDPRIORITY;
+
+/* Bridge out structure for RGXDebugMiscSetOSidPriority */
+typedef struct PVRSRV_BRIDGE_OUT_RGXDEBUGMISCSETOSIDPRIORITY_TAG
+{
+	PVRSRV_ERROR eError;
+} __attribute__((packed)) PVRSRV_BRIDGE_OUT_RGXDEBUGMISCSETOSIDPRIORITY;
+
+
+/*******************************************
+            RGXDebugMiscSetOSNewOnlineState          
+ *******************************************/
+
+/* Bridge in structure for RGXDebugMiscSetOSNewOnlineState */
+typedef struct PVRSRV_BRIDGE_IN_RGXDEBUGMISCSETOSNEWONLINESTATE_TAG
+{
+	IMG_UINT32 ui32OSid;
+	IMG_UINT32 ui32OSNewState;
+} __attribute__((packed)) PVRSRV_BRIDGE_IN_RGXDEBUGMISCSETOSNEWONLINESTATE;
+
+/* Bridge out structure for RGXDebugMiscSetOSNewOnlineState */
+typedef struct PVRSRV_BRIDGE_OUT_RGXDEBUGMISCSETOSNEWONLINESTATE_TAG
+{
+	PVRSRV_ERROR eError;
+} __attribute__((packed)) PVRSRV_BRIDGE_OUT_RGXDEBUGMISCSETOSNEWONLINESTATE;
+
+
 #endif /* COMMON_DEBUGMISC_BRIDGE_H */
diff --git a/drivers/staging/imgtec/rogue/generated/debugmisc_bridge/server_debugmisc_bridge.c b/drivers/staging/imgtec/rogue/generated/debugmisc_bridge/server_debugmisc_bridge.c
index 6dcf4b1..c3f5677 100644
--- a/drivers/staging/imgtec/rogue/generated/debugmisc_bridge/server_debugmisc_bridge.c
+++ b/drivers/staging/imgtec/rogue/generated/debugmisc_bridge/server_debugmisc_bridge.c
@@ -67,6 +67,8 @@
 
 
 
+
+
 /* ***************************************************************************
  * Server-side bridge entry points
  */
@@ -84,6 +86,7 @@
 
 
 
+
 	psDebugMiscSLCSetBypassStateOUT->eError =
 		PVRSRVDebugMiscSLCSetBypassStateKM(psConnection, OSGetDevData(psConnection),
 					psDebugMiscSLCSetBypassStateIN->ui32Flags,
@@ -93,9 +96,13 @@
 
 
 
+
+
+
 	return 0;
 }
 
+
 static IMG_INT
 PVRSRVBridgeRGXDebugMiscSetFWLog(IMG_UINT32 ui32DispatchTableEntry,
 					  PVRSRV_BRIDGE_IN_RGXDEBUGMISCSETFWLOG *psRGXDebugMiscSetFWLogIN,
@@ -109,6 +116,7 @@
 
 
 
+
 	psRGXDebugMiscSetFWLogOUT->eError =
 		PVRSRVRGXDebugMiscSetFWLogKM(psConnection, OSGetDevData(psConnection),
 					psRGXDebugMiscSetFWLogIN->ui32RGXFWLogType);
@@ -117,9 +125,13 @@
 
 
 
+
+
+
 	return 0;
 }
 
+
 static IMG_INT
 PVRSRVBridgeRGXDebugMiscDumpFreelistPageList(IMG_UINT32 ui32DispatchTableEntry,
 					  PVRSRV_BRIDGE_IN_RGXDEBUGMISCDUMPFREELISTPAGELIST *psRGXDebugMiscDumpFreelistPageListIN,
@@ -127,9 +139,10 @@
 					 CONNECTION_DATA *psConnection)
 {
 
-	PVR_UNREFERENCED_PARAMETER(psRGXDebugMiscDumpFreelistPageListIN);
 
 
+	PVR_UNREFERENCED_PARAMETER(psRGXDebugMiscDumpFreelistPageListIN);
+
 
 
 
@@ -142,9 +155,13 @@
 
 
 
+
+
+
 	return 0;
 }
 
+
 static IMG_INT
 PVRSRVBridgePhysmemImportSecBuf(IMG_UINT32 ui32DispatchTableEntry,
 					  PVRSRV_BRIDGE_IN_PHYSMEMIMPORTSECBUF *psPhysmemImportSecBufIN,
@@ -157,26 +174,31 @@
 
 
 
-	PMRLock();
+
 
 
 	psPhysmemImportSecBufOUT->eError =
 		PhysmemImportSecBuf(psConnection, OSGetDevData(psConnection),
 					psPhysmemImportSecBufIN->uiSize,
+					psPhysmemImportSecBufIN->ui32Log2Align,
 					psPhysmemImportSecBufIN->uiFlags,
-					&psPhysmemImportSecBufOUT->ui32Align,
 					&psPMRPtrInt,
 					&psPhysmemImportSecBufOUT->ui64SecBufHandle);
 	/* Exit early if bridged call fails */
 	if(psPhysmemImportSecBufOUT->eError != PVRSRV_OK)
 	{
-		PMRUnlock();
 		goto PhysmemImportSecBuf_exit;
 	}
-	PMRUnlock();
+
+	/* Lock over handle creation. */
+	LockHandle();
 
 
-	psPhysmemImportSecBufOUT->eError = PVRSRVAllocHandle(psConnection->psHandleBase,
+
+
+
+	psPhysmemImportSecBufOUT->eError = PVRSRVAllocHandleUnlocked(psConnection->psHandleBase,
+
 							&psPhysmemImportSecBufOUT->hPMRPtr,
 							(void *) psPMRPtrInt,
 							PVRSRV_HANDLE_TYPE_PHYSMEM_PMR,
@@ -184,13 +206,19 @@
 							,(PFN_HANDLE_RELEASE)&PMRUnrefPMR);
 	if (psPhysmemImportSecBufOUT->eError != PVRSRV_OK)
 	{
+		UnlockHandle();
 		goto PhysmemImportSecBuf_exit;
 	}
 
+	/* Release now we have created handles. */
+	UnlockHandle();
 
 
 
 PhysmemImportSecBuf_exit:
+
+
+
 	if (psPhysmemImportSecBufOUT->eError != PVRSRV_OK)
 	{
 		if (psPMRPtrInt)
@@ -204,6 +232,96 @@
 }
 
 
+static IMG_INT
+PVRSRVBridgeRGXDebugMiscSetHCSDeadline(IMG_UINT32 ui32DispatchTableEntry,
+					  PVRSRV_BRIDGE_IN_RGXDEBUGMISCSETHCSDEADLINE *psRGXDebugMiscSetHCSDeadlineIN,
+					  PVRSRV_BRIDGE_OUT_RGXDEBUGMISCSETHCSDEADLINE *psRGXDebugMiscSetHCSDeadlineOUT,
+					 CONNECTION_DATA *psConnection)
+{
+
+
+
+
+
+
+
+
+	psRGXDebugMiscSetHCSDeadlineOUT->eError =
+		PVRSRVRGXDebugMiscSetHCSDeadlineKM(psConnection, OSGetDevData(psConnection),
+					psRGXDebugMiscSetHCSDeadlineIN->ui32RGXHCSDeadline);
+
+
+
+
+
+
+
+
+	return 0;
+}
+
+
+static IMG_INT
+PVRSRVBridgeRGXDebugMiscSetOSidPriority(IMG_UINT32 ui32DispatchTableEntry,
+					  PVRSRV_BRIDGE_IN_RGXDEBUGMISCSETOSIDPRIORITY *psRGXDebugMiscSetOSidPriorityIN,
+					  PVRSRV_BRIDGE_OUT_RGXDEBUGMISCSETOSIDPRIORITY *psRGXDebugMiscSetOSidPriorityOUT,
+					 CONNECTION_DATA *psConnection)
+{
+
+
+
+
+
+
+
+
+	psRGXDebugMiscSetOSidPriorityOUT->eError =
+		PVRSRVRGXDebugMiscSetOSidPriorityKM(psConnection, OSGetDevData(psConnection),
+					psRGXDebugMiscSetOSidPriorityIN->ui32OSid,
+					psRGXDebugMiscSetOSidPriorityIN->ui32Priority);
+
+
+
+
+
+
+
+
+	return 0;
+}
+
+
+static IMG_INT
+PVRSRVBridgeRGXDebugMiscSetOSNewOnlineState(IMG_UINT32 ui32DispatchTableEntry,
+					  PVRSRV_BRIDGE_IN_RGXDEBUGMISCSETOSNEWONLINESTATE *psRGXDebugMiscSetOSNewOnlineStateIN,
+					  PVRSRV_BRIDGE_OUT_RGXDEBUGMISCSETOSNEWONLINESTATE *psRGXDebugMiscSetOSNewOnlineStateOUT,
+					 CONNECTION_DATA *psConnection)
+{
+
+
+
+
+
+
+
+
+	psRGXDebugMiscSetOSNewOnlineStateOUT->eError =
+		PVRSRVRGXDebugMiscSetOSNewOnlineStateKM(psConnection, OSGetDevData(psConnection),
+					psRGXDebugMiscSetOSNewOnlineStateIN->ui32OSid,
+					psRGXDebugMiscSetOSNewOnlineStateIN->ui32OSNewState);
+
+
+
+
+
+
+
+
+	return 0;
+}
+
+
+
 
 /* *************************************************************************** 
  * Server bridge dispatch related glue 
@@ -232,6 +350,15 @@
 	SetDispatchTableEntry(PVRSRV_BRIDGE_DEBUGMISC, PVRSRV_BRIDGE_DEBUGMISC_PHYSMEMIMPORTSECBUF, PVRSRVBridgePhysmemImportSecBuf,
 					NULL, bUseLock);
 
+	SetDispatchTableEntry(PVRSRV_BRIDGE_DEBUGMISC, PVRSRV_BRIDGE_DEBUGMISC_RGXDEBUGMISCSETHCSDEADLINE, PVRSRVBridgeRGXDebugMiscSetHCSDeadline,
+					NULL, bUseLock);
+
+	SetDispatchTableEntry(PVRSRV_BRIDGE_DEBUGMISC, PVRSRV_BRIDGE_DEBUGMISC_RGXDEBUGMISCSETOSIDPRIORITY, PVRSRVBridgeRGXDebugMiscSetOSidPriority,
+					NULL, bUseLock);
+
+	SetDispatchTableEntry(PVRSRV_BRIDGE_DEBUGMISC, PVRSRV_BRIDGE_DEBUGMISC_RGXDEBUGMISCSETOSNEWONLINESTATE, PVRSRVBridgeRGXDebugMiscSetOSNewOnlineState,
+					NULL, bUseLock);
+
 
 	return PVRSRV_OK;
 }
@@ -243,4 +370,3 @@
 {
 	return PVRSRV_OK;
 }
-
diff --git a/drivers/staging/imgtec/rogue/generated/devicememhistory_bridge/client_devicememhistory_bridge.h b/drivers/staging/imgtec/rogue/generated/devicememhistory_bridge/client_devicememhistory_bridge.h
index 1ed68b1..a47e2e4 100644
--- a/drivers/staging/imgtec/rogue/generated/devicememhistory_bridge/client_devicememhistory_bridge.h
+++ b/drivers/staging/imgtec/rogue/generated/devicememhistory_bridge/client_devicememhistory_bridge.h
@@ -64,5 +64,59 @@
 								   IMG_DEVMEM_SIZE_T uiSize,
 								   const IMG_CHAR *puiText);
 
+IMG_INTERNAL PVRSRV_ERROR IMG_CALLCONV BridgeDevicememHistoryMapNew(IMG_HANDLE hBridge,
+								    IMG_HANDLE hPMR,
+								    IMG_DEVMEM_SIZE_T uiOffset,
+								    IMG_DEV_VIRTADDR sDevVAddr,
+								    IMG_DEVMEM_SIZE_T uiSize,
+								    const IMG_CHAR *puiText,
+								    IMG_UINT32 ui32Log2PageSize,
+								    IMG_UINT32 ui32AllocationIndex,
+								    IMG_UINT32 *pui32AllocationIndexOut);
+
+IMG_INTERNAL PVRSRV_ERROR IMG_CALLCONV BridgeDevicememHistoryUnmapNew(IMG_HANDLE hBridge,
+								      IMG_HANDLE hPMR,
+								      IMG_DEVMEM_SIZE_T uiOffset,
+								      IMG_DEV_VIRTADDR sDevVAddr,
+								      IMG_DEVMEM_SIZE_T uiSize,
+								      const IMG_CHAR *puiText,
+								      IMG_UINT32 ui32Log2PageSize,
+								      IMG_UINT32 ui32AllocationIndex,
+								      IMG_UINT32 *pui32AllocationIndexOut);
+
+IMG_INTERNAL PVRSRV_ERROR IMG_CALLCONV BridgeDevicememHistoryMapVRange(IMG_HANDLE hBridge,
+								       IMG_DEV_VIRTADDR sBaseDevVAddr,
+								       IMG_UINT32 ui32ui32StartPage,
+								       IMG_UINT32 ui32NumPages,
+								       IMG_DEVMEM_SIZE_T uiAllocSize,
+								       const IMG_CHAR *puiText,
+								       IMG_UINT32 ui32Log2PageSize,
+								       IMG_UINT32 ui32AllocationIndex,
+								       IMG_UINT32 *pui32AllocationIndexOut);
+
+IMG_INTERNAL PVRSRV_ERROR IMG_CALLCONV BridgeDevicememHistoryUnmapVRange(IMG_HANDLE hBridge,
+									 IMG_DEV_VIRTADDR sBaseDevVAddr,
+									 IMG_UINT32 ui32ui32StartPage,
+									 IMG_UINT32 ui32NumPages,
+									 IMG_DEVMEM_SIZE_T uiAllocSize,
+									 const IMG_CHAR *puiText,
+									 IMG_UINT32 ui32Log2PageSize,
+									 IMG_UINT32 ui32AllocationIndex,
+									 IMG_UINT32 *pui32AllocationIndexOut);
+
+IMG_INTERNAL PVRSRV_ERROR IMG_CALLCONV BridgeDevicememHistorySparseChange(IMG_HANDLE hBridge,
+									  IMG_HANDLE hPMR,
+									  IMG_DEVMEM_SIZE_T uiOffset,
+									  IMG_DEV_VIRTADDR sDevVAddr,
+									  IMG_DEVMEM_SIZE_T uiSize,
+									  const IMG_CHAR *puiText,
+									  IMG_UINT32 ui32Log2PageSize,
+									  IMG_UINT32 ui32AllocPageCount,
+									  IMG_UINT32 *pui32AllocPageIndices,
+									  IMG_UINT32 ui32FreePageCount,
+									  IMG_UINT32 *pui32FreePageIndices,
+									  IMG_UINT32 ui32AllocationIndex,
+									  IMG_UINT32 *pui32AllocationIndexOut);
+
 
 #endif /* CLIENT_DEVICEMEMHISTORY_BRIDGE_H */
diff --git a/drivers/staging/imgtec/rogue/generated/devicememhistory_bridge/client_devicememhistory_direct_bridge.c b/drivers/staging/imgtec/rogue/generated/devicememhistory_bridge/client_devicememhistory_direct_bridge.c
index 21225f7..4d11c82 100644
--- a/drivers/staging/imgtec/rogue/generated/devicememhistory_bridge/client_devicememhistory_direct_bridge.c
+++ b/drivers/staging/imgtec/rogue/generated/devicememhistory_bridge/client_devicememhistory_direct_bridge.c
@@ -86,3 +86,157 @@
 	return eError;
 }
 
+IMG_INTERNAL PVRSRV_ERROR IMG_CALLCONV BridgeDevicememHistoryMapNew(IMG_HANDLE hBridge,
+								    IMG_HANDLE hPMR,
+								    IMG_DEVMEM_SIZE_T uiOffset,
+								    IMG_DEV_VIRTADDR sDevVAddr,
+								    IMG_DEVMEM_SIZE_T uiSize,
+								    const IMG_CHAR *puiText,
+								    IMG_UINT32 ui32Log2PageSize,
+								    IMG_UINT32 ui32AllocationIndex,
+								    IMG_UINT32 *pui32AllocationIndexOut)
+{
+	PVRSRV_ERROR eError;
+	PMR * psPMRInt;
+	PVR_UNREFERENCED_PARAMETER(hBridge);
+
+	psPMRInt = (PMR *) hPMR;
+
+	eError =
+		DevicememHistoryMapNewKM(
+					psPMRInt,
+					uiOffset,
+					sDevVAddr,
+					uiSize,
+					puiText,
+					ui32Log2PageSize,
+					ui32AllocationIndex,
+					pui32AllocationIndexOut);
+
+	return eError;
+}
+
+IMG_INTERNAL PVRSRV_ERROR IMG_CALLCONV BridgeDevicememHistoryUnmapNew(IMG_HANDLE hBridge,
+								      IMG_HANDLE hPMR,
+								      IMG_DEVMEM_SIZE_T uiOffset,
+								      IMG_DEV_VIRTADDR sDevVAddr,
+								      IMG_DEVMEM_SIZE_T uiSize,
+								      const IMG_CHAR *puiText,
+								      IMG_UINT32 ui32Log2PageSize,
+								      IMG_UINT32 ui32AllocationIndex,
+								      IMG_UINT32 *pui32AllocationIndexOut)
+{
+	PVRSRV_ERROR eError;
+	PMR * psPMRInt;
+	PVR_UNREFERENCED_PARAMETER(hBridge);
+
+	psPMRInt = (PMR *) hPMR;
+
+	eError =
+		DevicememHistoryUnmapNewKM(
+					psPMRInt,
+					uiOffset,
+					sDevVAddr,
+					uiSize,
+					puiText,
+					ui32Log2PageSize,
+					ui32AllocationIndex,
+					pui32AllocationIndexOut);
+
+	return eError;
+}
+
+IMG_INTERNAL PVRSRV_ERROR IMG_CALLCONV BridgeDevicememHistoryMapVRange(IMG_HANDLE hBridge,
+								       IMG_DEV_VIRTADDR sBaseDevVAddr,
+								       IMG_UINT32 ui32ui32StartPage,
+								       IMG_UINT32 ui32NumPages,
+								       IMG_DEVMEM_SIZE_T uiAllocSize,
+								       const IMG_CHAR *puiText,
+								       IMG_UINT32 ui32Log2PageSize,
+								       IMG_UINT32 ui32AllocationIndex,
+								       IMG_UINT32 *pui32AllocationIndexOut)
+{
+	PVRSRV_ERROR eError;
+	PVR_UNREFERENCED_PARAMETER(hBridge);
+
+
+	eError =
+		DevicememHistoryMapVRangeKM(
+					sBaseDevVAddr,
+					ui32ui32StartPage,
+					ui32NumPages,
+					uiAllocSize,
+					puiText,
+					ui32Log2PageSize,
+					ui32AllocationIndex,
+					pui32AllocationIndexOut);
+
+	return eError;
+}
+
+IMG_INTERNAL PVRSRV_ERROR IMG_CALLCONV BridgeDevicememHistoryUnmapVRange(IMG_HANDLE hBridge,
+									 IMG_DEV_VIRTADDR sBaseDevVAddr,
+									 IMG_UINT32 ui32ui32StartPage,
+									 IMG_UINT32 ui32NumPages,
+									 IMG_DEVMEM_SIZE_T uiAllocSize,
+									 const IMG_CHAR *puiText,
+									 IMG_UINT32 ui32Log2PageSize,
+									 IMG_UINT32 ui32AllocationIndex,
+									 IMG_UINT32 *pui32AllocationIndexOut)
+{
+	PVRSRV_ERROR eError;
+	PVR_UNREFERENCED_PARAMETER(hBridge);
+
+
+	eError =
+		DevicememHistoryUnmapVRangeKM(
+					sBaseDevVAddr,
+					ui32ui32StartPage,
+					ui32NumPages,
+					uiAllocSize,
+					puiText,
+					ui32Log2PageSize,
+					ui32AllocationIndex,
+					pui32AllocationIndexOut);
+
+	return eError;
+}
+
+IMG_INTERNAL PVRSRV_ERROR IMG_CALLCONV BridgeDevicememHistorySparseChange(IMG_HANDLE hBridge,
+									  IMG_HANDLE hPMR,
+									  IMG_DEVMEM_SIZE_T uiOffset,
+									  IMG_DEV_VIRTADDR sDevVAddr,
+									  IMG_DEVMEM_SIZE_T uiSize,
+									  const IMG_CHAR *puiText,
+									  IMG_UINT32 ui32Log2PageSize,
+									  IMG_UINT32 ui32AllocPageCount,
+									  IMG_UINT32 *pui32AllocPageIndices,
+									  IMG_UINT32 ui32FreePageCount,
+									  IMG_UINT32 *pui32FreePageIndices,
+									  IMG_UINT32 ui32AllocationIndex,
+									  IMG_UINT32 *pui32AllocationIndexOut)
+{
+	PVRSRV_ERROR eError;
+	PMR * psPMRInt;
+	PVR_UNREFERENCED_PARAMETER(hBridge);
+
+	psPMRInt = (PMR *) hPMR;
+
+	eError =
+		DevicememHistorySparseChangeKM(
+					psPMRInt,
+					uiOffset,
+					sDevVAddr,
+					uiSize,
+					puiText,
+					ui32Log2PageSize,
+					ui32AllocPageCount,
+					pui32AllocPageIndices,
+					ui32FreePageCount,
+					pui32FreePageIndices,
+					ui32AllocationIndex,
+					pui32AllocationIndexOut);
+
+	return eError;
+}
+
diff --git a/drivers/staging/imgtec/rogue/generated/devicememhistory_bridge/common_devicememhistory_bridge.h b/drivers/staging/imgtec/rogue/generated/devicememhistory_bridge/common_devicememhistory_bridge.h
index 63c6ec3..ed0a59a 100644
--- a/drivers/staging/imgtec/rogue/generated/devicememhistory_bridge/common_devicememhistory_bridge.h
+++ b/drivers/staging/imgtec/rogue/generated/devicememhistory_bridge/common_devicememhistory_bridge.h
@@ -2,8 +2,8 @@
 @File
 @Title          Common bridge header for devicememhistory
 @Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
-@Description    Declares common defines and structures that are used by both
-                the client and sever side of the bridge for devicememhistory
+@Description    Declares common defines and structures used by both the client
+                and server side of the bridge for devicememhistory
 @License        Dual MIT/GPLv2
 
 The contents of this file are subject to the MIT license as set out below.
@@ -45,6 +45,8 @@
 #ifndef COMMON_DEVICEMEMHISTORY_BRIDGE_H
 #define COMMON_DEVICEMEMHISTORY_BRIDGE_H
 
+#include <powervr/mem_types.h>
+
 #include "img_types.h"
 #include "pvrsrv_error.h"
 
@@ -55,7 +57,12 @@
 #define PVRSRV_BRIDGE_DEVICEMEMHISTORY_CMD_FIRST			0
 #define PVRSRV_BRIDGE_DEVICEMEMHISTORY_DEVICEMEMHISTORYMAP			PVRSRV_BRIDGE_DEVICEMEMHISTORY_CMD_FIRST+0
 #define PVRSRV_BRIDGE_DEVICEMEMHISTORY_DEVICEMEMHISTORYUNMAP			PVRSRV_BRIDGE_DEVICEMEMHISTORY_CMD_FIRST+1
-#define PVRSRV_BRIDGE_DEVICEMEMHISTORY_CMD_LAST			(PVRSRV_BRIDGE_DEVICEMEMHISTORY_CMD_FIRST+1)
+#define PVRSRV_BRIDGE_DEVICEMEMHISTORY_DEVICEMEMHISTORYMAPNEW			PVRSRV_BRIDGE_DEVICEMEMHISTORY_CMD_FIRST+2
+#define PVRSRV_BRIDGE_DEVICEMEMHISTORY_DEVICEMEMHISTORYUNMAPNEW			PVRSRV_BRIDGE_DEVICEMEMHISTORY_CMD_FIRST+3
+#define PVRSRV_BRIDGE_DEVICEMEMHISTORY_DEVICEMEMHISTORYMAPVRANGE			PVRSRV_BRIDGE_DEVICEMEMHISTORY_CMD_FIRST+4
+#define PVRSRV_BRIDGE_DEVICEMEMHISTORY_DEVICEMEMHISTORYUNMAPVRANGE			PVRSRV_BRIDGE_DEVICEMEMHISTORY_CMD_FIRST+5
+#define PVRSRV_BRIDGE_DEVICEMEMHISTORY_DEVICEMEMHISTORYSPARSECHANGE			PVRSRV_BRIDGE_DEVICEMEMHISTORY_CMD_FIRST+6
+#define PVRSRV_BRIDGE_DEVICEMEMHISTORY_CMD_LAST			(PVRSRV_BRIDGE_DEVICEMEMHISTORY_CMD_FIRST+6)
 
 
 /*******************************************
@@ -96,4 +103,128 @@
 } __attribute__((packed)) PVRSRV_BRIDGE_OUT_DEVICEMEMHISTORYUNMAP;
 
 
+/*******************************************
+            DevicememHistoryMapNew          
+ *******************************************/
+
+/* Bridge in structure for DevicememHistoryMapNew */
+typedef struct PVRSRV_BRIDGE_IN_DEVICEMEMHISTORYMAPNEW_TAG
+{
+	IMG_HANDLE hPMR;
+	IMG_DEVMEM_SIZE_T uiOffset;
+	IMG_DEV_VIRTADDR sDevVAddr;
+	IMG_DEVMEM_SIZE_T uiSize;
+	const IMG_CHAR * puiText;
+	IMG_UINT32 ui32Log2PageSize;
+	IMG_UINT32 ui32AllocationIndex;
+} __attribute__((packed)) PVRSRV_BRIDGE_IN_DEVICEMEMHISTORYMAPNEW;
+
+/* Bridge out structure for DevicememHistoryMapNew */
+typedef struct PVRSRV_BRIDGE_OUT_DEVICEMEMHISTORYMAPNEW_TAG
+{
+	IMG_UINT32 ui32AllocationIndexOut;
+	PVRSRV_ERROR eError;
+} __attribute__((packed)) PVRSRV_BRIDGE_OUT_DEVICEMEMHISTORYMAPNEW;
+
+
+/*******************************************
+            DevicememHistoryUnmapNew          
+ *******************************************/
+
+/* Bridge in structure for DevicememHistoryUnmapNew */
+typedef struct PVRSRV_BRIDGE_IN_DEVICEMEMHISTORYUNMAPNEW_TAG
+{
+	IMG_HANDLE hPMR;
+	IMG_DEVMEM_SIZE_T uiOffset;
+	IMG_DEV_VIRTADDR sDevVAddr;
+	IMG_DEVMEM_SIZE_T uiSize;
+	const IMG_CHAR * puiText;
+	IMG_UINT32 ui32Log2PageSize;
+	IMG_UINT32 ui32AllocationIndex;
+} __attribute__((packed)) PVRSRV_BRIDGE_IN_DEVICEMEMHISTORYUNMAPNEW;
+
+/* Bridge out structure for DevicememHistoryUnmapNew */
+typedef struct PVRSRV_BRIDGE_OUT_DEVICEMEMHISTORYUNMAPNEW_TAG
+{
+	IMG_UINT32 ui32AllocationIndexOut;
+	PVRSRV_ERROR eError;
+} __attribute__((packed)) PVRSRV_BRIDGE_OUT_DEVICEMEMHISTORYUNMAPNEW;
+
+
+/*******************************************
+            DevicememHistoryMapVRange          
+ *******************************************/
+
+/* Bridge in structure for DevicememHistoryMapVRange */
+typedef struct PVRSRV_BRIDGE_IN_DEVICEMEMHISTORYMAPVRANGE_TAG
+{
+	IMG_DEV_VIRTADDR sBaseDevVAddr;
+	IMG_UINT32 ui32ui32StartPage;
+	IMG_UINT32 ui32NumPages;
+	IMG_DEVMEM_SIZE_T uiAllocSize;
+	const IMG_CHAR * puiText;
+	IMG_UINT32 ui32Log2PageSize;
+	IMG_UINT32 ui32AllocationIndex;
+} __attribute__((packed)) PVRSRV_BRIDGE_IN_DEVICEMEMHISTORYMAPVRANGE;
+
+/* Bridge out structure for DevicememHistoryMapVRange */
+typedef struct PVRSRV_BRIDGE_OUT_DEVICEMEMHISTORYMAPVRANGE_TAG
+{
+	IMG_UINT32 ui32AllocationIndexOut;
+	PVRSRV_ERROR eError;
+} __attribute__((packed)) PVRSRV_BRIDGE_OUT_DEVICEMEMHISTORYMAPVRANGE;
+
+
+/*******************************************
+            DevicememHistoryUnmapVRange          
+ *******************************************/
+
+/* Bridge in structure for DevicememHistoryUnmapVRange */
+typedef struct PVRSRV_BRIDGE_IN_DEVICEMEMHISTORYUNMAPVRANGE_TAG
+{
+	IMG_DEV_VIRTADDR sBaseDevVAddr;
+	IMG_UINT32 ui32ui32StartPage;
+	IMG_UINT32 ui32NumPages;
+	IMG_DEVMEM_SIZE_T uiAllocSize;
+	const IMG_CHAR * puiText;
+	IMG_UINT32 ui32Log2PageSize;
+	IMG_UINT32 ui32AllocationIndex;
+} __attribute__((packed)) PVRSRV_BRIDGE_IN_DEVICEMEMHISTORYUNMAPVRANGE;
+
+/* Bridge out structure for DevicememHistoryUnmapVRange */
+typedef struct PVRSRV_BRIDGE_OUT_DEVICEMEMHISTORYUNMAPVRANGE_TAG
+{
+	IMG_UINT32 ui32AllocationIndexOut;
+	PVRSRV_ERROR eError;
+} __attribute__((packed)) PVRSRV_BRIDGE_OUT_DEVICEMEMHISTORYUNMAPVRANGE;
+
+
+/*******************************************
+            DevicememHistorySparseChange          
+ *******************************************/
+
+/* Bridge in structure for DevicememHistorySparseChange */
+typedef struct PVRSRV_BRIDGE_IN_DEVICEMEMHISTORYSPARSECHANGE_TAG
+{
+	IMG_HANDLE hPMR;
+	IMG_DEVMEM_SIZE_T uiOffset;
+	IMG_DEV_VIRTADDR sDevVAddr;
+	IMG_DEVMEM_SIZE_T uiSize;
+	const IMG_CHAR * puiText;
+	IMG_UINT32 ui32Log2PageSize;
+	IMG_UINT32 ui32AllocPageCount;
+	IMG_UINT32 * pui32AllocPageIndices;
+	IMG_UINT32 ui32FreePageCount;
+	IMG_UINT32 * pui32FreePageIndices;
+	IMG_UINT32 ui32AllocationIndex;
+} __attribute__((packed)) PVRSRV_BRIDGE_IN_DEVICEMEMHISTORYSPARSECHANGE;
+
+/* Bridge out structure for DevicememHistorySparseChange */
+typedef struct PVRSRV_BRIDGE_OUT_DEVICEMEMHISTORYSPARSECHANGE_TAG
+{
+	IMG_UINT32 ui32AllocationIndexOut;
+	PVRSRV_ERROR eError;
+} __attribute__((packed)) PVRSRV_BRIDGE_OUT_DEVICEMEMHISTORYSPARSECHANGE;
+
+
 #endif /* COMMON_DEVICEMEMHISTORY_BRIDGE_H */
diff --git a/drivers/staging/imgtec/rogue/generated/devicememhistory_bridge/server_devicememhistory_bridge.c b/drivers/staging/imgtec/rogue/generated/devicememhistory_bridge/server_devicememhistory_bridge.c
index 3641b3b..cb8bc58 100644
--- a/drivers/staging/imgtec/rogue/generated/devicememhistory_bridge/server_devicememhistory_bridge.c
+++ b/drivers/staging/imgtec/rogue/generated/devicememhistory_bridge/server_devicememhistory_bridge.c
@@ -64,6 +64,9 @@
 #include "lock.h"
 
 
+#if defined(SUPPORT_DEVICEMEMHISTORY_BRIDGE)
+
+
 
 /* ***************************************************************************
  * Server-side bridge entry points
@@ -77,33 +80,66 @@
 {
 	IMG_CHAR *uiTextInt = NULL;
 
+	IMG_UINT32 ui32NextOffset = 0;
+	IMG_BYTE   *pArrayArgsBuffer = NULL;
+#if !defined(INTEGRITY_OS)
+	IMG_BOOL bHaveEnoughSpace = IMG_FALSE;
+#endif
+
+	IMG_UINT32 ui32BufferSize = 
+			(DEVICEMEM_HISTORY_TEXT_BUFSZ * sizeof(IMG_CHAR)) +
+			0;
+
+
 	PVR_UNREFERENCED_PARAMETER(psConnection);
 
 
 
-	
+	if (ui32BufferSize != 0)
 	{
-		uiTextInt = OSAllocMemNoStats(DEVICEMEM_HISTORY_TEXT_BUFSZ * sizeof(IMG_CHAR));
-		if (!uiTextInt)
+#if !defined(INTEGRITY_OS)
+		/* Try to use remainder of input buffer for copies if possible, word-aligned for safety. */
+		IMG_UINT32 ui32InBufferOffset = PVR_ALIGN(sizeof(*psDevicememHistoryMapIN), sizeof(unsigned long));
+		IMG_UINT32 ui32InBufferExcessSize = ui32InBufferOffset >= PVRSRV_MAX_BRIDGE_IN_SIZE ? 0 :
+			PVRSRV_MAX_BRIDGE_IN_SIZE - ui32InBufferOffset;
+
+		bHaveEnoughSpace = ui32BufferSize <= ui32InBufferExcessSize;
+		if (bHaveEnoughSpace)
 		{
-			psDevicememHistoryMapOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
-	
-			goto DevicememHistoryMap_exit;
+			IMG_BYTE *pInputBuffer = (IMG_BYTE *)psDevicememHistoryMapIN;
+
+			pArrayArgsBuffer = &pInputBuffer[ui32InBufferOffset];		}
+		else
+#endif
+		{
+			pArrayArgsBuffer = OSAllocMemNoStats(ui32BufferSize);
+
+			if(!pArrayArgsBuffer)
+			{
+				psDevicememHistoryMapOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
+				goto DevicememHistoryMap_exit;
+			}
 		}
 	}
 
+	
+	{
+		uiTextInt = (IMG_CHAR*)(((IMG_UINT8 *)pArrayArgsBuffer) + ui32NextOffset);
+		ui32NextOffset += DEVICEMEM_HISTORY_TEXT_BUFSZ * sizeof(IMG_CHAR);
+	}
+
 			/* Copy the data over */
-			if ( !OSAccessOK(PVR_VERIFY_READ, (void*) psDevicememHistoryMapIN->puiText, DEVICEMEM_HISTORY_TEXT_BUFSZ * sizeof(IMG_CHAR))
-				|| (OSCopyFromUser(NULL, uiTextInt, psDevicememHistoryMapIN->puiText,
-				DEVICEMEM_HISTORY_TEXT_BUFSZ * sizeof(IMG_CHAR)) != PVRSRV_OK) )
+			if (DEVICEMEM_HISTORY_TEXT_BUFSZ * sizeof(IMG_CHAR) > 0)
 			{
-				psDevicememHistoryMapOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
+				if ( OSCopyFromUser(NULL, uiTextInt, psDevicememHistoryMapIN->puiText, DEVICEMEM_HISTORY_TEXT_BUFSZ * sizeof(IMG_CHAR)) != PVRSRV_OK )
+				{
+					psDevicememHistoryMapOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
 
-				goto DevicememHistoryMap_exit;
+					goto DevicememHistoryMap_exit;
+				}
 			}
 
 
-
 	psDevicememHistoryMapOUT->eError =
 		DevicememHistoryMapKM(
 					psDevicememHistoryMapIN->sDevVAddr,
@@ -114,12 +150,24 @@
 
 
 DevicememHistoryMap_exit:
-	if (uiTextInt)
-		OSFreeMemNoStats(uiTextInt);
+
+
+
+	/* Allocated space should be equal to the last updated offset */
+	PVR_ASSERT(ui32BufferSize == ui32NextOffset);
+
+#if defined(INTEGRITY_OS)
+	if(pArrayArgsBuffer)
+#else
+	if(!bHaveEnoughSpace && pArrayArgsBuffer)
+#endif
+		OSFreeMemNoStats(pArrayArgsBuffer);
+
 
 	return 0;
 }
 
+
 static IMG_INT
 PVRSRVBridgeDevicememHistoryUnmap(IMG_UINT32 ui32DispatchTableEntry,
 					  PVRSRV_BRIDGE_IN_DEVICEMEMHISTORYUNMAP *psDevicememHistoryUnmapIN,
@@ -128,33 +176,66 @@
 {
 	IMG_CHAR *uiTextInt = NULL;
 
+	IMG_UINT32 ui32NextOffset = 0;
+	IMG_BYTE   *pArrayArgsBuffer = NULL;
+#if !defined(INTEGRITY_OS)
+	IMG_BOOL bHaveEnoughSpace = IMG_FALSE;
+#endif
+
+	IMG_UINT32 ui32BufferSize = 
+			(DEVICEMEM_HISTORY_TEXT_BUFSZ * sizeof(IMG_CHAR)) +
+			0;
+
+
 	PVR_UNREFERENCED_PARAMETER(psConnection);
 
 
 
-	
+	if (ui32BufferSize != 0)
 	{
-		uiTextInt = OSAllocMemNoStats(DEVICEMEM_HISTORY_TEXT_BUFSZ * sizeof(IMG_CHAR));
-		if (!uiTextInt)
+#if !defined(INTEGRITY_OS)
+		/* Try to use remainder of input buffer for copies if possible, word-aligned for safety. */
+		IMG_UINT32 ui32InBufferOffset = PVR_ALIGN(sizeof(*psDevicememHistoryUnmapIN), sizeof(unsigned long));
+		IMG_UINT32 ui32InBufferExcessSize = ui32InBufferOffset >= PVRSRV_MAX_BRIDGE_IN_SIZE ? 0 :
+			PVRSRV_MAX_BRIDGE_IN_SIZE - ui32InBufferOffset;
+
+		bHaveEnoughSpace = ui32BufferSize <= ui32InBufferExcessSize;
+		if (bHaveEnoughSpace)
 		{
-			psDevicememHistoryUnmapOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
-	
-			goto DevicememHistoryUnmap_exit;
+			IMG_BYTE *pInputBuffer = (IMG_BYTE *)psDevicememHistoryUnmapIN;
+
+			pArrayArgsBuffer = &pInputBuffer[ui32InBufferOffset];		}
+		else
+#endif
+		{
+			pArrayArgsBuffer = OSAllocMemNoStats(ui32BufferSize);
+
+			if(!pArrayArgsBuffer)
+			{
+				psDevicememHistoryUnmapOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
+				goto DevicememHistoryUnmap_exit;
+			}
 		}
 	}
 
+	
+	{
+		uiTextInt = (IMG_CHAR*)(((IMG_UINT8 *)pArrayArgsBuffer) + ui32NextOffset);
+		ui32NextOffset += DEVICEMEM_HISTORY_TEXT_BUFSZ * sizeof(IMG_CHAR);
+	}
+
 			/* Copy the data over */
-			if ( !OSAccessOK(PVR_VERIFY_READ, (void*) psDevicememHistoryUnmapIN->puiText, DEVICEMEM_HISTORY_TEXT_BUFSZ * sizeof(IMG_CHAR))
-				|| (OSCopyFromUser(NULL, uiTextInt, psDevicememHistoryUnmapIN->puiText,
-				DEVICEMEM_HISTORY_TEXT_BUFSZ * sizeof(IMG_CHAR)) != PVRSRV_OK) )
+			if (DEVICEMEM_HISTORY_TEXT_BUFSZ * sizeof(IMG_CHAR) > 0)
 			{
-				psDevicememHistoryUnmapOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
+				if ( OSCopyFromUser(NULL, uiTextInt, psDevicememHistoryUnmapIN->puiText, DEVICEMEM_HISTORY_TEXT_BUFSZ * sizeof(IMG_CHAR)) != PVRSRV_OK )
+				{
+					psDevicememHistoryUnmapOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
 
-				goto DevicememHistoryUnmap_exit;
+					goto DevicememHistoryUnmap_exit;
+				}
 			}
 
 
-
 	psDevicememHistoryUnmapOUT->eError =
 		DevicememHistoryUnmapKM(
 					psDevicememHistoryUnmapIN->sDevVAddr,
@@ -165,13 +246,696 @@
 
 
 DevicememHistoryUnmap_exit:
-	if (uiTextInt)
-		OSFreeMemNoStats(uiTextInt);
+
+
+
+	/* Allocated space should be equal to the last updated offset */
+	PVR_ASSERT(ui32BufferSize == ui32NextOffset);
+
+#if defined(INTEGRITY_OS)
+	if(pArrayArgsBuffer)
+#else
+	if(!bHaveEnoughSpace && pArrayArgsBuffer)
+#endif
+		OSFreeMemNoStats(pArrayArgsBuffer);
+
 
 	return 0;
 }
 
 
+static IMG_INT
+PVRSRVBridgeDevicememHistoryMapNew(IMG_UINT32 ui32DispatchTableEntry,
+					  PVRSRV_BRIDGE_IN_DEVICEMEMHISTORYMAPNEW *psDevicememHistoryMapNewIN,
+					  PVRSRV_BRIDGE_OUT_DEVICEMEMHISTORYMAPNEW *psDevicememHistoryMapNewOUT,
+					 CONNECTION_DATA *psConnection)
+{
+	IMG_HANDLE hPMR = psDevicememHistoryMapNewIN->hPMR;
+	PMR * psPMRInt = NULL;
+	IMG_CHAR *uiTextInt = NULL;
+
+	IMG_UINT32 ui32NextOffset = 0;
+	IMG_BYTE   *pArrayArgsBuffer = NULL;
+#if !defined(INTEGRITY_OS)
+	IMG_BOOL bHaveEnoughSpace = IMG_FALSE;
+#endif
+
+	IMG_UINT32 ui32BufferSize = 
+			(DEVICEMEM_HISTORY_TEXT_BUFSZ * sizeof(IMG_CHAR)) +
+			0;
+
+
+
+
+
+	if (ui32BufferSize != 0)
+	{
+#if !defined(INTEGRITY_OS)
+		/* Try to use remainder of input buffer for copies if possible, word-aligned for safety. */
+		IMG_UINT32 ui32InBufferOffset = PVR_ALIGN(sizeof(*psDevicememHistoryMapNewIN), sizeof(unsigned long));
+		IMG_UINT32 ui32InBufferExcessSize = ui32InBufferOffset >= PVRSRV_MAX_BRIDGE_IN_SIZE ? 0 :
+			PVRSRV_MAX_BRIDGE_IN_SIZE - ui32InBufferOffset;
+
+		bHaveEnoughSpace = ui32BufferSize <= ui32InBufferExcessSize;
+		if (bHaveEnoughSpace)
+		{
+			IMG_BYTE *pInputBuffer = (IMG_BYTE *)psDevicememHistoryMapNewIN;
+
+			pArrayArgsBuffer = &pInputBuffer[ui32InBufferOffset];		}
+		else
+#endif
+		{
+			pArrayArgsBuffer = OSAllocMemNoStats(ui32BufferSize);
+
+			if(!pArrayArgsBuffer)
+			{
+				psDevicememHistoryMapNewOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
+				goto DevicememHistoryMapNew_exit;
+			}
+		}
+	}
+
+	
+	{
+		uiTextInt = (IMG_CHAR*)(((IMG_UINT8 *)pArrayArgsBuffer) + ui32NextOffset);
+		ui32NextOffset += DEVICEMEM_HISTORY_TEXT_BUFSZ * sizeof(IMG_CHAR);
+	}
+
+			/* Copy the data over */
+			if (DEVICEMEM_HISTORY_TEXT_BUFSZ * sizeof(IMG_CHAR) > 0)
+			{
+				if ( OSCopyFromUser(NULL, uiTextInt, psDevicememHistoryMapNewIN->puiText, DEVICEMEM_HISTORY_TEXT_BUFSZ * sizeof(IMG_CHAR)) != PVRSRV_OK )
+				{
+					psDevicememHistoryMapNewOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
+
+					goto DevicememHistoryMapNew_exit;
+				}
+			}
+
+	/* Lock over handle lookup. */
+	LockHandle();
+
+
+
+
+
+				{
+					/* Look up the address from the handle */
+					psDevicememHistoryMapNewOUT->eError =
+						PVRSRVLookupHandleUnlocked(psConnection->psHandleBase,
+											(void **) &psPMRInt,
+											hPMR,
+											PVRSRV_HANDLE_TYPE_PHYSMEM_PMR,
+											IMG_TRUE);
+					if(psDevicememHistoryMapNewOUT->eError != PVRSRV_OK)
+					{
+						UnlockHandle();
+						goto DevicememHistoryMapNew_exit;
+					}
+				}
+	/* Release now we have looked up handles. */
+	UnlockHandle();
+
+	psDevicememHistoryMapNewOUT->eError =
+		DevicememHistoryMapNewKM(
+					psPMRInt,
+					psDevicememHistoryMapNewIN->uiOffset,
+					psDevicememHistoryMapNewIN->sDevVAddr,
+					psDevicememHistoryMapNewIN->uiSize,
+					uiTextInt,
+					psDevicememHistoryMapNewIN->ui32Log2PageSize,
+					psDevicememHistoryMapNewIN->ui32AllocationIndex,
+					&psDevicememHistoryMapNewOUT->ui32AllocationIndexOut);
+
+
+
+
+DevicememHistoryMapNew_exit:
+
+	/* Lock over handle lookup cleanup. */
+	LockHandle();
+
+
+
+
+
+
+				{
+					/* Unreference the previously looked up handle */
+						if(psPMRInt)
+						{
+							PVRSRVReleaseHandleUnlocked(psConnection->psHandleBase,
+											hPMR,
+											PVRSRV_HANDLE_TYPE_PHYSMEM_PMR);
+						}
+				}
+	/* Release now we have cleaned up look up handles. */
+	UnlockHandle();
+
+	/* Allocated space should be equal to the last updated offset */
+	PVR_ASSERT(ui32BufferSize == ui32NextOffset);
+
+#if defined(INTEGRITY_OS)
+	if(pArrayArgsBuffer)
+#else
+	if(!bHaveEnoughSpace && pArrayArgsBuffer)
+#endif
+		OSFreeMemNoStats(pArrayArgsBuffer);
+
+
+	return 0;
+}
+
+
+static IMG_INT
+PVRSRVBridgeDevicememHistoryUnmapNew(IMG_UINT32 ui32DispatchTableEntry,
+					  PVRSRV_BRIDGE_IN_DEVICEMEMHISTORYUNMAPNEW *psDevicememHistoryUnmapNewIN,
+					  PVRSRV_BRIDGE_OUT_DEVICEMEMHISTORYUNMAPNEW *psDevicememHistoryUnmapNewOUT,
+					 CONNECTION_DATA *psConnection)
+{
+	IMG_HANDLE hPMR = psDevicememHistoryUnmapNewIN->hPMR;
+	PMR * psPMRInt = NULL;
+	IMG_CHAR *uiTextInt = NULL;
+
+	IMG_UINT32 ui32NextOffset = 0;
+	IMG_BYTE   *pArrayArgsBuffer = NULL;
+#if !defined(INTEGRITY_OS)
+	IMG_BOOL bHaveEnoughSpace = IMG_FALSE;
+#endif
+
+	IMG_UINT32 ui32BufferSize = 
+			(DEVICEMEM_HISTORY_TEXT_BUFSZ * sizeof(IMG_CHAR)) +
+			0;
+
+
+
+
+
+	if (ui32BufferSize != 0)
+	{
+#if !defined(INTEGRITY_OS)
+		/* Try to use remainder of input buffer for copies if possible, word-aligned for safety. */
+		IMG_UINT32 ui32InBufferOffset = PVR_ALIGN(sizeof(*psDevicememHistoryUnmapNewIN), sizeof(unsigned long));
+		IMG_UINT32 ui32InBufferExcessSize = ui32InBufferOffset >= PVRSRV_MAX_BRIDGE_IN_SIZE ? 0 :
+			PVRSRV_MAX_BRIDGE_IN_SIZE - ui32InBufferOffset;
+
+		bHaveEnoughSpace = ui32BufferSize <= ui32InBufferExcessSize;
+		if (bHaveEnoughSpace)
+		{
+			IMG_BYTE *pInputBuffer = (IMG_BYTE *)psDevicememHistoryUnmapNewIN;
+
+			pArrayArgsBuffer = &pInputBuffer[ui32InBufferOffset];		}
+		else
+#endif
+		{
+			pArrayArgsBuffer = OSAllocMemNoStats(ui32BufferSize);
+
+			if(!pArrayArgsBuffer)
+			{
+				psDevicememHistoryUnmapNewOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
+				goto DevicememHistoryUnmapNew_exit;
+			}
+		}
+	}
+
+	
+	{
+		uiTextInt = (IMG_CHAR*)(((IMG_UINT8 *)pArrayArgsBuffer) + ui32NextOffset);
+		ui32NextOffset += DEVICEMEM_HISTORY_TEXT_BUFSZ * sizeof(IMG_CHAR);
+	}
+
+			/* Copy the data over */
+			if (DEVICEMEM_HISTORY_TEXT_BUFSZ * sizeof(IMG_CHAR) > 0)
+			{
+				if ( OSCopyFromUser(NULL, uiTextInt, psDevicememHistoryUnmapNewIN->puiText, DEVICEMEM_HISTORY_TEXT_BUFSZ * sizeof(IMG_CHAR)) != PVRSRV_OK )
+				{
+					psDevicememHistoryUnmapNewOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
+
+					goto DevicememHistoryUnmapNew_exit;
+				}
+			}
+
+	/* Lock over handle lookup. */
+	LockHandle();
+
+
+
+
+
+				{
+					/* Look up the address from the handle */
+					psDevicememHistoryUnmapNewOUT->eError =
+						PVRSRVLookupHandleUnlocked(psConnection->psHandleBase,
+											(void **) &psPMRInt,
+											hPMR,
+											PVRSRV_HANDLE_TYPE_PHYSMEM_PMR,
+											IMG_TRUE);
+					if(psDevicememHistoryUnmapNewOUT->eError != PVRSRV_OK)
+					{
+						UnlockHandle();
+						goto DevicememHistoryUnmapNew_exit;
+					}
+				}
+	/* Release now we have looked up handles. */
+	UnlockHandle();
+
+	psDevicememHistoryUnmapNewOUT->eError =
+		DevicememHistoryUnmapNewKM(
+					psPMRInt,
+					psDevicememHistoryUnmapNewIN->uiOffset,
+					psDevicememHistoryUnmapNewIN->sDevVAddr,
+					psDevicememHistoryUnmapNewIN->uiSize,
+					uiTextInt,
+					psDevicememHistoryUnmapNewIN->ui32Log2PageSize,
+					psDevicememHistoryUnmapNewIN->ui32AllocationIndex,
+					&psDevicememHistoryUnmapNewOUT->ui32AllocationIndexOut);
+
+
+
+
+DevicememHistoryUnmapNew_exit:
+
+	/* Lock over handle lookup cleanup. */
+	LockHandle();
+
+
+
+
+
+
+				{
+					/* Unreference the previously looked up handle */
+						if(psPMRInt)
+						{
+							PVRSRVReleaseHandleUnlocked(psConnection->psHandleBase,
+											hPMR,
+											PVRSRV_HANDLE_TYPE_PHYSMEM_PMR);
+						}
+				}
+	/* Release now we have cleaned up look up handles. */
+	UnlockHandle();
+
+	/* Allocated space should be equal to the last updated offset */
+	PVR_ASSERT(ui32BufferSize == ui32NextOffset);
+
+#if defined(INTEGRITY_OS)
+	if(pArrayArgsBuffer)
+#else
+	if(!bHaveEnoughSpace && pArrayArgsBuffer)
+#endif
+		OSFreeMemNoStats(pArrayArgsBuffer);
+
+
+	return 0;
+}
+
+
+static IMG_INT
+PVRSRVBridgeDevicememHistoryMapVRange(IMG_UINT32 ui32DispatchTableEntry,
+					  PVRSRV_BRIDGE_IN_DEVICEMEMHISTORYMAPVRANGE *psDevicememHistoryMapVRangeIN,
+					  PVRSRV_BRIDGE_OUT_DEVICEMEMHISTORYMAPVRANGE *psDevicememHistoryMapVRangeOUT,
+					 CONNECTION_DATA *psConnection)
+{
+	IMG_CHAR *uiTextInt = NULL;
+
+	IMG_UINT32 ui32NextOffset = 0;
+	IMG_BYTE   *pArrayArgsBuffer = NULL;
+#if !defined(INTEGRITY_OS)
+	IMG_BOOL bHaveEnoughSpace = IMG_FALSE;
+#endif
+
+	IMG_UINT32 ui32BufferSize = 
+			(DEVICEMEM_HISTORY_TEXT_BUFSZ * sizeof(IMG_CHAR)) +
+			0;
+
+
+	PVR_UNREFERENCED_PARAMETER(psConnection);
+
+
+
+	if (ui32BufferSize != 0)
+	{
+#if !defined(INTEGRITY_OS)
+		/* Try to use remainder of input buffer for copies if possible, word-aligned for safety. */
+		IMG_UINT32 ui32InBufferOffset = PVR_ALIGN(sizeof(*psDevicememHistoryMapVRangeIN), sizeof(unsigned long));
+		IMG_UINT32 ui32InBufferExcessSize = ui32InBufferOffset >= PVRSRV_MAX_BRIDGE_IN_SIZE ? 0 :
+			PVRSRV_MAX_BRIDGE_IN_SIZE - ui32InBufferOffset;
+
+		bHaveEnoughSpace = ui32BufferSize <= ui32InBufferExcessSize;
+		if (bHaveEnoughSpace)
+		{
+			IMG_BYTE *pInputBuffer = (IMG_BYTE *)psDevicememHistoryMapVRangeIN;
+
+			pArrayArgsBuffer = &pInputBuffer[ui32InBufferOffset];		}
+		else
+#endif
+		{
+			pArrayArgsBuffer = OSAllocMemNoStats(ui32BufferSize);
+
+			if(!pArrayArgsBuffer)
+			{
+				psDevicememHistoryMapVRangeOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
+				goto DevicememHistoryMapVRange_exit;
+			}
+		}
+	}
+
+	
+	{
+		uiTextInt = (IMG_CHAR*)(((IMG_UINT8 *)pArrayArgsBuffer) + ui32NextOffset);
+		ui32NextOffset += DEVICEMEM_HISTORY_TEXT_BUFSZ * sizeof(IMG_CHAR);
+	}
+
+			/* Copy the data over */
+			if (DEVICEMEM_HISTORY_TEXT_BUFSZ * sizeof(IMG_CHAR) > 0)
+			{
+				if ( OSCopyFromUser(NULL, uiTextInt, psDevicememHistoryMapVRangeIN->puiText, DEVICEMEM_HISTORY_TEXT_BUFSZ * sizeof(IMG_CHAR)) != PVRSRV_OK )
+				{
+					psDevicememHistoryMapVRangeOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
+
+					goto DevicememHistoryMapVRange_exit;
+				}
+			}
+
+
+	psDevicememHistoryMapVRangeOUT->eError =
+		DevicememHistoryMapVRangeKM(
+					psDevicememHistoryMapVRangeIN->sBaseDevVAddr,
+					psDevicememHistoryMapVRangeIN->ui32ui32StartPage,
+					psDevicememHistoryMapVRangeIN->ui32NumPages,
+					psDevicememHistoryMapVRangeIN->uiAllocSize,
+					uiTextInt,
+					psDevicememHistoryMapVRangeIN->ui32Log2PageSize,
+					psDevicememHistoryMapVRangeIN->ui32AllocationIndex,
+					&psDevicememHistoryMapVRangeOUT->ui32AllocationIndexOut);
+
+
+
+
+DevicememHistoryMapVRange_exit:
+
+
+
+	/* Allocated space should be equal to the last updated offset */
+	PVR_ASSERT(ui32BufferSize == ui32NextOffset);
+
+#if defined(INTEGRITY_OS)
+	if(pArrayArgsBuffer)
+#else
+	if(!bHaveEnoughSpace && pArrayArgsBuffer)
+#endif
+		OSFreeMemNoStats(pArrayArgsBuffer);
+
+
+	return 0;
+}
+
+
+static IMG_INT
+PVRSRVBridgeDevicememHistoryUnmapVRange(IMG_UINT32 ui32DispatchTableEntry,
+					  PVRSRV_BRIDGE_IN_DEVICEMEMHISTORYUNMAPVRANGE *psDevicememHistoryUnmapVRangeIN,
+					  PVRSRV_BRIDGE_OUT_DEVICEMEMHISTORYUNMAPVRANGE *psDevicememHistoryUnmapVRangeOUT,
+					 CONNECTION_DATA *psConnection)
+{
+	IMG_CHAR *uiTextInt = NULL;
+
+	IMG_UINT32 ui32NextOffset = 0;
+	IMG_BYTE   *pArrayArgsBuffer = NULL;
+#if !defined(INTEGRITY_OS)
+	IMG_BOOL bHaveEnoughSpace = IMG_FALSE;
+#endif
+
+	IMG_UINT32 ui32BufferSize = 
+			(DEVICEMEM_HISTORY_TEXT_BUFSZ * sizeof(IMG_CHAR)) +
+			0;
+
+
+	PVR_UNREFERENCED_PARAMETER(psConnection);
+
+
+
+	if (ui32BufferSize != 0)
+	{
+#if !defined(INTEGRITY_OS)
+		/* Try to use remainder of input buffer for copies if possible, word-aligned for safety. */
+		IMG_UINT32 ui32InBufferOffset = PVR_ALIGN(sizeof(*psDevicememHistoryUnmapVRangeIN), sizeof(unsigned long));
+		IMG_UINT32 ui32InBufferExcessSize = ui32InBufferOffset >= PVRSRV_MAX_BRIDGE_IN_SIZE ? 0 :
+			PVRSRV_MAX_BRIDGE_IN_SIZE - ui32InBufferOffset;
+
+		bHaveEnoughSpace = ui32BufferSize <= ui32InBufferExcessSize;
+		if (bHaveEnoughSpace)
+		{
+			IMG_BYTE *pInputBuffer = (IMG_BYTE *)psDevicememHistoryUnmapVRangeIN;
+
+			pArrayArgsBuffer = &pInputBuffer[ui32InBufferOffset];		}
+		else
+#endif
+		{
+			pArrayArgsBuffer = OSAllocMemNoStats(ui32BufferSize);
+
+			if(!pArrayArgsBuffer)
+			{
+				psDevicememHistoryUnmapVRangeOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
+				goto DevicememHistoryUnmapVRange_exit;
+			}
+		}
+	}
+
+	
+	{
+		uiTextInt = (IMG_CHAR*)(((IMG_UINT8 *)pArrayArgsBuffer) + ui32NextOffset);
+		ui32NextOffset += DEVICEMEM_HISTORY_TEXT_BUFSZ * sizeof(IMG_CHAR);
+	}
+
+			/* Copy the data over */
+			if (DEVICEMEM_HISTORY_TEXT_BUFSZ * sizeof(IMG_CHAR) > 0)
+			{
+				if ( OSCopyFromUser(NULL, uiTextInt, psDevicememHistoryUnmapVRangeIN->puiText, DEVICEMEM_HISTORY_TEXT_BUFSZ * sizeof(IMG_CHAR)) != PVRSRV_OK )
+				{
+					psDevicememHistoryUnmapVRangeOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
+
+					goto DevicememHistoryUnmapVRange_exit;
+				}
+			}
+
+
+	psDevicememHistoryUnmapVRangeOUT->eError =
+		DevicememHistoryUnmapVRangeKM(
+					psDevicememHistoryUnmapVRangeIN->sBaseDevVAddr,
+					psDevicememHistoryUnmapVRangeIN->ui32ui32StartPage,
+					psDevicememHistoryUnmapVRangeIN->ui32NumPages,
+					psDevicememHistoryUnmapVRangeIN->uiAllocSize,
+					uiTextInt,
+					psDevicememHistoryUnmapVRangeIN->ui32Log2PageSize,
+					psDevicememHistoryUnmapVRangeIN->ui32AllocationIndex,
+					&psDevicememHistoryUnmapVRangeOUT->ui32AllocationIndexOut);
+
+
+
+
+DevicememHistoryUnmapVRange_exit:
+
+
+
+	/* Allocated space should be equal to the last updated offset */
+	PVR_ASSERT(ui32BufferSize == ui32NextOffset);
+
+#if defined(INTEGRITY_OS)
+	if(pArrayArgsBuffer)
+#else
+	if(!bHaveEnoughSpace && pArrayArgsBuffer)
+#endif
+		OSFreeMemNoStats(pArrayArgsBuffer);
+
+
+	return 0;
+}
+
+
+static IMG_INT
+PVRSRVBridgeDevicememHistorySparseChange(IMG_UINT32 ui32DispatchTableEntry,
+					  PVRSRV_BRIDGE_IN_DEVICEMEMHISTORYSPARSECHANGE *psDevicememHistorySparseChangeIN,
+					  PVRSRV_BRIDGE_OUT_DEVICEMEMHISTORYSPARSECHANGE *psDevicememHistorySparseChangeOUT,
+					 CONNECTION_DATA *psConnection)
+{
+	IMG_HANDLE hPMR = psDevicememHistorySparseChangeIN->hPMR;
+	PMR * psPMRInt = NULL;
+	IMG_CHAR *uiTextInt = NULL;
+	IMG_UINT32 *ui32AllocPageIndicesInt = NULL;
+	IMG_UINT32 *ui32FreePageIndicesInt = NULL;
+
+	IMG_UINT32 ui32NextOffset = 0;
+	IMG_BYTE   *pArrayArgsBuffer = NULL;
+#if !defined(INTEGRITY_OS)
+	IMG_BOOL bHaveEnoughSpace = IMG_FALSE;
+#endif
+
+	IMG_UINT32 ui32BufferSize = 
+			(DEVICEMEM_HISTORY_TEXT_BUFSZ * sizeof(IMG_CHAR)) +
+			(psDevicememHistorySparseChangeIN->ui32AllocPageCount * sizeof(IMG_UINT32)) +
+			(psDevicememHistorySparseChangeIN->ui32FreePageCount * sizeof(IMG_UINT32)) +
+			0;
+
+
+
+
+
+	if (ui32BufferSize != 0)
+	{
+#if !defined(INTEGRITY_OS)
+		/* Try to use remainder of input buffer for copies if possible, word-aligned for safety. */
+		IMG_UINT32 ui32InBufferOffset = PVR_ALIGN(sizeof(*psDevicememHistorySparseChangeIN), sizeof(unsigned long));
+		IMG_UINT32 ui32InBufferExcessSize = ui32InBufferOffset >= PVRSRV_MAX_BRIDGE_IN_SIZE ? 0 :
+			PVRSRV_MAX_BRIDGE_IN_SIZE - ui32InBufferOffset;
+
+		bHaveEnoughSpace = ui32BufferSize <= ui32InBufferExcessSize;
+		if (bHaveEnoughSpace)
+		{
+			IMG_BYTE *pInputBuffer = (IMG_BYTE *)psDevicememHistorySparseChangeIN;
+
+			pArrayArgsBuffer = &pInputBuffer[ui32InBufferOffset];		}
+		else
+#endif
+		{
+			pArrayArgsBuffer = OSAllocMemNoStats(ui32BufferSize);
+
+			if(!pArrayArgsBuffer)
+			{
+				psDevicememHistorySparseChangeOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
+				goto DevicememHistorySparseChange_exit;
+			}
+		}
+	}
+
+	
+	{
+		uiTextInt = (IMG_CHAR*)(((IMG_UINT8 *)pArrayArgsBuffer) + ui32NextOffset);
+		ui32NextOffset += DEVICEMEM_HISTORY_TEXT_BUFSZ * sizeof(IMG_CHAR);
+	}
+
+			/* Copy the data over */
+			if (DEVICEMEM_HISTORY_TEXT_BUFSZ * sizeof(IMG_CHAR) > 0)
+			{
+				if ( OSCopyFromUser(NULL, uiTextInt, psDevicememHistorySparseChangeIN->puiText, DEVICEMEM_HISTORY_TEXT_BUFSZ * sizeof(IMG_CHAR)) != PVRSRV_OK )
+				{
+					psDevicememHistorySparseChangeOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
+
+					goto DevicememHistorySparseChange_exit;
+				}
+			}
+	if (psDevicememHistorySparseChangeIN->ui32AllocPageCount != 0)
+	{
+		ui32AllocPageIndicesInt = (IMG_UINT32*)(((IMG_UINT8 *)pArrayArgsBuffer) + ui32NextOffset);
+		ui32NextOffset += psDevicememHistorySparseChangeIN->ui32AllocPageCount * sizeof(IMG_UINT32);
+	}
+
+			/* Copy the data over */
+			if (psDevicememHistorySparseChangeIN->ui32AllocPageCount * sizeof(IMG_UINT32) > 0)
+			{
+				if ( OSCopyFromUser(NULL, ui32AllocPageIndicesInt, psDevicememHistorySparseChangeIN->pui32AllocPageIndices, psDevicememHistorySparseChangeIN->ui32AllocPageCount * sizeof(IMG_UINT32)) != PVRSRV_OK )
+				{
+					psDevicememHistorySparseChangeOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
+
+					goto DevicememHistorySparseChange_exit;
+				}
+			}
+	if (psDevicememHistorySparseChangeIN->ui32FreePageCount != 0)
+	{
+		ui32FreePageIndicesInt = (IMG_UINT32*)(((IMG_UINT8 *)pArrayArgsBuffer) + ui32NextOffset);
+		ui32NextOffset += psDevicememHistorySparseChangeIN->ui32FreePageCount * sizeof(IMG_UINT32);
+	}
+
+			/* Copy the data over */
+			if (psDevicememHistorySparseChangeIN->ui32FreePageCount * sizeof(IMG_UINT32) > 0)
+			{
+				if ( OSCopyFromUser(NULL, ui32FreePageIndicesInt, psDevicememHistorySparseChangeIN->pui32FreePageIndices, psDevicememHistorySparseChangeIN->ui32FreePageCount * sizeof(IMG_UINT32)) != PVRSRV_OK )
+				{
+					psDevicememHistorySparseChangeOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
+
+					goto DevicememHistorySparseChange_exit;
+				}
+			}
+
+	/* Lock over handle lookup. */
+	LockHandle();
+
+
+
+
+
+				{
+					/* Look up the address from the handle */
+					psDevicememHistorySparseChangeOUT->eError =
+						PVRSRVLookupHandleUnlocked(psConnection->psHandleBase,
+											(void **) &psPMRInt,
+											hPMR,
+											PVRSRV_HANDLE_TYPE_PHYSMEM_PMR,
+											IMG_TRUE);
+					if(psDevicememHistorySparseChangeOUT->eError != PVRSRV_OK)
+					{
+						UnlockHandle();
+						goto DevicememHistorySparseChange_exit;
+					}
+				}
+	/* Release now we have looked up handles. */
+	UnlockHandle();
+
+	psDevicememHistorySparseChangeOUT->eError =
+		DevicememHistorySparseChangeKM(
+					psPMRInt,
+					psDevicememHistorySparseChangeIN->uiOffset,
+					psDevicememHistorySparseChangeIN->sDevVAddr,
+					psDevicememHistorySparseChangeIN->uiSize,
+					uiTextInt,
+					psDevicememHistorySparseChangeIN->ui32Log2PageSize,
+					psDevicememHistorySparseChangeIN->ui32AllocPageCount,
+					ui32AllocPageIndicesInt,
+					psDevicememHistorySparseChangeIN->ui32FreePageCount,
+					ui32FreePageIndicesInt,
+					psDevicememHistorySparseChangeIN->ui32AllocationIndex,
+					&psDevicememHistorySparseChangeOUT->ui32AllocationIndexOut);
+
+
+
+
+DevicememHistorySparseChange_exit:
+
+	/* Lock over handle lookup cleanup. */
+	LockHandle();
+
+
+
+
+
+
+				{
+					/* Unreference the previously looked up handle */
+						if(psPMRInt)
+						{
+							PVRSRVReleaseHandleUnlocked(psConnection->psHandleBase,
+											hPMR,
+											PVRSRV_HANDLE_TYPE_PHYSMEM_PMR);
+						}
+				}
+	/* Release now we have cleaned up look up handles. */
+	UnlockHandle();
+
+	/* Allocated space should be equal to the last updated offset */
+	PVR_ASSERT(ui32BufferSize == ui32NextOffset);
+
+#if defined(INTEGRITY_OS)
+	if(pArrayArgsBuffer)
+#else
+	if(!bHaveEnoughSpace && pArrayArgsBuffer)
+#endif
+		OSFreeMemNoStats(pArrayArgsBuffer);
+
+
+	return 0;
+}
+
+
+
 
 /* *************************************************************************** 
  * Server bridge dispatch related glue 
@@ -179,7 +943,9 @@
 
 static POS_LOCK pDEVICEMEMHISTORYBridgeLock;
 static IMG_BOOL bUseLock = IMG_TRUE;
+#endif /* SUPPORT_DEVICEMEMHISTORY_BRIDGE */
 
+#if defined(SUPPORT_DEVICEMEMHISTORY_BRIDGE)
 PVRSRV_ERROR InitDEVICEMEMHISTORYBridge(void);
 PVRSRV_ERROR DeinitDEVICEMEMHISTORYBridge(void);
 
@@ -196,6 +962,21 @@
 	SetDispatchTableEntry(PVRSRV_BRIDGE_DEVICEMEMHISTORY, PVRSRV_BRIDGE_DEVICEMEMHISTORY_DEVICEMEMHISTORYUNMAP, PVRSRVBridgeDevicememHistoryUnmap,
 					pDEVICEMEMHISTORYBridgeLock, bUseLock);
 
+	SetDispatchTableEntry(PVRSRV_BRIDGE_DEVICEMEMHISTORY, PVRSRV_BRIDGE_DEVICEMEMHISTORY_DEVICEMEMHISTORYMAPNEW, PVRSRVBridgeDevicememHistoryMapNew,
+					pDEVICEMEMHISTORYBridgeLock, bUseLock);
+
+	SetDispatchTableEntry(PVRSRV_BRIDGE_DEVICEMEMHISTORY, PVRSRV_BRIDGE_DEVICEMEMHISTORY_DEVICEMEMHISTORYUNMAPNEW, PVRSRVBridgeDevicememHistoryUnmapNew,
+					pDEVICEMEMHISTORYBridgeLock, bUseLock);
+
+	SetDispatchTableEntry(PVRSRV_BRIDGE_DEVICEMEMHISTORY, PVRSRV_BRIDGE_DEVICEMEMHISTORY_DEVICEMEMHISTORYMAPVRANGE, PVRSRVBridgeDevicememHistoryMapVRange,
+					pDEVICEMEMHISTORYBridgeLock, bUseLock);
+
+	SetDispatchTableEntry(PVRSRV_BRIDGE_DEVICEMEMHISTORY, PVRSRV_BRIDGE_DEVICEMEMHISTORY_DEVICEMEMHISTORYUNMAPVRANGE, PVRSRVBridgeDevicememHistoryUnmapVRange,
+					pDEVICEMEMHISTORYBridgeLock, bUseLock);
+
+	SetDispatchTableEntry(PVRSRV_BRIDGE_DEVICEMEMHISTORY, PVRSRV_BRIDGE_DEVICEMEMHISTORY_DEVICEMEMHISTORYSPARSECHANGE, PVRSRVBridgeDevicememHistorySparseChange,
+					pDEVICEMEMHISTORYBridgeLock, bUseLock);
+
 
 	return PVRSRV_OK;
 }
@@ -208,4 +989,14 @@
 	PVR_LOGR_IF_ERROR(OSLockDestroy(pDEVICEMEMHISTORYBridgeLock), "OSLockDestroy");
 	return PVRSRV_OK;
 }
+#else /* SUPPORT_DEVICEMEMHISTORY_BRIDGE */
+/* This bridge is conditional on SUPPORT_DEVICEMEMHISTORY_BRIDGE - when not defined,
+ * do not populate the dispatch table with its functions
+ */
+#define InitDEVICEMEMHISTORYBridge() \
+	PVRSRV_OK
 
+#define DeinitDEVICEMEMHISTORYBridge() \
+	PVRSRV_OK
+
+#endif /* SUPPORT_DEVICEMEMHISTORY_BRIDGE */
diff --git a/drivers/staging/imgtec/rogue/generated/dmabuf_bridge/common_dmabuf_bridge.h b/drivers/staging/imgtec/rogue/generated/dmabuf_bridge/common_dmabuf_bridge.h
index fc4c5a5..5647cbd 100644
--- a/drivers/staging/imgtec/rogue/generated/dmabuf_bridge/common_dmabuf_bridge.h
+++ b/drivers/staging/imgtec/rogue/generated/dmabuf_bridge/common_dmabuf_bridge.h
@@ -2,8 +2,8 @@
 @File
 @Title          Common bridge header for dmabuf
 @Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
-@Description    Declares common defines and structures that are used by both
-                the client and sever side of the bridge for dmabuf
+@Description    Declares common defines and structures used by both the client
+                and server side of the bridge for dmabuf
 @License        Dual MIT/GPLv2
 
 The contents of this file are subject to the MIT license as set out below.
@@ -45,6 +45,8 @@
 #ifndef COMMON_DMABUF_BRIDGE_H
 #define COMMON_DMABUF_BRIDGE_H
 
+#include <powervr/mem_types.h>
+
 #include "img_types.h"
 #include "pvrsrv_error.h"
 
@@ -54,7 +56,8 @@
 #define PVRSRV_BRIDGE_DMABUF_CMD_FIRST			0
 #define PVRSRV_BRIDGE_DMABUF_PHYSMEMIMPORTDMABUF			PVRSRV_BRIDGE_DMABUF_CMD_FIRST+0
 #define PVRSRV_BRIDGE_DMABUF_PHYSMEMEXPORTDMABUF			PVRSRV_BRIDGE_DMABUF_CMD_FIRST+1
-#define PVRSRV_BRIDGE_DMABUF_CMD_LAST			(PVRSRV_BRIDGE_DMABUF_CMD_FIRST+1)
+#define PVRSRV_BRIDGE_DMABUF_PHYSMEMIMPORTSPARSEDMABUF			PVRSRV_BRIDGE_DMABUF_CMD_FIRST+2
+#define PVRSRV_BRIDGE_DMABUF_CMD_LAST			(PVRSRV_BRIDGE_DMABUF_CMD_FIRST+2)
 
 
 /*******************************************
@@ -96,4 +99,29 @@
 } __attribute__((packed)) PVRSRV_BRIDGE_OUT_PHYSMEMEXPORTDMABUF;
 
 
+/*******************************************
+            PhysmemImportSparseDmaBuf          
+ *******************************************/
+
+/* Bridge in structure for PhysmemImportSparseDmaBuf */
+typedef struct PVRSRV_BRIDGE_IN_PHYSMEMIMPORTSPARSEDMABUF_TAG
+{
+	IMG_INT ifd;
+	PVRSRV_MEMALLOCFLAGS_T uiFlags;
+	IMG_DEVMEM_SIZE_T uiChunkSize;
+	IMG_UINT32 ui32NumPhysChunks;
+	IMG_UINT32 ui32NumVirtChunks;
+	IMG_UINT32 * pui32MappingTable;
+} __attribute__((packed)) PVRSRV_BRIDGE_IN_PHYSMEMIMPORTSPARSEDMABUF;
+
+/* Bridge out structure for PhysmemImportSparseDmaBuf */
+typedef struct PVRSRV_BRIDGE_OUT_PHYSMEMIMPORTSPARSEDMABUF_TAG
+{
+	IMG_HANDLE hPMRPtr;
+	IMG_DEVMEM_SIZE_T uiSize;
+	IMG_DEVMEM_ALIGN_T sAlign;
+	PVRSRV_ERROR eError;
+} __attribute__((packed)) PVRSRV_BRIDGE_OUT_PHYSMEMIMPORTSPARSEDMABUF;
+
+
 #endif /* COMMON_DMABUF_BRIDGE_H */
diff --git a/drivers/staging/imgtec/rogue/generated/dmabuf_bridge/server_dmabuf_bridge.c b/drivers/staging/imgtec/rogue/generated/dmabuf_bridge/server_dmabuf_bridge.c
index f2df3a1..01b289b 100644
--- a/drivers/staging/imgtec/rogue/generated/dmabuf_bridge/server_dmabuf_bridge.c
+++ b/drivers/staging/imgtec/rogue/generated/dmabuf_bridge/server_dmabuf_bridge.c
@@ -65,6 +65,8 @@
 
 
 
+
+
 /* ***************************************************************************
  * Server-side bridge entry points
  */
@@ -81,7 +83,7 @@
 
 
 
-	PMRLock();
+
 
 
 	psPhysmemImportDmaBufOUT->eError =
@@ -94,27 +96,38 @@
 	/* Exit early if bridged call fails */
 	if(psPhysmemImportDmaBufOUT->eError != PVRSRV_OK)
 	{
-		PMRUnlock();
 		goto PhysmemImportDmaBuf_exit;
 	}
-	PMRUnlock();
+
+	/* Lock over handle creation. */
+	LockHandle();
 
 
-	psPhysmemImportDmaBufOUT->eError = PVRSRVAllocHandle(psConnection->psHandleBase,
+
+
+
+	psPhysmemImportDmaBufOUT->eError = PVRSRVAllocHandleUnlocked(psConnection->psHandleBase,
+
 							&psPhysmemImportDmaBufOUT->hPMRPtr,
 							(void *) psPMRPtrInt,
 							PVRSRV_HANDLE_TYPE_PHYSMEM_PMR,
-							PVRSRV_HANDLE_ALLOC_FLAG_SHARED
+							PVRSRV_HANDLE_ALLOC_FLAG_MULTI
 							,(PFN_HANDLE_RELEASE)&PMRUnrefPMR);
 	if (psPhysmemImportDmaBufOUT->eError != PVRSRV_OK)
 	{
+		UnlockHandle();
 		goto PhysmemImportDmaBuf_exit;
 	}
 
+	/* Release now we have created handles. */
+	UnlockHandle();
 
 
 
 PhysmemImportDmaBuf_exit:
+
+
+
 	if (psPhysmemImportDmaBufOUT->eError != PVRSRV_OK)
 	{
 		if (psPMRPtrInt)
@@ -127,51 +140,219 @@
 	return 0;
 }
 
+
 static IMG_INT
 PVRSRVBridgePhysmemExportDmaBuf(IMG_UINT32 ui32DispatchTableEntry,
 					  PVRSRV_BRIDGE_IN_PHYSMEMEXPORTDMABUF *psPhysmemExportDmaBufIN,
 					  PVRSRV_BRIDGE_OUT_PHYSMEMEXPORTDMABUF *psPhysmemExportDmaBufOUT,
 					 CONNECTION_DATA *psConnection)
 {
+	IMG_HANDLE hPMR = psPhysmemExportDmaBufIN->hPMR;
 	PMR * psPMRInt = NULL;
 
 
 
 
 
-	PMRLock();
+
+
+	/* Lock over handle lookup. */
+	LockHandle();
+
+
+
 
 
 				{
 					/* Look up the address from the handle */
 					psPhysmemExportDmaBufOUT->eError =
-						PVRSRVLookupHandle(psConnection->psHandleBase,
+						PVRSRVLookupHandleUnlocked(psConnection->psHandleBase,
 											(void **) &psPMRInt,
-											psPhysmemExportDmaBufIN->hPMR,
-											PVRSRV_HANDLE_TYPE_PHYSMEM_PMR);
+											hPMR,
+											PVRSRV_HANDLE_TYPE_PHYSMEM_PMR,
+											IMG_TRUE);
 					if(psPhysmemExportDmaBufOUT->eError != PVRSRV_OK)
 					{
-						PMRUnlock();
+						UnlockHandle();
 						goto PhysmemExportDmaBuf_exit;
 					}
 				}
-
+	/* Release now we have looked up handles. */
+	UnlockHandle();
 
 	psPhysmemExportDmaBufOUT->eError =
 		PhysmemExportDmaBuf(psConnection, OSGetDevData(psConnection),
 					psPMRInt,
 					&psPhysmemExportDmaBufOUT->iFd);
-	PMRUnlock();
 
 
 
 
 PhysmemExportDmaBuf_exit:
 
+	/* Lock over handle lookup cleanup. */
+	LockHandle();
+
+
+
+
+
+
+				{
+					/* Unreference the previously looked up handle */
+						if(psPMRInt)
+						{
+							PVRSRVReleaseHandleUnlocked(psConnection->psHandleBase,
+											hPMR,
+											PVRSRV_HANDLE_TYPE_PHYSMEM_PMR);
+						}
+				}
+	/* Release now we have cleaned up look up handles. */
+	UnlockHandle();
+
+
 	return 0;
 }
 
 
+static IMG_INT
+PVRSRVBridgePhysmemImportSparseDmaBuf(IMG_UINT32 ui32DispatchTableEntry,
+					  PVRSRV_BRIDGE_IN_PHYSMEMIMPORTSPARSEDMABUF *psPhysmemImportSparseDmaBufIN,
+					  PVRSRV_BRIDGE_OUT_PHYSMEMIMPORTSPARSEDMABUF *psPhysmemImportSparseDmaBufOUT,
+					 CONNECTION_DATA *psConnection)
+{
+	IMG_UINT32 *ui32MappingTableInt = NULL;
+	PMR * psPMRPtrInt = NULL;
+
+	IMG_UINT32 ui32NextOffset = 0;
+	IMG_BYTE   *pArrayArgsBuffer = NULL;
+#if !defined(INTEGRITY_OS)
+	IMG_BOOL bHaveEnoughSpace = IMG_FALSE;
+#endif
+
+	IMG_UINT32 ui32BufferSize = 
+			(psPhysmemImportSparseDmaBufIN->ui32NumPhysChunks * sizeof(IMG_UINT32)) +
+			0;
+
+
+
+
+
+	if (ui32BufferSize != 0)
+	{
+#if !defined(INTEGRITY_OS)
+		/* Try to use remainder of input buffer for copies if possible, word-aligned for safety. */
+		IMG_UINT32 ui32InBufferOffset = PVR_ALIGN(sizeof(*psPhysmemImportSparseDmaBufIN), sizeof(unsigned long));
+		IMG_UINT32 ui32InBufferExcessSize = ui32InBufferOffset >= PVRSRV_MAX_BRIDGE_IN_SIZE ? 0 :
+			PVRSRV_MAX_BRIDGE_IN_SIZE - ui32InBufferOffset;
+
+		bHaveEnoughSpace = ui32BufferSize <= ui32InBufferExcessSize;
+		if (bHaveEnoughSpace)
+		{
+			IMG_BYTE *pInputBuffer = (IMG_BYTE *)psPhysmemImportSparseDmaBufIN;
+
+			pArrayArgsBuffer = &pInputBuffer[ui32InBufferOffset];		}
+		else
+#endif
+		{
+			pArrayArgsBuffer = OSAllocMemNoStats(ui32BufferSize);
+
+			if(!pArrayArgsBuffer)
+			{
+				psPhysmemImportSparseDmaBufOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
+				goto PhysmemImportSparseDmaBuf_exit;
+			}
+		}
+	}
+
+	if (psPhysmemImportSparseDmaBufIN->ui32NumPhysChunks != 0)
+	{
+		ui32MappingTableInt = (IMG_UINT32*)(((IMG_UINT8 *)pArrayArgsBuffer) + ui32NextOffset);
+		ui32NextOffset += psPhysmemImportSparseDmaBufIN->ui32NumPhysChunks * sizeof(IMG_UINT32);
+	}
+
+			/* Copy the data over */
+			if (psPhysmemImportSparseDmaBufIN->ui32NumPhysChunks * sizeof(IMG_UINT32) > 0)
+			{
+				if ( OSCopyFromUser(NULL, ui32MappingTableInt, psPhysmemImportSparseDmaBufIN->pui32MappingTable, psPhysmemImportSparseDmaBufIN->ui32NumPhysChunks * sizeof(IMG_UINT32)) != PVRSRV_OK )
+				{
+					psPhysmemImportSparseDmaBufOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
+
+					goto PhysmemImportSparseDmaBuf_exit;
+				}
+			}
+
+
+	psPhysmemImportSparseDmaBufOUT->eError =
+		PhysmemImportSparseDmaBuf(psConnection, OSGetDevData(psConnection),
+					psPhysmemImportSparseDmaBufIN->ifd,
+					psPhysmemImportSparseDmaBufIN->uiFlags,
+					psPhysmemImportSparseDmaBufIN->uiChunkSize,
+					psPhysmemImportSparseDmaBufIN->ui32NumPhysChunks,
+					psPhysmemImportSparseDmaBufIN->ui32NumVirtChunks,
+					ui32MappingTableInt,
+					&psPMRPtrInt,
+					&psPhysmemImportSparseDmaBufOUT->uiSize,
+					&psPhysmemImportSparseDmaBufOUT->sAlign);
+	/* Exit early if bridged call fails */
+	if(psPhysmemImportSparseDmaBufOUT->eError != PVRSRV_OK)
+	{
+		goto PhysmemImportSparseDmaBuf_exit;
+	}
+
+	/* Lock over handle creation. */
+	LockHandle();
+
+
+
+
+
+	psPhysmemImportSparseDmaBufOUT->eError = PVRSRVAllocHandleUnlocked(psConnection->psHandleBase,
+
+							&psPhysmemImportSparseDmaBufOUT->hPMRPtr,
+							(void *) psPMRPtrInt,
+							PVRSRV_HANDLE_TYPE_PHYSMEM_PMR,
+							PVRSRV_HANDLE_ALLOC_FLAG_MULTI
+							,(PFN_HANDLE_RELEASE)&PMRUnrefPMR);
+	if (psPhysmemImportSparseDmaBufOUT->eError != PVRSRV_OK)
+	{
+		UnlockHandle();
+		goto PhysmemImportSparseDmaBuf_exit;
+	}
+
+	/* Release now we have created handles. */
+	UnlockHandle();
+
+
+
+PhysmemImportSparseDmaBuf_exit:
+
+
+
+	if (psPhysmemImportSparseDmaBufOUT->eError != PVRSRV_OK)
+	{
+		if (psPMRPtrInt)
+		{
+			PMRUnrefPMR(psPMRPtrInt);
+		}
+	}
+
+	/* Allocated space should be equal to the last updated offset */
+	PVR_ASSERT(ui32BufferSize == ui32NextOffset);
+
+#if defined(INTEGRITY_OS)
+	if(pArrayArgsBuffer)
+#else
+	if(!bHaveEnoughSpace && pArrayArgsBuffer)
+#endif
+		OSFreeMemNoStats(pArrayArgsBuffer);
+
+
+	return 0;
+}
+
+
+
 
 /* *************************************************************************** 
  * Server bridge dispatch related glue 
@@ -194,6 +375,9 @@
 	SetDispatchTableEntry(PVRSRV_BRIDGE_DMABUF, PVRSRV_BRIDGE_DMABUF_PHYSMEMEXPORTDMABUF, PVRSRVBridgePhysmemExportDmaBuf,
 					NULL, bUseLock);
 
+	SetDispatchTableEntry(PVRSRV_BRIDGE_DMABUF, PVRSRV_BRIDGE_DMABUF_PHYSMEMIMPORTSPARSEDMABUF, PVRSRVBridgePhysmemImportSparseDmaBuf,
+					NULL, bUseLock);
+
 
 	return PVRSRV_OK;
 }
@@ -205,4 +389,3 @@
 {
 	return PVRSRV_OK;
 }
-
diff --git a/drivers/staging/imgtec/rogue/generated/htbuffer_bridge/common_htbuffer_bridge.h b/drivers/staging/imgtec/rogue/generated/htbuffer_bridge/common_htbuffer_bridge.h
index c77cd1f..496d736 100644
--- a/drivers/staging/imgtec/rogue/generated/htbuffer_bridge/common_htbuffer_bridge.h
+++ b/drivers/staging/imgtec/rogue/generated/htbuffer_bridge/common_htbuffer_bridge.h
@@ -2,8 +2,8 @@
 @File
 @Title          Common bridge header for htbuffer
 @Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
-@Description    Declares common defines and structures that are used by both
-                the client and sever side of the bridge for htbuffer
+@Description    Declares common defines and structures used by both the client
+                and server side of the bridge for htbuffer
 @License        Dual MIT/GPLv2
 
 The contents of this file are subject to the MIT license as set out below.
@@ -45,6 +45,8 @@
 #ifndef COMMON_HTBUFFER_BRIDGE_H
 #define COMMON_HTBUFFER_BRIDGE_H
 
+#include <powervr/mem_types.h>
+
 #include "img_types.h"
 #include "pvrsrv_error.h"
 
diff --git a/drivers/staging/imgtec/rogue/generated/htbuffer_bridge/server_htbuffer_bridge.c b/drivers/staging/imgtec/rogue/generated/htbuffer_bridge/server_htbuffer_bridge.c
index d4cf4f5..6356b7a 100644
--- a/drivers/staging/imgtec/rogue/generated/htbuffer_bridge/server_htbuffer_bridge.c
+++ b/drivers/staging/imgtec/rogue/generated/htbuffer_bridge/server_htbuffer_bridge.c
@@ -64,6 +64,9 @@
 #include "lock.h"
 
 
+#if !defined(EXCLUDE_HTBUFFER_BRIDGE)
+
+
 
 /* ***************************************************************************
  * Server-side bridge entry points
@@ -77,33 +80,66 @@
 {
 	IMG_CHAR *uiNameInt = NULL;
 
+	IMG_UINT32 ui32NextOffset = 0;
+	IMG_BYTE   *pArrayArgsBuffer = NULL;
+#if !defined(INTEGRITY_OS)
+	IMG_BOOL bHaveEnoughSpace = IMG_FALSE;
+#endif
+
+	IMG_UINT32 ui32BufferSize = 
+			(psHTBConfigureIN->ui32NameSize * sizeof(IMG_CHAR)) +
+			0;
+
+
 	PVR_UNREFERENCED_PARAMETER(psConnection);
 
 
 
-	if (psHTBConfigureIN->ui32NameSize != 0)
+	if (ui32BufferSize != 0)
 	{
-		uiNameInt = OSAllocMemNoStats(psHTBConfigureIN->ui32NameSize * sizeof(IMG_CHAR));
-		if (!uiNameInt)
+#if !defined(INTEGRITY_OS)
+		/* Try to use remainder of input buffer for copies if possible, word-aligned for safety. */
+		IMG_UINT32 ui32InBufferOffset = PVR_ALIGN(sizeof(*psHTBConfigureIN), sizeof(unsigned long));
+		IMG_UINT32 ui32InBufferExcessSize = ui32InBufferOffset >= PVRSRV_MAX_BRIDGE_IN_SIZE ? 0 :
+			PVRSRV_MAX_BRIDGE_IN_SIZE - ui32InBufferOffset;
+
+		bHaveEnoughSpace = ui32BufferSize <= ui32InBufferExcessSize;
+		if (bHaveEnoughSpace)
 		{
-			psHTBConfigureOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
-	
-			goto HTBConfigure_exit;
+			IMG_BYTE *pInputBuffer = (IMG_BYTE *)psHTBConfigureIN;
+
+			pArrayArgsBuffer = &pInputBuffer[ui32InBufferOffset];		}
+		else
+#endif
+		{
+			pArrayArgsBuffer = OSAllocMemNoStats(ui32BufferSize);
+
+			if(!pArrayArgsBuffer)
+			{
+				psHTBConfigureOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
+				goto HTBConfigure_exit;
+			}
 		}
 	}
 
+	if (psHTBConfigureIN->ui32NameSize != 0)
+	{
+		uiNameInt = (IMG_CHAR*)(((IMG_UINT8 *)pArrayArgsBuffer) + ui32NextOffset);
+		ui32NextOffset += psHTBConfigureIN->ui32NameSize * sizeof(IMG_CHAR);
+	}
+
 			/* Copy the data over */
-			if ( !OSAccessOK(PVR_VERIFY_READ, (void*) psHTBConfigureIN->puiName, psHTBConfigureIN->ui32NameSize * sizeof(IMG_CHAR))
-				|| (OSCopyFromUser(NULL, uiNameInt, psHTBConfigureIN->puiName,
-				psHTBConfigureIN->ui32NameSize * sizeof(IMG_CHAR)) != PVRSRV_OK) )
+			if (psHTBConfigureIN->ui32NameSize * sizeof(IMG_CHAR) > 0)
 			{
-				psHTBConfigureOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
+				if ( OSCopyFromUser(NULL, uiNameInt, psHTBConfigureIN->puiName, psHTBConfigureIN->ui32NameSize * sizeof(IMG_CHAR)) != PVRSRV_OK )
+				{
+					psHTBConfigureOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
 
-				goto HTBConfigure_exit;
+					goto HTBConfigure_exit;
+				}
 			}
 
 
-
 	psHTBConfigureOUT->eError =
 		HTBConfigureKM(
 					psHTBConfigureIN->ui32NameSize,
@@ -114,12 +150,24 @@
 
 
 HTBConfigure_exit:
-	if (uiNameInt)
-		OSFreeMemNoStats(uiNameInt);
+
+
+
+	/* Allocated space should be equal to the last updated offset */
+	PVR_ASSERT(ui32BufferSize == ui32NextOffset);
+
+#if defined(INTEGRITY_OS)
+	if(pArrayArgsBuffer)
+#else
+	if(!bHaveEnoughSpace && pArrayArgsBuffer)
+#endif
+		OSFreeMemNoStats(pArrayArgsBuffer);
+
 
 	return 0;
 }
 
+
 static IMG_INT
 PVRSRVBridgeHTBControl(IMG_UINT32 ui32DispatchTableEntry,
 					  PVRSRV_BRIDGE_IN_HTBCONTROL *psHTBControlIN,
@@ -128,33 +176,66 @@
 {
 	IMG_UINT32 *ui32GroupEnableInt = NULL;
 
+	IMG_UINT32 ui32NextOffset = 0;
+	IMG_BYTE   *pArrayArgsBuffer = NULL;
+#if !defined(INTEGRITY_OS)
+	IMG_BOOL bHaveEnoughSpace = IMG_FALSE;
+#endif
+
+	IMG_UINT32 ui32BufferSize = 
+			(psHTBControlIN->ui32NumGroups * sizeof(IMG_UINT32)) +
+			0;
+
+
 	PVR_UNREFERENCED_PARAMETER(psConnection);
 
 
 
-	if (psHTBControlIN->ui32NumGroups != 0)
+	if (ui32BufferSize != 0)
 	{
-		ui32GroupEnableInt = OSAllocMemNoStats(psHTBControlIN->ui32NumGroups * sizeof(IMG_UINT32));
-		if (!ui32GroupEnableInt)
+#if !defined(INTEGRITY_OS)
+		/* Try to use remainder of input buffer for copies if possible, word-aligned for safety. */
+		IMG_UINT32 ui32InBufferOffset = PVR_ALIGN(sizeof(*psHTBControlIN), sizeof(unsigned long));
+		IMG_UINT32 ui32InBufferExcessSize = ui32InBufferOffset >= PVRSRV_MAX_BRIDGE_IN_SIZE ? 0 :
+			PVRSRV_MAX_BRIDGE_IN_SIZE - ui32InBufferOffset;
+
+		bHaveEnoughSpace = ui32BufferSize <= ui32InBufferExcessSize;
+		if (bHaveEnoughSpace)
 		{
-			psHTBControlOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
-	
-			goto HTBControl_exit;
+			IMG_BYTE *pInputBuffer = (IMG_BYTE *)psHTBControlIN;
+
+			pArrayArgsBuffer = &pInputBuffer[ui32InBufferOffset];		}
+		else
+#endif
+		{
+			pArrayArgsBuffer = OSAllocMemNoStats(ui32BufferSize);
+
+			if(!pArrayArgsBuffer)
+			{
+				psHTBControlOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
+				goto HTBControl_exit;
+			}
 		}
 	}
 
+	if (psHTBControlIN->ui32NumGroups != 0)
+	{
+		ui32GroupEnableInt = (IMG_UINT32*)(((IMG_UINT8 *)pArrayArgsBuffer) + ui32NextOffset);
+		ui32NextOffset += psHTBControlIN->ui32NumGroups * sizeof(IMG_UINT32);
+	}
+
 			/* Copy the data over */
-			if ( !OSAccessOK(PVR_VERIFY_READ, (void*) psHTBControlIN->pui32GroupEnable, psHTBControlIN->ui32NumGroups * sizeof(IMG_UINT32))
-				|| (OSCopyFromUser(NULL, ui32GroupEnableInt, psHTBControlIN->pui32GroupEnable,
-				psHTBControlIN->ui32NumGroups * sizeof(IMG_UINT32)) != PVRSRV_OK) )
+			if (psHTBControlIN->ui32NumGroups * sizeof(IMG_UINT32) > 0)
 			{
-				psHTBControlOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
+				if ( OSCopyFromUser(NULL, ui32GroupEnableInt, psHTBControlIN->pui32GroupEnable, psHTBControlIN->ui32NumGroups * sizeof(IMG_UINT32)) != PVRSRV_OK )
+				{
+					psHTBControlOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
 
-				goto HTBControl_exit;
+					goto HTBControl_exit;
+				}
 			}
 
 
-
 	psHTBControlOUT->eError =
 		HTBControlKM(
 					psHTBControlIN->ui32NumGroups,
@@ -168,12 +249,24 @@
 
 
 HTBControl_exit:
-	if (ui32GroupEnableInt)
-		OSFreeMemNoStats(ui32GroupEnableInt);
+
+
+
+	/* Allocated space should be equal to the last updated offset */
+	PVR_ASSERT(ui32BufferSize == ui32NextOffset);
+
+#if defined(INTEGRITY_OS)
+	if(pArrayArgsBuffer)
+#else
+	if(!bHaveEnoughSpace && pArrayArgsBuffer)
+#endif
+		OSFreeMemNoStats(pArrayArgsBuffer);
+
 
 	return 0;
 }
 
+
 static IMG_INT
 PVRSRVBridgeHTBLog(IMG_UINT32 ui32DispatchTableEntry,
 					  PVRSRV_BRIDGE_IN_HTBLOG *psHTBLogIN,
@@ -182,33 +275,66 @@
 {
 	IMG_UINT32 *ui32ArgsInt = NULL;
 
+	IMG_UINT32 ui32NextOffset = 0;
+	IMG_BYTE   *pArrayArgsBuffer = NULL;
+#if !defined(INTEGRITY_OS)
+	IMG_BOOL bHaveEnoughSpace = IMG_FALSE;
+#endif
+
+	IMG_UINT32 ui32BufferSize = 
+			(psHTBLogIN->ui32NumArgs * sizeof(IMG_UINT32)) +
+			0;
+
+
 	PVR_UNREFERENCED_PARAMETER(psConnection);
 
 
 
-	if (psHTBLogIN->ui32NumArgs != 0)
+	if (ui32BufferSize != 0)
 	{
-		ui32ArgsInt = OSAllocMemNoStats(psHTBLogIN->ui32NumArgs * sizeof(IMG_UINT32));
-		if (!ui32ArgsInt)
+#if !defined(INTEGRITY_OS)
+		/* Try to use remainder of input buffer for copies if possible, word-aligned for safety. */
+		IMG_UINT32 ui32InBufferOffset = PVR_ALIGN(sizeof(*psHTBLogIN), sizeof(unsigned long));
+		IMG_UINT32 ui32InBufferExcessSize = ui32InBufferOffset >= PVRSRV_MAX_BRIDGE_IN_SIZE ? 0 :
+			PVRSRV_MAX_BRIDGE_IN_SIZE - ui32InBufferOffset;
+
+		bHaveEnoughSpace = ui32BufferSize <= ui32InBufferExcessSize;
+		if (bHaveEnoughSpace)
 		{
-			psHTBLogOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
-	
-			goto HTBLog_exit;
+			IMG_BYTE *pInputBuffer = (IMG_BYTE *)psHTBLogIN;
+
+			pArrayArgsBuffer = &pInputBuffer[ui32InBufferOffset];		}
+		else
+#endif
+		{
+			pArrayArgsBuffer = OSAllocMemNoStats(ui32BufferSize);
+
+			if(!pArrayArgsBuffer)
+			{
+				psHTBLogOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
+				goto HTBLog_exit;
+			}
 		}
 	}
 
+	if (psHTBLogIN->ui32NumArgs != 0)
+	{
+		ui32ArgsInt = (IMG_UINT32*)(((IMG_UINT8 *)pArrayArgsBuffer) + ui32NextOffset);
+		ui32NextOffset += psHTBLogIN->ui32NumArgs * sizeof(IMG_UINT32);
+	}
+
 			/* Copy the data over */
-			if ( !OSAccessOK(PVR_VERIFY_READ, (void*) psHTBLogIN->pui32Args, psHTBLogIN->ui32NumArgs * sizeof(IMG_UINT32))
-				|| (OSCopyFromUser(NULL, ui32ArgsInt, psHTBLogIN->pui32Args,
-				psHTBLogIN->ui32NumArgs * sizeof(IMG_UINT32)) != PVRSRV_OK) )
+			if (psHTBLogIN->ui32NumArgs * sizeof(IMG_UINT32) > 0)
 			{
-				psHTBLogOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
+				if ( OSCopyFromUser(NULL, ui32ArgsInt, psHTBLogIN->pui32Args, psHTBLogIN->ui32NumArgs * sizeof(IMG_UINT32)) != PVRSRV_OK )
+				{
+					psHTBLogOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
 
-				goto HTBLog_exit;
+					goto HTBLog_exit;
+				}
 			}
 
 
-
 	psHTBLogOUT->eError =
 		HTBLogKM(
 					psHTBLogIN->ui32PID,
@@ -221,21 +347,35 @@
 
 
 HTBLog_exit:
-	if (ui32ArgsInt)
-		OSFreeMemNoStats(ui32ArgsInt);
+
+
+
+	/* Allocated space should be equal to the last updated offset */
+	PVR_ASSERT(ui32BufferSize == ui32NextOffset);
+
+#if defined(INTEGRITY_OS)
+	if(pArrayArgsBuffer)
+#else
+	if(!bHaveEnoughSpace && pArrayArgsBuffer)
+#endif
+		OSFreeMemNoStats(pArrayArgsBuffer);
+
 
 	return 0;
 }
 
 
 
+
 /* *************************************************************************** 
  * Server bridge dispatch related glue 
  */
 
 static POS_LOCK pHTBUFFERBridgeLock;
 static IMG_BOOL bUseLock = IMG_TRUE;
+#endif /* EXCLUDE_HTBUFFER_BRIDGE */
 
+#if !defined(EXCLUDE_HTBUFFER_BRIDGE)
 PVRSRV_ERROR InitHTBUFFERBridge(void);
 PVRSRV_ERROR DeinitHTBUFFERBridge(void);
 
@@ -267,4 +407,14 @@
 	PVR_LOGR_IF_ERROR(OSLockDestroy(pHTBUFFERBridgeLock), "OSLockDestroy");
 	return PVRSRV_OK;
 }
+#else /* EXCLUDE_HTBUFFER_BRIDGE */
+/* This bridge is conditional on EXCLUDE_HTBUFFER_BRIDGE - when defined,
+ * do not populate the dispatch table with its functions
+ */
+#define InitHTBUFFERBridge() \
+	PVRSRV_OK
 
+#define DeinitHTBUFFERBridge() \
+	PVRSRV_OK
+
+#endif /* EXCLUDE_HTBUFFER_BRIDGE */
diff --git a/drivers/staging/imgtec/rogue/generated/mm_bridge/client_mm_bridge.h b/drivers/staging/imgtec/rogue/generated/mm_bridge/client_mm_bridge.h
index eec0210..5e470cb 100644
--- a/drivers/staging/imgtec/rogue/generated/mm_bridge/client_mm_bridge.h
+++ b/drivers/staging/imgtec/rogue/generated/mm_bridge/client_mm_bridge.h
@@ -102,6 +102,8 @@
 								    IMG_UINT32 *pui32MappingTable,
 								    IMG_UINT32 ui32Log2PageSize,
 								    PVRSRV_MEMALLOCFLAGS_T uiFlags,
+								    IMG_UINT32 ui32AnnotationLength,
+								    const IMG_CHAR *puiAnnotation,
 								    IMG_HANDLE *phPMRPtr);
 
 IMG_INTERNAL PVRSRV_ERROR IMG_CALLCONV BridgePhysmemNewRamBackedLockedPMR(IMG_HANDLE hBridge,
@@ -112,6 +114,8 @@
 									  IMG_UINT32 *pui32MappingTable,
 									  IMG_UINT32 ui32Log2PageSize,
 									  PVRSRV_MEMALLOCFLAGS_T uiFlags,
+									  IMG_UINT32 ui32AnnotationLength,
+									  const IMG_CHAR *puiAnnotation,
 									  IMG_HANDLE *phPMRPtr);
 
 IMG_INTERNAL PVRSRV_ERROR IMG_CALLCONV BridgeDevmemIntPin(IMG_HANDLE hBridge,
@@ -131,7 +135,8 @@
 IMG_INTERNAL PVRSRV_ERROR IMG_CALLCONV BridgeDevmemIntCtxCreate(IMG_HANDLE hBridge,
 								IMG_BOOL bbKernelMemoryCtx,
 								IMG_HANDLE *phDevMemServerContext,
-								IMG_HANDLE *phPrivData);
+								IMG_HANDLE *phPrivData,
+								IMG_UINT32 *pui32CPUCacheLineSize);
 
 IMG_INTERNAL PVRSRV_ERROR IMG_CALLCONV BridgeDevmemIntCtxDestroy(IMG_HANDLE hBridge,
 								 IMG_HANDLE hDevmemServerContext);
@@ -175,8 +180,7 @@
 							     IMG_UINT32 ui32SparseFlags,
 							     PVRSRV_MEMALLOCFLAGS_T uiFlags,
 							     IMG_DEV_VIRTADDR sDevVAddr,
-							     IMG_UINT64 ui64CPUVAddr,
-							     IMG_UINT32 *pui32Status);
+							     IMG_UINT64 ui64CPUVAddr);
 
 IMG_INTERNAL PVRSRV_ERROR IMG_CALLCONV BridgeDevmemIntMapPages(IMG_HANDLE hBridge,
 							       IMG_HANDLE hReservation,
@@ -191,10 +195,6 @@
 								 IMG_DEV_VIRTADDR sDevVAddr,
 								 IMG_UINT32 ui32PageCount);
 
-IMG_INTERNAL PVRSRV_ERROR IMG_CALLCONV BridgeDevmemSLCFlushInvalRequest(IMG_HANDLE hBridge,
-									IMG_HANDLE hDeviceNode,
-									IMG_HANDLE hPmr);
-
 IMG_INTERNAL PVRSRV_ERROR IMG_CALLCONV BridgeDevmemIsVDevAddrValid(IMG_HANDLE hBridge,
 								   IMG_HANDLE hDevmemCtx,
 								   IMG_DEV_VIRTADDR sAddress);
@@ -221,11 +221,10 @@
 								IMG_UINT32 *pui32Log2DataPageSizeOut,
 								IMG_UINT32 *pui32Log2ImportAlignmentOut);
 
-IMG_INTERNAL PVRSRV_ERROR IMG_CALLCONV BridgeDevmemIntCtxCreateCLS(IMG_HANDLE hBridge,
-								   IMG_BOOL bbKernelMemoryCtx,
-								   IMG_HANDLE *phDevMemServerContext,
-								   IMG_HANDLE *phPrivData,
-								   IMG_UINT32 *pui32CPUCacheLineSize);
+IMG_INTERNAL PVRSRV_ERROR IMG_CALLCONV BridgeDevmemIntRegisterPFNotifyKM(IMG_HANDLE hBridge,
+									 IMG_HANDLE hDevmemCtx,
+									 IMG_UINT32 ui32PID,
+									 IMG_BOOL bRegister);
 
 
 #endif /* CLIENT_MM_BRIDGE_H */
diff --git a/drivers/staging/imgtec/rogue/generated/mm_bridge/client_mm_direct_bridge.c b/drivers/staging/imgtec/rogue/generated/mm_bridge/client_mm_direct_bridge.c
index 0182976..cff3aaa 100644
--- a/drivers/staging/imgtec/rogue/generated/mm_bridge/client_mm_direct_bridge.c
+++ b/drivers/staging/imgtec/rogue/generated/mm_bridge/client_mm_direct_bridge.c
@@ -47,6 +47,7 @@
 #include "pvrsrv_memallocflags.h"
 #include "devicemem_typedefs.h"
 
+#include "devicemem.h"
 #include "devicemem_server.h"
 #include "pmr.h"
 #include "devicemem_heapcfg.h"
@@ -159,12 +160,12 @@
 	PVRSRV_ERROR eError;
 	PMR_EXPORT * psPMRExportInt;
 	PMR * psPMRInt;
-	PVR_UNREFERENCED_PARAMETER(hBridge);
 
 	psPMRExportInt = (PMR_EXPORT *) hPMRExport;
 
 	eError =
-		PMRImportPMR(
+		PMRImportPMR(NULL, (PVRSRV_DEVICE_NODE *)((void*) hBridge)
+		,
 					psPMRExportInt,
 					ui64uiPassword,
 					ui64uiSize,
@@ -239,6 +240,8 @@
 								    IMG_UINT32 *pui32MappingTable,
 								    IMG_UINT32 ui32Log2PageSize,
 								    PVRSRV_MEMALLOCFLAGS_T uiFlags,
+								    IMG_UINT32 ui32AnnotationLength,
+								    const IMG_CHAR *puiAnnotation,
 								    IMG_HANDLE *phPMRPtr)
 {
 	PVRSRV_ERROR eError;
@@ -255,6 +258,8 @@
 					pui32MappingTable,
 					ui32Log2PageSize,
 					uiFlags,
+					ui32AnnotationLength,
+					puiAnnotation,
 					&psPMRPtrInt);
 
 	*phPMRPtr = psPMRPtrInt;
@@ -269,6 +274,8 @@
 									  IMG_UINT32 *pui32MappingTable,
 									  IMG_UINT32 ui32Log2PageSize,
 									  PVRSRV_MEMALLOCFLAGS_T uiFlags,
+									  IMG_UINT32 ui32AnnotationLength,
+									  const IMG_CHAR *puiAnnotation,
 									  IMG_HANDLE *phPMRPtr)
 {
 	PVRSRV_ERROR eError;
@@ -285,6 +292,8 @@
 					pui32MappingTable,
 					ui32Log2PageSize,
 					uiFlags,
+					ui32AnnotationLength,
+					puiAnnotation,
 					&psPMRPtrInt);
 
 	*phPMRPtr = psPMRPtrInt;
@@ -366,7 +375,8 @@
 IMG_INTERNAL PVRSRV_ERROR IMG_CALLCONV BridgeDevmemIntCtxCreate(IMG_HANDLE hBridge,
 								IMG_BOOL bbKernelMemoryCtx,
 								IMG_HANDLE *phDevMemServerContext,
-								IMG_HANDLE *phPrivData)
+								IMG_HANDLE *phPrivData,
+								IMG_UINT32 *pui32CPUCacheLineSize)
 {
 	PVRSRV_ERROR eError;
 	DEVMEMINT_CTX * psDevMemServerContextInt;
@@ -378,7 +388,8 @@
 		,
 					bbKernelMemoryCtx,
 					&psDevMemServerContextInt,
-					&hPrivDataInt);
+					&hPrivDataInt,
+					pui32CPUCacheLineSize);
 
 	*phDevMemServerContext = psDevMemServerContextInt;
 	*phPrivData = hPrivDataInt;
@@ -539,8 +550,7 @@
 							     IMG_UINT32 ui32SparseFlags,
 							     PVRSRV_MEMALLOCFLAGS_T uiFlags,
 							     IMG_DEV_VIRTADDR sDevVAddr,
-							     IMG_UINT64 ui64CPUVAddr,
-							     IMG_UINT32 *pui32Status)
+							     IMG_UINT64 ui64CPUVAddr)
 {
 	PVRSRV_ERROR eError;
 	DEVMEMINT_HEAP * psSrvDevMemHeapInt;
@@ -551,7 +561,7 @@
 	psPMRInt = (PMR *) hPMR;
 
 	eError =
-		DeviceMemChangeSparseServer(
+		DevmemIntChangeSparse(
 					psSrvDevMemHeapInt,
 					psPMRInt,
 					ui32AllocPageCount,
@@ -561,8 +571,7 @@
 					ui32SparseFlags,
 					uiFlags,
 					sDevVAddr,
-					ui64CPUVAddr,
-					pui32Status);
+					ui64CPUVAddr);
 
 	return eError;
 }
@@ -615,38 +624,18 @@
 	return eError;
 }
 
-IMG_INTERNAL PVRSRV_ERROR IMG_CALLCONV BridgeDevmemSLCFlushInvalRequest(IMG_HANDLE hBridge,
-									IMG_HANDLE hDeviceNode,
-									IMG_HANDLE hPmr)
-{
-	PVRSRV_ERROR eError;
-	IMG_HANDLE hDeviceNodeInt;
-	PMR * psPmrInt;
-	PVR_UNREFERENCED_PARAMETER(hBridge);
-
-	hDeviceNodeInt = (IMG_HANDLE) hDeviceNode;
-	psPmrInt = (PMR *) hPmr;
-
-	eError =
-		DevmemSLCFlushInvalRequest(
-					hDeviceNodeInt,
-					psPmrInt);
-
-	return eError;
-}
-
 IMG_INTERNAL PVRSRV_ERROR IMG_CALLCONV BridgeDevmemIsVDevAddrValid(IMG_HANDLE hBridge,
 								   IMG_HANDLE hDevmemCtx,
 								   IMG_DEV_VIRTADDR sAddress)
 {
 	PVRSRV_ERROR eError;
 	DEVMEMINT_CTX * psDevmemCtxInt;
-	PVR_UNREFERENCED_PARAMETER(hBridge);
 
 	psDevmemCtxInt = (DEVMEMINT_CTX *) hDevmemCtx;
 
 	eError =
-		DevmemIntIsVDevAddrValid(
+		DevmemIntIsVDevAddrValid(NULL, (PVRSRV_DEVICE_NODE *)((void*) hBridge)
+		,
 					psDevmemCtxInt,
 					sAddress);
 
@@ -729,27 +718,23 @@
 	return eError;
 }
 
-IMG_INTERNAL PVRSRV_ERROR IMG_CALLCONV BridgeDevmemIntCtxCreateCLS(IMG_HANDLE hBridge,
-								   IMG_BOOL bbKernelMemoryCtx,
-								   IMG_HANDLE *phDevMemServerContext,
-								   IMG_HANDLE *phPrivData,
-								   IMG_UINT32 *pui32CPUCacheLineSize)
+IMG_INTERNAL PVRSRV_ERROR IMG_CALLCONV BridgeDevmemIntRegisterPFNotifyKM(IMG_HANDLE hBridge,
+									 IMG_HANDLE hDevmemCtx,
+									 IMG_UINT32 ui32PID,
+									 IMG_BOOL bRegister)
 {
 	PVRSRV_ERROR eError;
-	DEVMEMINT_CTX * psDevMemServerContextInt;
-	IMG_HANDLE hPrivDataInt;
+	DEVMEMINT_CTX * psDevmemCtxInt;
+	PVR_UNREFERENCED_PARAMETER(hBridge);
 
+	psDevmemCtxInt = (DEVMEMINT_CTX *) hDevmemCtx;
 
 	eError =
-		DevmemIntCtxCreateCLS(NULL, (PVRSRV_DEVICE_NODE *)((void*) hBridge)
-		,
-					bbKernelMemoryCtx,
-					&psDevMemServerContextInt,
-					&hPrivDataInt,
-					pui32CPUCacheLineSize);
+		DevmemIntRegisterPFNotifyKM(
+					psDevmemCtxInt,
+					ui32PID,
+					bRegister);
 
-	*phDevMemServerContext = psDevMemServerContextInt;
-	*phPrivData = hPrivDataInt;
 	return eError;
 }
 
diff --git a/drivers/staging/imgtec/rogue/generated/mm_bridge/common_mm_bridge.h b/drivers/staging/imgtec/rogue/generated/mm_bridge/common_mm_bridge.h
index f6344d2..0cd734d 100644
--- a/drivers/staging/imgtec/rogue/generated/mm_bridge/common_mm_bridge.h
+++ b/drivers/staging/imgtec/rogue/generated/mm_bridge/common_mm_bridge.h
@@ -2,8 +2,8 @@
 @File
 @Title          Common bridge header for mm
 @Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
-@Description    Declares common defines and structures that are used by both
-                the client and sever side of the bridge for mm
+@Description    Declares common defines and structures used by both the client
+                and server side of the bridge for mm
 @License        Dual MIT/GPLv2
 
 The contents of this file are subject to the MIT license as set out below.
@@ -45,6 +45,8 @@
 #ifndef COMMON_MM_BRIDGE_H
 #define COMMON_MM_BRIDGE_H
 
+#include <powervr/mem_types.h>
+
 #include "img_types.h"
 #include "pvrsrv_error.h"
 
@@ -79,14 +81,13 @@
 #define PVRSRV_BRIDGE_MM_CHANGESPARSEMEM			PVRSRV_BRIDGE_MM_CMD_FIRST+23
 #define PVRSRV_BRIDGE_MM_DEVMEMINTMAPPAGES			PVRSRV_BRIDGE_MM_CMD_FIRST+24
 #define PVRSRV_BRIDGE_MM_DEVMEMINTUNMAPPAGES			PVRSRV_BRIDGE_MM_CMD_FIRST+25
-#define PVRSRV_BRIDGE_MM_DEVMEMSLCFLUSHINVALREQUEST			PVRSRV_BRIDGE_MM_CMD_FIRST+26
-#define PVRSRV_BRIDGE_MM_DEVMEMISVDEVADDRVALID			PVRSRV_BRIDGE_MM_CMD_FIRST+27
-#define PVRSRV_BRIDGE_MM_HEAPCFGHEAPCONFIGCOUNT			PVRSRV_BRIDGE_MM_CMD_FIRST+28
-#define PVRSRV_BRIDGE_MM_HEAPCFGHEAPCOUNT			PVRSRV_BRIDGE_MM_CMD_FIRST+29
-#define PVRSRV_BRIDGE_MM_HEAPCFGHEAPCONFIGNAME			PVRSRV_BRIDGE_MM_CMD_FIRST+30
-#define PVRSRV_BRIDGE_MM_HEAPCFGHEAPDETAILS			PVRSRV_BRIDGE_MM_CMD_FIRST+31
-#define PVRSRV_BRIDGE_MM_DEVMEMINTCTXCREATECLS			PVRSRV_BRIDGE_MM_CMD_FIRST+32
-#define PVRSRV_BRIDGE_MM_CMD_LAST			(PVRSRV_BRIDGE_MM_CMD_FIRST+32)
+#define PVRSRV_BRIDGE_MM_DEVMEMISVDEVADDRVALID			PVRSRV_BRIDGE_MM_CMD_FIRST+26
+#define PVRSRV_BRIDGE_MM_HEAPCFGHEAPCONFIGCOUNT			PVRSRV_BRIDGE_MM_CMD_FIRST+27
+#define PVRSRV_BRIDGE_MM_HEAPCFGHEAPCOUNT			PVRSRV_BRIDGE_MM_CMD_FIRST+28
+#define PVRSRV_BRIDGE_MM_HEAPCFGHEAPCONFIGNAME			PVRSRV_BRIDGE_MM_CMD_FIRST+29
+#define PVRSRV_BRIDGE_MM_HEAPCFGHEAPDETAILS			PVRSRV_BRIDGE_MM_CMD_FIRST+30
+#define PVRSRV_BRIDGE_MM_DEVMEMINTREGISTERPFNOTIFYKM			PVRSRV_BRIDGE_MM_CMD_FIRST+31
+#define PVRSRV_BRIDGE_MM_CMD_LAST			(PVRSRV_BRIDGE_MM_CMD_FIRST+31)
 
 
 /*******************************************
@@ -269,6 +270,8 @@
 	IMG_UINT32 * pui32MappingTable;
 	IMG_UINT32 ui32Log2PageSize;
 	PVRSRV_MEMALLOCFLAGS_T uiFlags;
+	IMG_UINT32 ui32AnnotationLength;
+	const IMG_CHAR * puiAnnotation;
 } __attribute__((packed)) PVRSRV_BRIDGE_IN_PHYSMEMNEWRAMBACKEDPMR;
 
 /* Bridge out structure for PhysmemNewRamBackedPMR */
@@ -293,6 +296,8 @@
 	IMG_UINT32 * pui32MappingTable;
 	IMG_UINT32 ui32Log2PageSize;
 	PVRSRV_MEMALLOCFLAGS_T uiFlags;
+	IMG_UINT32 ui32AnnotationLength;
+	const IMG_CHAR * puiAnnotation;
 } __attribute__((packed)) PVRSRV_BRIDGE_IN_PHYSMEMNEWRAMBACKEDLOCKEDPMR;
 
 /* Bridge out structure for PhysmemNewRamBackedLockedPMR */
@@ -388,6 +393,7 @@
 {
 	IMG_HANDLE hDevMemServerContext;
 	IMG_HANDLE hPrivData;
+	IMG_UINT32 ui32CPUCacheLineSize;
 	PVRSRV_ERROR eError;
 } __attribute__((packed)) PVRSRV_BRIDGE_OUT_DEVMEMINTCTXCREATE;
 
@@ -544,7 +550,6 @@
 /* Bridge out structure for ChangeSparseMem */
 typedef struct PVRSRV_BRIDGE_OUT_CHANGESPARSEMEM_TAG
 {
-	IMG_UINT32 ui32Status;
 	PVRSRV_ERROR eError;
 } __attribute__((packed)) PVRSRV_BRIDGE_OUT_CHANGESPARSEMEM;
 
@@ -591,24 +596,6 @@
 
 
 /*******************************************
-            DevmemSLCFlushInvalRequest          
- *******************************************/
-
-/* Bridge in structure for DevmemSLCFlushInvalRequest */
-typedef struct PVRSRV_BRIDGE_IN_DEVMEMSLCFLUSHINVALREQUEST_TAG
-{
-	IMG_HANDLE hDeviceNode;
-	IMG_HANDLE hPmr;
-} __attribute__((packed)) PVRSRV_BRIDGE_IN_DEVMEMSLCFLUSHINVALREQUEST;
-
-/* Bridge out structure for DevmemSLCFlushInvalRequest */
-typedef struct PVRSRV_BRIDGE_OUT_DEVMEMSLCFLUSHINVALREQUEST_TAG
-{
-	PVRSRV_ERROR eError;
-} __attribute__((packed)) PVRSRV_BRIDGE_OUT_DEVMEMSLCFLUSHINVALREQUEST;
-
-
-/*******************************************
             DevmemIsVDevAddrValid          
  *******************************************/
 
@@ -710,23 +697,22 @@
 
 
 /*******************************************
-            DevmemIntCtxCreateCLS          
+            DevmemIntRegisterPFNotifyKM          
  *******************************************/
 
-/* Bridge in structure for DevmemIntCtxCreateCLS */
-typedef struct PVRSRV_BRIDGE_IN_DEVMEMINTCTXCREATECLS_TAG
+/* Bridge in structure for DevmemIntRegisterPFNotifyKM */
+typedef struct PVRSRV_BRIDGE_IN_DEVMEMINTREGISTERPFNOTIFYKM_TAG
 {
-	IMG_BOOL bbKernelMemoryCtx;
-} __attribute__((packed)) PVRSRV_BRIDGE_IN_DEVMEMINTCTXCREATECLS;
+	IMG_HANDLE hDevmemCtx;
+	IMG_UINT32 ui32PID;
+	IMG_BOOL bRegister;
+} __attribute__((packed)) PVRSRV_BRIDGE_IN_DEVMEMINTREGISTERPFNOTIFYKM;
 
-/* Bridge out structure for DevmemIntCtxCreateCLS */
-typedef struct PVRSRV_BRIDGE_OUT_DEVMEMINTCTXCREATECLS_TAG
+/* Bridge out structure for DevmemIntRegisterPFNotifyKM */
+typedef struct PVRSRV_BRIDGE_OUT_DEVMEMINTREGISTERPFNOTIFYKM_TAG
 {
-	IMG_HANDLE hDevMemServerContext;
-	IMG_HANDLE hPrivData;
-	IMG_UINT32 ui32CPUCacheLineSize;
 	PVRSRV_ERROR eError;
-} __attribute__((packed)) PVRSRV_BRIDGE_OUT_DEVMEMINTCTXCREATECLS;
+} __attribute__((packed)) PVRSRV_BRIDGE_OUT_DEVMEMINTREGISTERPFNOTIFYKM;
 
 
 #endif /* COMMON_MM_BRIDGE_H */
diff --git a/drivers/staging/imgtec/rogue/generated/mm_bridge/server_mm_bridge.c b/drivers/staging/imgtec/rogue/generated/mm_bridge/server_mm_bridge.c
index e6592fa..58fa70c 100644
--- a/drivers/staging/imgtec/rogue/generated/mm_bridge/server_mm_bridge.c
+++ b/drivers/staging/imgtec/rogue/generated/mm_bridge/server_mm_bridge.c
@@ -46,6 +46,7 @@
 
 #include "img_defs.h"
 
+#include "devicemem.h"
 #include "devicemem_server.h"
 #include "pmr.h"
 #include "devicemem_heapcfg.h"
@@ -65,6 +66,8 @@
 #include <linux/slab.h>
 
 
+
+
 static PVRSRV_ERROR ReleasePMRExport(void *pvData)
 {
 	PVR_UNREFERENCED_PARAMETER(pvData);
@@ -83,6 +86,7 @@
 					  PVRSRV_BRIDGE_OUT_PMREXPORTPMR *psPMRExportPMROUT,
 					 CONNECTION_DATA *psConnection)
 {
+	IMG_HANDLE hPMR = psPMRExportPMRIN->hPMR;
 	PMR * psPMRInt = NULL;
 	PMR_EXPORT * psPMRExportInt = NULL;
 	IMG_HANDLE hPMRExportInt = NULL;
@@ -91,23 +95,31 @@
 
 
 
-	PMRLock();
+
+
+	/* Lock over handle lookup. */
+	LockHandle();
+
+
+
 
 
 				{
 					/* Look up the address from the handle */
 					psPMRExportPMROUT->eError =
-						PVRSRVLookupHandle(psConnection->psHandleBase,
+						PVRSRVLookupHandleUnlocked(psConnection->psHandleBase,
 											(void **) &psPMRInt,
-											psPMRExportPMRIN->hPMR,
-											PVRSRV_HANDLE_TYPE_PHYSMEM_PMR);
+											hPMR,
+											PVRSRV_HANDLE_TYPE_PHYSMEM_PMR,
+											IMG_TRUE);
 					if(psPMRExportPMROUT->eError != PVRSRV_OK)
 					{
-						PMRUnlock();
+						UnlockHandle();
 						goto PMRExportPMR_exit;
 					}
 				}
-
+	/* Release now we have looked up handles. */
+	UnlockHandle();
 
 	psPMRExportPMROUT->eError =
 		PMRExportPMR(
@@ -119,11 +131,11 @@
 	/* Exit early if bridged call fails */
 	if(psPMRExportPMROUT->eError != PVRSRV_OK)
 	{
-		PMRUnlock();
 		goto PMRExportPMR_exit;
 	}
-	PMRUnlock();
 
+	/* Lock over handle creation. */
+	LockHandle();
 
 	/*
 	 * For cases where we need a cross process handle we actually allocate two.
@@ -139,18 +151,24 @@
 	 * The second one is a cross process handle and it gets given a noop release
 	 * function. This handle does get returned to the caller.
 	 */
-	psPMRExportPMROUT->eError = PVRSRVAllocHandle(psConnection->psHandleBase,
+
+
+
+
+	psPMRExportPMROUT->eError = PVRSRVAllocHandleUnlocked(psConnection->psProcessHandleBase->psHandleBase,
+
 							&hPMRExportInt,
 							(void *) psPMRExportInt,
 							PVRSRV_HANDLE_TYPE_PHYSMEM_PMR_EXPORT,
-							PVRSRV_HANDLE_ALLOC_FLAG_SHARED
+							PVRSRV_HANDLE_ALLOC_FLAG_MULTI
 							,(PFN_HANDLE_RELEASE)&PMRUnexportPMR);
 	if (psPMRExportPMROUT->eError != PVRSRV_OK)
 	{
+		UnlockHandle();
 		goto PMRExportPMR_exit;
 	}
 
-	psPMRExportPMROUT->eError = PVRSRVAllocHandle(KERNEL_HANDLE_BASE,
+	psPMRExportPMROUT->eError = PVRSRVAllocHandleUnlocked(KERNEL_HANDLE_BASE,
 							&psPMRExportPMROUT->hPMRExport,
 							(void *) psPMRExportInt,
 							PVRSRV_HANDLE_TYPE_PHYSMEM_PMR_EXPORT,
@@ -158,38 +176,80 @@
 							(PFN_HANDLE_RELEASE)&ReleasePMRExport);
 	if (psPMRExportPMROUT->eError != PVRSRV_OK)
 	{
+		UnlockHandle();
 		goto PMRExportPMR_exit;
 	}
+	/* Release now we have created handles. */
+	UnlockHandle();
 
 
 
 PMRExportPMR_exit:
+
+	/* Lock over handle lookup cleanup. */
+	LockHandle();
+
+
+
+
+
+
+				{
+					/* Unreference the previously looked up handle */
+						if(psPMRInt)
+						{
+							PVRSRVReleaseHandleUnlocked(psConnection->psHandleBase,
+											hPMR,
+											PVRSRV_HANDLE_TYPE_PHYSMEM_PMR);
+						}
+				}
+	/* Release now we have cleaned up look up handles. */
+	UnlockHandle();
+
 	if (psPMRExportPMROUT->eError != PVRSRV_OK)
 	{
+		/* Lock over handle creation cleanup. */
+		LockHandle();
 		if (psPMRExportPMROUT->hPMRExport)
 		{
-			PVRSRV_ERROR eError = PVRSRVReleaseHandle(KERNEL_HANDLE_BASE,
+
+
+			PVRSRV_ERROR eError = PVRSRVReleaseHandleUnlocked(KERNEL_HANDLE_BASE,
 						(IMG_HANDLE) psPMRExportPMROUT->hPMRExport,
 						PVRSRV_HANDLE_TYPE_PHYSMEM_PMR_EXPORT);
-
-			/* Releasing the handle should free/destroy/release the resource. This should never fail... */
+			if ((eError != PVRSRV_OK) && (eError != PVRSRV_ERROR_RETRY))
+			{
+				PVR_DPF((PVR_DBG_ERROR,
+				        "PVRSRVBridgePMRExportPMR: %s",
+				        PVRSRVGetErrorStringKM(eError)));
+			}
+			/* Releasing the handle should free/destroy/release the resource.
+			 * This should never fail... */
 			PVR_ASSERT((eError == PVRSRV_OK) || (eError == PVRSRV_ERROR_RETRY));
 
 		}
 
 		if (hPMRExportInt)
 		{
-			PVRSRV_ERROR eError = PVRSRVReleaseHandle(psConnection->psHandleBase,
+			PVRSRV_ERROR eError = PVRSRVReleaseHandleUnlocked(psConnection->psProcessHandleBase->psHandleBase,
 						hPMRExportInt,
 						PVRSRV_HANDLE_TYPE_PHYSMEM_PMR_EXPORT);
-
-			/* Releasing the handle should free/destroy/release the resource. This should never fail... */
+			if ((eError != PVRSRV_OK) && (eError != PVRSRV_ERROR_RETRY))
+			{
+				PVR_DPF((PVR_DBG_ERROR,
+				        "PVRSRVBridgePMRExportPMR: %s",
+				        PVRSRVGetErrorStringKM(eError)));
+			}
+			/* Releasing the handle should free/destroy/release the resource.
+			 * This should never fail... */
 			PVR_ASSERT((eError == PVRSRV_OK) || (eError == PVRSRV_ERROR_RETRY));
 
 			/* Avoid freeing/destroying/releasing the resource a second time below */
 			psPMRExportInt = NULL;
 		}
 
+		/* Release now we have cleaned up creation handles. */
+		UnlockHandle();
 		if (psPMRExportInt)
 		{
 			PMRUnexportPMR(psPMRExportInt);
@@ -200,6 +260,7 @@
 	return 0;
 }
 
+
 static IMG_INT
 PVRSRVBridgePMRUnexportPMR(IMG_UINT32 ui32DispatchTableEntry,
 					  PVRSRV_BRIDGE_IN_PMRUNEXPORTPMR *psPMRUnexportPMRIN,
@@ -209,20 +270,31 @@
 	PMR_EXPORT * psPMRExportInt = NULL;
 	IMG_HANDLE hPMRExportInt = NULL;
 
+
+
 	PVR_UNREFERENCED_PARAMETER(psConnection);
 
 
 
 
-	PMRLock();
 
 
+	/* Lock over handle destruction. */
+	LockHandle();
+
 
 	psPMRUnexportPMROUT->eError =
-		PVRSRVLookupHandle(KERNEL_HANDLE_BASE,
+		PVRSRVLookupHandleUnlocked(KERNEL_HANDLE_BASE,
 					(void **) &psPMRExportInt,
 					(IMG_HANDLE) psPMRUnexportPMRIN->hPMRExport,
-					PVRSRV_HANDLE_TYPE_PHYSMEM_PMR_EXPORT);
+					PVRSRV_HANDLE_TYPE_PHYSMEM_PMR_EXPORT,
+					IMG_FALSE);
+	if (psPMRUnexportPMROUT->eError != PVRSRV_OK)
+	{
+		PVR_DPF((PVR_DBG_ERROR,
+		        "PVRSRVBridgePMRUnexportPMR: %s",
+		        PVRSRVGetErrorStringKM(psPMRUnexportPMROUT->eError)));
+	}
 	PVR_ASSERT(psPMRUnexportPMROUT->eError == PVRSRV_OK);
 
 	/*
@@ -232,87 +304,146 @@
 	 * process handle is allocated for more details).
 	 */
 	psPMRUnexportPMROUT->eError =
-		PVRSRVFindHandle(psConnection->psHandleBase,
+		PVRSRVFindHandleUnlocked(psConnection->psProcessHandleBase->psHandleBase,
 					&hPMRExportInt,
 					psPMRExportInt,
 					PVRSRV_HANDLE_TYPE_PHYSMEM_PMR_EXPORT);
+	if (psPMRUnexportPMROUT->eError != PVRSRV_OK)
+	{
+		PVR_DPF((PVR_DBG_ERROR,
+		        "PVRSRVBridgePMRUnexportPMR: %s",
+		        PVRSRVGetErrorStringKM(psPMRUnexportPMROUT->eError)));
+	}
 	PVR_ASSERT(psPMRUnexportPMROUT->eError == PVRSRV_OK);
 
 	psPMRUnexportPMROUT->eError =
-		PVRSRVReleaseHandle(psConnection->psHandleBase,
+		PVRSRVReleaseHandleUnlocked(psConnection->psProcessHandleBase->psHandleBase,
 					hPMRExportInt,
 					PVRSRV_HANDLE_TYPE_PHYSMEM_PMR_EXPORT);
-	PVR_ASSERT((psPMRUnexportPMROUT->eError == PVRSRV_OK) || (psPMRUnexportPMROUT->eError == PVRSRV_ERROR_RETRY));
+	if ((psPMRUnexportPMROUT->eError != PVRSRV_OK) &&
+	    (psPMRUnexportPMROUT->eError != PVRSRV_ERROR_RETRY))
+	{
+		PVR_DPF((PVR_DBG_ERROR,
+		        "PVRSRVBridgePMRUnexportPMR: %s",
+		        PVRSRVGetErrorStringKM(psPMRUnexportPMROUT->eError)));
+	}
+	PVR_ASSERT((psPMRUnexportPMROUT->eError == PVRSRV_OK) ||
+	           (psPMRUnexportPMROUT->eError == PVRSRV_ERROR_RETRY));
+
+
+
+
 
 	psPMRUnexportPMROUT->eError =
-		PVRSRVReleaseHandle(KERNEL_HANDLE_BASE,
+		PVRSRVReleaseHandleUnlocked(KERNEL_HANDLE_BASE,
 					(IMG_HANDLE) psPMRUnexportPMRIN->hPMRExport,
 					PVRSRV_HANDLE_TYPE_PHYSMEM_PMR_EXPORT);
-	if ((psPMRUnexportPMROUT->eError != PVRSRV_OK) && (psPMRUnexportPMROUT->eError != PVRSRV_ERROR_RETRY))
+	if ((psPMRUnexportPMROUT->eError != PVRSRV_OK) &&
+	    (psPMRUnexportPMROUT->eError != PVRSRV_ERROR_RETRY))
 	{
+		PVR_DPF((PVR_DBG_ERROR,
+		        "PVRSRVBridgePMRUnexportPMR: %s",
+		        PVRSRVGetErrorStringKM(psPMRUnexportPMROUT->eError)));
 		PVR_ASSERT(0);
-		PMRUnlock();
+		UnlockHandle();
 		goto PMRUnexportPMR_exit;
 	}
 
-	PMRUnlock();
+	/* Release now we have destroyed handles. */
+	UnlockHandle();
+
 
 
 PMRUnexportPMR_exit:
 
+
+
+
 	return 0;
 }
 
+
 static IMG_INT
 PVRSRVBridgePMRGetUID(IMG_UINT32 ui32DispatchTableEntry,
 					  PVRSRV_BRIDGE_IN_PMRGETUID *psPMRGetUIDIN,
 					  PVRSRV_BRIDGE_OUT_PMRGETUID *psPMRGetUIDOUT,
 					 CONNECTION_DATA *psConnection)
 {
+	IMG_HANDLE hPMR = psPMRGetUIDIN->hPMR;
 	PMR * psPMRInt = NULL;
 
 
 
 
 
-	PMRLock();
+
+
+	/* Lock over handle lookup. */
+	LockHandle();
+
+
+
 
 
 				{
 					/* Look up the address from the handle */
 					psPMRGetUIDOUT->eError =
-						PVRSRVLookupHandle(psConnection->psHandleBase,
+						PVRSRVLookupHandleUnlocked(psConnection->psHandleBase,
 											(void **) &psPMRInt,
-											psPMRGetUIDIN->hPMR,
-											PVRSRV_HANDLE_TYPE_PHYSMEM_PMR);
+											hPMR,
+											PVRSRV_HANDLE_TYPE_PHYSMEM_PMR,
+											IMG_TRUE);
 					if(psPMRGetUIDOUT->eError != PVRSRV_OK)
 					{
-						PMRUnlock();
+						UnlockHandle();
 						goto PMRGetUID_exit;
 					}
 				}
-
+	/* Release now we have looked up handles. */
+	UnlockHandle();
 
 	psPMRGetUIDOUT->eError =
 		PMRGetUID(
 					psPMRInt,
 					&psPMRGetUIDOUT->ui64UID);
-	PMRUnlock();
 
 
 
 
 PMRGetUID_exit:
 
+	/* Lock over handle lookup cleanup. */
+	LockHandle();
+
+
+
+
+
+
+				{
+					/* Unreference the previously looked up handle */
+						if(psPMRInt)
+						{
+							PVRSRVReleaseHandleUnlocked(psConnection->psHandleBase,
+											hPMR,
+											PVRSRV_HANDLE_TYPE_PHYSMEM_PMR);
+						}
+				}
+	/* Release now we have cleaned up look up handles. */
+	UnlockHandle();
+
+
 	return 0;
 }
 
+
 static IMG_INT
 PVRSRVBridgePMRMakeLocalImportHandle(IMG_UINT32 ui32DispatchTableEntry,
 					  PVRSRV_BRIDGE_IN_PMRMAKELOCALIMPORTHANDLE *psPMRMakeLocalImportHandleIN,
 					  PVRSRV_BRIDGE_OUT_PMRMAKELOCALIMPORTHANDLE *psPMRMakeLocalImportHandleOUT,
 					 CONNECTION_DATA *psConnection)
 {
+	IMG_HANDLE hBuffer = psPMRMakeLocalImportHandleIN->hBuffer;
 	PMR * psBufferInt = NULL;
 	PMR * psExtMemInt = NULL;
 
@@ -320,23 +451,31 @@
 
 
 
-	PMRLock();
+
+
+	/* Lock over handle lookup. */
+	LockHandle();
+
+
+
 
 
 				{
 					/* Look up the address from the handle */
 					psPMRMakeLocalImportHandleOUT->eError =
-						PVRSRVLookupHandle(psConnection->psHandleBase,
+						PVRSRVLookupHandleUnlocked(psConnection->psHandleBase,
 											(void **) &psBufferInt,
-											psPMRMakeLocalImportHandleIN->hBuffer,
-											PVRSRV_HANDLE_TYPE_PMR_LOCAL_EXPORT_HANDLE);
+											hBuffer,
+											PVRSRV_HANDLE_TYPE_PMR_LOCAL_EXPORT_HANDLE,
+											IMG_TRUE);
 					if(psPMRMakeLocalImportHandleOUT->eError != PVRSRV_OK)
 					{
-						PMRUnlock();
+						UnlockHandle();
 						goto PMRMakeLocalImportHandle_exit;
 					}
 				}
-
+	/* Release now we have looked up handles. */
+	UnlockHandle();
 
 	psPMRMakeLocalImportHandleOUT->eError =
 		PMRMakeLocalImportHandle(
@@ -345,13 +484,18 @@
 	/* Exit early if bridged call fails */
 	if(psPMRMakeLocalImportHandleOUT->eError != PVRSRV_OK)
 	{
-		PMRUnlock();
 		goto PMRMakeLocalImportHandle_exit;
 	}
-	PMRUnlock();
+
+	/* Lock over handle creation. */
+	LockHandle();
 
 
-	psPMRMakeLocalImportHandleOUT->eError = PVRSRVAllocHandle(psConnection->psHandleBase,
+
+
+
+	psPMRMakeLocalImportHandleOUT->eError = PVRSRVAllocHandleUnlocked(psConnection->psHandleBase,
+
 							&psPMRMakeLocalImportHandleOUT->hExtMem,
 							(void *) psExtMemInt,
 							PVRSRV_HANDLE_TYPE_DEVMEM_MEM_IMPORT,
@@ -359,13 +503,37 @@
 							,(PFN_HANDLE_RELEASE)&PMRUnmakeLocalImportHandle);
 	if (psPMRMakeLocalImportHandleOUT->eError != PVRSRV_OK)
 	{
+		UnlockHandle();
 		goto PMRMakeLocalImportHandle_exit;
 	}
 
+	/* Release now we have created handles. */
+	UnlockHandle();
 
 
 
 PMRMakeLocalImportHandle_exit:
+
+	/* Lock over handle lookup cleanup. */
+	LockHandle();
+
+
+
+
+
+
+				{
+					/* Unreference the previously looked up handle */
+						if(psBufferInt)
+						{
+							PVRSRVReleaseHandleUnlocked(psConnection->psHandleBase,
+											hBuffer,
+											PVRSRV_HANDLE_TYPE_PMR_LOCAL_EXPORT_HANDLE);
+						}
+				}
+	/* Release now we have cleaned up look up handles. */
+	UnlockHandle();
+
 	if (psPMRMakeLocalImportHandleOUT->eError != PVRSRV_OK)
 	{
 		if (psExtMemInt)
@@ -378,6 +546,7 @@
 	return 0;
 }
 
+
 static IMG_INT
 PVRSRVBridgePMRUnmakeLocalImportHandle(IMG_UINT32 ui32DispatchTableEntry,
 					  PVRSRV_BRIDGE_IN_PMRUNMAKELOCALIMPORTHANDLE *psPMRUnmakeLocalImportHandleIN,
@@ -389,36 +558,53 @@
 
 
 
-	PMRLock();
+
+
+
+
+	/* Lock over handle destruction. */
+	LockHandle();
+
 
 
 
 
 	psPMRUnmakeLocalImportHandleOUT->eError =
-		PVRSRVReleaseHandle(psConnection->psHandleBase,
+		PVRSRVReleaseHandleUnlocked(psConnection->psHandleBase,
 					(IMG_HANDLE) psPMRUnmakeLocalImportHandleIN->hExtMem,
 					PVRSRV_HANDLE_TYPE_DEVMEM_MEM_IMPORT);
-	if ((psPMRUnmakeLocalImportHandleOUT->eError != PVRSRV_OK) && (psPMRUnmakeLocalImportHandleOUT->eError != PVRSRV_ERROR_RETRY))
+	if ((psPMRUnmakeLocalImportHandleOUT->eError != PVRSRV_OK) &&
+	    (psPMRUnmakeLocalImportHandleOUT->eError != PVRSRV_ERROR_RETRY))
 	{
+		PVR_DPF((PVR_DBG_ERROR,
+		        "PVRSRVBridgePMRUnmakeLocalImportHandle: %s",
+		        PVRSRVGetErrorStringKM(psPMRUnmakeLocalImportHandleOUT->eError)));
 		PVR_ASSERT(0);
-		PMRUnlock();
+		UnlockHandle();
 		goto PMRUnmakeLocalImportHandle_exit;
 	}
 
-	PMRUnlock();
+	/* Release now we have destroyed handles. */
+	UnlockHandle();
+
 
 
 PMRUnmakeLocalImportHandle_exit:
 
+
+
+
 	return 0;
 }
 
+
 static IMG_INT
 PVRSRVBridgePMRImportPMR(IMG_UINT32 ui32DispatchTableEntry,
 					  PVRSRV_BRIDGE_IN_PMRIMPORTPMR *psPMRImportPMRIN,
 					  PVRSRV_BRIDGE_OUT_PMRIMPORTPMR *psPMRImportPMROUT,
 					 CONNECTION_DATA *psConnection)
 {
+	IMG_HANDLE hPMRExport = psPMRImportPMRIN->hPMRExport;
 	PMR_EXPORT * psPMRExportInt = NULL;
 	PMR * psPMRInt = NULL;
 
@@ -426,26 +612,34 @@
 
 
 
-	PMRLock();
+
+
+	/* Lock over handle lookup. */
+	LockHandle();
+
+
+
 
 
 				{
 					/* Look up the address from the handle */
 					psPMRImportPMROUT->eError =
-						PVRSRVLookupHandle(KERNEL_HANDLE_BASE,
+						PVRSRVLookupHandleUnlocked(KERNEL_HANDLE_BASE,
 											(void **) &psPMRExportInt,
-											psPMRImportPMRIN->hPMRExport,
-											PVRSRV_HANDLE_TYPE_PHYSMEM_PMR_EXPORT);
+											hPMRExport,
+											PVRSRV_HANDLE_TYPE_PHYSMEM_PMR_EXPORT,
+											IMG_TRUE);
 					if(psPMRImportPMROUT->eError != PVRSRV_OK)
 					{
-						PMRUnlock();
+						UnlockHandle();
 						goto PMRImportPMR_exit;
 					}
 				}
-
+	/* Release now we have looked up handles. */
+	UnlockHandle();
 
 	psPMRImportPMROUT->eError =
-		PMRImportPMR(
+		PMRImportPMR(psConnection, OSGetDevData(psConnection),
 					psPMRExportInt,
 					psPMRImportPMRIN->ui64uiPassword,
 					psPMRImportPMRIN->ui64uiSize,
@@ -454,13 +648,18 @@
 	/* Exit early if bridged call fails */
 	if(psPMRImportPMROUT->eError != PVRSRV_OK)
 	{
-		PMRUnlock();
 		goto PMRImportPMR_exit;
 	}
-	PMRUnlock();
+
+	/* Lock over handle creation. */
+	LockHandle();
 
 
-	psPMRImportPMROUT->eError = PVRSRVAllocHandle(psConnection->psHandleBase,
+
+
+
+	psPMRImportPMROUT->eError = PVRSRVAllocHandleUnlocked(psConnection->psHandleBase,
+
 							&psPMRImportPMROUT->hPMR,
 							(void *) psPMRInt,
 							PVRSRV_HANDLE_TYPE_PHYSMEM_PMR,
@@ -468,13 +667,37 @@
 							,(PFN_HANDLE_RELEASE)&PMRUnrefPMR);
 	if (psPMRImportPMROUT->eError != PVRSRV_OK)
 	{
+		UnlockHandle();
 		goto PMRImportPMR_exit;
 	}
 
+	/* Release now we have created handles. */
+	UnlockHandle();
 
 
 
 PMRImportPMR_exit:
+
+	/* Lock over handle lookup cleanup. */
+	LockHandle();
+
+
+
+
+
+
+				{
+					/* Unreference the previously looked up handle */
+						if(psPMRExportInt)
+						{
+							PVRSRVReleaseHandleUnlocked(KERNEL_HANDLE_BASE,
+											hPMRExport,
+											PVRSRV_HANDLE_TYPE_PHYSMEM_PMR_EXPORT);
+						}
+				}
+	/* Release now we have cleaned up look up handles. */
+	UnlockHandle();
+
 	if (psPMRImportPMROUT->eError != PVRSRV_OK)
 	{
 		if (psPMRInt)
@@ -487,12 +710,14 @@
 	return 0;
 }
 
+
 static IMG_INT
 PVRSRVBridgePMRLocalImportPMR(IMG_UINT32 ui32DispatchTableEntry,
 					  PVRSRV_BRIDGE_IN_PMRLOCALIMPORTPMR *psPMRLocalImportPMRIN,
 					  PVRSRV_BRIDGE_OUT_PMRLOCALIMPORTPMR *psPMRLocalImportPMROUT,
 					 CONNECTION_DATA *psConnection)
 {
+	IMG_HANDLE hExtHandle = psPMRLocalImportPMRIN->hExtHandle;
 	PMR * psExtHandleInt = NULL;
 	PMR * psPMRInt = NULL;
 
@@ -500,23 +725,31 @@
 
 
 
-	PMRLock();
+
+
+	/* Lock over handle lookup. */
+	LockHandle();
+
+
+
 
 
 				{
 					/* Look up the address from the handle */
 					psPMRLocalImportPMROUT->eError =
-						PVRSRVLookupHandle(psConnection->psHandleBase,
+						PVRSRVLookupHandleUnlocked(psConnection->psHandleBase,
 											(void **) &psExtHandleInt,
-											psPMRLocalImportPMRIN->hExtHandle,
-											PVRSRV_HANDLE_TYPE_DEVMEM_MEM_IMPORT);
+											hExtHandle,
+											PVRSRV_HANDLE_TYPE_DEVMEM_MEM_IMPORT,
+											IMG_TRUE);
 					if(psPMRLocalImportPMROUT->eError != PVRSRV_OK)
 					{
-						PMRUnlock();
+						UnlockHandle();
 						goto PMRLocalImportPMR_exit;
 					}
 				}
-
+	/* Release now we have looked up handles. */
+	UnlockHandle();
 
 	psPMRLocalImportPMROUT->eError =
 		PMRLocalImportPMR(
@@ -527,13 +760,18 @@
 	/* Exit early if bridged call fails */
 	if(psPMRLocalImportPMROUT->eError != PVRSRV_OK)
 	{
-		PMRUnlock();
 		goto PMRLocalImportPMR_exit;
 	}
-	PMRUnlock();
+
+	/* Lock over handle creation. */
+	LockHandle();
 
 
-	psPMRLocalImportPMROUT->eError = PVRSRVAllocHandle(psConnection->psHandleBase,
+
+
+
+	psPMRLocalImportPMROUT->eError = PVRSRVAllocHandleUnlocked(psConnection->psHandleBase,
+
 							&psPMRLocalImportPMROUT->hPMR,
 							(void *) psPMRInt,
 							PVRSRV_HANDLE_TYPE_PHYSMEM_PMR,
@@ -541,13 +779,37 @@
 							,(PFN_HANDLE_RELEASE)&PMRUnrefPMR);
 	if (psPMRLocalImportPMROUT->eError != PVRSRV_OK)
 	{
+		UnlockHandle();
 		goto PMRLocalImportPMR_exit;
 	}
 
+	/* Release now we have created handles. */
+	UnlockHandle();
 
 
 
 PMRLocalImportPMR_exit:
+
+	/* Lock over handle lookup cleanup. */
+	LockHandle();
+
+
+
+
+
+
+				{
+					/* Unreference the previously looked up handle */
+						if(psExtHandleInt)
+						{
+							PVRSRVReleaseHandleUnlocked(psConnection->psHandleBase,
+											hExtHandle,
+											PVRSRV_HANDLE_TYPE_DEVMEM_MEM_IMPORT);
+						}
+				}
+	/* Release now we have cleaned up look up handles. */
+	UnlockHandle();
+
 	if (psPMRLocalImportPMROUT->eError != PVRSRV_OK)
 	{
 		if (psPMRInt)
@@ -560,6 +822,7 @@
 	return 0;
 }
 
+
 static IMG_INT
 PVRSRVBridgePMRUnrefPMR(IMG_UINT32 ui32DispatchTableEntry,
 					  PVRSRV_BRIDGE_IN_PMRUNREFPMR *psPMRUnrefPMRIN,
@@ -571,30 +834,46 @@
 
 
 
-	PMRLock();
+
+
+
+
+	/* Lock over handle destruction. */
+	LockHandle();
+
 
 
 
 
 	psPMRUnrefPMROUT->eError =
-		PVRSRVReleaseHandle(psConnection->psHandleBase,
+		PVRSRVReleaseHandleUnlocked(psConnection->psHandleBase,
 					(IMG_HANDLE) psPMRUnrefPMRIN->hPMR,
 					PVRSRV_HANDLE_TYPE_PHYSMEM_PMR);
-	if ((psPMRUnrefPMROUT->eError != PVRSRV_OK) && (psPMRUnrefPMROUT->eError != PVRSRV_ERROR_RETRY))
+	if ((psPMRUnrefPMROUT->eError != PVRSRV_OK) &&
+	    (psPMRUnrefPMROUT->eError != PVRSRV_ERROR_RETRY))
 	{
+		PVR_DPF((PVR_DBG_ERROR,
+		        "PVRSRVBridgePMRUnrefPMR: %s",
+		        PVRSRVGetErrorStringKM(psPMRUnrefPMROUT->eError)));
 		PVR_ASSERT(0);
-		PMRUnlock();
+		UnlockHandle();
 		goto PMRUnrefPMR_exit;
 	}
 
-	PMRUnlock();
+	/* Release now we have destroyed handles. */
+	UnlockHandle();
+
 
 
 PMRUnrefPMR_exit:
 
+
+
+
 	return 0;
 }
 
+
 static IMG_INT
 PVRSRVBridgePMRUnrefUnlockPMR(IMG_UINT32 ui32DispatchTableEntry,
 					  PVRSRV_BRIDGE_IN_PMRUNREFUNLOCKPMR *psPMRUnrefUnlockPMRIN,
@@ -606,30 +885,46 @@
 
 
 
-	PMRLock();
+
+
+
+
+	/* Lock over handle destruction. */
+	LockHandle();
+
 
 
 
 
 	psPMRUnrefUnlockPMROUT->eError =
-		PVRSRVReleaseHandle(psConnection->psHandleBase,
+		PVRSRVReleaseHandleUnlocked(psConnection->psHandleBase,
 					(IMG_HANDLE) psPMRUnrefUnlockPMRIN->hPMR,
 					PVRSRV_HANDLE_TYPE_PHYSMEM_PMR);
-	if ((psPMRUnrefUnlockPMROUT->eError != PVRSRV_OK) && (psPMRUnrefUnlockPMROUT->eError != PVRSRV_ERROR_RETRY))
+	if ((psPMRUnrefUnlockPMROUT->eError != PVRSRV_OK) &&
+	    (psPMRUnrefUnlockPMROUT->eError != PVRSRV_ERROR_RETRY))
 	{
+		PVR_DPF((PVR_DBG_ERROR,
+		        "PVRSRVBridgePMRUnrefUnlockPMR: %s",
+		        PVRSRVGetErrorStringKM(psPMRUnrefUnlockPMROUT->eError)));
 		PVR_ASSERT(0);
-		PMRUnlock();
+		UnlockHandle();
 		goto PMRUnrefUnlockPMR_exit;
 	}
 
-	PMRUnlock();
+	/* Release now we have destroyed handles. */
+	UnlockHandle();
+
 
 
 PMRUnrefUnlockPMR_exit:
 
+
+
+
 	return 0;
 }
 
+
 static IMG_INT
 PVRSRVBridgePhysmemNewRamBackedPMR(IMG_UINT32 ui32DispatchTableEntry,
 					  PVRSRV_BRIDGE_IN_PHYSMEMNEWRAMBACKEDPMR *psPhysmemNewRamBackedPMRIN,
@@ -637,33 +932,83 @@
 					 CONNECTION_DATA *psConnection)
 {
 	IMG_UINT32 *ui32MappingTableInt = NULL;
+	IMG_CHAR *uiAnnotationInt = NULL;
 	PMR * psPMRPtrInt = NULL;
 
+	IMG_UINT32 ui32NextOffset = 0;
+	IMG_BYTE   *pArrayArgsBuffer = NULL;
+#if !defined(INTEGRITY_OS)
+	IMG_BOOL bHaveEnoughSpace = IMG_FALSE;
+#endif
+
+	IMG_UINT32 ui32BufferSize = 
+			(psPhysmemNewRamBackedPMRIN->ui32NumPhysChunks * sizeof(IMG_UINT32)) +
+			(psPhysmemNewRamBackedPMRIN->ui32AnnotationLength * sizeof(IMG_CHAR)) +
+			0;
 
 
 
-	if (psPhysmemNewRamBackedPMRIN->ui32NumPhysChunks != 0)
+
+
+	if (ui32BufferSize != 0)
 	{
-		ui32MappingTableInt = OSAllocMemNoStats(psPhysmemNewRamBackedPMRIN->ui32NumPhysChunks * sizeof(IMG_UINT32));
-		if (!ui32MappingTableInt)
+#if !defined(INTEGRITY_OS)
+		/* Try to use remainder of input buffer for copies if possible, word-aligned for safety. */
+		IMG_UINT32 ui32InBufferOffset = PVR_ALIGN(sizeof(*psPhysmemNewRamBackedPMRIN), sizeof(unsigned long));
+		IMG_UINT32 ui32InBufferExcessSize = ui32InBufferOffset >= PVRSRV_MAX_BRIDGE_IN_SIZE ? 0 :
+			PVRSRV_MAX_BRIDGE_IN_SIZE - ui32InBufferOffset;
+
+		bHaveEnoughSpace = ui32BufferSize <= ui32InBufferExcessSize;
+		if (bHaveEnoughSpace)
 		{
-			psPhysmemNewRamBackedPMROUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
-	
-			goto PhysmemNewRamBackedPMR_exit;
+			IMG_BYTE *pInputBuffer = (IMG_BYTE *)psPhysmemNewRamBackedPMRIN;
+
+			pArrayArgsBuffer = &pInputBuffer[ui32InBufferOffset];		}
+		else
+#endif
+		{
+			pArrayArgsBuffer = OSAllocMemNoStats(ui32BufferSize);
+
+			if(!pArrayArgsBuffer)
+			{
+				psPhysmemNewRamBackedPMROUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
+				goto PhysmemNewRamBackedPMR_exit;
+			}
 		}
 	}
 
+	if (psPhysmemNewRamBackedPMRIN->ui32NumPhysChunks != 0)
+	{
+		ui32MappingTableInt = (IMG_UINT32*)(((IMG_UINT8 *)pArrayArgsBuffer) + ui32NextOffset);
+		ui32NextOffset += psPhysmemNewRamBackedPMRIN->ui32NumPhysChunks * sizeof(IMG_UINT32);
+	}
+
 			/* Copy the data over */
-			if ( !OSAccessOK(PVR_VERIFY_READ, (void*) psPhysmemNewRamBackedPMRIN->pui32MappingTable, psPhysmemNewRamBackedPMRIN->ui32NumPhysChunks * sizeof(IMG_UINT32))
-				|| (OSCopyFromUser(NULL, ui32MappingTableInt, psPhysmemNewRamBackedPMRIN->pui32MappingTable,
-				psPhysmemNewRamBackedPMRIN->ui32NumPhysChunks * sizeof(IMG_UINT32)) != PVRSRV_OK) )
+			if (psPhysmemNewRamBackedPMRIN->ui32NumPhysChunks * sizeof(IMG_UINT32) > 0)
 			{
-				psPhysmemNewRamBackedPMROUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
+				if ( OSCopyFromUser(NULL, ui32MappingTableInt, psPhysmemNewRamBackedPMRIN->pui32MappingTable, psPhysmemNewRamBackedPMRIN->ui32NumPhysChunks * sizeof(IMG_UINT32)) != PVRSRV_OK )
+				{
+					psPhysmemNewRamBackedPMROUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
 
-				goto PhysmemNewRamBackedPMR_exit;
+					goto PhysmemNewRamBackedPMR_exit;
+				}
 			}
+	if (psPhysmemNewRamBackedPMRIN->ui32AnnotationLength != 0)
+	{
+		uiAnnotationInt = (IMG_CHAR*)(((IMG_UINT8 *)pArrayArgsBuffer) + ui32NextOffset);
+		ui32NextOffset += psPhysmemNewRamBackedPMRIN->ui32AnnotationLength * sizeof(IMG_CHAR);
+	}
 
-	PMRLock();
+			/* Copy the data over */
+			if (psPhysmemNewRamBackedPMRIN->ui32AnnotationLength * sizeof(IMG_CHAR) > 0)
+			{
+				if ( OSCopyFromUser(NULL, uiAnnotationInt, psPhysmemNewRamBackedPMRIN->puiAnnotation, psPhysmemNewRamBackedPMRIN->ui32AnnotationLength * sizeof(IMG_CHAR)) != PVRSRV_OK )
+				{
+					psPhysmemNewRamBackedPMROUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
+
+					goto PhysmemNewRamBackedPMR_exit;
+				}
+			}
 
 
 	psPhysmemNewRamBackedPMROUT->eError =
@@ -675,17 +1020,24 @@
 					ui32MappingTableInt,
 					psPhysmemNewRamBackedPMRIN->ui32Log2PageSize,
 					psPhysmemNewRamBackedPMRIN->uiFlags,
+					psPhysmemNewRamBackedPMRIN->ui32AnnotationLength,
+					uiAnnotationInt,
 					&psPMRPtrInt);
 	/* Exit early if bridged call fails */
 	if(psPhysmemNewRamBackedPMROUT->eError != PVRSRV_OK)
 	{
-		PMRUnlock();
 		goto PhysmemNewRamBackedPMR_exit;
 	}
-	PMRUnlock();
+
+	/* Lock over handle creation. */
+	LockHandle();
 
 
-	psPhysmemNewRamBackedPMROUT->eError = PVRSRVAllocHandle(psConnection->psHandleBase,
+
+
+
+	psPhysmemNewRamBackedPMROUT->eError = PVRSRVAllocHandleUnlocked(psConnection->psHandleBase,
+
 							&psPhysmemNewRamBackedPMROUT->hPMRPtr,
 							(void *) psPMRPtrInt,
 							PVRSRV_HANDLE_TYPE_PHYSMEM_PMR,
@@ -693,13 +1045,19 @@
 							,(PFN_HANDLE_RELEASE)&PMRUnrefPMR);
 	if (psPhysmemNewRamBackedPMROUT->eError != PVRSRV_OK)
 	{
+		UnlockHandle();
 		goto PhysmemNewRamBackedPMR_exit;
 	}
 
+	/* Release now we have created handles. */
+	UnlockHandle();
 
 
 
 PhysmemNewRamBackedPMR_exit:
+
+
+
 	if (psPhysmemNewRamBackedPMROUT->eError != PVRSRV_OK)
 	{
 		if (psPMRPtrInt)
@@ -708,12 +1066,21 @@
 		}
 	}
 
-	if (ui32MappingTableInt)
-		OSFreeMemNoStats(ui32MappingTableInt);
+	/* Allocated space should be equal to the last updated offset */
+	PVR_ASSERT(ui32BufferSize == ui32NextOffset);
+
+#if defined(INTEGRITY_OS)
+	if(pArrayArgsBuffer)
+#else
+	if(!bHaveEnoughSpace && pArrayArgsBuffer)
+#endif
+		OSFreeMemNoStats(pArrayArgsBuffer);
+
 
 	return 0;
 }
 
+
 static IMG_INT
 PVRSRVBridgePhysmemNewRamBackedLockedPMR(IMG_UINT32 ui32DispatchTableEntry,
 					  PVRSRV_BRIDGE_IN_PHYSMEMNEWRAMBACKEDLOCKEDPMR *psPhysmemNewRamBackedLockedPMRIN,
@@ -721,33 +1088,83 @@
 					 CONNECTION_DATA *psConnection)
 {
 	IMG_UINT32 *ui32MappingTableInt = NULL;
+	IMG_CHAR *uiAnnotationInt = NULL;
 	PMR * psPMRPtrInt = NULL;
 
+	IMG_UINT32 ui32NextOffset = 0;
+	IMG_BYTE   *pArrayArgsBuffer = NULL;
+#if !defined(INTEGRITY_OS)
+	IMG_BOOL bHaveEnoughSpace = IMG_FALSE;
+#endif
+
+	IMG_UINT32 ui32BufferSize = 
+			(psPhysmemNewRamBackedLockedPMRIN->ui32NumVirtChunks * sizeof(IMG_UINT32)) +
+			(psPhysmemNewRamBackedLockedPMRIN->ui32AnnotationLength * sizeof(IMG_CHAR)) +
+			0;
 
 
 
-	if (psPhysmemNewRamBackedLockedPMRIN->ui32NumVirtChunks != 0)
+
+
+	if (ui32BufferSize != 0)
 	{
-		ui32MappingTableInt = OSAllocMemNoStats(psPhysmemNewRamBackedLockedPMRIN->ui32NumVirtChunks * sizeof(IMG_UINT32));
-		if (!ui32MappingTableInt)
+#if !defined(INTEGRITY_OS)
+		/* Try to use remainder of input buffer for copies if possible, word-aligned for safety. */
+		IMG_UINT32 ui32InBufferOffset = PVR_ALIGN(sizeof(*psPhysmemNewRamBackedLockedPMRIN), sizeof(unsigned long));
+		IMG_UINT32 ui32InBufferExcessSize = ui32InBufferOffset >= PVRSRV_MAX_BRIDGE_IN_SIZE ? 0 :
+			PVRSRV_MAX_BRIDGE_IN_SIZE - ui32InBufferOffset;
+
+		bHaveEnoughSpace = ui32BufferSize <= ui32InBufferExcessSize;
+		if (bHaveEnoughSpace)
 		{
-			psPhysmemNewRamBackedLockedPMROUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
-	
-			goto PhysmemNewRamBackedLockedPMR_exit;
+			IMG_BYTE *pInputBuffer = (IMG_BYTE *)psPhysmemNewRamBackedLockedPMRIN;
+
+			pArrayArgsBuffer = &pInputBuffer[ui32InBufferOffset];		}
+		else
+#endif
+		{
+			pArrayArgsBuffer = OSAllocMemNoStats(ui32BufferSize);
+
+			if(!pArrayArgsBuffer)
+			{
+				psPhysmemNewRamBackedLockedPMROUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
+				goto PhysmemNewRamBackedLockedPMR_exit;
+			}
 		}
 	}
 
+	if (psPhysmemNewRamBackedLockedPMRIN->ui32NumVirtChunks != 0)
+	{
+		ui32MappingTableInt = (IMG_UINT32*)(((IMG_UINT8 *)pArrayArgsBuffer) + ui32NextOffset);
+		ui32NextOffset += psPhysmemNewRamBackedLockedPMRIN->ui32NumVirtChunks * sizeof(IMG_UINT32);
+	}
+
 			/* Copy the data over */
-			if ( !OSAccessOK(PVR_VERIFY_READ, (void*) psPhysmemNewRamBackedLockedPMRIN->pui32MappingTable, psPhysmemNewRamBackedLockedPMRIN->ui32NumVirtChunks * sizeof(IMG_UINT32))
-				|| (OSCopyFromUser(NULL, ui32MappingTableInt, psPhysmemNewRamBackedLockedPMRIN->pui32MappingTable,
-				psPhysmemNewRamBackedLockedPMRIN->ui32NumVirtChunks * sizeof(IMG_UINT32)) != PVRSRV_OK) )
+			if (psPhysmemNewRamBackedLockedPMRIN->ui32NumVirtChunks * sizeof(IMG_UINT32) > 0)
 			{
-				psPhysmemNewRamBackedLockedPMROUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
+				if ( OSCopyFromUser(NULL, ui32MappingTableInt, psPhysmemNewRamBackedLockedPMRIN->pui32MappingTable, psPhysmemNewRamBackedLockedPMRIN->ui32NumVirtChunks * sizeof(IMG_UINT32)) != PVRSRV_OK )
+				{
+					psPhysmemNewRamBackedLockedPMROUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
 
-				goto PhysmemNewRamBackedLockedPMR_exit;
+					goto PhysmemNewRamBackedLockedPMR_exit;
+				}
 			}
+	if (psPhysmemNewRamBackedLockedPMRIN->ui32AnnotationLength != 0)
+	{
+		uiAnnotationInt = (IMG_CHAR*)(((IMG_UINT8 *)pArrayArgsBuffer) + ui32NextOffset);
+		ui32NextOffset += psPhysmemNewRamBackedLockedPMRIN->ui32AnnotationLength * sizeof(IMG_CHAR);
+	}
 
-	PMRLock();
+			/* Copy the data over */
+			if (psPhysmemNewRamBackedLockedPMRIN->ui32AnnotationLength * sizeof(IMG_CHAR) > 0)
+			{
+				if ( OSCopyFromUser(NULL, uiAnnotationInt, psPhysmemNewRamBackedLockedPMRIN->puiAnnotation, psPhysmemNewRamBackedLockedPMRIN->ui32AnnotationLength * sizeof(IMG_CHAR)) != PVRSRV_OK )
+				{
+					psPhysmemNewRamBackedLockedPMROUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
+
+					goto PhysmemNewRamBackedLockedPMR_exit;
+				}
+			}
 
 
 	psPhysmemNewRamBackedLockedPMROUT->eError =
@@ -759,17 +1176,24 @@
 					ui32MappingTableInt,
 					psPhysmemNewRamBackedLockedPMRIN->ui32Log2PageSize,
 					psPhysmemNewRamBackedLockedPMRIN->uiFlags,
+					psPhysmemNewRamBackedLockedPMRIN->ui32AnnotationLength,
+					uiAnnotationInt,
 					&psPMRPtrInt);
 	/* Exit early if bridged call fails */
 	if(psPhysmemNewRamBackedLockedPMROUT->eError != PVRSRV_OK)
 	{
-		PMRUnlock();
 		goto PhysmemNewRamBackedLockedPMR_exit;
 	}
-	PMRUnlock();
+
+	/* Lock over handle creation. */
+	LockHandle();
 
 
-	psPhysmemNewRamBackedLockedPMROUT->eError = PVRSRVAllocHandle(psConnection->psHandleBase,
+
+
+
+	psPhysmemNewRamBackedLockedPMROUT->eError = PVRSRVAllocHandleUnlocked(psConnection->psHandleBase,
+
 							&psPhysmemNewRamBackedLockedPMROUT->hPMRPtr,
 							(void *) psPMRPtrInt,
 							PVRSRV_HANDLE_TYPE_PHYSMEM_PMR,
@@ -777,13 +1201,19 @@
 							,(PFN_HANDLE_RELEASE)&PMRUnrefUnlockPMR);
 	if (psPhysmemNewRamBackedLockedPMROUT->eError != PVRSRV_OK)
 	{
+		UnlockHandle();
 		goto PhysmemNewRamBackedLockedPMR_exit;
 	}
 
+	/* Release now we have created handles. */
+	UnlockHandle();
 
 
 
 PhysmemNewRamBackedLockedPMR_exit:
+
+
+
 	if (psPhysmemNewRamBackedLockedPMROUT->eError != PVRSRV_OK)
 	{
 		if (psPMRPtrInt)
@@ -792,105 +1222,176 @@
 		}
 	}
 
-	if (ui32MappingTableInt)
-		OSFreeMemNoStats(ui32MappingTableInt);
+	/* Allocated space should be equal to the last updated offset */
+	PVR_ASSERT(ui32BufferSize == ui32NextOffset);
+
+#if defined(INTEGRITY_OS)
+	if(pArrayArgsBuffer)
+#else
+	if(!bHaveEnoughSpace && pArrayArgsBuffer)
+#endif
+		OSFreeMemNoStats(pArrayArgsBuffer);
+
 
 	return 0;
 }
 
+
 static IMG_INT
 PVRSRVBridgeDevmemIntPin(IMG_UINT32 ui32DispatchTableEntry,
 					  PVRSRV_BRIDGE_IN_DEVMEMINTPIN *psDevmemIntPinIN,
 					  PVRSRV_BRIDGE_OUT_DEVMEMINTPIN *psDevmemIntPinOUT,
 					 CONNECTION_DATA *psConnection)
 {
+	IMG_HANDLE hPMR = psDevmemIntPinIN->hPMR;
 	PMR * psPMRInt = NULL;
 
 
 
 
 
-	PMRLock();
+
+
+	/* Lock over handle lookup. */
+	LockHandle();
+
+
+
 
 
 				{
 					/* Look up the address from the handle */
 					psDevmemIntPinOUT->eError =
-						PVRSRVLookupHandle(psConnection->psHandleBase,
+						PVRSRVLookupHandleUnlocked(psConnection->psHandleBase,
 											(void **) &psPMRInt,
-											psDevmemIntPinIN->hPMR,
-											PVRSRV_HANDLE_TYPE_PHYSMEM_PMR);
+											hPMR,
+											PVRSRV_HANDLE_TYPE_PHYSMEM_PMR,
+											IMG_TRUE);
 					if(psDevmemIntPinOUT->eError != PVRSRV_OK)
 					{
-						PMRUnlock();
+						UnlockHandle();
 						goto DevmemIntPin_exit;
 					}
 				}
-
+	/* Release now we have looked up handles. */
+	UnlockHandle();
 
 	psDevmemIntPinOUT->eError =
 		DevmemIntPin(
 					psPMRInt);
-	PMRUnlock();
 
 
 
 
 DevmemIntPin_exit:
 
+	/* Lock over handle lookup cleanup. */
+	LockHandle();
+
+
+
+
+
+
+				{
+					/* Unreference the previously looked up handle */
+						if(psPMRInt)
+						{
+							PVRSRVReleaseHandleUnlocked(psConnection->psHandleBase,
+											hPMR,
+											PVRSRV_HANDLE_TYPE_PHYSMEM_PMR);
+						}
+				}
+	/* Release now we have cleaned up look up handles. */
+	UnlockHandle();
+
+
 	return 0;
 }
 
+
 static IMG_INT
 PVRSRVBridgeDevmemIntUnpin(IMG_UINT32 ui32DispatchTableEntry,
 					  PVRSRV_BRIDGE_IN_DEVMEMINTUNPIN *psDevmemIntUnpinIN,
 					  PVRSRV_BRIDGE_OUT_DEVMEMINTUNPIN *psDevmemIntUnpinOUT,
 					 CONNECTION_DATA *psConnection)
 {
+	IMG_HANDLE hPMR = psDevmemIntUnpinIN->hPMR;
 	PMR * psPMRInt = NULL;
 
 
 
 
 
-	PMRLock();
+
+
+	/* Lock over handle lookup. */
+	LockHandle();
+
+
+
 
 
 				{
 					/* Look up the address from the handle */
 					psDevmemIntUnpinOUT->eError =
-						PVRSRVLookupHandle(psConnection->psHandleBase,
+						PVRSRVLookupHandleUnlocked(psConnection->psHandleBase,
 											(void **) &psPMRInt,
-											psDevmemIntUnpinIN->hPMR,
-											PVRSRV_HANDLE_TYPE_PHYSMEM_PMR);
+											hPMR,
+											PVRSRV_HANDLE_TYPE_PHYSMEM_PMR,
+											IMG_TRUE);
 					if(psDevmemIntUnpinOUT->eError != PVRSRV_OK)
 					{
-						PMRUnlock();
+						UnlockHandle();
 						goto DevmemIntUnpin_exit;
 					}
 				}
-
+	/* Release now we have looked up handles. */
+	UnlockHandle();
 
 	psDevmemIntUnpinOUT->eError =
 		DevmemIntUnpin(
 					psPMRInt);
-	PMRUnlock();
 
 
 
 
 DevmemIntUnpin_exit:
 
+	/* Lock over handle lookup cleanup. */
+	LockHandle();
+
+
+
+
+
+
+				{
+					/* Unreference the previously looked up handle */
+						if(psPMRInt)
+						{
+							PVRSRVReleaseHandleUnlocked(psConnection->psHandleBase,
+											hPMR,
+											PVRSRV_HANDLE_TYPE_PHYSMEM_PMR);
+						}
+				}
+	/* Release now we have cleaned up look up handles. */
+	UnlockHandle();
+
+
 	return 0;
 }
 
+
 static IMG_INT
 PVRSRVBridgeDevmemIntPinValidate(IMG_UINT32 ui32DispatchTableEntry,
 					  PVRSRV_BRIDGE_IN_DEVMEMINTPINVALIDATE *psDevmemIntPinValidateIN,
 					  PVRSRV_BRIDGE_OUT_DEVMEMINTPINVALIDATE *psDevmemIntPinValidateOUT,
 					 CONNECTION_DATA *psConnection)
 {
+	IMG_HANDLE hMapping = psDevmemIntPinValidateIN->hMapping;
 	DEVMEMINT_MAPPING * psMappingInt = NULL;
+	IMG_HANDLE hPMR = psDevmemIntPinValidateIN->hPMR;
 	PMR * psPMRInt = NULL;
 
 
@@ -899,33 +1400,48 @@
 
 
 
+	/* Lock over handle lookup. */
+	LockHandle();
+
+
+
+
+
 				{
 					/* Look up the address from the handle */
 					psDevmemIntPinValidateOUT->eError =
-						PVRSRVLookupHandle(psConnection->psHandleBase,
+						PVRSRVLookupHandleUnlocked(psConnection->psHandleBase,
 											(void **) &psMappingInt,
-											psDevmemIntPinValidateIN->hMapping,
-											PVRSRV_HANDLE_TYPE_DEVMEMINT_MAPPING);
+											hMapping,
+											PVRSRV_HANDLE_TYPE_DEVMEMINT_MAPPING,
+											IMG_TRUE);
 					if(psDevmemIntPinValidateOUT->eError != PVRSRV_OK)
 					{
+						UnlockHandle();
 						goto DevmemIntPinValidate_exit;
 					}
 				}
 
 
+
+
+
 				{
 					/* Look up the address from the handle */
 					psDevmemIntPinValidateOUT->eError =
-						PVRSRVLookupHandle(psConnection->psHandleBase,
+						PVRSRVLookupHandleUnlocked(psConnection->psHandleBase,
 											(void **) &psPMRInt,
-											psDevmemIntPinValidateIN->hPMR,
-											PVRSRV_HANDLE_TYPE_PHYSMEM_PMR);
+											hPMR,
+											PVRSRV_HANDLE_TYPE_PHYSMEM_PMR,
+											IMG_TRUE);
 					if(psDevmemIntPinValidateOUT->eError != PVRSRV_OK)
 					{
+						UnlockHandle();
 						goto DevmemIntPinValidate_exit;
 					}
 				}
-
+	/* Release now we have looked up handles. */
+	UnlockHandle();
 
 	psDevmemIntPinValidateOUT->eError =
 		DevmemIntPinValidate(
@@ -937,16 +1453,54 @@
 
 DevmemIntPinValidate_exit:
 
+	/* Lock over handle lookup cleanup. */
+	LockHandle();
+
+
+
+
+
+
+				{
+					/* Unreference the previously looked up handle */
+						if(psMappingInt)
+						{
+							PVRSRVReleaseHandleUnlocked(psConnection->psHandleBase,
+											hMapping,
+											PVRSRV_HANDLE_TYPE_DEVMEMINT_MAPPING);
+						}
+				}
+
+
+
+
+
+				{
+					/* Unreference the previously looked up handle */
+						if(psPMRInt)
+						{
+							PVRSRVReleaseHandleUnlocked(psConnection->psHandleBase,
+											hPMR,
+											PVRSRV_HANDLE_TYPE_PHYSMEM_PMR);
+						}
+				}
+	/* Release now we have cleaned up look up handles. */
+	UnlockHandle();
+
+
 	return 0;
 }
 
+
 static IMG_INT
 PVRSRVBridgeDevmemIntUnpinInvalidate(IMG_UINT32 ui32DispatchTableEntry,
 					  PVRSRV_BRIDGE_IN_DEVMEMINTUNPININVALIDATE *psDevmemIntUnpinInvalidateIN,
 					  PVRSRV_BRIDGE_OUT_DEVMEMINTUNPININVALIDATE *psDevmemIntUnpinInvalidateOUT,
 					 CONNECTION_DATA *psConnection)
 {
+	IMG_HANDLE hMapping = psDevmemIntUnpinInvalidateIN->hMapping;
 	DEVMEMINT_MAPPING * psMappingInt = NULL;
+	IMG_HANDLE hPMR = psDevmemIntUnpinInvalidateIN->hPMR;
 	PMR * psPMRInt = NULL;
 
 
@@ -955,33 +1509,48 @@
 
 
 
+	/* Lock over handle lookup. */
+	LockHandle();
+
+
+
+
+
 				{
 					/* Look up the address from the handle */
 					psDevmemIntUnpinInvalidateOUT->eError =
-						PVRSRVLookupHandle(psConnection->psHandleBase,
+						PVRSRVLookupHandleUnlocked(psConnection->psHandleBase,
 											(void **) &psMappingInt,
-											psDevmemIntUnpinInvalidateIN->hMapping,
-											PVRSRV_HANDLE_TYPE_DEVMEMINT_MAPPING);
+											hMapping,
+											PVRSRV_HANDLE_TYPE_DEVMEMINT_MAPPING,
+											IMG_TRUE);
 					if(psDevmemIntUnpinInvalidateOUT->eError != PVRSRV_OK)
 					{
+						UnlockHandle();
 						goto DevmemIntUnpinInvalidate_exit;
 					}
 				}
 
 
+
+
+
 				{
 					/* Look up the address from the handle */
 					psDevmemIntUnpinInvalidateOUT->eError =
-						PVRSRVLookupHandle(psConnection->psHandleBase,
+						PVRSRVLookupHandleUnlocked(psConnection->psHandleBase,
 											(void **) &psPMRInt,
-											psDevmemIntUnpinInvalidateIN->hPMR,
-											PVRSRV_HANDLE_TYPE_PHYSMEM_PMR);
+											hPMR,
+											PVRSRV_HANDLE_TYPE_PHYSMEM_PMR,
+											IMG_TRUE);
 					if(psDevmemIntUnpinInvalidateOUT->eError != PVRSRV_OK)
 					{
+						UnlockHandle();
 						goto DevmemIntUnpinInvalidate_exit;
 					}
 				}
-
+	/* Release now we have looked up handles. */
+	UnlockHandle();
 
 	psDevmemIntUnpinInvalidateOUT->eError =
 		DevmemIntUnpinInvalidate(
@@ -993,9 +1562,45 @@
 
 DevmemIntUnpinInvalidate_exit:
 
+	/* Lock over handle lookup cleanup. */
+	LockHandle();
+
+
+
+
+
+
+				{
+					/* Unreference the previously looked up handle */
+						if(psMappingInt)
+						{
+							PVRSRVReleaseHandleUnlocked(psConnection->psHandleBase,
+											hMapping,
+											PVRSRV_HANDLE_TYPE_DEVMEMINT_MAPPING);
+						}
+				}
+
+
+
+
+
+				{
+					/* Unreference the previously looked up handle */
+						if(psPMRInt)
+						{
+							PVRSRVReleaseHandleUnlocked(psConnection->psHandleBase,
+											hPMR,
+											PVRSRV_HANDLE_TYPE_PHYSMEM_PMR);
+						}
+				}
+	/* Release now we have cleaned up look up handles. */
+	UnlockHandle();
+
+
 	return 0;
 }
 
+
 static IMG_INT
 PVRSRVBridgeDevmemIntCtxCreate(IMG_UINT32 ui32DispatchTableEntry,
 					  PVRSRV_BRIDGE_IN_DEVMEMINTCTXCREATE *psDevmemIntCtxCreateIN,
@@ -1007,27 +1612,33 @@
 
 
 
+
+
 	psDevmemIntCtxCreateOUT->hDevMemServerContext = NULL;
 
 
-	PMRLock();
-
 
 	psDevmemIntCtxCreateOUT->eError =
 		DevmemIntCtxCreate(psConnection, OSGetDevData(psConnection),
 					psDevmemIntCtxCreateIN->bbKernelMemoryCtx,
 					&psDevMemServerContextInt,
-					&hPrivDataInt);
+					&hPrivDataInt,
+					&psDevmemIntCtxCreateOUT->ui32CPUCacheLineSize);
 	/* Exit early if bridged call fails */
 	if(psDevmemIntCtxCreateOUT->eError != PVRSRV_OK)
 	{
-		PMRUnlock();
 		goto DevmemIntCtxCreate_exit;
 	}
-	PMRUnlock();
+
+	/* Lock over handle creation. */
+	LockHandle();
 
 
-	psDevmemIntCtxCreateOUT->eError = PVRSRVAllocHandle(psConnection->psHandleBase,
+
+
+
+	psDevmemIntCtxCreateOUT->eError = PVRSRVAllocHandleUnlocked(psConnection->psHandleBase,
+
 							&psDevmemIntCtxCreateOUT->hDevMemServerContext,
 							(void *) psDevMemServerContextInt,
 							PVRSRV_HANDLE_TYPE_DEVMEMINT_CTX,
@@ -1035,11 +1646,17 @@
 							,(PFN_HANDLE_RELEASE)&DevmemIntCtxDestroy);
 	if (psDevmemIntCtxCreateOUT->eError != PVRSRV_OK)
 	{
+		UnlockHandle();
 		goto DevmemIntCtxCreate_exit;
 	}
 
 
-	psDevmemIntCtxCreateOUT->eError = PVRSRVAllocSubHandle(psConnection->psHandleBase,
+
+
+
+
+	psDevmemIntCtxCreateOUT->eError = PVRSRVAllocSubHandleUnlocked(psConnection->psHandleBase,
+
 							&psDevmemIntCtxCreateOUT->hPrivData,
 							(void *) hPrivDataInt,
 							PVRSRV_HANDLE_TYPE_DEV_PRIV_DATA,
@@ -1047,22 +1664,38 @@
 							,psDevmemIntCtxCreateOUT->hDevMemServerContext);
 	if (psDevmemIntCtxCreateOUT->eError != PVRSRV_OK)
 	{
+		UnlockHandle();
 		goto DevmemIntCtxCreate_exit;
 	}
 
+	/* Release now we have created handles. */
+	UnlockHandle();
 
 
 
 DevmemIntCtxCreate_exit:
+
+
+
 	if (psDevmemIntCtxCreateOUT->eError != PVRSRV_OK)
 	{
+		/* Lock over handle creation cleanup. */
+		LockHandle();
 		if (psDevmemIntCtxCreateOUT->hDevMemServerContext)
 		{
-			PVRSRV_ERROR eError = PVRSRVReleaseHandle(psConnection->psHandleBase,
+
+
+			PVRSRV_ERROR eError = PVRSRVReleaseHandleUnlocked(psConnection->psHandleBase,
 						(IMG_HANDLE) psDevmemIntCtxCreateOUT->hDevMemServerContext,
 						PVRSRV_HANDLE_TYPE_DEVMEMINT_CTX);
-
-			/* Releasing the handle should free/destroy/release the resource. This should never fail... */
+			if ((eError != PVRSRV_OK) && (eError != PVRSRV_ERROR_RETRY))
+			{
+				PVR_DPF((PVR_DBG_ERROR,
+				        "PVRSRVBridgeDevmemIntCtxCreate: %s",
+				        PVRSRVGetErrorStringKM(eError)));
+			}
+			/* Releasing the handle should free/destroy/release the resource.
+			 * This should never fail... */
 			PVR_ASSERT((eError == PVRSRV_OK) || (eError == PVRSRV_ERROR_RETRY));
 
 			/* Avoid freeing/destroying/releasing the resource a second time below */
@@ -1070,6 +1703,8 @@
 		}
 
 
+		/* Release now we have cleaned up creation handles. */
+		UnlockHandle();
 		if (psDevMemServerContextInt)
 		{
 			DevmemIntCtxDestroy(psDevMemServerContextInt);
@@ -1080,6 +1715,7 @@
 	return 0;
 }
 
+
 static IMG_INT
 PVRSRVBridgeDevmemIntCtxDestroy(IMG_UINT32 ui32DispatchTableEntry,
 					  PVRSRV_BRIDGE_IN_DEVMEMINTCTXDESTROY *psDevmemIntCtxDestroyIN,
@@ -1091,36 +1727,53 @@
 
 
 
-	PMRLock();
+
+
+
+
+	/* Lock over handle destruction. */
+	LockHandle();
+
 
 
 
 
 	psDevmemIntCtxDestroyOUT->eError =
-		PVRSRVReleaseHandle(psConnection->psHandleBase,
+		PVRSRVReleaseHandleUnlocked(psConnection->psHandleBase,
 					(IMG_HANDLE) psDevmemIntCtxDestroyIN->hDevmemServerContext,
 					PVRSRV_HANDLE_TYPE_DEVMEMINT_CTX);
-	if ((psDevmemIntCtxDestroyOUT->eError != PVRSRV_OK) && (psDevmemIntCtxDestroyOUT->eError != PVRSRV_ERROR_RETRY))
+	if ((psDevmemIntCtxDestroyOUT->eError != PVRSRV_OK) &&
+	    (psDevmemIntCtxDestroyOUT->eError != PVRSRV_ERROR_RETRY))
 	{
+		PVR_DPF((PVR_DBG_ERROR,
+		        "PVRSRVBridgeDevmemIntCtxDestroy: %s",
+		        PVRSRVGetErrorStringKM(psDevmemIntCtxDestroyOUT->eError)));
 		PVR_ASSERT(0);
-		PMRUnlock();
+		UnlockHandle();
 		goto DevmemIntCtxDestroy_exit;
 	}
 
-	PMRUnlock();
+	/* Release now we have destroyed handles. */
+	UnlockHandle();
+
 
 
 DevmemIntCtxDestroy_exit:
 
+
+
+
 	return 0;
 }
 
+
 static IMG_INT
 PVRSRVBridgeDevmemIntHeapCreate(IMG_UINT32 ui32DispatchTableEntry,
 					  PVRSRV_BRIDGE_IN_DEVMEMINTHEAPCREATE *psDevmemIntHeapCreateIN,
 					  PVRSRV_BRIDGE_OUT_DEVMEMINTHEAPCREATE *psDevmemIntHeapCreateOUT,
 					 CONNECTION_DATA *psConnection)
 {
+	IMG_HANDLE hDevmemCtx = psDevmemIntHeapCreateIN->hDevmemCtx;
 	DEVMEMINT_CTX * psDevmemCtxInt = NULL;
 	DEVMEMINT_HEAP * psDevmemHeapPtrInt = NULL;
 
@@ -1130,19 +1783,29 @@
 
 
 
+	/* Lock over handle lookup. */
+	LockHandle();
+
+
+
+
+
 				{
 					/* Look up the address from the handle */
 					psDevmemIntHeapCreateOUT->eError =
-						PVRSRVLookupHandle(psConnection->psHandleBase,
+						PVRSRVLookupHandleUnlocked(psConnection->psHandleBase,
 											(void **) &psDevmemCtxInt,
-											psDevmemIntHeapCreateIN->hDevmemCtx,
-											PVRSRV_HANDLE_TYPE_DEVMEMINT_CTX);
+											hDevmemCtx,
+											PVRSRV_HANDLE_TYPE_DEVMEMINT_CTX,
+											IMG_TRUE);
 					if(psDevmemIntHeapCreateOUT->eError != PVRSRV_OK)
 					{
+						UnlockHandle();
 						goto DevmemIntHeapCreate_exit;
 					}
 				}
-
+	/* Release now we have looked up handles. */
+	UnlockHandle();
 
 	psDevmemIntHeapCreateOUT->eError =
 		DevmemIntHeapCreate(
@@ -1157,8 +1820,15 @@
 		goto DevmemIntHeapCreate_exit;
 	}
 
+	/* Lock over handle creation. */
+	LockHandle();
 
-	psDevmemIntHeapCreateOUT->eError = PVRSRVAllocHandle(psConnection->psHandleBase,
+
+
+
+
+	psDevmemIntHeapCreateOUT->eError = PVRSRVAllocHandleUnlocked(psConnection->psHandleBase,
+
 							&psDevmemIntHeapCreateOUT->hDevmemHeapPtr,
 							(void *) psDevmemHeapPtrInt,
 							PVRSRV_HANDLE_TYPE_DEVMEMINT_HEAP,
@@ -1166,13 +1836,37 @@
 							,(PFN_HANDLE_RELEASE)&DevmemIntHeapDestroy);
 	if (psDevmemIntHeapCreateOUT->eError != PVRSRV_OK)
 	{
+		UnlockHandle();
 		goto DevmemIntHeapCreate_exit;
 	}
 
+	/* Release now we have created handles. */
+	UnlockHandle();
 
 
 
 DevmemIntHeapCreate_exit:
+
+	/* Lock over handle lookup cleanup. */
+	LockHandle();
+
+
+
+
+
+
+				{
+					/* Unreference the previously looked up handle */
+						if(psDevmemCtxInt)
+						{
+							PVRSRVReleaseHandleUnlocked(psConnection->psHandleBase,
+											hDevmemCtx,
+											PVRSRV_HANDLE_TYPE_DEVMEMINT_CTX);
+						}
+				}
+	/* Release now we have cleaned up look up handles. */
+	UnlockHandle();
+
 	if (psDevmemIntHeapCreateOUT->eError != PVRSRV_OK)
 	{
 		if (psDevmemHeapPtrInt)
@@ -1185,6 +1879,7 @@
 	return 0;
 }
 
+
 static IMG_INT
 PVRSRVBridgeDevmemIntHeapDestroy(IMG_UINT32 ui32DispatchTableEntry,
 					  PVRSRV_BRIDGE_IN_DEVMEMINTHEAPDESTROY *psDevmemIntHeapDestroyIN,
@@ -1200,31 +1895,53 @@
 
 
 
+	/* Lock over handle destruction. */
+	LockHandle();
+
+
+
+
+
 	psDevmemIntHeapDestroyOUT->eError =
-		PVRSRVReleaseHandle(psConnection->psHandleBase,
+		PVRSRVReleaseHandleUnlocked(psConnection->psHandleBase,
 					(IMG_HANDLE) psDevmemIntHeapDestroyIN->hDevmemHeap,
 					PVRSRV_HANDLE_TYPE_DEVMEMINT_HEAP);
-	if ((psDevmemIntHeapDestroyOUT->eError != PVRSRV_OK) && (psDevmemIntHeapDestroyOUT->eError != PVRSRV_ERROR_RETRY))
+	if ((psDevmemIntHeapDestroyOUT->eError != PVRSRV_OK) &&
+	    (psDevmemIntHeapDestroyOUT->eError != PVRSRV_ERROR_RETRY))
 	{
+		PVR_DPF((PVR_DBG_ERROR,
+		        "PVRSRVBridgeDevmemIntHeapDestroy: %s",
+		        PVRSRVGetErrorStringKM(psDevmemIntHeapDestroyOUT->eError)));
 		PVR_ASSERT(0);
+		UnlockHandle();
 		goto DevmemIntHeapDestroy_exit;
 	}
 
+	/* Release now we have destroyed handles. */
+	UnlockHandle();
+
 
 
 DevmemIntHeapDestroy_exit:
 
+
+
+
 	return 0;
 }
 
+
 static IMG_INT
 PVRSRVBridgeDevmemIntMapPMR(IMG_UINT32 ui32DispatchTableEntry,
 					  PVRSRV_BRIDGE_IN_DEVMEMINTMAPPMR *psDevmemIntMapPMRIN,
 					  PVRSRV_BRIDGE_OUT_DEVMEMINTMAPPMR *psDevmemIntMapPMROUT,
 					 CONNECTION_DATA *psConnection)
 {
+	IMG_HANDLE hDevmemServerHeap = psDevmemIntMapPMRIN->hDevmemServerHeap;
 	DEVMEMINT_HEAP * psDevmemServerHeapInt = NULL;
+	IMG_HANDLE hReservation = psDevmemIntMapPMRIN->hReservation;
 	DEVMEMINT_RESERVATION * psReservationInt = NULL;
+	IMG_HANDLE hPMR = psDevmemIntMapPMRIN->hPMR;
 	PMR * psPMRInt = NULL;
 	DEVMEMINT_MAPPING * psMappingInt = NULL;
 
@@ -1232,53 +1949,69 @@
 
 
 
-	PMRLock();
+
+
+	/* Lock over handle lookup. */
+	LockHandle();
+
+
+
 
 
 				{
 					/* Look up the address from the handle */
 					psDevmemIntMapPMROUT->eError =
-						PVRSRVLookupHandle(psConnection->psHandleBase,
+						PVRSRVLookupHandleUnlocked(psConnection->psHandleBase,
 											(void **) &psDevmemServerHeapInt,
-											psDevmemIntMapPMRIN->hDevmemServerHeap,
-											PVRSRV_HANDLE_TYPE_DEVMEMINT_HEAP);
+											hDevmemServerHeap,
+											PVRSRV_HANDLE_TYPE_DEVMEMINT_HEAP,
+											IMG_TRUE);
 					if(psDevmemIntMapPMROUT->eError != PVRSRV_OK)
 					{
-						PMRUnlock();
+						UnlockHandle();
 						goto DevmemIntMapPMR_exit;
 					}
 				}
 
 
+
+
+
 				{
 					/* Look up the address from the handle */
 					psDevmemIntMapPMROUT->eError =
-						PVRSRVLookupHandle(psConnection->psHandleBase,
+						PVRSRVLookupHandleUnlocked(psConnection->psHandleBase,
 											(void **) &psReservationInt,
-											psDevmemIntMapPMRIN->hReservation,
-											PVRSRV_HANDLE_TYPE_DEVMEMINT_RESERVATION);
+											hReservation,
+											PVRSRV_HANDLE_TYPE_DEVMEMINT_RESERVATION,
+											IMG_TRUE);
 					if(psDevmemIntMapPMROUT->eError != PVRSRV_OK)
 					{
-						PMRUnlock();
+						UnlockHandle();
 						goto DevmemIntMapPMR_exit;
 					}
 				}
 
 
+
+
+
 				{
 					/* Look up the address from the handle */
 					psDevmemIntMapPMROUT->eError =
-						PVRSRVLookupHandle(psConnection->psHandleBase,
+						PVRSRVLookupHandleUnlocked(psConnection->psHandleBase,
 											(void **) &psPMRInt,
-											psDevmemIntMapPMRIN->hPMR,
-											PVRSRV_HANDLE_TYPE_PHYSMEM_PMR);
+											hPMR,
+											PVRSRV_HANDLE_TYPE_PHYSMEM_PMR,
+											IMG_TRUE);
 					if(psDevmemIntMapPMROUT->eError != PVRSRV_OK)
 					{
-						PMRUnlock();
+						UnlockHandle();
 						goto DevmemIntMapPMR_exit;
 					}
 				}
-
+	/* Release now we have looked up handles. */
+	UnlockHandle();
 
 	psDevmemIntMapPMROUT->eError =
 		DevmemIntMapPMR(
@@ -1290,13 +2023,18 @@
 	/* Exit early if bridged call fails */
 	if(psDevmemIntMapPMROUT->eError != PVRSRV_OK)
 	{
-		PMRUnlock();
 		goto DevmemIntMapPMR_exit;
 	}
-	PMRUnlock();
+
+	/* Lock over handle creation. */
+	LockHandle();
 
 
-	psDevmemIntMapPMROUT->eError = PVRSRVAllocHandle(psConnection->psHandleBase,
+
+
+
+	psDevmemIntMapPMROUT->eError = PVRSRVAllocHandleUnlocked(psConnection->psHandleBase,
+
 							&psDevmemIntMapPMROUT->hMapping,
 							(void *) psMappingInt,
 							PVRSRV_HANDLE_TYPE_DEVMEMINT_MAPPING,
@@ -1304,13 +2042,65 @@
 							,(PFN_HANDLE_RELEASE)&DevmemIntUnmapPMR);
 	if (psDevmemIntMapPMROUT->eError != PVRSRV_OK)
 	{
+		UnlockHandle();
 		goto DevmemIntMapPMR_exit;
 	}
 
+	/* Release now we have created handles. */
+	UnlockHandle();
 
 
 
 DevmemIntMapPMR_exit:
+
+	/* Lock over handle lookup cleanup. */
+	LockHandle();
+
+
+
+
+
+
+				{
+					/* Unreference the previously looked up handle */
+						if(psDevmemServerHeapInt)
+						{
+							PVRSRVReleaseHandleUnlocked(psConnection->psHandleBase,
+											hDevmemServerHeap,
+											PVRSRV_HANDLE_TYPE_DEVMEMINT_HEAP);
+						}
+				}
+
+
+
+
+
+				{
+					/* Unreference the previously looked up handle */
+						if(psReservationInt)
+						{
+							PVRSRVReleaseHandleUnlocked(psConnection->psHandleBase,
+											hReservation,
+											PVRSRV_HANDLE_TYPE_DEVMEMINT_RESERVATION);
+						}
+				}
+
+
+
+
+
+				{
+					/* Unreference the previously looked up handle */
+						if(psPMRInt)
+						{
+							PVRSRVReleaseHandleUnlocked(psConnection->psHandleBase,
+											hPMR,
+											PVRSRV_HANDLE_TYPE_PHYSMEM_PMR);
+						}
+				}
+	/* Release now we have cleaned up look up handles. */
+	UnlockHandle();
+
 	if (psDevmemIntMapPMROUT->eError != PVRSRV_OK)
 	{
 		if (psMappingInt)
@@ -1323,6 +2113,7 @@
 	return 0;
 }
 
+
 static IMG_INT
 PVRSRVBridgeDevmemIntUnmapPMR(IMG_UINT32 ui32DispatchTableEntry,
 					  PVRSRV_BRIDGE_IN_DEVMEMINTUNMAPPMR *psDevmemIntUnmapPMRIN,
@@ -1334,36 +2125,53 @@
 
 
 
-	PMRLock();
+
+
+
+
+	/* Lock over handle destruction. */
+	LockHandle();
+
 
 
 
 
 	psDevmemIntUnmapPMROUT->eError =
-		PVRSRVReleaseHandle(psConnection->psHandleBase,
+		PVRSRVReleaseHandleUnlocked(psConnection->psHandleBase,
 					(IMG_HANDLE) psDevmemIntUnmapPMRIN->hMapping,
 					PVRSRV_HANDLE_TYPE_DEVMEMINT_MAPPING);
-	if ((psDevmemIntUnmapPMROUT->eError != PVRSRV_OK) && (psDevmemIntUnmapPMROUT->eError != PVRSRV_ERROR_RETRY))
+	if ((psDevmemIntUnmapPMROUT->eError != PVRSRV_OK) &&
+	    (psDevmemIntUnmapPMROUT->eError != PVRSRV_ERROR_RETRY))
 	{
+		PVR_DPF((PVR_DBG_ERROR,
+		        "PVRSRVBridgeDevmemIntUnmapPMR: %s",
+		        PVRSRVGetErrorStringKM(psDevmemIntUnmapPMROUT->eError)));
 		PVR_ASSERT(0);
-		PMRUnlock();
+		UnlockHandle();
 		goto DevmemIntUnmapPMR_exit;
 	}
 
-	PMRUnlock();
+	/* Release now we have destroyed handles. */
+	UnlockHandle();
+
 
 
 DevmemIntUnmapPMR_exit:
 
+
+
+
 	return 0;
 }
 
+
 static IMG_INT
 PVRSRVBridgeDevmemIntReserveRange(IMG_UINT32 ui32DispatchTableEntry,
 					  PVRSRV_BRIDGE_IN_DEVMEMINTRESERVERANGE *psDevmemIntReserveRangeIN,
 					  PVRSRV_BRIDGE_OUT_DEVMEMINTRESERVERANGE *psDevmemIntReserveRangeOUT,
 					 CONNECTION_DATA *psConnection)
 {
+	IMG_HANDLE hDevmemServerHeap = psDevmemIntReserveRangeIN->hDevmemServerHeap;
 	DEVMEMINT_HEAP * psDevmemServerHeapInt = NULL;
 	DEVMEMINT_RESERVATION * psReservationInt = NULL;
 
@@ -1373,19 +2181,29 @@
 
 
 
+	/* Lock over handle lookup. */
+	LockHandle();
+
+
+
+
+
 				{
 					/* Look up the address from the handle */
 					psDevmemIntReserveRangeOUT->eError =
-						PVRSRVLookupHandle(psConnection->psHandleBase,
+						PVRSRVLookupHandleUnlocked(psConnection->psHandleBase,
 											(void **) &psDevmemServerHeapInt,
-											psDevmemIntReserveRangeIN->hDevmemServerHeap,
-											PVRSRV_HANDLE_TYPE_DEVMEMINT_HEAP);
+											hDevmemServerHeap,
+											PVRSRV_HANDLE_TYPE_DEVMEMINT_HEAP,
+											IMG_TRUE);
 					if(psDevmemIntReserveRangeOUT->eError != PVRSRV_OK)
 					{
+						UnlockHandle();
 						goto DevmemIntReserveRange_exit;
 					}
 				}
-
+	/* Release now we have looked up handles. */
+	UnlockHandle();
 
 	psDevmemIntReserveRangeOUT->eError =
 		DevmemIntReserveRange(
@@ -1399,8 +2217,15 @@
 		goto DevmemIntReserveRange_exit;
 	}
 
+	/* Lock over handle creation. */
+	LockHandle();
 
-	psDevmemIntReserveRangeOUT->eError = PVRSRVAllocHandle(psConnection->psHandleBase,
+
+
+
+
+	psDevmemIntReserveRangeOUT->eError = PVRSRVAllocHandleUnlocked(psConnection->psHandleBase,
+
 							&psDevmemIntReserveRangeOUT->hReservation,
 							(void *) psReservationInt,
 							PVRSRV_HANDLE_TYPE_DEVMEMINT_RESERVATION,
@@ -1408,13 +2233,37 @@
 							,(PFN_HANDLE_RELEASE)&DevmemIntUnreserveRange);
 	if (psDevmemIntReserveRangeOUT->eError != PVRSRV_OK)
 	{
+		UnlockHandle();
 		goto DevmemIntReserveRange_exit;
 	}
 
+	/* Release now we have created handles. */
+	UnlockHandle();
 
 
 
 DevmemIntReserveRange_exit:
+
+	/* Lock over handle lookup cleanup. */
+	LockHandle();
+
+
+
+
+
+
+				{
+					/* Unreference the previously looked up handle */
+						if(psDevmemServerHeapInt)
+						{
+							PVRSRVReleaseHandleUnlocked(psConnection->psHandleBase,
+											hDevmemServerHeap,
+											PVRSRV_HANDLE_TYPE_DEVMEMINT_HEAP);
+						}
+				}
+	/* Release now we have cleaned up look up handles. */
+	UnlockHandle();
+
 	if (psDevmemIntReserveRangeOUT->eError != PVRSRV_OK)
 	{
 		if (psReservationInt)
@@ -1427,6 +2276,7 @@
 	return 0;
 }
 
+
 static IMG_INT
 PVRSRVBridgeDevmemIntUnreserveRange(IMG_UINT32 ui32DispatchTableEntry,
 					  PVRSRV_BRIDGE_IN_DEVMEMINTUNRESERVERANGE *psDevmemIntUnreserveRangeIN,
@@ -1442,113 +2292,175 @@
 
 
 
+	/* Lock over handle destruction. */
+	LockHandle();
+
+
+
+
+
 	psDevmemIntUnreserveRangeOUT->eError =
-		PVRSRVReleaseHandle(psConnection->psHandleBase,
+		PVRSRVReleaseHandleUnlocked(psConnection->psHandleBase,
 					(IMG_HANDLE) psDevmemIntUnreserveRangeIN->hReservation,
 					PVRSRV_HANDLE_TYPE_DEVMEMINT_RESERVATION);
-	if ((psDevmemIntUnreserveRangeOUT->eError != PVRSRV_OK) && (psDevmemIntUnreserveRangeOUT->eError != PVRSRV_ERROR_RETRY))
+	if ((psDevmemIntUnreserveRangeOUT->eError != PVRSRV_OK) &&
+	    (psDevmemIntUnreserveRangeOUT->eError != PVRSRV_ERROR_RETRY))
 	{
+		PVR_DPF((PVR_DBG_ERROR,
+		        "PVRSRVBridgeDevmemIntUnreserveRange: %s",
+		        PVRSRVGetErrorStringKM(psDevmemIntUnreserveRangeOUT->eError)));
 		PVR_ASSERT(0);
+		UnlockHandle();
 		goto DevmemIntUnreserveRange_exit;
 	}
 
+	/* Release now we have destroyed handles. */
+	UnlockHandle();
+
 
 
 DevmemIntUnreserveRange_exit:
 
+
+
+
 	return 0;
 }
 
+
 static IMG_INT
 PVRSRVBridgeChangeSparseMem(IMG_UINT32 ui32DispatchTableEntry,
 					  PVRSRV_BRIDGE_IN_CHANGESPARSEMEM *psChangeSparseMemIN,
 					  PVRSRV_BRIDGE_OUT_CHANGESPARSEMEM *psChangeSparseMemOUT,
 					 CONNECTION_DATA *psConnection)
 {
+	IMG_HANDLE hSrvDevMemHeap = psChangeSparseMemIN->hSrvDevMemHeap;
 	DEVMEMINT_HEAP * psSrvDevMemHeapInt = NULL;
+	IMG_HANDLE hPMR = psChangeSparseMemIN->hPMR;
 	PMR * psPMRInt = NULL;
 	IMG_UINT32 *ui32AllocPageIndicesInt = NULL;
 	IMG_UINT32 *ui32FreePageIndicesInt = NULL;
 
+	IMG_UINT32 ui32NextOffset = 0;
+	IMG_BYTE   *pArrayArgsBuffer = NULL;
+#if !defined(INTEGRITY_OS)
+	IMG_BOOL bHaveEnoughSpace = IMG_FALSE;
+#endif
+
+	IMG_UINT32 ui32BufferSize = 
+			(psChangeSparseMemIN->ui32AllocPageCount * sizeof(IMG_UINT32)) +
+			(psChangeSparseMemIN->ui32FreePageCount * sizeof(IMG_UINT32)) +
+			0;
 
 
 
+
+
+	if (ui32BufferSize != 0)
+	{
+#if !defined(INTEGRITY_OS)
+		/* Try to use remainder of input buffer for copies if possible, word-aligned for safety. */
+		IMG_UINT32 ui32InBufferOffset = PVR_ALIGN(sizeof(*psChangeSparseMemIN), sizeof(unsigned long));
+		IMG_UINT32 ui32InBufferExcessSize = ui32InBufferOffset >= PVRSRV_MAX_BRIDGE_IN_SIZE ? 0 :
+			PVRSRV_MAX_BRIDGE_IN_SIZE - ui32InBufferOffset;
+
+		bHaveEnoughSpace = ui32BufferSize <= ui32InBufferExcessSize;
+		if (bHaveEnoughSpace)
+		{
+			IMG_BYTE *pInputBuffer = (IMG_BYTE *)psChangeSparseMemIN;
+
+			pArrayArgsBuffer = &pInputBuffer[ui32InBufferOffset];		}
+		else
+#endif
+		{
+			pArrayArgsBuffer = OSAllocMemNoStats(ui32BufferSize);
+
+			if(!pArrayArgsBuffer)
+			{
+				psChangeSparseMemOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
+				goto ChangeSparseMem_exit;
+			}
+		}
+	}
+
 	if (psChangeSparseMemIN->ui32AllocPageCount != 0)
 	{
-		ui32AllocPageIndicesInt = OSAllocMemNoStats(psChangeSparseMemIN->ui32AllocPageCount * sizeof(IMG_UINT32));
-		if (!ui32AllocPageIndicesInt)
-		{
-			psChangeSparseMemOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
-	
-			goto ChangeSparseMem_exit;
-		}
+		ui32AllocPageIndicesInt = (IMG_UINT32*)(((IMG_UINT8 *)pArrayArgsBuffer) + ui32NextOffset);
+		ui32NextOffset += psChangeSparseMemIN->ui32AllocPageCount * sizeof(IMG_UINT32);
 	}
 
 			/* Copy the data over */
-			if ( !OSAccessOK(PVR_VERIFY_READ, (void*) psChangeSparseMemIN->pui32AllocPageIndices, psChangeSparseMemIN->ui32AllocPageCount * sizeof(IMG_UINT32))
-				|| (OSCopyFromUser(NULL, ui32AllocPageIndicesInt, psChangeSparseMemIN->pui32AllocPageIndices,
-				psChangeSparseMemIN->ui32AllocPageCount * sizeof(IMG_UINT32)) != PVRSRV_OK) )
+			if (psChangeSparseMemIN->ui32AllocPageCount * sizeof(IMG_UINT32) > 0)
 			{
-				psChangeSparseMemOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
+				if ( OSCopyFromUser(NULL, ui32AllocPageIndicesInt, psChangeSparseMemIN->pui32AllocPageIndices, psChangeSparseMemIN->ui32AllocPageCount * sizeof(IMG_UINT32)) != PVRSRV_OK )
+				{
+					psChangeSparseMemOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
 
-				goto ChangeSparseMem_exit;
+					goto ChangeSparseMem_exit;
+				}
 			}
 	if (psChangeSparseMemIN->ui32FreePageCount != 0)
 	{
-		ui32FreePageIndicesInt = OSAllocMemNoStats(psChangeSparseMemIN->ui32FreePageCount * sizeof(IMG_UINT32));
-		if (!ui32FreePageIndicesInt)
-		{
-			psChangeSparseMemOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
-	
-			goto ChangeSparseMem_exit;
-		}
+		ui32FreePageIndicesInt = (IMG_UINT32*)(((IMG_UINT8 *)pArrayArgsBuffer) + ui32NextOffset);
+		ui32NextOffset += psChangeSparseMemIN->ui32FreePageCount * sizeof(IMG_UINT32);
 	}
 
 			/* Copy the data over */
-			if ( !OSAccessOK(PVR_VERIFY_READ, (void*) psChangeSparseMemIN->pui32FreePageIndices, psChangeSparseMemIN->ui32FreePageCount * sizeof(IMG_UINT32))
-				|| (OSCopyFromUser(NULL, ui32FreePageIndicesInt, psChangeSparseMemIN->pui32FreePageIndices,
-				psChangeSparseMemIN->ui32FreePageCount * sizeof(IMG_UINT32)) != PVRSRV_OK) )
+			if (psChangeSparseMemIN->ui32FreePageCount * sizeof(IMG_UINT32) > 0)
 			{
-				psChangeSparseMemOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
+				if ( OSCopyFromUser(NULL, ui32FreePageIndicesInt, psChangeSparseMemIN->pui32FreePageIndices, psChangeSparseMemIN->ui32FreePageCount * sizeof(IMG_UINT32)) != PVRSRV_OK )
+				{
+					psChangeSparseMemOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
 
-				goto ChangeSparseMem_exit;
+					goto ChangeSparseMem_exit;
+				}
 			}
 
-	PMRLock();
+	/* Lock over handle lookup. */
+	LockHandle();
+
+
+
 
 
 				{
 					/* Look up the address from the handle */
 					psChangeSparseMemOUT->eError =
-						PVRSRVLookupHandle(psConnection->psHandleBase,
+						PVRSRVLookupHandleUnlocked(psConnection->psHandleBase,
 											(void **) &psSrvDevMemHeapInt,
-											psChangeSparseMemIN->hSrvDevMemHeap,
-											PVRSRV_HANDLE_TYPE_DEVMEMINT_HEAP);
+											hSrvDevMemHeap,
+											PVRSRV_HANDLE_TYPE_DEVMEMINT_HEAP,
+											IMG_TRUE);
 					if(psChangeSparseMemOUT->eError != PVRSRV_OK)
 					{
-						PMRUnlock();
+						UnlockHandle();
 						goto ChangeSparseMem_exit;
 					}
 				}
 
 
+
+
+
 				{
 					/* Look up the address from the handle */
 					psChangeSparseMemOUT->eError =
-						PVRSRVLookupHandle(psConnection->psHandleBase,
+						PVRSRVLookupHandleUnlocked(psConnection->psHandleBase,
 											(void **) &psPMRInt,
-											psChangeSparseMemIN->hPMR,
-											PVRSRV_HANDLE_TYPE_PHYSMEM_PMR);
+											hPMR,
+											PVRSRV_HANDLE_TYPE_PHYSMEM_PMR,
+											IMG_TRUE);
 					if(psChangeSparseMemOUT->eError != PVRSRV_OK)
 					{
-						PMRUnlock();
+						UnlockHandle();
 						goto ChangeSparseMem_exit;
 					}
 				}
-
+	/* Release now we have looked up handles. */
+	UnlockHandle();
 
 	psChangeSparseMemOUT->eError =
-		DeviceMemChangeSparseServer(
+		DevmemIntChangeSparse(
 					psSrvDevMemHeapInt,
 					psPMRInt,
 					psChangeSparseMemIN->ui32AllocPageCount,
@@ -1558,67 +2470,121 @@
 					psChangeSparseMemIN->ui32SparseFlags,
 					psChangeSparseMemIN->uiFlags,
 					psChangeSparseMemIN->sDevVAddr,
-					psChangeSparseMemIN->ui64CPUVAddr,
-					&psChangeSparseMemOUT->ui32Status);
-	PMRUnlock();
+					psChangeSparseMemIN->ui64CPUVAddr);
 
 
 
 
 ChangeSparseMem_exit:
-	if (ui32AllocPageIndicesInt)
-		OSFreeMemNoStats(ui32AllocPageIndicesInt);
-	if (ui32FreePageIndicesInt)
-		OSFreeMemNoStats(ui32FreePageIndicesInt);
+
+	/* Lock over handle lookup cleanup. */
+	LockHandle();
+
+
+
+
+
+
+				{
+					/* Unreference the previously looked up handle */
+						if(psSrvDevMemHeapInt)
+						{
+							PVRSRVReleaseHandleUnlocked(psConnection->psHandleBase,
+											hSrvDevMemHeap,
+											PVRSRV_HANDLE_TYPE_DEVMEMINT_HEAP);
+						}
+				}
+
+
+
+
+
+				{
+					/* Unreference the previously looked up handle */
+						if(psPMRInt)
+						{
+							PVRSRVReleaseHandleUnlocked(psConnection->psHandleBase,
+											hPMR,
+											PVRSRV_HANDLE_TYPE_PHYSMEM_PMR);
+						}
+				}
+	/* Release now we have cleaned up look up handles. */
+	UnlockHandle();
+
+	/* Allocated space should be equal to the last updated offset */
+	PVR_ASSERT(ui32BufferSize == ui32NextOffset);
+
+#if defined(INTEGRITY_OS)
+	if(pArrayArgsBuffer)
+#else
+	if(!bHaveEnoughSpace && pArrayArgsBuffer)
+#endif
+		OSFreeMemNoStats(pArrayArgsBuffer);
+
 
 	return 0;
 }
 
+
 static IMG_INT
 PVRSRVBridgeDevmemIntMapPages(IMG_UINT32 ui32DispatchTableEntry,
 					  PVRSRV_BRIDGE_IN_DEVMEMINTMAPPAGES *psDevmemIntMapPagesIN,
 					  PVRSRV_BRIDGE_OUT_DEVMEMINTMAPPAGES *psDevmemIntMapPagesOUT,
 					 CONNECTION_DATA *psConnection)
 {
+	IMG_HANDLE hReservation = psDevmemIntMapPagesIN->hReservation;
 	DEVMEMINT_RESERVATION * psReservationInt = NULL;
+	IMG_HANDLE hPMR = psDevmemIntMapPagesIN->hPMR;
 	PMR * psPMRInt = NULL;
 
 
 
 
 
-	PMRLock();
+
+
+	/* Lock over handle lookup. */
+	LockHandle();
+
+
+
 
 
 				{
 					/* Look up the address from the handle */
 					psDevmemIntMapPagesOUT->eError =
-						PVRSRVLookupHandle(psConnection->psHandleBase,
+						PVRSRVLookupHandleUnlocked(psConnection->psHandleBase,
 											(void **) &psReservationInt,
-											psDevmemIntMapPagesIN->hReservation,
-											PVRSRV_HANDLE_TYPE_DEVMEMINT_RESERVATION);
+											hReservation,
+											PVRSRV_HANDLE_TYPE_DEVMEMINT_RESERVATION,
+											IMG_TRUE);
 					if(psDevmemIntMapPagesOUT->eError != PVRSRV_OK)
 					{
-						PMRUnlock();
+						UnlockHandle();
 						goto DevmemIntMapPages_exit;
 					}
 				}
 
 
+
+
+
 				{
 					/* Look up the address from the handle */
 					psDevmemIntMapPagesOUT->eError =
-						PVRSRVLookupHandle(psConnection->psHandleBase,
+						PVRSRVLookupHandleUnlocked(psConnection->psHandleBase,
 											(void **) &psPMRInt,
-											psDevmemIntMapPagesIN->hPMR,
-											PVRSRV_HANDLE_TYPE_PHYSMEM_PMR);
+											hPMR,
+											PVRSRV_HANDLE_TYPE_PHYSMEM_PMR,
+											IMG_TRUE);
 					if(psDevmemIntMapPagesOUT->eError != PVRSRV_OK)
 					{
-						PMRUnlock();
+						UnlockHandle();
 						goto DevmemIntMapPages_exit;
 					}
 				}
-
+	/* Release now we have looked up handles. */
+	UnlockHandle();
 
 	psDevmemIntMapPagesOUT->eError =
 		DevmemIntMapPages(
@@ -1628,22 +2594,58 @@
 					psDevmemIntMapPagesIN->ui32PhysicalPgOffset,
 					psDevmemIntMapPagesIN->uiFlags,
 					psDevmemIntMapPagesIN->sDevVAddr);
-	PMRUnlock();
 
 
 
 
 DevmemIntMapPages_exit:
 
+	/* Lock over handle lookup cleanup. */
+	LockHandle();
+
+
+
+
+
+
+				{
+					/* Unreference the previously looked up handle */
+						if(psReservationInt)
+						{
+							PVRSRVReleaseHandleUnlocked(psConnection->psHandleBase,
+											hReservation,
+											PVRSRV_HANDLE_TYPE_DEVMEMINT_RESERVATION);
+						}
+				}
+
+
+
+
+
+				{
+					/* Unreference the previously looked up handle */
+						if(psPMRInt)
+						{
+							PVRSRVReleaseHandleUnlocked(psConnection->psHandleBase,
+											hPMR,
+											PVRSRV_HANDLE_TYPE_PHYSMEM_PMR);
+						}
+				}
+	/* Release now we have cleaned up look up handles. */
+	UnlockHandle();
+
+
 	return 0;
 }
 
+
 static IMG_INT
 PVRSRVBridgeDevmemIntUnmapPages(IMG_UINT32 ui32DispatchTableEntry,
 					  PVRSRV_BRIDGE_IN_DEVMEMINTUNMAPPAGES *psDevmemIntUnmapPagesIN,
 					  PVRSRV_BRIDGE_OUT_DEVMEMINTUNMAPPAGES *psDevmemIntUnmapPagesOUT,
 					 CONNECTION_DATA *psConnection)
 {
+	IMG_HANDLE hReservation = psDevmemIntUnmapPagesIN->hReservation;
 	DEVMEMINT_RESERVATION * psReservationInt = NULL;
 
 
@@ -1652,19 +2654,29 @@
 
 
 
+	/* Lock over handle lookup. */
+	LockHandle();
+
+
+
+
+
 				{
 					/* Look up the address from the handle */
 					psDevmemIntUnmapPagesOUT->eError =
-						PVRSRVLookupHandle(psConnection->psHandleBase,
+						PVRSRVLookupHandleUnlocked(psConnection->psHandleBase,
 											(void **) &psReservationInt,
-											psDevmemIntUnmapPagesIN->hReservation,
-											PVRSRV_HANDLE_TYPE_DEVMEMINT_RESERVATION);
+											hReservation,
+											PVRSRV_HANDLE_TYPE_DEVMEMINT_RESERVATION,
+											IMG_TRUE);
 					if(psDevmemIntUnmapPagesOUT->eError != PVRSRV_OK)
 					{
+						UnlockHandle();
 						goto DevmemIntUnmapPages_exit;
 					}
 				}
-
+	/* Release now we have looked up handles. */
+	UnlockHandle();
 
 	psDevmemIntUnmapPagesOUT->eError =
 		DevmemIntUnmapPages(
@@ -1677,18 +2689,8 @@
 
 DevmemIntUnmapPages_exit:
 
-	return 0;
-}
-
-static IMG_INT
-PVRSRVBridgeDevmemSLCFlushInvalRequest(IMG_UINT32 ui32DispatchTableEntry,
-					  PVRSRV_BRIDGE_IN_DEVMEMSLCFLUSHINVALREQUEST *psDevmemSLCFlushInvalRequestIN,
-					  PVRSRV_BRIDGE_OUT_DEVMEMSLCFLUSHINVALREQUEST *psDevmemSLCFlushInvalRequestOUT,
-					 CONNECTION_DATA *psConnection)
-{
-	IMG_HANDLE hDeviceNodeInt = NULL;
-	PMR * psPmrInt = NULL;
-
+	/* Lock over handle lookup cleanup. */
+	LockHandle();
 
 
 
@@ -1696,52 +2698,29 @@
 
 
 				{
-					/* Look up the address from the handle */
-					psDevmemSLCFlushInvalRequestOUT->eError =
-						PVRSRVLookupHandle(psConnection->psHandleBase,
-											(void **) &hDeviceNodeInt,
-											psDevmemSLCFlushInvalRequestIN->hDeviceNode,
-											PVRSRV_HANDLE_TYPE_DEV_NODE);
-					if(psDevmemSLCFlushInvalRequestOUT->eError != PVRSRV_OK)
-					{
-						goto DevmemSLCFlushInvalRequest_exit;
-					}
+					/* Unreference the previously looked up handle */
+						if(psReservationInt)
+						{
+							PVRSRVReleaseHandleUnlocked(psConnection->psHandleBase,
+											hReservation,
+											PVRSRV_HANDLE_TYPE_DEVMEMINT_RESERVATION);
+						}
 				}
+	/* Release now we have cleaned up look up handles. */
+	UnlockHandle();
 
 
-				{
-					/* Look up the address from the handle */
-					psDevmemSLCFlushInvalRequestOUT->eError =
-						PVRSRVLookupHandle(psConnection->psHandleBase,
-											(void **) &psPmrInt,
-											psDevmemSLCFlushInvalRequestIN->hPmr,
-											PVRSRV_HANDLE_TYPE_PHYSMEM_PMR);
-					if(psDevmemSLCFlushInvalRequestOUT->eError != PVRSRV_OK)
-					{
-						goto DevmemSLCFlushInvalRequest_exit;
-					}
-				}
-
-
-	psDevmemSLCFlushInvalRequestOUT->eError =
-		DevmemSLCFlushInvalRequest(
-					hDeviceNodeInt,
-					psPmrInt);
-
-
-
-
-DevmemSLCFlushInvalRequest_exit:
-
 	return 0;
 }
 
+
 static IMG_INT
 PVRSRVBridgeDevmemIsVDevAddrValid(IMG_UINT32 ui32DispatchTableEntry,
 					  PVRSRV_BRIDGE_IN_DEVMEMISVDEVADDRVALID *psDevmemIsVDevAddrValidIN,
 					  PVRSRV_BRIDGE_OUT_DEVMEMISVDEVADDRVALID *psDevmemIsVDevAddrValidOUT,
 					 CONNECTION_DATA *psConnection)
 {
+	IMG_HANDLE hDevmemCtx = psDevmemIsVDevAddrValidIN->hDevmemCtx;
 	DEVMEMINT_CTX * psDevmemCtxInt = NULL;
 
 
@@ -1750,22 +2729,32 @@
 
 
 
+	/* Lock over handle lookup. */
+	LockHandle();
+
+
+
+
+
 				{
 					/* Look up the address from the handle */
 					psDevmemIsVDevAddrValidOUT->eError =
-						PVRSRVLookupHandle(psConnection->psHandleBase,
+						PVRSRVLookupHandleUnlocked(psConnection->psHandleBase,
 											(void **) &psDevmemCtxInt,
-											psDevmemIsVDevAddrValidIN->hDevmemCtx,
-											PVRSRV_HANDLE_TYPE_DEVMEMINT_CTX);
+											hDevmemCtx,
+											PVRSRV_HANDLE_TYPE_DEVMEMINT_CTX,
+											IMG_TRUE);
 					if(psDevmemIsVDevAddrValidOUT->eError != PVRSRV_OK)
 					{
+						UnlockHandle();
 						goto DevmemIsVDevAddrValid_exit;
 					}
 				}
-
+	/* Release now we have looked up handles. */
+	UnlockHandle();
 
 	psDevmemIsVDevAddrValidOUT->eError =
-		DevmemIntIsVDevAddrValid(
+		DevmemIntIsVDevAddrValid(psConnection, OSGetDevData(psConnection),
 					psDevmemCtxInt,
 					psDevmemIsVDevAddrValidIN->sAddress);
 
@@ -1774,9 +2763,31 @@
 
 DevmemIsVDevAddrValid_exit:
 
+	/* Lock over handle lookup cleanup. */
+	LockHandle();
+
+
+
+
+
+
+				{
+					/* Unreference the previously looked up handle */
+						if(psDevmemCtxInt)
+						{
+							PVRSRVReleaseHandleUnlocked(psConnection->psHandleBase,
+											hDevmemCtx,
+											PVRSRV_HANDLE_TYPE_DEVMEMINT_CTX);
+						}
+				}
+	/* Release now we have cleaned up look up handles. */
+	UnlockHandle();
+
+
 	return 0;
 }
 
+
 static IMG_INT
 PVRSRVBridgeHeapCfgHeapConfigCount(IMG_UINT32 ui32DispatchTableEntry,
 					  PVRSRV_BRIDGE_IN_HEAPCFGHEAPCONFIGCOUNT *psHeapCfgHeapConfigCountIN,
@@ -1784,9 +2795,10 @@
 					 CONNECTION_DATA *psConnection)
 {
 
-	PVR_UNREFERENCED_PARAMETER(psHeapCfgHeapConfigCountIN);
 
 
+	PVR_UNREFERENCED_PARAMETER(psHeapCfgHeapConfigCountIN);
+
 
 
 
@@ -1799,9 +2811,13 @@
 
 
 
+
+
+
 	return 0;
 }
 
+
 static IMG_INT
 PVRSRVBridgeHeapCfgHeapCount(IMG_UINT32 ui32DispatchTableEntry,
 					  PVRSRV_BRIDGE_IN_HEAPCFGHEAPCOUNT *psHeapCfgHeapCountIN,
@@ -1815,6 +2831,7 @@
 
 
 
+
 	psHeapCfgHeapCountOUT->eError =
 		HeapCfgHeapCount(psConnection, OSGetDevData(psConnection),
 					psHeapCfgHeapCountIN->ui32HeapConfigIndex,
@@ -1824,9 +2841,13 @@
 
 
 
+
+
+
 	return 0;
 }
 
+
 static IMG_INT
 PVRSRVBridgeHeapCfgHeapConfigName(IMG_UINT32 ui32DispatchTableEntry,
 					  PVRSRV_BRIDGE_IN_HEAPCFGHEAPCONFIGNAME *psHeapCfgHeapConfigNameIN,
@@ -1835,21 +2856,53 @@
 {
 	IMG_CHAR *puiHeapConfigNameInt = NULL;
 
+	IMG_UINT32 ui32NextOffset = 0;
+	IMG_BYTE   *pArrayArgsBuffer = NULL;
+#if !defined(INTEGRITY_OS)
+	IMG_BOOL bHaveEnoughSpace = IMG_FALSE;
+#endif
+
+	IMG_UINT32 ui32BufferSize = 
+			(psHeapCfgHeapConfigNameIN->ui32HeapConfigNameBufSz * sizeof(IMG_CHAR)) +
+			0;
+
+
 
 	psHeapCfgHeapConfigNameOUT->puiHeapConfigName = psHeapCfgHeapConfigNameIN->puiHeapConfigName;
 
 
-	if (psHeapCfgHeapConfigNameIN->ui32HeapConfigNameBufSz != 0)
+	if (ui32BufferSize != 0)
 	{
-		puiHeapConfigNameInt = OSAllocMemNoStats(psHeapCfgHeapConfigNameIN->ui32HeapConfigNameBufSz * sizeof(IMG_CHAR));
-		if (!puiHeapConfigNameInt)
+#if !defined(INTEGRITY_OS)
+		/* Try to use remainder of input buffer for copies if possible, word-aligned for safety. */
+		IMG_UINT32 ui32InBufferOffset = PVR_ALIGN(sizeof(*psHeapCfgHeapConfigNameIN), sizeof(unsigned long));
+		IMG_UINT32 ui32InBufferExcessSize = ui32InBufferOffset >= PVRSRV_MAX_BRIDGE_IN_SIZE ? 0 :
+			PVRSRV_MAX_BRIDGE_IN_SIZE - ui32InBufferOffset;
+
+		bHaveEnoughSpace = ui32BufferSize <= ui32InBufferExcessSize;
+		if (bHaveEnoughSpace)
 		{
-			psHeapCfgHeapConfigNameOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
-	
-			goto HeapCfgHeapConfigName_exit;
+			IMG_BYTE *pInputBuffer = (IMG_BYTE *)psHeapCfgHeapConfigNameIN;
+
+			pArrayArgsBuffer = &pInputBuffer[ui32InBufferOffset];		}
+		else
+#endif
+		{
+			pArrayArgsBuffer = OSAllocMemNoStats(ui32BufferSize);
+
+			if(!pArrayArgsBuffer)
+			{
+				psHeapCfgHeapConfigNameOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
+				goto HeapCfgHeapConfigName_exit;
+			}
 		}
 	}
 
+	if (psHeapCfgHeapConfigNameIN->ui32HeapConfigNameBufSz != 0)
+	{
+		puiHeapConfigNameInt = (IMG_CHAR*)(((IMG_UINT8 *)pArrayArgsBuffer) + ui32NextOffset);
+		ui32NextOffset += psHeapCfgHeapConfigNameIN->ui32HeapConfigNameBufSz * sizeof(IMG_CHAR);
+	}
 
 
 
@@ -1861,23 +2914,37 @@
 
 
 
-	if ( !OSAccessOK(PVR_VERIFY_WRITE, (void*) psHeapCfgHeapConfigNameOUT->puiHeapConfigName, (psHeapCfgHeapConfigNameIN->ui32HeapConfigNameBufSz * sizeof(IMG_CHAR)))
-		|| (OSCopyToUser(NULL, psHeapCfgHeapConfigNameOUT->puiHeapConfigName, puiHeapConfigNameInt,
-		(psHeapCfgHeapConfigNameIN->ui32HeapConfigNameBufSz * sizeof(IMG_CHAR))) != PVRSRV_OK) )
+	if ((psHeapCfgHeapConfigNameIN->ui32HeapConfigNameBufSz * sizeof(IMG_CHAR)) > 0)
 	{
-		psHeapCfgHeapConfigNameOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
+		if ( OSCopyToUser(NULL, psHeapCfgHeapConfigNameOUT->puiHeapConfigName, puiHeapConfigNameInt,
+			(psHeapCfgHeapConfigNameIN->ui32HeapConfigNameBufSz * sizeof(IMG_CHAR))) != PVRSRV_OK )
+		{
+			psHeapCfgHeapConfigNameOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
 
-		goto HeapCfgHeapConfigName_exit;
+			goto HeapCfgHeapConfigName_exit;
+		}
 	}
 
 
 HeapCfgHeapConfigName_exit:
-	if (puiHeapConfigNameInt)
-		OSFreeMemNoStats(puiHeapConfigNameInt);
+
+
+
+	/* Allocated space should be equal to the last updated offset */
+	PVR_ASSERT(ui32BufferSize == ui32NextOffset);
+
+#if defined(INTEGRITY_OS)
+	if(pArrayArgsBuffer)
+#else
+	if(!bHaveEnoughSpace && pArrayArgsBuffer)
+#endif
+		OSFreeMemNoStats(pArrayArgsBuffer);
+
 
 	return 0;
 }
 
+
 static IMG_INT
 PVRSRVBridgeHeapCfgHeapDetails(IMG_UINT32 ui32DispatchTableEntry,
 					  PVRSRV_BRIDGE_IN_HEAPCFGHEAPDETAILS *psHeapCfgHeapDetailsIN,
@@ -1886,21 +2953,53 @@
 {
 	IMG_CHAR *puiHeapNameOutInt = NULL;
 
+	IMG_UINT32 ui32NextOffset = 0;
+	IMG_BYTE   *pArrayArgsBuffer = NULL;
+#if !defined(INTEGRITY_OS)
+	IMG_BOOL bHaveEnoughSpace = IMG_FALSE;
+#endif
+
+	IMG_UINT32 ui32BufferSize = 
+			(psHeapCfgHeapDetailsIN->ui32HeapNameBufSz * sizeof(IMG_CHAR)) +
+			0;
+
+
 
 	psHeapCfgHeapDetailsOUT->puiHeapNameOut = psHeapCfgHeapDetailsIN->puiHeapNameOut;
 
 
-	if (psHeapCfgHeapDetailsIN->ui32HeapNameBufSz != 0)
+	if (ui32BufferSize != 0)
 	{
-		puiHeapNameOutInt = OSAllocMemNoStats(psHeapCfgHeapDetailsIN->ui32HeapNameBufSz * sizeof(IMG_CHAR));
-		if (!puiHeapNameOutInt)
+#if !defined(INTEGRITY_OS)
+		/* Try to use remainder of input buffer for copies if possible, word-aligned for safety. */
+		IMG_UINT32 ui32InBufferOffset = PVR_ALIGN(sizeof(*psHeapCfgHeapDetailsIN), sizeof(unsigned long));
+		IMG_UINT32 ui32InBufferExcessSize = ui32InBufferOffset >= PVRSRV_MAX_BRIDGE_IN_SIZE ? 0 :
+			PVRSRV_MAX_BRIDGE_IN_SIZE - ui32InBufferOffset;
+
+		bHaveEnoughSpace = ui32BufferSize <= ui32InBufferExcessSize;
+		if (bHaveEnoughSpace)
 		{
-			psHeapCfgHeapDetailsOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
-	
-			goto HeapCfgHeapDetails_exit;
+			IMG_BYTE *pInputBuffer = (IMG_BYTE *)psHeapCfgHeapDetailsIN;
+
+			pArrayArgsBuffer = &pInputBuffer[ui32InBufferOffset];		}
+		else
+#endif
+		{
+			pArrayArgsBuffer = OSAllocMemNoStats(ui32BufferSize);
+
+			if(!pArrayArgsBuffer)
+			{
+				psHeapCfgHeapDetailsOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
+				goto HeapCfgHeapDetails_exit;
+			}
 		}
 	}
 
+	if (psHeapCfgHeapDetailsIN->ui32HeapNameBufSz != 0)
+	{
+		puiHeapNameOutInt = (IMG_CHAR*)(((IMG_UINT8 *)pArrayArgsBuffer) + ui32NextOffset);
+		ui32NextOffset += psHeapCfgHeapDetailsIN->ui32HeapNameBufSz * sizeof(IMG_CHAR);
+	}
 
 
 
@@ -1917,103 +3016,106 @@
 
 
 
-	if ( !OSAccessOK(PVR_VERIFY_WRITE, (void*) psHeapCfgHeapDetailsOUT->puiHeapNameOut, (psHeapCfgHeapDetailsIN->ui32HeapNameBufSz * sizeof(IMG_CHAR)))
-		|| (OSCopyToUser(NULL, psHeapCfgHeapDetailsOUT->puiHeapNameOut, puiHeapNameOutInt,
-		(psHeapCfgHeapDetailsIN->ui32HeapNameBufSz * sizeof(IMG_CHAR))) != PVRSRV_OK) )
+	if ((psHeapCfgHeapDetailsIN->ui32HeapNameBufSz * sizeof(IMG_CHAR)) > 0)
 	{
-		psHeapCfgHeapDetailsOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
+		if ( OSCopyToUser(NULL, psHeapCfgHeapDetailsOUT->puiHeapNameOut, puiHeapNameOutInt,
+			(psHeapCfgHeapDetailsIN->ui32HeapNameBufSz * sizeof(IMG_CHAR))) != PVRSRV_OK )
+		{
+			psHeapCfgHeapDetailsOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
 
-		goto HeapCfgHeapDetails_exit;
+			goto HeapCfgHeapDetails_exit;
+		}
 	}
 
 
 HeapCfgHeapDetails_exit:
-	if (puiHeapNameOutInt)
-		OSFreeMemNoStats(puiHeapNameOutInt);
+
+
+
+	/* Allocated space should be equal to the last updated offset */
+	PVR_ASSERT(ui32BufferSize == ui32NextOffset);
+
+#if defined(INTEGRITY_OS)
+	if(pArrayArgsBuffer)
+#else
+	if(!bHaveEnoughSpace && pArrayArgsBuffer)
+#endif
+		OSFreeMemNoStats(pArrayArgsBuffer);
+
 
 	return 0;
 }
 
+
 static IMG_INT
-PVRSRVBridgeDevmemIntCtxCreateCLS(IMG_UINT32 ui32DispatchTableEntry,
-					  PVRSRV_BRIDGE_IN_DEVMEMINTCTXCREATECLS *psDevmemIntCtxCreateCLSIN,
-					  PVRSRV_BRIDGE_OUT_DEVMEMINTCTXCREATECLS *psDevmemIntCtxCreateCLSOUT,
+PVRSRVBridgeDevmemIntRegisterPFNotifyKM(IMG_UINT32 ui32DispatchTableEntry,
+					  PVRSRV_BRIDGE_IN_DEVMEMINTREGISTERPFNOTIFYKM *psDevmemIntRegisterPFNotifyKMIN,
+					  PVRSRV_BRIDGE_OUT_DEVMEMINTREGISTERPFNOTIFYKM *psDevmemIntRegisterPFNotifyKMOUT,
 					 CONNECTION_DATA *psConnection)
 {
-	DEVMEMINT_CTX * psDevMemServerContextInt = NULL;
-	IMG_HANDLE hPrivDataInt = NULL;
-
-
-
-	psDevmemIntCtxCreateCLSOUT->hDevMemServerContext = NULL;
-
-
-	PMRLock();
-
-
-	psDevmemIntCtxCreateCLSOUT->eError =
-		DevmemIntCtxCreateCLS(psConnection, OSGetDevData(psConnection),
-					psDevmemIntCtxCreateCLSIN->bbKernelMemoryCtx,
-					&psDevMemServerContextInt,
-					&hPrivDataInt,
-					&psDevmemIntCtxCreateCLSOUT->ui32CPUCacheLineSize);
-	/* Exit early if bridged call fails */
-	if(psDevmemIntCtxCreateCLSOUT->eError != PVRSRV_OK)
-	{
-		PMRUnlock();
-		goto DevmemIntCtxCreateCLS_exit;
-	}
-	PMRUnlock();
-
-
-	psDevmemIntCtxCreateCLSOUT->eError = PVRSRVAllocHandle(psConnection->psHandleBase,
-							&psDevmemIntCtxCreateCLSOUT->hDevMemServerContext,
-							(void *) psDevMemServerContextInt,
-							PVRSRV_HANDLE_TYPE_DEVMEMINT_CTX,
-							PVRSRV_HANDLE_ALLOC_FLAG_MULTI
-							,(PFN_HANDLE_RELEASE)&DevmemIntCtxDestroy);
-	if (psDevmemIntCtxCreateCLSOUT->eError != PVRSRV_OK)
-	{
-		goto DevmemIntCtxCreateCLS_exit;
-	}
-
-
-	psDevmemIntCtxCreateCLSOUT->eError = PVRSRVAllocSubHandle(psConnection->psHandleBase,
-							&psDevmemIntCtxCreateCLSOUT->hPrivData,
-							(void *) hPrivDataInt,
-							PVRSRV_HANDLE_TYPE_DEV_PRIV_DATA,
-							PVRSRV_HANDLE_ALLOC_FLAG_MULTI
-							,psDevmemIntCtxCreateCLSOUT->hDevMemServerContext);
-	if (psDevmemIntCtxCreateCLSOUT->eError != PVRSRV_OK)
-	{
-		goto DevmemIntCtxCreateCLS_exit;
-	}
+	IMG_HANDLE hDevmemCtx = psDevmemIntRegisterPFNotifyKMIN->hDevmemCtx;
+	DEVMEMINT_CTX * psDevmemCtxInt = NULL;
 
 
 
 
-DevmemIntCtxCreateCLS_exit:
-	if (psDevmemIntCtxCreateCLSOUT->eError != PVRSRV_OK)
-	{
-		if (psDevmemIntCtxCreateCLSOUT->hDevMemServerContext)
-		{
-			PVRSRV_ERROR eError = PVRSRVReleaseHandle(psConnection->psHandleBase,
-						(IMG_HANDLE) psDevmemIntCtxCreateCLSOUT->hDevMemServerContext,
-						PVRSRV_HANDLE_TYPE_DEVMEMINT_CTX);
-
-			/* Releasing the handle should free/destroy/release the resource. This should never fail... */
-			PVR_ASSERT((eError == PVRSRV_OK) || (eError == PVRSRV_ERROR_RETRY));
-
-			/* Avoid freeing/destroying/releasing the resource a second time below */
-			psDevMemServerContextInt = NULL;
-		}
 
 
-		if (psDevMemServerContextInt)
-		{
-			DevmemIntCtxDestroy(psDevMemServerContextInt);
-		}
-	}
+
+	/* Lock over handle lookup. */
+	LockHandle();
+
+
+
+
+
+				{
+					/* Look up the address from the handle */
+					psDevmemIntRegisterPFNotifyKMOUT->eError =
+						PVRSRVLookupHandleUnlocked(psConnection->psHandleBase,
+											(void **) &psDevmemCtxInt,
+											hDevmemCtx,
+											PVRSRV_HANDLE_TYPE_DEVMEMINT_CTX,
+											IMG_TRUE);
+					if(psDevmemIntRegisterPFNotifyKMOUT->eError != PVRSRV_OK)
+					{
+						UnlockHandle();
+						goto DevmemIntRegisterPFNotifyKM_exit;
+					}
+				}
+	/* Release now we have looked up handles. */
+	UnlockHandle();
+
+	psDevmemIntRegisterPFNotifyKMOUT->eError =
+		DevmemIntRegisterPFNotifyKM(
+					psDevmemCtxInt,
+					psDevmemIntRegisterPFNotifyKMIN->ui32PID,
+					psDevmemIntRegisterPFNotifyKMIN->bRegister);
+
+
+
+
+DevmemIntRegisterPFNotifyKM_exit:
+
+	/* Lock over handle lookup cleanup. */
+	LockHandle();
+
+
+
+
+
+
+				{
+					/* Unreference the previously looked up handle */
+						if(psDevmemCtxInt)
+						{
+							PVRSRVReleaseHandleUnlocked(psConnection->psHandleBase,
+											hDevmemCtx,
+											PVRSRV_HANDLE_TYPE_DEVMEMINT_CTX);
+						}
+				}
+	/* Release now we have cleaned up look up handles. */
+	UnlockHandle();
 
 
 	return 0;
@@ -2021,6 +3123,7 @@
 
 
 
+
 /* *************************************************************************** 
  * Server bridge dispatch related glue 
  */
@@ -2114,9 +3217,6 @@
 	SetDispatchTableEntry(PVRSRV_BRIDGE_MM, PVRSRV_BRIDGE_MM_DEVMEMINTUNMAPPAGES, PVRSRVBridgeDevmemIntUnmapPages,
 					NULL, bUseLock);
 
-	SetDispatchTableEntry(PVRSRV_BRIDGE_MM, PVRSRV_BRIDGE_MM_DEVMEMSLCFLUSHINVALREQUEST, PVRSRVBridgeDevmemSLCFlushInvalRequest,
-					NULL, bUseLock);
-
 	SetDispatchTableEntry(PVRSRV_BRIDGE_MM, PVRSRV_BRIDGE_MM_DEVMEMISVDEVADDRVALID, PVRSRVBridgeDevmemIsVDevAddrValid,
 					NULL, bUseLock);
 
@@ -2132,7 +3232,7 @@
 	SetDispatchTableEntry(PVRSRV_BRIDGE_MM, PVRSRV_BRIDGE_MM_HEAPCFGHEAPDETAILS, PVRSRVBridgeHeapCfgHeapDetails,
 					NULL, bUseLock);
 
-	SetDispatchTableEntry(PVRSRV_BRIDGE_MM, PVRSRV_BRIDGE_MM_DEVMEMINTCTXCREATECLS, PVRSRVBridgeDevmemIntCtxCreateCLS,
+	SetDispatchTableEntry(PVRSRV_BRIDGE_MM, PVRSRV_BRIDGE_MM_DEVMEMINTREGISTERPFNOTIFYKM, PVRSRVBridgeDevmemIntRegisterPFNotifyKM,
 					NULL, bUseLock);
 
 
@@ -2146,4 +3246,3 @@
 {
 	return PVRSRV_OK;
 }
-
diff --git a/drivers/staging/imgtec/rogue/generated/cachegeneric_bridge/client_cachegeneric_bridge.h b/drivers/staging/imgtec/rogue/generated/pdump_bridge/client_pdump_bridge.h
similarity index 69%
copy from drivers/staging/imgtec/rogue/generated/cachegeneric_bridge/client_cachegeneric_bridge.h
copy to drivers/staging/imgtec/rogue/generated/pdump_bridge/client_pdump_bridge.h
index 839a17a..b628b08 100644
--- a/drivers/staging/imgtec/rogue/generated/cachegeneric_bridge/client_cachegeneric_bridge.h
+++ b/drivers/staging/imgtec/rogue/generated/pdump_bridge/client_pdump_bridge.h
@@ -1,8 +1,8 @@
 /*************************************************************************/ /*!
 @File
-@Title          Client bridge header for cachegeneric
+@Title          Client bridge header for pdump
 @Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
-@Description    Exports the client bridge functions for cachegeneric
+@Description    Exports the client bridge functions for pdump
 @License        Dual MIT/GPLv2
 
 The contents of this file are subject to the MIT license as set out below.
@@ -41,8 +41,8 @@
 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */ /**************************************************************************/
 
-#ifndef CLIENT_CACHEGENERIC_BRIDGE_H
-#define CLIENT_CACHEGENERIC_BRIDGE_H
+#ifndef CLIENT_PDUMP_BRIDGE_H
+#define CLIENT_PDUMP_BRIDGE_H
 
 #include "img_defs.h"
 #include "pvrsrv_error.h"
@@ -52,13 +52,27 @@
 #include "pvr_bridge.h"
 #endif
 
-#include "common_cachegeneric_bridge.h"
+#include "common_pdump_bridge.h"
 
-IMG_INTERNAL PVRSRV_ERROR IMG_CALLCONV BridgeCacheOpQueue(IMG_HANDLE hBridge,
-							  IMG_HANDLE hPMR,
-							  IMG_DEVMEM_OFFSET_T uiOffset,
-							  IMG_DEVMEM_SIZE_T uiSize,
-							  PVRSRV_CACHE_OP iuCacheOp);
+IMG_INTERNAL PVRSRV_ERROR IMG_CALLCONV BridgeDevmemPDumpBitmap(IMG_HANDLE hBridge,
+							       IMG_CHAR *puiFileName,
+							       IMG_UINT32 ui32FileOffset,
+							       IMG_UINT32 ui32Width,
+							       IMG_UINT32 ui32Height,
+							       IMG_UINT32 ui32StrideInBytes,
+							       IMG_DEV_VIRTADDR sDevBaseAddr,
+							       IMG_HANDLE hDevmemCtx,
+							       IMG_UINT32 ui32Size,
+							       PDUMP_PIXEL_FORMAT ePixelFormat,
+							       IMG_UINT32 ui32AddrMode,
+							       IMG_UINT32 ui32PDumpFlags);
+
+IMG_INTERNAL PVRSRV_ERROR IMG_CALLCONV BridgePVRSRVPDumpComment(IMG_HANDLE hBridge,
+								IMG_CHAR *puiComment,
+								IMG_UINT32 ui32Flags);
+
+IMG_INTERNAL PVRSRV_ERROR IMG_CALLCONV BridgePVRSRVPDumpSetFrame(IMG_HANDLE hBridge,
+								 IMG_UINT32 ui32Frame);
 
 
-#endif /* CLIENT_CACHEGENERIC_BRIDGE_H */
+#endif /* CLIENT_PDUMP_BRIDGE_H */
diff --git a/drivers/staging/imgtec/rogue/generated/cachegeneric_bridge/client_cachegeneric_direct_bridge.c b/drivers/staging/imgtec/rogue/generated/pdump_bridge/client_pdump_direct_bridge.c
similarity index 60%
copy from drivers/staging/imgtec/rogue/generated/cachegeneric_bridge/client_cachegeneric_direct_bridge.c
copy to drivers/staging/imgtec/rogue/generated/pdump_bridge/client_pdump_direct_bridge.c
index d0cdf5a..b4977ef 100644
--- a/drivers/staging/imgtec/rogue/generated/cachegeneric_bridge/client_cachegeneric_direct_bridge.c
+++ b/drivers/staging/imgtec/rogue/generated/pdump_bridge/client_pdump_direct_bridge.c
@@ -1,5 +1,5 @@
 /*************************************************************************/ /*!
-@Title          Direct client bridge for cachegeneric
+@Title          Direct client bridge for pdump
 @Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
 @License        Dual MIT/GPLv2
 
@@ -39,34 +39,80 @@
 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */ /**************************************************************************/
 
-#include "client_cachegeneric_bridge.h"
+#include "client_pdump_bridge.h"
 #include "img_defs.h"
 #include "pvr_debug.h"
 
 /* Module specific includes */
-#include "cache_external.h"
+#include "devicemem_typedefs.h"
+#include "pdumpdefs.h"
 
-#include "cache_generic.h"
+#include "devicemem_server.h"
+#include "pdump_km.h"
 
 
-IMG_INTERNAL PVRSRV_ERROR IMG_CALLCONV BridgeCacheOpQueue(IMG_HANDLE hBridge,
-							  IMG_HANDLE hPMR,
-							  IMG_DEVMEM_OFFSET_T uiOffset,
-							  IMG_DEVMEM_SIZE_T uiSize,
-							  PVRSRV_CACHE_OP iuCacheOp)
+IMG_INTERNAL PVRSRV_ERROR IMG_CALLCONV BridgeDevmemPDumpBitmap(IMG_HANDLE hBridge,
+							       IMG_CHAR *puiFileName,
+							       IMG_UINT32 ui32FileOffset,
+							       IMG_UINT32 ui32Width,
+							       IMG_UINT32 ui32Height,
+							       IMG_UINT32 ui32StrideInBytes,
+							       IMG_DEV_VIRTADDR sDevBaseAddr,
+							       IMG_HANDLE hDevmemCtx,
+							       IMG_UINT32 ui32Size,
+							       PDUMP_PIXEL_FORMAT ePixelFormat,
+							       IMG_UINT32 ui32AddrMode,
+							       IMG_UINT32 ui32PDumpFlags)
 {
 	PVRSRV_ERROR eError;
-	PMR * psPMRInt;
-	PVR_UNREFERENCED_PARAMETER(hBridge);
+	DEVMEMINT_CTX * psDevmemCtxInt;
 
-	psPMRInt = (PMR *) hPMR;
+	psDevmemCtxInt = (DEVMEMINT_CTX *) hDevmemCtx;
 
 	eError =
-		CacheOpQueue(
-					psPMRInt,
-					uiOffset,
-					uiSize,
-					iuCacheOp);
+		DevmemIntPDumpBitmap(NULL, (PVRSRV_DEVICE_NODE *)((void*) hBridge)
+		,
+					puiFileName,
+					ui32FileOffset,
+					ui32Width,
+					ui32Height,
+					ui32StrideInBytes,
+					sDevBaseAddr,
+					psDevmemCtxInt,
+					ui32Size,
+					ePixelFormat,
+					ui32AddrMode,
+					ui32PDumpFlags);
+
+	return eError;
+}
+
+IMG_INTERNAL PVRSRV_ERROR IMG_CALLCONV BridgePVRSRVPDumpComment(IMG_HANDLE hBridge,
+								IMG_CHAR *puiComment,
+								IMG_UINT32 ui32Flags)
+{
+	PVRSRV_ERROR eError;
+	PVR_UNREFERENCED_PARAMETER(hBridge);
+
+
+	eError =
+		PDumpCommentKM(
+					puiComment,
+					ui32Flags);
+
+	return eError;
+}
+
+IMG_INTERNAL PVRSRV_ERROR IMG_CALLCONV BridgePVRSRVPDumpSetFrame(IMG_HANDLE hBridge,
+								 IMG_UINT32 ui32Frame)
+{
+	PVRSRV_ERROR eError;
+
+
+	eError =
+		PDumpSetFrameKM(NULL, (PVRSRV_DEVICE_NODE *)((void*) hBridge)
+		,
+					ui32Frame);
 
 	return eError;
 }
diff --git a/drivers/staging/imgtec/rogue/generated/pdump_bridge/common_pdump_bridge.h b/drivers/staging/imgtec/rogue/generated/pdump_bridge/common_pdump_bridge.h
index e11e056..0159b82 100644
--- a/drivers/staging/imgtec/rogue/generated/pdump_bridge/common_pdump_bridge.h
+++ b/drivers/staging/imgtec/rogue/generated/pdump_bridge/common_pdump_bridge.h
@@ -2,8 +2,8 @@
 @File
 @Title          Common bridge header for pdump
 @Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
-@Description    Declares common defines and structures that are used by both
-                the client and sever side of the bridge for pdump
+@Description    Declares common defines and structures used by both the client
+                and server side of the bridge for pdump
 @License        Dual MIT/GPLv2
 
 The contents of this file are subject to the MIT license as set out below.
@@ -45,6 +45,8 @@
 #ifndef COMMON_PDUMP_BRIDGE_H
 #define COMMON_PDUMP_BRIDGE_H
 
+#include <powervr/mem_types.h>
+
 #include "img_types.h"
 #include "pvrsrv_error.h"
 
diff --git a/drivers/staging/imgtec/rogue/generated/pdump_bridge/server_pdump_bridge.c b/drivers/staging/imgtec/rogue/generated/pdump_bridge/server_pdump_bridge.c
index f89a8a2..0b38a25 100644
--- a/drivers/staging/imgtec/rogue/generated/pdump_bridge/server_pdump_bridge.c
+++ b/drivers/staging/imgtec/rogue/generated/pdump_bridge/server_pdump_bridge.c
@@ -65,6 +65,8 @@
 
 
 
+
+
 /* ***************************************************************************
  * Server-side bridge entry points
  */
@@ -76,47 +78,90 @@
 					 CONNECTION_DATA *psConnection)
 {
 	IMG_CHAR *uiFileNameInt = NULL;
+	IMG_HANDLE hDevmemCtx = psDevmemPDumpBitmapIN->hDevmemCtx;
 	DEVMEMINT_CTX * psDevmemCtxInt = NULL;
 
+	IMG_UINT32 ui32NextOffset = 0;
+	IMG_BYTE   *pArrayArgsBuffer = NULL;
+#if !defined(INTEGRITY_OS)
+	IMG_BOOL bHaveEnoughSpace = IMG_FALSE;
+#endif
+
+	IMG_UINT32 ui32BufferSize = 
+			(PVRSRV_PDUMP_MAX_FILENAME_SIZE * sizeof(IMG_CHAR)) +
+			0;
 
 
 
-	
+
+
+	if (ui32BufferSize != 0)
 	{
-		uiFileNameInt = OSAllocMemNoStats(PVRSRV_PDUMP_MAX_FILENAME_SIZE * sizeof(IMG_CHAR));
-		if (!uiFileNameInt)
+#if !defined(INTEGRITY_OS)
+		/* Try to use remainder of input buffer for copies if possible, word-aligned for safety. */
+		IMG_UINT32 ui32InBufferOffset = PVR_ALIGN(sizeof(*psDevmemPDumpBitmapIN), sizeof(unsigned long));
+		IMG_UINT32 ui32InBufferExcessSize = ui32InBufferOffset >= PVRSRV_MAX_BRIDGE_IN_SIZE ? 0 :
+			PVRSRV_MAX_BRIDGE_IN_SIZE - ui32InBufferOffset;
+
+		bHaveEnoughSpace = ui32BufferSize <= ui32InBufferExcessSize;
+		if (bHaveEnoughSpace)
 		{
-			psDevmemPDumpBitmapOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
-	
-			goto DevmemPDumpBitmap_exit;
+			IMG_BYTE *pInputBuffer = (IMG_BYTE *)psDevmemPDumpBitmapIN;
+
+			pArrayArgsBuffer = &pInputBuffer[ui32InBufferOffset];		}
+		else
+#endif
+		{
+			pArrayArgsBuffer = OSAllocMemNoStats(ui32BufferSize);
+
+			if(!pArrayArgsBuffer)
+			{
+				psDevmemPDumpBitmapOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
+				goto DevmemPDumpBitmap_exit;
+			}
 		}
 	}
 
-			/* Copy the data over */
-			if ( !OSAccessOK(PVR_VERIFY_READ, (void*) psDevmemPDumpBitmapIN->puiFileName, PVRSRV_PDUMP_MAX_FILENAME_SIZE * sizeof(IMG_CHAR))
-				|| (OSCopyFromUser(NULL, uiFileNameInt, psDevmemPDumpBitmapIN->puiFileName,
-				PVRSRV_PDUMP_MAX_FILENAME_SIZE * sizeof(IMG_CHAR)) != PVRSRV_OK) )
-			{
-				psDevmemPDumpBitmapOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
+	
+	{
+		uiFileNameInt = (IMG_CHAR*)(((IMG_UINT8 *)pArrayArgsBuffer) + ui32NextOffset);
+		ui32NextOffset += PVRSRV_PDUMP_MAX_FILENAME_SIZE * sizeof(IMG_CHAR);
+	}
 
-				goto DevmemPDumpBitmap_exit;
+			/* Copy the data over */
+			if (PVRSRV_PDUMP_MAX_FILENAME_SIZE * sizeof(IMG_CHAR) > 0)
+			{
+				if ( OSCopyFromUser(NULL, uiFileNameInt, psDevmemPDumpBitmapIN->puiFileName, PVRSRV_PDUMP_MAX_FILENAME_SIZE * sizeof(IMG_CHAR)) != PVRSRV_OK )
+				{
+					psDevmemPDumpBitmapOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
+
+					goto DevmemPDumpBitmap_exit;
+				}
 			}
 
+	/* Lock over handle lookup. */
+	LockHandle();
+
+
+
 
 
 				{
 					/* Look up the address from the handle */
 					psDevmemPDumpBitmapOUT->eError =
-						PVRSRVLookupHandle(psConnection->psHandleBase,
+						PVRSRVLookupHandleUnlocked(psConnection->psHandleBase,
 											(void **) &psDevmemCtxInt,
-											psDevmemPDumpBitmapIN->hDevmemCtx,
-											PVRSRV_HANDLE_TYPE_DEVMEMINT_CTX);
+											hDevmemCtx,
+											PVRSRV_HANDLE_TYPE_DEVMEMINT_CTX,
+											IMG_TRUE);
 					if(psDevmemPDumpBitmapOUT->eError != PVRSRV_OK)
 					{
+						UnlockHandle();
 						goto DevmemPDumpBitmap_exit;
 					}
 				}
-
+	/* Release now we have looked up handles. */
+	UnlockHandle();
 
 	psDevmemPDumpBitmapOUT->eError =
 		DevmemIntPDumpBitmap(psConnection, OSGetDevData(psConnection),
@@ -136,12 +181,42 @@
 
 
 DevmemPDumpBitmap_exit:
-	if (uiFileNameInt)
-		OSFreeMemNoStats(uiFileNameInt);
+
+	/* Lock over handle lookup cleanup. */
+	LockHandle();
+
+
+
+
+
+
+				{
+					/* Unreference the previously looked up handle */
+						if(psDevmemCtxInt)
+						{
+							PVRSRVReleaseHandleUnlocked(psConnection->psHandleBase,
+											hDevmemCtx,
+											PVRSRV_HANDLE_TYPE_DEVMEMINT_CTX);
+						}
+				}
+	/* Release now we have cleaned up look up handles. */
+	UnlockHandle();
+
+	/* Allocated space should be equal to the last updated offset */
+	PVR_ASSERT(ui32BufferSize == ui32NextOffset);
+
+#if defined(INTEGRITY_OS)
+	if(pArrayArgsBuffer)
+#else
+	if(!bHaveEnoughSpace && pArrayArgsBuffer)
+#endif
+		OSFreeMemNoStats(pArrayArgsBuffer);
+
 
 	return 0;
 }
 
+
 static IMG_INT
 PVRSRVBridgePVRSRVPDumpComment(IMG_UINT32 ui32DispatchTableEntry,
 					  PVRSRV_BRIDGE_IN_PVRSRVPDUMPCOMMENT *psPVRSRVPDumpCommentIN,
@@ -150,33 +225,66 @@
 {
 	IMG_CHAR *uiCommentInt = NULL;
 
+	IMG_UINT32 ui32NextOffset = 0;
+	IMG_BYTE   *pArrayArgsBuffer = NULL;
+#if !defined(INTEGRITY_OS)
+	IMG_BOOL bHaveEnoughSpace = IMG_FALSE;
+#endif
+
+	IMG_UINT32 ui32BufferSize = 
+			(PVRSRV_PDUMP_MAX_COMMENT_SIZE * sizeof(IMG_CHAR)) +
+			0;
+
+
 	PVR_UNREFERENCED_PARAMETER(psConnection);
 
 
 
-	
+	if (ui32BufferSize != 0)
 	{
-		uiCommentInt = OSAllocMemNoStats(PVRSRV_PDUMP_MAX_COMMENT_SIZE * sizeof(IMG_CHAR));
-		if (!uiCommentInt)
+#if !defined(INTEGRITY_OS)
+		/* Try to use remainder of input buffer for copies if possible, word-aligned for safety. */
+		IMG_UINT32 ui32InBufferOffset = PVR_ALIGN(sizeof(*psPVRSRVPDumpCommentIN), sizeof(unsigned long));
+		IMG_UINT32 ui32InBufferExcessSize = ui32InBufferOffset >= PVRSRV_MAX_BRIDGE_IN_SIZE ? 0 :
+			PVRSRV_MAX_BRIDGE_IN_SIZE - ui32InBufferOffset;
+
+		bHaveEnoughSpace = ui32BufferSize <= ui32InBufferExcessSize;
+		if (bHaveEnoughSpace)
 		{
-			psPVRSRVPDumpCommentOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
-	
-			goto PVRSRVPDumpComment_exit;
+			IMG_BYTE *pInputBuffer = (IMG_BYTE *)psPVRSRVPDumpCommentIN;
+
+			pArrayArgsBuffer = &pInputBuffer[ui32InBufferOffset];		}
+		else
+#endif
+		{
+			pArrayArgsBuffer = OSAllocMemNoStats(ui32BufferSize);
+
+			if(!pArrayArgsBuffer)
+			{
+				psPVRSRVPDumpCommentOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
+				goto PVRSRVPDumpComment_exit;
+			}
 		}
 	}
 
+	
+	{
+		uiCommentInt = (IMG_CHAR*)(((IMG_UINT8 *)pArrayArgsBuffer) + ui32NextOffset);
+		ui32NextOffset += PVRSRV_PDUMP_MAX_COMMENT_SIZE * sizeof(IMG_CHAR);
+	}
+
 			/* Copy the data over */
-			if ( !OSAccessOK(PVR_VERIFY_READ, (void*) psPVRSRVPDumpCommentIN->puiComment, PVRSRV_PDUMP_MAX_COMMENT_SIZE * sizeof(IMG_CHAR))
-				|| (OSCopyFromUser(NULL, uiCommentInt, psPVRSRVPDumpCommentIN->puiComment,
-				PVRSRV_PDUMP_MAX_COMMENT_SIZE * sizeof(IMG_CHAR)) != PVRSRV_OK) )
+			if (PVRSRV_PDUMP_MAX_COMMENT_SIZE * sizeof(IMG_CHAR) > 0)
 			{
-				psPVRSRVPDumpCommentOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
+				if ( OSCopyFromUser(NULL, uiCommentInt, psPVRSRVPDumpCommentIN->puiComment, PVRSRV_PDUMP_MAX_COMMENT_SIZE * sizeof(IMG_CHAR)) != PVRSRV_OK )
+				{
+					psPVRSRVPDumpCommentOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
 
-				goto PVRSRVPDumpComment_exit;
+					goto PVRSRVPDumpComment_exit;
+				}
 			}
 
 
-
 	psPVRSRVPDumpCommentOUT->eError =
 		PDumpCommentKM(
 					uiCommentInt,
@@ -186,12 +294,24 @@
 
 
 PVRSRVPDumpComment_exit:
-	if (uiCommentInt)
-		OSFreeMemNoStats(uiCommentInt);
+
+
+
+	/* Allocated space should be equal to the last updated offset */
+	PVR_ASSERT(ui32BufferSize == ui32NextOffset);
+
+#if defined(INTEGRITY_OS)
+	if(pArrayArgsBuffer)
+#else
+	if(!bHaveEnoughSpace && pArrayArgsBuffer)
+#endif
+		OSFreeMemNoStats(pArrayArgsBuffer);
+
 
 	return 0;
 }
 
+
 static IMG_INT
 PVRSRVBridgePVRSRVPDumpSetFrame(IMG_UINT32 ui32DispatchTableEntry,
 					  PVRSRV_BRIDGE_IN_PVRSRVPDUMPSETFRAME *psPVRSRVPDumpSetFrameIN,
@@ -203,17 +323,15 @@
 
 
 
-#if defined(PDUMP)
-	PMRLock();
-#endif
+
 
 
 	psPVRSRVPDumpSetFrameOUT->eError =
 		PDumpSetFrameKM(psConnection, OSGetDevData(psConnection),
 					psPVRSRVPDumpSetFrameIN->ui32Frame);
-#if defined(PDUMP)
-	PMRUnlock();
-#endif
+
+
+
 
 
 
@@ -224,6 +342,7 @@
 
 
 
+
 /* *************************************************************************** 
  * Server bridge dispatch related glue 
  */
@@ -259,4 +378,3 @@
 {
 	return PVRSRV_OK;
 }
-
diff --git a/drivers/staging/imgtec/rogue/generated/cachegeneric_bridge/client_cachegeneric_bridge.h b/drivers/staging/imgtec/rogue/generated/pdumpctrl_bridge/client_pdumpctrl_bridge.h
similarity index 71%
copy from drivers/staging/imgtec/rogue/generated/cachegeneric_bridge/client_cachegeneric_bridge.h
copy to drivers/staging/imgtec/rogue/generated/pdumpctrl_bridge/client_pdumpctrl_bridge.h
index 839a17a..65ca48d 100644
--- a/drivers/staging/imgtec/rogue/generated/cachegeneric_bridge/client_cachegeneric_bridge.h
+++ b/drivers/staging/imgtec/rogue/generated/pdumpctrl_bridge/client_pdumpctrl_bridge.h
@@ -1,8 +1,8 @@
 /*************************************************************************/ /*!
 @File
-@Title          Client bridge header for cachegeneric
+@Title          Client bridge header for pdumpctrl
 @Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
-@Description    Exports the client bridge functions for cachegeneric
+@Description    Exports the client bridge functions for pdumpctrl
 @License        Dual MIT/GPLv2
 
 The contents of this file are subject to the MIT license as set out below.
@@ -41,8 +41,8 @@
 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */ /**************************************************************************/
 
-#ifndef CLIENT_CACHEGENERIC_BRIDGE_H
-#define CLIENT_CACHEGENERIC_BRIDGE_H
+#ifndef CLIENT_PDUMPCTRL_BRIDGE_H
+#define CLIENT_PDUMPCTRL_BRIDGE_H
 
 #include "img_defs.h"
 #include "pvrsrv_error.h"
@@ -52,13 +52,23 @@
 #include "pvr_bridge.h"
 #endif
 
-#include "common_cachegeneric_bridge.h"
+#include "common_pdumpctrl_bridge.h"
 
-IMG_INTERNAL PVRSRV_ERROR IMG_CALLCONV BridgeCacheOpQueue(IMG_HANDLE hBridge,
-							  IMG_HANDLE hPMR,
-							  IMG_DEVMEM_OFFSET_T uiOffset,
-							  IMG_DEVMEM_SIZE_T uiSize,
-							  PVRSRV_CACHE_OP iuCacheOp);
+IMG_INTERNAL PVRSRV_ERROR IMG_CALLCONV BridgePVRSRVPDumpIsCapturing(IMG_HANDLE hBridge,
+								    IMG_BOOL *pbIsCapturing);
+
+IMG_INTERNAL PVRSRV_ERROR IMG_CALLCONV BridgePVRSRVPDumpGetFrame(IMG_HANDLE hBridge,
+								 IMG_UINT32 *pui32Frame);
+
+IMG_INTERNAL PVRSRV_ERROR IMG_CALLCONV BridgePVRSRVPDumpSetDefaultCaptureParams(IMG_HANDLE hBridge,
+										IMG_UINT32 ui32Mode,
+										IMG_UINT32 ui32Start,
+										IMG_UINT32 ui32End,
+										IMG_UINT32 ui32Interval,
+										IMG_UINT32 ui32MaxParamFileSize);
+
+IMG_INTERNAL PVRSRV_ERROR IMG_CALLCONV BridgePVRSRVPDumpIsLastCaptureFrame(IMG_HANDLE hBridge,
+									   IMG_BOOL *pbpbIsLastCaptureFrame);
 
 
-#endif /* CLIENT_CACHEGENERIC_BRIDGE_H */
+#endif /* CLIENT_PDUMPCTRL_BRIDGE_H */
diff --git a/drivers/staging/imgtec/rogue/generated/cachegeneric_bridge/client_cachegeneric_direct_bridge.c b/drivers/staging/imgtec/rogue/generated/pdumpctrl_bridge/client_pdumpctrl_direct_bridge.c
similarity index 64%
copy from drivers/staging/imgtec/rogue/generated/cachegeneric_bridge/client_cachegeneric_direct_bridge.c
copy to drivers/staging/imgtec/rogue/generated/pdumpctrl_bridge/client_pdumpctrl_direct_bridge.c
index d0cdf5a..c8132fc 100644
--- a/drivers/staging/imgtec/rogue/generated/cachegeneric_bridge/client_cachegeneric_direct_bridge.c
+++ b/drivers/staging/imgtec/rogue/generated/pdumpctrl_bridge/client_pdumpctrl_direct_bridge.c
@@ -1,5 +1,5 @@
 /*************************************************************************/ /*!
-@Title          Direct client bridge for cachegeneric
+@Title          Direct client bridge for pdumpctrl
 @Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
 @License        Dual MIT/GPLv2
 
@@ -39,34 +39,75 @@
 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */ /**************************************************************************/
 
-#include "client_cachegeneric_bridge.h"
+#include "client_pdumpctrl_bridge.h"
 #include "img_defs.h"
 #include "pvr_debug.h"
 
 /* Module specific includes */
-#include "cache_external.h"
 
-#include "cache_generic.h"
+#include "pdump_km.h"
 
 
-IMG_INTERNAL PVRSRV_ERROR IMG_CALLCONV BridgeCacheOpQueue(IMG_HANDLE hBridge,
-							  IMG_HANDLE hPMR,
-							  IMG_DEVMEM_OFFSET_T uiOffset,
-							  IMG_DEVMEM_SIZE_T uiSize,
-							  PVRSRV_CACHE_OP iuCacheOp)
+IMG_INTERNAL PVRSRV_ERROR IMG_CALLCONV BridgePVRSRVPDumpIsCapturing(IMG_HANDLE hBridge,
+								    IMG_BOOL *pbIsCapturing)
 {
 	PVRSRV_ERROR eError;
-	PMR * psPMRInt;
 	PVR_UNREFERENCED_PARAMETER(hBridge);
 
-	psPMRInt = (PMR *) hPMR;
 
 	eError =
-		CacheOpQueue(
-					psPMRInt,
-					uiOffset,
-					uiSize,
-					iuCacheOp);
+		PDumpIsCaptureFrameKM(
+					pbIsCapturing);
+
+	return eError;
+}
+
+IMG_INTERNAL PVRSRV_ERROR IMG_CALLCONV BridgePVRSRVPDumpGetFrame(IMG_HANDLE hBridge,
+								 IMG_UINT32 *pui32Frame)
+{
+	PVRSRV_ERROR eError;
+
+
+	eError =
+		PDumpGetFrameKM(NULL, (PVRSRV_DEVICE_NODE *)((void*) hBridge)
+		,
+					pui32Frame);
+
+	return eError;
+}
+
+IMG_INTERNAL PVRSRV_ERROR IMG_CALLCONV BridgePVRSRVPDumpSetDefaultCaptureParams(IMG_HANDLE hBridge,
+										IMG_UINT32 ui32Mode,
+										IMG_UINT32 ui32Start,
+										IMG_UINT32 ui32End,
+										IMG_UINT32 ui32Interval,
+										IMG_UINT32 ui32MaxParamFileSize)
+{
+	PVRSRV_ERROR eError;
+	PVR_UNREFERENCED_PARAMETER(hBridge);
+
+
+	eError =
+		PDumpSetDefaultCaptureParamsKM(
+					ui32Mode,
+					ui32Start,
+					ui32End,
+					ui32Interval,
+					ui32MaxParamFileSize);
+
+	return eError;
+}
+
+IMG_INTERNAL PVRSRV_ERROR IMG_CALLCONV BridgePVRSRVPDumpIsLastCaptureFrame(IMG_HANDLE hBridge,
+									   IMG_BOOL *pbpbIsLastCaptureFrame)
+{
+	PVRSRV_ERROR eError;
+	PVR_UNREFERENCED_PARAMETER(hBridge);
+
+
+	eError =
+		PDumpIsLastCaptureFrameKM(
+					pbpbIsLastCaptureFrame);
 
 	return eError;
 }
diff --git a/drivers/staging/imgtec/rogue/generated/pdumpctrl_bridge/common_pdumpctrl_bridge.h b/drivers/staging/imgtec/rogue/generated/pdumpctrl_bridge/common_pdumpctrl_bridge.h
index 841ee1d..a165141 100644
--- a/drivers/staging/imgtec/rogue/generated/pdumpctrl_bridge/common_pdumpctrl_bridge.h
+++ b/drivers/staging/imgtec/rogue/generated/pdumpctrl_bridge/common_pdumpctrl_bridge.h
@@ -2,8 +2,8 @@
 @File
 @Title          Common bridge header for pdumpctrl
 @Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
-@Description    Declares common defines and structures that are used by both
-                the client and sever side of the bridge for pdumpctrl
+@Description    Declares common defines and structures used by both the client
+                and server side of the bridge for pdumpctrl
 @License        Dual MIT/GPLv2
 
 The contents of this file are subject to the MIT license as set out below.
@@ -45,6 +45,8 @@
 #ifndef COMMON_PDUMPCTRL_BRIDGE_H
 #define COMMON_PDUMPCTRL_BRIDGE_H
 
+#include <powervr/mem_types.h>
+
 #include "img_types.h"
 #include "pvrsrv_error.h"
 
@@ -128,6 +130,7 @@
 /* Bridge out structure for PVRSRVPDumpIsLastCaptureFrame */
 typedef struct PVRSRV_BRIDGE_OUT_PVRSRVPDUMPISLASTCAPTUREFRAME_TAG
 {
+	IMG_BOOL bpbIsLastCaptureFrame;
 	PVRSRV_ERROR eError;
 } __attribute__((packed)) PVRSRV_BRIDGE_OUT_PVRSRVPDUMPISLASTCAPTUREFRAME;
 
diff --git a/drivers/staging/imgtec/rogue/generated/pdumpctrl_bridge/server_pdumpctrl_bridge.c b/drivers/staging/imgtec/rogue/generated/pdumpctrl_bridge/server_pdumpctrl_bridge.c
index 54bfce0..148c726 100644
--- a/drivers/staging/imgtec/rogue/generated/pdumpctrl_bridge/server_pdumpctrl_bridge.c
+++ b/drivers/staging/imgtec/rogue/generated/pdumpctrl_bridge/server_pdumpctrl_bridge.c
@@ -65,6 +65,8 @@
 
 
 
+
+
 /* ***************************************************************************
  * Server-side bridge entry points
  */
@@ -76,6 +78,8 @@
 					 CONNECTION_DATA *psConnection)
 {
 
+
+
 	PVR_UNREFERENCED_PARAMETER(psConnection);
 	PVR_UNREFERENCED_PARAMETER(psPVRSRVPDumpIsCapturingIN);
 
@@ -83,7 +87,6 @@
 
 
 
-
 	psPVRSRVPDumpIsCapturingOUT->eError =
 		PDumpIsCaptureFrameKM(
 					&psPVRSRVPDumpIsCapturingOUT->bIsCapturing);
@@ -92,9 +95,13 @@
 
 
 
+
+
+
 	return 0;
 }
 
+
 static IMG_INT
 PVRSRVBridgePVRSRVPDumpGetFrame(IMG_UINT32 ui32DispatchTableEntry,
 					  PVRSRV_BRIDGE_IN_PVRSRVPDUMPGETFRAME *psPVRSRVPDumpGetFrameIN,
@@ -102,9 +109,10 @@
 					 CONNECTION_DATA *psConnection)
 {
 
-	PVR_UNREFERENCED_PARAMETER(psPVRSRVPDumpGetFrameIN);
 
 
+	PVR_UNREFERENCED_PARAMETER(psPVRSRVPDumpGetFrameIN);
+
 
 
 
@@ -117,9 +125,13 @@
 
 
 
+
+
+
 	return 0;
 }
 
+
 static IMG_INT
 PVRSRVBridgePVRSRVPDumpSetDefaultCaptureParams(IMG_UINT32 ui32DispatchTableEntry,
 					  PVRSRV_BRIDGE_IN_PVRSRVPDUMPSETDEFAULTCAPTUREPARAMS *psPVRSRVPDumpSetDefaultCaptureParamsIN,
@@ -127,9 +139,10 @@
 					 CONNECTION_DATA *psConnection)
 {
 
-	PVR_UNREFERENCED_PARAMETER(psConnection);
 
 
+	PVR_UNREFERENCED_PARAMETER(psConnection);
+
 
 
 
@@ -146,9 +159,13 @@
 
 
 
+
+
+
 	return 0;
 }
 
+
 static IMG_INT
 PVRSRVBridgePVRSRVPDumpIsLastCaptureFrame(IMG_UINT32 ui32DispatchTableEntry,
 					  PVRSRV_BRIDGE_IN_PVRSRVPDUMPISLASTCAPTUREFRAME *psPVRSRVPDumpIsLastCaptureFrameIN,
@@ -156,6 +173,8 @@
 					 CONNECTION_DATA *psConnection)
 {
 
+
+
 	PVR_UNREFERENCED_PARAMETER(psConnection);
 	PVR_UNREFERENCED_PARAMETER(psPVRSRVPDumpIsLastCaptureFrameIN);
 
@@ -163,10 +182,12 @@
 
 
 
-
 	psPVRSRVPDumpIsLastCaptureFrameOUT->eError =
 		PDumpIsLastCaptureFrameKM(
-					);
+					&psPVRSRVPDumpIsLastCaptureFrameOUT->bpbIsLastCaptureFrame);
+
+
+
 
 
 
@@ -177,6 +198,7 @@
 
 
 
+
 /* *************************************************************************** 
  * Server bridge dispatch related glue 
  */
@@ -218,4 +240,3 @@
 	PVR_LOGR_IF_ERROR(OSLockDestroy(pPDUMPCTRLBridgeLock), "OSLockDestroy");
 	return PVRSRV_OK;
 }
-
diff --git a/drivers/staging/imgtec/rogue/generated/pdumpmm_bridge/common_pdumpmm_bridge.h b/drivers/staging/imgtec/rogue/generated/pdumpmm_bridge/common_pdumpmm_bridge.h
index 854a8f8..07e17b2 100644
--- a/drivers/staging/imgtec/rogue/generated/pdumpmm_bridge/common_pdumpmm_bridge.h
+++ b/drivers/staging/imgtec/rogue/generated/pdumpmm_bridge/common_pdumpmm_bridge.h
@@ -2,8 +2,8 @@
 @File
 @Title          Common bridge header for pdumpmm
 @Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
-@Description    Declares common defines and structures that are used by both
-                the client and sever side of the bridge for pdumpmm
+@Description    Declares common defines and structures used by both the client
+                and server side of the bridge for pdumpmm
 @License        Dual MIT/GPLv2
 
 The contents of this file are subject to the MIT license as set out below.
@@ -45,6 +45,8 @@
 #ifndef COMMON_PDUMPMM_BRIDGE_H
 #define COMMON_PDUMPMM_BRIDGE_H
 
+#include <powervr/mem_types.h>
+
 #include "img_types.h"
 #include "pvrsrv_error.h"
 
diff --git a/drivers/staging/imgtec/rogue/generated/pdumpmm_bridge/server_pdumpmm_bridge.c b/drivers/staging/imgtec/rogue/generated/pdumpmm_bridge/server_pdumpmm_bridge.c
index fc3bf19..f5bab7c 100644
--- a/drivers/staging/imgtec/rogue/generated/pdumpmm_bridge/server_pdumpmm_bridge.c
+++ b/drivers/staging/imgtec/rogue/generated/pdumpmm_bridge/server_pdumpmm_bridge.c
@@ -66,6 +66,8 @@
 
 
 
+
+
 /* ***************************************************************************
  * Server-side bridge entry points
  */
@@ -76,29 +78,38 @@
 					  PVRSRV_BRIDGE_OUT_PMRPDUMPLOADMEM *psPMRPDumpLoadMemOUT,
 					 CONNECTION_DATA *psConnection)
 {
+	IMG_HANDLE hPMR = psPMRPDumpLoadMemIN->hPMR;
 	PMR * psPMRInt = NULL;
 
 
 
 
 
-	PMRLock();
+
+
+	/* Lock over handle lookup. */
+	LockHandle();
+
+
+
 
 
 				{
 					/* Look up the address from the handle */
 					psPMRPDumpLoadMemOUT->eError =
-						PVRSRVLookupHandle(psConnection->psHandleBase,
+						PVRSRVLookupHandleUnlocked(psConnection->psHandleBase,
 											(void **) &psPMRInt,
-											psPMRPDumpLoadMemIN->hPMR,
-											PVRSRV_HANDLE_TYPE_PHYSMEM_PMR);
+											hPMR,
+											PVRSRV_HANDLE_TYPE_PHYSMEM_PMR,
+											IMG_TRUE);
 					if(psPMRPDumpLoadMemOUT->eError != PVRSRV_OK)
 					{
-						PMRUnlock();
+						UnlockHandle();
 						goto PMRPDumpLoadMem_exit;
 					}
 				}
-
+	/* Release now we have looked up handles. */
+	UnlockHandle();
 
 	psPMRPDumpLoadMemOUT->eError =
 		PMRPDumpLoadMem(
@@ -107,45 +118,75 @@
 					psPMRPDumpLoadMemIN->uiSize,
 					psPMRPDumpLoadMemIN->ui32PDumpFlags,
 					psPMRPDumpLoadMemIN->bbZero);
-	PMRUnlock();
 
 
 
 
 PMRPDumpLoadMem_exit:
 
+	/* Lock over handle lookup cleanup. */
+	LockHandle();
+
+
+
+
+
+
+				{
+					/* Unreference the previously looked up handle */
+						if(psPMRInt)
+						{
+							PVRSRVReleaseHandleUnlocked(psConnection->psHandleBase,
+											hPMR,
+											PVRSRV_HANDLE_TYPE_PHYSMEM_PMR);
+						}
+				}
+	/* Release now we have cleaned up look up handles. */
+	UnlockHandle();
+
+
 	return 0;
 }
 
+
 static IMG_INT
 PVRSRVBridgePMRPDumpLoadMemValue32(IMG_UINT32 ui32DispatchTableEntry,
 					  PVRSRV_BRIDGE_IN_PMRPDUMPLOADMEMVALUE32 *psPMRPDumpLoadMemValue32IN,
 					  PVRSRV_BRIDGE_OUT_PMRPDUMPLOADMEMVALUE32 *psPMRPDumpLoadMemValue32OUT,
 					 CONNECTION_DATA *psConnection)
 {
+	IMG_HANDLE hPMR = psPMRPDumpLoadMemValue32IN->hPMR;
 	PMR * psPMRInt = NULL;
 
 
 
 
 
-	PMRLock();
+
+
+	/* Lock over handle lookup. */
+	LockHandle();
+
+
+
 
 
 				{
 					/* Look up the address from the handle */
 					psPMRPDumpLoadMemValue32OUT->eError =
-						PVRSRVLookupHandle(psConnection->psHandleBase,
+						PVRSRVLookupHandleUnlocked(psConnection->psHandleBase,
 											(void **) &psPMRInt,
-											psPMRPDumpLoadMemValue32IN->hPMR,
-											PVRSRV_HANDLE_TYPE_PHYSMEM_PMR);
+											hPMR,
+											PVRSRV_HANDLE_TYPE_PHYSMEM_PMR,
+											IMG_TRUE);
 					if(psPMRPDumpLoadMemValue32OUT->eError != PVRSRV_OK)
 					{
-						PMRUnlock();
+						UnlockHandle();
 						goto PMRPDumpLoadMemValue32_exit;
 					}
 				}
-
+	/* Release now we have looked up handles. */
+	UnlockHandle();
 
 	psPMRPDumpLoadMemValue32OUT->eError =
 		PMRPDumpLoadMemValue32(
@@ -153,45 +194,75 @@
 					psPMRPDumpLoadMemValue32IN->uiOffset,
 					psPMRPDumpLoadMemValue32IN->ui32Value,
 					psPMRPDumpLoadMemValue32IN->ui32PDumpFlags);
-	PMRUnlock();
 
 
 
 
 PMRPDumpLoadMemValue32_exit:
 
+	/* Lock over handle lookup cleanup. */
+	LockHandle();
+
+
+
+
+
+
+				{
+					/* Unreference the previously looked up handle */
+						if(psPMRInt)
+						{
+							PVRSRVReleaseHandleUnlocked(psConnection->psHandleBase,
+											hPMR,
+											PVRSRV_HANDLE_TYPE_PHYSMEM_PMR);
+						}
+				}
+	/* Release now we have cleaned up look up handles. */
+	UnlockHandle();
+
+
 	return 0;
 }
 
+
 static IMG_INT
 PVRSRVBridgePMRPDumpLoadMemValue64(IMG_UINT32 ui32DispatchTableEntry,
 					  PVRSRV_BRIDGE_IN_PMRPDUMPLOADMEMVALUE64 *psPMRPDumpLoadMemValue64IN,
 					  PVRSRV_BRIDGE_OUT_PMRPDUMPLOADMEMVALUE64 *psPMRPDumpLoadMemValue64OUT,
 					 CONNECTION_DATA *psConnection)
 {
+	IMG_HANDLE hPMR = psPMRPDumpLoadMemValue64IN->hPMR;
 	PMR * psPMRInt = NULL;
 
 
 
 
 
-	PMRLock();
+
+
+	/* Lock over handle lookup. */
+	LockHandle();
+
+
+
 
 
 				{
 					/* Look up the address from the handle */
 					psPMRPDumpLoadMemValue64OUT->eError =
-						PVRSRVLookupHandle(psConnection->psHandleBase,
+						PVRSRVLookupHandleUnlocked(psConnection->psHandleBase,
 											(void **) &psPMRInt,
-											psPMRPDumpLoadMemValue64IN->hPMR,
-											PVRSRV_HANDLE_TYPE_PHYSMEM_PMR);
+											hPMR,
+											PVRSRV_HANDLE_TYPE_PHYSMEM_PMR,
+											IMG_TRUE);
 					if(psPMRPDumpLoadMemValue64OUT->eError != PVRSRV_OK)
 					{
-						PMRUnlock();
+						UnlockHandle();
 						goto PMRPDumpLoadMemValue64_exit;
 					}
 				}
-
+	/* Release now we have looked up handles. */
+	UnlockHandle();
 
 	psPMRPDumpLoadMemValue64OUT->eError =
 		PMRPDumpLoadMemValue64(
@@ -199,66 +270,128 @@
 					psPMRPDumpLoadMemValue64IN->uiOffset,
 					psPMRPDumpLoadMemValue64IN->ui64Value,
 					psPMRPDumpLoadMemValue64IN->ui32PDumpFlags);
-	PMRUnlock();
 
 
 
 
 PMRPDumpLoadMemValue64_exit:
 
+	/* Lock over handle lookup cleanup. */
+	LockHandle();
+
+
+
+
+
+
+				{
+					/* Unreference the previously looked up handle */
+						if(psPMRInt)
+						{
+							PVRSRVReleaseHandleUnlocked(psConnection->psHandleBase,
+											hPMR,
+											PVRSRV_HANDLE_TYPE_PHYSMEM_PMR);
+						}
+				}
+	/* Release now we have cleaned up look up handles. */
+	UnlockHandle();
+
+
 	return 0;
 }
 
+
 static IMG_INT
 PVRSRVBridgePMRPDumpSaveToFile(IMG_UINT32 ui32DispatchTableEntry,
 					  PVRSRV_BRIDGE_IN_PMRPDUMPSAVETOFILE *psPMRPDumpSaveToFileIN,
 					  PVRSRV_BRIDGE_OUT_PMRPDUMPSAVETOFILE *psPMRPDumpSaveToFileOUT,
 					 CONNECTION_DATA *psConnection)
 {
+	IMG_HANDLE hPMR = psPMRPDumpSaveToFileIN->hPMR;
 	PMR * psPMRInt = NULL;
 	IMG_CHAR *uiFileNameInt = NULL;
 
+	IMG_UINT32 ui32NextOffset = 0;
+	IMG_BYTE   *pArrayArgsBuffer = NULL;
+#if !defined(INTEGRITY_OS)
+	IMG_BOOL bHaveEnoughSpace = IMG_FALSE;
+#endif
+
+	IMG_UINT32 ui32BufferSize = 
+			(psPMRPDumpSaveToFileIN->ui32ArraySize * sizeof(IMG_CHAR)) +
+			0;
 
 
 
-	if (psPMRPDumpSaveToFileIN->ui32ArraySize != 0)
+
+
+	if (ui32BufferSize != 0)
 	{
-		uiFileNameInt = OSAllocMemNoStats(psPMRPDumpSaveToFileIN->ui32ArraySize * sizeof(IMG_CHAR));
-		if (!uiFileNameInt)
+#if !defined(INTEGRITY_OS)
+		/* Try to use remainder of input buffer for copies if possible, word-aligned for safety. */
+		IMG_UINT32 ui32InBufferOffset = PVR_ALIGN(sizeof(*psPMRPDumpSaveToFileIN), sizeof(unsigned long));
+		IMG_UINT32 ui32InBufferExcessSize = ui32InBufferOffset >= PVRSRV_MAX_BRIDGE_IN_SIZE ? 0 :
+			PVRSRV_MAX_BRIDGE_IN_SIZE - ui32InBufferOffset;
+
+		bHaveEnoughSpace = ui32BufferSize <= ui32InBufferExcessSize;
+		if (bHaveEnoughSpace)
 		{
-			psPMRPDumpSaveToFileOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
-	
-			goto PMRPDumpSaveToFile_exit;
+			IMG_BYTE *pInputBuffer = (IMG_BYTE *)psPMRPDumpSaveToFileIN;
+
+			pArrayArgsBuffer = &pInputBuffer[ui32InBufferOffset];		}
+		else
+#endif
+		{
+			pArrayArgsBuffer = OSAllocMemNoStats(ui32BufferSize);
+
+			if(!pArrayArgsBuffer)
+			{
+				psPMRPDumpSaveToFileOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
+				goto PMRPDumpSaveToFile_exit;
+			}
 		}
 	}
 
-			/* Copy the data over */
-			if ( !OSAccessOK(PVR_VERIFY_READ, (void*) psPMRPDumpSaveToFileIN->puiFileName, psPMRPDumpSaveToFileIN->ui32ArraySize * sizeof(IMG_CHAR))
-				|| (OSCopyFromUser(NULL, uiFileNameInt, psPMRPDumpSaveToFileIN->puiFileName,
-				psPMRPDumpSaveToFileIN->ui32ArraySize * sizeof(IMG_CHAR)) != PVRSRV_OK) )
-			{
-				psPMRPDumpSaveToFileOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
+	if (psPMRPDumpSaveToFileIN->ui32ArraySize != 0)
+	{
+		uiFileNameInt = (IMG_CHAR*)(((IMG_UINT8 *)pArrayArgsBuffer) + ui32NextOffset);
+		ui32NextOffset += psPMRPDumpSaveToFileIN->ui32ArraySize * sizeof(IMG_CHAR);
+	}
 
-				goto PMRPDumpSaveToFile_exit;
+			/* Copy the data over */
+			if (psPMRPDumpSaveToFileIN->ui32ArraySize * sizeof(IMG_CHAR) > 0)
+			{
+				if ( OSCopyFromUser(NULL, uiFileNameInt, psPMRPDumpSaveToFileIN->puiFileName, psPMRPDumpSaveToFileIN->ui32ArraySize * sizeof(IMG_CHAR)) != PVRSRV_OK )
+				{
+					psPMRPDumpSaveToFileOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
+
+					goto PMRPDumpSaveToFile_exit;
+				}
 			}
 
-	PMRLock();
+	/* Lock over handle lookup. */
+	LockHandle();
+
+
+
 
 
 				{
 					/* Look up the address from the handle */
 					psPMRPDumpSaveToFileOUT->eError =
-						PVRSRVLookupHandle(psConnection->psHandleBase,
+						PVRSRVLookupHandleUnlocked(psConnection->psHandleBase,
 											(void **) &psPMRInt,
-											psPMRPDumpSaveToFileIN->hPMR,
-											PVRSRV_HANDLE_TYPE_PHYSMEM_PMR);
+											hPMR,
+											PVRSRV_HANDLE_TYPE_PHYSMEM_PMR,
+											IMG_TRUE);
 					if(psPMRPDumpSaveToFileOUT->eError != PVRSRV_OK)
 					{
-						PMRUnlock();
+						UnlockHandle();
 						goto PMRPDumpSaveToFile_exit;
 					}
 				}
-
+	/* Release now we have looked up handles. */
+	UnlockHandle();
 
 	psPMRPDumpSaveToFileOUT->eError =
 		PMRPDumpSaveToFile(
@@ -268,73 +401,138 @@
 					psPMRPDumpSaveToFileIN->ui32ArraySize,
 					uiFileNameInt,
 					psPMRPDumpSaveToFileIN->ui32uiFileOffset);
-	PMRUnlock();
 
 
 
 
 PMRPDumpSaveToFile_exit:
-	if (uiFileNameInt)
-		OSFreeMemNoStats(uiFileNameInt);
+
+	/* Lock over handle lookup cleanup. */
+	LockHandle();
+
+
+
+
+
+
+				{
+					/* Unreference the previously looked up handle */
+						if(psPMRInt)
+						{
+							PVRSRVReleaseHandleUnlocked(psConnection->psHandleBase,
+											hPMR,
+											PVRSRV_HANDLE_TYPE_PHYSMEM_PMR);
+						}
+				}
+	/* Release now we have cleaned up look up handles. */
+	UnlockHandle();
+
+	/* Allocated space should be equal to the last updated offset */
+	PVR_ASSERT(ui32BufferSize == ui32NextOffset);
+
+#if defined(INTEGRITY_OS)
+	if(pArrayArgsBuffer)
+#else
+	if(!bHaveEnoughSpace && pArrayArgsBuffer)
+#endif
+		OSFreeMemNoStats(pArrayArgsBuffer);
+
 
 	return 0;
 }
 
+
 static IMG_INT
 PVRSRVBridgePMRPDumpSymbolicAddr(IMG_UINT32 ui32DispatchTableEntry,
 					  PVRSRV_BRIDGE_IN_PMRPDUMPSYMBOLICADDR *psPMRPDumpSymbolicAddrIN,
 					  PVRSRV_BRIDGE_OUT_PMRPDUMPSYMBOLICADDR *psPMRPDumpSymbolicAddrOUT,
 					 CONNECTION_DATA *psConnection)
 {
+	IMG_HANDLE hPMR = psPMRPDumpSymbolicAddrIN->hPMR;
 	PMR * psPMRInt = NULL;
 	IMG_CHAR *puiMemspaceNameInt = NULL;
 	IMG_CHAR *puiSymbolicAddrInt = NULL;
 
+	IMG_UINT32 ui32NextOffset = 0;
+	IMG_BYTE   *pArrayArgsBuffer = NULL;
+#if !defined(INTEGRITY_OS)
+	IMG_BOOL bHaveEnoughSpace = IMG_FALSE;
+#endif
+
+	IMG_UINT32 ui32BufferSize = 
+			(psPMRPDumpSymbolicAddrIN->ui32MemspaceNameLen * sizeof(IMG_CHAR)) +
+			(psPMRPDumpSymbolicAddrIN->ui32SymbolicAddrLen * sizeof(IMG_CHAR)) +
+			0;
+
+
 
 	psPMRPDumpSymbolicAddrOUT->puiMemspaceName = psPMRPDumpSymbolicAddrIN->puiMemspaceName;
 	psPMRPDumpSymbolicAddrOUT->puiSymbolicAddr = psPMRPDumpSymbolicAddrIN->puiSymbolicAddr;
 
 
+	if (ui32BufferSize != 0)
+	{
+#if !defined(INTEGRITY_OS)
+		/* Try to use remainder of input buffer for copies if possible, word-aligned for safety. */
+		IMG_UINT32 ui32InBufferOffset = PVR_ALIGN(sizeof(*psPMRPDumpSymbolicAddrIN), sizeof(unsigned long));
+		IMG_UINT32 ui32InBufferExcessSize = ui32InBufferOffset >= PVRSRV_MAX_BRIDGE_IN_SIZE ? 0 :
+			PVRSRV_MAX_BRIDGE_IN_SIZE - ui32InBufferOffset;
+
+		bHaveEnoughSpace = ui32BufferSize <= ui32InBufferExcessSize;
+		if (bHaveEnoughSpace)
+		{
+			IMG_BYTE *pInputBuffer = (IMG_BYTE *)psPMRPDumpSymbolicAddrIN;
+
+			pArrayArgsBuffer = &pInputBuffer[ui32InBufferOffset];		}
+		else
+#endif
+		{
+			pArrayArgsBuffer = OSAllocMemNoStats(ui32BufferSize);
+
+			if(!pArrayArgsBuffer)
+			{
+				psPMRPDumpSymbolicAddrOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
+				goto PMRPDumpSymbolicAddr_exit;
+			}
+		}
+	}
+
 	if (psPMRPDumpSymbolicAddrIN->ui32MemspaceNameLen != 0)
 	{
-		puiMemspaceNameInt = OSAllocMemNoStats(psPMRPDumpSymbolicAddrIN->ui32MemspaceNameLen * sizeof(IMG_CHAR));
-		if (!puiMemspaceNameInt)
-		{
-			psPMRPDumpSymbolicAddrOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
-	
-			goto PMRPDumpSymbolicAddr_exit;
-		}
+		puiMemspaceNameInt = (IMG_CHAR*)(((IMG_UINT8 *)pArrayArgsBuffer) + ui32NextOffset);
+		ui32NextOffset += psPMRPDumpSymbolicAddrIN->ui32MemspaceNameLen * sizeof(IMG_CHAR);
 	}
 
 	if (psPMRPDumpSymbolicAddrIN->ui32SymbolicAddrLen != 0)
 	{
-		puiSymbolicAddrInt = OSAllocMemNoStats(psPMRPDumpSymbolicAddrIN->ui32SymbolicAddrLen * sizeof(IMG_CHAR));
-		if (!puiSymbolicAddrInt)
-		{
-			psPMRPDumpSymbolicAddrOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
-	
-			goto PMRPDumpSymbolicAddr_exit;
-		}
+		puiSymbolicAddrInt = (IMG_CHAR*)(((IMG_UINT8 *)pArrayArgsBuffer) + ui32NextOffset);
+		ui32NextOffset += psPMRPDumpSymbolicAddrIN->ui32SymbolicAddrLen * sizeof(IMG_CHAR);
 	}
 
 
-	PMRLock();
+	/* Lock over handle lookup. */
+	LockHandle();
+
+
+
 
 
 				{
 					/* Look up the address from the handle */
 					psPMRPDumpSymbolicAddrOUT->eError =
-						PVRSRVLookupHandle(psConnection->psHandleBase,
+						PVRSRVLookupHandleUnlocked(psConnection->psHandleBase,
 											(void **) &psPMRInt,
-											psPMRPDumpSymbolicAddrIN->hPMR,
-											PVRSRV_HANDLE_TYPE_PHYSMEM_PMR);
+											hPMR,
+											PVRSRV_HANDLE_TYPE_PHYSMEM_PMR,
+											IMG_TRUE);
 					if(psPMRPDumpSymbolicAddrOUT->eError != PVRSRV_OK)
 					{
-						PMRUnlock();
+						UnlockHandle();
 						goto PMRPDumpSymbolicAddr_exit;
 					}
 				}
-
+	/* Release now we have looked up handles. */
+	UnlockHandle();
 
 	psPMRPDumpSymbolicAddrOUT->eError =
 		PMR_PDumpSymbolicAddr(
@@ -346,67 +544,107 @@
 					puiSymbolicAddrInt,
 					&psPMRPDumpSymbolicAddrOUT->uiNewOffset,
 					&psPMRPDumpSymbolicAddrOUT->uiNextSymName);
-	PMRUnlock();
 
 
 
-	if ( !OSAccessOK(PVR_VERIFY_WRITE, (void*) psPMRPDumpSymbolicAddrOUT->puiMemspaceName, (psPMRPDumpSymbolicAddrIN->ui32MemspaceNameLen * sizeof(IMG_CHAR)))
-		|| (OSCopyToUser(NULL, psPMRPDumpSymbolicAddrOUT->puiMemspaceName, puiMemspaceNameInt,
-		(psPMRPDumpSymbolicAddrIN->ui32MemspaceNameLen * sizeof(IMG_CHAR))) != PVRSRV_OK) )
+	if ((psPMRPDumpSymbolicAddrIN->ui32MemspaceNameLen * sizeof(IMG_CHAR)) > 0)
 	{
-		psPMRPDumpSymbolicAddrOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
+		if ( OSCopyToUser(NULL, psPMRPDumpSymbolicAddrOUT->puiMemspaceName, puiMemspaceNameInt,
+			(psPMRPDumpSymbolicAddrIN->ui32MemspaceNameLen * sizeof(IMG_CHAR))) != PVRSRV_OK )
+		{
+			psPMRPDumpSymbolicAddrOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
 
-		goto PMRPDumpSymbolicAddr_exit;
+			goto PMRPDumpSymbolicAddr_exit;
+		}
 	}
 
-	if ( !OSAccessOK(PVR_VERIFY_WRITE, (void*) psPMRPDumpSymbolicAddrOUT->puiSymbolicAddr, (psPMRPDumpSymbolicAddrIN->ui32SymbolicAddrLen * sizeof(IMG_CHAR)))
-		|| (OSCopyToUser(NULL, psPMRPDumpSymbolicAddrOUT->puiSymbolicAddr, puiSymbolicAddrInt,
-		(psPMRPDumpSymbolicAddrIN->ui32SymbolicAddrLen * sizeof(IMG_CHAR))) != PVRSRV_OK) )
+	if ((psPMRPDumpSymbolicAddrIN->ui32SymbolicAddrLen * sizeof(IMG_CHAR)) > 0)
 	{
-		psPMRPDumpSymbolicAddrOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
+		if ( OSCopyToUser(NULL, psPMRPDumpSymbolicAddrOUT->puiSymbolicAddr, puiSymbolicAddrInt,
+			(psPMRPDumpSymbolicAddrIN->ui32SymbolicAddrLen * sizeof(IMG_CHAR))) != PVRSRV_OK )
+		{
+			psPMRPDumpSymbolicAddrOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
 
-		goto PMRPDumpSymbolicAddr_exit;
+			goto PMRPDumpSymbolicAddr_exit;
+		}
 	}
 
 
 PMRPDumpSymbolicAddr_exit:
-	if (puiMemspaceNameInt)
-		OSFreeMemNoStats(puiMemspaceNameInt);
-	if (puiSymbolicAddrInt)
-		OSFreeMemNoStats(puiSymbolicAddrInt);
+
+	/* Lock over handle lookup cleanup. */
+	LockHandle();
+
+
+
+
+
+
+				{
+					/* Unreference the previously looked up handle */
+						if(psPMRInt)
+						{
+							PVRSRVReleaseHandleUnlocked(psConnection->psHandleBase,
+											hPMR,
+											PVRSRV_HANDLE_TYPE_PHYSMEM_PMR);
+						}
+				}
+	/* Release now we have cleaned up look up handles. */
+	UnlockHandle();
+
+	/* Allocated space should be equal to the last updated offset */
+	PVR_ASSERT(ui32BufferSize == ui32NextOffset);
+
+#if defined(INTEGRITY_OS)
+	if(pArrayArgsBuffer)
+#else
+	if(!bHaveEnoughSpace && pArrayArgsBuffer)
+#endif
+		OSFreeMemNoStats(pArrayArgsBuffer);
+
 
 	return 0;
 }
 
+
 static IMG_INT
 PVRSRVBridgePMRPDumpPol32(IMG_UINT32 ui32DispatchTableEntry,
 					  PVRSRV_BRIDGE_IN_PMRPDUMPPOL32 *psPMRPDumpPol32IN,
 					  PVRSRV_BRIDGE_OUT_PMRPDUMPPOL32 *psPMRPDumpPol32OUT,
 					 CONNECTION_DATA *psConnection)
 {
+	IMG_HANDLE hPMR = psPMRPDumpPol32IN->hPMR;
 	PMR * psPMRInt = NULL;
 
 
 
 
 
-	PMRLock();
+
+
+	/* Lock over handle lookup. */
+	LockHandle();
+
+
+
 
 
 				{
 					/* Look up the address from the handle */
 					psPMRPDumpPol32OUT->eError =
-						PVRSRVLookupHandle(psConnection->psHandleBase,
+						PVRSRVLookupHandleUnlocked(psConnection->psHandleBase,
 											(void **) &psPMRInt,
-											psPMRPDumpPol32IN->hPMR,
-											PVRSRV_HANDLE_TYPE_PHYSMEM_PMR);
+											hPMR,
+											PVRSRV_HANDLE_TYPE_PHYSMEM_PMR,
+											IMG_TRUE);
 					if(psPMRPDumpPol32OUT->eError != PVRSRV_OK)
 					{
-						PMRUnlock();
+						UnlockHandle();
 						goto PMRPDumpPol32_exit;
 					}
 				}
-
+	/* Release now we have looked up handles. */
+	UnlockHandle();
 
 	psPMRPDumpPol32OUT->eError =
 		PMRPDumpPol32(
@@ -416,45 +654,75 @@
 					psPMRPDumpPol32IN->ui32Mask,
 					psPMRPDumpPol32IN->eOperator,
 					psPMRPDumpPol32IN->ui32PDumpFlags);
-	PMRUnlock();
 
 
 
 
 PMRPDumpPol32_exit:
 
+	/* Lock over handle lookup cleanup. */
+	LockHandle();
+
+
+
+
+
+
+				{
+					/* Unreference the previously looked up handle */
+						if(psPMRInt)
+						{
+							PVRSRVReleaseHandleUnlocked(psConnection->psHandleBase,
+											hPMR,
+											PVRSRV_HANDLE_TYPE_PHYSMEM_PMR);
+						}
+				}
+	/* Release now we have cleaned up look up handles. */
+	UnlockHandle();
+
+
 	return 0;
 }
 
+
 static IMG_INT
 PVRSRVBridgePMRPDumpCBP(IMG_UINT32 ui32DispatchTableEntry,
 					  PVRSRV_BRIDGE_IN_PMRPDUMPCBP *psPMRPDumpCBPIN,
 					  PVRSRV_BRIDGE_OUT_PMRPDUMPCBP *psPMRPDumpCBPOUT,
 					 CONNECTION_DATA *psConnection)
 {
+	IMG_HANDLE hPMR = psPMRPDumpCBPIN->hPMR;
 	PMR * psPMRInt = NULL;
 
 
 
 
 
-	PMRLock();
+
+
+	/* Lock over handle lookup. */
+	LockHandle();
+
+
+
 
 
 				{
 					/* Look up the address from the handle */
 					psPMRPDumpCBPOUT->eError =
-						PVRSRVLookupHandle(psConnection->psHandleBase,
+						PVRSRVLookupHandleUnlocked(psConnection->psHandleBase,
 											(void **) &psPMRInt,
-											psPMRPDumpCBPIN->hPMR,
-											PVRSRV_HANDLE_TYPE_PHYSMEM_PMR);
+											hPMR,
+											PVRSRV_HANDLE_TYPE_PHYSMEM_PMR,
+											IMG_TRUE);
 					if(psPMRPDumpCBPOUT->eError != PVRSRV_OK)
 					{
-						PMRUnlock();
+						UnlockHandle();
 						goto PMRPDumpCBP_exit;
 					}
 				}
-
+	/* Release now we have looked up handles. */
+	UnlockHandle();
 
 	psPMRPDumpCBPOUT->eError =
 		PMRPDumpCBP(
@@ -463,64 +731,128 @@
 					psPMRPDumpCBPIN->uiWriteOffset,
 					psPMRPDumpCBPIN->uiPacketSize,
 					psPMRPDumpCBPIN->uiBufferSize);
-	PMRUnlock();
 
 
 
 
 PMRPDumpCBP_exit:
 
+	/* Lock over handle lookup cleanup. */
+	LockHandle();
+
+
+
+
+
+
+				{
+					/* Unreference the previously looked up handle */
+						if(psPMRInt)
+						{
+							PVRSRVReleaseHandleUnlocked(psConnection->psHandleBase,
+											hPMR,
+											PVRSRV_HANDLE_TYPE_PHYSMEM_PMR);
+						}
+				}
+	/* Release now we have cleaned up look up handles. */
+	UnlockHandle();
+
+
 	return 0;
 }
 
+
 static IMG_INT
 PVRSRVBridgeDevmemIntPDumpSaveToFileVirtual(IMG_UINT32 ui32DispatchTableEntry,
 					  PVRSRV_BRIDGE_IN_DEVMEMINTPDUMPSAVETOFILEVIRTUAL *psDevmemIntPDumpSaveToFileVirtualIN,
 					  PVRSRV_BRIDGE_OUT_DEVMEMINTPDUMPSAVETOFILEVIRTUAL *psDevmemIntPDumpSaveToFileVirtualOUT,
 					 CONNECTION_DATA *psConnection)
 {
+	IMG_HANDLE hDevmemServerContext = psDevmemIntPDumpSaveToFileVirtualIN->hDevmemServerContext;
 	DEVMEMINT_CTX * psDevmemServerContextInt = NULL;
 	IMG_CHAR *uiFileNameInt = NULL;
 
+	IMG_UINT32 ui32NextOffset = 0;
+	IMG_BYTE   *pArrayArgsBuffer = NULL;
+#if !defined(INTEGRITY_OS)
+	IMG_BOOL bHaveEnoughSpace = IMG_FALSE;
+#endif
+
+	IMG_UINT32 ui32BufferSize = 
+			(psDevmemIntPDumpSaveToFileVirtualIN->ui32ArraySize * sizeof(IMG_CHAR)) +
+			0;
 
 
 
-	if (psDevmemIntPDumpSaveToFileVirtualIN->ui32ArraySize != 0)
+
+
+	if (ui32BufferSize != 0)
 	{
-		uiFileNameInt = OSAllocMemNoStats(psDevmemIntPDumpSaveToFileVirtualIN->ui32ArraySize * sizeof(IMG_CHAR));
-		if (!uiFileNameInt)
+#if !defined(INTEGRITY_OS)
+		/* Try to use remainder of input buffer for copies if possible, word-aligned for safety. */
+		IMG_UINT32 ui32InBufferOffset = PVR_ALIGN(sizeof(*psDevmemIntPDumpSaveToFileVirtualIN), sizeof(unsigned long));
+		IMG_UINT32 ui32InBufferExcessSize = ui32InBufferOffset >= PVRSRV_MAX_BRIDGE_IN_SIZE ? 0 :
+			PVRSRV_MAX_BRIDGE_IN_SIZE - ui32InBufferOffset;
+
+		bHaveEnoughSpace = ui32BufferSize <= ui32InBufferExcessSize;
+		if (bHaveEnoughSpace)
 		{
-			psDevmemIntPDumpSaveToFileVirtualOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
-	
-			goto DevmemIntPDumpSaveToFileVirtual_exit;
+			IMG_BYTE *pInputBuffer = (IMG_BYTE *)psDevmemIntPDumpSaveToFileVirtualIN;
+
+			pArrayArgsBuffer = &pInputBuffer[ui32InBufferOffset];		}
+		else
+#endif
+		{
+			pArrayArgsBuffer = OSAllocMemNoStats(ui32BufferSize);
+
+			if(!pArrayArgsBuffer)
+			{
+				psDevmemIntPDumpSaveToFileVirtualOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
+				goto DevmemIntPDumpSaveToFileVirtual_exit;
+			}
 		}
 	}
 
-			/* Copy the data over */
-			if ( !OSAccessOK(PVR_VERIFY_READ, (void*) psDevmemIntPDumpSaveToFileVirtualIN->puiFileName, psDevmemIntPDumpSaveToFileVirtualIN->ui32ArraySize * sizeof(IMG_CHAR))
-				|| (OSCopyFromUser(NULL, uiFileNameInt, psDevmemIntPDumpSaveToFileVirtualIN->puiFileName,
-				psDevmemIntPDumpSaveToFileVirtualIN->ui32ArraySize * sizeof(IMG_CHAR)) != PVRSRV_OK) )
-			{
-				psDevmemIntPDumpSaveToFileVirtualOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
+	if (psDevmemIntPDumpSaveToFileVirtualIN->ui32ArraySize != 0)
+	{
+		uiFileNameInt = (IMG_CHAR*)(((IMG_UINT8 *)pArrayArgsBuffer) + ui32NextOffset);
+		ui32NextOffset += psDevmemIntPDumpSaveToFileVirtualIN->ui32ArraySize * sizeof(IMG_CHAR);
+	}
 
-				goto DevmemIntPDumpSaveToFileVirtual_exit;
+			/* Copy the data over */
+			if (psDevmemIntPDumpSaveToFileVirtualIN->ui32ArraySize * sizeof(IMG_CHAR) > 0)
+			{
+				if ( OSCopyFromUser(NULL, uiFileNameInt, psDevmemIntPDumpSaveToFileVirtualIN->puiFileName, psDevmemIntPDumpSaveToFileVirtualIN->ui32ArraySize * sizeof(IMG_CHAR)) != PVRSRV_OK )
+				{
+					psDevmemIntPDumpSaveToFileVirtualOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
+
+					goto DevmemIntPDumpSaveToFileVirtual_exit;
+				}
 			}
 
+	/* Lock over handle lookup. */
+	LockHandle();
+
+
+
 
 
 				{
 					/* Look up the address from the handle */
 					psDevmemIntPDumpSaveToFileVirtualOUT->eError =
-						PVRSRVLookupHandle(psConnection->psHandleBase,
+						PVRSRVLookupHandleUnlocked(psConnection->psHandleBase,
 											(void **) &psDevmemServerContextInt,
-											psDevmemIntPDumpSaveToFileVirtualIN->hDevmemServerContext,
-											PVRSRV_HANDLE_TYPE_DEVMEMINT_CTX);
+											hDevmemServerContext,
+											PVRSRV_HANDLE_TYPE_DEVMEMINT_CTX,
+											IMG_TRUE);
 					if(psDevmemIntPDumpSaveToFileVirtualOUT->eError != PVRSRV_OK)
 					{
+						UnlockHandle();
 						goto DevmemIntPDumpSaveToFileVirtual_exit;
 					}
 				}
-
+	/* Release now we have looked up handles. */
+	UnlockHandle();
 
 	psDevmemIntPDumpSaveToFileVirtualOUT->eError =
 		DevmemIntPDumpSaveToFileVirtual(
@@ -536,14 +868,44 @@
 
 
 DevmemIntPDumpSaveToFileVirtual_exit:
-	if (uiFileNameInt)
-		OSFreeMemNoStats(uiFileNameInt);
+
+	/* Lock over handle lookup cleanup. */
+	LockHandle();
+
+
+
+
+
+
+				{
+					/* Unreference the previously looked up handle */
+						if(psDevmemServerContextInt)
+						{
+							PVRSRVReleaseHandleUnlocked(psConnection->psHandleBase,
+											hDevmemServerContext,
+											PVRSRV_HANDLE_TYPE_DEVMEMINT_CTX);
+						}
+				}
+	/* Release now we have cleaned up look up handles. */
+	UnlockHandle();
+
+	/* Allocated space should be equal to the last updated offset */
+	PVR_ASSERT(ui32BufferSize == ui32NextOffset);
+
+#if defined(INTEGRITY_OS)
+	if(pArrayArgsBuffer)
+#else
+	if(!bHaveEnoughSpace && pArrayArgsBuffer)
+#endif
+		OSFreeMemNoStats(pArrayArgsBuffer);
+
 
 	return 0;
 }
 
 
 
+
 /* *************************************************************************** 
  * Server bridge dispatch related glue 
  */
@@ -594,4 +956,3 @@
 {
 	return PVRSRV_OK;
 }
-
diff --git a/drivers/staging/imgtec/rogue/generated/pvrtl_bridge/client_pvrtl_bridge.h b/drivers/staging/imgtec/rogue/generated/pvrtl_bridge/client_pvrtl_bridge.h
index 124a261..4aacc8d 100644
--- a/drivers/staging/imgtec/rogue/generated/pvrtl_bridge/client_pvrtl_bridge.h
+++ b/drivers/staging/imgtec/rogue/generated/pvrtl_bridge/client_pvrtl_bridge.h
@@ -55,7 +55,7 @@
 #include "common_pvrtl_bridge.h"
 
 IMG_INTERNAL PVRSRV_ERROR IMG_CALLCONV BridgeTLOpenStream(IMG_HANDLE hBridge,
-							  IMG_CHAR *puiName,
+							  const IMG_CHAR *puiName,
 							  IMG_UINT32 ui32Mode,
 							  IMG_HANDLE *phSD,
 							  IMG_HANDLE *phTLPMR);
@@ -73,5 +73,27 @@
 							   IMG_UINT32 ui32ReadOffset,
 							   IMG_UINT32 ui32ReadLen);
 
+IMG_INTERNAL PVRSRV_ERROR IMG_CALLCONV BridgeTLDiscoverStreams(IMG_HANDLE hBridge,
+							       const IMG_CHAR *puiNamePattern,
+							       IMG_UINT32 ui32Max,
+							       IMG_UINT32 *pui32Streams,
+							       IMG_UINT32 *pui32NumFound);
+
+IMG_INTERNAL PVRSRV_ERROR IMG_CALLCONV BridgeTLReserveStream(IMG_HANDLE hBridge,
+							     IMG_HANDLE hSD,
+							     IMG_UINT32 *pui32BufferOffset,
+							     IMG_UINT32 ui32Size,
+							     IMG_UINT32 ui32SizeMin,
+							     IMG_UINT32 *pui32Available);
+
+IMG_INTERNAL PVRSRV_ERROR IMG_CALLCONV BridgeTLCommitStream(IMG_HANDLE hBridge,
+							    IMG_HANDLE hSD,
+							    IMG_UINT32 ui32ReqSize);
+
+IMG_INTERNAL PVRSRV_ERROR IMG_CALLCONV BridgeTLWriteData(IMG_HANDLE hBridge,
+							 IMG_HANDLE hSD,
+							 IMG_UINT32 ui32Size,
+							 IMG_BYTE *psData);
+
 
 #endif /* CLIENT_PVRTL_BRIDGE_H */
diff --git a/drivers/staging/imgtec/rogue/generated/pvrtl_bridge/client_pvrtl_direct_bridge.c b/drivers/staging/imgtec/rogue/generated/pvrtl_bridge/client_pvrtl_direct_bridge.c
index d671ffa..c6d793d 100644
--- a/drivers/staging/imgtec/rogue/generated/pvrtl_bridge/client_pvrtl_direct_bridge.c
+++ b/drivers/staging/imgtec/rogue/generated/pvrtl_bridge/client_pvrtl_direct_bridge.c
@@ -45,13 +45,13 @@
 
 /* Module specific includes */
 #include "devicemem_typedefs.h"
-#include "pvr_tl.h"
+#include "pvrsrv_tlcommon.h"
 
 #include "tlserver.h"
 
 
 IMG_INTERNAL PVRSRV_ERROR IMG_CALLCONV BridgeTLOpenStream(IMG_HANDLE hBridge,
-							  IMG_CHAR *puiName,
+							  const IMG_CHAR *puiName,
 							  IMG_UINT32 ui32Mode,
 							  IMG_HANDLE *phSD,
 							  IMG_HANDLE *phTLPMR)
@@ -130,3 +130,85 @@
 	return eError;
 }
 
+IMG_INTERNAL PVRSRV_ERROR IMG_CALLCONV BridgeTLDiscoverStreams(IMG_HANDLE hBridge,
+							       const IMG_CHAR *puiNamePattern,
+							       IMG_UINT32 ui32Max,
+							       IMG_UINT32 *pui32Streams,
+							       IMG_UINT32 *pui32NumFound)
+{
+	PVRSRV_ERROR eError;
+	PVR_UNREFERENCED_PARAMETER(hBridge);
+
+
+	eError =
+		TLServerDiscoverStreamsKM(
+					puiNamePattern,
+					ui32Max,
+					pui32Streams,
+					pui32NumFound);
+
+	return eError;
+}
+
+IMG_INTERNAL PVRSRV_ERROR IMG_CALLCONV BridgeTLReserveStream(IMG_HANDLE hBridge,
+							     IMG_HANDLE hSD,
+							     IMG_UINT32 *pui32BufferOffset,
+							     IMG_UINT32 ui32Size,
+							     IMG_UINT32 ui32SizeMin,
+							     IMG_UINT32 *pui32Available)
+{
+	PVRSRV_ERROR eError;
+	TL_STREAM_DESC * psSDInt;
+	PVR_UNREFERENCED_PARAMETER(hBridge);
+
+	psSDInt = (TL_STREAM_DESC *) hSD;
+
+	eError =
+		TLServerReserveStreamKM(
+					psSDInt,
+					pui32BufferOffset,
+					ui32Size,
+					ui32SizeMin,
+					pui32Available);
+
+	return eError;
+}
+
+IMG_INTERNAL PVRSRV_ERROR IMG_CALLCONV BridgeTLCommitStream(IMG_HANDLE hBridge,
+							    IMG_HANDLE hSD,
+							    IMG_UINT32 ui32ReqSize)
+{
+	PVRSRV_ERROR eError;
+	TL_STREAM_DESC * psSDInt;
+	PVR_UNREFERENCED_PARAMETER(hBridge);
+
+	psSDInt = (TL_STREAM_DESC *) hSD;
+
+	eError =
+		TLServerCommitStreamKM(
+					psSDInt,
+					ui32ReqSize);
+
+	return eError;
+}
+
+IMG_INTERNAL PVRSRV_ERROR IMG_CALLCONV BridgeTLWriteData(IMG_HANDLE hBridge,
+							 IMG_HANDLE hSD,
+							 IMG_UINT32 ui32Size,
+							 IMG_BYTE *psData)
+{
+	PVRSRV_ERROR eError;
+	TL_STREAM_DESC * psSDInt;
+	PVR_UNREFERENCED_PARAMETER(hBridge);
+
+	psSDInt = (TL_STREAM_DESC *) hSD;
+
+	eError =
+		TLServerWriteDataKM(
+					psSDInt,
+					ui32Size,
+					psData);
+
+	return eError;
+}
+
diff --git a/drivers/staging/imgtec/rogue/generated/pvrtl_bridge/common_pvrtl_bridge.h b/drivers/staging/imgtec/rogue/generated/pvrtl_bridge/common_pvrtl_bridge.h
index bb46797..173b9fc 100644
--- a/drivers/staging/imgtec/rogue/generated/pvrtl_bridge/common_pvrtl_bridge.h
+++ b/drivers/staging/imgtec/rogue/generated/pvrtl_bridge/common_pvrtl_bridge.h
@@ -2,8 +2,8 @@
 @File
 @Title          Common bridge header for pvrtl
 @Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
-@Description    Declares common defines and structures that are used by both
-                the client and sever side of the bridge for pvrtl
+@Description    Declares common defines and structures used by both the client
+                and server side of the bridge for pvrtl
 @License        Dual MIT/GPLv2
 
 The contents of this file are subject to the MIT license as set out below.
@@ -45,11 +45,13 @@
 #ifndef COMMON_PVRTL_BRIDGE_H
 #define COMMON_PVRTL_BRIDGE_H
 
+#include <powervr/mem_types.h>
+
 #include "img_types.h"
 #include "pvrsrv_error.h"
 
 #include "devicemem_typedefs.h"
-#include "pvr_tl.h"
+#include "pvrsrv_tlcommon.h"
 
 
 #define PVRSRV_BRIDGE_PVRTL_CMD_FIRST			0
@@ -57,7 +59,11 @@
 #define PVRSRV_BRIDGE_PVRTL_TLCLOSESTREAM			PVRSRV_BRIDGE_PVRTL_CMD_FIRST+1
 #define PVRSRV_BRIDGE_PVRTL_TLACQUIREDATA			PVRSRV_BRIDGE_PVRTL_CMD_FIRST+2
 #define PVRSRV_BRIDGE_PVRTL_TLRELEASEDATA			PVRSRV_BRIDGE_PVRTL_CMD_FIRST+3
-#define PVRSRV_BRIDGE_PVRTL_CMD_LAST			(PVRSRV_BRIDGE_PVRTL_CMD_FIRST+3)
+#define PVRSRV_BRIDGE_PVRTL_TLDISCOVERSTREAMS			PVRSRV_BRIDGE_PVRTL_CMD_FIRST+4
+#define PVRSRV_BRIDGE_PVRTL_TLRESERVESTREAM			PVRSRV_BRIDGE_PVRTL_CMD_FIRST+5
+#define PVRSRV_BRIDGE_PVRTL_TLCOMMITSTREAM			PVRSRV_BRIDGE_PVRTL_CMD_FIRST+6
+#define PVRSRV_BRIDGE_PVRTL_TLWRITEDATA			PVRSRV_BRIDGE_PVRTL_CMD_FIRST+7
+#define PVRSRV_BRIDGE_PVRTL_CMD_LAST			(PVRSRV_BRIDGE_PVRTL_CMD_FIRST+7)
 
 
 /*******************************************
@@ -67,7 +73,7 @@
 /* Bridge in structure for TLOpenStream */
 typedef struct PVRSRV_BRIDGE_IN_TLOPENSTREAM_TAG
 {
-	IMG_CHAR * puiName;
+	const IMG_CHAR * puiName;
 	IMG_UINT32 ui32Mode;
 } __attribute__((packed)) PVRSRV_BRIDGE_IN_TLOPENSTREAM;
 
@@ -135,4 +141,84 @@
 } __attribute__((packed)) PVRSRV_BRIDGE_OUT_TLRELEASEDATA;
 
 
+/*******************************************
+            TLDiscoverStreams          
+ *******************************************/
+
+/* Bridge in structure for TLDiscoverStreams */
+typedef struct PVRSRV_BRIDGE_IN_TLDISCOVERSTREAMS_TAG
+{
+	const IMG_CHAR * puiNamePattern;
+	IMG_UINT32 ui32Max;
+	/* Output pointer pui32Streams is also an implied input */
+	IMG_UINT32 * pui32Streams;
+} __attribute__((packed)) PVRSRV_BRIDGE_IN_TLDISCOVERSTREAMS;
+
+/* Bridge out structure for TLDiscoverStreams */
+typedef struct PVRSRV_BRIDGE_OUT_TLDISCOVERSTREAMS_TAG
+{
+	IMG_UINT32 * pui32Streams;
+	IMG_UINT32 ui32NumFound;
+	PVRSRV_ERROR eError;
+} __attribute__((packed)) PVRSRV_BRIDGE_OUT_TLDISCOVERSTREAMS;
+
+
+/*******************************************
+            TLReserveStream          
+ *******************************************/
+
+/* Bridge in structure for TLReserveStream */
+typedef struct PVRSRV_BRIDGE_IN_TLRESERVESTREAM_TAG
+{
+	IMG_HANDLE hSD;
+	IMG_UINT32 ui32Size;
+	IMG_UINT32 ui32SizeMin;
+} __attribute__((packed)) PVRSRV_BRIDGE_IN_TLRESERVESTREAM;
+
+/* Bridge out structure for TLReserveStream */
+typedef struct PVRSRV_BRIDGE_OUT_TLRESERVESTREAM_TAG
+{
+	IMG_UINT32 ui32BufferOffset;
+	IMG_UINT32 ui32Available;
+	PVRSRV_ERROR eError;
+} __attribute__((packed)) PVRSRV_BRIDGE_OUT_TLRESERVESTREAM;
+
+
+/*******************************************
+            TLCommitStream          
+ *******************************************/
+
+/* Bridge in structure for TLCommitStream */
+typedef struct PVRSRV_BRIDGE_IN_TLCOMMITSTREAM_TAG
+{
+	IMG_HANDLE hSD;
+	IMG_UINT32 ui32ReqSize;
+} __attribute__((packed)) PVRSRV_BRIDGE_IN_TLCOMMITSTREAM;
+
+/* Bridge out structure for TLCommitStream */
+typedef struct PVRSRV_BRIDGE_OUT_TLCOMMITSTREAM_TAG
+{
+	PVRSRV_ERROR eError;
+} __attribute__((packed)) PVRSRV_BRIDGE_OUT_TLCOMMITSTREAM;
+
+
+/*******************************************
+            TLWriteData          
+ *******************************************/
+
+/* Bridge in structure for TLWriteData */
+typedef struct PVRSRV_BRIDGE_IN_TLWRITEDATA_TAG
+{
+	IMG_HANDLE hSD;
+	IMG_UINT32 ui32Size;
+	IMG_BYTE * psData;
+} __attribute__((packed)) PVRSRV_BRIDGE_IN_TLWRITEDATA;
+
+/* Bridge out structure for TLWriteData */
+typedef struct PVRSRV_BRIDGE_OUT_TLWRITEDATA_TAG
+{
+	PVRSRV_ERROR eError;
+} __attribute__((packed)) PVRSRV_BRIDGE_OUT_TLWRITEDATA;
+
+
 #endif /* COMMON_PVRTL_BRIDGE_H */
diff --git a/drivers/staging/imgtec/rogue/generated/pvrtl_bridge/server_pvrtl_bridge.c b/drivers/staging/imgtec/rogue/generated/pvrtl_bridge/server_pvrtl_bridge.c
index 567e11c..f634b6b 100644
--- a/drivers/staging/imgtec/rogue/generated/pvrtl_bridge/server_pvrtl_bridge.c
+++ b/drivers/staging/imgtec/rogue/generated/pvrtl_bridge/server_pvrtl_bridge.c
@@ -64,6 +64,8 @@
 
 
 
+
+
 /* ***************************************************************************
  * Server-side bridge entry points
  */
@@ -78,33 +80,66 @@
 	TL_STREAM_DESC * psSDInt = NULL;
 	PMR * psTLPMRInt = NULL;
 
+	IMG_UINT32 ui32NextOffset = 0;
+	IMG_BYTE   *pArrayArgsBuffer = NULL;
+#if !defined(INTEGRITY_OS)
+	IMG_BOOL bHaveEnoughSpace = IMG_FALSE;
+#endif
+
+	IMG_UINT32 ui32BufferSize = 
+			(PRVSRVTL_MAX_STREAM_NAME_SIZE * sizeof(IMG_CHAR)) +
+			0;
+
+
 
 
 	psTLOpenStreamOUT->hSD = NULL;
 
-	
+	if (ui32BufferSize != 0)
 	{
-		uiNameInt = OSAllocMemNoStats(PRVSRVTL_MAX_STREAM_NAME_SIZE * sizeof(IMG_CHAR));
-		if (!uiNameInt)
+#if !defined(INTEGRITY_OS)
+		/* Try to use remainder of input buffer for copies if possible, word-aligned for safety. */
+		IMG_UINT32 ui32InBufferOffset = PVR_ALIGN(sizeof(*psTLOpenStreamIN), sizeof(unsigned long));
+		IMG_UINT32 ui32InBufferExcessSize = ui32InBufferOffset >= PVRSRV_MAX_BRIDGE_IN_SIZE ? 0 :
+			PVRSRV_MAX_BRIDGE_IN_SIZE - ui32InBufferOffset;
+
+		bHaveEnoughSpace = ui32BufferSize <= ui32InBufferExcessSize;
+		if (bHaveEnoughSpace)
 		{
-			psTLOpenStreamOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
-	
-			goto TLOpenStream_exit;
+			IMG_BYTE *pInputBuffer = (IMG_BYTE *)psTLOpenStreamIN;
+
+			pArrayArgsBuffer = &pInputBuffer[ui32InBufferOffset];		}
+		else
+#endif
+		{
+			pArrayArgsBuffer = OSAllocMemNoStats(ui32BufferSize);
+
+			if(!pArrayArgsBuffer)
+			{
+				psTLOpenStreamOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
+				goto TLOpenStream_exit;
+			}
 		}
 	}
 
+	
+	{
+		uiNameInt = (IMG_CHAR*)(((IMG_UINT8 *)pArrayArgsBuffer) + ui32NextOffset);
+		ui32NextOffset += PRVSRVTL_MAX_STREAM_NAME_SIZE * sizeof(IMG_CHAR);
+	}
+
 			/* Copy the data over */
-			if ( !OSAccessOK(PVR_VERIFY_READ, (void*) psTLOpenStreamIN->puiName, PRVSRVTL_MAX_STREAM_NAME_SIZE * sizeof(IMG_CHAR))
-				|| (OSCopyFromUser(NULL, uiNameInt, psTLOpenStreamIN->puiName,
-				PRVSRVTL_MAX_STREAM_NAME_SIZE * sizeof(IMG_CHAR)) != PVRSRV_OK) )
+			if (PRVSRVTL_MAX_STREAM_NAME_SIZE * sizeof(IMG_CHAR) > 0)
 			{
-				psTLOpenStreamOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
+				if ( OSCopyFromUser(NULL, uiNameInt, psTLOpenStreamIN->puiName, PRVSRVTL_MAX_STREAM_NAME_SIZE * sizeof(IMG_CHAR)) != PVRSRV_OK )
+				{
+					psTLOpenStreamOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
 
-				goto TLOpenStream_exit;
+					goto TLOpenStream_exit;
+				}
 			}
 
 
-
 	psTLOpenStreamOUT->eError =
 		TLServerOpenStreamKM(
 					uiNameInt,
@@ -117,8 +152,15 @@
 		goto TLOpenStream_exit;
 	}
 
+	/* Lock over handle creation. */
+	LockHandle();
 
-	psTLOpenStreamOUT->eError = PVRSRVAllocHandle(psConnection->psHandleBase,
+
+
+
+
+	psTLOpenStreamOUT->eError = PVRSRVAllocHandleUnlocked(psConnection->psHandleBase,
+
 							&psTLOpenStreamOUT->hSD,
 							(void *) psSDInt,
 							PVRSRV_HANDLE_TYPE_PVR_TL_SD,
@@ -126,34 +168,56 @@
 							,(PFN_HANDLE_RELEASE)&TLServerCloseStreamKM);
 	if (psTLOpenStreamOUT->eError != PVRSRV_OK)
 	{
+		UnlockHandle();
 		goto TLOpenStream_exit;
 	}
 
 
-	psTLOpenStreamOUT->eError = PVRSRVAllocSubHandle(psConnection->psHandleBase,
+
+
+
+
+	psTLOpenStreamOUT->eError = PVRSRVAllocSubHandleUnlocked(psConnection->psHandleBase,
+
 							&psTLOpenStreamOUT->hTLPMR,
 							(void *) psTLPMRInt,
 							PVRSRV_HANDLE_TYPE_PMR_LOCAL_EXPORT_HANDLE,
-							PVRSRV_HANDLE_ALLOC_FLAG_NONE
+							PVRSRV_HANDLE_ALLOC_FLAG_MULTI
 							,psTLOpenStreamOUT->hSD);
 	if (psTLOpenStreamOUT->eError != PVRSRV_OK)
 	{
+		UnlockHandle();
 		goto TLOpenStream_exit;
 	}
 
+	/* Release now we have created handles. */
+	UnlockHandle();
 
 
 
 TLOpenStream_exit:
+
+
+
 	if (psTLOpenStreamOUT->eError != PVRSRV_OK)
 	{
+		/* Lock over handle creation cleanup. */
+		LockHandle();
 		if (psTLOpenStreamOUT->hSD)
 		{
-			PVRSRV_ERROR eError = PVRSRVReleaseHandle(psConnection->psHandleBase,
+
+
+			PVRSRV_ERROR eError = PVRSRVReleaseHandleUnlocked(psConnection->psHandleBase,
 						(IMG_HANDLE) psTLOpenStreamOUT->hSD,
 						PVRSRV_HANDLE_TYPE_PVR_TL_SD);
-
-			/* Releasing the handle should free/destroy/release the resource. This should never fail... */
+			if ((eError != PVRSRV_OK) && (eError != PVRSRV_ERROR_RETRY))
+			{
+				PVR_DPF((PVR_DBG_ERROR,
+				        "PVRSRVBridgeTLOpenStream: %s",
+				        PVRSRVGetErrorStringKM(eError)));
+			}
+			/* Releasing the handle should free/destroy/release the resource.
+			 * This should never fail... */
 			PVR_ASSERT((eError == PVRSRV_OK) || (eError == PVRSRV_ERROR_RETRY));
 
 			/* Avoid freeing/destroying/releasing the resource a second time below */
@@ -161,18 +225,29 @@
 		}
 
 
+		/* Release now we have cleaned up creation handles. */
+		UnlockHandle();
 		if (psSDInt)
 		{
 			TLServerCloseStreamKM(psSDInt);
 		}
 	}
 
-	if (uiNameInt)
-		OSFreeMemNoStats(uiNameInt);
+	/* Allocated space should be equal to the last updated offset */
+	PVR_ASSERT(ui32BufferSize == ui32NextOffset);
+
+#if defined(INTEGRITY_OS)
+	if(pArrayArgsBuffer)
+#else
+	if(!bHaveEnoughSpace && pArrayArgsBuffer)
+#endif
+		OSFreeMemNoStats(pArrayArgsBuffer);
+
 
 	return 0;
 }
 
+
 static IMG_INT
 PVRSRVBridgeTLCloseStream(IMG_UINT32 ui32DispatchTableEntry,
 					  PVRSRV_BRIDGE_IN_TLCLOSESTREAM *psTLCloseStreamIN,
@@ -188,29 +263,49 @@
 
 
 
+	/* Lock over handle destruction. */
+	LockHandle();
+
+
+
+
+
 	psTLCloseStreamOUT->eError =
-		PVRSRVReleaseHandle(psConnection->psHandleBase,
+		PVRSRVReleaseHandleUnlocked(psConnection->psHandleBase,
 					(IMG_HANDLE) psTLCloseStreamIN->hSD,
 					PVRSRV_HANDLE_TYPE_PVR_TL_SD);
-	if ((psTLCloseStreamOUT->eError != PVRSRV_OK) && (psTLCloseStreamOUT->eError != PVRSRV_ERROR_RETRY))
+	if ((psTLCloseStreamOUT->eError != PVRSRV_OK) &&
+	    (psTLCloseStreamOUT->eError != PVRSRV_ERROR_RETRY))
 	{
+		PVR_DPF((PVR_DBG_ERROR,
+		        "PVRSRVBridgeTLCloseStream: %s",
+		        PVRSRVGetErrorStringKM(psTLCloseStreamOUT->eError)));
 		PVR_ASSERT(0);
+		UnlockHandle();
 		goto TLCloseStream_exit;
 	}
 
+	/* Release now we have destroyed handles. */
+	UnlockHandle();
+
 
 
 TLCloseStream_exit:
 
+
+
+
 	return 0;
 }
 
+
 static IMG_INT
 PVRSRVBridgeTLAcquireData(IMG_UINT32 ui32DispatchTableEntry,
 					  PVRSRV_BRIDGE_IN_TLACQUIREDATA *psTLAcquireDataIN,
 					  PVRSRV_BRIDGE_OUT_TLACQUIREDATA *psTLAcquireDataOUT,
 					 CONNECTION_DATA *psConnection)
 {
+	IMG_HANDLE hSD = psTLAcquireDataIN->hSD;
 	TL_STREAM_DESC * psSDInt = NULL;
 
 
@@ -219,19 +314,29 @@
 
 
 
+	/* Lock over handle lookup. */
+	LockHandle();
+
+
+
+
+
 				{
 					/* Look up the address from the handle */
 					psTLAcquireDataOUT->eError =
-						PVRSRVLookupHandle(psConnection->psHandleBase,
+						PVRSRVLookupHandleUnlocked(psConnection->psHandleBase,
 											(void **) &psSDInt,
-											psTLAcquireDataIN->hSD,
-											PVRSRV_HANDLE_TYPE_PVR_TL_SD);
+											hSD,
+											PVRSRV_HANDLE_TYPE_PVR_TL_SD,
+											IMG_TRUE);
 					if(psTLAcquireDataOUT->eError != PVRSRV_OK)
 					{
+						UnlockHandle();
 						goto TLAcquireData_exit;
 					}
 				}
-
+	/* Release now we have looked up handles. */
+	UnlockHandle();
 
 	psTLAcquireDataOUT->eError =
 		TLServerAcquireDataKM(
@@ -244,15 +349,38 @@
 
 TLAcquireData_exit:
 
+	/* Lock over handle lookup cleanup. */
+	LockHandle();
+
+
+
+
+
+
+				{
+					/* Unreference the previously looked up handle */
+						if(psSDInt)
+						{
+							PVRSRVReleaseHandleUnlocked(psConnection->psHandleBase,
+											hSD,
+											PVRSRV_HANDLE_TYPE_PVR_TL_SD);
+						}
+				}
+	/* Release now we have cleaned up look up handles. */
+	UnlockHandle();
+
+
 	return 0;
 }
 
+
 static IMG_INT
 PVRSRVBridgeTLReleaseData(IMG_UINT32 ui32DispatchTableEntry,
 					  PVRSRV_BRIDGE_IN_TLRELEASEDATA *psTLReleaseDataIN,
 					  PVRSRV_BRIDGE_OUT_TLRELEASEDATA *psTLReleaseDataOUT,
 					 CONNECTION_DATA *psConnection)
 {
+	IMG_HANDLE hSD = psTLReleaseDataIN->hSD;
 	TL_STREAM_DESC * psSDInt = NULL;
 
 
@@ -261,19 +389,29 @@
 
 
 
+	/* Lock over handle lookup. */
+	LockHandle();
+
+
+
+
+
 				{
 					/* Look up the address from the handle */
 					psTLReleaseDataOUT->eError =
-						PVRSRVLookupHandle(psConnection->psHandleBase,
+						PVRSRVLookupHandleUnlocked(psConnection->psHandleBase,
 											(void **) &psSDInt,
-											psTLReleaseDataIN->hSD,
-											PVRSRV_HANDLE_TYPE_PVR_TL_SD);
+											hSD,
+											PVRSRV_HANDLE_TYPE_PVR_TL_SD,
+											IMG_TRUE);
 					if(psTLReleaseDataOUT->eError != PVRSRV_OK)
 					{
+						UnlockHandle();
 						goto TLReleaseData_exit;
 					}
 				}
-
+	/* Release now we have looked up handles. */
+	UnlockHandle();
 
 	psTLReleaseDataOUT->eError =
 		TLServerReleaseDataKM(
@@ -286,10 +424,438 @@
 
 TLReleaseData_exit:
 
+	/* Lock over handle lookup cleanup. */
+	LockHandle();
+
+
+
+
+
+
+				{
+					/* Unreference the previously looked up handle */
+						if(psSDInt)
+						{
+							PVRSRVReleaseHandleUnlocked(psConnection->psHandleBase,
+											hSD,
+											PVRSRV_HANDLE_TYPE_PVR_TL_SD);
+						}
+				}
+	/* Release now we have cleaned up look up handles. */
+	UnlockHandle();
+
+
 	return 0;
 }
 
 
+static IMG_INT
+PVRSRVBridgeTLDiscoverStreams(IMG_UINT32 ui32DispatchTableEntry,
+					  PVRSRV_BRIDGE_IN_TLDISCOVERSTREAMS *psTLDiscoverStreamsIN,
+					  PVRSRV_BRIDGE_OUT_TLDISCOVERSTREAMS *psTLDiscoverStreamsOUT,
+					 CONNECTION_DATA *psConnection)
+{
+	IMG_CHAR *uiNamePatternInt = NULL;
+	IMG_UINT32 *pui32StreamsInt = NULL;
+
+	IMG_UINT32 ui32NextOffset = 0;
+	IMG_BYTE   *pArrayArgsBuffer = NULL;
+#if !defined(INTEGRITY_OS)
+	IMG_BOOL bHaveEnoughSpace = IMG_FALSE;
+#endif
+
+	IMG_UINT32 ui32BufferSize = 
+			(PRVSRVTL_MAX_STREAM_NAME_SIZE * sizeof(IMG_CHAR)) +
+			(psTLDiscoverStreamsIN->ui32Max * sizeof(IMG_UINT32)) +
+			0;
+
+
+	PVR_UNREFERENCED_PARAMETER(psConnection);
+
+	psTLDiscoverStreamsOUT->pui32Streams = psTLDiscoverStreamsIN->pui32Streams;
+
+
+	if (ui32BufferSize != 0)
+	{
+#if !defined(INTEGRITY_OS)
+		/* Try to use remainder of input buffer for copies if possible, word-aligned for safety. */
+		IMG_UINT32 ui32InBufferOffset = PVR_ALIGN(sizeof(*psTLDiscoverStreamsIN), sizeof(unsigned long));
+		IMG_UINT32 ui32InBufferExcessSize = ui32InBufferOffset >= PVRSRV_MAX_BRIDGE_IN_SIZE ? 0 :
+			PVRSRV_MAX_BRIDGE_IN_SIZE - ui32InBufferOffset;
+
+		bHaveEnoughSpace = ui32BufferSize <= ui32InBufferExcessSize;
+		if (bHaveEnoughSpace)
+		{
+			IMG_BYTE *pInputBuffer = (IMG_BYTE *)psTLDiscoverStreamsIN;
+
+			pArrayArgsBuffer = &pInputBuffer[ui32InBufferOffset];		}
+		else
+#endif
+		{
+			pArrayArgsBuffer = OSAllocMemNoStats(ui32BufferSize);
+
+			if(!pArrayArgsBuffer)
+			{
+				psTLDiscoverStreamsOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
+				goto TLDiscoverStreams_exit;
+			}
+		}
+	}
+
+	
+	{
+		uiNamePatternInt = (IMG_CHAR*)(((IMG_UINT8 *)pArrayArgsBuffer) + ui32NextOffset);
+		ui32NextOffset += PRVSRVTL_MAX_STREAM_NAME_SIZE * sizeof(IMG_CHAR);
+	}
+
+			/* Copy the data over */
+			if (PRVSRVTL_MAX_STREAM_NAME_SIZE * sizeof(IMG_CHAR) > 0)
+			{
+				if ( OSCopyFromUser(NULL, uiNamePatternInt, psTLDiscoverStreamsIN->puiNamePattern, PRVSRVTL_MAX_STREAM_NAME_SIZE * sizeof(IMG_CHAR)) != PVRSRV_OK )
+				{
+					psTLDiscoverStreamsOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
+
+					goto TLDiscoverStreams_exit;
+				}
+			}
+	if (psTLDiscoverStreamsIN->ui32Max != 0)
+	{
+		pui32StreamsInt = (IMG_UINT32*)(((IMG_UINT8 *)pArrayArgsBuffer) + ui32NextOffset);
+		ui32NextOffset += psTLDiscoverStreamsIN->ui32Max * sizeof(IMG_UINT32);
+	}
+
+
+
+	psTLDiscoverStreamsOUT->eError =
+		TLServerDiscoverStreamsKM(
+					uiNamePatternInt,
+					psTLDiscoverStreamsIN->ui32Max,
+					pui32StreamsInt,
+					&psTLDiscoverStreamsOUT->ui32NumFound);
+
+
+
+	if ((psTLDiscoverStreamsIN->ui32Max * sizeof(IMG_UINT32)) > 0)
+	{
+		if ( OSCopyToUser(NULL, psTLDiscoverStreamsOUT->pui32Streams, pui32StreamsInt,
+			(psTLDiscoverStreamsIN->ui32Max * sizeof(IMG_UINT32))) != PVRSRV_OK )
+		{
+			psTLDiscoverStreamsOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
+
+			goto TLDiscoverStreams_exit;
+		}
+	}
+
+
+TLDiscoverStreams_exit:
+
+
+
+	/* Allocated space should be equal to the last updated offset */
+	PVR_ASSERT(ui32BufferSize == ui32NextOffset);
+
+#if defined(INTEGRITY_OS)
+	if(pArrayArgsBuffer)
+#else
+	if(!bHaveEnoughSpace && pArrayArgsBuffer)
+#endif
+		OSFreeMemNoStats(pArrayArgsBuffer);
+
+
+	return 0;
+}
+
+
+static IMG_INT
+PVRSRVBridgeTLReserveStream(IMG_UINT32 ui32DispatchTableEntry,
+					  PVRSRV_BRIDGE_IN_TLRESERVESTREAM *psTLReserveStreamIN,
+					  PVRSRV_BRIDGE_OUT_TLRESERVESTREAM *psTLReserveStreamOUT,
+					 CONNECTION_DATA *psConnection)
+{
+	IMG_HANDLE hSD = psTLReserveStreamIN->hSD;
+	TL_STREAM_DESC * psSDInt = NULL;
+
+
+
+
+
+
+
+	/* Lock over handle lookup. */
+	LockHandle();
+
+
+
+
+
+				{
+					/* Look up the address from the handle */
+					psTLReserveStreamOUT->eError =
+						PVRSRVLookupHandleUnlocked(psConnection->psHandleBase,
+											(void **) &psSDInt,
+											hSD,
+											PVRSRV_HANDLE_TYPE_PVR_TL_SD,
+											IMG_TRUE);
+					if(psTLReserveStreamOUT->eError != PVRSRV_OK)
+					{
+						UnlockHandle();
+						goto TLReserveStream_exit;
+					}
+				}
+	/* Release now we have looked up handles. */
+	UnlockHandle();
+
+	psTLReserveStreamOUT->eError =
+		TLServerReserveStreamKM(
+					psSDInt,
+					&psTLReserveStreamOUT->ui32BufferOffset,
+					psTLReserveStreamIN->ui32Size,
+					psTLReserveStreamIN->ui32SizeMin,
+					&psTLReserveStreamOUT->ui32Available);
+
+
+
+
+TLReserveStream_exit:
+
+	/* Lock over handle lookup cleanup. */
+	LockHandle();
+
+
+
+
+
+
+				{
+					/* Unreference the previously looked up handle */
+						if(psSDInt)
+						{
+							PVRSRVReleaseHandleUnlocked(psConnection->psHandleBase,
+											hSD,
+											PVRSRV_HANDLE_TYPE_PVR_TL_SD);
+						}
+				}
+	/* Release now we have cleaned up look up handles. */
+	UnlockHandle();
+
+
+	return 0;
+}
+
+
+static IMG_INT
+PVRSRVBridgeTLCommitStream(IMG_UINT32 ui32DispatchTableEntry,
+					  PVRSRV_BRIDGE_IN_TLCOMMITSTREAM *psTLCommitStreamIN,
+					  PVRSRV_BRIDGE_OUT_TLCOMMITSTREAM *psTLCommitStreamOUT,
+					 CONNECTION_DATA *psConnection)
+{
+	IMG_HANDLE hSD = psTLCommitStreamIN->hSD;
+	TL_STREAM_DESC * psSDInt = NULL;
+
+
+
+
+
+
+
+	/* Lock over handle lookup. */
+	LockHandle();
+
+
+
+
+
+				{
+					/* Look up the address from the handle */
+					psTLCommitStreamOUT->eError =
+						PVRSRVLookupHandleUnlocked(psConnection->psHandleBase,
+											(void **) &psSDInt,
+											hSD,
+											PVRSRV_HANDLE_TYPE_PVR_TL_SD,
+											IMG_TRUE);
+					if(psTLCommitStreamOUT->eError != PVRSRV_OK)
+					{
+						UnlockHandle();
+						goto TLCommitStream_exit;
+					}
+				}
+	/* Release now we have looked up handles. */
+	UnlockHandle();
+
+	psTLCommitStreamOUT->eError =
+		TLServerCommitStreamKM(
+					psSDInt,
+					psTLCommitStreamIN->ui32ReqSize);
+
+
+
+
+TLCommitStream_exit:
+
+	/* Lock over handle lookup cleanup. */
+	LockHandle();
+
+
+
+
+
+
+				{
+					/* Unreference the previously looked up handle */
+						if(psSDInt)
+						{
+							PVRSRVReleaseHandleUnlocked(psConnection->psHandleBase,
+											hSD,
+											PVRSRV_HANDLE_TYPE_PVR_TL_SD);
+						}
+				}
+	/* Release now we have cleaned up look up handles. */
+	UnlockHandle();
+
+
+	return 0;
+}
+
+
+static IMG_INT
+PVRSRVBridgeTLWriteData(IMG_UINT32 ui32DispatchTableEntry,
+					  PVRSRV_BRIDGE_IN_TLWRITEDATA *psTLWriteDataIN,
+					  PVRSRV_BRIDGE_OUT_TLWRITEDATA *psTLWriteDataOUT,
+					 CONNECTION_DATA *psConnection)
+{
+	IMG_HANDLE hSD = psTLWriteDataIN->hSD;
+	TL_STREAM_DESC * psSDInt = NULL;
+	IMG_BYTE *psDataInt = NULL;
+
+	IMG_UINT32 ui32NextOffset = 0;
+	IMG_BYTE   *pArrayArgsBuffer = NULL;
+#if !defined(INTEGRITY_OS)
+	IMG_BOOL bHaveEnoughSpace = IMG_FALSE;
+#endif
+
+	IMG_UINT32 ui32BufferSize = 
+			(psTLWriteDataIN->ui32Size * sizeof(IMG_BYTE)) +
+			0;
+
+
+
+
+
+	if (ui32BufferSize != 0)
+	{
+#if !defined(INTEGRITY_OS)
+		/* Try to use remainder of input buffer for copies if possible, word-aligned for safety. */
+		IMG_UINT32 ui32InBufferOffset = PVR_ALIGN(sizeof(*psTLWriteDataIN), sizeof(unsigned long));
+		IMG_UINT32 ui32InBufferExcessSize = ui32InBufferOffset >= PVRSRV_MAX_BRIDGE_IN_SIZE ? 0 :
+			PVRSRV_MAX_BRIDGE_IN_SIZE - ui32InBufferOffset;
+
+		bHaveEnoughSpace = ui32BufferSize <= ui32InBufferExcessSize;
+		if (bHaveEnoughSpace)
+		{
+			IMG_BYTE *pInputBuffer = (IMG_BYTE *)psTLWriteDataIN;
+
+			pArrayArgsBuffer = &pInputBuffer[ui32InBufferOffset];		}
+		else
+#endif
+		{
+			pArrayArgsBuffer = OSAllocMemNoStats(ui32BufferSize);
+
+			if(!pArrayArgsBuffer)
+			{
+				psTLWriteDataOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
+				goto TLWriteData_exit;
+			}
+		}
+	}
+
+	if (psTLWriteDataIN->ui32Size != 0)
+	{
+		psDataInt = (IMG_BYTE*)(((IMG_UINT8 *)pArrayArgsBuffer) + ui32NextOffset);
+		ui32NextOffset += psTLWriteDataIN->ui32Size * sizeof(IMG_BYTE);
+	}
+
+			/* Copy the data over */
+			if (psTLWriteDataIN->ui32Size * sizeof(IMG_BYTE) > 0)
+			{
+				if ( OSCopyFromUser(NULL, psDataInt, psTLWriteDataIN->psData, psTLWriteDataIN->ui32Size * sizeof(IMG_BYTE)) != PVRSRV_OK )
+				{
+					psTLWriteDataOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
+
+					goto TLWriteData_exit;
+				}
+			}
+
+	/* Lock over handle lookup. */
+	LockHandle();
+
+
+
+
+
+				{
+					/* Look up the address from the handle */
+					psTLWriteDataOUT->eError =
+						PVRSRVLookupHandleUnlocked(psConnection->psHandleBase,
+											(void **) &psSDInt,
+											hSD,
+											PVRSRV_HANDLE_TYPE_PVR_TL_SD,
+											IMG_TRUE);
+					if(psTLWriteDataOUT->eError != PVRSRV_OK)
+					{
+						UnlockHandle();
+						goto TLWriteData_exit;
+					}
+				}
+	/* Release now we have looked up handles. */
+	UnlockHandle();
+
+	psTLWriteDataOUT->eError =
+		TLServerWriteDataKM(
+					psSDInt,
+					psTLWriteDataIN->ui32Size,
+					psDataInt);
+
+
+
+
+TLWriteData_exit:
+
+	/* Lock over handle lookup cleanup. */
+	LockHandle();
+
+
+
+
+
+
+				{
+					/* Unreference the previously looked up handle */
+						if(psSDInt)
+						{
+							PVRSRVReleaseHandleUnlocked(psConnection->psHandleBase,
+											hSD,
+											PVRSRV_HANDLE_TYPE_PVR_TL_SD);
+						}
+				}
+	/* Release now we have cleaned up look up handles. */
+	UnlockHandle();
+
+	/* Allocated space should be equal to the last updated offset */
+	PVR_ASSERT(ui32BufferSize == ui32NextOffset);
+
+#if defined(INTEGRITY_OS)
+	if(pArrayArgsBuffer)
+#else
+	if(!bHaveEnoughSpace && pArrayArgsBuffer)
+#endif
+		OSFreeMemNoStats(pArrayArgsBuffer);
+
+
+	return 0;
+}
+
+
+
 
 /* *************************************************************************** 
  * Server bridge dispatch related glue 
@@ -318,6 +884,18 @@
 	SetDispatchTableEntry(PVRSRV_BRIDGE_PVRTL, PVRSRV_BRIDGE_PVRTL_TLRELEASEDATA, PVRSRVBridgeTLReleaseData,
 					NULL, bUseLock);
 
+	SetDispatchTableEntry(PVRSRV_BRIDGE_PVRTL, PVRSRV_BRIDGE_PVRTL_TLDISCOVERSTREAMS, PVRSRVBridgeTLDiscoverStreams,
+					NULL, bUseLock);
+
+	SetDispatchTableEntry(PVRSRV_BRIDGE_PVRTL, PVRSRV_BRIDGE_PVRTL_TLRESERVESTREAM, PVRSRVBridgeTLReserveStream,
+					NULL, bUseLock);
+
+	SetDispatchTableEntry(PVRSRV_BRIDGE_PVRTL, PVRSRV_BRIDGE_PVRTL_TLCOMMITSTREAM, PVRSRVBridgeTLCommitStream,
+					NULL, bUseLock);
+
+	SetDispatchTableEntry(PVRSRV_BRIDGE_PVRTL, PVRSRV_BRIDGE_PVRTL_TLWRITEDATA, PVRSRVBridgeTLWriteData,
+					NULL, bUseLock);
+
 
 	return PVRSRV_OK;
 }
@@ -329,4 +907,3 @@
 {
 	return PVRSRV_OK;
 }
-
diff --git a/drivers/staging/imgtec/rogue/generated/regconfig_bridge/common_regconfig_bridge.h b/drivers/staging/imgtec/rogue/generated/regconfig_bridge/common_regconfig_bridge.h
index 64a147c..ebd98e8 100644
--- a/drivers/staging/imgtec/rogue/generated/regconfig_bridge/common_regconfig_bridge.h
+++ b/drivers/staging/imgtec/rogue/generated/regconfig_bridge/common_regconfig_bridge.h
@@ -2,8 +2,8 @@
 @File
 @Title          Common bridge header for regconfig
 @Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
-@Description    Declares common defines and structures that are used by both
-                the client and sever side of the bridge for regconfig
+@Description    Declares common defines and structures used by both the client
+                and server side of the bridge for regconfig
 @License        Dual MIT/GPLv2
 
 The contents of this file are subject to the MIT license as set out below.
@@ -45,6 +45,8 @@
 #ifndef COMMON_REGCONFIG_BRIDGE_H
 #define COMMON_REGCONFIG_BRIDGE_H
 
+#include <powervr/mem_types.h>
+
 #include "img_types.h"
 #include "pvrsrv_error.h"
 
diff --git a/drivers/staging/imgtec/rogue/generated/regconfig_bridge/server_regconfig_bridge.c b/drivers/staging/imgtec/rogue/generated/regconfig_bridge/server_regconfig_bridge.c
index 0e7aff2..2671e78 100644
--- a/drivers/staging/imgtec/rogue/generated/regconfig_bridge/server_regconfig_bridge.c
+++ b/drivers/staging/imgtec/rogue/generated/regconfig_bridge/server_regconfig_bridge.c
@@ -63,6 +63,9 @@
 
 
 
+#if !defined(EXCLUDE_REGCONFIG_BRIDGE)
+
+
 
 /* ***************************************************************************
  * Server-side bridge entry points
@@ -81,6 +84,7 @@
 
 
 
+
 	psRGXSetRegConfigTypeOUT->eError =
 		PVRSRVRGXSetRegConfigTypeKM(psConnection, OSGetDevData(psConnection),
 					psRGXSetRegConfigTypeIN->ui8RegPowerIsland);
@@ -89,9 +93,13 @@
 
 
 
+
+
+
 	return 0;
 }
 
+
 static IMG_INT
 PVRSRVBridgeRGXAddRegconfig(IMG_UINT32 ui32DispatchTableEntry,
 					  PVRSRV_BRIDGE_IN_RGXADDREGCONFIG *psRGXAddRegconfigIN,
@@ -105,6 +113,7 @@
 
 
 
+
 	psRGXAddRegconfigOUT->eError =
 		PVRSRVRGXAddRegConfigKM(psConnection, OSGetDevData(psConnection),
 					psRGXAddRegconfigIN->ui32RegAddr,
@@ -115,9 +124,13 @@
 
 
 
+
+
+
 	return 0;
 }
 
+
 static IMG_INT
 PVRSRVBridgeRGXClearRegConfig(IMG_UINT32 ui32DispatchTableEntry,
 					  PVRSRV_BRIDGE_IN_RGXCLEARREGCONFIG *psRGXClearRegConfigIN,
@@ -125,9 +138,10 @@
 					 CONNECTION_DATA *psConnection)
 {
 
-	PVR_UNREFERENCED_PARAMETER(psRGXClearRegConfigIN);
 
 
+	PVR_UNREFERENCED_PARAMETER(psRGXClearRegConfigIN);
+
 
 
 
@@ -140,9 +154,13 @@
 
 
 
+
+
+
 	return 0;
 }
 
+
 static IMG_INT
 PVRSRVBridgeRGXEnableRegConfig(IMG_UINT32 ui32DispatchTableEntry,
 					  PVRSRV_BRIDGE_IN_RGXENABLEREGCONFIG *psRGXEnableRegConfigIN,
@@ -150,9 +168,10 @@
 					 CONNECTION_DATA *psConnection)
 {
 
-	PVR_UNREFERENCED_PARAMETER(psRGXEnableRegConfigIN);
 
 
+	PVR_UNREFERENCED_PARAMETER(psRGXEnableRegConfigIN);
+
 
 
 
@@ -165,9 +184,13 @@
 
 
 
+
+
+
 	return 0;
 }
 
+
 static IMG_INT
 PVRSRVBridgeRGXDisableRegConfig(IMG_UINT32 ui32DispatchTableEntry,
 					  PVRSRV_BRIDGE_IN_RGXDISABLEREGCONFIG *psRGXDisableRegConfigIN,
@@ -175,9 +198,10 @@
 					 CONNECTION_DATA *psConnection)
 {
 
-	PVR_UNREFERENCED_PARAMETER(psRGXDisableRegConfigIN);
 
 
+	PVR_UNREFERENCED_PARAMETER(psRGXDisableRegConfigIN);
+
 
 
 
@@ -190,17 +214,23 @@
 
 
 
+
+
+
 	return 0;
 }
 
 
 
+
 /* *************************************************************************** 
  * Server bridge dispatch related glue 
  */
 
 static IMG_BOOL bUseLock = IMG_TRUE;
+#endif /* EXCLUDE_REGCONFIG_BRIDGE */
 
+#if !defined(EXCLUDE_REGCONFIG_BRIDGE)
 PVRSRV_ERROR InitREGCONFIGBridge(void);
 PVRSRV_ERROR DeinitREGCONFIGBridge(void);
 
@@ -236,4 +266,14 @@
 {
 	return PVRSRV_OK;
 }
+#else /* EXCLUDE_REGCONFIG_BRIDGE */
+/* This bridge is conditional on EXCLUDE_REGCONFIG_BRIDGE - when defined,
+ * do not populate the dispatch table with its functions
+ */
+#define InitREGCONFIGBridge() \
+	PVRSRV_OK
 
+#define DeinitREGCONFIGBridge() \
+	PVRSRV_OK
+
+#endif /* EXCLUDE_REGCONFIG_BRIDGE */
diff --git a/drivers/staging/imgtec/rogue/generated/rgxcmp_bridge/common_rgxcmp_bridge.h b/drivers/staging/imgtec/rogue/generated/rgxcmp_bridge/common_rgxcmp_bridge.h
index dd86e79..a18075e 100644
--- a/drivers/staging/imgtec/rogue/generated/rgxcmp_bridge/common_rgxcmp_bridge.h
+++ b/drivers/staging/imgtec/rogue/generated/rgxcmp_bridge/common_rgxcmp_bridge.h
@@ -2,8 +2,8 @@
 @File
 @Title          Common bridge header for rgxcmp
 @Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
-@Description    Declares common defines and structures that are used by both
-                the client and sever side of the bridge for rgxcmp
+@Description    Declares common defines and structures used by both the client
+                and server side of the bridge for rgxcmp
 @License        Dual MIT/GPLv2
 
 The contents of this file are subject to the MIT license as set out below.
@@ -45,12 +45,13 @@
 #ifndef COMMON_RGXCMP_BRIDGE_H
 #define COMMON_RGXCMP_BRIDGE_H
 
+#include <powervr/mem_types.h>
+
 #include "img_types.h"
 #include "pvrsrv_error.h"
 
 #include "rgx_bridge.h"
-#include "sync_external.h"
-#include "rgx_fwif_shared.h"
+#include <powervr/sync_external.h>
 
 
 #define PVRSRV_BRIDGE_RGXCMP_CMD_FIRST			0
@@ -60,7 +61,8 @@
 #define PVRSRV_BRIDGE_RGXCMP_RGXFLUSHCOMPUTEDATA			PVRSRV_BRIDGE_RGXCMP_CMD_FIRST+3
 #define PVRSRV_BRIDGE_RGXCMP_RGXSETCOMPUTECONTEXTPRIORITY			PVRSRV_BRIDGE_RGXCMP_CMD_FIRST+4
 #define PVRSRV_BRIDGE_RGXCMP_RGXGETLASTCOMPUTECONTEXTRESETREASON			PVRSRV_BRIDGE_RGXCMP_CMD_FIRST+5
-#define PVRSRV_BRIDGE_RGXCMP_CMD_LAST			(PVRSRV_BRIDGE_RGXCMP_CMD_FIRST+5)
+#define PVRSRV_BRIDGE_RGXCMP_RGXNOTIFYCOMPUTEWRITEOFFSETUPDATE			PVRSRV_BRIDGE_RGXCMP_CMD_FIRST+6
+#define PVRSRV_BRIDGE_RGXCMP_CMD_LAST			(PVRSRV_BRIDGE_RGXCMP_CMD_FIRST+6)
 
 
 /*******************************************
@@ -75,6 +77,7 @@
 	IMG_UINT32 ui32FrameworkCmdize;
 	IMG_BYTE * psFrameworkCmd;
 	IMG_HANDLE hPrivData;
+	IMG_DEV_VIRTADDR sResumeSignalAddr;
 } __attribute__((packed)) PVRSRV_BRIDGE_IN_RGXCREATECOMPUTECONTEXT;
 
 /* Bridge out structure for RGXCreateComputeContext */
@@ -110,6 +113,7 @@
 typedef struct PVRSRV_BRIDGE_IN_RGXKICKCDM_TAG
 {
 	IMG_HANDLE hComputeContext;
+	IMG_UINT32 ui32ClientCacheOpSeqNum;
 	IMG_UINT32 ui32ClientFenceCount;
 	IMG_HANDLE * phClientFenceUFOSyncPrimBlock;
 	IMG_UINT32 * pui32ClientFenceOffset;
@@ -121,16 +125,19 @@
 	IMG_UINT32 ui32ServerSyncCount;
 	IMG_UINT32 * pui32ServerSyncFlags;
 	IMG_HANDLE * phServerSyncs;
+	IMG_INT32 i32CheckFenceFd;
+	IMG_INT32 i32UpdateTimelineFd;
+	IMG_CHAR * puiUpdateFenceName;
 	IMG_UINT32 ui32CmdSize;
 	IMG_BYTE * psDMCmd;
-	IMG_BOOL bbPDumpContinuous;
+	IMG_UINT32 ui32PDumpFlags;
 	IMG_UINT32 ui32ExtJobRef;
-	IMG_UINT32 ui32IntJobRef;
 } __attribute__((packed)) PVRSRV_BRIDGE_IN_RGXKICKCDM;
 
 /* Bridge out structure for RGXKickCDM */
 typedef struct PVRSRV_BRIDGE_OUT_RGXKICKCDM_TAG
 {
+	IMG_INT32 i32UpdateFenceFd;
 	PVRSRV_ERROR eError;
 } __attribute__((packed)) PVRSRV_BRIDGE_OUT_RGXKICKCDM;
 
@@ -189,4 +196,21 @@
 } __attribute__((packed)) PVRSRV_BRIDGE_OUT_RGXGETLASTCOMPUTECONTEXTRESETREASON;
 
 
+/*******************************************
+            RGXNotifyComputeWriteOffsetUpdate          
+ *******************************************/
+
+/* Bridge in structure for RGXNotifyComputeWriteOffsetUpdate */
+typedef struct PVRSRV_BRIDGE_IN_RGXNOTIFYCOMPUTEWRITEOFFSETUPDATE_TAG
+{
+	IMG_HANDLE hComputeContext;
+} __attribute__((packed)) PVRSRV_BRIDGE_IN_RGXNOTIFYCOMPUTEWRITEOFFSETUPDATE;
+
+/* Bridge out structure for RGXNotifyComputeWriteOffsetUpdate */
+typedef struct PVRSRV_BRIDGE_OUT_RGXNOTIFYCOMPUTEWRITEOFFSETUPDATE_TAG
+{
+	PVRSRV_ERROR eError;
+} __attribute__((packed)) PVRSRV_BRIDGE_OUT_RGXNOTIFYCOMPUTEWRITEOFFSETUPDATE;
+
+
 #endif /* COMMON_RGXCMP_BRIDGE_H */
diff --git a/drivers/staging/imgtec/rogue/generated/rgxcmp_bridge/server_rgxcmp_bridge.c b/drivers/staging/imgtec/rogue/generated/rgxcmp_bridge/server_rgxcmp_bridge.c
index 43b0350..c531498 100644
--- a/drivers/staging/imgtec/rogue/generated/rgxcmp_bridge/server_rgxcmp_bridge.c
+++ b/drivers/staging/imgtec/rogue/generated/rgxcmp_bridge/server_rgxcmp_bridge.c
@@ -62,6 +62,9 @@
 #include <linux/slab.h>
 
 
+#include "rgx_bvnc_defs_km.h"
+
+
 
 
 /* ***************************************************************************
@@ -75,50 +78,103 @@
 					 CONNECTION_DATA *psConnection)
 {
 	IMG_BYTE *psFrameworkCmdInt = NULL;
+	IMG_HANDLE hPrivData = psRGXCreateComputeContextIN->hPrivData;
 	IMG_HANDLE hPrivDataInt = NULL;
 	RGX_SERVER_COMPUTE_CONTEXT * psComputeContextInt = NULL;
 
+	IMG_UINT32 ui32NextOffset = 0;
+	IMG_BYTE   *pArrayArgsBuffer = NULL;
+#if !defined(INTEGRITY_OS)
+	IMG_BOOL bHaveEnoughSpace = IMG_FALSE;
+#endif
 
+	IMG_UINT32 ui32BufferSize = 
+			(psRGXCreateComputeContextIN->ui32FrameworkCmdize * sizeof(IMG_BYTE)) +
+			0;
 
-
-	if (psRGXCreateComputeContextIN->ui32FrameworkCmdize != 0)
 	{
-		psFrameworkCmdInt = OSAllocMemNoStats(psRGXCreateComputeContextIN->ui32FrameworkCmdize * sizeof(IMG_BYTE));
-		if (!psFrameworkCmdInt)
+		PVRSRV_DEVICE_NODE *psDeviceNode = OSGetDevData(psConnection);
+
+		/* Check that device supports the required feature */
+		if ((psDeviceNode->pfnCheckDeviceFeature) &&
+			!psDeviceNode->pfnCheckDeviceFeature(psDeviceNode, RGX_FEATURE_COMPUTE_BIT_MASK))
 		{
-			psRGXCreateComputeContextOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
-	
+			psRGXCreateComputeContextOUT->eError = PVRSRV_ERROR_NOT_SUPPORTED;
+
 			goto RGXCreateComputeContext_exit;
 		}
 	}
 
-			/* Copy the data over */
-			if ( !OSAccessOK(PVR_VERIFY_READ, (void*) psRGXCreateComputeContextIN->psFrameworkCmd, psRGXCreateComputeContextIN->ui32FrameworkCmdize * sizeof(IMG_BYTE))
-				|| (OSCopyFromUser(NULL, psFrameworkCmdInt, psRGXCreateComputeContextIN->psFrameworkCmd,
-				psRGXCreateComputeContextIN->ui32FrameworkCmdize * sizeof(IMG_BYTE)) != PVRSRV_OK) )
-			{
-				psRGXCreateComputeContextOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
 
+
+
+	if (ui32BufferSize != 0)
+	{
+#if !defined(INTEGRITY_OS)
+		/* Try to use remainder of input buffer for copies if possible, word-aligned for safety. */
+		IMG_UINT32 ui32InBufferOffset = PVR_ALIGN(sizeof(*psRGXCreateComputeContextIN), sizeof(unsigned long));
+		IMG_UINT32 ui32InBufferExcessSize = ui32InBufferOffset >= PVRSRV_MAX_BRIDGE_IN_SIZE ? 0 :
+			PVRSRV_MAX_BRIDGE_IN_SIZE - ui32InBufferOffset;
+
+		bHaveEnoughSpace = ui32BufferSize <= ui32InBufferExcessSize;
+		if (bHaveEnoughSpace)
+		{
+			IMG_BYTE *pInputBuffer = (IMG_BYTE *)psRGXCreateComputeContextIN;
+
+			pArrayArgsBuffer = &pInputBuffer[ui32InBufferOffset];		}
+		else
+#endif
+		{
+			pArrayArgsBuffer = OSAllocMemNoStats(ui32BufferSize);
+
+			if(!pArrayArgsBuffer)
+			{
+				psRGXCreateComputeContextOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
 				goto RGXCreateComputeContext_exit;
 			}
+		}
+	}
 
-	PMRLock();
+	if (psRGXCreateComputeContextIN->ui32FrameworkCmdize != 0)
+	{
+		psFrameworkCmdInt = (IMG_BYTE*)(((IMG_UINT8 *)pArrayArgsBuffer) + ui32NextOffset);
+		ui32NextOffset += psRGXCreateComputeContextIN->ui32FrameworkCmdize * sizeof(IMG_BYTE);
+	}
+
+			/* Copy the data over */
+			if (psRGXCreateComputeContextIN->ui32FrameworkCmdize * sizeof(IMG_BYTE) > 0)
+			{
+				if ( OSCopyFromUser(NULL, psFrameworkCmdInt, psRGXCreateComputeContextIN->psFrameworkCmd, psRGXCreateComputeContextIN->ui32FrameworkCmdize * sizeof(IMG_BYTE)) != PVRSRV_OK )
+				{
+					psRGXCreateComputeContextOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
+
+					goto RGXCreateComputeContext_exit;
+				}
+			}
+
+	/* Lock over handle lookup. */
+	LockHandle();
+
+
+
 
 
 				{
 					/* Look up the address from the handle */
 					psRGXCreateComputeContextOUT->eError =
-						PVRSRVLookupHandle(psConnection->psHandleBase,
+						PVRSRVLookupHandleUnlocked(psConnection->psHandleBase,
 											(void **) &hPrivDataInt,
-											psRGXCreateComputeContextIN->hPrivData,
-											PVRSRV_HANDLE_TYPE_DEV_PRIV_DATA);
+											hPrivData,
+											PVRSRV_HANDLE_TYPE_DEV_PRIV_DATA,
+											IMG_TRUE);
 					if(psRGXCreateComputeContextOUT->eError != PVRSRV_OK)
 					{
-						PMRUnlock();
+						UnlockHandle();
 						goto RGXCreateComputeContext_exit;
 					}
 				}
-
+	/* Release now we have looked up handles. */
+	UnlockHandle();
 
 	psRGXCreateComputeContextOUT->eError =
 		PVRSRVRGXCreateComputeContextKM(psConnection, OSGetDevData(psConnection),
@@ -127,17 +183,23 @@
 					psRGXCreateComputeContextIN->ui32FrameworkCmdize,
 					psFrameworkCmdInt,
 					hPrivDataInt,
+					psRGXCreateComputeContextIN->sResumeSignalAddr,
 					&psComputeContextInt);
 	/* Exit early if bridged call fails */
 	if(psRGXCreateComputeContextOUT->eError != PVRSRV_OK)
 	{
-		PMRUnlock();
 		goto RGXCreateComputeContext_exit;
 	}
-	PMRUnlock();
+
+	/* Lock over handle creation. */
+	LockHandle();
 
 
-	psRGXCreateComputeContextOUT->eError = PVRSRVAllocHandle(psConnection->psHandleBase,
+
+
+
+	psRGXCreateComputeContextOUT->eError = PVRSRVAllocHandleUnlocked(psConnection->psHandleBase,
+
 							&psRGXCreateComputeContextOUT->hComputeContext,
 							(void *) psComputeContextInt,
 							PVRSRV_HANDLE_TYPE_RGX_SERVER_COMPUTE_CONTEXT,
@@ -145,13 +207,37 @@
 							,(PFN_HANDLE_RELEASE)&PVRSRVRGXDestroyComputeContextKM);
 	if (psRGXCreateComputeContextOUT->eError != PVRSRV_OK)
 	{
+		UnlockHandle();
 		goto RGXCreateComputeContext_exit;
 	}
 
+	/* Release now we have created handles. */
+	UnlockHandle();
 
 
 
 RGXCreateComputeContext_exit:
+
+	/* Lock over handle lookup cleanup. */
+	LockHandle();
+
+
+
+
+
+
+				{
+					/* Unreference the previously looked up handle */
+						if(hPrivDataInt)
+						{
+							PVRSRVReleaseHandleUnlocked(psConnection->psHandleBase,
+											hPrivData,
+											PVRSRV_HANDLE_TYPE_DEV_PRIV_DATA);
+						}
+				}
+	/* Release now we have cleaned up look up handles. */
+	UnlockHandle();
+
 	if (psRGXCreateComputeContextOUT->eError != PVRSRV_OK)
 	{
 		if (psComputeContextInt)
@@ -160,12 +246,21 @@
 		}
 	}
 
-	if (psFrameworkCmdInt)
-		OSFreeMemNoStats(psFrameworkCmdInt);
+	/* Allocated space should be equal to the last updated offset */
+	PVR_ASSERT(ui32BufferSize == ui32NextOffset);
+
+#if defined(INTEGRITY_OS)
+	if(pArrayArgsBuffer)
+#else
+	if(!bHaveEnoughSpace && pArrayArgsBuffer)
+#endif
+		OSFreeMemNoStats(pArrayArgsBuffer);
+
 
 	return 0;
 }
 
+
 static IMG_INT
 PVRSRVBridgeRGXDestroyComputeContext(IMG_UINT32 ui32DispatchTableEntry,
 					  PVRSRV_BRIDGE_IN_RGXDESTROYCOMPUTECONTEXT *psRGXDestroyComputeContextIN,
@@ -174,39 +269,68 @@
 {
 
 
+	{
+		PVRSRV_DEVICE_NODE *psDeviceNode = OSGetDevData(psConnection);
+
+		/* Check that device supports the required feature */
+		if ((psDeviceNode->pfnCheckDeviceFeature) &&
+			!psDeviceNode->pfnCheckDeviceFeature(psDeviceNode, RGX_FEATURE_COMPUTE_BIT_MASK))
+		{
+			psRGXDestroyComputeContextOUT->eError = PVRSRV_ERROR_NOT_SUPPORTED;
+
+			goto RGXDestroyComputeContext_exit;
+		}
+	}
 
 
 
-	PMRLock();
+
+
+
+
+	/* Lock over handle destruction. */
+	LockHandle();
+
 
 
 
 
 	psRGXDestroyComputeContextOUT->eError =
-		PVRSRVReleaseHandle(psConnection->psHandleBase,
+		PVRSRVReleaseHandleUnlocked(psConnection->psHandleBase,
 					(IMG_HANDLE) psRGXDestroyComputeContextIN->hComputeContext,
 					PVRSRV_HANDLE_TYPE_RGX_SERVER_COMPUTE_CONTEXT);
-	if ((psRGXDestroyComputeContextOUT->eError != PVRSRV_OK) && (psRGXDestroyComputeContextOUT->eError != PVRSRV_ERROR_RETRY))
+	if ((psRGXDestroyComputeContextOUT->eError != PVRSRV_OK) &&
+	    (psRGXDestroyComputeContextOUT->eError != PVRSRV_ERROR_RETRY))
 	{
+		PVR_DPF((PVR_DBG_ERROR,
+		        "PVRSRVBridgeRGXDestroyComputeContext: %s",
+		        PVRSRVGetErrorStringKM(psRGXDestroyComputeContextOUT->eError)));
 		PVR_ASSERT(0);
-		PMRUnlock();
+		UnlockHandle();
 		goto RGXDestroyComputeContext_exit;
 	}
 
-	PMRUnlock();
+	/* Release now we have destroyed handles. */
+	UnlockHandle();
+
 
 
 RGXDestroyComputeContext_exit:
 
+
+
+
 	return 0;
 }
 
+
 static IMG_INT
 PVRSRVBridgeRGXKickCDM(IMG_UINT32 ui32DispatchTableEntry,
 					  PVRSRV_BRIDGE_IN_RGXKICKCDM *psRGXKickCDMIN,
 					  PVRSRV_BRIDGE_OUT_RGXKICKCDM *psRGXKickCDMOUT,
 					 CONNECTION_DATA *psConnection)
 {
+	IMG_HANDLE hComputeContext = psRGXKickCDMIN->hComputeContext;
 	RGX_SERVER_COMPUTE_CONTEXT * psComputeContextInt = NULL;
 	SYNC_PRIMITIVE_BLOCK * *psClientFenceUFOSyncPrimBlockInt = NULL;
 	IMG_HANDLE *hClientFenceUFOSyncPrimBlockInt2 = NULL;
@@ -219,235 +343,267 @@
 	IMG_UINT32 *ui32ServerSyncFlagsInt = NULL;
 	SERVER_SYNC_PRIMITIVE * *psServerSyncsInt = NULL;
 	IMG_HANDLE *hServerSyncsInt2 = NULL;
+	IMG_CHAR *uiUpdateFenceNameInt = NULL;
 	IMG_BYTE *psDMCmdInt = NULL;
 
+	IMG_UINT32 ui32NextOffset = 0;
+	IMG_BYTE   *pArrayArgsBuffer = NULL;
+#if !defined(INTEGRITY_OS)
+	IMG_BOOL bHaveEnoughSpace = IMG_FALSE;
+#endif
+
+	IMG_UINT32 ui32BufferSize = 
+			(psRGXKickCDMIN->ui32ClientFenceCount * sizeof(SYNC_PRIMITIVE_BLOCK *)) +
+			(psRGXKickCDMIN->ui32ClientFenceCount * sizeof(IMG_HANDLE)) +
+			(psRGXKickCDMIN->ui32ClientFenceCount * sizeof(IMG_UINT32)) +
+			(psRGXKickCDMIN->ui32ClientFenceCount * sizeof(IMG_UINT32)) +
+			(psRGXKickCDMIN->ui32ClientUpdateCount * sizeof(SYNC_PRIMITIVE_BLOCK *)) +
+			(psRGXKickCDMIN->ui32ClientUpdateCount * sizeof(IMG_HANDLE)) +
+			(psRGXKickCDMIN->ui32ClientUpdateCount * sizeof(IMG_UINT32)) +
+			(psRGXKickCDMIN->ui32ClientUpdateCount * sizeof(IMG_UINT32)) +
+			(psRGXKickCDMIN->ui32ServerSyncCount * sizeof(IMG_UINT32)) +
+			(psRGXKickCDMIN->ui32ServerSyncCount * sizeof(SERVER_SYNC_PRIMITIVE *)) +
+			(psRGXKickCDMIN->ui32ServerSyncCount * sizeof(IMG_HANDLE)) +
+			(32 * sizeof(IMG_CHAR)) +
+			(psRGXKickCDMIN->ui32CmdSize * sizeof(IMG_BYTE)) +
+			0;
+
+	{
+		PVRSRV_DEVICE_NODE *psDeviceNode = OSGetDevData(psConnection);
+
+		/* Check that device supports the required feature */
+		if ((psDeviceNode->pfnCheckDeviceFeature) &&
+			!psDeviceNode->pfnCheckDeviceFeature(psDeviceNode, RGX_FEATURE_COMPUTE_BIT_MASK))
+		{
+			psRGXKickCDMOUT->eError = PVRSRV_ERROR_NOT_SUPPORTED;
+
+			goto RGXKickCDM_exit;
+		}
+	}
 
 
 
+
+	if (ui32BufferSize != 0)
+	{
+#if !defined(INTEGRITY_OS)
+		/* Try to use remainder of input buffer for copies if possible, word-aligned for safety. */
+		IMG_UINT32 ui32InBufferOffset = PVR_ALIGN(sizeof(*psRGXKickCDMIN), sizeof(unsigned long));
+		IMG_UINT32 ui32InBufferExcessSize = ui32InBufferOffset >= PVRSRV_MAX_BRIDGE_IN_SIZE ? 0 :
+			PVRSRV_MAX_BRIDGE_IN_SIZE - ui32InBufferOffset;
+
+		bHaveEnoughSpace = ui32BufferSize <= ui32InBufferExcessSize;
+		if (bHaveEnoughSpace)
+		{
+			IMG_BYTE *pInputBuffer = (IMG_BYTE *)psRGXKickCDMIN;
+
+			pArrayArgsBuffer = &pInputBuffer[ui32InBufferOffset];		}
+		else
+#endif
+		{
+			pArrayArgsBuffer = OSAllocMemNoStats(ui32BufferSize);
+
+			if(!pArrayArgsBuffer)
+			{
+				psRGXKickCDMOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
+				goto RGXKickCDM_exit;
+			}
+		}
+	}
+
 	if (psRGXKickCDMIN->ui32ClientFenceCount != 0)
 	{
-		psClientFenceUFOSyncPrimBlockInt = OSAllocMemNoStats(psRGXKickCDMIN->ui32ClientFenceCount * sizeof(SYNC_PRIMITIVE_BLOCK *));
-		if (!psClientFenceUFOSyncPrimBlockInt)
-		{
-			psRGXKickCDMOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
-	
-			goto RGXKickCDM_exit;
-		}
-		hClientFenceUFOSyncPrimBlockInt2 = OSAllocMemNoStats(psRGXKickCDMIN->ui32ClientFenceCount * sizeof(IMG_HANDLE));
-		if (!hClientFenceUFOSyncPrimBlockInt2)
-		{
-			psRGXKickCDMOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
-	
-			goto RGXKickCDM_exit;
-		}
+		psClientFenceUFOSyncPrimBlockInt = (SYNC_PRIMITIVE_BLOCK **)(((IMG_UINT8 *)pArrayArgsBuffer) + ui32NextOffset);
+		ui32NextOffset += psRGXKickCDMIN->ui32ClientFenceCount * sizeof(SYNC_PRIMITIVE_BLOCK *);
+		hClientFenceUFOSyncPrimBlockInt2 = (IMG_HANDLE *)(((IMG_UINT8 *)pArrayArgsBuffer) + ui32NextOffset); 
+		ui32NextOffset += psRGXKickCDMIN->ui32ClientFenceCount * sizeof(IMG_HANDLE);
 	}
 
 			/* Copy the data over */
-			if ( !OSAccessOK(PVR_VERIFY_READ, (void*) psRGXKickCDMIN->phClientFenceUFOSyncPrimBlock, psRGXKickCDMIN->ui32ClientFenceCount * sizeof(IMG_HANDLE))
-				|| (OSCopyFromUser(NULL, hClientFenceUFOSyncPrimBlockInt2, psRGXKickCDMIN->phClientFenceUFOSyncPrimBlock,
-				psRGXKickCDMIN->ui32ClientFenceCount * sizeof(IMG_HANDLE)) != PVRSRV_OK) )
+			if (psRGXKickCDMIN->ui32ClientFenceCount * sizeof(IMG_HANDLE) > 0)
 			{
-				psRGXKickCDMOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
+				if ( OSCopyFromUser(NULL, hClientFenceUFOSyncPrimBlockInt2, psRGXKickCDMIN->phClientFenceUFOSyncPrimBlock, psRGXKickCDMIN->ui32ClientFenceCount * sizeof(IMG_HANDLE)) != PVRSRV_OK )
+				{
+					psRGXKickCDMOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
 
-				goto RGXKickCDM_exit;
+					goto RGXKickCDM_exit;
+				}
 			}
 	if (psRGXKickCDMIN->ui32ClientFenceCount != 0)
 	{
-		ui32ClientFenceOffsetInt = OSAllocMemNoStats(psRGXKickCDMIN->ui32ClientFenceCount * sizeof(IMG_UINT32));
-		if (!ui32ClientFenceOffsetInt)
-		{
-			psRGXKickCDMOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
-	
-			goto RGXKickCDM_exit;
-		}
+		ui32ClientFenceOffsetInt = (IMG_UINT32*)(((IMG_UINT8 *)pArrayArgsBuffer) + ui32NextOffset);
+		ui32NextOffset += psRGXKickCDMIN->ui32ClientFenceCount * sizeof(IMG_UINT32);
 	}
 
 			/* Copy the data over */
-			if ( !OSAccessOK(PVR_VERIFY_READ, (void*) psRGXKickCDMIN->pui32ClientFenceOffset, psRGXKickCDMIN->ui32ClientFenceCount * sizeof(IMG_UINT32))
-				|| (OSCopyFromUser(NULL, ui32ClientFenceOffsetInt, psRGXKickCDMIN->pui32ClientFenceOffset,
-				psRGXKickCDMIN->ui32ClientFenceCount * sizeof(IMG_UINT32)) != PVRSRV_OK) )
+			if (psRGXKickCDMIN->ui32ClientFenceCount * sizeof(IMG_UINT32) > 0)
 			{
-				psRGXKickCDMOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
+				if ( OSCopyFromUser(NULL, ui32ClientFenceOffsetInt, psRGXKickCDMIN->pui32ClientFenceOffset, psRGXKickCDMIN->ui32ClientFenceCount * sizeof(IMG_UINT32)) != PVRSRV_OK )
+				{
+					psRGXKickCDMOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
 
-				goto RGXKickCDM_exit;
+					goto RGXKickCDM_exit;
+				}
 			}
 	if (psRGXKickCDMIN->ui32ClientFenceCount != 0)
 	{
-		ui32ClientFenceValueInt = OSAllocMemNoStats(psRGXKickCDMIN->ui32ClientFenceCount * sizeof(IMG_UINT32));
-		if (!ui32ClientFenceValueInt)
-		{
-			psRGXKickCDMOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
-	
-			goto RGXKickCDM_exit;
-		}
+		ui32ClientFenceValueInt = (IMG_UINT32*)(((IMG_UINT8 *)pArrayArgsBuffer) + ui32NextOffset);
+		ui32NextOffset += psRGXKickCDMIN->ui32ClientFenceCount * sizeof(IMG_UINT32);
 	}
 
 			/* Copy the data over */
-			if ( !OSAccessOK(PVR_VERIFY_READ, (void*) psRGXKickCDMIN->pui32ClientFenceValue, psRGXKickCDMIN->ui32ClientFenceCount * sizeof(IMG_UINT32))
-				|| (OSCopyFromUser(NULL, ui32ClientFenceValueInt, psRGXKickCDMIN->pui32ClientFenceValue,
-				psRGXKickCDMIN->ui32ClientFenceCount * sizeof(IMG_UINT32)) != PVRSRV_OK) )
+			if (psRGXKickCDMIN->ui32ClientFenceCount * sizeof(IMG_UINT32) > 0)
 			{
-				psRGXKickCDMOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
+				if ( OSCopyFromUser(NULL, ui32ClientFenceValueInt, psRGXKickCDMIN->pui32ClientFenceValue, psRGXKickCDMIN->ui32ClientFenceCount * sizeof(IMG_UINT32)) != PVRSRV_OK )
+				{
+					psRGXKickCDMOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
 
-				goto RGXKickCDM_exit;
+					goto RGXKickCDM_exit;
+				}
 			}
 	if (psRGXKickCDMIN->ui32ClientUpdateCount != 0)
 	{
-		psClientUpdateUFOSyncPrimBlockInt = OSAllocMemNoStats(psRGXKickCDMIN->ui32ClientUpdateCount * sizeof(SYNC_PRIMITIVE_BLOCK *));
-		if (!psClientUpdateUFOSyncPrimBlockInt)
-		{
-			psRGXKickCDMOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
-	
-			goto RGXKickCDM_exit;
-		}
-		hClientUpdateUFOSyncPrimBlockInt2 = OSAllocMemNoStats(psRGXKickCDMIN->ui32ClientUpdateCount * sizeof(IMG_HANDLE));
-		if (!hClientUpdateUFOSyncPrimBlockInt2)
-		{
-			psRGXKickCDMOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
-	
-			goto RGXKickCDM_exit;
-		}
+		psClientUpdateUFOSyncPrimBlockInt = (SYNC_PRIMITIVE_BLOCK **)(((IMG_UINT8 *)pArrayArgsBuffer) + ui32NextOffset);
+		ui32NextOffset += psRGXKickCDMIN->ui32ClientUpdateCount * sizeof(SYNC_PRIMITIVE_BLOCK *);
+		hClientUpdateUFOSyncPrimBlockInt2 = (IMG_HANDLE *)(((IMG_UINT8 *)pArrayArgsBuffer) + ui32NextOffset); 
+		ui32NextOffset += psRGXKickCDMIN->ui32ClientUpdateCount * sizeof(IMG_HANDLE);
 	}
 
 			/* Copy the data over */
-			if ( !OSAccessOK(PVR_VERIFY_READ, (void*) psRGXKickCDMIN->phClientUpdateUFOSyncPrimBlock, psRGXKickCDMIN->ui32ClientUpdateCount * sizeof(IMG_HANDLE))
-				|| (OSCopyFromUser(NULL, hClientUpdateUFOSyncPrimBlockInt2, psRGXKickCDMIN->phClientUpdateUFOSyncPrimBlock,
-				psRGXKickCDMIN->ui32ClientUpdateCount * sizeof(IMG_HANDLE)) != PVRSRV_OK) )
+			if (psRGXKickCDMIN->ui32ClientUpdateCount * sizeof(IMG_HANDLE) > 0)
 			{
-				psRGXKickCDMOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
+				if ( OSCopyFromUser(NULL, hClientUpdateUFOSyncPrimBlockInt2, psRGXKickCDMIN->phClientUpdateUFOSyncPrimBlock, psRGXKickCDMIN->ui32ClientUpdateCount * sizeof(IMG_HANDLE)) != PVRSRV_OK )
+				{
+					psRGXKickCDMOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
 
-				goto RGXKickCDM_exit;
+					goto RGXKickCDM_exit;
+				}
 			}
 	if (psRGXKickCDMIN->ui32ClientUpdateCount != 0)
 	{
-		ui32ClientUpdateOffsetInt = OSAllocMemNoStats(psRGXKickCDMIN->ui32ClientUpdateCount * sizeof(IMG_UINT32));
-		if (!ui32ClientUpdateOffsetInt)
-		{
-			psRGXKickCDMOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
-	
-			goto RGXKickCDM_exit;
-		}
+		ui32ClientUpdateOffsetInt = (IMG_UINT32*)(((IMG_UINT8 *)pArrayArgsBuffer) + ui32NextOffset);
+		ui32NextOffset += psRGXKickCDMIN->ui32ClientUpdateCount * sizeof(IMG_UINT32);
 	}
 
 			/* Copy the data over */
-			if ( !OSAccessOK(PVR_VERIFY_READ, (void*) psRGXKickCDMIN->pui32ClientUpdateOffset, psRGXKickCDMIN->ui32ClientUpdateCount * sizeof(IMG_UINT32))
-				|| (OSCopyFromUser(NULL, ui32ClientUpdateOffsetInt, psRGXKickCDMIN->pui32ClientUpdateOffset,
-				psRGXKickCDMIN->ui32ClientUpdateCount * sizeof(IMG_UINT32)) != PVRSRV_OK) )
+			if (psRGXKickCDMIN->ui32ClientUpdateCount * sizeof(IMG_UINT32) > 0)
 			{
-				psRGXKickCDMOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
+				if ( OSCopyFromUser(NULL, ui32ClientUpdateOffsetInt, psRGXKickCDMIN->pui32ClientUpdateOffset, psRGXKickCDMIN->ui32ClientUpdateCount * sizeof(IMG_UINT32)) != PVRSRV_OK )
+				{
+					psRGXKickCDMOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
 
-				goto RGXKickCDM_exit;
+					goto RGXKickCDM_exit;
+				}
 			}
 	if (psRGXKickCDMIN->ui32ClientUpdateCount != 0)
 	{
-		ui32ClientUpdateValueInt = OSAllocMemNoStats(psRGXKickCDMIN->ui32ClientUpdateCount * sizeof(IMG_UINT32));
-		if (!ui32ClientUpdateValueInt)
-		{
-			psRGXKickCDMOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
-	
-			goto RGXKickCDM_exit;
-		}
+		ui32ClientUpdateValueInt = (IMG_UINT32*)(((IMG_UINT8 *)pArrayArgsBuffer) + ui32NextOffset);
+		ui32NextOffset += psRGXKickCDMIN->ui32ClientUpdateCount * sizeof(IMG_UINT32);
 	}
 
 			/* Copy the data over */
-			if ( !OSAccessOK(PVR_VERIFY_READ, (void*) psRGXKickCDMIN->pui32ClientUpdateValue, psRGXKickCDMIN->ui32ClientUpdateCount * sizeof(IMG_UINT32))
-				|| (OSCopyFromUser(NULL, ui32ClientUpdateValueInt, psRGXKickCDMIN->pui32ClientUpdateValue,
-				psRGXKickCDMIN->ui32ClientUpdateCount * sizeof(IMG_UINT32)) != PVRSRV_OK) )
+			if (psRGXKickCDMIN->ui32ClientUpdateCount * sizeof(IMG_UINT32) > 0)
 			{
-				psRGXKickCDMOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
+				if ( OSCopyFromUser(NULL, ui32ClientUpdateValueInt, psRGXKickCDMIN->pui32ClientUpdateValue, psRGXKickCDMIN->ui32ClientUpdateCount * sizeof(IMG_UINT32)) != PVRSRV_OK )
+				{
+					psRGXKickCDMOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
 
-				goto RGXKickCDM_exit;
+					goto RGXKickCDM_exit;
+				}
 			}
 	if (psRGXKickCDMIN->ui32ServerSyncCount != 0)
 	{
-		ui32ServerSyncFlagsInt = OSAllocMemNoStats(psRGXKickCDMIN->ui32ServerSyncCount * sizeof(IMG_UINT32));
-		if (!ui32ServerSyncFlagsInt)
-		{
-			psRGXKickCDMOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
-	
-			goto RGXKickCDM_exit;
-		}
+		ui32ServerSyncFlagsInt = (IMG_UINT32*)(((IMG_UINT8 *)pArrayArgsBuffer) + ui32NextOffset);
+		ui32NextOffset += psRGXKickCDMIN->ui32ServerSyncCount * sizeof(IMG_UINT32);
 	}
 
 			/* Copy the data over */
-			if ( !OSAccessOK(PVR_VERIFY_READ, (void*) psRGXKickCDMIN->pui32ServerSyncFlags, psRGXKickCDMIN->ui32ServerSyncCount * sizeof(IMG_UINT32))
-				|| (OSCopyFromUser(NULL, ui32ServerSyncFlagsInt, psRGXKickCDMIN->pui32ServerSyncFlags,
-				psRGXKickCDMIN->ui32ServerSyncCount * sizeof(IMG_UINT32)) != PVRSRV_OK) )
+			if (psRGXKickCDMIN->ui32ServerSyncCount * sizeof(IMG_UINT32) > 0)
 			{
-				psRGXKickCDMOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
+				if ( OSCopyFromUser(NULL, ui32ServerSyncFlagsInt, psRGXKickCDMIN->pui32ServerSyncFlags, psRGXKickCDMIN->ui32ServerSyncCount * sizeof(IMG_UINT32)) != PVRSRV_OK )
+				{
+					psRGXKickCDMOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
 
-				goto RGXKickCDM_exit;
+					goto RGXKickCDM_exit;
+				}
 			}
 	if (psRGXKickCDMIN->ui32ServerSyncCount != 0)
 	{
-		psServerSyncsInt = OSAllocMemNoStats(psRGXKickCDMIN->ui32ServerSyncCount * sizeof(SERVER_SYNC_PRIMITIVE *));
-		if (!psServerSyncsInt)
-		{
-			psRGXKickCDMOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
-	
-			goto RGXKickCDM_exit;
-		}
-		hServerSyncsInt2 = OSAllocMemNoStats(psRGXKickCDMIN->ui32ServerSyncCount * sizeof(IMG_HANDLE));
-		if (!hServerSyncsInt2)
-		{
-			psRGXKickCDMOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
-	
-			goto RGXKickCDM_exit;
-		}
+		psServerSyncsInt = (SERVER_SYNC_PRIMITIVE **)(((IMG_UINT8 *)pArrayArgsBuffer) + ui32NextOffset);
+		ui32NextOffset += psRGXKickCDMIN->ui32ServerSyncCount * sizeof(SERVER_SYNC_PRIMITIVE *);
+		hServerSyncsInt2 = (IMG_HANDLE *)(((IMG_UINT8 *)pArrayArgsBuffer) + ui32NextOffset); 
+		ui32NextOffset += psRGXKickCDMIN->ui32ServerSyncCount * sizeof(IMG_HANDLE);
 	}
 
 			/* Copy the data over */
-			if ( !OSAccessOK(PVR_VERIFY_READ, (void*) psRGXKickCDMIN->phServerSyncs, psRGXKickCDMIN->ui32ServerSyncCount * sizeof(IMG_HANDLE))
-				|| (OSCopyFromUser(NULL, hServerSyncsInt2, psRGXKickCDMIN->phServerSyncs,
-				psRGXKickCDMIN->ui32ServerSyncCount * sizeof(IMG_HANDLE)) != PVRSRV_OK) )
+			if (psRGXKickCDMIN->ui32ServerSyncCount * sizeof(IMG_HANDLE) > 0)
 			{
-				psRGXKickCDMOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
+				if ( OSCopyFromUser(NULL, hServerSyncsInt2, psRGXKickCDMIN->phServerSyncs, psRGXKickCDMIN->ui32ServerSyncCount * sizeof(IMG_HANDLE)) != PVRSRV_OK )
+				{
+					psRGXKickCDMOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
 
-				goto RGXKickCDM_exit;
+					goto RGXKickCDM_exit;
+				}
+			}
+	
+	{
+		uiUpdateFenceNameInt = (IMG_CHAR*)(((IMG_UINT8 *)pArrayArgsBuffer) + ui32NextOffset);
+		ui32NextOffset += 32 * sizeof(IMG_CHAR);
+	}
+
+			/* Copy the data over */
+			if (32 * sizeof(IMG_CHAR) > 0)
+			{
+				if ( OSCopyFromUser(NULL, uiUpdateFenceNameInt, psRGXKickCDMIN->puiUpdateFenceName, 32 * sizeof(IMG_CHAR)) != PVRSRV_OK )
+				{
+					psRGXKickCDMOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
+
+					goto RGXKickCDM_exit;
+				}
 			}
 	if (psRGXKickCDMIN->ui32CmdSize != 0)
 	{
-		psDMCmdInt = OSAllocMemNoStats(psRGXKickCDMIN->ui32CmdSize * sizeof(IMG_BYTE));
-		if (!psDMCmdInt)
-		{
-			psRGXKickCDMOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
-	
-			goto RGXKickCDM_exit;
-		}
+		psDMCmdInt = (IMG_BYTE*)(((IMG_UINT8 *)pArrayArgsBuffer) + ui32NextOffset);
+		ui32NextOffset += psRGXKickCDMIN->ui32CmdSize * sizeof(IMG_BYTE);
 	}
 
 			/* Copy the data over */
-			if ( !OSAccessOK(PVR_VERIFY_READ, (void*) psRGXKickCDMIN->psDMCmd, psRGXKickCDMIN->ui32CmdSize * sizeof(IMG_BYTE))
-				|| (OSCopyFromUser(NULL, psDMCmdInt, psRGXKickCDMIN->psDMCmd,
-				psRGXKickCDMIN->ui32CmdSize * sizeof(IMG_BYTE)) != PVRSRV_OK) )
+			if (psRGXKickCDMIN->ui32CmdSize * sizeof(IMG_BYTE) > 0)
 			{
-				psRGXKickCDMOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
+				if ( OSCopyFromUser(NULL, psDMCmdInt, psRGXKickCDMIN->psDMCmd, psRGXKickCDMIN->ui32CmdSize * sizeof(IMG_BYTE)) != PVRSRV_OK )
+				{
+					psRGXKickCDMOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
 
-				goto RGXKickCDM_exit;
+					goto RGXKickCDM_exit;
+				}
 			}
 
-#if defined(PDUMP)
-	PMRLock();
-#endif
+	/* Lock over handle lookup. */
+	LockHandle();
+
+
+
 
 
 				{
 					/* Look up the address from the handle */
 					psRGXKickCDMOUT->eError =
-						PVRSRVLookupHandle(psConnection->psHandleBase,
+						PVRSRVLookupHandleUnlocked(psConnection->psHandleBase,
 											(void **) &psComputeContextInt,
-											psRGXKickCDMIN->hComputeContext,
-											PVRSRV_HANDLE_TYPE_RGX_SERVER_COMPUTE_CONTEXT);
+											hComputeContext,
+											PVRSRV_HANDLE_TYPE_RGX_SERVER_COMPUTE_CONTEXT,
+											IMG_TRUE);
 					if(psRGXKickCDMOUT->eError != PVRSRV_OK)
 					{
-#if defined(PDUMP)
-						PMRUnlock();
-#endif
+						UnlockHandle();
 						goto RGXKickCDM_exit;
 					}
 				}
 
 
+
+
+
 	{
 		IMG_UINT32 i;
 
@@ -456,22 +612,24 @@
 				{
 					/* Look up the address from the handle */
 					psRGXKickCDMOUT->eError =
-						PVRSRVLookupHandle(psConnection->psHandleBase,
+						PVRSRVLookupHandleUnlocked(psConnection->psHandleBase,
 											(void **) &psClientFenceUFOSyncPrimBlockInt[i],
 											hClientFenceUFOSyncPrimBlockInt2[i],
-											PVRSRV_HANDLE_TYPE_SYNC_PRIMITIVE_BLOCK);
+											PVRSRV_HANDLE_TYPE_SYNC_PRIMITIVE_BLOCK,
+											IMG_TRUE);
 					if(psRGXKickCDMOUT->eError != PVRSRV_OK)
 					{
-#if defined(PDUMP)
-						PMRUnlock();
-#endif
+						UnlockHandle();
 						goto RGXKickCDM_exit;
 					}
 				}
-
 		}
 	}
 
+
+
+
+
 	{
 		IMG_UINT32 i;
 
@@ -480,22 +638,24 @@
 				{
 					/* Look up the address from the handle */
 					psRGXKickCDMOUT->eError =
-						PVRSRVLookupHandle(psConnection->psHandleBase,
+						PVRSRVLookupHandleUnlocked(psConnection->psHandleBase,
 											(void **) &psClientUpdateUFOSyncPrimBlockInt[i],
 											hClientUpdateUFOSyncPrimBlockInt2[i],
-											PVRSRV_HANDLE_TYPE_SYNC_PRIMITIVE_BLOCK);
+											PVRSRV_HANDLE_TYPE_SYNC_PRIMITIVE_BLOCK,
+											IMG_TRUE);
 					if(psRGXKickCDMOUT->eError != PVRSRV_OK)
 					{
-#if defined(PDUMP)
-						PMRUnlock();
-#endif
+						UnlockHandle();
 						goto RGXKickCDM_exit;
 					}
 				}
-
 		}
 	}
 
+
+
+
+
 	{
 		IMG_UINT32 i;
 
@@ -504,25 +664,26 @@
 				{
 					/* Look up the address from the handle */
 					psRGXKickCDMOUT->eError =
-						PVRSRVLookupHandle(psConnection->psHandleBase,
+						PVRSRVLookupHandleUnlocked(psConnection->psHandleBase,
 											(void **) &psServerSyncsInt[i],
 											hServerSyncsInt2[i],
-											PVRSRV_HANDLE_TYPE_SERVER_SYNC_PRIMITIVE);
+											PVRSRV_HANDLE_TYPE_SERVER_SYNC_PRIMITIVE,
+											IMG_TRUE);
 					if(psRGXKickCDMOUT->eError != PVRSRV_OK)
 					{
-#if defined(PDUMP)
-						PMRUnlock();
-#endif
+						UnlockHandle();
 						goto RGXKickCDM_exit;
 					}
 				}
-
 		}
 	}
+	/* Release now we have looked up handles. */
+	UnlockHandle();
 
 	psRGXKickCDMOUT->eError =
 		PVRSRVRGXKickCDMKM(
 					psComputeContextInt,
+					psRGXKickCDMIN->ui32ClientCacheOpSeqNum,
 					psRGXKickCDMIN->ui32ClientFenceCount,
 					psClientFenceUFOSyncPrimBlockInt,
 					ui32ClientFenceOffsetInt,
@@ -534,105 +695,238 @@
 					psRGXKickCDMIN->ui32ServerSyncCount,
 					ui32ServerSyncFlagsInt,
 					psServerSyncsInt,
+					psRGXKickCDMIN->i32CheckFenceFd,
+					psRGXKickCDMIN->i32UpdateTimelineFd,
+					&psRGXKickCDMOUT->i32UpdateFenceFd,
+					uiUpdateFenceNameInt,
 					psRGXKickCDMIN->ui32CmdSize,
 					psDMCmdInt,
-					psRGXKickCDMIN->bbPDumpContinuous,
-					psRGXKickCDMIN->ui32ExtJobRef,
-					psRGXKickCDMIN->ui32IntJobRef);
-#if defined(PDUMP)
-	PMRUnlock();
-#endif
+					psRGXKickCDMIN->ui32PDumpFlags,
+					psRGXKickCDMIN->ui32ExtJobRef);
 
 
 
 
 RGXKickCDM_exit:
-	if (psClientFenceUFOSyncPrimBlockInt)
-		OSFreeMemNoStats(psClientFenceUFOSyncPrimBlockInt);
+
+	/* Lock over handle lookup cleanup. */
+	LockHandle();
+
+
+
+
+
+
+				{
+					/* Unreference the previously looked up handle */
+						if(psComputeContextInt)
+						{
+							PVRSRVReleaseHandleUnlocked(psConnection->psHandleBase,
+											hComputeContext,
+											PVRSRV_HANDLE_TYPE_RGX_SERVER_COMPUTE_CONTEXT);
+						}
+				}
+
+
+
+
+
+
 	if (hClientFenceUFOSyncPrimBlockInt2)
-		OSFreeMemNoStats(hClientFenceUFOSyncPrimBlockInt2);
-	if (ui32ClientFenceOffsetInt)
-		OSFreeMemNoStats(ui32ClientFenceOffsetInt);
-	if (ui32ClientFenceValueInt)
-		OSFreeMemNoStats(ui32ClientFenceValueInt);
-	if (psClientUpdateUFOSyncPrimBlockInt)
-		OSFreeMemNoStats(psClientUpdateUFOSyncPrimBlockInt);
+	{
+		IMG_UINT32 i;
+
+		for (i=0;i<psRGXKickCDMIN->ui32ClientFenceCount;i++)
+		{
+				{
+					/* Unreference the previously looked up handle */
+						if(psClientFenceUFOSyncPrimBlockInt[i])
+						{
+							PVRSRVReleaseHandleUnlocked(psConnection->psHandleBase,
+											hClientFenceUFOSyncPrimBlockInt2[i],
+											PVRSRV_HANDLE_TYPE_SYNC_PRIMITIVE_BLOCK);
+						}
+				}
+		}
+	}
+
+
+
+
+
+
 	if (hClientUpdateUFOSyncPrimBlockInt2)
-		OSFreeMemNoStats(hClientUpdateUFOSyncPrimBlockInt2);
-	if (ui32ClientUpdateOffsetInt)
-		OSFreeMemNoStats(ui32ClientUpdateOffsetInt);
-	if (ui32ClientUpdateValueInt)
-		OSFreeMemNoStats(ui32ClientUpdateValueInt);
-	if (ui32ServerSyncFlagsInt)
-		OSFreeMemNoStats(ui32ServerSyncFlagsInt);
-	if (psServerSyncsInt)
-		OSFreeMemNoStats(psServerSyncsInt);
+	{
+		IMG_UINT32 i;
+
+		for (i=0;i<psRGXKickCDMIN->ui32ClientUpdateCount;i++)
+		{
+				{
+					/* Unreference the previously looked up handle */
+						if(psClientUpdateUFOSyncPrimBlockInt[i])
+						{
+							PVRSRVReleaseHandleUnlocked(psConnection->psHandleBase,
+											hClientUpdateUFOSyncPrimBlockInt2[i],
+											PVRSRV_HANDLE_TYPE_SYNC_PRIMITIVE_BLOCK);
+						}
+				}
+		}
+	}
+
+
+
+
+
+
 	if (hServerSyncsInt2)
-		OSFreeMemNoStats(hServerSyncsInt2);
-	if (psDMCmdInt)
-		OSFreeMemNoStats(psDMCmdInt);
+	{
+		IMG_UINT32 i;
+
+		for (i=0;i<psRGXKickCDMIN->ui32ServerSyncCount;i++)
+		{
+				{
+					/* Unreference the previously looked up handle */
+						if(psServerSyncsInt[i])
+						{
+							PVRSRVReleaseHandleUnlocked(psConnection->psHandleBase,
+											hServerSyncsInt2[i],
+											PVRSRV_HANDLE_TYPE_SERVER_SYNC_PRIMITIVE);
+						}
+				}
+		}
+	}
+	/* Release now we have cleaned up look up handles. */
+	UnlockHandle();
+
+	/* Allocated space should be equal to the last updated offset */
+	PVR_ASSERT(ui32BufferSize == ui32NextOffset);
+
+#if defined(INTEGRITY_OS)
+	if(pArrayArgsBuffer)
+#else
+	if(!bHaveEnoughSpace && pArrayArgsBuffer)
+#endif
+		OSFreeMemNoStats(pArrayArgsBuffer);
+
 
 	return 0;
 }
 
+
 static IMG_INT
 PVRSRVBridgeRGXFlushComputeData(IMG_UINT32 ui32DispatchTableEntry,
 					  PVRSRV_BRIDGE_IN_RGXFLUSHCOMPUTEDATA *psRGXFlushComputeDataIN,
 					  PVRSRV_BRIDGE_OUT_RGXFLUSHCOMPUTEDATA *psRGXFlushComputeDataOUT,
 					 CONNECTION_DATA *psConnection)
 {
+	IMG_HANDLE hComputeContext = psRGXFlushComputeDataIN->hComputeContext;
 	RGX_SERVER_COMPUTE_CONTEXT * psComputeContextInt = NULL;
 
 
+	{
+		PVRSRV_DEVICE_NODE *psDeviceNode = OSGetDevData(psConnection);
+
+		/* Check that device supports the required feature */
+		if ((psDeviceNode->pfnCheckDeviceFeature) &&
+			!psDeviceNode->pfnCheckDeviceFeature(psDeviceNode, RGX_FEATURE_COMPUTE_BIT_MASK))
+		{
+			psRGXFlushComputeDataOUT->eError = PVRSRV_ERROR_NOT_SUPPORTED;
+
+			goto RGXFlushComputeData_exit;
+		}
+	}
 
 
 
-#if defined(PDUMP)
-	PMRLock();
-#endif
+
+
+	/* Lock over handle lookup. */
+	LockHandle();
+
+
+
 
 
 				{
 					/* Look up the address from the handle */
 					psRGXFlushComputeDataOUT->eError =
-						PVRSRVLookupHandle(psConnection->psHandleBase,
+						PVRSRVLookupHandleUnlocked(psConnection->psHandleBase,
 											(void **) &psComputeContextInt,
-											psRGXFlushComputeDataIN->hComputeContext,
-											PVRSRV_HANDLE_TYPE_RGX_SERVER_COMPUTE_CONTEXT);
+											hComputeContext,
+											PVRSRV_HANDLE_TYPE_RGX_SERVER_COMPUTE_CONTEXT,
+											IMG_TRUE);
 					if(psRGXFlushComputeDataOUT->eError != PVRSRV_OK)
 					{
-#if defined(PDUMP)
-						PMRUnlock();
-#endif
+						UnlockHandle();
 						goto RGXFlushComputeData_exit;
 					}
 				}
-
+	/* Release now we have looked up handles. */
+	UnlockHandle();
 
 	psRGXFlushComputeDataOUT->eError =
 		PVRSRVRGXFlushComputeDataKM(
 					psComputeContextInt);
-#if defined(PDUMP)
-	PMRUnlock();
-#endif
 
 
 
 
 RGXFlushComputeData_exit:
 
+	/* Lock over handle lookup cleanup. */
+	LockHandle();
+
+
+
+
+
+
+				{
+					/* Unreference the previously looked up handle */
+						if(psComputeContextInt)
+						{
+							PVRSRVReleaseHandleUnlocked(psConnection->psHandleBase,
+											hComputeContext,
+											PVRSRV_HANDLE_TYPE_RGX_SERVER_COMPUTE_CONTEXT);
+						}
+				}
+	/* Release now we have cleaned up look up handles. */
+	UnlockHandle();
+
+
 	return 0;
 }
 
+
 static IMG_INT
 PVRSRVBridgeRGXSetComputeContextPriority(IMG_UINT32 ui32DispatchTableEntry,
 					  PVRSRV_BRIDGE_IN_RGXSETCOMPUTECONTEXTPRIORITY *psRGXSetComputeContextPriorityIN,
 					  PVRSRV_BRIDGE_OUT_RGXSETCOMPUTECONTEXTPRIORITY *psRGXSetComputeContextPriorityOUT,
 					 CONNECTION_DATA *psConnection)
 {
+	IMG_HANDLE hComputeContext = psRGXSetComputeContextPriorityIN->hComputeContext;
 	RGX_SERVER_COMPUTE_CONTEXT * psComputeContextInt = NULL;
 
 
+	{
+		PVRSRV_DEVICE_NODE *psDeviceNode = OSGetDevData(psConnection);
+
+		/* Check that device supports the required feature */
+		if ((psDeviceNode->pfnCheckDeviceFeature) &&
+			!psDeviceNode->pfnCheckDeviceFeature(psDeviceNode, RGX_FEATURE_COMPUTE_BIT_MASK))
+		{
+			psRGXSetComputeContextPriorityOUT->eError = PVRSRV_ERROR_NOT_SUPPORTED;
+
+			goto RGXSetComputeContextPriority_exit;
+		}
+	}
+
+
+
+
+
+	/* Lock over handle lookup. */
+	LockHandle();
 
 
 
@@ -641,16 +935,19 @@
 				{
 					/* Look up the address from the handle */
 					psRGXSetComputeContextPriorityOUT->eError =
-						PVRSRVLookupHandle(psConnection->psHandleBase,
+						PVRSRVLookupHandleUnlocked(psConnection->psHandleBase,
 											(void **) &psComputeContextInt,
-											psRGXSetComputeContextPriorityIN->hComputeContext,
-											PVRSRV_HANDLE_TYPE_RGX_SERVER_COMPUTE_CONTEXT);
+											hComputeContext,
+											PVRSRV_HANDLE_TYPE_RGX_SERVER_COMPUTE_CONTEXT,
+											IMG_TRUE);
 					if(psRGXSetComputeContextPriorityOUT->eError != PVRSRV_OK)
 					{
+						UnlockHandle();
 						goto RGXSetComputeContextPriority_exit;
 					}
 				}
-
+	/* Release now we have looked up handles. */
+	UnlockHandle();
 
 	psRGXSetComputeContextPriorityOUT->eError =
 		PVRSRVRGXSetComputeContextPriorityKM(psConnection, OSGetDevData(psConnection),
@@ -662,18 +959,60 @@
 
 RGXSetComputeContextPriority_exit:
 
+	/* Lock over handle lookup cleanup. */
+	LockHandle();
+
+
+
+
+
+
+				{
+					/* Unreference the previously looked up handle */
+						if(psComputeContextInt)
+						{
+							PVRSRVReleaseHandleUnlocked(psConnection->psHandleBase,
+											hComputeContext,
+											PVRSRV_HANDLE_TYPE_RGX_SERVER_COMPUTE_CONTEXT);
+						}
+				}
+	/* Release now we have cleaned up look up handles. */
+	UnlockHandle();
+
+
 	return 0;
 }
 
+
 static IMG_INT
 PVRSRVBridgeRGXGetLastComputeContextResetReason(IMG_UINT32 ui32DispatchTableEntry,
 					  PVRSRV_BRIDGE_IN_RGXGETLASTCOMPUTECONTEXTRESETREASON *psRGXGetLastComputeContextResetReasonIN,
 					  PVRSRV_BRIDGE_OUT_RGXGETLASTCOMPUTECONTEXTRESETREASON *psRGXGetLastComputeContextResetReasonOUT,
 					 CONNECTION_DATA *psConnection)
 {
+	IMG_HANDLE hComputeContext = psRGXGetLastComputeContextResetReasonIN->hComputeContext;
 	RGX_SERVER_COMPUTE_CONTEXT * psComputeContextInt = NULL;
 
 
+	{
+		PVRSRV_DEVICE_NODE *psDeviceNode = OSGetDevData(psConnection);
+
+		/* Check that device supports the required feature */
+		if ((psDeviceNode->pfnCheckDeviceFeature) &&
+			!psDeviceNode->pfnCheckDeviceFeature(psDeviceNode, RGX_FEATURE_COMPUTE_BIT_MASK))
+		{
+			psRGXGetLastComputeContextResetReasonOUT->eError = PVRSRV_ERROR_NOT_SUPPORTED;
+
+			goto RGXGetLastComputeContextResetReason_exit;
+		}
+	}
+
+
+
+
+
+	/* Lock over handle lookup. */
+	LockHandle();
 
 
 
@@ -682,16 +1021,19 @@
 				{
 					/* Look up the address from the handle */
 					psRGXGetLastComputeContextResetReasonOUT->eError =
-						PVRSRVLookupHandle(psConnection->psHandleBase,
+						PVRSRVLookupHandleUnlocked(psConnection->psHandleBase,
 											(void **) &psComputeContextInt,
-											psRGXGetLastComputeContextResetReasonIN->hComputeContext,
-											PVRSRV_HANDLE_TYPE_RGX_SERVER_COMPUTE_CONTEXT);
+											hComputeContext,
+											PVRSRV_HANDLE_TYPE_RGX_SERVER_COMPUTE_CONTEXT,
+											IMG_TRUE);
 					if(psRGXGetLastComputeContextResetReasonOUT->eError != PVRSRV_OK)
 					{
+						UnlockHandle();
 						goto RGXGetLastComputeContextResetReason_exit;
 					}
 				}
-
+	/* Release now we have looked up handles. */
+	UnlockHandle();
 
 	psRGXGetLastComputeContextResetReasonOUT->eError =
 		PVRSRVRGXGetLastComputeContextResetReasonKM(
@@ -704,10 +1046,117 @@
 
 RGXGetLastComputeContextResetReason_exit:
 
+	/* Lock over handle lookup cleanup. */
+	LockHandle();
+
+
+
+
+
+
+				{
+					/* Unreference the previously looked up handle */
+						if(psComputeContextInt)
+						{
+							PVRSRVReleaseHandleUnlocked(psConnection->psHandleBase,
+											hComputeContext,
+											PVRSRV_HANDLE_TYPE_RGX_SERVER_COMPUTE_CONTEXT);
+						}
+				}
+	/* Release now we have cleaned up look up handles. */
+	UnlockHandle();
+
+
 	return 0;
 }
 
 
+static IMG_INT
+PVRSRVBridgeRGXNotifyComputeWriteOffsetUpdate(IMG_UINT32 ui32DispatchTableEntry,
+					  PVRSRV_BRIDGE_IN_RGXNOTIFYCOMPUTEWRITEOFFSETUPDATE *psRGXNotifyComputeWriteOffsetUpdateIN,
+					  PVRSRV_BRIDGE_OUT_RGXNOTIFYCOMPUTEWRITEOFFSETUPDATE *psRGXNotifyComputeWriteOffsetUpdateOUT,
+					 CONNECTION_DATA *psConnection)
+{
+	IMG_HANDLE hComputeContext = psRGXNotifyComputeWriteOffsetUpdateIN->hComputeContext;
+	RGX_SERVER_COMPUTE_CONTEXT * psComputeContextInt = NULL;
+
+
+	{
+		PVRSRV_DEVICE_NODE *psDeviceNode = OSGetDevData(psConnection);
+
+		/* Check that device supports the required feature */
+		if ((psDeviceNode->pfnCheckDeviceFeature) &&
+			!psDeviceNode->pfnCheckDeviceFeature(psDeviceNode, RGX_FEATURE_COMPUTE_BIT_MASK))
+		{
+			psRGXNotifyComputeWriteOffsetUpdateOUT->eError = PVRSRV_ERROR_NOT_SUPPORTED;
+
+			goto RGXNotifyComputeWriteOffsetUpdate_exit;
+		}
+	}
+
+
+
+
+
+	/* Lock over handle lookup. */
+	LockHandle();
+
+
+
+
+
+				{
+					/* Look up the address from the handle */
+					psRGXNotifyComputeWriteOffsetUpdateOUT->eError =
+						PVRSRVLookupHandleUnlocked(psConnection->psHandleBase,
+											(void **) &psComputeContextInt,
+											hComputeContext,
+											PVRSRV_HANDLE_TYPE_RGX_SERVER_COMPUTE_CONTEXT,
+											IMG_TRUE);
+					if(psRGXNotifyComputeWriteOffsetUpdateOUT->eError != PVRSRV_OK)
+					{
+						UnlockHandle();
+						goto RGXNotifyComputeWriteOffsetUpdate_exit;
+					}
+				}
+	/* Release now we have looked up handles. */
+	UnlockHandle();
+
+	psRGXNotifyComputeWriteOffsetUpdateOUT->eError =
+		PVRSRVRGXNotifyComputeWriteOffsetUpdateKM(
+					psComputeContextInt);
+
+
+
+
+RGXNotifyComputeWriteOffsetUpdate_exit:
+
+	/* Lock over handle lookup cleanup. */
+	LockHandle();
+
+
+
+
+
+
+				{
+					/* Unreference the previously looked up handle */
+						if(psComputeContextInt)
+						{
+							PVRSRVReleaseHandleUnlocked(psConnection->psHandleBase,
+											hComputeContext,
+											PVRSRV_HANDLE_TYPE_RGX_SERVER_COMPUTE_CONTEXT);
+						}
+				}
+	/* Release now we have cleaned up look up handles. */
+	UnlockHandle();
+
+
+	return 0;
+}
+
+
+
 
 /* *************************************************************************** 
  * Server bridge dispatch related glue 
@@ -742,6 +1191,9 @@
 	SetDispatchTableEntry(PVRSRV_BRIDGE_RGXCMP, PVRSRV_BRIDGE_RGXCMP_RGXGETLASTCOMPUTECONTEXTRESETREASON, PVRSRVBridgeRGXGetLastComputeContextResetReason,
 					NULL, bUseLock);
 
+	SetDispatchTableEntry(PVRSRV_BRIDGE_RGXCMP, PVRSRV_BRIDGE_RGXCMP_RGXNOTIFYCOMPUTEWRITEOFFSETUPDATE, PVRSRVBridgeRGXNotifyComputeWriteOffsetUpdate,
+					NULL, bUseLock);
+
 
 	return PVRSRV_OK;
 }
@@ -753,4 +1205,3 @@
 {
 	return PVRSRV_OK;
 }
-
diff --git a/drivers/staging/imgtec/rogue/generated/rgxhwperf_bridge/common_rgxhwperf_bridge.h b/drivers/staging/imgtec/rogue/generated/rgxhwperf_bridge/common_rgxhwperf_bridge.h
index f8ec275..2b96a84 100644
--- a/drivers/staging/imgtec/rogue/generated/rgxhwperf_bridge/common_rgxhwperf_bridge.h
+++ b/drivers/staging/imgtec/rogue/generated/rgxhwperf_bridge/common_rgxhwperf_bridge.h
@@ -2,8 +2,8 @@
 @File
 @Title          Common bridge header for rgxhwperf
 @Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
-@Description    Declares common defines and structures that are used by both
-                the client and sever side of the bridge for rgxhwperf
+@Description    Declares common defines and structures used by both the client
+                and server side of the bridge for rgxhwperf
 @License        Dual MIT/GPLv2
 
 The contents of this file are subject to the MIT license as set out below.
@@ -45,6 +45,8 @@
 #ifndef COMMON_RGXHWPERF_BRIDGE_H
 #define COMMON_RGXHWPERF_BRIDGE_H
 
+#include <powervr/mem_types.h>
+
 #include "img_types.h"
 #include "pvrsrv_error.h"
 
diff --git a/drivers/staging/imgtec/rogue/generated/rgxhwperf_bridge/server_rgxhwperf_bridge.c b/drivers/staging/imgtec/rogue/generated/rgxhwperf_bridge/server_rgxhwperf_bridge.c
index fc74f10..f8becba 100644
--- a/drivers/staging/imgtec/rogue/generated/rgxhwperf_bridge/server_rgxhwperf_bridge.c
+++ b/drivers/staging/imgtec/rogue/generated/rgxhwperf_bridge/server_rgxhwperf_bridge.c
@@ -64,6 +64,8 @@
 
 
 
+
+
 /* ***************************************************************************
  * Server-side bridge entry points
  */
@@ -81,6 +83,7 @@
 
 
 
+
 	psRGXCtrlHWPerfOUT->eError =
 		PVRSRVRGXCtrlHWPerfKM(psConnection, OSGetDevData(psConnection),
 					psRGXCtrlHWPerfIN->ui32StreamId,
@@ -91,9 +94,13 @@
 
 
 
+
+
+
 	return 0;
 }
 
+
 static IMG_INT
 PVRSRVBridgeRGXConfigEnableHWPerfCounters(IMG_UINT32 ui32DispatchTableEntry,
 					  PVRSRV_BRIDGE_IN_RGXCONFIGENABLEHWPERFCOUNTERS *psRGXConfigEnableHWPerfCountersIN,
@@ -102,32 +109,65 @@
 {
 	RGX_HWPERF_CONFIG_CNTBLK *psBlockConfigsInt = NULL;
 
+	IMG_UINT32 ui32NextOffset = 0;
+	IMG_BYTE   *pArrayArgsBuffer = NULL;
+#if !defined(INTEGRITY_OS)
+	IMG_BOOL bHaveEnoughSpace = IMG_FALSE;
+#endif
+
+	IMG_UINT32 ui32BufferSize = 
+			(psRGXConfigEnableHWPerfCountersIN->ui32ArrayLen * sizeof(RGX_HWPERF_CONFIG_CNTBLK)) +
+			0;
 
 
 
-	if (psRGXConfigEnableHWPerfCountersIN->ui32ArrayLen != 0)
+
+
+	if (ui32BufferSize != 0)
 	{
-		psBlockConfigsInt = OSAllocMemNoStats(psRGXConfigEnableHWPerfCountersIN->ui32ArrayLen * sizeof(RGX_HWPERF_CONFIG_CNTBLK));
-		if (!psBlockConfigsInt)
+#if !defined(INTEGRITY_OS)
+		/* Try to use remainder of input buffer for copies if possible, word-aligned for safety. */
+		IMG_UINT32 ui32InBufferOffset = PVR_ALIGN(sizeof(*psRGXConfigEnableHWPerfCountersIN), sizeof(unsigned long));
+		IMG_UINT32 ui32InBufferExcessSize = ui32InBufferOffset >= PVRSRV_MAX_BRIDGE_IN_SIZE ? 0 :
+			PVRSRV_MAX_BRIDGE_IN_SIZE - ui32InBufferOffset;
+
+		bHaveEnoughSpace = ui32BufferSize <= ui32InBufferExcessSize;
+		if (bHaveEnoughSpace)
 		{
-			psRGXConfigEnableHWPerfCountersOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
-	
-			goto RGXConfigEnableHWPerfCounters_exit;
+			IMG_BYTE *pInputBuffer = (IMG_BYTE *)psRGXConfigEnableHWPerfCountersIN;
+
+			pArrayArgsBuffer = &pInputBuffer[ui32InBufferOffset];		}
+		else
+#endif
+		{
+			pArrayArgsBuffer = OSAllocMemNoStats(ui32BufferSize);
+
+			if(!pArrayArgsBuffer)
+			{
+				psRGXConfigEnableHWPerfCountersOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
+				goto RGXConfigEnableHWPerfCounters_exit;
+			}
 		}
 	}
 
+	if (psRGXConfigEnableHWPerfCountersIN->ui32ArrayLen != 0)
+	{
+		psBlockConfigsInt = (RGX_HWPERF_CONFIG_CNTBLK*)(((IMG_UINT8 *)pArrayArgsBuffer) + ui32NextOffset);
+		ui32NextOffset += psRGXConfigEnableHWPerfCountersIN->ui32ArrayLen * sizeof(RGX_HWPERF_CONFIG_CNTBLK);
+	}
+
 			/* Copy the data over */
-			if ( !OSAccessOK(PVR_VERIFY_READ, (void*) psRGXConfigEnableHWPerfCountersIN->psBlockConfigs, psRGXConfigEnableHWPerfCountersIN->ui32ArrayLen * sizeof(RGX_HWPERF_CONFIG_CNTBLK))
-				|| (OSCopyFromUser(NULL, psBlockConfigsInt, psRGXConfigEnableHWPerfCountersIN->psBlockConfigs,
-				psRGXConfigEnableHWPerfCountersIN->ui32ArrayLen * sizeof(RGX_HWPERF_CONFIG_CNTBLK)) != PVRSRV_OK) )
+			if (psRGXConfigEnableHWPerfCountersIN->ui32ArrayLen * sizeof(RGX_HWPERF_CONFIG_CNTBLK) > 0)
 			{
-				psRGXConfigEnableHWPerfCountersOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
+				if ( OSCopyFromUser(NULL, psBlockConfigsInt, psRGXConfigEnableHWPerfCountersIN->psBlockConfigs, psRGXConfigEnableHWPerfCountersIN->ui32ArrayLen * sizeof(RGX_HWPERF_CONFIG_CNTBLK)) != PVRSRV_OK )
+				{
+					psRGXConfigEnableHWPerfCountersOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
 
-				goto RGXConfigEnableHWPerfCounters_exit;
+					goto RGXConfigEnableHWPerfCounters_exit;
+				}
 			}
 
 
-
 	psRGXConfigEnableHWPerfCountersOUT->eError =
 		PVRSRVRGXConfigEnableHWPerfCountersKM(psConnection, OSGetDevData(psConnection),
 					psRGXConfigEnableHWPerfCountersIN->ui32ArrayLen,
@@ -137,12 +177,24 @@
 
 
 RGXConfigEnableHWPerfCounters_exit:
-	if (psBlockConfigsInt)
-		OSFreeMemNoStats(psBlockConfigsInt);
+
+
+
+	/* Allocated space should be equal to the last updated offset */
+	PVR_ASSERT(ui32BufferSize == ui32NextOffset);
+
+#if defined(INTEGRITY_OS)
+	if(pArrayArgsBuffer)
+#else
+	if(!bHaveEnoughSpace && pArrayArgsBuffer)
+#endif
+		OSFreeMemNoStats(pArrayArgsBuffer);
+
 
 	return 0;
 }
 
+
 static IMG_INT
 PVRSRVBridgeRGXCtrlHWPerfCounters(IMG_UINT32 ui32DispatchTableEntry,
 					  PVRSRV_BRIDGE_IN_RGXCTRLHWPERFCOUNTERS *psRGXCtrlHWPerfCountersIN,
@@ -151,32 +203,65 @@
 {
 	IMG_UINT16 *ui16BlockIDsInt = NULL;
 
+	IMG_UINT32 ui32NextOffset = 0;
+	IMG_BYTE   *pArrayArgsBuffer = NULL;
+#if !defined(INTEGRITY_OS)
+	IMG_BOOL bHaveEnoughSpace = IMG_FALSE;
+#endif
+
+	IMG_UINT32 ui32BufferSize = 
+			(psRGXCtrlHWPerfCountersIN->ui32ArrayLen * sizeof(IMG_UINT16)) +
+			0;
 
 
 
-	if (psRGXCtrlHWPerfCountersIN->ui32ArrayLen != 0)
+
+
+	if (ui32BufferSize != 0)
 	{
-		ui16BlockIDsInt = OSAllocMemNoStats(psRGXCtrlHWPerfCountersIN->ui32ArrayLen * sizeof(IMG_UINT16));
-		if (!ui16BlockIDsInt)
+#if !defined(INTEGRITY_OS)
+		/* Try to use remainder of input buffer for copies if possible, word-aligned for safety. */
+		IMG_UINT32 ui32InBufferOffset = PVR_ALIGN(sizeof(*psRGXCtrlHWPerfCountersIN), sizeof(unsigned long));
+		IMG_UINT32 ui32InBufferExcessSize = ui32InBufferOffset >= PVRSRV_MAX_BRIDGE_IN_SIZE ? 0 :
+			PVRSRV_MAX_BRIDGE_IN_SIZE - ui32InBufferOffset;
+
+		bHaveEnoughSpace = ui32BufferSize <= ui32InBufferExcessSize;
+		if (bHaveEnoughSpace)
 		{
-			psRGXCtrlHWPerfCountersOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
-	
-			goto RGXCtrlHWPerfCounters_exit;
+			IMG_BYTE *pInputBuffer = (IMG_BYTE *)psRGXCtrlHWPerfCountersIN;
+
+			pArrayArgsBuffer = &pInputBuffer[ui32InBufferOffset];		}
+		else
+#endif
+		{
+			pArrayArgsBuffer = OSAllocMemNoStats(ui32BufferSize);
+
+			if(!pArrayArgsBuffer)
+			{
+				psRGXCtrlHWPerfCountersOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
+				goto RGXCtrlHWPerfCounters_exit;
+			}
 		}
 	}
 
+	if (psRGXCtrlHWPerfCountersIN->ui32ArrayLen != 0)
+	{
+		ui16BlockIDsInt = (IMG_UINT16*)(((IMG_UINT8 *)pArrayArgsBuffer) + ui32NextOffset);
+		ui32NextOffset += psRGXCtrlHWPerfCountersIN->ui32ArrayLen * sizeof(IMG_UINT16);
+	}
+
 			/* Copy the data over */
-			if ( !OSAccessOK(PVR_VERIFY_READ, (void*) psRGXCtrlHWPerfCountersIN->pui16BlockIDs, psRGXCtrlHWPerfCountersIN->ui32ArrayLen * sizeof(IMG_UINT16))
-				|| (OSCopyFromUser(NULL, ui16BlockIDsInt, psRGXCtrlHWPerfCountersIN->pui16BlockIDs,
-				psRGXCtrlHWPerfCountersIN->ui32ArrayLen * sizeof(IMG_UINT16)) != PVRSRV_OK) )
+			if (psRGXCtrlHWPerfCountersIN->ui32ArrayLen * sizeof(IMG_UINT16) > 0)
 			{
-				psRGXCtrlHWPerfCountersOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
+				if ( OSCopyFromUser(NULL, ui16BlockIDsInt, psRGXCtrlHWPerfCountersIN->pui16BlockIDs, psRGXCtrlHWPerfCountersIN->ui32ArrayLen * sizeof(IMG_UINT16)) != PVRSRV_OK )
+				{
+					psRGXCtrlHWPerfCountersOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
 
-				goto RGXCtrlHWPerfCounters_exit;
+					goto RGXCtrlHWPerfCounters_exit;
+				}
 			}
 
 
-
 	psRGXCtrlHWPerfCountersOUT->eError =
 		PVRSRVRGXCtrlHWPerfCountersKM(psConnection, OSGetDevData(psConnection),
 					psRGXCtrlHWPerfCountersIN->bEnable,
@@ -187,12 +272,24 @@
 
 
 RGXCtrlHWPerfCounters_exit:
-	if (ui16BlockIDsInt)
-		OSFreeMemNoStats(ui16BlockIDsInt);
+
+
+
+	/* Allocated space should be equal to the last updated offset */
+	PVR_ASSERT(ui32BufferSize == ui32NextOffset);
+
+#if defined(INTEGRITY_OS)
+	if(pArrayArgsBuffer)
+#else
+	if(!bHaveEnoughSpace && pArrayArgsBuffer)
+#endif
+		OSFreeMemNoStats(pArrayArgsBuffer);
+
 
 	return 0;
 }
 
+
 static IMG_INT
 PVRSRVBridgeRGXConfigCustomCounters(IMG_UINT32 ui32DispatchTableEntry,
 					  PVRSRV_BRIDGE_IN_RGXCONFIGCUSTOMCOUNTERS *psRGXConfigCustomCountersIN,
@@ -201,32 +298,65 @@
 {
 	IMG_UINT32 *ui32CustomCounterIDsInt = NULL;
 
+	IMG_UINT32 ui32NextOffset = 0;
+	IMG_BYTE   *pArrayArgsBuffer = NULL;
+#if !defined(INTEGRITY_OS)
+	IMG_BOOL bHaveEnoughSpace = IMG_FALSE;
+#endif
+
+	IMG_UINT32 ui32BufferSize = 
+			(psRGXConfigCustomCountersIN->ui16NumCustomCounters * sizeof(IMG_UINT32)) +
+			0;
 
 
 
-	if (psRGXConfigCustomCountersIN->ui16NumCustomCounters != 0)
+
+
+	if (ui32BufferSize != 0)
 	{
-		ui32CustomCounterIDsInt = OSAllocMemNoStats(psRGXConfigCustomCountersIN->ui16NumCustomCounters * sizeof(IMG_UINT32));
-		if (!ui32CustomCounterIDsInt)
+#if !defined(INTEGRITY_OS)
+		/* Try to use remainder of input buffer for copies if possible, word-aligned for safety. */
+		IMG_UINT32 ui32InBufferOffset = PVR_ALIGN(sizeof(*psRGXConfigCustomCountersIN), sizeof(unsigned long));
+		IMG_UINT32 ui32InBufferExcessSize = ui32InBufferOffset >= PVRSRV_MAX_BRIDGE_IN_SIZE ? 0 :
+			PVRSRV_MAX_BRIDGE_IN_SIZE - ui32InBufferOffset;
+
+		bHaveEnoughSpace = ui32BufferSize <= ui32InBufferExcessSize;
+		if (bHaveEnoughSpace)
 		{
-			psRGXConfigCustomCountersOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
-	
-			goto RGXConfigCustomCounters_exit;
+			IMG_BYTE *pInputBuffer = (IMG_BYTE *)psRGXConfigCustomCountersIN;
+
+			pArrayArgsBuffer = &pInputBuffer[ui32InBufferOffset];		}
+		else
+#endif
+		{
+			pArrayArgsBuffer = OSAllocMemNoStats(ui32BufferSize);
+
+			if(!pArrayArgsBuffer)
+			{
+				psRGXConfigCustomCountersOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
+				goto RGXConfigCustomCounters_exit;
+			}
 		}
 	}
 
+	if (psRGXConfigCustomCountersIN->ui16NumCustomCounters != 0)
+	{
+		ui32CustomCounterIDsInt = (IMG_UINT32*)(((IMG_UINT8 *)pArrayArgsBuffer) + ui32NextOffset);
+		ui32NextOffset += psRGXConfigCustomCountersIN->ui16NumCustomCounters * sizeof(IMG_UINT32);
+	}
+
 			/* Copy the data over */
-			if ( !OSAccessOK(PVR_VERIFY_READ, (void*) psRGXConfigCustomCountersIN->pui32CustomCounterIDs, psRGXConfigCustomCountersIN->ui16NumCustomCounters * sizeof(IMG_UINT32))
-				|| (OSCopyFromUser(NULL, ui32CustomCounterIDsInt, psRGXConfigCustomCountersIN->pui32CustomCounterIDs,
-				psRGXConfigCustomCountersIN->ui16NumCustomCounters * sizeof(IMG_UINT32)) != PVRSRV_OK) )
+			if (psRGXConfigCustomCountersIN->ui16NumCustomCounters * sizeof(IMG_UINT32) > 0)
 			{
-				psRGXConfigCustomCountersOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
+				if ( OSCopyFromUser(NULL, ui32CustomCounterIDsInt, psRGXConfigCustomCountersIN->pui32CustomCounterIDs, psRGXConfigCustomCountersIN->ui16NumCustomCounters * sizeof(IMG_UINT32)) != PVRSRV_OK )
+				{
+					psRGXConfigCustomCountersOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
 
-				goto RGXConfigCustomCounters_exit;
+					goto RGXConfigCustomCounters_exit;
+				}
 			}
 
 
-
 	psRGXConfigCustomCountersOUT->eError =
 		PVRSRVRGXConfigCustomCountersKM(psConnection, OSGetDevData(psConnection),
 					psRGXConfigCustomCountersIN->ui16CustomBlockID,
@@ -237,14 +367,26 @@
 
 
 RGXConfigCustomCounters_exit:
-	if (ui32CustomCounterIDsInt)
-		OSFreeMemNoStats(ui32CustomCounterIDsInt);
+
+
+
+	/* Allocated space should be equal to the last updated offset */
+	PVR_ASSERT(ui32BufferSize == ui32NextOffset);
+
+#if defined(INTEGRITY_OS)
+	if(pArrayArgsBuffer)
+#else
+	if(!bHaveEnoughSpace && pArrayArgsBuffer)
+#endif
+		OSFreeMemNoStats(pArrayArgsBuffer);
+
 
 	return 0;
 }
 
 
 
+
 /* *************************************************************************** 
  * Server bridge dispatch related glue 
  */
@@ -283,4 +425,3 @@
 {
 	return PVRSRV_OK;
 }
-
diff --git a/drivers/staging/imgtec/rogue/generated/rgxinit_bridge/client_rgxinit_bridge.h b/drivers/staging/imgtec/rogue/generated/rgxinit_bridge/client_rgxinit_bridge.h
index 2e7bdd5..7a90352 100644
--- a/drivers/staging/imgtec/rogue/generated/rgxinit_bridge/client_rgxinit_bridge.h
+++ b/drivers/staging/imgtec/rogue/generated/rgxinit_bridge/client_rgxinit_bridge.h
@@ -72,7 +72,7 @@
 							     IMG_UINT32 ui32SignatureChecksBufSize,
 							     IMG_UINT32 ui32HWPerfFWBufSizeKB,
 							     IMG_UINT64 ui64HWPerfFilter,
-							     IMG_UINT32 ui32RGXFWAlignChecksSize,
+							     IMG_UINT32 ui32RGXFWAlignChecksArrLength,
 							     IMG_UINT32 *pui32RGXFWAlignChecks,
 							     IMG_UINT32 ui32ConfigFlags,
 							     IMG_UINT32 ui32LogType,
@@ -85,15 +85,12 @@
 							     RGX_RD_POWER_ISLAND_CONF eRGXRDPowerIslandConf,
 							     FW_PERF_CONF eFirmwarePerf);
 
-IMG_INTERNAL PVRSRV_ERROR IMG_CALLCONV BridgeRGXInitFinaliseFWImage(IMG_HANDLE hBridge,
-								    IMG_HANDLE hFWImagePMRImport,
-								    IMG_UINT64 ui64FWImgLen);
+IMG_INTERNAL PVRSRV_ERROR IMG_CALLCONV BridgeRGXInitFinaliseFWImage(IMG_HANDLE hBridge);
 
 IMG_INTERNAL PVRSRV_ERROR IMG_CALLCONV BridgeRGXInitDevPart2(IMG_HANDLE hBridge,
 							     RGX_INIT_COMMAND *psDbgScript,
-							     RGX_INIT_COMMAND *psDbgBusScript,
-							     RGX_INIT_COMMAND *psDeinitScript,
 							     IMG_UINT32 ui32DeviceFlags,
+							     IMG_UINT32 ui32HWPerfHostBufSize,
 							     IMG_UINT32 ui32HWPerfHostFilter,
 							     IMG_UINT32 ui32RGXActivePMConf,
 							     IMG_HANDLE hFWCodePMR,
@@ -103,7 +100,23 @@
 
 IMG_INTERNAL PVRSRV_ERROR IMG_CALLCONV BridgeGPUVIRTPopulateLMASubArenas(IMG_HANDLE hBridge,
 									 IMG_UINT32 ui32NumElements,
-									 IMG_UINT32 *pui32Elements);
+									 IMG_UINT32 *pui32Elements,
+									 IMG_BOOL bEnableTrustedDeviceAceConfig);
+
+IMG_INTERNAL PVRSRV_ERROR IMG_CALLCONV BridgeRGXInitGuest(IMG_HANDLE hBridge,
+							  IMG_BOOL bEnableSignatureChecks,
+							  IMG_UINT32 ui32SignatureChecksBufSize,
+							  IMG_UINT32 ui32RGXFWAlignChecksArrLength,
+							  IMG_UINT32 *pui32RGXFWAlignChecks,
+							  IMG_UINT32 ui32DeviceFlags,
+							  RGXFWIF_COMPCHECKS_BVNC *psClientBVNC);
+
+IMG_INTERNAL PVRSRV_ERROR IMG_CALLCONV BridgeRGXInitFirmwareExtended(IMG_HANDLE hBridge,
+								     IMG_UINT32 ui32RGXFWAlignChecksArrLength,
+								     IMG_UINT32 *pui32RGXFWAlignChecks,
+								     RGXFWIF_DEV_VIRTADDR *pspsRGXFwInit,
+								     IMG_HANDLE *phHWPerfPMR2,
+								     RGX_FW_INIT_IN_PARAMS *pspsInParams);
 
 
 #endif /* CLIENT_RGXINIT_BRIDGE_H */
diff --git a/drivers/staging/imgtec/rogue/generated/rgxinit_bridge/client_rgxinit_direct_bridge.c b/drivers/staging/imgtec/rogue/generated/rgxinit_bridge/client_rgxinit_direct_bridge.c
index 9add8ee..68958cb 100644
--- a/drivers/staging/imgtec/rogue/generated/rgxinit_bridge/client_rgxinit_direct_bridge.c
+++ b/drivers/staging/imgtec/rogue/generated/rgxinit_bridge/client_rgxinit_direct_bridge.c
@@ -47,7 +47,6 @@
 #include "rgx_bridge.h"
 #include "rgxscript.h"
 #include "devicemem_typedefs.h"
-#include "rgx_fwif_shared.h"
 #include "rgx_fwif.h"
 
 #include "rgxinit.h"
@@ -98,7 +97,7 @@
 							     IMG_UINT32 ui32SignatureChecksBufSize,
 							     IMG_UINT32 ui32HWPerfFWBufSizeKB,
 							     IMG_UINT64 ui64HWPerfFilter,
-							     IMG_UINT32 ui32RGXFWAlignChecksSize,
+							     IMG_UINT32 ui32RGXFWAlignChecksArrLength,
 							     IMG_UINT32 *pui32RGXFWAlignChecks,
 							     IMG_UINT32 ui32ConfigFlags,
 							     IMG_UINT32 ui32LogType,
@@ -123,7 +122,7 @@
 					ui32SignatureChecksBufSize,
 					ui32HWPerfFWBufSizeKB,
 					ui64HWPerfFilter,
-					ui32RGXFWAlignChecksSize,
+					ui32RGXFWAlignChecksArrLength,
 					pui32RGXFWAlignChecks,
 					ui32ConfigFlags,
 					ui32LogType,
@@ -140,29 +139,21 @@
 	return eError;
 }
 
-IMG_INTERNAL PVRSRV_ERROR IMG_CALLCONV BridgeRGXInitFinaliseFWImage(IMG_HANDLE hBridge,
-								    IMG_HANDLE hFWImagePMRImport,
-								    IMG_UINT64 ui64FWImgLen)
+IMG_INTERNAL PVRSRV_ERROR IMG_CALLCONV BridgeRGXInitFinaliseFWImage(IMG_HANDLE hBridge)
 {
 	PVRSRV_ERROR eError;
-	PMR * psFWImagePMRImportInt;
 
-	psFWImagePMRImportInt = (PMR *) hFWImagePMRImport;
 
 	eError =
 		PVRSRVRGXInitFinaliseFWImageKM(NULL, (PVRSRV_DEVICE_NODE *)((void*) hBridge)
-		,
-					psFWImagePMRImportInt,
-					ui64FWImgLen);
-
+					);
 	return eError;
 }
 
 IMG_INTERNAL PVRSRV_ERROR IMG_CALLCONV BridgeRGXInitDevPart2(IMG_HANDLE hBridge,
 							     RGX_INIT_COMMAND *psDbgScript,
-							     RGX_INIT_COMMAND *psDbgBusScript,
-							     RGX_INIT_COMMAND *psDeinitScript,
 							     IMG_UINT32 ui32DeviceFlags,
+							     IMG_UINT32 ui32HWPerfHostBufSize,
 							     IMG_UINT32 ui32HWPerfHostFilter,
 							     IMG_UINT32 ui32RGXActivePMConf,
 							     IMG_HANDLE hFWCodePMR,
@@ -185,9 +176,8 @@
 		PVRSRVRGXInitDevPart2KM(NULL, (PVRSRV_DEVICE_NODE *)((void*) hBridge)
 		,
 					psDbgScript,
-					psDbgBusScript,
-					psDeinitScript,
 					ui32DeviceFlags,
+					ui32HWPerfHostBufSize,
 					ui32HWPerfHostFilter,
 					ui32RGXActivePMConf,
 					psFWCodePMRInt,
@@ -200,7 +190,8 @@
 
 IMG_INTERNAL PVRSRV_ERROR IMG_CALLCONV BridgeGPUVIRTPopulateLMASubArenas(IMG_HANDLE hBridge,
 									 IMG_UINT32 ui32NumElements,
-									 IMG_UINT32 *pui32Elements)
+									 IMG_UINT32 *pui32Elements,
+									 IMG_BOOL bEnableTrustedDeviceAceConfig)
 {
 	PVRSRV_ERROR eError;
 
@@ -209,8 +200,57 @@
 		PVRSRVGPUVIRTPopulateLMASubArenasKM(NULL, (PVRSRV_DEVICE_NODE *)((void*) hBridge)
 		,
 					ui32NumElements,
-					pui32Elements);
+					pui32Elements,
+					bEnableTrustedDeviceAceConfig);
 
 	return eError;
 }
 
+IMG_INTERNAL PVRSRV_ERROR IMG_CALLCONV BridgeRGXInitGuest(IMG_HANDLE hBridge,
+							  IMG_BOOL bEnableSignatureChecks,
+							  IMG_UINT32 ui32SignatureChecksBufSize,
+							  IMG_UINT32 ui32RGXFWAlignChecksArrLength,
+							  IMG_UINT32 *pui32RGXFWAlignChecks,
+							  IMG_UINT32 ui32DeviceFlags,
+							  RGXFWIF_COMPCHECKS_BVNC *psClientBVNC)
+{
+	PVRSRV_ERROR eError;
+
+
+	eError =
+		PVRSRVRGXInitGuestKM(NULL, (PVRSRV_DEVICE_NODE *)((void*) hBridge)
+		,
+					bEnableSignatureChecks,
+					ui32SignatureChecksBufSize,
+					ui32RGXFWAlignChecksArrLength,
+					pui32RGXFWAlignChecks,
+					ui32DeviceFlags,
+					psClientBVNC);
+
+	return eError;
+}
+
+IMG_INTERNAL PVRSRV_ERROR IMG_CALLCONV BridgeRGXInitFirmwareExtended(IMG_HANDLE hBridge,
+								     IMG_UINT32 ui32RGXFWAlignChecksArrLength,
+								     IMG_UINT32 *pui32RGXFWAlignChecks,
+								     RGXFWIF_DEV_VIRTADDR *pspsRGXFwInit,
+								     IMG_HANDLE *phHWPerfPMR2,
+								     RGX_FW_INIT_IN_PARAMS *pspsInParams)
+{
+	PVRSRV_ERROR eError;
+	PMR * psHWPerfPMR2Int;
+
+
+	eError =
+		PVRSRVRGXInitFirmwareExtendedKM(NULL, (PVRSRV_DEVICE_NODE *)((void*) hBridge)
+		,
+					ui32RGXFWAlignChecksArrLength,
+					pui32RGXFWAlignChecks,
+					pspsRGXFwInit,
+					&psHWPerfPMR2Int,
+					pspsInParams);
+
+	*phHWPerfPMR2 = psHWPerfPMR2Int;
+	return eError;
+}
+
diff --git a/drivers/staging/imgtec/rogue/generated/rgxinit_bridge/common_rgxinit_bridge.h b/drivers/staging/imgtec/rogue/generated/rgxinit_bridge/common_rgxinit_bridge.h
index e565faf..55e948b 100644
--- a/drivers/staging/imgtec/rogue/generated/rgxinit_bridge/common_rgxinit_bridge.h
+++ b/drivers/staging/imgtec/rogue/generated/rgxinit_bridge/common_rgxinit_bridge.h
@@ -2,8 +2,8 @@
 @File
 @Title          Common bridge header for rgxinit
 @Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
-@Description    Declares common defines and structures that are used by both
-                the client and sever side of the bridge for rgxinit
+@Description    Declares common defines and structures used by both the client
+                and server side of the bridge for rgxinit
 @License        Dual MIT/GPLv2
 
 The contents of this file are subject to the MIT license as set out below.
@@ -45,13 +45,14 @@
 #ifndef COMMON_RGXINIT_BRIDGE_H
 #define COMMON_RGXINIT_BRIDGE_H
 
+#include <powervr/mem_types.h>
+
 #include "img_types.h"
 #include "pvrsrv_error.h"
 
 #include "rgx_bridge.h"
 #include "rgxscript.h"
 #include "devicemem_typedefs.h"
-#include "rgx_fwif_shared.h"
 #include "rgx_fwif.h"
 
 
@@ -61,7 +62,9 @@
 #define PVRSRV_BRIDGE_RGXINIT_RGXINITFINALISEFWIMAGE			PVRSRV_BRIDGE_RGXINIT_CMD_FIRST+2
 #define PVRSRV_BRIDGE_RGXINIT_RGXINITDEVPART2			PVRSRV_BRIDGE_RGXINIT_CMD_FIRST+3
 #define PVRSRV_BRIDGE_RGXINIT_GPUVIRTPOPULATELMASUBARENAS			PVRSRV_BRIDGE_RGXINIT_CMD_FIRST+4
-#define PVRSRV_BRIDGE_RGXINIT_CMD_LAST			(PVRSRV_BRIDGE_RGXINIT_CMD_FIRST+4)
+#define PVRSRV_BRIDGE_RGXINIT_RGXINITGUEST			PVRSRV_BRIDGE_RGXINIT_CMD_FIRST+5
+#define PVRSRV_BRIDGE_RGXINIT_RGXINITFIRMWAREEXTENDED			PVRSRV_BRIDGE_RGXINIT_CMD_FIRST+6
+#define PVRSRV_BRIDGE_RGXINIT_CMD_LAST			(PVRSRV_BRIDGE_RGXINIT_CMD_FIRST+6)
 
 
 /*******************************************
@@ -101,7 +104,7 @@
 	IMG_UINT32 ui32SignatureChecksBufSize;
 	IMG_UINT32 ui32HWPerfFWBufSizeKB;
 	IMG_UINT64 ui64HWPerfFilter;
-	IMG_UINT32 ui32RGXFWAlignChecksSize;
+	IMG_UINT32 ui32RGXFWAlignChecksArrLength;
 	IMG_UINT32 * pui32RGXFWAlignChecks;
 	IMG_UINT32 ui32ConfigFlags;
 	IMG_UINT32 ui32LogType;
@@ -130,8 +133,7 @@
 /* Bridge in structure for RGXInitFinaliseFWImage */
 typedef struct PVRSRV_BRIDGE_IN_RGXINITFINALISEFWIMAGE_TAG
 {
-	IMG_HANDLE hFWImagePMRImport;
-	IMG_UINT64 ui64FWImgLen;
+	 IMG_UINT32 ui32EmptyStructPlaceholder;
 } __attribute__((packed)) PVRSRV_BRIDGE_IN_RGXINITFINALISEFWIMAGE;
 
 /* Bridge out structure for RGXInitFinaliseFWImage */
@@ -149,9 +151,8 @@
 typedef struct PVRSRV_BRIDGE_IN_RGXINITDEVPART2_TAG
 {
 	RGX_INIT_COMMAND * psDbgScript;
-	RGX_INIT_COMMAND * psDbgBusScript;
-	RGX_INIT_COMMAND * psDeinitScript;
 	IMG_UINT32 ui32DeviceFlags;
+	IMG_UINT32 ui32HWPerfHostBufSize;
 	IMG_UINT32 ui32HWPerfHostFilter;
 	IMG_UINT32 ui32RGXActivePMConf;
 	IMG_HANDLE hFWCodePMR;
@@ -176,6 +177,7 @@
 {
 	IMG_UINT32 ui32NumElements;
 	IMG_UINT32 * pui32Elements;
+	IMG_BOOL bEnableTrustedDeviceAceConfig;
 } __attribute__((packed)) PVRSRV_BRIDGE_IN_GPUVIRTPOPULATELMASUBARENAS;
 
 /* Bridge out structure for GPUVIRTPopulateLMASubArenas */
@@ -185,4 +187,47 @@
 } __attribute__((packed)) PVRSRV_BRIDGE_OUT_GPUVIRTPOPULATELMASUBARENAS;
 
 
+/*******************************************
+            RGXInitGuest          
+ *******************************************/
+
+/* Bridge in structure for RGXInitGuest */
+typedef struct PVRSRV_BRIDGE_IN_RGXINITGUEST_TAG
+{
+	IMG_BOOL bEnableSignatureChecks;
+	IMG_UINT32 ui32SignatureChecksBufSize;
+	IMG_UINT32 ui32RGXFWAlignChecksArrLength;
+	IMG_UINT32 * pui32RGXFWAlignChecks;
+	IMG_UINT32 ui32DeviceFlags;
+	RGXFWIF_COMPCHECKS_BVNC sClientBVNC;
+} __attribute__((packed)) PVRSRV_BRIDGE_IN_RGXINITGUEST;
+
+/* Bridge out structure for RGXInitGuest */
+typedef struct PVRSRV_BRIDGE_OUT_RGXINITGUEST_TAG
+{
+	PVRSRV_ERROR eError;
+} __attribute__((packed)) PVRSRV_BRIDGE_OUT_RGXINITGUEST;
+
+
+/*******************************************
+            RGXInitFirmwareExtended          
+ *******************************************/
+
+/* Bridge in structure for RGXInitFirmwareExtended */
+typedef struct PVRSRV_BRIDGE_IN_RGXINITFIRMWAREEXTENDED_TAG
+{
+	IMG_UINT32 ui32RGXFWAlignChecksArrLength;
+	IMG_UINT32 * pui32RGXFWAlignChecks;
+	RGX_FW_INIT_IN_PARAMS spsInParams;
+} __attribute__((packed)) PVRSRV_BRIDGE_IN_RGXINITFIRMWAREEXTENDED;
+
+/* Bridge out structure for RGXInitFirmwareExtended */
+typedef struct PVRSRV_BRIDGE_OUT_RGXINITFIRMWAREEXTENDED_TAG
+{
+	RGXFWIF_DEV_VIRTADDR spsRGXFwInit;
+	IMG_HANDLE hHWPerfPMR2;
+	PVRSRV_ERROR eError;
+} __attribute__((packed)) PVRSRV_BRIDGE_OUT_RGXINITFIRMWAREEXTENDED;
+
+
 #endif /* COMMON_RGXINIT_BRIDGE_H */
diff --git a/drivers/staging/imgtec/rogue/generated/rgxinit_bridge/server_rgxinit_bridge.c b/drivers/staging/imgtec/rogue/generated/rgxinit_bridge/server_rgxinit_bridge.c
deleted file mode 100644
index 3aac66c..0000000
--- a/drivers/staging/imgtec/rogue/generated/rgxinit_bridge/server_rgxinit_bridge.c
+++ /dev/null
@@ -1,553 +0,0 @@
-/*************************************************************************/ /*!
-@File
-@Title          Server bridge for rgxinit
-@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
-@Description    Implements the server side of the bridge for rgxinit
-@License        Dual MIT/GPLv2
-
-The contents of this file are subject to the MIT license as set out below.
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-Alternatively, the contents of this file may be used under the terms of
-the GNU General Public License Version 2 ("GPL") in which case the provisions
-of GPL are applicable instead of those above.
-
-If you wish to allow use of your version of this file only under the terms of
-GPL, and not to allow others to use your version of this file under the terms
-of the MIT license, indicate your decision by deleting the provisions above
-and replace them with the notice and other provisions required by GPL as set
-out in the file called "GPL-COPYING" included in this distribution. If you do
-not delete the provisions above, a recipient may use your version of this file
-under the terms of either the MIT license or GPL.
-
-This License is also included in this distribution in the file called
-"MIT-COPYING".
-
-EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
-PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
-BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
-PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
-COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
-IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
-CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-*/ /**************************************************************************/
-
-#include <stddef.h>
-#include <asm/uaccess.h>
-
-#include "img_defs.h"
-
-#include "rgxinit.h"
-#include "pmr.h"
-
-
-#include "common_rgxinit_bridge.h"
-
-#include "allocmem.h"
-#include "pvr_debug.h"
-#include "connection_server.h"
-#include "pvr_bridge.h"
-#include "rgx_bridge.h"
-#include "srvcore.h"
-#include "handle.h"
-
-#include <linux/slab.h>
-
-
-static PVRSRV_ERROR ReleaseFWCodePMR(void *pvData)
-{
-	PVR_UNREFERENCED_PARAMETER(pvData);
-
-	return PVRSRV_OK;
-}
-static PVRSRV_ERROR ReleaseFWDataPMR(void *pvData)
-{
-	PVR_UNREFERENCED_PARAMETER(pvData);
-
-	return PVRSRV_OK;
-}
-static PVRSRV_ERROR ReleaseFWCorememPMR(void *pvData)
-{
-	PVR_UNREFERENCED_PARAMETER(pvData);
-
-	return PVRSRV_OK;
-}
-static PVRSRV_ERROR ReleaseHWPerfPMR(void *pvData)
-{
-	PVR_UNREFERENCED_PARAMETER(pvData);
-
-	return PVRSRV_OK;
-}
-
-
-/* ***************************************************************************
- * Server-side bridge entry points
- */
- 
-static IMG_INT
-PVRSRVBridgeRGXInitAllocFWImgMem(IMG_UINT32 ui32DispatchTableEntry,
-					  PVRSRV_BRIDGE_IN_RGXINITALLOCFWIMGMEM *psRGXInitAllocFWImgMemIN,
-					  PVRSRV_BRIDGE_OUT_RGXINITALLOCFWIMGMEM *psRGXInitAllocFWImgMemOUT,
-					 CONNECTION_DATA *psConnection)
-{
-	PMR * psFWCodePMRInt = NULL;
-	PMR * psFWDataPMRInt = NULL;
-	PMR * psFWCorememPMRInt = NULL;
-
-
-
-
-
-
-
-	psRGXInitAllocFWImgMemOUT->eError =
-		PVRSRVRGXInitAllocFWImgMemKM(psConnection, OSGetDevData(psConnection),
-					psRGXInitAllocFWImgMemIN->uiFWCodeLen,
-					psRGXInitAllocFWImgMemIN->uiFWDataLen,
-					psRGXInitAllocFWImgMemIN->uiFWCoremem,
-					&psFWCodePMRInt,
-					&psRGXInitAllocFWImgMemOUT->sFWCodeDevVAddrBase,
-					&psFWDataPMRInt,
-					&psRGXInitAllocFWImgMemOUT->sFWDataDevVAddrBase,
-					&psFWCorememPMRInt,
-					&psRGXInitAllocFWImgMemOUT->sFWCorememDevVAddrBase,
-					&psRGXInitAllocFWImgMemOUT->sFWCorememMetaVAddrBase);
-	/* Exit early if bridged call fails */
-	if(psRGXInitAllocFWImgMemOUT->eError != PVRSRV_OK)
-	{
-		goto RGXInitAllocFWImgMem_exit;
-	}
-
-
-	psRGXInitAllocFWImgMemOUT->eError = PVRSRVAllocHandle(psConnection->psHandleBase,
-							&psRGXInitAllocFWImgMemOUT->hFWCodePMR,
-							(void *) psFWCodePMRInt,
-							PVRSRV_HANDLE_TYPE_PMR_LOCAL_EXPORT_HANDLE,
-							PVRSRV_HANDLE_ALLOC_FLAG_NONE
-							,(PFN_HANDLE_RELEASE)&ReleaseFWCodePMR);
-	if (psRGXInitAllocFWImgMemOUT->eError != PVRSRV_OK)
-	{
-		goto RGXInitAllocFWImgMem_exit;
-	}
-
-
-	psRGXInitAllocFWImgMemOUT->eError = PVRSRVAllocHandle(psConnection->psHandleBase,
-							&psRGXInitAllocFWImgMemOUT->hFWDataPMR,
-							(void *) psFWDataPMRInt,
-							PVRSRV_HANDLE_TYPE_PMR_LOCAL_EXPORT_HANDLE,
-							PVRSRV_HANDLE_ALLOC_FLAG_NONE
-							,(PFN_HANDLE_RELEASE)&ReleaseFWDataPMR);
-	if (psRGXInitAllocFWImgMemOUT->eError != PVRSRV_OK)
-	{
-		goto RGXInitAllocFWImgMem_exit;
-	}
-
-
-	psRGXInitAllocFWImgMemOUT->eError = PVRSRVAllocHandle(psConnection->psHandleBase,
-							&psRGXInitAllocFWImgMemOUT->hFWCorememPMR,
-							(void *) psFWCorememPMRInt,
-							PVRSRV_HANDLE_TYPE_PMR_LOCAL_EXPORT_HANDLE,
-							PVRSRV_HANDLE_ALLOC_FLAG_NONE
-							,(PFN_HANDLE_RELEASE)&ReleaseFWCorememPMR);
-	if (psRGXInitAllocFWImgMemOUT->eError != PVRSRV_OK)
-	{
-		goto RGXInitAllocFWImgMem_exit;
-	}
-
-
-
-
-RGXInitAllocFWImgMem_exit:
-	if (psRGXInitAllocFWImgMemOUT->eError != PVRSRV_OK)
-	{
-	}
-
-
-	return 0;
-}
-
-static IMG_INT
-PVRSRVBridgeRGXInitFirmware(IMG_UINT32 ui32DispatchTableEntry,
-					  PVRSRV_BRIDGE_IN_RGXINITFIRMWARE *psRGXInitFirmwareIN,
-					  PVRSRV_BRIDGE_OUT_RGXINITFIRMWARE *psRGXInitFirmwareOUT,
-					 CONNECTION_DATA *psConnection)
-{
-	IMG_UINT32 *ui32RGXFWAlignChecksInt = NULL;
-	PMR * psHWPerfPMRInt = NULL;
-
-
-
-
-	if (psRGXInitFirmwareIN->ui32RGXFWAlignChecksSize != 0)
-	{
-		ui32RGXFWAlignChecksInt = OSAllocMemNoStats(psRGXInitFirmwareIN->ui32RGXFWAlignChecksSize * sizeof(IMG_UINT32));
-		if (!ui32RGXFWAlignChecksInt)
-		{
-			psRGXInitFirmwareOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
-	
-			goto RGXInitFirmware_exit;
-		}
-	}
-
-			/* Copy the data over */
-			if ( !OSAccessOK(PVR_VERIFY_READ, (void*) psRGXInitFirmwareIN->pui32RGXFWAlignChecks, psRGXInitFirmwareIN->ui32RGXFWAlignChecksSize * sizeof(IMG_UINT32))
-				|| (OSCopyFromUser(NULL, ui32RGXFWAlignChecksInt, psRGXInitFirmwareIN->pui32RGXFWAlignChecks,
-				psRGXInitFirmwareIN->ui32RGXFWAlignChecksSize * sizeof(IMG_UINT32)) != PVRSRV_OK) )
-			{
-				psRGXInitFirmwareOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
-
-				goto RGXInitFirmware_exit;
-			}
-
-
-
-	psRGXInitFirmwareOUT->eError =
-		PVRSRVRGXInitFirmwareKM(psConnection, OSGetDevData(psConnection),
-					&psRGXInitFirmwareOUT->spsRGXFwInit,
-					psRGXInitFirmwareIN->bEnableSignatureChecks,
-					psRGXInitFirmwareIN->ui32SignatureChecksBufSize,
-					psRGXInitFirmwareIN->ui32HWPerfFWBufSizeKB,
-					psRGXInitFirmwareIN->ui64HWPerfFilter,
-					psRGXInitFirmwareIN->ui32RGXFWAlignChecksSize,
-					ui32RGXFWAlignChecksInt,
-					psRGXInitFirmwareIN->ui32ConfigFlags,
-					psRGXInitFirmwareIN->ui32LogType,
-					psRGXInitFirmwareIN->ui32FilterFlags,
-					psRGXInitFirmwareIN->ui32JonesDisableMask,
-					psRGXInitFirmwareIN->ui32ui32HWRDebugDumpLimit,
-					&psRGXInitFirmwareIN->sClientBVNC,
-					psRGXInitFirmwareIN->ui32HWPerfCountersDataSize,
-					&psHWPerfPMRInt,
-					psRGXInitFirmwareIN->eRGXRDPowerIslandConf,
-					psRGXInitFirmwareIN->eFirmwarePerf);
-	/* Exit early if bridged call fails */
-	if(psRGXInitFirmwareOUT->eError != PVRSRV_OK)
-	{
-		goto RGXInitFirmware_exit;
-	}
-
-
-	psRGXInitFirmwareOUT->eError = PVRSRVAllocHandle(psConnection->psHandleBase,
-							&psRGXInitFirmwareOUT->hHWPerfPMR,
-							(void *) psHWPerfPMRInt,
-							PVRSRV_HANDLE_TYPE_PMR_LOCAL_EXPORT_HANDLE,
-							PVRSRV_HANDLE_ALLOC_FLAG_NONE
-							,(PFN_HANDLE_RELEASE)&ReleaseHWPerfPMR);
-	if (psRGXInitFirmwareOUT->eError != PVRSRV_OK)
-	{
-		goto RGXInitFirmware_exit;
-	}
-
-
-
-
-RGXInitFirmware_exit:
-	if (psRGXInitFirmwareOUT->eError != PVRSRV_OK)
-	{
-	}
-
-	if (ui32RGXFWAlignChecksInt)
-		OSFreeMemNoStats(ui32RGXFWAlignChecksInt);
-
-	return 0;
-}
-
-static IMG_INT
-PVRSRVBridgeRGXInitFinaliseFWImage(IMG_UINT32 ui32DispatchTableEntry,
-					  PVRSRV_BRIDGE_IN_RGXINITFINALISEFWIMAGE *psRGXInitFinaliseFWImageIN,
-					  PVRSRV_BRIDGE_OUT_RGXINITFINALISEFWIMAGE *psRGXInitFinaliseFWImageOUT,
-					 CONNECTION_DATA *psConnection)
-{
-	PMR * psFWImagePMRImportInt = NULL;
-
-
-
-
-
-	PMRLock();
-
-
-				{
-					/* Look up the address from the handle */
-					psRGXInitFinaliseFWImageOUT->eError =
-						PVRSRVLookupHandle(psConnection->psHandleBase,
-											(void **) &psFWImagePMRImportInt,
-											psRGXInitFinaliseFWImageIN->hFWImagePMRImport,
-											PVRSRV_HANDLE_TYPE_PMR_LOCAL_EXPORT_HANDLE);
-					if(psRGXInitFinaliseFWImageOUT->eError != PVRSRV_OK)
-					{
-						PMRUnlock();
-						goto RGXInitFinaliseFWImage_exit;
-					}
-				}
-
-
-	psRGXInitFinaliseFWImageOUT->eError =
-		PVRSRVRGXInitFinaliseFWImageKM(psConnection, OSGetDevData(psConnection),
-					psFWImagePMRImportInt,
-					psRGXInitFinaliseFWImageIN->ui64FWImgLen);
-	PMRUnlock();
-
-
-
-
-RGXInitFinaliseFWImage_exit:
-
-	return 0;
-}
-
-static IMG_INT
-PVRSRVBridgeRGXInitDevPart2(IMG_UINT32 ui32DispatchTableEntry,
-					  PVRSRV_BRIDGE_IN_RGXINITDEVPART2 *psRGXInitDevPart2IN,
-					  PVRSRV_BRIDGE_OUT_RGXINITDEVPART2 *psRGXInitDevPart2OUT,
-					 CONNECTION_DATA *psConnection)
-{
-	RGX_INIT_COMMAND *psDbgScriptInt = NULL;
-	RGX_INIT_COMMAND *psDbgBusScriptInt = NULL;
-	RGX_INIT_COMMAND *psDeinitScriptInt = NULL;
-	PMR * psFWCodePMRInt = NULL;
-	PMR * psFWDataPMRInt = NULL;
-	PMR * psFWCorememPMRInt = NULL;
-	PMR * psHWPerfPMRInt = NULL;
-
-
-
-
-	
-	{
-		psDbgScriptInt = OSAllocMemNoStats(RGX_MAX_DEBUG_COMMANDS * sizeof(RGX_INIT_COMMAND));
-		if (!psDbgScriptInt)
-		{
-			psRGXInitDevPart2OUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
-	
-			goto RGXInitDevPart2_exit;
-		}
-	}
-
-			/* Copy the data over */
-			if ( !OSAccessOK(PVR_VERIFY_READ, (void*) psRGXInitDevPart2IN->psDbgScript, RGX_MAX_DEBUG_COMMANDS * sizeof(RGX_INIT_COMMAND))
-				|| (OSCopyFromUser(NULL, psDbgScriptInt, psRGXInitDevPart2IN->psDbgScript,
-				RGX_MAX_DEBUG_COMMANDS * sizeof(RGX_INIT_COMMAND)) != PVRSRV_OK) )
-			{
-				psRGXInitDevPart2OUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
-
-				goto RGXInitDevPart2_exit;
-			}
-	
-	{
-		psDbgBusScriptInt = OSAllocMemNoStats(RGX_MAX_DBGBUS_COMMANDS * sizeof(RGX_INIT_COMMAND));
-		if (!psDbgBusScriptInt)
-		{
-			psRGXInitDevPart2OUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
-	
-			goto RGXInitDevPart2_exit;
-		}
-	}
-
-			/* Copy the data over */
-			if ( !OSAccessOK(PVR_VERIFY_READ, (void*) psRGXInitDevPart2IN->psDbgBusScript, RGX_MAX_DBGBUS_COMMANDS * sizeof(RGX_INIT_COMMAND))
-				|| (OSCopyFromUser(NULL, psDbgBusScriptInt, psRGXInitDevPart2IN->psDbgBusScript,
-				RGX_MAX_DBGBUS_COMMANDS * sizeof(RGX_INIT_COMMAND)) != PVRSRV_OK) )
-			{
-				psRGXInitDevPart2OUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
-
-				goto RGXInitDevPart2_exit;
-			}
-	
-	{
-		psDeinitScriptInt = OSAllocMemNoStats(RGX_MAX_DEINIT_COMMANDS * sizeof(RGX_INIT_COMMAND));
-		if (!psDeinitScriptInt)
-		{
-			psRGXInitDevPart2OUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
-	
-			goto RGXInitDevPart2_exit;
-		}
-	}
-
-			/* Copy the data over */
-			if ( !OSAccessOK(PVR_VERIFY_READ, (void*) psRGXInitDevPart2IN->psDeinitScript, RGX_MAX_DEINIT_COMMANDS * sizeof(RGX_INIT_COMMAND))
-				|| (OSCopyFromUser(NULL, psDeinitScriptInt, psRGXInitDevPart2IN->psDeinitScript,
-				RGX_MAX_DEINIT_COMMANDS * sizeof(RGX_INIT_COMMAND)) != PVRSRV_OK) )
-			{
-				psRGXInitDevPart2OUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
-
-				goto RGXInitDevPart2_exit;
-			}
-
-	PMRLock();
-
-
-	psRGXInitDevPart2OUT->eError =
-		PVRSRVRGXInitDevPart2KM(psConnection, OSGetDevData(psConnection),
-					psDbgScriptInt,
-					psDbgBusScriptInt,
-					psDeinitScriptInt,
-					psRGXInitDevPart2IN->ui32DeviceFlags,
-					psRGXInitDevPart2IN->ui32HWPerfHostFilter,
-					psRGXInitDevPart2IN->ui32RGXActivePMConf,
-					psFWCodePMRInt,
-					psFWDataPMRInt,
-					psFWCorememPMRInt,
-					psHWPerfPMRInt);
-	PMRUnlock();
-
-
-	psRGXInitDevPart2OUT->eError =
-		PVRSRVReleaseHandle(psConnection->psHandleBase,
-					(IMG_HANDLE) psRGXInitDevPart2IN->hFWCodePMR,
-					PVRSRV_HANDLE_TYPE_PMR_LOCAL_EXPORT_HANDLE);
-	if ((psRGXInitDevPart2OUT->eError != PVRSRV_OK) && (psRGXInitDevPart2OUT->eError != PVRSRV_ERROR_RETRY))
-	{
-		PVR_ASSERT(0);
-		PMRUnlock();
-		goto RGXInitDevPart2_exit;
-	}
-
-	psRGXInitDevPart2OUT->eError =
-		PVRSRVReleaseHandle(psConnection->psHandleBase,
-					(IMG_HANDLE) psRGXInitDevPart2IN->hFWDataPMR,
-					PVRSRV_HANDLE_TYPE_PMR_LOCAL_EXPORT_HANDLE);
-	if ((psRGXInitDevPart2OUT->eError != PVRSRV_OK) && (psRGXInitDevPart2OUT->eError != PVRSRV_ERROR_RETRY))
-	{
-		PVR_ASSERT(0);
-		PMRUnlock();
-		goto RGXInitDevPart2_exit;
-	}
-
-	psRGXInitDevPart2OUT->eError =
-		PVRSRVReleaseHandle(psConnection->psHandleBase,
-					(IMG_HANDLE) psRGXInitDevPart2IN->hFWCorememPMR,
-					PVRSRV_HANDLE_TYPE_PMR_LOCAL_EXPORT_HANDLE);
-	if ((psRGXInitDevPart2OUT->eError != PVRSRV_OK) && (psRGXInitDevPart2OUT->eError != PVRSRV_ERROR_RETRY))
-	{
-		PVR_ASSERT(0);
-		PMRUnlock();
-		goto RGXInitDevPart2_exit;
-	}
-
-	psRGXInitDevPart2OUT->eError =
-		PVRSRVReleaseHandle(psConnection->psHandleBase,
-					(IMG_HANDLE) psRGXInitDevPart2IN->hHWPerfPMR,
-					PVRSRV_HANDLE_TYPE_PMR_LOCAL_EXPORT_HANDLE);
-	if ((psRGXInitDevPart2OUT->eError != PVRSRV_OK) && (psRGXInitDevPart2OUT->eError != PVRSRV_ERROR_RETRY))
-	{
-		PVR_ASSERT(0);
-		PMRUnlock();
-		goto RGXInitDevPart2_exit;
-	}
-
-
-
-RGXInitDevPart2_exit:
-	if (psDbgScriptInt)
-		OSFreeMemNoStats(psDbgScriptInt);
-	if (psDbgBusScriptInt)
-		OSFreeMemNoStats(psDbgBusScriptInt);
-	if (psDeinitScriptInt)
-		OSFreeMemNoStats(psDeinitScriptInt);
-
-	return 0;
-}
-
-static IMG_INT
-PVRSRVBridgeGPUVIRTPopulateLMASubArenas(IMG_UINT32 ui32DispatchTableEntry,
-					  PVRSRV_BRIDGE_IN_GPUVIRTPOPULATELMASUBARENAS *psGPUVIRTPopulateLMASubArenasIN,
-					  PVRSRV_BRIDGE_OUT_GPUVIRTPOPULATELMASUBARENAS *psGPUVIRTPopulateLMASubArenasOUT,
-					 CONNECTION_DATA *psConnection)
-{
-	IMG_UINT32 *ui32ElementsInt = NULL;
-
-
-
-
-	if (psGPUVIRTPopulateLMASubArenasIN->ui32NumElements != 0)
-	{
-		ui32ElementsInt = OSAllocMemNoStats(psGPUVIRTPopulateLMASubArenasIN->ui32NumElements * sizeof(IMG_UINT32));
-		if (!ui32ElementsInt)
-		{
-			psGPUVIRTPopulateLMASubArenasOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
-	
-			goto GPUVIRTPopulateLMASubArenas_exit;
-		}
-	}
-
-			/* Copy the data over */
-			if ( !OSAccessOK(PVR_VERIFY_READ, (void*) psGPUVIRTPopulateLMASubArenasIN->pui32Elements, psGPUVIRTPopulateLMASubArenasIN->ui32NumElements * sizeof(IMG_UINT32))
-				|| (OSCopyFromUser(NULL, ui32ElementsInt, psGPUVIRTPopulateLMASubArenasIN->pui32Elements,
-				psGPUVIRTPopulateLMASubArenasIN->ui32NumElements * sizeof(IMG_UINT32)) != PVRSRV_OK) )
-			{
-				psGPUVIRTPopulateLMASubArenasOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
-
-				goto GPUVIRTPopulateLMASubArenas_exit;
-			}
-
-
-
-	psGPUVIRTPopulateLMASubArenasOUT->eError =
-		PVRSRVGPUVIRTPopulateLMASubArenasKM(psConnection, OSGetDevData(psConnection),
-					psGPUVIRTPopulateLMASubArenasIN->ui32NumElements,
-					ui32ElementsInt);
-
-
-
-
-GPUVIRTPopulateLMASubArenas_exit:
-	if (ui32ElementsInt)
-		OSFreeMemNoStats(ui32ElementsInt);
-
-	return 0;
-}
-
-
-
-/* *************************************************************************** 
- * Server bridge dispatch related glue 
- */
-
-static IMG_BOOL bUseLock = IMG_TRUE;
-
-PVRSRV_ERROR InitRGXINITBridge(void);
-PVRSRV_ERROR DeinitRGXINITBridge(void);
-
-/*
- * Register all RGXINIT functions with services
- */
-PVRSRV_ERROR InitRGXINITBridge(void)
-{
-
-	SetDispatchTableEntry(PVRSRV_BRIDGE_RGXINIT, PVRSRV_BRIDGE_RGXINIT_RGXINITALLOCFWIMGMEM, PVRSRVBridgeRGXInitAllocFWImgMem,
-					NULL, bUseLock);
-
-	SetDispatchTableEntry(PVRSRV_BRIDGE_RGXINIT, PVRSRV_BRIDGE_RGXINIT_RGXINITFIRMWARE, PVRSRVBridgeRGXInitFirmware,
-					NULL, bUseLock);
-
-	SetDispatchTableEntry(PVRSRV_BRIDGE_RGXINIT, PVRSRV_BRIDGE_RGXINIT_RGXINITFINALISEFWIMAGE, PVRSRVBridgeRGXInitFinaliseFWImage,
-					NULL, bUseLock);
-
-	SetDispatchTableEntry(PVRSRV_BRIDGE_RGXINIT, PVRSRV_BRIDGE_RGXINIT_RGXINITDEVPART2, PVRSRVBridgeRGXInitDevPart2,
-					NULL, bUseLock);
-
-	SetDispatchTableEntry(PVRSRV_BRIDGE_RGXINIT, PVRSRV_BRIDGE_RGXINIT_GPUVIRTPOPULATELMASUBARENAS, PVRSRVBridgeGPUVIRTPopulateLMASubArenas,
-					NULL, bUseLock);
-
-
-	return PVRSRV_OK;
-}
-
-/*
- * Unregister all rgxinit functions with services
- */
-PVRSRV_ERROR DeinitRGXINITBridge(void)
-{
-	return PVRSRV_OK;
-}
-
diff --git a/drivers/staging/imgtec/rogue/generated/rgxkicksync_bridge/common_rgxkicksync_bridge.h b/drivers/staging/imgtec/rogue/generated/rgxkicksync_bridge/common_rgxkicksync_bridge.h
index 4221e29..b1b6fae 100644
--- a/drivers/staging/imgtec/rogue/generated/rgxkicksync_bridge/common_rgxkicksync_bridge.h
+++ b/drivers/staging/imgtec/rogue/generated/rgxkicksync_bridge/common_rgxkicksync_bridge.h
@@ -2,8 +2,8 @@
 @File
 @Title          Common bridge header for rgxkicksync
 @Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
-@Description    Declares common defines and structures that are used by both
-                the client and sever side of the bridge for rgxkicksync
+@Description    Declares common defines and structures used by both the client
+                and server side of the bridge for rgxkicksync
 @License        Dual MIT/GPLv2
 
 The contents of this file are subject to the MIT license as set out below.
@@ -45,12 +45,13 @@
 #ifndef COMMON_RGXKICKSYNC_BRIDGE_H
 #define COMMON_RGXKICKSYNC_BRIDGE_H
 
+#include <powervr/mem_types.h>
+
 #include "img_types.h"
 #include "pvrsrv_error.h"
 
 #include "rgx_bridge.h"
-#include "sync_external.h"
-#include "rgx_fwif_shared.h"
+#include <powervr/sync_external.h>
 
 
 #define PVRSRV_BRIDGE_RGXKICKSYNC_CMD_FIRST			0
@@ -103,6 +104,7 @@
 typedef struct PVRSRV_BRIDGE_IN_RGXKICKSYNC_TAG
 {
 	IMG_HANDLE hKickSyncContext;
+	IMG_UINT32 ui32ClientCacheOpSeqNum;
 	IMG_UINT32 ui32ClientFenceCount;
 	IMG_HANDLE * phFenceUFOSyncPrimBlock;
 	IMG_UINT32 * pui32FenceSyncOffset;
@@ -118,7 +120,6 @@
 	IMG_INT32 i32TimelineFenceFD;
 	IMG_CHAR * puiUpdateFenceName;
 	IMG_UINT32 ui32ExtJobRef;
-	IMG_UINT32 ui32IntJobRef;
 } __attribute__((packed)) PVRSRV_BRIDGE_IN_RGXKICKSYNC;
 
 /* Bridge out structure for RGXKickSync */
diff --git a/drivers/staging/imgtec/rogue/generated/rgxkicksync_bridge/server_rgxkicksync_bridge.c b/drivers/staging/imgtec/rogue/generated/rgxkicksync_bridge/server_rgxkicksync_bridge.c
index 19c9c41..7739b38 100644
--- a/drivers/staging/imgtec/rogue/generated/rgxkicksync_bridge/server_rgxkicksync_bridge.c
+++ b/drivers/staging/imgtec/rogue/generated/rgxkicksync_bridge/server_rgxkicksync_bridge.c
@@ -64,6 +64,8 @@
 
 
 
+
+
 /* ***************************************************************************
  * Server-side bridge entry points
  */
@@ -74,6 +76,7 @@
 					  PVRSRV_BRIDGE_OUT_RGXCREATEKICKSYNCCONTEXT *psRGXCreateKickSyncContextOUT,
 					 CONNECTION_DATA *psConnection)
 {
+	IMG_HANDLE hPrivData = psRGXCreateKickSyncContextIN->hPrivData;
 	IMG_HANDLE hPrivDataInt = NULL;
 	RGX_SERVER_KICKSYNC_CONTEXT * psKickSyncContextInt = NULL;
 
@@ -83,19 +86,29 @@
 
 
 
+	/* Lock over handle lookup. */
+	LockHandle();
+
+
+
+
+
 				{
 					/* Look up the address from the handle */
 					psRGXCreateKickSyncContextOUT->eError =
-						PVRSRVLookupHandle(psConnection->psHandleBase,
+						PVRSRVLookupHandleUnlocked(psConnection->psHandleBase,
 											(void **) &hPrivDataInt,
-											psRGXCreateKickSyncContextIN->hPrivData,
-											PVRSRV_HANDLE_TYPE_DEV_PRIV_DATA);
+											hPrivData,
+											PVRSRV_HANDLE_TYPE_DEV_PRIV_DATA,
+											IMG_TRUE);
 					if(psRGXCreateKickSyncContextOUT->eError != PVRSRV_OK)
 					{
+						UnlockHandle();
 						goto RGXCreateKickSyncContext_exit;
 					}
 				}
-
+	/* Release now we have looked up handles. */
+	UnlockHandle();
 
 	psRGXCreateKickSyncContextOUT->eError =
 		PVRSRVRGXCreateKickSyncContextKM(psConnection, OSGetDevData(psConnection),
@@ -107,8 +120,15 @@
 		goto RGXCreateKickSyncContext_exit;
 	}
 
+	/* Lock over handle creation. */
+	LockHandle();
 
-	psRGXCreateKickSyncContextOUT->eError = PVRSRVAllocHandle(psConnection->psHandleBase,
+
+
+
+
+	psRGXCreateKickSyncContextOUT->eError = PVRSRVAllocHandleUnlocked(psConnection->psHandleBase,
+
 							&psRGXCreateKickSyncContextOUT->hKickSyncContext,
 							(void *) psKickSyncContextInt,
 							PVRSRV_HANDLE_TYPE_RGX_SERVER_KICKSYNC_CONTEXT,
@@ -116,13 +136,37 @@
 							,(PFN_HANDLE_RELEASE)&PVRSRVRGXDestroyKickSyncContextKM);
 	if (psRGXCreateKickSyncContextOUT->eError != PVRSRV_OK)
 	{
+		UnlockHandle();
 		goto RGXCreateKickSyncContext_exit;
 	}
 
+	/* Release now we have created handles. */
+	UnlockHandle();
 
 
 
 RGXCreateKickSyncContext_exit:
+
+	/* Lock over handle lookup cleanup. */
+	LockHandle();
+
+
+
+
+
+
+				{
+					/* Unreference the previously looked up handle */
+						if(hPrivDataInt)
+						{
+							PVRSRVReleaseHandleUnlocked(psConnection->psHandleBase,
+											hPrivData,
+											PVRSRV_HANDLE_TYPE_DEV_PRIV_DATA);
+						}
+				}
+	/* Release now we have cleaned up look up handles. */
+	UnlockHandle();
+
 	if (psRGXCreateKickSyncContextOUT->eError != PVRSRV_OK)
 	{
 		if (psKickSyncContextInt)
@@ -135,6 +179,7 @@
 	return 0;
 }
 
+
 static IMG_INT
 PVRSRVBridgeRGXDestroyKickSyncContext(IMG_UINT32 ui32DispatchTableEntry,
 					  PVRSRV_BRIDGE_IN_RGXDESTROYKICKSYNCCONTEXT *psRGXDestroyKickSyncContextIN,
@@ -150,29 +195,49 @@
 
 
 
+	/* Lock over handle destruction. */
+	LockHandle();
+
+
+
+
+
 	psRGXDestroyKickSyncContextOUT->eError =
-		PVRSRVReleaseHandle(psConnection->psHandleBase,
+		PVRSRVReleaseHandleUnlocked(psConnection->psHandleBase,
 					(IMG_HANDLE) psRGXDestroyKickSyncContextIN->hKickSyncContext,
 					PVRSRV_HANDLE_TYPE_RGX_SERVER_KICKSYNC_CONTEXT);
-	if ((psRGXDestroyKickSyncContextOUT->eError != PVRSRV_OK) && (psRGXDestroyKickSyncContextOUT->eError != PVRSRV_ERROR_RETRY))
+	if ((psRGXDestroyKickSyncContextOUT->eError != PVRSRV_OK) &&
+	    (psRGXDestroyKickSyncContextOUT->eError != PVRSRV_ERROR_RETRY))
 	{
+		PVR_DPF((PVR_DBG_ERROR,
+		        "PVRSRVBridgeRGXDestroyKickSyncContext: %s",
+		        PVRSRVGetErrorStringKM(psRGXDestroyKickSyncContextOUT->eError)));
 		PVR_ASSERT(0);
+		UnlockHandle();
 		goto RGXDestroyKickSyncContext_exit;
 	}
 
+	/* Release now we have destroyed handles. */
+	UnlockHandle();
+
 
 
 RGXDestroyKickSyncContext_exit:
 
+
+
+
 	return 0;
 }
 
+
 static IMG_INT
 PVRSRVBridgeRGXKickSync(IMG_UINT32 ui32DispatchTableEntry,
 					  PVRSRV_BRIDGE_IN_RGXKICKSYNC *psRGXKickSyncIN,
 					  PVRSRV_BRIDGE_OUT_RGXKICKSYNC *psRGXKickSyncOUT,
 					 CONNECTION_DATA *psConnection)
 {
+	IMG_HANDLE hKickSyncContext = psRGXKickSyncIN->hKickSyncContext;
 	RGX_SERVER_KICKSYNC_CONTEXT * psKickSyncContextInt = NULL;
 	SYNC_PRIMITIVE_BLOCK * *psFenceUFOSyncPrimBlockInt = NULL;
 	IMG_HANDLE *hFenceUFOSyncPrimBlockInt2 = NULL;
@@ -187,227 +252,235 @@
 	IMG_HANDLE *hServerSyncInt2 = NULL;
 	IMG_CHAR *uiUpdateFenceNameInt = NULL;
 
+	IMG_UINT32 ui32NextOffset = 0;
+	IMG_BYTE   *pArrayArgsBuffer = NULL;
+#if !defined(INTEGRITY_OS)
+	IMG_BOOL bHaveEnoughSpace = IMG_FALSE;
+#endif
+
+	IMG_UINT32 ui32BufferSize = 
+			(psRGXKickSyncIN->ui32ClientFenceCount * sizeof(SYNC_PRIMITIVE_BLOCK *)) +
+			(psRGXKickSyncIN->ui32ClientFenceCount * sizeof(IMG_HANDLE)) +
+			(psRGXKickSyncIN->ui32ClientFenceCount * sizeof(IMG_UINT32)) +
+			(psRGXKickSyncIN->ui32ClientFenceCount * sizeof(IMG_UINT32)) +
+			(psRGXKickSyncIN->ui32ClientUpdateCount * sizeof(SYNC_PRIMITIVE_BLOCK *)) +
+			(psRGXKickSyncIN->ui32ClientUpdateCount * sizeof(IMG_HANDLE)) +
+			(psRGXKickSyncIN->ui32ClientUpdateCount * sizeof(IMG_UINT32)) +
+			(psRGXKickSyncIN->ui32ClientUpdateCount * sizeof(IMG_UINT32)) +
+			(psRGXKickSyncIN->ui32ServerSyncCount * sizeof(IMG_UINT32)) +
+			(psRGXKickSyncIN->ui32ServerSyncCount * sizeof(SERVER_SYNC_PRIMITIVE *)) +
+			(psRGXKickSyncIN->ui32ServerSyncCount * sizeof(IMG_HANDLE)) +
+			(32 * sizeof(IMG_CHAR)) +
+			0;
 
 
 
+
+
+	if (ui32BufferSize != 0)
+	{
+#if !defined(INTEGRITY_OS)
+		/* Try to use remainder of input buffer for copies if possible, word-aligned for safety. */
+		IMG_UINT32 ui32InBufferOffset = PVR_ALIGN(sizeof(*psRGXKickSyncIN), sizeof(unsigned long));
+		IMG_UINT32 ui32InBufferExcessSize = ui32InBufferOffset >= PVRSRV_MAX_BRIDGE_IN_SIZE ? 0 :
+			PVRSRV_MAX_BRIDGE_IN_SIZE - ui32InBufferOffset;
+
+		bHaveEnoughSpace = ui32BufferSize <= ui32InBufferExcessSize;
+		if (bHaveEnoughSpace)
+		{
+			IMG_BYTE *pInputBuffer = (IMG_BYTE *)psRGXKickSyncIN;
+
+			pArrayArgsBuffer = &pInputBuffer[ui32InBufferOffset];		}
+		else
+#endif
+		{
+			pArrayArgsBuffer = OSAllocMemNoStats(ui32BufferSize);
+
+			if(!pArrayArgsBuffer)
+			{
+				psRGXKickSyncOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
+				goto RGXKickSync_exit;
+			}
+		}
+	}
+
 	if (psRGXKickSyncIN->ui32ClientFenceCount != 0)
 	{
-		psFenceUFOSyncPrimBlockInt = OSAllocMemNoStats(psRGXKickSyncIN->ui32ClientFenceCount * sizeof(SYNC_PRIMITIVE_BLOCK *));
-		if (!psFenceUFOSyncPrimBlockInt)
-		{
-			psRGXKickSyncOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
-	
-			goto RGXKickSync_exit;
-		}
-		hFenceUFOSyncPrimBlockInt2 = OSAllocMemNoStats(psRGXKickSyncIN->ui32ClientFenceCount * sizeof(IMG_HANDLE));
-		if (!hFenceUFOSyncPrimBlockInt2)
-		{
-			psRGXKickSyncOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
-	
-			goto RGXKickSync_exit;
-		}
+		psFenceUFOSyncPrimBlockInt = (SYNC_PRIMITIVE_BLOCK **)(((IMG_UINT8 *)pArrayArgsBuffer) + ui32NextOffset);
+		ui32NextOffset += psRGXKickSyncIN->ui32ClientFenceCount * sizeof(SYNC_PRIMITIVE_BLOCK *);
+		hFenceUFOSyncPrimBlockInt2 = (IMG_HANDLE *)(((IMG_UINT8 *)pArrayArgsBuffer) + ui32NextOffset); 
+		ui32NextOffset += psRGXKickSyncIN->ui32ClientFenceCount * sizeof(IMG_HANDLE);
 	}
 
 			/* Copy the data over */
-			if ( !OSAccessOK(PVR_VERIFY_READ, (void*) psRGXKickSyncIN->phFenceUFOSyncPrimBlock, psRGXKickSyncIN->ui32ClientFenceCount * sizeof(IMG_HANDLE))
-				|| (OSCopyFromUser(NULL, hFenceUFOSyncPrimBlockInt2, psRGXKickSyncIN->phFenceUFOSyncPrimBlock,
-				psRGXKickSyncIN->ui32ClientFenceCount * sizeof(IMG_HANDLE)) != PVRSRV_OK) )
+			if (psRGXKickSyncIN->ui32ClientFenceCount * sizeof(IMG_HANDLE) > 0)
 			{
-				psRGXKickSyncOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
+				if ( OSCopyFromUser(NULL, hFenceUFOSyncPrimBlockInt2, psRGXKickSyncIN->phFenceUFOSyncPrimBlock, psRGXKickSyncIN->ui32ClientFenceCount * sizeof(IMG_HANDLE)) != PVRSRV_OK )
+				{
+					psRGXKickSyncOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
 
-				goto RGXKickSync_exit;
+					goto RGXKickSync_exit;
+				}
 			}
 	if (psRGXKickSyncIN->ui32ClientFenceCount != 0)
 	{
-		ui32FenceSyncOffsetInt = OSAllocMemNoStats(psRGXKickSyncIN->ui32ClientFenceCount * sizeof(IMG_UINT32));
-		if (!ui32FenceSyncOffsetInt)
-		{
-			psRGXKickSyncOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
-	
-			goto RGXKickSync_exit;
-		}
+		ui32FenceSyncOffsetInt = (IMG_UINT32*)(((IMG_UINT8 *)pArrayArgsBuffer) + ui32NextOffset);
+		ui32NextOffset += psRGXKickSyncIN->ui32ClientFenceCount * sizeof(IMG_UINT32);
 	}
 
 			/* Copy the data over */
-			if ( !OSAccessOK(PVR_VERIFY_READ, (void*) psRGXKickSyncIN->pui32FenceSyncOffset, psRGXKickSyncIN->ui32ClientFenceCount * sizeof(IMG_UINT32))
-				|| (OSCopyFromUser(NULL, ui32FenceSyncOffsetInt, psRGXKickSyncIN->pui32FenceSyncOffset,
-				psRGXKickSyncIN->ui32ClientFenceCount * sizeof(IMG_UINT32)) != PVRSRV_OK) )
+			if (psRGXKickSyncIN->ui32ClientFenceCount * sizeof(IMG_UINT32) > 0)
 			{
-				psRGXKickSyncOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
+				if ( OSCopyFromUser(NULL, ui32FenceSyncOffsetInt, psRGXKickSyncIN->pui32FenceSyncOffset, psRGXKickSyncIN->ui32ClientFenceCount * sizeof(IMG_UINT32)) != PVRSRV_OK )
+				{
+					psRGXKickSyncOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
 
-				goto RGXKickSync_exit;
+					goto RGXKickSync_exit;
+				}
 			}
 	if (psRGXKickSyncIN->ui32ClientFenceCount != 0)
 	{
-		ui32FenceValueInt = OSAllocMemNoStats(psRGXKickSyncIN->ui32ClientFenceCount * sizeof(IMG_UINT32));
-		if (!ui32FenceValueInt)
-		{
-			psRGXKickSyncOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
-	
-			goto RGXKickSync_exit;
-		}
+		ui32FenceValueInt = (IMG_UINT32*)(((IMG_UINT8 *)pArrayArgsBuffer) + ui32NextOffset);
+		ui32NextOffset += psRGXKickSyncIN->ui32ClientFenceCount * sizeof(IMG_UINT32);
 	}
 
 			/* Copy the data over */
-			if ( !OSAccessOK(PVR_VERIFY_READ, (void*) psRGXKickSyncIN->pui32FenceValue, psRGXKickSyncIN->ui32ClientFenceCount * sizeof(IMG_UINT32))
-				|| (OSCopyFromUser(NULL, ui32FenceValueInt, psRGXKickSyncIN->pui32FenceValue,
-				psRGXKickSyncIN->ui32ClientFenceCount * sizeof(IMG_UINT32)) != PVRSRV_OK) )
+			if (psRGXKickSyncIN->ui32ClientFenceCount * sizeof(IMG_UINT32) > 0)
 			{
-				psRGXKickSyncOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
+				if ( OSCopyFromUser(NULL, ui32FenceValueInt, psRGXKickSyncIN->pui32FenceValue, psRGXKickSyncIN->ui32ClientFenceCount * sizeof(IMG_UINT32)) != PVRSRV_OK )
+				{
+					psRGXKickSyncOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
 
-				goto RGXKickSync_exit;
+					goto RGXKickSync_exit;
+				}
 			}
 	if (psRGXKickSyncIN->ui32ClientUpdateCount != 0)
 	{
-		psUpdateUFOSyncPrimBlockInt = OSAllocMemNoStats(psRGXKickSyncIN->ui32ClientUpdateCount * sizeof(SYNC_PRIMITIVE_BLOCK *));
-		if (!psUpdateUFOSyncPrimBlockInt)
-		{
-			psRGXKickSyncOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
-	
-			goto RGXKickSync_exit;
-		}
-		hUpdateUFOSyncPrimBlockInt2 = OSAllocMemNoStats(psRGXKickSyncIN->ui32ClientUpdateCount * sizeof(IMG_HANDLE));
-		if (!hUpdateUFOSyncPrimBlockInt2)
-		{
-			psRGXKickSyncOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
-	
-			goto RGXKickSync_exit;
-		}
+		psUpdateUFOSyncPrimBlockInt = (SYNC_PRIMITIVE_BLOCK **)(((IMG_UINT8 *)pArrayArgsBuffer) + ui32NextOffset);
+		ui32NextOffset += psRGXKickSyncIN->ui32ClientUpdateCount * sizeof(SYNC_PRIMITIVE_BLOCK *);
+		hUpdateUFOSyncPrimBlockInt2 = (IMG_HANDLE *)(((IMG_UINT8 *)pArrayArgsBuffer) + ui32NextOffset); 
+		ui32NextOffset += psRGXKickSyncIN->ui32ClientUpdateCount * sizeof(IMG_HANDLE);
 	}
 
 			/* Copy the data over */
-			if ( !OSAccessOK(PVR_VERIFY_READ, (void*) psRGXKickSyncIN->phUpdateUFOSyncPrimBlock, psRGXKickSyncIN->ui32ClientUpdateCount * sizeof(IMG_HANDLE))
-				|| (OSCopyFromUser(NULL, hUpdateUFOSyncPrimBlockInt2, psRGXKickSyncIN->phUpdateUFOSyncPrimBlock,
-				psRGXKickSyncIN->ui32ClientUpdateCount * sizeof(IMG_HANDLE)) != PVRSRV_OK) )
+			if (psRGXKickSyncIN->ui32ClientUpdateCount * sizeof(IMG_HANDLE) > 0)
 			{
-				psRGXKickSyncOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
+				if ( OSCopyFromUser(NULL, hUpdateUFOSyncPrimBlockInt2, psRGXKickSyncIN->phUpdateUFOSyncPrimBlock, psRGXKickSyncIN->ui32ClientUpdateCount * sizeof(IMG_HANDLE)) != PVRSRV_OK )
+				{
+					psRGXKickSyncOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
 
-				goto RGXKickSync_exit;
+					goto RGXKickSync_exit;
+				}
 			}
 	if (psRGXKickSyncIN->ui32ClientUpdateCount != 0)
 	{
-		ui32UpdateSyncOffsetInt = OSAllocMemNoStats(psRGXKickSyncIN->ui32ClientUpdateCount * sizeof(IMG_UINT32));
-		if (!ui32UpdateSyncOffsetInt)
-		{
-			psRGXKickSyncOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
-	
-			goto RGXKickSync_exit;
-		}
+		ui32UpdateSyncOffsetInt = (IMG_UINT32*)(((IMG_UINT8 *)pArrayArgsBuffer) + ui32NextOffset);
+		ui32NextOffset += psRGXKickSyncIN->ui32ClientUpdateCount * sizeof(IMG_UINT32);
 	}
 
 			/* Copy the data over */
-			if ( !OSAccessOK(PVR_VERIFY_READ, (void*) psRGXKickSyncIN->pui32UpdateSyncOffset, psRGXKickSyncIN->ui32ClientUpdateCount * sizeof(IMG_UINT32))
-				|| (OSCopyFromUser(NULL, ui32UpdateSyncOffsetInt, psRGXKickSyncIN->pui32UpdateSyncOffset,
-				psRGXKickSyncIN->ui32ClientUpdateCount * sizeof(IMG_UINT32)) != PVRSRV_OK) )
+			if (psRGXKickSyncIN->ui32ClientUpdateCount * sizeof(IMG_UINT32) > 0)
 			{
-				psRGXKickSyncOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
+				if ( OSCopyFromUser(NULL, ui32UpdateSyncOffsetInt, psRGXKickSyncIN->pui32UpdateSyncOffset, psRGXKickSyncIN->ui32ClientUpdateCount * sizeof(IMG_UINT32)) != PVRSRV_OK )
+				{
+					psRGXKickSyncOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
 
-				goto RGXKickSync_exit;
+					goto RGXKickSync_exit;
+				}
 			}
 	if (psRGXKickSyncIN->ui32ClientUpdateCount != 0)
 	{
-		ui32UpdateValueInt = OSAllocMemNoStats(psRGXKickSyncIN->ui32ClientUpdateCount * sizeof(IMG_UINT32));
-		if (!ui32UpdateValueInt)
-		{
-			psRGXKickSyncOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
-	
-			goto RGXKickSync_exit;
-		}
+		ui32UpdateValueInt = (IMG_UINT32*)(((IMG_UINT8 *)pArrayArgsBuffer) + ui32NextOffset);
+		ui32NextOffset += psRGXKickSyncIN->ui32ClientUpdateCount * sizeof(IMG_UINT32);
 	}
 
 			/* Copy the data over */
-			if ( !OSAccessOK(PVR_VERIFY_READ, (void*) psRGXKickSyncIN->pui32UpdateValue, psRGXKickSyncIN->ui32ClientUpdateCount * sizeof(IMG_UINT32))
-				|| (OSCopyFromUser(NULL, ui32UpdateValueInt, psRGXKickSyncIN->pui32UpdateValue,
-				psRGXKickSyncIN->ui32ClientUpdateCount * sizeof(IMG_UINT32)) != PVRSRV_OK) )
+			if (psRGXKickSyncIN->ui32ClientUpdateCount * sizeof(IMG_UINT32) > 0)
 			{
-				psRGXKickSyncOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
+				if ( OSCopyFromUser(NULL, ui32UpdateValueInt, psRGXKickSyncIN->pui32UpdateValue, psRGXKickSyncIN->ui32ClientUpdateCount * sizeof(IMG_UINT32)) != PVRSRV_OK )
+				{
+					psRGXKickSyncOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
 
-				goto RGXKickSync_exit;
+					goto RGXKickSync_exit;
+				}
 			}
 	if (psRGXKickSyncIN->ui32ServerSyncCount != 0)
 	{
-		ui32ServerSyncFlagsInt = OSAllocMemNoStats(psRGXKickSyncIN->ui32ServerSyncCount * sizeof(IMG_UINT32));
-		if (!ui32ServerSyncFlagsInt)
-		{
-			psRGXKickSyncOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
-	
-			goto RGXKickSync_exit;
-		}
+		ui32ServerSyncFlagsInt = (IMG_UINT32*)(((IMG_UINT8 *)pArrayArgsBuffer) + ui32NextOffset);
+		ui32NextOffset += psRGXKickSyncIN->ui32ServerSyncCount * sizeof(IMG_UINT32);
 	}
 
 			/* Copy the data over */
-			if ( !OSAccessOK(PVR_VERIFY_READ, (void*) psRGXKickSyncIN->pui32ServerSyncFlags, psRGXKickSyncIN->ui32ServerSyncCount * sizeof(IMG_UINT32))
-				|| (OSCopyFromUser(NULL, ui32ServerSyncFlagsInt, psRGXKickSyncIN->pui32ServerSyncFlags,
-				psRGXKickSyncIN->ui32ServerSyncCount * sizeof(IMG_UINT32)) != PVRSRV_OK) )
+			if (psRGXKickSyncIN->ui32ServerSyncCount * sizeof(IMG_UINT32) > 0)
 			{
-				psRGXKickSyncOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
+				if ( OSCopyFromUser(NULL, ui32ServerSyncFlagsInt, psRGXKickSyncIN->pui32ServerSyncFlags, psRGXKickSyncIN->ui32ServerSyncCount * sizeof(IMG_UINT32)) != PVRSRV_OK )
+				{
+					psRGXKickSyncOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
 
-				goto RGXKickSync_exit;
+					goto RGXKickSync_exit;
+				}
 			}
 	if (psRGXKickSyncIN->ui32ServerSyncCount != 0)
 	{
-		psServerSyncInt = OSAllocMemNoStats(psRGXKickSyncIN->ui32ServerSyncCount * sizeof(SERVER_SYNC_PRIMITIVE *));
-		if (!psServerSyncInt)
-		{
-			psRGXKickSyncOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
-	
-			goto RGXKickSync_exit;
-		}
-		hServerSyncInt2 = OSAllocMemNoStats(psRGXKickSyncIN->ui32ServerSyncCount * sizeof(IMG_HANDLE));
-		if (!hServerSyncInt2)
-		{
-			psRGXKickSyncOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
-	
-			goto RGXKickSync_exit;
-		}
+		psServerSyncInt = (SERVER_SYNC_PRIMITIVE **)(((IMG_UINT8 *)pArrayArgsBuffer) + ui32NextOffset);
+		ui32NextOffset += psRGXKickSyncIN->ui32ServerSyncCount * sizeof(SERVER_SYNC_PRIMITIVE *);
+		hServerSyncInt2 = (IMG_HANDLE *)(((IMG_UINT8 *)pArrayArgsBuffer) + ui32NextOffset); 
+		ui32NextOffset += psRGXKickSyncIN->ui32ServerSyncCount * sizeof(IMG_HANDLE);
 	}
 
 			/* Copy the data over */
-			if ( !OSAccessOK(PVR_VERIFY_READ, (void*) psRGXKickSyncIN->phServerSync, psRGXKickSyncIN->ui32ServerSyncCount * sizeof(IMG_HANDLE))
-				|| (OSCopyFromUser(NULL, hServerSyncInt2, psRGXKickSyncIN->phServerSync,
-				psRGXKickSyncIN->ui32ServerSyncCount * sizeof(IMG_HANDLE)) != PVRSRV_OK) )
+			if (psRGXKickSyncIN->ui32ServerSyncCount * sizeof(IMG_HANDLE) > 0)
 			{
-				psRGXKickSyncOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
+				if ( OSCopyFromUser(NULL, hServerSyncInt2, psRGXKickSyncIN->phServerSync, psRGXKickSyncIN->ui32ServerSyncCount * sizeof(IMG_HANDLE)) != PVRSRV_OK )
+				{
+					psRGXKickSyncOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
 
-				goto RGXKickSync_exit;
+					goto RGXKickSync_exit;
+				}
 			}
 	
 	{
-		uiUpdateFenceNameInt = OSAllocMemNoStats(32 * sizeof(IMG_CHAR));
-		if (!uiUpdateFenceNameInt)
-		{
-			psRGXKickSyncOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
-	
-			goto RGXKickSync_exit;
-		}
+		uiUpdateFenceNameInt = (IMG_CHAR*)(((IMG_UINT8 *)pArrayArgsBuffer) + ui32NextOffset);
+		ui32NextOffset += 32 * sizeof(IMG_CHAR);
 	}
 
 			/* Copy the data over */
-			if ( !OSAccessOK(PVR_VERIFY_READ, (void*) psRGXKickSyncIN->puiUpdateFenceName, 32 * sizeof(IMG_CHAR))
-				|| (OSCopyFromUser(NULL, uiUpdateFenceNameInt, psRGXKickSyncIN->puiUpdateFenceName,
-				32 * sizeof(IMG_CHAR)) != PVRSRV_OK) )
+			if (32 * sizeof(IMG_CHAR) > 0)
 			{
-				psRGXKickSyncOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
+				if ( OSCopyFromUser(NULL, uiUpdateFenceNameInt, psRGXKickSyncIN->puiUpdateFenceName, 32 * sizeof(IMG_CHAR)) != PVRSRV_OK )
+				{
+					psRGXKickSyncOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
 
-				goto RGXKickSync_exit;
+					goto RGXKickSync_exit;
+				}
 			}
 
+	/* Lock over handle lookup. */
+	LockHandle();
+
+
+
 
 
 				{
 					/* Look up the address from the handle */
 					psRGXKickSyncOUT->eError =
-						PVRSRVLookupHandle(psConnection->psHandleBase,
+						PVRSRVLookupHandleUnlocked(psConnection->psHandleBase,
 											(void **) &psKickSyncContextInt,
-											psRGXKickSyncIN->hKickSyncContext,
-											PVRSRV_HANDLE_TYPE_RGX_SERVER_KICKSYNC_CONTEXT);
+											hKickSyncContext,
+											PVRSRV_HANDLE_TYPE_RGX_SERVER_KICKSYNC_CONTEXT,
+											IMG_TRUE);
 					if(psRGXKickSyncOUT->eError != PVRSRV_OK)
 					{
+						UnlockHandle();
 						goto RGXKickSync_exit;
 					}
 				}
 
 
+
+
+
 	{
 		IMG_UINT32 i;
 
@@ -416,19 +489,24 @@
 				{
 					/* Look up the address from the handle */
 					psRGXKickSyncOUT->eError =
-						PVRSRVLookupHandle(psConnection->psHandleBase,
+						PVRSRVLookupHandleUnlocked(psConnection->psHandleBase,
 											(void **) &psFenceUFOSyncPrimBlockInt[i],
 											hFenceUFOSyncPrimBlockInt2[i],
-											PVRSRV_HANDLE_TYPE_SYNC_PRIMITIVE_BLOCK);
+											PVRSRV_HANDLE_TYPE_SYNC_PRIMITIVE_BLOCK,
+											IMG_TRUE);
 					if(psRGXKickSyncOUT->eError != PVRSRV_OK)
 					{
+						UnlockHandle();
 						goto RGXKickSync_exit;
 					}
 				}
-
 		}
 	}
 
+
+
+
+
 	{
 		IMG_UINT32 i;
 
@@ -437,19 +515,24 @@
 				{
 					/* Look up the address from the handle */
 					psRGXKickSyncOUT->eError =
-						PVRSRVLookupHandle(psConnection->psHandleBase,
+						PVRSRVLookupHandleUnlocked(psConnection->psHandleBase,
 											(void **) &psUpdateUFOSyncPrimBlockInt[i],
 											hUpdateUFOSyncPrimBlockInt2[i],
-											PVRSRV_HANDLE_TYPE_SYNC_PRIMITIVE_BLOCK);
+											PVRSRV_HANDLE_TYPE_SYNC_PRIMITIVE_BLOCK,
+											IMG_TRUE);
 					if(psRGXKickSyncOUT->eError != PVRSRV_OK)
 					{
+						UnlockHandle();
 						goto RGXKickSync_exit;
 					}
 				}
-
 		}
 	}
 
+
+
+
+
 	{
 		IMG_UINT32 i;
 
@@ -458,22 +541,26 @@
 				{
 					/* Look up the address from the handle */
 					psRGXKickSyncOUT->eError =
-						PVRSRVLookupHandle(psConnection->psHandleBase,
+						PVRSRVLookupHandleUnlocked(psConnection->psHandleBase,
 											(void **) &psServerSyncInt[i],
 											hServerSyncInt2[i],
-											PVRSRV_HANDLE_TYPE_SERVER_SYNC_PRIMITIVE);
+											PVRSRV_HANDLE_TYPE_SERVER_SYNC_PRIMITIVE,
+											IMG_TRUE);
 					if(psRGXKickSyncOUT->eError != PVRSRV_OK)
 					{
+						UnlockHandle();
 						goto RGXKickSync_exit;
 					}
 				}
-
 		}
 	}
+	/* Release now we have looked up handles. */
+	UnlockHandle();
 
 	psRGXKickSyncOUT->eError =
 		PVRSRVRGXKickSyncKM(
 					psKickSyncContextInt,
+					psRGXKickSyncIN->ui32ClientCacheOpSeqNum,
 					psRGXKickSyncIN->ui32ClientFenceCount,
 					psFenceUFOSyncPrimBlockInt,
 					ui32FenceSyncOffsetInt,
@@ -489,43 +576,119 @@
 					psRGXKickSyncIN->i32TimelineFenceFD,
 					&psRGXKickSyncOUT->i32UpdateFenceFD,
 					uiUpdateFenceNameInt,
-					psRGXKickSyncIN->ui32ExtJobRef,
-					psRGXKickSyncIN->ui32IntJobRef);
+					psRGXKickSyncIN->ui32ExtJobRef);
 
 
 
 
 RGXKickSync_exit:
-	if (psFenceUFOSyncPrimBlockInt)
-		OSFreeMemNoStats(psFenceUFOSyncPrimBlockInt);
+
+	/* Lock over handle lookup cleanup. */
+	LockHandle();
+
+
+
+
+
+
+				{
+					/* Unreference the previously looked up handle */
+						if(psKickSyncContextInt)
+						{
+							PVRSRVReleaseHandleUnlocked(psConnection->psHandleBase,
+											hKickSyncContext,
+											PVRSRV_HANDLE_TYPE_RGX_SERVER_KICKSYNC_CONTEXT);
+						}
+				}
+
+
+
+
+
+
 	if (hFenceUFOSyncPrimBlockInt2)
-		OSFreeMemNoStats(hFenceUFOSyncPrimBlockInt2);
-	if (ui32FenceSyncOffsetInt)
-		OSFreeMemNoStats(ui32FenceSyncOffsetInt);
-	if (ui32FenceValueInt)
-		OSFreeMemNoStats(ui32FenceValueInt);
-	if (psUpdateUFOSyncPrimBlockInt)
-		OSFreeMemNoStats(psUpdateUFOSyncPrimBlockInt);
+	{
+		IMG_UINT32 i;
+
+		for (i=0;i<psRGXKickSyncIN->ui32ClientFenceCount;i++)
+		{
+				{
+					/* Unreference the previously looked up handle */
+						if(psFenceUFOSyncPrimBlockInt[i])
+						{
+							PVRSRVReleaseHandleUnlocked(psConnection->psHandleBase,
+											hFenceUFOSyncPrimBlockInt2[i],
+											PVRSRV_HANDLE_TYPE_SYNC_PRIMITIVE_BLOCK);
+						}
+				}
+		}
+	}
+
+
+
+
+
+
 	if (hUpdateUFOSyncPrimBlockInt2)
-		OSFreeMemNoStats(hUpdateUFOSyncPrimBlockInt2);
-	if (ui32UpdateSyncOffsetInt)
-		OSFreeMemNoStats(ui32UpdateSyncOffsetInt);
-	if (ui32UpdateValueInt)
-		OSFreeMemNoStats(ui32UpdateValueInt);
-	if (ui32ServerSyncFlagsInt)
-		OSFreeMemNoStats(ui32ServerSyncFlagsInt);
-	if (psServerSyncInt)
-		OSFreeMemNoStats(psServerSyncInt);
+	{
+		IMG_UINT32 i;
+
+		for (i=0;i<psRGXKickSyncIN->ui32ClientUpdateCount;i++)
+		{
+				{
+					/* Unreference the previously looked up handle */
+						if(psUpdateUFOSyncPrimBlockInt[i])
+						{
+							PVRSRVReleaseHandleUnlocked(psConnection->psHandleBase,
+											hUpdateUFOSyncPrimBlockInt2[i],
+											PVRSRV_HANDLE_TYPE_SYNC_PRIMITIVE_BLOCK);
+						}
+				}
+		}
+	}
+
+
+
+
+
+
 	if (hServerSyncInt2)
-		OSFreeMemNoStats(hServerSyncInt2);
-	if (uiUpdateFenceNameInt)
-		OSFreeMemNoStats(uiUpdateFenceNameInt);
+	{
+		IMG_UINT32 i;
+
+		for (i=0;i<psRGXKickSyncIN->ui32ServerSyncCount;i++)
+		{
+				{
+					/* Unreference the previously looked up handle */
+						if(psServerSyncInt[i])
+						{
+							PVRSRVReleaseHandleUnlocked(psConnection->psHandleBase,
+											hServerSyncInt2[i],
+											PVRSRV_HANDLE_TYPE_SERVER_SYNC_PRIMITIVE);
+						}
+				}
+		}
+	}
+	/* Release now we have cleaned up look up handles. */
+	UnlockHandle();
+
+	/* Allocated space should be equal to the last updated offset */
+	PVR_ASSERT(ui32BufferSize == ui32NextOffset);
+
+#if defined(INTEGRITY_OS)
+	if(pArrayArgsBuffer)
+#else
+	if(!bHaveEnoughSpace && pArrayArgsBuffer)
+#endif
+		OSFreeMemNoStats(pArrayArgsBuffer);
+
 
 	return 0;
 }
 
 
 
+
 /* *************************************************************************** 
  * Server bridge dispatch related glue 
  */
@@ -561,4 +724,3 @@
 {
 	return PVRSRV_OK;
 }
-
diff --git a/drivers/staging/imgtec/rogue/generated/cachegeneric_bridge/client_cachegeneric_bridge.h b/drivers/staging/imgtec/rogue/generated/rgxpdump_bridge/client_rgxpdump_bridge.h
similarity index 82%
rename from drivers/staging/imgtec/rogue/generated/cachegeneric_bridge/client_cachegeneric_bridge.h
rename to drivers/staging/imgtec/rogue/generated/rgxpdump_bridge/client_rgxpdump_bridge.h
index 839a17a..bedac78 100644
--- a/drivers/staging/imgtec/rogue/generated/cachegeneric_bridge/client_cachegeneric_bridge.h
+++ b/drivers/staging/imgtec/rogue/generated/rgxpdump_bridge/client_rgxpdump_bridge.h
@@ -1,8 +1,8 @@
 /*************************************************************************/ /*!
 @File
-@Title          Client bridge header for cachegeneric
+@Title          Client bridge header for rgxpdump
 @Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
-@Description    Exports the client bridge functions for cachegeneric
+@Description    Exports the client bridge functions for rgxpdump
 @License        Dual MIT/GPLv2
 
 The contents of this file are subject to the MIT license as set out below.
@@ -41,8 +41,8 @@
 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */ /**************************************************************************/
 
-#ifndef CLIENT_CACHEGENERIC_BRIDGE_H
-#define CLIENT_CACHEGENERIC_BRIDGE_H
+#ifndef CLIENT_RGXPDUMP_BRIDGE_H
+#define CLIENT_RGXPDUMP_BRIDGE_H
 
 #include "img_defs.h"
 #include "pvrsrv_error.h"
@@ -52,13 +52,13 @@
 #include "pvr_bridge.h"
 #endif
 
-#include "common_cachegeneric_bridge.h"
+#include "common_rgxpdump_bridge.h"
 
-IMG_INTERNAL PVRSRV_ERROR IMG_CALLCONV BridgeCacheOpQueue(IMG_HANDLE hBridge,
-							  IMG_HANDLE hPMR,
-							  IMG_DEVMEM_OFFSET_T uiOffset,
-							  IMG_DEVMEM_SIZE_T uiSize,
-							  PVRSRV_CACHE_OP iuCacheOp);
+IMG_INTERNAL PVRSRV_ERROR IMG_CALLCONV BridgePDumpTraceBuffer(IMG_HANDLE hBridge,
+							      IMG_UINT32 ui32PDumpFlags);
+
+IMG_INTERNAL PVRSRV_ERROR IMG_CALLCONV BridgePDumpSignatureBuffer(IMG_HANDLE hBridge,
+								  IMG_UINT32 ui32PDumpFlags);
 
 
-#endif /* CLIENT_CACHEGENERIC_BRIDGE_H */
+#endif /* CLIENT_RGXPDUMP_BRIDGE_H */
diff --git a/drivers/staging/imgtec/rogue/generated/cachegeneric_bridge/client_cachegeneric_direct_bridge.c b/drivers/staging/imgtec/rogue/generated/rgxpdump_bridge/client_rgxpdump_direct_bridge.c
similarity index 78%
rename from drivers/staging/imgtec/rogue/generated/cachegeneric_bridge/client_cachegeneric_direct_bridge.c
rename to drivers/staging/imgtec/rogue/generated/rgxpdump_bridge/client_rgxpdump_direct_bridge.c
index d0cdf5a..e669f50 100644
--- a/drivers/staging/imgtec/rogue/generated/cachegeneric_bridge/client_cachegeneric_direct_bridge.c
+++ b/drivers/staging/imgtec/rogue/generated/rgxpdump_bridge/client_rgxpdump_direct_bridge.c
@@ -1,5 +1,5 @@
 /*************************************************************************/ /*!
-@Title          Direct client bridge for cachegeneric
+@Title          Direct client bridge for rgxpdump
 @Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
 @License        Dual MIT/GPLv2
 
@@ -39,34 +39,40 @@
 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */ /**************************************************************************/
 
-#include "client_cachegeneric_bridge.h"
+#include "client_rgxpdump_bridge.h"
 #include "img_defs.h"
 #include "pvr_debug.h"
 
 /* Module specific includes */
-#include "cache_external.h"
+#include "rgx_bridge.h"
 
-#include "cache_generic.h"
+#include "rgxpdump.h"
 
 
-IMG_INTERNAL PVRSRV_ERROR IMG_CALLCONV BridgeCacheOpQueue(IMG_HANDLE hBridge,
-							  IMG_HANDLE hPMR,
-							  IMG_DEVMEM_OFFSET_T uiOffset,
-							  IMG_DEVMEM_SIZE_T uiSize,
-							  PVRSRV_CACHE_OP iuCacheOp)
+IMG_INTERNAL PVRSRV_ERROR IMG_CALLCONV BridgePDumpTraceBuffer(IMG_HANDLE hBridge,
+							      IMG_UINT32 ui32PDumpFlags)
 {
 	PVRSRV_ERROR eError;
-	PMR * psPMRInt;
-	PVR_UNREFERENCED_PARAMETER(hBridge);
 
-	psPMRInt = (PMR *) hPMR;
 
 	eError =
-		CacheOpQueue(
-					psPMRInt,
-					uiOffset,
-					uiSize,
-					iuCacheOp);
+		PVRSRVPDumpTraceBufferKM(NULL, (PVRSRV_DEVICE_NODE *)((void*) hBridge)
+		,
+					ui32PDumpFlags);
+
+	return eError;
+}
+
+IMG_INTERNAL PVRSRV_ERROR IMG_CALLCONV BridgePDumpSignatureBuffer(IMG_HANDLE hBridge,
+								  IMG_UINT32 ui32PDumpFlags)
+{
+	PVRSRV_ERROR eError;
+
+
+	eError =
+		PVRSRVPDumpSignatureBufferKM(NULL, (PVRSRV_DEVICE_NODE *)((void*) hBridge)
+		,
+					ui32PDumpFlags);
 
 	return eError;
 }
diff --git a/drivers/staging/imgtec/rogue/generated/rgxpdump_bridge/common_rgxpdump_bridge.h b/drivers/staging/imgtec/rogue/generated/rgxpdump_bridge/common_rgxpdump_bridge.h
index d44bbe9..f1aacd5 100644
--- a/drivers/staging/imgtec/rogue/generated/rgxpdump_bridge/common_rgxpdump_bridge.h
+++ b/drivers/staging/imgtec/rogue/generated/rgxpdump_bridge/common_rgxpdump_bridge.h
@@ -2,8 +2,8 @@
 @File
 @Title          Common bridge header for rgxpdump
 @Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
-@Description    Declares common defines and structures that are used by both
-                the client and sever side of the bridge for rgxpdump
+@Description    Declares common defines and structures used by both the client
+                and server side of the bridge for rgxpdump
 @License        Dual MIT/GPLv2
 
 The contents of this file are subject to the MIT license as set out below.
@@ -45,6 +45,8 @@
 #ifndef COMMON_RGXPDUMP_BRIDGE_H
 #define COMMON_RGXPDUMP_BRIDGE_H
 
+#include <powervr/mem_types.h>
+
 #include "img_types.h"
 #include "pvrsrv_error.h"
 
diff --git a/drivers/staging/imgtec/rogue/generated/rgxpdump_bridge/server_rgxpdump_bridge.c b/drivers/staging/imgtec/rogue/generated/rgxpdump_bridge/server_rgxpdump_bridge.c
index 0b0edf3..152450d 100644
--- a/drivers/staging/imgtec/rogue/generated/rgxpdump_bridge/server_rgxpdump_bridge.c
+++ b/drivers/staging/imgtec/rogue/generated/rgxpdump_bridge/server_rgxpdump_bridge.c
@@ -64,6 +64,8 @@
 
 
 
+
+
 /* ***************************************************************************
  * Server-side bridge entry points
  */
@@ -81,6 +83,7 @@
 
 
 
+
 	psPDumpTraceBufferOUT->eError =
 		PVRSRVPDumpTraceBufferKM(psConnection, OSGetDevData(psConnection),
 					psPDumpTraceBufferIN->ui32PDumpFlags);
@@ -89,9 +92,13 @@
 
 
 
+
+
+
 	return 0;
 }
 
+
 static IMG_INT
 PVRSRVBridgePDumpSignatureBuffer(IMG_UINT32 ui32DispatchTableEntry,
 					  PVRSRV_BRIDGE_IN_PDUMPSIGNATUREBUFFER *psPDumpSignatureBufferIN,
@@ -105,6 +112,7 @@
 
 
 
+
 	psPDumpSignatureBufferOUT->eError =
 		PVRSRVPDumpSignatureBufferKM(psConnection, OSGetDevData(psConnection),
 					psPDumpSignatureBufferIN->ui32PDumpFlags);
@@ -113,11 +121,15 @@
 
 
 
+
+
+
 	return 0;
 }
 
 
 
+
 /* *************************************************************************** 
  * Server bridge dispatch related glue 
  */
@@ -150,4 +162,3 @@
 {
 	return PVRSRV_OK;
 }
-
diff --git a/drivers/staging/imgtec/rogue/generated/rgxray_bridge/common_rgxray_bridge.h b/drivers/staging/imgtec/rogue/generated/rgxray_bridge/common_rgxray_bridge.h
new file mode 100644
index 0000000..a76cc2e
--- /dev/null
+++ b/drivers/staging/imgtec/rogue/generated/rgxray_bridge/common_rgxray_bridge.h
@@ -0,0 +1,281 @@
+/*************************************************************************/ /*!
+@File
+@Title          Common bridge header for rgxray
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description    Declares common defines and structures used by both the client
+                and server side of the bridge for rgxray
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#ifndef COMMON_RGXRAY_BRIDGE_H
+#define COMMON_RGXRAY_BRIDGE_H
+
+#include <powervr/mem_types.h>
+
+#include "img_types.h"
+#include "pvrsrv_error.h"
+
+#include "rgx_bridge.h"
+#include "pvrsrv_devmem.h"
+#include "devicemem_typedefs.h"
+
+
+#define PVRSRV_BRIDGE_RGXRAY_CMD_FIRST			0
+#define PVRSRV_BRIDGE_RGXRAY_RGXCREATERPMFREELIST			PVRSRV_BRIDGE_RGXRAY_CMD_FIRST+0
+#define PVRSRV_BRIDGE_RGXRAY_RGXDESTROYRPMFREELIST			PVRSRV_BRIDGE_RGXRAY_CMD_FIRST+1
+#define PVRSRV_BRIDGE_RGXRAY_RGXCREATERPMCONTEXT			PVRSRV_BRIDGE_RGXRAY_CMD_FIRST+2
+#define PVRSRV_BRIDGE_RGXRAY_RGXDESTROYRPMCONTEXT			PVRSRV_BRIDGE_RGXRAY_CMD_FIRST+3
+#define PVRSRV_BRIDGE_RGXRAY_RGXKICKRS			PVRSRV_BRIDGE_RGXRAY_CMD_FIRST+4
+#define PVRSRV_BRIDGE_RGXRAY_RGXKICKVRDM			PVRSRV_BRIDGE_RGXRAY_CMD_FIRST+5
+#define PVRSRV_BRIDGE_RGXRAY_RGXCREATERAYCONTEXT			PVRSRV_BRIDGE_RGXRAY_CMD_FIRST+6
+#define PVRSRV_BRIDGE_RGXRAY_RGXDESTROYRAYCONTEXT			PVRSRV_BRIDGE_RGXRAY_CMD_FIRST+7
+#define PVRSRV_BRIDGE_RGXRAY_RGXSETRAYCONTEXTPRIORITY			PVRSRV_BRIDGE_RGXRAY_CMD_FIRST+8
+#define PVRSRV_BRIDGE_RGXRAY_CMD_LAST			(PVRSRV_BRIDGE_RGXRAY_CMD_FIRST+8)
+
+
+/*******************************************
+            RGXCreateRPMFreeList          
+ *******************************************/
+
+/* Bridge in structure for RGXCreateRPMFreeList */
+typedef struct PVRSRV_BRIDGE_IN_RGXCREATERPMFREELIST_TAG
+{
+	IMG_HANDLE hRPMContext;
+	IMG_UINT32 ui32InitFLPages;
+	IMG_UINT32 ui32GrowFLPages;
+	IMG_DEV_VIRTADDR sFreeListDevVAddr;
+	IMG_BOOL bIsExternal;
+} __attribute__((packed)) PVRSRV_BRIDGE_IN_RGXCREATERPMFREELIST;
+
+/* Bridge out structure for RGXCreateRPMFreeList */
+typedef struct PVRSRV_BRIDGE_OUT_RGXCREATERPMFREELIST_TAG
+{
+	IMG_HANDLE hCleanupCookie;
+	IMG_UINT32 ui32HWFreeList;
+	PVRSRV_ERROR eError;
+} __attribute__((packed)) PVRSRV_BRIDGE_OUT_RGXCREATERPMFREELIST;
+
+
+/*******************************************
+            RGXDestroyRPMFreeList          
+ *******************************************/
+
+/* Bridge in structure for RGXDestroyRPMFreeList */
+typedef struct PVRSRV_BRIDGE_IN_RGXDESTROYRPMFREELIST_TAG
+{
+	IMG_HANDLE hCleanupCookie;
+} __attribute__((packed)) PVRSRV_BRIDGE_IN_RGXDESTROYRPMFREELIST;
+
+/* Bridge out structure for RGXDestroyRPMFreeList */
+typedef struct PVRSRV_BRIDGE_OUT_RGXDESTROYRPMFREELIST_TAG
+{
+	PVRSRV_ERROR eError;
+} __attribute__((packed)) PVRSRV_BRIDGE_OUT_RGXDESTROYRPMFREELIST;
+
+
+/*******************************************
+            RGXCreateRPMContext          
+ *******************************************/
+
+/* Bridge in structure for RGXCreateRPMContext */
+typedef struct PVRSRV_BRIDGE_IN_RGXCREATERPMCONTEXT_TAG
+{
+	IMG_UINT32 ui32TotalRPMPages;
+	IMG_UINT32 ui32Log2DopplerPageSize;
+	IMG_DEV_VIRTADDR sSceneMemoryBaseAddr;
+	IMG_DEV_VIRTADDR sDopplerHeapBaseAddr;
+	IMG_HANDLE hSceneHeap;
+	IMG_DEV_VIRTADDR sRPMPageTableBaseAddr;
+	IMG_HANDLE hRPMPageTableHeap;
+} __attribute__((packed)) PVRSRV_BRIDGE_IN_RGXCREATERPMCONTEXT;
+
+/* Bridge out structure for RGXCreateRPMContext */
+typedef struct PVRSRV_BRIDGE_OUT_RGXCREATERPMCONTEXT_TAG
+{
+	IMG_HANDLE hCleanupCookie;
+	IMG_HANDLE hHWMemDesc;
+	IMG_UINT32 ui32HWFrameData;
+	PVRSRV_ERROR eError;
+} __attribute__((packed)) PVRSRV_BRIDGE_OUT_RGXCREATERPMCONTEXT;
+
+
+/*******************************************
+            RGXDestroyRPMContext          
+ *******************************************/
+
+/* Bridge in structure for RGXDestroyRPMContext */
+typedef struct PVRSRV_BRIDGE_IN_RGXDESTROYRPMCONTEXT_TAG
+{
+	IMG_HANDLE hCleanupCookie;
+} __attribute__((packed)) PVRSRV_BRIDGE_IN_RGXDESTROYRPMCONTEXT;
+
+/* Bridge out structure for RGXDestroyRPMContext */
+typedef struct PVRSRV_BRIDGE_OUT_RGXDESTROYRPMCONTEXT_TAG
+{
+	PVRSRV_ERROR eError;
+} __attribute__((packed)) PVRSRV_BRIDGE_OUT_RGXDESTROYRPMCONTEXT;
+
+
+/*******************************************
+            RGXKickRS          
+ *******************************************/
+
+/* Bridge in structure for RGXKickRS */
+typedef struct PVRSRV_BRIDGE_IN_RGXKICKRS_TAG
+{
+	IMG_HANDLE hRayContext;
+	IMG_UINT32 ui32ClientCacheOpSeqNum;
+	IMG_UINT32 ui32ClientFenceCount;
+	IMG_HANDLE * phClientFenceUFOSyncPrimBlock;
+	IMG_UINT32 * pui32ClientFenceSyncOffset;
+	IMG_UINT32 * pui32ClientFenceValue;
+	IMG_UINT32 ui32ClientUpdateCount;
+	IMG_HANDLE * phClientUpdateUFOSyncPrimBlock;
+	IMG_UINT32 * pui32ClientUpdateSyncOffset;
+	IMG_UINT32 * pui32ClientUpdateValue;
+	IMG_UINT32 ui32ServerSyncCount;
+	IMG_UINT32 * pui32ServerSyncFlags;
+	IMG_HANDLE * phServerSyncs;
+	IMG_UINT32 ui32CmdSize;
+	IMG_BYTE * psDMCmd;
+	IMG_UINT32 ui32FCCmdSize;
+	IMG_BYTE * psFCDMCmd;
+	IMG_UINT32 ui32FrameContext;
+	IMG_UINT32 ui32PDumpFlags;
+	IMG_UINT32 ui32ExtJobRef;
+} __attribute__((packed)) PVRSRV_BRIDGE_IN_RGXKICKRS;
+
+/* Bridge out structure for RGXKickRS */
+typedef struct PVRSRV_BRIDGE_OUT_RGXKICKRS_TAG
+{
+	PVRSRV_ERROR eError;
+} __attribute__((packed)) PVRSRV_BRIDGE_OUT_RGXKICKRS;
+
+
+/*******************************************
+            RGXKickVRDM          
+ *******************************************/
+
+/* Bridge in structure for RGXKickVRDM */
+typedef struct PVRSRV_BRIDGE_IN_RGXKICKVRDM_TAG
+{
+	IMG_HANDLE hRayContext;
+	IMG_UINT32 ui32ClientCacheOpSeqNum;
+	IMG_UINT32 ui32ClientFenceCount;
+	IMG_HANDLE * phClientFenceUFOSyncPrimBlock;
+	IMG_UINT32 * pui32ClientFenceSyncOffset;
+	IMG_UINT32 * pui32ClientFenceValue;
+	IMG_UINT32 ui32ClientUpdateCount;
+	IMG_HANDLE * phClientUpdateUFOSyncPrimBlock;
+	IMG_UINT32 * pui32ClientUpdateSyncOffset;
+	IMG_UINT32 * pui32ClientUpdateValue;
+	IMG_UINT32 ui32ServerSyncCount;
+	IMG_UINT32 * pui32ServerSyncFlags;
+	IMG_HANDLE * phServerSyncs;
+	IMG_UINT32 ui32CmdSize;
+	IMG_BYTE * psDMCmd;
+	IMG_UINT32 ui32PDumpFlags;
+	IMG_UINT32 ui32ExtJobRef;
+} __attribute__((packed)) PVRSRV_BRIDGE_IN_RGXKICKVRDM;
+
+/* Bridge out structure for RGXKickVRDM */
+typedef struct PVRSRV_BRIDGE_OUT_RGXKICKVRDM_TAG
+{
+	PVRSRV_ERROR eError;
+} __attribute__((packed)) PVRSRV_BRIDGE_OUT_RGXKICKVRDM;
+
+
+/*******************************************
+            RGXCreateRayContext          
+ *******************************************/
+
+/* Bridge in structure for RGXCreateRayContext */
+typedef struct PVRSRV_BRIDGE_IN_RGXCREATERAYCONTEXT_TAG
+{
+	IMG_UINT32 ui32Priority;
+	IMG_DEV_VIRTADDR sMCUFenceAddr;
+	IMG_DEV_VIRTADDR sVRMCallStackAddr;
+	IMG_UINT32 ui32FrameworkCmdSize;
+	IMG_BYTE * psFrameworkCmd;
+	IMG_HANDLE hPrivData;
+} __attribute__((packed)) PVRSRV_BRIDGE_IN_RGXCREATERAYCONTEXT;
+
+/* Bridge out structure for RGXCreateRayContext */
+typedef struct PVRSRV_BRIDGE_OUT_RGXCREATERAYCONTEXT_TAG
+{
+	IMG_HANDLE hRayContext;
+	PVRSRV_ERROR eError;
+} __attribute__((packed)) PVRSRV_BRIDGE_OUT_RGXCREATERAYCONTEXT;
+
+
+/*******************************************
+            RGXDestroyRayContext          
+ *******************************************/
+
+/* Bridge in structure for RGXDestroyRayContext */
+typedef struct PVRSRV_BRIDGE_IN_RGXDESTROYRAYCONTEXT_TAG
+{
+	IMG_HANDLE hRayContext;
+} __attribute__((packed)) PVRSRV_BRIDGE_IN_RGXDESTROYRAYCONTEXT;
+
+/* Bridge out structure for RGXDestroyRayContext */
+typedef struct PVRSRV_BRIDGE_OUT_RGXDESTROYRAYCONTEXT_TAG
+{
+	PVRSRV_ERROR eError;
+} __attribute__((packed)) PVRSRV_BRIDGE_OUT_RGXDESTROYRAYCONTEXT;
+
+
+/*******************************************
+            RGXSetRayContextPriority          
+ *******************************************/
+
+/* Bridge in structure for RGXSetRayContextPriority */
+typedef struct PVRSRV_BRIDGE_IN_RGXSETRAYCONTEXTPRIORITY_TAG
+{
+	IMG_HANDLE hRayContext;
+	IMG_UINT32 ui32Priority;
+} __attribute__((packed)) PVRSRV_BRIDGE_IN_RGXSETRAYCONTEXTPRIORITY;
+
+/* Bridge out structure for RGXSetRayContextPriority */
+typedef struct PVRSRV_BRIDGE_OUT_RGXSETRAYCONTEXTPRIORITY_TAG
+{
+	PVRSRV_ERROR eError;
+} __attribute__((packed)) PVRSRV_BRIDGE_OUT_RGXSETRAYCONTEXTPRIORITY;
+
+
+#endif /* COMMON_RGXRAY_BRIDGE_H */
diff --git a/drivers/staging/imgtec/rogue/generated/rgxray_bridge/server_rgxray_bridge.c b/drivers/staging/imgtec/rogue/generated/rgxray_bridge/server_rgxray_bridge.c
new file mode 100644
index 0000000..2246f93
--- /dev/null
+++ b/drivers/staging/imgtec/rogue/generated/rgxray_bridge/server_rgxray_bridge.c
@@ -0,0 +1,1887 @@
+/*************************************************************************/ /*!
+@File
+@Title          Server bridge for rgxray
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description    Implements the server side of the bridge for rgxray
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#include <stddef.h>
+#include <asm/uaccess.h>
+
+#include "img_defs.h"
+
+#include "rgxray.h"
+#include "devicemem_server.h"
+
+
+#include "common_rgxray_bridge.h"
+
+#include "allocmem.h"
+#include "pvr_debug.h"
+#include "connection_server.h"
+#include "pvr_bridge.h"
+#include "rgx_bridge.h"
+#include "srvcore.h"
+#include "handle.h"
+
+#include <linux/slab.h>
+
+
+#include "rgx_bvnc_defs_km.h"
+
+
+
+
+/* ***************************************************************************
+ * Server-side bridge entry points
+ */
+ 
+static IMG_INT
+PVRSRVBridgeRGXCreateRPMFreeList(IMG_UINT32 ui32DispatchTableEntry,
+					  PVRSRV_BRIDGE_IN_RGXCREATERPMFREELIST *psRGXCreateRPMFreeListIN,
+					  PVRSRV_BRIDGE_OUT_RGXCREATERPMFREELIST *psRGXCreateRPMFreeListOUT,
+					 CONNECTION_DATA *psConnection)
+{
+	IMG_HANDLE hRPMContext = psRGXCreateRPMFreeListIN->hRPMContext;
+	RGX_SERVER_RPM_CONTEXT * psRPMContextInt = NULL;
+	RGX_RPM_FREELIST * psCleanupCookieInt = NULL;
+
+
+	{
+		PVRSRV_DEVICE_NODE *psDeviceNode = OSGetDevData(psConnection);
+
+		/* Check that device supports the required feature */
+		if ((psDeviceNode->pfnCheckDeviceFeature) &&
+			!psDeviceNode->pfnCheckDeviceFeature(psDeviceNode, RGX_FEATURE_RAY_TRACING_BIT_MASK))
+		{
+			psRGXCreateRPMFreeListOUT->eError = PVRSRV_ERROR_NOT_SUPPORTED;
+
+			goto RGXCreateRPMFreeList_exit;
+		}
+	}
+
+
+
+
+
+	/* Lock over handle lookup. */
+	LockHandle();
+
+
+
+
+
+				{
+					/* Look up the address from the handle */
+					psRGXCreateRPMFreeListOUT->eError =
+						PVRSRVLookupHandleUnlocked(psConnection->psHandleBase,
+											(void **) &psRPMContextInt,
+											hRPMContext,
+											PVRSRV_HANDLE_TYPE_RGX_SERVER_RPM_CONTEXT,
+											IMG_TRUE);
+					if(psRGXCreateRPMFreeListOUT->eError != PVRSRV_OK)
+					{
+						UnlockHandle();
+						goto RGXCreateRPMFreeList_exit;
+					}
+				}
+	/* Release now we have looked up handles. */
+	UnlockHandle();
+
+	psRGXCreateRPMFreeListOUT->eError =
+		RGXCreateRPMFreeList(psConnection, OSGetDevData(psConnection),
+					psRPMContextInt,
+					psRGXCreateRPMFreeListIN->ui32InitFLPages,
+					psRGXCreateRPMFreeListIN->ui32GrowFLPages,
+					psRGXCreateRPMFreeListIN->sFreeListDevVAddr,
+					&psCleanupCookieInt,
+					&psRGXCreateRPMFreeListOUT->ui32HWFreeList,
+					psRGXCreateRPMFreeListIN->bIsExternal);
+	/* Exit early if bridged call fails */
+	if(psRGXCreateRPMFreeListOUT->eError != PVRSRV_OK)
+	{
+		goto RGXCreateRPMFreeList_exit;
+	}
+
+	/* Lock over handle creation. */
+	LockHandle();
+
+
+
+
+
+	psRGXCreateRPMFreeListOUT->eError = PVRSRVAllocHandleUnlocked(psConnection->psHandleBase,
+
+							&psRGXCreateRPMFreeListOUT->hCleanupCookie,
+							(void *) psCleanupCookieInt,
+							PVRSRV_HANDLE_TYPE_RGX_RPM_FREELIST,
+							PVRSRV_HANDLE_ALLOC_FLAG_NONE
+							,(PFN_HANDLE_RELEASE)&RGXDestroyRPMFreeList);
+	if (psRGXCreateRPMFreeListOUT->eError != PVRSRV_OK)
+	{
+		UnlockHandle();
+		goto RGXCreateRPMFreeList_exit;
+	}
+
+	/* Release now we have created handles. */
+	UnlockHandle();
+
+
+
+RGXCreateRPMFreeList_exit:
+
+	/* Lock over handle lookup cleanup. */
+	LockHandle();
+
+
+
+
+
+
+				{
+					/* Unreference the previously looked up handle */
+						if(psRPMContextInt)
+						{
+							PVRSRVReleaseHandleUnlocked(psConnection->psHandleBase,
+											hRPMContext,
+											PVRSRV_HANDLE_TYPE_RGX_SERVER_RPM_CONTEXT);
+						}
+				}
+	/* Release now we have cleaned up look up handles. */
+	UnlockHandle();
+
+	if (psRGXCreateRPMFreeListOUT->eError != PVRSRV_OK)
+	{
+		if (psCleanupCookieInt)
+		{
+			RGXDestroyRPMFreeList(psCleanupCookieInt);
+		}
+	}
+
+
+	return 0;
+}
+
+
+static IMG_INT
+PVRSRVBridgeRGXDestroyRPMFreeList(IMG_UINT32 ui32DispatchTableEntry,
+					  PVRSRV_BRIDGE_IN_RGXDESTROYRPMFREELIST *psRGXDestroyRPMFreeListIN,
+					  PVRSRV_BRIDGE_OUT_RGXDESTROYRPMFREELIST *psRGXDestroyRPMFreeListOUT,
+					 CONNECTION_DATA *psConnection)
+{
+
+
+	{
+		PVRSRV_DEVICE_NODE *psDeviceNode = OSGetDevData(psConnection);
+
+		/* Check that device supports the required feature */
+		if ((psDeviceNode->pfnCheckDeviceFeature) &&
+			!psDeviceNode->pfnCheckDeviceFeature(psDeviceNode, RGX_FEATURE_RAY_TRACING_BIT_MASK))
+		{
+			psRGXDestroyRPMFreeListOUT->eError = PVRSRV_ERROR_NOT_SUPPORTED;
+
+			goto RGXDestroyRPMFreeList_exit;
+		}
+	}
+
+
+
+
+
+
+
+	/* Lock over handle destruction. */
+	LockHandle();
+
+
+
+
+
+	psRGXDestroyRPMFreeListOUT->eError =
+		PVRSRVReleaseHandleUnlocked(psConnection->psHandleBase,
+					(IMG_HANDLE) psRGXDestroyRPMFreeListIN->hCleanupCookie,
+					PVRSRV_HANDLE_TYPE_RGX_RPM_FREELIST);
+	if ((psRGXDestroyRPMFreeListOUT->eError != PVRSRV_OK) &&
+	    (psRGXDestroyRPMFreeListOUT->eError != PVRSRV_ERROR_RETRY))
+	{
+		PVR_DPF((PVR_DBG_ERROR,
+		        "PVRSRVBridgeRGXDestroyRPMFreeList: %s",
+		        PVRSRVGetErrorStringKM(psRGXDestroyRPMFreeListOUT->eError)));
+		PVR_ASSERT(0);
+		UnlockHandle();
+		goto RGXDestroyRPMFreeList_exit;
+	}
+
+	/* Release now we have destroyed handles. */
+	UnlockHandle();
+
+
+
+RGXDestroyRPMFreeList_exit:
+
+
+
+
+	return 0;
+}
+
+
+static IMG_INT
+PVRSRVBridgeRGXCreateRPMContext(IMG_UINT32 ui32DispatchTableEntry,
+					  PVRSRV_BRIDGE_IN_RGXCREATERPMCONTEXT *psRGXCreateRPMContextIN,
+					  PVRSRV_BRIDGE_OUT_RGXCREATERPMCONTEXT *psRGXCreateRPMContextOUT,
+					 CONNECTION_DATA *psConnection)
+{
+	RGX_SERVER_RPM_CONTEXT * psCleanupCookieInt = NULL;
+	IMG_HANDLE hSceneHeap = psRGXCreateRPMContextIN->hSceneHeap;
+	DEVMEMINT_HEAP * psSceneHeapInt = NULL;
+	IMG_HANDLE hRPMPageTableHeap = psRGXCreateRPMContextIN->hRPMPageTableHeap;
+	DEVMEMINT_HEAP * psRPMPageTableHeapInt = NULL;
+	DEVMEM_MEMDESC * psHWMemDescInt = NULL;
+
+
+	{
+		PVRSRV_DEVICE_NODE *psDeviceNode = OSGetDevData(psConnection);
+
+		/* Check that device supports the required feature */
+		if ((psDeviceNode->pfnCheckDeviceFeature) &&
+			!psDeviceNode->pfnCheckDeviceFeature(psDeviceNode, RGX_FEATURE_RAY_TRACING_BIT_MASK))
+		{
+			psRGXCreateRPMContextOUT->eError = PVRSRV_ERROR_NOT_SUPPORTED;
+
+			goto RGXCreateRPMContext_exit;
+		}
+	}
+
+
+
+	psRGXCreateRPMContextOUT->hCleanupCookie = NULL;
+
+
+	/* Lock over handle lookup. */
+	LockHandle();
+
+
+
+
+
+				{
+					/* Look up the address from the handle */
+					psRGXCreateRPMContextOUT->eError =
+						PVRSRVLookupHandleUnlocked(psConnection->psHandleBase,
+											(void **) &psSceneHeapInt,
+											hSceneHeap,
+											PVRSRV_HANDLE_TYPE_DEVMEMINT_HEAP,
+											IMG_TRUE);
+					if(psRGXCreateRPMContextOUT->eError != PVRSRV_OK)
+					{
+						UnlockHandle();
+						goto RGXCreateRPMContext_exit;
+					}
+				}
+
+
+
+
+
+				{
+					/* Look up the address from the handle */
+					psRGXCreateRPMContextOUT->eError =
+						PVRSRVLookupHandleUnlocked(psConnection->psHandleBase,
+											(void **) &psRPMPageTableHeapInt,
+											hRPMPageTableHeap,
+											PVRSRV_HANDLE_TYPE_DEVMEMINT_HEAP,
+											IMG_TRUE);
+					if(psRGXCreateRPMContextOUT->eError != PVRSRV_OK)
+					{
+						UnlockHandle();
+						goto RGXCreateRPMContext_exit;
+					}
+				}
+	/* Release now we have looked up handles. */
+	UnlockHandle();
+
+	psRGXCreateRPMContextOUT->eError =
+		RGXCreateRPMContext(psConnection, OSGetDevData(psConnection),
+					&psCleanupCookieInt,
+					psRGXCreateRPMContextIN->ui32TotalRPMPages,
+					psRGXCreateRPMContextIN->ui32Log2DopplerPageSize,
+					psRGXCreateRPMContextIN->sSceneMemoryBaseAddr,
+					psRGXCreateRPMContextIN->sDopplerHeapBaseAddr,
+					psSceneHeapInt,
+					psRGXCreateRPMContextIN->sRPMPageTableBaseAddr,
+					psRPMPageTableHeapInt,
+					&psHWMemDescInt,
+					&psRGXCreateRPMContextOUT->ui32HWFrameData);
+	/* Exit early if bridged call fails */
+	if(psRGXCreateRPMContextOUT->eError != PVRSRV_OK)
+	{
+		goto RGXCreateRPMContext_exit;
+	}
+
+	/* Lock over handle creation. */
+	LockHandle();
+
+
+
+
+
+	psRGXCreateRPMContextOUT->eError = PVRSRVAllocHandleUnlocked(psConnection->psHandleBase,
+
+							&psRGXCreateRPMContextOUT->hCleanupCookie,
+							(void *) psCleanupCookieInt,
+							PVRSRV_HANDLE_TYPE_RGX_SERVER_RPM_CONTEXT,
+							PVRSRV_HANDLE_ALLOC_FLAG_NONE
+							,(PFN_HANDLE_RELEASE)&RGXDestroyRPMContext);
+	if (psRGXCreateRPMContextOUT->eError != PVRSRV_OK)
+	{
+		UnlockHandle();
+		goto RGXCreateRPMContext_exit;
+	}
+
+
+
+
+
+
+	psRGXCreateRPMContextOUT->eError = PVRSRVAllocSubHandleUnlocked(psConnection->psHandleBase,
+
+							&psRGXCreateRPMContextOUT->hHWMemDesc,
+							(void *) psHWMemDescInt,
+							PVRSRV_HANDLE_TYPE_RGX_FW_MEMDESC,
+							PVRSRV_HANDLE_ALLOC_FLAG_NONE
+							,psRGXCreateRPMContextOUT->hCleanupCookie);
+	if (psRGXCreateRPMContextOUT->eError != PVRSRV_OK)
+	{
+		UnlockHandle();
+		goto RGXCreateRPMContext_exit;
+	}
+
+	/* Release now we have created handles. */
+	UnlockHandle();
+
+
+
+RGXCreateRPMContext_exit:
+
+	/* Lock over handle lookup cleanup. */
+	LockHandle();
+
+
+
+
+
+
+				{
+					/* Unreference the previously looked up handle */
+						if(psSceneHeapInt)
+						{
+							PVRSRVReleaseHandleUnlocked(psConnection->psHandleBase,
+											hSceneHeap,
+											PVRSRV_HANDLE_TYPE_DEVMEMINT_HEAP);
+						}
+				}
+
+
+
+
+
+				{
+					/* Unreference the previously looked up handle */
+						if(psRPMPageTableHeapInt)
+						{
+							PVRSRVReleaseHandleUnlocked(psConnection->psHandleBase,
+											hRPMPageTableHeap,
+											PVRSRV_HANDLE_TYPE_DEVMEMINT_HEAP);
+						}
+				}
+	/* Release now we have cleaned up look up handles. */
+	UnlockHandle();
+
+	if (psRGXCreateRPMContextOUT->eError != PVRSRV_OK)
+	{
+		/* Lock over handle creation cleanup. */
+		LockHandle();
+		if (psRGXCreateRPMContextOUT->hCleanupCookie)
+		{
+
+
+			PVRSRV_ERROR eError = PVRSRVReleaseHandleUnlocked(psConnection->psHandleBase,
+						(IMG_HANDLE) psRGXCreateRPMContextOUT->hCleanupCookie,
+						PVRSRV_HANDLE_TYPE_RGX_SERVER_RPM_CONTEXT);
+			if ((eError != PVRSRV_OK) && (eError != PVRSRV_ERROR_RETRY))
+			{
+				PVR_DPF((PVR_DBG_ERROR,
+				        "PVRSRVBridgeRGXCreateRPMContext: %s",
+				        PVRSRVGetErrorStringKM(eError)));
+			}
+			/* Releasing the handle should free/destroy/release the resource.
+			 * This should never fail... */
+			PVR_ASSERT((eError == PVRSRV_OK) || (eError == PVRSRV_ERROR_RETRY));
+
+			/* Avoid freeing/destroying/releasing the resource a second time below */
+			psCleanupCookieInt = NULL;
+		}
+
+
+		/* Release now we have cleaned up creation handles. */
+		UnlockHandle();
+		if (psCleanupCookieInt)
+		{
+			RGXDestroyRPMContext(psCleanupCookieInt);
+		}
+	}
+
+
+	return 0;
+}
+
+
+static IMG_INT
+PVRSRVBridgeRGXDestroyRPMContext(IMG_UINT32 ui32DispatchTableEntry,
+					  PVRSRV_BRIDGE_IN_RGXDESTROYRPMCONTEXT *psRGXDestroyRPMContextIN,
+					  PVRSRV_BRIDGE_OUT_RGXDESTROYRPMCONTEXT *psRGXDestroyRPMContextOUT,
+					 CONNECTION_DATA *psConnection)
+{
+
+
+	{
+		PVRSRV_DEVICE_NODE *psDeviceNode = OSGetDevData(psConnection);
+
+		/* Check that device supports the required feature */
+		if ((psDeviceNode->pfnCheckDeviceFeature) &&
+			!psDeviceNode->pfnCheckDeviceFeature(psDeviceNode, RGX_FEATURE_RAY_TRACING_BIT_MASK))
+		{
+			psRGXDestroyRPMContextOUT->eError = PVRSRV_ERROR_NOT_SUPPORTED;
+
+			goto RGXDestroyRPMContext_exit;
+		}
+	}
+
+
+
+
+
+
+
+	/* Lock over handle destruction. */
+	LockHandle();
+
+
+
+
+
+	psRGXDestroyRPMContextOUT->eError =
+		PVRSRVReleaseHandleUnlocked(psConnection->psHandleBase,
+					(IMG_HANDLE) psRGXDestroyRPMContextIN->hCleanupCookie,
+					PVRSRV_HANDLE_TYPE_RGX_SERVER_RPM_CONTEXT);
+	if ((psRGXDestroyRPMContextOUT->eError != PVRSRV_OK) &&
+	    (psRGXDestroyRPMContextOUT->eError != PVRSRV_ERROR_RETRY))
+	{
+		PVR_DPF((PVR_DBG_ERROR,
+		        "PVRSRVBridgeRGXDestroyRPMContext: %s",
+		        PVRSRVGetErrorStringKM(psRGXDestroyRPMContextOUT->eError)));
+		PVR_ASSERT(0);
+		UnlockHandle();
+		goto RGXDestroyRPMContext_exit;
+	}
+
+	/* Release now we have destroyed handles. */
+	UnlockHandle();
+
+
+
+RGXDestroyRPMContext_exit:
+
+
+
+
+	return 0;
+}
+
+
+static IMG_INT
+PVRSRVBridgeRGXKickRS(IMG_UINT32 ui32DispatchTableEntry,
+					  PVRSRV_BRIDGE_IN_RGXKICKRS *psRGXKickRSIN,
+					  PVRSRV_BRIDGE_OUT_RGXKICKRS *psRGXKickRSOUT,
+					 CONNECTION_DATA *psConnection)
+{
+	IMG_HANDLE hRayContext = psRGXKickRSIN->hRayContext;
+	RGX_SERVER_RAY_CONTEXT * psRayContextInt = NULL;
+	SYNC_PRIMITIVE_BLOCK * *psClientFenceUFOSyncPrimBlockInt = NULL;
+	IMG_HANDLE *hClientFenceUFOSyncPrimBlockInt2 = NULL;
+	IMG_UINT32 *ui32ClientFenceSyncOffsetInt = NULL;
+	IMG_UINT32 *ui32ClientFenceValueInt = NULL;
+	SYNC_PRIMITIVE_BLOCK * *psClientUpdateUFOSyncPrimBlockInt = NULL;
+	IMG_HANDLE *hClientUpdateUFOSyncPrimBlockInt2 = NULL;
+	IMG_UINT32 *ui32ClientUpdateSyncOffsetInt = NULL;
+	IMG_UINT32 *ui32ClientUpdateValueInt = NULL;
+	IMG_UINT32 *ui32ServerSyncFlagsInt = NULL;
+	SERVER_SYNC_PRIMITIVE * *psServerSyncsInt = NULL;
+	IMG_HANDLE *hServerSyncsInt2 = NULL;
+	IMG_BYTE *psDMCmdInt = NULL;
+	IMG_BYTE *psFCDMCmdInt = NULL;
+
+	IMG_UINT32 ui32NextOffset = 0;
+	IMG_BYTE   *pArrayArgsBuffer = NULL;
+#if !defined(INTEGRITY_OS)
+	IMG_BOOL bHaveEnoughSpace = IMG_FALSE;
+#endif
+
+	IMG_UINT32 ui32BufferSize = 
+			(psRGXKickRSIN->ui32ClientFenceCount * sizeof(SYNC_PRIMITIVE_BLOCK *)) +
+			(psRGXKickRSIN->ui32ClientFenceCount * sizeof(IMG_HANDLE)) +
+			(psRGXKickRSIN->ui32ClientFenceCount * sizeof(IMG_UINT32)) +
+			(psRGXKickRSIN->ui32ClientFenceCount * sizeof(IMG_UINT32)) +
+			(psRGXKickRSIN->ui32ClientUpdateCount * sizeof(SYNC_PRIMITIVE_BLOCK *)) +
+			(psRGXKickRSIN->ui32ClientUpdateCount * sizeof(IMG_HANDLE)) +
+			(psRGXKickRSIN->ui32ClientUpdateCount * sizeof(IMG_UINT32)) +
+			(psRGXKickRSIN->ui32ClientUpdateCount * sizeof(IMG_UINT32)) +
+			(psRGXKickRSIN->ui32ServerSyncCount * sizeof(IMG_UINT32)) +
+			(psRGXKickRSIN->ui32ServerSyncCount * sizeof(SERVER_SYNC_PRIMITIVE *)) +
+			(psRGXKickRSIN->ui32ServerSyncCount * sizeof(IMG_HANDLE)) +
+			(psRGXKickRSIN->ui32CmdSize * sizeof(IMG_BYTE)) +
+			(psRGXKickRSIN->ui32FCCmdSize * sizeof(IMG_BYTE)) +
+			0;
+
+	{
+		PVRSRV_DEVICE_NODE *psDeviceNode = OSGetDevData(psConnection);
+
+		/* Check that device supports the required feature */
+		if ((psDeviceNode->pfnCheckDeviceFeature) &&
+			!psDeviceNode->pfnCheckDeviceFeature(psDeviceNode, RGX_FEATURE_RAY_TRACING_BIT_MASK))
+		{
+			psRGXKickRSOUT->eError = PVRSRV_ERROR_NOT_SUPPORTED;
+
+			goto RGXKickRS_exit;
+		}
+	}
+
+
+
+
+	if (ui32BufferSize != 0)
+	{
+#if !defined(INTEGRITY_OS)
+		/* Try to use remainder of input buffer for copies if possible, word-aligned for safety. */
+		IMG_UINT32 ui32InBufferOffset = PVR_ALIGN(sizeof(*psRGXKickRSIN), sizeof(unsigned long));
+		IMG_UINT32 ui32InBufferExcessSize = ui32InBufferOffset >= PVRSRV_MAX_BRIDGE_IN_SIZE ? 0 :
+			PVRSRV_MAX_BRIDGE_IN_SIZE - ui32InBufferOffset;
+
+		bHaveEnoughSpace = ui32BufferSize <= ui32InBufferExcessSize;
+		if (bHaveEnoughSpace)
+		{
+			IMG_BYTE *pInputBuffer = (IMG_BYTE *)psRGXKickRSIN;
+
+			pArrayArgsBuffer = &pInputBuffer[ui32InBufferOffset];		}
+		else
+#endif
+		{
+			pArrayArgsBuffer = OSAllocMemNoStats(ui32BufferSize);
+
+			if(!pArrayArgsBuffer)
+			{
+				psRGXKickRSOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
+				goto RGXKickRS_exit;
+			}
+		}
+	}
+
+	if (psRGXKickRSIN->ui32ClientFenceCount != 0)
+	{
+		psClientFenceUFOSyncPrimBlockInt = (SYNC_PRIMITIVE_BLOCK **)(((IMG_UINT8 *)pArrayArgsBuffer) + ui32NextOffset);
+		ui32NextOffset += psRGXKickRSIN->ui32ClientFenceCount * sizeof(SYNC_PRIMITIVE_BLOCK *);
+		hClientFenceUFOSyncPrimBlockInt2 = (IMG_HANDLE *)(((IMG_UINT8 *)pArrayArgsBuffer) + ui32NextOffset); 
+		ui32NextOffset += psRGXKickRSIN->ui32ClientFenceCount * sizeof(IMG_HANDLE);
+	}
+
+			/* Copy the data over */
+			if (psRGXKickRSIN->ui32ClientFenceCount * sizeof(IMG_HANDLE) > 0)
+			{
+				if ( OSCopyFromUser(NULL, hClientFenceUFOSyncPrimBlockInt2, psRGXKickRSIN->phClientFenceUFOSyncPrimBlock, psRGXKickRSIN->ui32ClientFenceCount * sizeof(IMG_HANDLE)) != PVRSRV_OK )
+				{
+					psRGXKickRSOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
+
+					goto RGXKickRS_exit;
+				}
+			}
+	if (psRGXKickRSIN->ui32ClientFenceCount != 0)
+	{
+		ui32ClientFenceSyncOffsetInt = (IMG_UINT32*)(((IMG_UINT8 *)pArrayArgsBuffer) + ui32NextOffset);
+		ui32NextOffset += psRGXKickRSIN->ui32ClientFenceCount * sizeof(IMG_UINT32);
+	}
+
+			/* Copy the data over */
+			if (psRGXKickRSIN->ui32ClientFenceCount * sizeof(IMG_UINT32) > 0)
+			{
+				if ( OSCopyFromUser(NULL, ui32ClientFenceSyncOffsetInt, psRGXKickRSIN->pui32ClientFenceSyncOffset, psRGXKickRSIN->ui32ClientFenceCount * sizeof(IMG_UINT32)) != PVRSRV_OK )
+				{
+					psRGXKickRSOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
+
+					goto RGXKickRS_exit;
+				}
+			}
+	if (psRGXKickRSIN->ui32ClientFenceCount != 0)
+	{
+		ui32ClientFenceValueInt = (IMG_UINT32*)(((IMG_UINT8 *)pArrayArgsBuffer) + ui32NextOffset);
+		ui32NextOffset += psRGXKickRSIN->ui32ClientFenceCount * sizeof(IMG_UINT32);
+	}
+
+			/* Copy the data over */
+			if (psRGXKickRSIN->ui32ClientFenceCount * sizeof(IMG_UINT32) > 0)
+			{
+				if ( OSCopyFromUser(NULL, ui32ClientFenceValueInt, psRGXKickRSIN->pui32ClientFenceValue, psRGXKickRSIN->ui32ClientFenceCount * sizeof(IMG_UINT32)) != PVRSRV_OK )
+				{
+					psRGXKickRSOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
+
+					goto RGXKickRS_exit;
+				}
+			}
+	if (psRGXKickRSIN->ui32ClientUpdateCount != 0)
+	{
+		psClientUpdateUFOSyncPrimBlockInt = (SYNC_PRIMITIVE_BLOCK **)(((IMG_UINT8 *)pArrayArgsBuffer) + ui32NextOffset);
+		ui32NextOffset += psRGXKickRSIN->ui32ClientUpdateCount * sizeof(SYNC_PRIMITIVE_BLOCK *);
+		hClientUpdateUFOSyncPrimBlockInt2 = (IMG_HANDLE *)(((IMG_UINT8 *)pArrayArgsBuffer) + ui32NextOffset); 
+		ui32NextOffset += psRGXKickRSIN->ui32ClientUpdateCount * sizeof(IMG_HANDLE);
+	}
+
+			/* Copy the data over */
+			if (psRGXKickRSIN->ui32ClientUpdateCount * sizeof(IMG_HANDLE) > 0)
+			{
+				if ( OSCopyFromUser(NULL, hClientUpdateUFOSyncPrimBlockInt2, psRGXKickRSIN->phClientUpdateUFOSyncPrimBlock, psRGXKickRSIN->ui32ClientUpdateCount * sizeof(IMG_HANDLE)) != PVRSRV_OK )
+				{
+					psRGXKickRSOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
+
+					goto RGXKickRS_exit;
+				}
+			}
+	if (psRGXKickRSIN->ui32ClientUpdateCount != 0)
+	{
+		ui32ClientUpdateSyncOffsetInt = (IMG_UINT32*)(((IMG_UINT8 *)pArrayArgsBuffer) + ui32NextOffset);
+		ui32NextOffset += psRGXKickRSIN->ui32ClientUpdateCount * sizeof(IMG_UINT32);
+	}
+
+			/* Copy the data over */
+			if (psRGXKickRSIN->ui32ClientUpdateCount * sizeof(IMG_UINT32) > 0)
+			{
+				if ( OSCopyFromUser(NULL, ui32ClientUpdateSyncOffsetInt, psRGXKickRSIN->pui32ClientUpdateSyncOffset, psRGXKickRSIN->ui32ClientUpdateCount * sizeof(IMG_UINT32)) != PVRSRV_OK )
+				{
+					psRGXKickRSOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
+
+					goto RGXKickRS_exit;
+				}
+			}
+	if (psRGXKickRSIN->ui32ClientUpdateCount != 0)
+	{
+		ui32ClientUpdateValueInt = (IMG_UINT32*)(((IMG_UINT8 *)pArrayArgsBuffer) + ui32NextOffset);
+		ui32NextOffset += psRGXKickRSIN->ui32ClientUpdateCount * sizeof(IMG_UINT32);
+	}
+
+			/* Copy the data over */
+			if (psRGXKickRSIN->ui32ClientUpdateCount * sizeof(IMG_UINT32) > 0)
+			{
+				if ( OSCopyFromUser(NULL, ui32ClientUpdateValueInt, psRGXKickRSIN->pui32ClientUpdateValue, psRGXKickRSIN->ui32ClientUpdateCount * sizeof(IMG_UINT32)) != PVRSRV_OK )
+				{
+					psRGXKickRSOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
+
+					goto RGXKickRS_exit;
+				}
+			}
+	if (psRGXKickRSIN->ui32ServerSyncCount != 0)
+	{
+		ui32ServerSyncFlagsInt = (IMG_UINT32*)(((IMG_UINT8 *)pArrayArgsBuffer) + ui32NextOffset);
+		ui32NextOffset += psRGXKickRSIN->ui32ServerSyncCount * sizeof(IMG_UINT32);
+	}
+
+			/* Copy the data over */
+			if (psRGXKickRSIN->ui32ServerSyncCount * sizeof(IMG_UINT32) > 0)
+			{
+				if ( OSCopyFromUser(NULL, ui32ServerSyncFlagsInt, psRGXKickRSIN->pui32ServerSyncFlags, psRGXKickRSIN->ui32ServerSyncCount * sizeof(IMG_UINT32)) != PVRSRV_OK )
+				{
+					psRGXKickRSOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
+
+					goto RGXKickRS_exit;
+				}
+			}
+	if (psRGXKickRSIN->ui32ServerSyncCount != 0)
+	{
+		psServerSyncsInt = (SERVER_SYNC_PRIMITIVE **)(((IMG_UINT8 *)pArrayArgsBuffer) + ui32NextOffset);
+		ui32NextOffset += psRGXKickRSIN->ui32ServerSyncCount * sizeof(SERVER_SYNC_PRIMITIVE *);
+		hServerSyncsInt2 = (IMG_HANDLE *)(((IMG_UINT8 *)pArrayArgsBuffer) + ui32NextOffset); 
+		ui32NextOffset += psRGXKickRSIN->ui32ServerSyncCount * sizeof(IMG_HANDLE);
+	}
+
+			/* Copy the data over */
+			if (psRGXKickRSIN->ui32ServerSyncCount * sizeof(IMG_HANDLE) > 0)
+			{
+				if ( OSCopyFromUser(NULL, hServerSyncsInt2, psRGXKickRSIN->phServerSyncs, psRGXKickRSIN->ui32ServerSyncCount * sizeof(IMG_HANDLE)) != PVRSRV_OK )
+				{
+					psRGXKickRSOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
+
+					goto RGXKickRS_exit;
+				}
+			}
+	if (psRGXKickRSIN->ui32CmdSize != 0)
+	{
+		psDMCmdInt = (IMG_BYTE*)(((IMG_UINT8 *)pArrayArgsBuffer) + ui32NextOffset);
+		ui32NextOffset += psRGXKickRSIN->ui32CmdSize * sizeof(IMG_BYTE);
+	}
+
+			/* Copy the data over */
+			if (psRGXKickRSIN->ui32CmdSize * sizeof(IMG_BYTE) > 0)
+			{
+				if ( OSCopyFromUser(NULL, psDMCmdInt, psRGXKickRSIN->psDMCmd, psRGXKickRSIN->ui32CmdSize * sizeof(IMG_BYTE)) != PVRSRV_OK )
+				{
+					psRGXKickRSOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
+
+					goto RGXKickRS_exit;
+				}
+			}
+	if (psRGXKickRSIN->ui32FCCmdSize != 0)
+	{
+		psFCDMCmdInt = (IMG_BYTE*)(((IMG_UINT8 *)pArrayArgsBuffer) + ui32NextOffset);
+		ui32NextOffset += psRGXKickRSIN->ui32FCCmdSize * sizeof(IMG_BYTE);
+	}
+
+			/* Copy the data over */
+			if (psRGXKickRSIN->ui32FCCmdSize * sizeof(IMG_BYTE) > 0)
+			{
+				if ( OSCopyFromUser(NULL, psFCDMCmdInt, psRGXKickRSIN->psFCDMCmd, psRGXKickRSIN->ui32FCCmdSize * sizeof(IMG_BYTE)) != PVRSRV_OK )
+				{
+					psRGXKickRSOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
+
+					goto RGXKickRS_exit;
+				}
+			}
+
+	/* Lock over handle lookup. */
+	LockHandle();
+
+
+
+
+
+				{
+					/* Look up the address from the handle */
+					psRGXKickRSOUT->eError =
+						PVRSRVLookupHandleUnlocked(psConnection->psHandleBase,
+											(void **) &psRayContextInt,
+											hRayContext,
+											PVRSRV_HANDLE_TYPE_RGX_SERVER_RAY_CONTEXT,
+											IMG_TRUE);
+					if(psRGXKickRSOUT->eError != PVRSRV_OK)
+					{
+						UnlockHandle();
+						goto RGXKickRS_exit;
+					}
+				}
+
+
+
+
+
+	{
+		IMG_UINT32 i;
+
+		for (i=0;i<psRGXKickRSIN->ui32ClientFenceCount;i++)
+		{
+				{
+					/* Look up the address from the handle */
+					psRGXKickRSOUT->eError =
+						PVRSRVLookupHandleUnlocked(psConnection->psHandleBase,
+											(void **) &psClientFenceUFOSyncPrimBlockInt[i],
+											hClientFenceUFOSyncPrimBlockInt2[i],
+											PVRSRV_HANDLE_TYPE_SYNC_PRIMITIVE_BLOCK,
+											IMG_TRUE);
+					if(psRGXKickRSOUT->eError != PVRSRV_OK)
+					{
+						UnlockHandle();
+						goto RGXKickRS_exit;
+					}
+				}
+		}
+	}
+
+
+
+
+
+	{
+		IMG_UINT32 i;
+
+		for (i=0;i<psRGXKickRSIN->ui32ClientUpdateCount;i++)
+		{
+				{
+					/* Look up the address from the handle */
+					psRGXKickRSOUT->eError =
+						PVRSRVLookupHandleUnlocked(psConnection->psHandleBase,
+											(void **) &psClientUpdateUFOSyncPrimBlockInt[i],
+											hClientUpdateUFOSyncPrimBlockInt2[i],
+											PVRSRV_HANDLE_TYPE_SYNC_PRIMITIVE_BLOCK,
+											IMG_TRUE);
+					if(psRGXKickRSOUT->eError != PVRSRV_OK)
+					{
+						UnlockHandle();
+						goto RGXKickRS_exit;
+					}
+				}
+		}
+	}
+
+
+
+
+
+	{
+		IMG_UINT32 i;
+
+		for (i=0;i<psRGXKickRSIN->ui32ServerSyncCount;i++)
+		{
+				{
+					/* Look up the address from the handle */
+					psRGXKickRSOUT->eError =
+						PVRSRVLookupHandleUnlocked(psConnection->psHandleBase,
+											(void **) &psServerSyncsInt[i],
+											hServerSyncsInt2[i],
+											PVRSRV_HANDLE_TYPE_SERVER_SYNC_PRIMITIVE,
+											IMG_TRUE);
+					if(psRGXKickRSOUT->eError != PVRSRV_OK)
+					{
+						UnlockHandle();
+						goto RGXKickRS_exit;
+					}
+				}
+		}
+	}
+	/* Release now we have looked up handles. */
+	UnlockHandle();
+
+	psRGXKickRSOUT->eError =
+		PVRSRVRGXKickRSKM(
+					psRayContextInt,
+					psRGXKickRSIN->ui32ClientCacheOpSeqNum,
+					psRGXKickRSIN->ui32ClientFenceCount,
+					psClientFenceUFOSyncPrimBlockInt,
+					ui32ClientFenceSyncOffsetInt,
+					ui32ClientFenceValueInt,
+					psRGXKickRSIN->ui32ClientUpdateCount,
+					psClientUpdateUFOSyncPrimBlockInt,
+					ui32ClientUpdateSyncOffsetInt,
+					ui32ClientUpdateValueInt,
+					psRGXKickRSIN->ui32ServerSyncCount,
+					ui32ServerSyncFlagsInt,
+					psServerSyncsInt,
+					psRGXKickRSIN->ui32CmdSize,
+					psDMCmdInt,
+					psRGXKickRSIN->ui32FCCmdSize,
+					psFCDMCmdInt,
+					psRGXKickRSIN->ui32FrameContext,
+					psRGXKickRSIN->ui32PDumpFlags,
+					psRGXKickRSIN->ui32ExtJobRef);
+
+
+
+
+RGXKickRS_exit:
+
+	/* Lock over handle lookup cleanup. */
+	LockHandle();
+
+
+
+
+
+
+				{
+					/* Unreference the previously looked up handle */
+						if(psRayContextInt)
+						{
+							PVRSRVReleaseHandleUnlocked(psConnection->psHandleBase,
+											hRayContext,
+											PVRSRV_HANDLE_TYPE_RGX_SERVER_RAY_CONTEXT);
+						}
+				}
+
+
+
+
+
+
+	if (hClientFenceUFOSyncPrimBlockInt2)
+	{
+		IMG_UINT32 i;
+
+		for (i=0;i<psRGXKickRSIN->ui32ClientFenceCount;i++)
+		{
+				{
+					/* Unreference the previously looked up handle */
+						if(psClientFenceUFOSyncPrimBlockInt[i])
+						{
+							PVRSRVReleaseHandleUnlocked(psConnection->psHandleBase,
+											hClientFenceUFOSyncPrimBlockInt2[i],
+											PVRSRV_HANDLE_TYPE_SYNC_PRIMITIVE_BLOCK);
+						}
+				}
+		}
+	}
+
+
+
+
+
+
+	if (hClientUpdateUFOSyncPrimBlockInt2)
+	{
+		IMG_UINT32 i;
+
+		for (i=0;i<psRGXKickRSIN->ui32ClientUpdateCount;i++)
+		{
+				{
+					/* Unreference the previously looked up handle */
+						if(psClientUpdateUFOSyncPrimBlockInt[i])
+						{
+							PVRSRVReleaseHandleUnlocked(psConnection->psHandleBase,
+											hClientUpdateUFOSyncPrimBlockInt2[i],
+											PVRSRV_HANDLE_TYPE_SYNC_PRIMITIVE_BLOCK);
+						}
+				}
+		}
+	}
+
+
+
+
+
+
+	if (hServerSyncsInt2)
+	{
+		IMG_UINT32 i;
+
+		for (i=0;i<psRGXKickRSIN->ui32ServerSyncCount;i++)
+		{
+				{
+					/* Unreference the previously looked up handle */
+						if(psServerSyncsInt[i])
+						{
+							PVRSRVReleaseHandleUnlocked(psConnection->psHandleBase,
+											hServerSyncsInt2[i],
+											PVRSRV_HANDLE_TYPE_SERVER_SYNC_PRIMITIVE);
+						}
+				}
+		}
+	}
+	/* Release now we have cleaned up look up handles. */
+	UnlockHandle();
+
+	/* Allocated space should be equal to the last updated offset */
+	PVR_ASSERT(ui32BufferSize == ui32NextOffset);
+
+#if defined(INTEGRITY_OS)
+	if(pArrayArgsBuffer)
+#else
+	if(!bHaveEnoughSpace && pArrayArgsBuffer)
+#endif
+		OSFreeMemNoStats(pArrayArgsBuffer);
+
+
+	return 0;
+}
+
+
+static IMG_INT
+PVRSRVBridgeRGXKickVRDM(IMG_UINT32 ui32DispatchTableEntry,
+					  PVRSRV_BRIDGE_IN_RGXKICKVRDM *psRGXKickVRDMIN,
+					  PVRSRV_BRIDGE_OUT_RGXKICKVRDM *psRGXKickVRDMOUT,
+					 CONNECTION_DATA *psConnection)
+{
+	IMG_HANDLE hRayContext = psRGXKickVRDMIN->hRayContext;
+	RGX_SERVER_RAY_CONTEXT * psRayContextInt = NULL;
+	SYNC_PRIMITIVE_BLOCK * *psClientFenceUFOSyncPrimBlockInt = NULL;
+	IMG_HANDLE *hClientFenceUFOSyncPrimBlockInt2 = NULL;
+	IMG_UINT32 *ui32ClientFenceSyncOffsetInt = NULL;
+	IMG_UINT32 *ui32ClientFenceValueInt = NULL;
+	SYNC_PRIMITIVE_BLOCK * *psClientUpdateUFOSyncPrimBlockInt = NULL;
+	IMG_HANDLE *hClientUpdateUFOSyncPrimBlockInt2 = NULL;
+	IMG_UINT32 *ui32ClientUpdateSyncOffsetInt = NULL;
+	IMG_UINT32 *ui32ClientUpdateValueInt = NULL;
+	IMG_UINT32 *ui32ServerSyncFlagsInt = NULL;
+	SERVER_SYNC_PRIMITIVE * *psServerSyncsInt = NULL;
+	IMG_HANDLE *hServerSyncsInt2 = NULL;
+	IMG_BYTE *psDMCmdInt = NULL;
+
+	IMG_UINT32 ui32NextOffset = 0;
+	IMG_BYTE   *pArrayArgsBuffer = NULL;
+#if !defined(INTEGRITY_OS)
+	IMG_BOOL bHaveEnoughSpace = IMG_FALSE;
+#endif
+
+	IMG_UINT32 ui32BufferSize = 
+			(psRGXKickVRDMIN->ui32ClientFenceCount * sizeof(SYNC_PRIMITIVE_BLOCK *)) +
+			(psRGXKickVRDMIN->ui32ClientFenceCount * sizeof(IMG_HANDLE)) +
+			(psRGXKickVRDMIN->ui32ClientFenceCount * sizeof(IMG_UINT32)) +
+			(psRGXKickVRDMIN->ui32ClientFenceCount * sizeof(IMG_UINT32)) +
+			(psRGXKickVRDMIN->ui32ClientUpdateCount * sizeof(SYNC_PRIMITIVE_BLOCK *)) +
+			(psRGXKickVRDMIN->ui32ClientUpdateCount * sizeof(IMG_HANDLE)) +
+			(psRGXKickVRDMIN->ui32ClientUpdateCount * sizeof(IMG_UINT32)) +
+			(psRGXKickVRDMIN->ui32ClientUpdateCount * sizeof(IMG_UINT32)) +
+			(psRGXKickVRDMIN->ui32ServerSyncCount * sizeof(IMG_UINT32)) +
+			(psRGXKickVRDMIN->ui32ServerSyncCount * sizeof(SERVER_SYNC_PRIMITIVE *)) +
+			(psRGXKickVRDMIN->ui32ServerSyncCount * sizeof(IMG_HANDLE)) +
+			(psRGXKickVRDMIN->ui32CmdSize * sizeof(IMG_BYTE)) +
+			0;
+
+	{
+		PVRSRV_DEVICE_NODE *psDeviceNode = OSGetDevData(psConnection);
+
+		/* Check that device supports the required feature */
+		if ((psDeviceNode->pfnCheckDeviceFeature) &&
+			!psDeviceNode->pfnCheckDeviceFeature(psDeviceNode, RGX_FEATURE_RAY_TRACING_BIT_MASK))
+		{
+			psRGXKickVRDMOUT->eError = PVRSRV_ERROR_NOT_SUPPORTED;
+
+			goto RGXKickVRDM_exit;
+		}
+	}
+
+
+
+
+	if (ui32BufferSize != 0)
+	{
+#if !defined(INTEGRITY_OS)
+		/* Try to use remainder of input buffer for copies if possible, word-aligned for safety. */
+		IMG_UINT32 ui32InBufferOffset = PVR_ALIGN(sizeof(*psRGXKickVRDMIN), sizeof(unsigned long));
+		IMG_UINT32 ui32InBufferExcessSize = ui32InBufferOffset >= PVRSRV_MAX_BRIDGE_IN_SIZE ? 0 :
+			PVRSRV_MAX_BRIDGE_IN_SIZE - ui32InBufferOffset;
+
+		bHaveEnoughSpace = ui32BufferSize <= ui32InBufferExcessSize;
+		if (bHaveEnoughSpace)
+		{
+			IMG_BYTE *pInputBuffer = (IMG_BYTE *)psRGXKickVRDMIN;
+
+			pArrayArgsBuffer = &pInputBuffer[ui32InBufferOffset];		}
+		else
+#endif
+		{
+			pArrayArgsBuffer = OSAllocMemNoStats(ui32BufferSize);
+
+			if(!pArrayArgsBuffer)
+			{
+				psRGXKickVRDMOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
+				goto RGXKickVRDM_exit;
+			}
+		}
+	}
+
+	if (psRGXKickVRDMIN->ui32ClientFenceCount != 0)
+	{
+		psClientFenceUFOSyncPrimBlockInt = (SYNC_PRIMITIVE_BLOCK **)(((IMG_UINT8 *)pArrayArgsBuffer) + ui32NextOffset);
+		ui32NextOffset += psRGXKickVRDMIN->ui32ClientFenceCount * sizeof(SYNC_PRIMITIVE_BLOCK *);
+		hClientFenceUFOSyncPrimBlockInt2 = (IMG_HANDLE *)(((IMG_UINT8 *)pArrayArgsBuffer) + ui32NextOffset); 
+		ui32NextOffset += psRGXKickVRDMIN->ui32ClientFenceCount * sizeof(IMG_HANDLE);
+	}
+
+			/* Copy the data over */
+			if (psRGXKickVRDMIN->ui32ClientFenceCount * sizeof(IMG_HANDLE) > 0)
+			{
+				if ( OSCopyFromUser(NULL, hClientFenceUFOSyncPrimBlockInt2, psRGXKickVRDMIN->phClientFenceUFOSyncPrimBlock, psRGXKickVRDMIN->ui32ClientFenceCount * sizeof(IMG_HANDLE)) != PVRSRV_OK )
+				{
+					psRGXKickVRDMOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
+
+					goto RGXKickVRDM_exit;
+				}
+			}
+	if (psRGXKickVRDMIN->ui32ClientFenceCount != 0)
+	{
+		ui32ClientFenceSyncOffsetInt = (IMG_UINT32*)(((IMG_UINT8 *)pArrayArgsBuffer) + ui32NextOffset);
+		ui32NextOffset += psRGXKickVRDMIN->ui32ClientFenceCount * sizeof(IMG_UINT32);
+	}
+
+			/* Copy the data over */
+			if (psRGXKickVRDMIN->ui32ClientFenceCount * sizeof(IMG_UINT32) > 0)
+			{
+				if ( OSCopyFromUser(NULL, ui32ClientFenceSyncOffsetInt, psRGXKickVRDMIN->pui32ClientFenceSyncOffset, psRGXKickVRDMIN->ui32ClientFenceCount * sizeof(IMG_UINT32)) != PVRSRV_OK )
+				{
+					psRGXKickVRDMOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
+
+					goto RGXKickVRDM_exit;
+				}
+			}
+	if (psRGXKickVRDMIN->ui32ClientFenceCount != 0)
+	{
+		ui32ClientFenceValueInt = (IMG_UINT32*)(((IMG_UINT8 *)pArrayArgsBuffer) + ui32NextOffset);
+		ui32NextOffset += psRGXKickVRDMIN->ui32ClientFenceCount * sizeof(IMG_UINT32);
+	}
+
+			/* Copy the data over */
+			if (psRGXKickVRDMIN->ui32ClientFenceCount * sizeof(IMG_UINT32) > 0)
+			{
+				if ( OSCopyFromUser(NULL, ui32ClientFenceValueInt, psRGXKickVRDMIN->pui32ClientFenceValue, psRGXKickVRDMIN->ui32ClientFenceCount * sizeof(IMG_UINT32)) != PVRSRV_OK )
+				{
+					psRGXKickVRDMOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
+
+					goto RGXKickVRDM_exit;
+				}
+			}
+	if (psRGXKickVRDMIN->ui32ClientUpdateCount != 0)
+	{
+		psClientUpdateUFOSyncPrimBlockInt = (SYNC_PRIMITIVE_BLOCK **)(((IMG_UINT8 *)pArrayArgsBuffer) + ui32NextOffset);
+		ui32NextOffset += psRGXKickVRDMIN->ui32ClientUpdateCount * sizeof(SYNC_PRIMITIVE_BLOCK *);
+		hClientUpdateUFOSyncPrimBlockInt2 = (IMG_HANDLE *)(((IMG_UINT8 *)pArrayArgsBuffer) + ui32NextOffset); 
+		ui32NextOffset += psRGXKickVRDMIN->ui32ClientUpdateCount * sizeof(IMG_HANDLE);
+	}
+
+			/* Copy the data over */
+			if (psRGXKickVRDMIN->ui32ClientUpdateCount * sizeof(IMG_HANDLE) > 0)
+			{
+				if ( OSCopyFromUser(NULL, hClientUpdateUFOSyncPrimBlockInt2, psRGXKickVRDMIN->phClientUpdateUFOSyncPrimBlock, psRGXKickVRDMIN->ui32ClientUpdateCount * sizeof(IMG_HANDLE)) != PVRSRV_OK )
+				{
+					psRGXKickVRDMOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
+
+					goto RGXKickVRDM_exit;
+				}
+			}
+	if (psRGXKickVRDMIN->ui32ClientUpdateCount != 0)
+	{
+		ui32ClientUpdateSyncOffsetInt = (IMG_UINT32*)(((IMG_UINT8 *)pArrayArgsBuffer) + ui32NextOffset);
+		ui32NextOffset += psRGXKickVRDMIN->ui32ClientUpdateCount * sizeof(IMG_UINT32);
+	}
+
+			/* Copy the data over */
+			if (psRGXKickVRDMIN->ui32ClientUpdateCount * sizeof(IMG_UINT32) > 0)
+			{
+				if ( OSCopyFromUser(NULL, ui32ClientUpdateSyncOffsetInt, psRGXKickVRDMIN->pui32ClientUpdateSyncOffset, psRGXKickVRDMIN->ui32ClientUpdateCount * sizeof(IMG_UINT32)) != PVRSRV_OK )
+				{
+					psRGXKickVRDMOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
+
+					goto RGXKickVRDM_exit;
+				}
+			}
+	if (psRGXKickVRDMIN->ui32ClientUpdateCount != 0)
+	{
+		ui32ClientUpdateValueInt = (IMG_UINT32*)(((IMG_UINT8 *)pArrayArgsBuffer) + ui32NextOffset);
+		ui32NextOffset += psRGXKickVRDMIN->ui32ClientUpdateCount * sizeof(IMG_UINT32);
+	}
+
+			/* Copy the data over */
+			if (psRGXKickVRDMIN->ui32ClientUpdateCount * sizeof(IMG_UINT32) > 0)
+			{
+				if ( OSCopyFromUser(NULL, ui32ClientUpdateValueInt, psRGXKickVRDMIN->pui32ClientUpdateValue, psRGXKickVRDMIN->ui32ClientUpdateCount * sizeof(IMG_UINT32)) != PVRSRV_OK )
+				{
+					psRGXKickVRDMOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
+
+					goto RGXKickVRDM_exit;
+				}
+			}
+	if (psRGXKickVRDMIN->ui32ServerSyncCount != 0)
+	{
+		ui32ServerSyncFlagsInt = (IMG_UINT32*)(((IMG_UINT8 *)pArrayArgsBuffer) + ui32NextOffset);
+		ui32NextOffset += psRGXKickVRDMIN->ui32ServerSyncCount * sizeof(IMG_UINT32);
+	}
+
+			/* Copy the data over */
+			if (psRGXKickVRDMIN->ui32ServerSyncCount * sizeof(IMG_UINT32) > 0)
+			{
+				if ( OSCopyFromUser(NULL, ui32ServerSyncFlagsInt, psRGXKickVRDMIN->pui32ServerSyncFlags, psRGXKickVRDMIN->ui32ServerSyncCount * sizeof(IMG_UINT32)) != PVRSRV_OK )
+				{
+					psRGXKickVRDMOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
+
+					goto RGXKickVRDM_exit;
+				}
+			}
+	if (psRGXKickVRDMIN->ui32ServerSyncCount != 0)
+	{
+		psServerSyncsInt = (SERVER_SYNC_PRIMITIVE **)(((IMG_UINT8 *)pArrayArgsBuffer) + ui32NextOffset);
+		ui32NextOffset += psRGXKickVRDMIN->ui32ServerSyncCount * sizeof(SERVER_SYNC_PRIMITIVE *);
+		hServerSyncsInt2 = (IMG_HANDLE *)(((IMG_UINT8 *)pArrayArgsBuffer) + ui32NextOffset); 
+		ui32NextOffset += psRGXKickVRDMIN->ui32ServerSyncCount * sizeof(IMG_HANDLE);
+	}
+
+			/* Copy the data over */
+			if (psRGXKickVRDMIN->ui32ServerSyncCount * sizeof(IMG_HANDLE) > 0)
+			{
+				if ( OSCopyFromUser(NULL, hServerSyncsInt2, psRGXKickVRDMIN->phServerSyncs, psRGXKickVRDMIN->ui32ServerSyncCount * sizeof(IMG_HANDLE)) != PVRSRV_OK )
+				{
+					psRGXKickVRDMOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
+
+					goto RGXKickVRDM_exit;
+				}
+			}
+	if (psRGXKickVRDMIN->ui32CmdSize != 0)
+	{
+		psDMCmdInt = (IMG_BYTE*)(((IMG_UINT8 *)pArrayArgsBuffer) + ui32NextOffset);
+		ui32NextOffset += psRGXKickVRDMIN->ui32CmdSize * sizeof(IMG_BYTE);
+	}
+
+			/* Copy the data over */
+			if (psRGXKickVRDMIN->ui32CmdSize * sizeof(IMG_BYTE) > 0)
+			{
+				if ( OSCopyFromUser(NULL, psDMCmdInt, psRGXKickVRDMIN->psDMCmd, psRGXKickVRDMIN->ui32CmdSize * sizeof(IMG_BYTE)) != PVRSRV_OK )
+				{
+					psRGXKickVRDMOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
+
+					goto RGXKickVRDM_exit;
+				}
+			}
+
+	/* Lock over handle lookup. */
+	LockHandle();
+
+
+
+
+
+				{
+					/* Look up the address from the handle */
+					psRGXKickVRDMOUT->eError =
+						PVRSRVLookupHandleUnlocked(psConnection->psHandleBase,
+											(void **) &psRayContextInt,
+											hRayContext,
+											PVRSRV_HANDLE_TYPE_RGX_SERVER_RAY_CONTEXT,
+											IMG_TRUE);
+					if(psRGXKickVRDMOUT->eError != PVRSRV_OK)
+					{
+						UnlockHandle();
+						goto RGXKickVRDM_exit;
+					}
+				}
+
+
+
+
+
+	{
+		IMG_UINT32 i;
+
+		for (i=0;i<psRGXKickVRDMIN->ui32ClientFenceCount;i++)
+		{
+				{
+					/* Look up the address from the handle */
+					psRGXKickVRDMOUT->eError =
+						PVRSRVLookupHandleUnlocked(psConnection->psHandleBase,
+											(void **) &psClientFenceUFOSyncPrimBlockInt[i],
+											hClientFenceUFOSyncPrimBlockInt2[i],
+											PVRSRV_HANDLE_TYPE_SYNC_PRIMITIVE_BLOCK,
+											IMG_TRUE);
+					if(psRGXKickVRDMOUT->eError != PVRSRV_OK)
+					{
+						UnlockHandle();
+						goto RGXKickVRDM_exit;
+					}
+				}
+		}
+	}
+
+
+
+
+
+	{
+		IMG_UINT32 i;
+
+		for (i=0;i<psRGXKickVRDMIN->ui32ClientUpdateCount;i++)
+		{
+				{
+					/* Look up the address from the handle */
+					psRGXKickVRDMOUT->eError =
+						PVRSRVLookupHandleUnlocked(psConnection->psHandleBase,
+											(void **) &psClientUpdateUFOSyncPrimBlockInt[i],
+											hClientUpdateUFOSyncPrimBlockInt2[i],
+											PVRSRV_HANDLE_TYPE_SYNC_PRIMITIVE_BLOCK,
+											IMG_TRUE);
+					if(psRGXKickVRDMOUT->eError != PVRSRV_OK)
+					{
+						UnlockHandle();
+						goto RGXKickVRDM_exit;
+					}
+				}
+		}
+	}
+
+
+
+
+
+	{
+		IMG_UINT32 i;
+
+		for (i=0;i<psRGXKickVRDMIN->ui32ServerSyncCount;i++)
+		{
+				{
+					/* Look up the address from the handle */
+					psRGXKickVRDMOUT->eError =
+						PVRSRVLookupHandleUnlocked(psConnection->psHandleBase,
+											(void **) &psServerSyncsInt[i],
+											hServerSyncsInt2[i],
+											PVRSRV_HANDLE_TYPE_SERVER_SYNC_PRIMITIVE,
+											IMG_TRUE);
+					if(psRGXKickVRDMOUT->eError != PVRSRV_OK)
+					{
+						UnlockHandle();
+						goto RGXKickVRDM_exit;
+					}
+				}
+		}
+	}
+	/* Release now we have looked up handles. */
+	UnlockHandle();
+
+	psRGXKickVRDMOUT->eError =
+		PVRSRVRGXKickVRDMKM(
+					psRayContextInt,
+					psRGXKickVRDMIN->ui32ClientCacheOpSeqNum,
+					psRGXKickVRDMIN->ui32ClientFenceCount,
+					psClientFenceUFOSyncPrimBlockInt,
+					ui32ClientFenceSyncOffsetInt,
+					ui32ClientFenceValueInt,
+					psRGXKickVRDMIN->ui32ClientUpdateCount,
+					psClientUpdateUFOSyncPrimBlockInt,
+					ui32ClientUpdateSyncOffsetInt,
+					ui32ClientUpdateValueInt,
+					psRGXKickVRDMIN->ui32ServerSyncCount,
+					ui32ServerSyncFlagsInt,
+					psServerSyncsInt,
+					psRGXKickVRDMIN->ui32CmdSize,
+					psDMCmdInt,
+					psRGXKickVRDMIN->ui32PDumpFlags,
+					psRGXKickVRDMIN->ui32ExtJobRef);
+
+
+
+
+RGXKickVRDM_exit:
+
+	/* Lock over handle lookup cleanup. */
+	LockHandle();
+
+
+
+
+
+
+				{
+					/* Unreference the previously looked up handle */
+						if(psRayContextInt)
+						{
+							PVRSRVReleaseHandleUnlocked(psConnection->psHandleBase,
+											hRayContext,
+											PVRSRV_HANDLE_TYPE_RGX_SERVER_RAY_CONTEXT);
+						}
+				}
+
+
+
+
+
+
+	if (hClientFenceUFOSyncPrimBlockInt2)
+	{
+		IMG_UINT32 i;
+
+		for (i=0;i<psRGXKickVRDMIN->ui32ClientFenceCount;i++)
+		{
+				{
+					/* Unreference the previously looked up handle */
+						if(psClientFenceUFOSyncPrimBlockInt[i])
+						{
+							PVRSRVReleaseHandleUnlocked(psConnection->psHandleBase,
+											hClientFenceUFOSyncPrimBlockInt2[i],
+											PVRSRV_HANDLE_TYPE_SYNC_PRIMITIVE_BLOCK);
+						}
+				}
+		}
+	}
+
+
+
+
+
+
+	if (hClientUpdateUFOSyncPrimBlockInt2)
+	{
+		IMG_UINT32 i;
+
+		for (i=0;i<psRGXKickVRDMIN->ui32ClientUpdateCount;i++)
+		{
+				{
+					/* Unreference the previously looked up handle */
+						if(psClientUpdateUFOSyncPrimBlockInt[i])
+						{
+							PVRSRVReleaseHandleUnlocked(psConnection->psHandleBase,
+											hClientUpdateUFOSyncPrimBlockInt2[i],
+											PVRSRV_HANDLE_TYPE_SYNC_PRIMITIVE_BLOCK);
+						}
+				}
+		}
+	}
+
+
+
+
+
+
+	if (hServerSyncsInt2)
+	{
+		IMG_UINT32 i;
+
+		for (i=0;i<psRGXKickVRDMIN->ui32ServerSyncCount;i++)
+		{
+				{
+					/* Unreference the previously looked up handle */
+						if(psServerSyncsInt[i])
+						{
+							PVRSRVReleaseHandleUnlocked(psConnection->psHandleBase,
+											hServerSyncsInt2[i],
+											PVRSRV_HANDLE_TYPE_SERVER_SYNC_PRIMITIVE);
+						}
+				}
+		}
+	}
+	/* Release now we have cleaned up look up handles. */
+	UnlockHandle();
+
+	/* Allocated space should be equal to the last updated offset */
+	PVR_ASSERT(ui32BufferSize == ui32NextOffset);
+
+#if defined(INTEGRITY_OS)
+	if(pArrayArgsBuffer)
+#else
+	if(!bHaveEnoughSpace && pArrayArgsBuffer)
+#endif
+		OSFreeMemNoStats(pArrayArgsBuffer);
+
+
+	return 0;
+}
+
+
+static IMG_INT
+PVRSRVBridgeRGXCreateRayContext(IMG_UINT32 ui32DispatchTableEntry,
+					  PVRSRV_BRIDGE_IN_RGXCREATERAYCONTEXT *psRGXCreateRayContextIN,
+					  PVRSRV_BRIDGE_OUT_RGXCREATERAYCONTEXT *psRGXCreateRayContextOUT,
+					 CONNECTION_DATA *psConnection)
+{
+	IMG_BYTE *psFrameworkCmdInt = NULL;
+	IMG_HANDLE hPrivData = psRGXCreateRayContextIN->hPrivData;
+	IMG_HANDLE hPrivDataInt = NULL;
+	RGX_SERVER_RAY_CONTEXT * psRayContextInt = NULL;
+
+	IMG_UINT32 ui32NextOffset = 0;
+	IMG_BYTE   *pArrayArgsBuffer = NULL;
+#if !defined(INTEGRITY_OS)
+	IMG_BOOL bHaveEnoughSpace = IMG_FALSE;
+#endif
+
+	IMG_UINT32 ui32BufferSize = 
+			(psRGXCreateRayContextIN->ui32FrameworkCmdSize * sizeof(IMG_BYTE)) +
+			0;
+
+	{
+		PVRSRV_DEVICE_NODE *psDeviceNode = OSGetDevData(psConnection);
+
+		/* Check that device supports the required feature */
+		if ((psDeviceNode->pfnCheckDeviceFeature) &&
+			!psDeviceNode->pfnCheckDeviceFeature(psDeviceNode, RGX_FEATURE_RAY_TRACING_BIT_MASK))
+		{
+			psRGXCreateRayContextOUT->eError = PVRSRV_ERROR_NOT_SUPPORTED;
+
+			goto RGXCreateRayContext_exit;
+		}
+	}
+
+
+
+
+	if (ui32BufferSize != 0)
+	{
+#if !defined(INTEGRITY_OS)
+		/* Try to use remainder of input buffer for copies if possible, word-aligned for safety. */
+		IMG_UINT32 ui32InBufferOffset = PVR_ALIGN(sizeof(*psRGXCreateRayContextIN), sizeof(unsigned long));
+		IMG_UINT32 ui32InBufferExcessSize = ui32InBufferOffset >= PVRSRV_MAX_BRIDGE_IN_SIZE ? 0 :
+			PVRSRV_MAX_BRIDGE_IN_SIZE - ui32InBufferOffset;
+
+		bHaveEnoughSpace = ui32BufferSize <= ui32InBufferExcessSize;
+		if (bHaveEnoughSpace)
+		{
+			IMG_BYTE *pInputBuffer = (IMG_BYTE *)psRGXCreateRayContextIN;
+
+			pArrayArgsBuffer = &pInputBuffer[ui32InBufferOffset];		}
+		else
+#endif
+		{
+			pArrayArgsBuffer = OSAllocMemNoStats(ui32BufferSize);
+
+			if(!pArrayArgsBuffer)
+			{
+				psRGXCreateRayContextOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
+				goto RGXCreateRayContext_exit;
+			}
+		}
+	}
+
+	if (psRGXCreateRayContextIN->ui32FrameworkCmdSize != 0)
+	{
+		psFrameworkCmdInt = (IMG_BYTE*)(((IMG_UINT8 *)pArrayArgsBuffer) + ui32NextOffset);
+		ui32NextOffset += psRGXCreateRayContextIN->ui32FrameworkCmdSize * sizeof(IMG_BYTE);
+	}
+
+			/* Copy the data over */
+			if (psRGXCreateRayContextIN->ui32FrameworkCmdSize * sizeof(IMG_BYTE) > 0)
+			{
+				if ( OSCopyFromUser(NULL, psFrameworkCmdInt, psRGXCreateRayContextIN->psFrameworkCmd, psRGXCreateRayContextIN->ui32FrameworkCmdSize * sizeof(IMG_BYTE)) != PVRSRV_OK )
+				{
+					psRGXCreateRayContextOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
+
+					goto RGXCreateRayContext_exit;
+				}
+			}
+
+	/* Lock over handle lookup. */
+	LockHandle();
+
+
+
+
+
+				{
+					/* Look up the address from the handle */
+					psRGXCreateRayContextOUT->eError =
+						PVRSRVLookupHandleUnlocked(psConnection->psHandleBase,
+											(void **) &hPrivDataInt,
+											hPrivData,
+											PVRSRV_HANDLE_TYPE_DEV_PRIV_DATA,
+											IMG_TRUE);
+					if(psRGXCreateRayContextOUT->eError != PVRSRV_OK)
+					{
+						UnlockHandle();
+						goto RGXCreateRayContext_exit;
+					}
+				}
+	/* Release now we have looked up handles. */
+	UnlockHandle();
+
+	psRGXCreateRayContextOUT->eError =
+		PVRSRVRGXCreateRayContextKM(psConnection, OSGetDevData(psConnection),
+					psRGXCreateRayContextIN->ui32Priority,
+					psRGXCreateRayContextIN->sMCUFenceAddr,
+					psRGXCreateRayContextIN->sVRMCallStackAddr,
+					psRGXCreateRayContextIN->ui32FrameworkCmdSize,
+					psFrameworkCmdInt,
+					hPrivDataInt,
+					&psRayContextInt);
+	/* Exit early if bridged call fails */
+	if(psRGXCreateRayContextOUT->eError != PVRSRV_OK)
+	{
+		goto RGXCreateRayContext_exit;
+	}
+
+	/* Lock over handle creation. */
+	LockHandle();
+
+
+
+
+
+	psRGXCreateRayContextOUT->eError = PVRSRVAllocHandleUnlocked(psConnection->psHandleBase,
+
+							&psRGXCreateRayContextOUT->hRayContext,
+							(void *) psRayContextInt,
+							PVRSRV_HANDLE_TYPE_RGX_SERVER_RAY_CONTEXT,
+							PVRSRV_HANDLE_ALLOC_FLAG_MULTI
+							,(PFN_HANDLE_RELEASE)&PVRSRVRGXDestroyRayContextKM);
+	if (psRGXCreateRayContextOUT->eError != PVRSRV_OK)
+	{
+		UnlockHandle();
+		goto RGXCreateRayContext_exit;
+	}
+
+	/* Release now we have created handles. */
+	UnlockHandle();
+
+
+
+RGXCreateRayContext_exit:
+
+	/* Lock over handle lookup cleanup. */
+	LockHandle();
+
+
+
+
+
+
+				{
+					/* Unreference the previously looked up handle */
+						if(hPrivDataInt)
+						{
+							PVRSRVReleaseHandleUnlocked(psConnection->psHandleBase,
+											hPrivData,
+											PVRSRV_HANDLE_TYPE_DEV_PRIV_DATA);
+						}
+				}
+	/* Release now we have cleaned up look up handles. */
+	UnlockHandle();
+
+	if (psRGXCreateRayContextOUT->eError != PVRSRV_OK)
+	{
+		if (psRayContextInt)
+		{
+			PVRSRVRGXDestroyRayContextKM(psRayContextInt);
+		}
+	}
+
+	/* Allocated space should be equal to the last updated offset */
+	PVR_ASSERT(ui32BufferSize == ui32NextOffset);
+
+#if defined(INTEGRITY_OS)
+	if(pArrayArgsBuffer)
+#else
+	if(!bHaveEnoughSpace && pArrayArgsBuffer)
+#endif
+		OSFreeMemNoStats(pArrayArgsBuffer);
+
+
+	return 0;
+}
+
+
+static IMG_INT
+PVRSRVBridgeRGXDestroyRayContext(IMG_UINT32 ui32DispatchTableEntry,
+					  PVRSRV_BRIDGE_IN_RGXDESTROYRAYCONTEXT *psRGXDestroyRayContextIN,
+					  PVRSRV_BRIDGE_OUT_RGXDESTROYRAYCONTEXT *psRGXDestroyRayContextOUT,
+					 CONNECTION_DATA *psConnection)
+{
+
+
+	{
+		PVRSRV_DEVICE_NODE *psDeviceNode = OSGetDevData(psConnection);
+
+		/* Check that device supports the required feature */
+		if ((psDeviceNode->pfnCheckDeviceFeature) &&
+			!psDeviceNode->pfnCheckDeviceFeature(psDeviceNode, RGX_FEATURE_RAY_TRACING_BIT_MASK))
+		{
+			psRGXDestroyRayContextOUT->eError = PVRSRV_ERROR_NOT_SUPPORTED;
+
+			goto RGXDestroyRayContext_exit;
+		}
+	}
+
+
+
+
+
+
+
+	/* Lock over handle destruction. */
+	LockHandle();
+
+
+
+
+
+	psRGXDestroyRayContextOUT->eError =
+		PVRSRVReleaseHandleUnlocked(psConnection->psHandleBase,
+					(IMG_HANDLE) psRGXDestroyRayContextIN->hRayContext,
+					PVRSRV_HANDLE_TYPE_RGX_SERVER_RAY_CONTEXT);
+	if ((psRGXDestroyRayContextOUT->eError != PVRSRV_OK) &&
+	    (psRGXDestroyRayContextOUT->eError != PVRSRV_ERROR_RETRY))
+	{
+		PVR_DPF((PVR_DBG_ERROR,
+		        "PVRSRVBridgeRGXDestroyRayContext: %s",
+		        PVRSRVGetErrorStringKM(psRGXDestroyRayContextOUT->eError)));
+		PVR_ASSERT(0);
+		UnlockHandle();
+		goto RGXDestroyRayContext_exit;
+	}
+
+	/* Release now we have destroyed handles. */
+	UnlockHandle();
+
+
+
+RGXDestroyRayContext_exit:
+
+
+
+
+	return 0;
+}
+
+
+static IMG_INT
+PVRSRVBridgeRGXSetRayContextPriority(IMG_UINT32 ui32DispatchTableEntry,
+					  PVRSRV_BRIDGE_IN_RGXSETRAYCONTEXTPRIORITY *psRGXSetRayContextPriorityIN,
+					  PVRSRV_BRIDGE_OUT_RGXSETRAYCONTEXTPRIORITY *psRGXSetRayContextPriorityOUT,
+					 CONNECTION_DATA *psConnection)
+{
+	IMG_HANDLE hRayContext = psRGXSetRayContextPriorityIN->hRayContext;
+	RGX_SERVER_RAY_CONTEXT * psRayContextInt = NULL;
+
+
+	{
+		PVRSRV_DEVICE_NODE *psDeviceNode = OSGetDevData(psConnection);
+
+		/* Check that device supports the required feature */
+		if ((psDeviceNode->pfnCheckDeviceFeature) &&
+			!psDeviceNode->pfnCheckDeviceFeature(psDeviceNode, RGX_FEATURE_RAY_TRACING_BIT_MASK))
+		{
+			psRGXSetRayContextPriorityOUT->eError = PVRSRV_ERROR_NOT_SUPPORTED;
+
+			goto RGXSetRayContextPriority_exit;
+		}
+	}
+
+
+
+
+
+	/* Lock over handle lookup. */
+	LockHandle();
+
+
+
+
+
+				{
+					/* Look up the address from the handle */
+					psRGXSetRayContextPriorityOUT->eError =
+						PVRSRVLookupHandleUnlocked(psConnection->psHandleBase,
+											(void **) &psRayContextInt,
+											hRayContext,
+											PVRSRV_HANDLE_TYPE_RGX_SERVER_RAY_CONTEXT,
+											IMG_TRUE);
+					if(psRGXSetRayContextPriorityOUT->eError != PVRSRV_OK)
+					{
+						UnlockHandle();
+						goto RGXSetRayContextPriority_exit;
+					}
+				}
+	/* Release now we have looked up handles. */
+	UnlockHandle();
+
+	psRGXSetRayContextPriorityOUT->eError =
+		PVRSRVRGXSetRayContextPriorityKM(psConnection, OSGetDevData(psConnection),
+					psRayContextInt,
+					psRGXSetRayContextPriorityIN->ui32Priority);
+
+
+
+
+RGXSetRayContextPriority_exit:
+
+	/* Lock over handle lookup cleanup. */
+	LockHandle();
+
+
+
+
+
+
+				{
+					/* Unreference the previously looked up handle */
+						if(psRayContextInt)
+						{
+							PVRSRVReleaseHandleUnlocked(psConnection->psHandleBase,
+											hRayContext,
+											PVRSRV_HANDLE_TYPE_RGX_SERVER_RAY_CONTEXT);
+						}
+				}
+	/* Release now we have cleaned up look up handles. */
+	UnlockHandle();
+
+
+	return 0;
+}
+
+
+
+
+/* *************************************************************************** 
+ * Server bridge dispatch related glue 
+ */
+
+static IMG_BOOL bUseLock = IMG_TRUE;
+
+PVRSRV_ERROR InitRGXRAYBridge(void);
+PVRSRV_ERROR DeinitRGXRAYBridge(void);
+
+/*
+ * Register all RGXRAY functions with services
+ */
+PVRSRV_ERROR InitRGXRAYBridge(void)
+{
+
+	SetDispatchTableEntry(PVRSRV_BRIDGE_RGXRAY, PVRSRV_BRIDGE_RGXRAY_RGXCREATERPMFREELIST, PVRSRVBridgeRGXCreateRPMFreeList,
+					NULL, bUseLock);
+
+	SetDispatchTableEntry(PVRSRV_BRIDGE_RGXRAY, PVRSRV_BRIDGE_RGXRAY_RGXDESTROYRPMFREELIST, PVRSRVBridgeRGXDestroyRPMFreeList,
+					NULL, bUseLock);
+
+	SetDispatchTableEntry(PVRSRV_BRIDGE_RGXRAY, PVRSRV_BRIDGE_RGXRAY_RGXCREATERPMCONTEXT, PVRSRVBridgeRGXCreateRPMContext,
+					NULL, bUseLock);
+
+	SetDispatchTableEntry(PVRSRV_BRIDGE_RGXRAY, PVRSRV_BRIDGE_RGXRAY_RGXDESTROYRPMCONTEXT, PVRSRVBridgeRGXDestroyRPMContext,
+					NULL, bUseLock);
+
+	SetDispatchTableEntry(PVRSRV_BRIDGE_RGXRAY, PVRSRV_BRIDGE_RGXRAY_RGXKICKRS, PVRSRVBridgeRGXKickRS,
+					NULL, bUseLock);
+
+	SetDispatchTableEntry(PVRSRV_BRIDGE_RGXRAY, PVRSRV_BRIDGE_RGXRAY_RGXKICKVRDM, PVRSRVBridgeRGXKickVRDM,
+					NULL, bUseLock);
+
+	SetDispatchTableEntry(PVRSRV_BRIDGE_RGXRAY, PVRSRV_BRIDGE_RGXRAY_RGXCREATERAYCONTEXT, PVRSRVBridgeRGXCreateRayContext,
+					NULL, bUseLock);
+
+	SetDispatchTableEntry(PVRSRV_BRIDGE_RGXRAY, PVRSRV_BRIDGE_RGXRAY_RGXDESTROYRAYCONTEXT, PVRSRVBridgeRGXDestroyRayContext,
+					NULL, bUseLock);
+
+	SetDispatchTableEntry(PVRSRV_BRIDGE_RGXRAY, PVRSRV_BRIDGE_RGXRAY_RGXSETRAYCONTEXTPRIORITY, PVRSRVBridgeRGXSetRayContextPriority,
+					NULL, bUseLock);
+
+
+	return PVRSRV_OK;
+}
+
+/*
+ * Unregister all rgxray functions with services
+ */
+PVRSRV_ERROR DeinitRGXRAYBridge(void)
+{
+	return PVRSRV_OK;
+}
diff --git a/drivers/staging/imgtec/rogue/generated/cachegeneric_bridge/common_cachegeneric_bridge.h b/drivers/staging/imgtec/rogue/generated/rgxsignals_bridge/common_rgxsignals_bridge.h
similarity index 69%
rename from drivers/staging/imgtec/rogue/generated/cachegeneric_bridge/common_cachegeneric_bridge.h
rename to drivers/staging/imgtec/rogue/generated/rgxsignals_bridge/common_rgxsignals_bridge.h
index ff34c80..18d747e 100644
--- a/drivers/staging/imgtec/rogue/generated/cachegeneric_bridge/common_cachegeneric_bridge.h
+++ b/drivers/staging/imgtec/rogue/generated/rgxsignals_bridge/common_rgxsignals_bridge.h
@@ -1,9 +1,9 @@
 /*************************************************************************/ /*!
 @File
-@Title          Common bridge header for cachegeneric
+@Title          Common bridge header for rgxsignals
 @Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
-@Description    Declares common defines and structures that are used by both
-                the client and sever side of the bridge for cachegeneric
+@Description    Declares common defines and structures used by both the client
+                and server side of the bridge for rgxsignals
 @License        Dual MIT/GPLv2
 
 The contents of this file are subject to the MIT license as set out below.
@@ -42,38 +42,38 @@
 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */ /**************************************************************************/
 
-#ifndef COMMON_CACHEGENERIC_BRIDGE_H
-#define COMMON_CACHEGENERIC_BRIDGE_H
+#ifndef COMMON_RGXSIGNALS_BRIDGE_H
+#define COMMON_RGXSIGNALS_BRIDGE_H
+
+#include <powervr/mem_types.h>
 
 #include "img_types.h"
 #include "pvrsrv_error.h"
 
-#include "cache_external.h"
+#include "rgx_bridge.h"
 
 
-#define PVRSRV_BRIDGE_CACHEGENERIC_CMD_FIRST			0
-#define PVRSRV_BRIDGE_CACHEGENERIC_CACHEOPQUEUE			PVRSRV_BRIDGE_CACHEGENERIC_CMD_FIRST+0
-#define PVRSRV_BRIDGE_CACHEGENERIC_CMD_LAST			(PVRSRV_BRIDGE_CACHEGENERIC_CMD_FIRST+0)
+#define PVRSRV_BRIDGE_RGXSIGNALS_CMD_FIRST			0
+#define PVRSRV_BRIDGE_RGXSIGNALS_RGXNOTIFYSIGNALUPDATE			PVRSRV_BRIDGE_RGXSIGNALS_CMD_FIRST+0
+#define PVRSRV_BRIDGE_RGXSIGNALS_CMD_LAST			(PVRSRV_BRIDGE_RGXSIGNALS_CMD_FIRST+0)
 
 
 /*******************************************
-            CacheOpQueue          
+            RGXNotifySignalUpdate          
  *******************************************/
 
-/* Bridge in structure for CacheOpQueue */
-typedef struct PVRSRV_BRIDGE_IN_CACHEOPQUEUE_TAG
+/* Bridge in structure for RGXNotifySignalUpdate */
+typedef struct PVRSRV_BRIDGE_IN_RGXNOTIFYSIGNALUPDATE_TAG
 {
-	IMG_HANDLE hPMR;
-	IMG_DEVMEM_OFFSET_T uiOffset;
-	IMG_DEVMEM_SIZE_T uiSize;
-	PVRSRV_CACHE_OP iuCacheOp;
-} __attribute__((packed)) PVRSRV_BRIDGE_IN_CACHEOPQUEUE;
+	IMG_HANDLE hPrivData;
+	IMG_DEV_VIRTADDR sDevSignalAddress;
+} __attribute__((packed)) PVRSRV_BRIDGE_IN_RGXNOTIFYSIGNALUPDATE;
 
-/* Bridge out structure for CacheOpQueue */
-typedef struct PVRSRV_BRIDGE_OUT_CACHEOPQUEUE_TAG
+/* Bridge out structure for RGXNotifySignalUpdate */
+typedef struct PVRSRV_BRIDGE_OUT_RGXNOTIFYSIGNALUPDATE_TAG
 {
 	PVRSRV_ERROR eError;
-} __attribute__((packed)) PVRSRV_BRIDGE_OUT_CACHEOPQUEUE;
+} __attribute__((packed)) PVRSRV_BRIDGE_OUT_RGXNOTIFYSIGNALUPDATE;
 
 
-#endif /* COMMON_CACHEGENERIC_BRIDGE_H */
+#endif /* COMMON_RGXSIGNALS_BRIDGE_H */
diff --git a/drivers/staging/imgtec/rogue/generated/rgxsignals_bridge/server_rgxsignals_bridge.c b/drivers/staging/imgtec/rogue/generated/rgxsignals_bridge/server_rgxsignals_bridge.c
new file mode 100644
index 0000000..7b9db97
--- /dev/null
+++ b/drivers/staging/imgtec/rogue/generated/rgxsignals_bridge/server_rgxsignals_bridge.c
@@ -0,0 +1,190 @@
+/*************************************************************************/ /*!
+@File
+@Title          Server bridge for rgxsignals
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description    Implements the server side of the bridge for rgxsignals
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#include <stddef.h>
+#include <asm/uaccess.h>
+
+#include "img_defs.h"
+
+#include "rgxsignals.h"
+
+
+#include "common_rgxsignals_bridge.h"
+
+#include "allocmem.h"
+#include "pvr_debug.h"
+#include "connection_server.h"
+#include "pvr_bridge.h"
+#include "rgx_bridge.h"
+#include "srvcore.h"
+#include "handle.h"
+
+#include <linux/slab.h>
+
+
+#include "rgx_bvnc_defs_km.h"
+
+
+
+
+/* ***************************************************************************
+ * Server-side bridge entry points
+ */
+ 
+static IMG_INT
+PVRSRVBridgeRGXNotifySignalUpdate(IMG_UINT32 ui32DispatchTableEntry,
+					  PVRSRV_BRIDGE_IN_RGXNOTIFYSIGNALUPDATE *psRGXNotifySignalUpdateIN,
+					  PVRSRV_BRIDGE_OUT_RGXNOTIFYSIGNALUPDATE *psRGXNotifySignalUpdateOUT,
+					 CONNECTION_DATA *psConnection)
+{
+	IMG_HANDLE hPrivData = psRGXNotifySignalUpdateIN->hPrivData;
+	IMG_HANDLE hPrivDataInt = NULL;
+
+
+	{
+		PVRSRV_DEVICE_NODE *psDeviceNode = OSGetDevData(psConnection);
+
+		/* Check that device supports the required feature */
+		if ((psDeviceNode->pfnCheckDeviceFeature) &&
+			!psDeviceNode->pfnCheckDeviceFeature(psDeviceNode, RGX_FEATURE_SIGNAL_SNOOPING_BIT_MASK))
+		{
+			psRGXNotifySignalUpdateOUT->eError = PVRSRV_ERROR_NOT_SUPPORTED;
+
+			goto RGXNotifySignalUpdate_exit;
+		}
+	}
+
+
+
+
+
+	/* Lock over handle lookup. */
+	LockHandle();
+
+
+
+
+
+				{
+					/* Look up the address from the handle */
+					psRGXNotifySignalUpdateOUT->eError =
+						PVRSRVLookupHandleUnlocked(psConnection->psHandleBase,
+											(void **) &hPrivDataInt,
+											hPrivData,
+											PVRSRV_HANDLE_TYPE_DEV_PRIV_DATA,
+											IMG_TRUE);
+					if(psRGXNotifySignalUpdateOUT->eError != PVRSRV_OK)
+					{
+						UnlockHandle();
+						goto RGXNotifySignalUpdate_exit;
+					}
+				}
+	/* Release now we have looked up handles. */
+	UnlockHandle();
+
+	psRGXNotifySignalUpdateOUT->eError =
+		PVRSRVRGXNotifySignalUpdateKM(psConnection, OSGetDevData(psConnection),
+					hPrivDataInt,
+					psRGXNotifySignalUpdateIN->sDevSignalAddress);
+
+
+
+
+RGXNotifySignalUpdate_exit:
+
+	/* Lock over handle lookup cleanup. */
+	LockHandle();
+
+
+
+
+
+
+				{
+					/* Unreference the previously looked up handle */
+						if(hPrivDataInt)
+						{
+							PVRSRVReleaseHandleUnlocked(psConnection->psHandleBase,
+											hPrivData,
+											PVRSRV_HANDLE_TYPE_DEV_PRIV_DATA);
+						}
+				}
+	/* Release now we have cleaned up look up handles. */
+	UnlockHandle();
+
+
+	return 0;
+}
+
+
+
+
+/* *************************************************************************** 
+ * Server bridge dispatch related glue 
+ */
+
+static IMG_BOOL bUseLock = IMG_TRUE;
+
+PVRSRV_ERROR InitRGXSIGNALSBridge(void);
+PVRSRV_ERROR DeinitRGXSIGNALSBridge(void);
+
+/*
+ * Register all RGXSIGNALS functions with services
+ */
+PVRSRV_ERROR InitRGXSIGNALSBridge(void)
+{
+
+	SetDispatchTableEntry(PVRSRV_BRIDGE_RGXSIGNALS, PVRSRV_BRIDGE_RGXSIGNALS_RGXNOTIFYSIGNALUPDATE, PVRSRVBridgeRGXNotifySignalUpdate,
+					NULL, bUseLock);
+
+
+	return PVRSRV_OK;
+}
+
+/*
+ * Unregister all rgxsignals functions with services
+ */
+PVRSRV_ERROR DeinitRGXSIGNALSBridge(void)
+{
+	return PVRSRV_OK;
+}
diff --git a/drivers/staging/imgtec/rogue/generated/rgxta3d_bridge/common_rgxta3d_bridge.h b/drivers/staging/imgtec/rogue/generated/rgxta3d_bridge/common_rgxta3d_bridge.h
index 4a07ac2..9f062c4 100644
--- a/drivers/staging/imgtec/rogue/generated/rgxta3d_bridge/common_rgxta3d_bridge.h
+++ b/drivers/staging/imgtec/rogue/generated/rgxta3d_bridge/common_rgxta3d_bridge.h
@@ -2,8 +2,8 @@
 @File
 @Title          Common bridge header for rgxta3d
 @Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
-@Description    Declares common defines and structures that are used by both
-                the client and sever side of the bridge for rgxta3d
+@Description    Declares common defines and structures used by both the client
+                and server side of the bridge for rgxta3d
 @License        Dual MIT/GPLv2
 
 The contents of this file are subject to the MIT license as set out below.
@@ -45,11 +45,13 @@
 #ifndef COMMON_RGXTA3D_BRIDGE_H
 #define COMMON_RGXTA3D_BRIDGE_H
 
+#include <powervr/mem_types.h>
+
 #include "img_types.h"
 #include "pvrsrv_error.h"
 
 #include "rgx_bridge.h"
-#include "sync_external.h"
+#include <powervr/sync_external.h>
 #include "rgx_fwif_shared.h"
 
 
@@ -253,6 +255,7 @@
 	IMG_UINT32 ui32ui32MaxFLPages;
 	IMG_UINT32 ui32ui32InitFLPages;
 	IMG_UINT32 ui32ui32GrowFLPages;
+	IMG_HANDLE hsGlobalFreeList;
 	IMG_BOOL bbFreeListCheck;
 	IMG_DEV_VIRTADDR spsFreeListDevVAddr;
 	IMG_HANDLE hsFreeListPMR;
@@ -367,6 +370,7 @@
 typedef struct PVRSRV_BRIDGE_IN_RGXKICKTA3D_TAG
 {
 	IMG_HANDLE hRenderContext;
+	IMG_UINT32 ui32ClientCacheOpSeqNum;
 	IMG_UINT32 ui32ClientTAFenceCount;
 	IMG_HANDLE * phClientTAFenceSyncPrimBlock;
 	IMG_UINT32 * pui32ClientTAFenceSyncOffset;
@@ -402,13 +406,12 @@
 	IMG_UINT32 ui323DCmdSize;
 	IMG_BYTE * ps3DCmd;
 	IMG_UINT32 ui32ExtJobRef;
-	IMG_UINT32 ui32IntJobRef;
 	IMG_BOOL bbLastTAInScene;
 	IMG_BOOL bbKickTA;
 	IMG_BOOL bbKickPR;
 	IMG_BOOL bbKick3D;
 	IMG_BOOL bbAbort;
-	IMG_BOOL bbPDumpContinuous;
+	IMG_UINT32 ui32PDumpFlags;
 	IMG_HANDLE hRTDataCleanup;
 	IMG_HANDLE hZBuffer;
 	IMG_HANDLE hSBuffer;
@@ -417,6 +420,11 @@
 	IMG_UINT32 ui32SyncPMRCount;
 	IMG_UINT32 * pui32SyncPMRFlags;
 	IMG_HANDLE * phSyncPMRs;
+	IMG_UINT32 ui32RenderTargetSize;
+	IMG_UINT32 ui32NumberOfDrawCalls;
+	IMG_UINT32 ui32NumberOfIndices;
+	IMG_UINT32 ui32NumberOfMRTs;
+	IMG_UINT64 ui64Deadline;
 } __attribute__((packed)) PVRSRV_BRIDGE_IN_RGXKICKTA3D;
 
 /* Bridge out structure for RGXKickTA3D */
diff --git a/drivers/staging/imgtec/rogue/generated/rgxta3d_bridge/server_rgxta3d_bridge.c b/drivers/staging/imgtec/rogue/generated/rgxta3d_bridge/server_rgxta3d_bridge.c
index 8ad589f..e5596a4 100644
--- a/drivers/staging/imgtec/rogue/generated/rgxta3d_bridge/server_rgxta3d_bridge.c
+++ b/drivers/staging/imgtec/rogue/generated/rgxta3d_bridge/server_rgxta3d_bridge.c
@@ -64,6 +64,8 @@
 
 
 
+
+
 /* ***************************************************************************
  * Server-side bridge entry points
  */
@@ -80,39 +82,73 @@
 	DEVMEM_MEMDESC * psRTACtlMemDescInt = NULL;
 	DEVMEM_MEMDESC * pssHWRTDataMemDescInt = NULL;
 
+	IMG_UINT32 ui32NextOffset = 0;
+	IMG_BYTE   *pArrayArgsBuffer = NULL;
+#if !defined(INTEGRITY_OS)
+	IMG_BOOL bHaveEnoughSpace = IMG_FALSE;
+#endif
+
+	IMG_UINT32 ui32BufferSize = 
+			(RGXFW_MAX_FREELISTS * sizeof(RGX_FREELIST *)) +
+			(RGXFW_MAX_FREELISTS * sizeof(IMG_HANDLE)) +
+			0;
+
+
 
 
 	psRGXCreateHWRTDataOUT->hCleanupCookie = NULL;
 
-	
+	if (ui32BufferSize != 0)
 	{
-		psapsFreeListsInt = OSAllocMemNoStats(RGXFW_MAX_FREELISTS * sizeof(RGX_FREELIST *));
-		if (!psapsFreeListsInt)
+#if !defined(INTEGRITY_OS)
+		/* Try to use remainder of input buffer for copies if possible, word-aligned for safety. */
+		IMG_UINT32 ui32InBufferOffset = PVR_ALIGN(sizeof(*psRGXCreateHWRTDataIN), sizeof(unsigned long));
+		IMG_UINT32 ui32InBufferExcessSize = ui32InBufferOffset >= PVRSRV_MAX_BRIDGE_IN_SIZE ? 0 :
+			PVRSRV_MAX_BRIDGE_IN_SIZE - ui32InBufferOffset;
+
+		bHaveEnoughSpace = ui32BufferSize <= ui32InBufferExcessSize;
+		if (bHaveEnoughSpace)
 		{
-			psRGXCreateHWRTDataOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
-	
-			goto RGXCreateHWRTData_exit;
-		}
-		hapsFreeListsInt2 = OSAllocMemNoStats(RGXFW_MAX_FREELISTS * sizeof(IMG_HANDLE));
-		if (!hapsFreeListsInt2)
+			IMG_BYTE *pInputBuffer = (IMG_BYTE *)psRGXCreateHWRTDataIN;
+
+			pArrayArgsBuffer = &pInputBuffer[ui32InBufferOffset];		}
+		else
+#endif
 		{
-			psRGXCreateHWRTDataOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
-	
-			goto RGXCreateHWRTData_exit;
+			pArrayArgsBuffer = OSAllocMemNoStats(ui32BufferSize);
+
+			if(!pArrayArgsBuffer)
+			{
+				psRGXCreateHWRTDataOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
+				goto RGXCreateHWRTData_exit;
+			}
 		}
 	}
 
-			/* Copy the data over */
-			if ( !OSAccessOK(PVR_VERIFY_READ, (void*) psRGXCreateHWRTDataIN->phapsFreeLists, RGXFW_MAX_FREELISTS * sizeof(IMG_HANDLE))
-				|| (OSCopyFromUser(NULL, hapsFreeListsInt2, psRGXCreateHWRTDataIN->phapsFreeLists,
-				RGXFW_MAX_FREELISTS * sizeof(IMG_HANDLE)) != PVRSRV_OK) )
-			{
-				psRGXCreateHWRTDataOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
+	
+	{
+		psapsFreeListsInt = (RGX_FREELIST **)(((IMG_UINT8 *)pArrayArgsBuffer) + ui32NextOffset);
+		ui32NextOffset += RGXFW_MAX_FREELISTS * sizeof(RGX_FREELIST *);
+		hapsFreeListsInt2 = (IMG_HANDLE *)(((IMG_UINT8 *)pArrayArgsBuffer) + ui32NextOffset); 
+		ui32NextOffset += RGXFW_MAX_FREELISTS * sizeof(IMG_HANDLE);
+	}
 
-				goto RGXCreateHWRTData_exit;
+			/* Copy the data over */
+			if (RGXFW_MAX_FREELISTS * sizeof(IMG_HANDLE) > 0)
+			{
+				if ( OSCopyFromUser(NULL, hapsFreeListsInt2, psRGXCreateHWRTDataIN->phapsFreeLists, RGXFW_MAX_FREELISTS * sizeof(IMG_HANDLE)) != PVRSRV_OK )
+				{
+					psRGXCreateHWRTDataOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
+
+					goto RGXCreateHWRTData_exit;
+				}
 			}
 
-	PMRLock();
+	/* Lock over handle lookup. */
+	LockHandle();
+
+
+
 
 
 	{
@@ -123,19 +159,21 @@
 				{
 					/* Look up the address from the handle */
 					psRGXCreateHWRTDataOUT->eError =
-						PVRSRVLookupHandle(psConnection->psHandleBase,
+						PVRSRVLookupHandleUnlocked(psConnection->psHandleBase,
 											(void **) &psapsFreeListsInt[i],
 											hapsFreeListsInt2[i],
-											PVRSRV_HANDLE_TYPE_RGX_FREELIST);
+											PVRSRV_HANDLE_TYPE_RGX_FREELIST,
+											IMG_TRUE);
 					if(psRGXCreateHWRTDataOUT->eError != PVRSRV_OK)
 					{
-						PMRUnlock();
+						UnlockHandle();
 						goto RGXCreateHWRTData_exit;
 					}
 				}
-
 		}
 	}
+	/* Release now we have looked up handles. */
+	UnlockHandle();
 
 	psRGXCreateHWRTDataOUT->eError =
 		RGXCreateHWRTData(psConnection, OSGetDevData(psConnection),
@@ -168,13 +206,18 @@
 	/* Exit early if bridged call fails */
 	if(psRGXCreateHWRTDataOUT->eError != PVRSRV_OK)
 	{
-		PMRUnlock();
 		goto RGXCreateHWRTData_exit;
 	}
-	PMRUnlock();
+
+	/* Lock over handle creation. */
+	LockHandle();
 
 
-	psRGXCreateHWRTDataOUT->eError = PVRSRVAllocHandle(psConnection->psHandleBase,
+
+
+
+	psRGXCreateHWRTDataOUT->eError = PVRSRVAllocHandleUnlocked(psConnection->psHandleBase,
+
 							&psRGXCreateHWRTDataOUT->hCleanupCookie,
 							(void *) psCleanupCookieInt,
 							PVRSRV_HANDLE_TYPE_RGX_RTDATA_CLEANUP,
@@ -182,11 +225,17 @@
 							,(PFN_HANDLE_RELEASE)&RGXDestroyHWRTData);
 	if (psRGXCreateHWRTDataOUT->eError != PVRSRV_OK)
 	{
+		UnlockHandle();
 		goto RGXCreateHWRTData_exit;
 	}
 
 
-	psRGXCreateHWRTDataOUT->eError = PVRSRVAllocSubHandle(psConnection->psHandleBase,
+
+
+
+
+	psRGXCreateHWRTDataOUT->eError = PVRSRVAllocSubHandleUnlocked(psConnection->psHandleBase,
+
 							&psRGXCreateHWRTDataOUT->hRTACtlMemDesc,
 							(void *) psRTACtlMemDescInt,
 							PVRSRV_HANDLE_TYPE_RGX_FW_MEMDESC,
@@ -194,11 +243,17 @@
 							,psRGXCreateHWRTDataOUT->hCleanupCookie);
 	if (psRGXCreateHWRTDataOUT->eError != PVRSRV_OK)
 	{
+		UnlockHandle();
 		goto RGXCreateHWRTData_exit;
 	}
 
 
-	psRGXCreateHWRTDataOUT->eError = PVRSRVAllocSubHandle(psConnection->psHandleBase,
+
+
+
+
+	psRGXCreateHWRTDataOUT->eError = PVRSRVAllocSubHandleUnlocked(psConnection->psHandleBase,
+
 							&psRGXCreateHWRTDataOUT->hsHWRTDataMemDesc,
 							(void *) pssHWRTDataMemDescInt,
 							PVRSRV_HANDLE_TYPE_RGX_FW_MEMDESC,
@@ -206,22 +261,65 @@
 							,psRGXCreateHWRTDataOUT->hCleanupCookie);
 	if (psRGXCreateHWRTDataOUT->eError != PVRSRV_OK)
 	{
+		UnlockHandle();
 		goto RGXCreateHWRTData_exit;
 	}
 
+	/* Release now we have created handles. */
+	UnlockHandle();
 
 
 
 RGXCreateHWRTData_exit:
+
+	/* Lock over handle lookup cleanup. */
+	LockHandle();
+
+
+
+
+
+
+
+	if (hapsFreeListsInt2)
+	{
+		IMG_UINT32 i;
+
+		for (i=0;i<RGXFW_MAX_FREELISTS;i++)
+		{
+				{
+					/* Unreference the previously looked up handle */
+						if(psapsFreeListsInt[i])
+						{
+							PVRSRVReleaseHandleUnlocked(psConnection->psHandleBase,
+											hapsFreeListsInt2[i],
+											PVRSRV_HANDLE_TYPE_RGX_FREELIST);
+						}
+				}
+		}
+	}
+	/* Release now we have cleaned up look up handles. */
+	UnlockHandle();
+
 	if (psRGXCreateHWRTDataOUT->eError != PVRSRV_OK)
 	{
+		/* Lock over handle creation cleanup. */
+		LockHandle();
 		if (psRGXCreateHWRTDataOUT->hCleanupCookie)
 		{
-			PVRSRV_ERROR eError = PVRSRVReleaseHandle(psConnection->psHandleBase,
+
+
+			PVRSRV_ERROR eError = PVRSRVReleaseHandleUnlocked(psConnection->psHandleBase,
 						(IMG_HANDLE) psRGXCreateHWRTDataOUT->hCleanupCookie,
 						PVRSRV_HANDLE_TYPE_RGX_RTDATA_CLEANUP);
-
-			/* Releasing the handle should free/destroy/release the resource. This should never fail... */
+			if ((eError != PVRSRV_OK) && (eError != PVRSRV_ERROR_RETRY))
+			{
+				PVR_DPF((PVR_DBG_ERROR,
+				        "PVRSRVBridgeRGXCreateHWRTData: %s",
+				        PVRSRVGetErrorStringKM(eError)));
+			}
+			/* Releasing the handle should free/destroy/release the resource.
+			 * This should never fail... */
 			PVR_ASSERT((eError == PVRSRV_OK) || (eError == PVRSRV_ERROR_RETRY));
 
 			/* Avoid freeing/destroying/releasing the resource a second time below */
@@ -229,20 +327,29 @@
 		}
 
 
+		/* Release now we have cleaned up creation handles. */
+		UnlockHandle();
 		if (psCleanupCookieInt)
 		{
 			RGXDestroyHWRTData(psCleanupCookieInt);
 		}
 	}
 
-	if (psapsFreeListsInt)
-		OSFreeMemNoStats(psapsFreeListsInt);
-	if (hapsFreeListsInt2)
-		OSFreeMemNoStats(hapsFreeListsInt2);
+	/* Allocated space should be equal to the last updated offset */
+	PVR_ASSERT(ui32BufferSize == ui32NextOffset);
+
+#if defined(INTEGRITY_OS)
+	if(pArrayArgsBuffer)
+#else
+	if(!bHaveEnoughSpace && pArrayArgsBuffer)
+#endif
+		OSFreeMemNoStats(pArrayArgsBuffer);
+
 
 	return 0;
 }
 
+
 static IMG_INT
 PVRSRVBridgeRGXDestroyHWRTData(IMG_UINT32 ui32DispatchTableEntry,
 					  PVRSRV_BRIDGE_IN_RGXDESTROYHWRTDATA *psRGXDestroyHWRTDataIN,
@@ -254,30 +361,46 @@
 
 
 
-	PMRLock();
+
+
+
+
+	/* Lock over handle destruction. */
+	LockHandle();
+
 
 
 
 
 	psRGXDestroyHWRTDataOUT->eError =
-		PVRSRVReleaseHandle(psConnection->psHandleBase,
+		PVRSRVReleaseHandleUnlocked(psConnection->psHandleBase,
 					(IMG_HANDLE) psRGXDestroyHWRTDataIN->hCleanupCookie,
 					PVRSRV_HANDLE_TYPE_RGX_RTDATA_CLEANUP);
-	if ((psRGXDestroyHWRTDataOUT->eError != PVRSRV_OK) && (psRGXDestroyHWRTDataOUT->eError != PVRSRV_ERROR_RETRY))
+	if ((psRGXDestroyHWRTDataOUT->eError != PVRSRV_OK) &&
+	    (psRGXDestroyHWRTDataOUT->eError != PVRSRV_ERROR_RETRY))
 	{
+		PVR_DPF((PVR_DBG_ERROR,
+		        "PVRSRVBridgeRGXDestroyHWRTData: %s",
+		        PVRSRVGetErrorStringKM(psRGXDestroyHWRTDataOUT->eError)));
 		PVR_ASSERT(0);
-		PMRUnlock();
+		UnlockHandle();
 		goto RGXDestroyHWRTData_exit;
 	}
 
-	PMRUnlock();
+	/* Release now we have destroyed handles. */
+	UnlockHandle();
+
 
 
 RGXDestroyHWRTData_exit:
 
+
+
+
 	return 0;
 }
 
+
 static IMG_INT
 PVRSRVBridgeRGXCreateRenderTarget(IMG_UINT32 ui32DispatchTableEntry,
 					  PVRSRV_BRIDGE_IN_RGXCREATERENDERTARGET *psRGXCreateRenderTargetIN,
@@ -290,7 +413,7 @@
 
 
 
-	PMRLock();
+
 
 
 	psRGXCreateRenderTargetOUT->eError =
@@ -301,13 +424,18 @@
 	/* Exit early if bridged call fails */
 	if(psRGXCreateRenderTargetOUT->eError != PVRSRV_OK)
 	{
-		PMRUnlock();
 		goto RGXCreateRenderTarget_exit;
 	}
-	PMRUnlock();
+
+	/* Lock over handle creation. */
+	LockHandle();
 
 
-	psRGXCreateRenderTargetOUT->eError = PVRSRVAllocHandle(psConnection->psHandleBase,
+
+
+
+	psRGXCreateRenderTargetOUT->eError = PVRSRVAllocHandleUnlocked(psConnection->psHandleBase,
+
 							&psRGXCreateRenderTargetOUT->hsRenderTargetMemDesc,
 							(void *) pssRenderTargetMemDescInt,
 							PVRSRV_HANDLE_TYPE_RGX_FWIF_RENDERTARGET,
@@ -315,13 +443,19 @@
 							,(PFN_HANDLE_RELEASE)&RGXDestroyRenderTarget);
 	if (psRGXCreateRenderTargetOUT->eError != PVRSRV_OK)
 	{
+		UnlockHandle();
 		goto RGXCreateRenderTarget_exit;
 	}
 
+	/* Release now we have created handles. */
+	UnlockHandle();
 
 
 
 RGXCreateRenderTarget_exit:
+
+
+
 	if (psRGXCreateRenderTargetOUT->eError != PVRSRV_OK)
 	{
 		if (pssRenderTargetMemDescInt)
@@ -334,6 +468,7 @@
 	return 0;
 }
 
+
 static IMG_INT
 PVRSRVBridgeRGXDestroyRenderTarget(IMG_UINT32 ui32DispatchTableEntry,
 					  PVRSRV_BRIDGE_IN_RGXDESTROYRENDERTARGET *psRGXDestroyRenderTargetIN,
@@ -345,37 +480,55 @@
 
 
 
-	PMRLock();
+
+
+
+
+	/* Lock over handle destruction. */
+	LockHandle();
+
 
 
 
 
 	psRGXDestroyRenderTargetOUT->eError =
-		PVRSRVReleaseHandle(psConnection->psHandleBase,
+		PVRSRVReleaseHandleUnlocked(psConnection->psHandleBase,
 					(IMG_HANDLE) psRGXDestroyRenderTargetIN->hsRenderTargetMemDesc,
 					PVRSRV_HANDLE_TYPE_RGX_FWIF_RENDERTARGET);
-	if ((psRGXDestroyRenderTargetOUT->eError != PVRSRV_OK) && (psRGXDestroyRenderTargetOUT->eError != PVRSRV_ERROR_RETRY))
+	if ((psRGXDestroyRenderTargetOUT->eError != PVRSRV_OK) &&
+	    (psRGXDestroyRenderTargetOUT->eError != PVRSRV_ERROR_RETRY))
 	{
+		PVR_DPF((PVR_DBG_ERROR,
+		        "PVRSRVBridgeRGXDestroyRenderTarget: %s",
+		        PVRSRVGetErrorStringKM(psRGXDestroyRenderTargetOUT->eError)));
 		PVR_ASSERT(0);
-		PMRUnlock();
+		UnlockHandle();
 		goto RGXDestroyRenderTarget_exit;
 	}
 
-	PMRUnlock();
+	/* Release now we have destroyed handles. */
+	UnlockHandle();
+
 
 
 RGXDestroyRenderTarget_exit:
 
+
+
+
 	return 0;
 }
 
+
 static IMG_INT
 PVRSRVBridgeRGXCreateZSBuffer(IMG_UINT32 ui32DispatchTableEntry,
 					  PVRSRV_BRIDGE_IN_RGXCREATEZSBUFFER *psRGXCreateZSBufferIN,
 					  PVRSRV_BRIDGE_OUT_RGXCREATEZSBUFFER *psRGXCreateZSBufferOUT,
 					 CONNECTION_DATA *psConnection)
 {
+	IMG_HANDLE hReservation = psRGXCreateZSBufferIN->hReservation;
 	DEVMEMINT_RESERVATION * psReservationInt = NULL;
+	IMG_HANDLE hPMR = psRGXCreateZSBufferIN->hPMR;
 	PMR * psPMRInt = NULL;
 	RGX_ZSBUFFER_DATA * pssZSBufferKMInt = NULL;
 
@@ -383,38 +536,50 @@
 
 
 
-	PMRLock();
+
+
+	/* Lock over handle lookup. */
+	LockHandle();
+
+
+
 
 
 				{
 					/* Look up the address from the handle */
 					psRGXCreateZSBufferOUT->eError =
-						PVRSRVLookupHandle(psConnection->psHandleBase,
+						PVRSRVLookupHandleUnlocked(psConnection->psHandleBase,
 											(void **) &psReservationInt,
-											psRGXCreateZSBufferIN->hReservation,
-											PVRSRV_HANDLE_TYPE_DEVMEMINT_RESERVATION);
+											hReservation,
+											PVRSRV_HANDLE_TYPE_DEVMEMINT_RESERVATION,
+											IMG_TRUE);
 					if(psRGXCreateZSBufferOUT->eError != PVRSRV_OK)
 					{
-						PMRUnlock();
+						UnlockHandle();
 						goto RGXCreateZSBuffer_exit;
 					}
 				}
 
 
+
+
+
 				{
 					/* Look up the address from the handle */
 					psRGXCreateZSBufferOUT->eError =
-						PVRSRVLookupHandle(psConnection->psHandleBase,
+						PVRSRVLookupHandleUnlocked(psConnection->psHandleBase,
 											(void **) &psPMRInt,
-											psRGXCreateZSBufferIN->hPMR,
-											PVRSRV_HANDLE_TYPE_PHYSMEM_PMR);
+											hPMR,
+											PVRSRV_HANDLE_TYPE_PHYSMEM_PMR,
+											IMG_TRUE);
 					if(psRGXCreateZSBufferOUT->eError != PVRSRV_OK)
 					{
-						PMRUnlock();
+						UnlockHandle();
 						goto RGXCreateZSBuffer_exit;
 					}
 				}
-
+	/* Release now we have looked up handles. */
+	UnlockHandle();
 
 	psRGXCreateZSBufferOUT->eError =
 		RGXCreateZSBufferKM(psConnection, OSGetDevData(psConnection),
@@ -426,13 +591,18 @@
 	/* Exit early if bridged call fails */
 	if(psRGXCreateZSBufferOUT->eError != PVRSRV_OK)
 	{
-		PMRUnlock();
 		goto RGXCreateZSBuffer_exit;
 	}
-	PMRUnlock();
+
+	/* Lock over handle creation. */
+	LockHandle();
 
 
-	psRGXCreateZSBufferOUT->eError = PVRSRVAllocHandle(psConnection->psHandleBase,
+
+
+
+	psRGXCreateZSBufferOUT->eError = PVRSRVAllocHandleUnlocked(psConnection->psHandleBase,
+
 							&psRGXCreateZSBufferOUT->hsZSBufferKM,
 							(void *) pssZSBufferKMInt,
 							PVRSRV_HANDLE_TYPE_RGX_FWIF_ZSBUFFER,
@@ -440,13 +610,51 @@
 							,(PFN_HANDLE_RELEASE)&RGXDestroyZSBufferKM);
 	if (psRGXCreateZSBufferOUT->eError != PVRSRV_OK)
 	{
+		UnlockHandle();
 		goto RGXCreateZSBuffer_exit;
 	}
 
+	/* Release now we have created handles. */
+	UnlockHandle();
 
 
 
 RGXCreateZSBuffer_exit:
+
+	/* Lock over handle lookup cleanup. */
+	LockHandle();
+
+
+
+
+
+
+				{
+					/* Unreference the previously looked up handle */
+						if(psReservationInt)
+						{
+							PVRSRVReleaseHandleUnlocked(psConnection->psHandleBase,
+											hReservation,
+											PVRSRV_HANDLE_TYPE_DEVMEMINT_RESERVATION);
+						}
+				}
+
+
+
+
+
+				{
+					/* Unreference the previously looked up handle */
+						if(psPMRInt)
+						{
+							PVRSRVReleaseHandleUnlocked(psConnection->psHandleBase,
+											hPMR,
+											PVRSRV_HANDLE_TYPE_PHYSMEM_PMR);
+						}
+				}
+	/* Release now we have cleaned up look up handles. */
+	UnlockHandle();
+
 	if (psRGXCreateZSBufferOUT->eError != PVRSRV_OK)
 	{
 		if (pssZSBufferKMInt)
@@ -459,6 +667,7 @@
 	return 0;
 }
 
+
 static IMG_INT
 PVRSRVBridgeRGXDestroyZSBuffer(IMG_UINT32 ui32DispatchTableEntry,
 					  PVRSRV_BRIDGE_IN_RGXDESTROYZSBUFFER *psRGXDestroyZSBufferIN,
@@ -470,36 +679,53 @@
 
 
 
-	PMRLock();
+
+
+
+
+	/* Lock over handle destruction. */
+	LockHandle();
+
 
 
 
 
 	psRGXDestroyZSBufferOUT->eError =
-		PVRSRVReleaseHandle(psConnection->psHandleBase,
+		PVRSRVReleaseHandleUnlocked(psConnection->psHandleBase,
 					(IMG_HANDLE) psRGXDestroyZSBufferIN->hsZSBufferMemDesc,
 					PVRSRV_HANDLE_TYPE_RGX_FWIF_ZSBUFFER);
-	if ((psRGXDestroyZSBufferOUT->eError != PVRSRV_OK) && (psRGXDestroyZSBufferOUT->eError != PVRSRV_ERROR_RETRY))
+	if ((psRGXDestroyZSBufferOUT->eError != PVRSRV_OK) &&
+	    (psRGXDestroyZSBufferOUT->eError != PVRSRV_ERROR_RETRY))
 	{
+		PVR_DPF((PVR_DBG_ERROR,
+		        "PVRSRVBridgeRGXDestroyZSBuffer: %s",
+		        PVRSRVGetErrorStringKM(psRGXDestroyZSBufferOUT->eError)));
 		PVR_ASSERT(0);
-		PMRUnlock();
+		UnlockHandle();
 		goto RGXDestroyZSBuffer_exit;
 	}
 
-	PMRUnlock();
+	/* Release now we have destroyed handles. */
+	UnlockHandle();
+
 
 
 RGXDestroyZSBuffer_exit:
 
+
+
+
 	return 0;
 }
 
+
 static IMG_INT
 PVRSRVBridgeRGXPopulateZSBuffer(IMG_UINT32 ui32DispatchTableEntry,
 					  PVRSRV_BRIDGE_IN_RGXPOPULATEZSBUFFER *psRGXPopulateZSBufferIN,
 					  PVRSRV_BRIDGE_OUT_RGXPOPULATEZSBUFFER *psRGXPopulateZSBufferOUT,
 					 CONNECTION_DATA *psConnection)
 {
+	IMG_HANDLE hsZSBufferKM = psRGXPopulateZSBufferIN->hsZSBufferKM;
 	RGX_ZSBUFFER_DATA * pssZSBufferKMInt = NULL;
 	RGX_POPULATION * pssPopulationInt = NULL;
 
@@ -507,23 +733,31 @@
 
 
 
-	PMRLock();
+
+
+	/* Lock over handle lookup. */
+	LockHandle();
+
+
+
 
 
 				{
 					/* Look up the address from the handle */
 					psRGXPopulateZSBufferOUT->eError =
-						PVRSRVLookupHandle(psConnection->psHandleBase,
+						PVRSRVLookupHandleUnlocked(psConnection->psHandleBase,
 											(void **) &pssZSBufferKMInt,
-											psRGXPopulateZSBufferIN->hsZSBufferKM,
-											PVRSRV_HANDLE_TYPE_RGX_FWIF_ZSBUFFER);
+											hsZSBufferKM,
+											PVRSRV_HANDLE_TYPE_RGX_FWIF_ZSBUFFER,
+											IMG_TRUE);
 					if(psRGXPopulateZSBufferOUT->eError != PVRSRV_OK)
 					{
-						PMRUnlock();
+						UnlockHandle();
 						goto RGXPopulateZSBuffer_exit;
 					}
 				}
-
+	/* Release now we have looked up handles. */
+	UnlockHandle();
 
 	psRGXPopulateZSBufferOUT->eError =
 		RGXPopulateZSBufferKM(
@@ -532,13 +766,18 @@
 	/* Exit early if bridged call fails */
 	if(psRGXPopulateZSBufferOUT->eError != PVRSRV_OK)
 	{
-		PMRUnlock();
 		goto RGXPopulateZSBuffer_exit;
 	}
-	PMRUnlock();
+
+	/* Lock over handle creation. */
+	LockHandle();
 
 
-	psRGXPopulateZSBufferOUT->eError = PVRSRVAllocHandle(psConnection->psHandleBase,
+
+
+
+	psRGXPopulateZSBufferOUT->eError = PVRSRVAllocHandleUnlocked(psConnection->psHandleBase,
+
 							&psRGXPopulateZSBufferOUT->hsPopulation,
 							(void *) pssPopulationInt,
 							PVRSRV_HANDLE_TYPE_RGX_POPULATION,
@@ -546,13 +785,37 @@
 							,(PFN_HANDLE_RELEASE)&RGXUnpopulateZSBufferKM);
 	if (psRGXPopulateZSBufferOUT->eError != PVRSRV_OK)
 	{
+		UnlockHandle();
 		goto RGXPopulateZSBuffer_exit;
 	}
 
+	/* Release now we have created handles. */
+	UnlockHandle();
 
 
 
 RGXPopulateZSBuffer_exit:
+
+	/* Lock over handle lookup cleanup. */
+	LockHandle();
+
+
+
+
+
+
+				{
+					/* Unreference the previously looked up handle */
+						if(pssZSBufferKMInt)
+						{
+							PVRSRVReleaseHandleUnlocked(psConnection->psHandleBase,
+											hsZSBufferKM,
+											PVRSRV_HANDLE_TYPE_RGX_FWIF_ZSBUFFER);
+						}
+				}
+	/* Release now we have cleaned up look up handles. */
+	UnlockHandle();
+
 	if (psRGXPopulateZSBufferOUT->eError != PVRSRV_OK)
 	{
 		if (pssPopulationInt)
@@ -565,6 +828,7 @@
 	return 0;
 }
 
+
 static IMG_INT
 PVRSRVBridgeRGXUnpopulateZSBuffer(IMG_UINT32 ui32DispatchTableEntry,
 					  PVRSRV_BRIDGE_IN_RGXUNPOPULATEZSBUFFER *psRGXUnpopulateZSBufferIN,
@@ -576,36 +840,55 @@
 
 
 
-	PMRLock();
+
+
+
+
+	/* Lock over handle destruction. */
+	LockHandle();
+
 
 
 
 
 	psRGXUnpopulateZSBufferOUT->eError =
-		PVRSRVReleaseHandle(psConnection->psHandleBase,
+		PVRSRVReleaseHandleUnlocked(psConnection->psHandleBase,
 					(IMG_HANDLE) psRGXUnpopulateZSBufferIN->hsPopulation,
 					PVRSRV_HANDLE_TYPE_RGX_POPULATION);
-	if ((psRGXUnpopulateZSBufferOUT->eError != PVRSRV_OK) && (psRGXUnpopulateZSBufferOUT->eError != PVRSRV_ERROR_RETRY))
+	if ((psRGXUnpopulateZSBufferOUT->eError != PVRSRV_OK) &&
+	    (psRGXUnpopulateZSBufferOUT->eError != PVRSRV_ERROR_RETRY))
 	{
+		PVR_DPF((PVR_DBG_ERROR,
+		        "PVRSRVBridgeRGXUnpopulateZSBuffer: %s",
+		        PVRSRVGetErrorStringKM(psRGXUnpopulateZSBufferOUT->eError)));
 		PVR_ASSERT(0);
-		PMRUnlock();
+		UnlockHandle();
 		goto RGXUnpopulateZSBuffer_exit;
 	}
 
-	PMRUnlock();
+	/* Release now we have destroyed handles. */
+	UnlockHandle();
+
 
 
 RGXUnpopulateZSBuffer_exit:
 
+
+
+
 	return 0;
 }
 
+
 static IMG_INT
 PVRSRVBridgeRGXCreateFreeList(IMG_UINT32 ui32DispatchTableEntry,
 					  PVRSRV_BRIDGE_IN_RGXCREATEFREELIST *psRGXCreateFreeListIN,
 					  PVRSRV_BRIDGE_OUT_RGXCREATEFREELIST *psRGXCreateFreeListOUT,
 					 CONNECTION_DATA *psConnection)
 {
+	IMG_HANDLE hsGlobalFreeList = psRGXCreateFreeListIN->hsGlobalFreeList;
+	RGX_FREELIST * pssGlobalFreeListInt = NULL;
+	IMG_HANDLE hsFreeListPMR = psRGXCreateFreeListIN->hsFreeListPMR;
 	PMR * pssFreeListPMRInt = NULL;
 	RGX_FREELIST * psCleanupCookieInt = NULL;
 
@@ -613,29 +896,58 @@
 
 
 
-	PMRLock();
+
+
+	/* Lock over handle lookup. */
+	LockHandle();
+
+
+
+
+
+				if (psRGXCreateFreeListIN->hsGlobalFreeList)
+				{
+					/* Look up the address from the handle */
+					psRGXCreateFreeListOUT->eError =
+						PVRSRVLookupHandleUnlocked(psConnection->psHandleBase,
+											(void **) &pssGlobalFreeListInt,
+											hsGlobalFreeList,
+											PVRSRV_HANDLE_TYPE_RGX_FREELIST,
+											IMG_TRUE);
+					if(psRGXCreateFreeListOUT->eError != PVRSRV_OK)
+					{
+						UnlockHandle();
+						goto RGXCreateFreeList_exit;
+					}
+				}
+
+
+
 
 
 				{
 					/* Look up the address from the handle */
 					psRGXCreateFreeListOUT->eError =
-						PVRSRVLookupHandle(psConnection->psHandleBase,
+						PVRSRVLookupHandleUnlocked(psConnection->psHandleBase,
 											(void **) &pssFreeListPMRInt,
-											psRGXCreateFreeListIN->hsFreeListPMR,
-											PVRSRV_HANDLE_TYPE_PHYSMEM_PMR);
+											hsFreeListPMR,
+											PVRSRV_HANDLE_TYPE_PHYSMEM_PMR,
+											IMG_TRUE);
 					if(psRGXCreateFreeListOUT->eError != PVRSRV_OK)
 					{
-						PMRUnlock();
+						UnlockHandle();
 						goto RGXCreateFreeList_exit;
 					}
 				}
-
+	/* Release now we have looked up handles. */
+	UnlockHandle();
 
 	psRGXCreateFreeListOUT->eError =
 		RGXCreateFreeList(psConnection, OSGetDevData(psConnection),
 					psRGXCreateFreeListIN->ui32ui32MaxFLPages,
 					psRGXCreateFreeListIN->ui32ui32InitFLPages,
 					psRGXCreateFreeListIN->ui32ui32GrowFLPages,
+					pssGlobalFreeListInt,
 					psRGXCreateFreeListIN->bbFreeListCheck,
 					psRGXCreateFreeListIN->spsFreeListDevVAddr,
 					pssFreeListPMRInt,
@@ -644,13 +956,18 @@
 	/* Exit early if bridged call fails */
 	if(psRGXCreateFreeListOUT->eError != PVRSRV_OK)
 	{
-		PMRUnlock();
 		goto RGXCreateFreeList_exit;
 	}
-	PMRUnlock();
+
+	/* Lock over handle creation. */
+	LockHandle();
 
 
-	psRGXCreateFreeListOUT->eError = PVRSRVAllocHandle(psConnection->psHandleBase,
+
+
+
+	psRGXCreateFreeListOUT->eError = PVRSRVAllocHandleUnlocked(psConnection->psHandleBase,
+
 							&psRGXCreateFreeListOUT->hCleanupCookie,
 							(void *) psCleanupCookieInt,
 							PVRSRV_HANDLE_TYPE_RGX_FREELIST,
@@ -658,13 +975,52 @@
 							,(PFN_HANDLE_RELEASE)&RGXDestroyFreeList);
 	if (psRGXCreateFreeListOUT->eError != PVRSRV_OK)
 	{
+		UnlockHandle();
 		goto RGXCreateFreeList_exit;
 	}
 
+	/* Release now we have created handles. */
+	UnlockHandle();
 
 
 
 RGXCreateFreeList_exit:
+
+	/* Lock over handle lookup cleanup. */
+	LockHandle();
+
+
+
+
+
+
+				if (psRGXCreateFreeListIN->hsGlobalFreeList)
+				{
+					/* Unreference the previously looked up handle */
+						if(pssGlobalFreeListInt)
+						{
+							PVRSRVReleaseHandleUnlocked(psConnection->psHandleBase,
+											hsGlobalFreeList,
+											PVRSRV_HANDLE_TYPE_RGX_FREELIST);
+						}
+				}
+
+
+
+
+
+				{
+					/* Unreference the previously looked up handle */
+						if(pssFreeListPMRInt)
+						{
+							PVRSRVReleaseHandleUnlocked(psConnection->psHandleBase,
+											hsFreeListPMR,
+											PVRSRV_HANDLE_TYPE_PHYSMEM_PMR);
+						}
+				}
+	/* Release now we have cleaned up look up handles. */
+	UnlockHandle();
+
 	if (psRGXCreateFreeListOUT->eError != PVRSRV_OK)
 	{
 		if (psCleanupCookieInt)
@@ -677,6 +1033,7 @@
 	return 0;
 }
 
+
 static IMG_INT
 PVRSRVBridgeRGXDestroyFreeList(IMG_UINT32 ui32DispatchTableEntry,
 					  PVRSRV_BRIDGE_IN_RGXDESTROYFREELIST *psRGXDestroyFreeListIN,
@@ -688,36 +1045,53 @@
 
 
 
-	PMRLock();
+
+
+
+
+	/* Lock over handle destruction. */
+	LockHandle();
+
 
 
 
 
 	psRGXDestroyFreeListOUT->eError =
-		PVRSRVReleaseHandle(psConnection->psHandleBase,
+		PVRSRVReleaseHandleUnlocked(psConnection->psHandleBase,
 					(IMG_HANDLE) psRGXDestroyFreeListIN->hCleanupCookie,
 					PVRSRV_HANDLE_TYPE_RGX_FREELIST);
-	if ((psRGXDestroyFreeListOUT->eError != PVRSRV_OK) && (psRGXDestroyFreeListOUT->eError != PVRSRV_ERROR_RETRY))
+	if ((psRGXDestroyFreeListOUT->eError != PVRSRV_OK) &&
+	    (psRGXDestroyFreeListOUT->eError != PVRSRV_ERROR_RETRY))
 	{
+		PVR_DPF((PVR_DBG_ERROR,
+		        "PVRSRVBridgeRGXDestroyFreeList: %s",
+		        PVRSRVGetErrorStringKM(psRGXDestroyFreeListOUT->eError)));
 		PVR_ASSERT(0);
-		PMRUnlock();
+		UnlockHandle();
 		goto RGXDestroyFreeList_exit;
 	}
 
-	PMRUnlock();
+	/* Release now we have destroyed handles. */
+	UnlockHandle();
+
 
 
 RGXDestroyFreeList_exit:
 
+
+
+
 	return 0;
 }
 
+
 static IMG_INT
 PVRSRVBridgeRGXAddBlockToFreeList(IMG_UINT32 ui32DispatchTableEntry,
 					  PVRSRV_BRIDGE_IN_RGXADDBLOCKTOFREELIST *psRGXAddBlockToFreeListIN,
 					  PVRSRV_BRIDGE_OUT_RGXADDBLOCKTOFREELIST *psRGXAddBlockToFreeListOUT,
 					 CONNECTION_DATA *psConnection)
 {
+	IMG_HANDLE hsFreeList = psRGXAddBlockToFreeListIN->hsFreeList;
 	RGX_FREELIST * pssFreeListInt = NULL;
 
 
@@ -726,19 +1100,29 @@
 
 
 
+	/* Lock over handle lookup. */
+	LockHandle();
+
+
+
+
+
 				{
 					/* Look up the address from the handle */
 					psRGXAddBlockToFreeListOUT->eError =
-						PVRSRVLookupHandle(psConnection->psHandleBase,
+						PVRSRVLookupHandleUnlocked(psConnection->psHandleBase,
 											(void **) &pssFreeListInt,
-											psRGXAddBlockToFreeListIN->hsFreeList,
-											PVRSRV_HANDLE_TYPE_RGX_FREELIST);
+											hsFreeList,
+											PVRSRV_HANDLE_TYPE_RGX_FREELIST,
+											IMG_TRUE);
 					if(psRGXAddBlockToFreeListOUT->eError != PVRSRV_OK)
 					{
+						UnlockHandle();
 						goto RGXAddBlockToFreeList_exit;
 					}
 				}
-
+	/* Release now we have looked up handles. */
+	UnlockHandle();
 
 	psRGXAddBlockToFreeListOUT->eError =
 		RGXAddBlockToFreeListKM(
@@ -750,15 +1134,38 @@
 
 RGXAddBlockToFreeList_exit:
 
+	/* Lock over handle lookup cleanup. */
+	LockHandle();
+
+
+
+
+
+
+				{
+					/* Unreference the previously looked up handle */
+						if(pssFreeListInt)
+						{
+							PVRSRVReleaseHandleUnlocked(psConnection->psHandleBase,
+											hsFreeList,
+											PVRSRV_HANDLE_TYPE_RGX_FREELIST);
+						}
+				}
+	/* Release now we have cleaned up look up handles. */
+	UnlockHandle();
+
+
 	return 0;
 }
 
+
 static IMG_INT
 PVRSRVBridgeRGXRemoveBlockFromFreeList(IMG_UINT32 ui32DispatchTableEntry,
 					  PVRSRV_BRIDGE_IN_RGXREMOVEBLOCKFROMFREELIST *psRGXRemoveBlockFromFreeListIN,
 					  PVRSRV_BRIDGE_OUT_RGXREMOVEBLOCKFROMFREELIST *psRGXRemoveBlockFromFreeListOUT,
 					 CONNECTION_DATA *psConnection)
 {
+	IMG_HANDLE hsFreeList = psRGXRemoveBlockFromFreeListIN->hsFreeList;
 	RGX_FREELIST * pssFreeListInt = NULL;
 
 
@@ -767,19 +1174,29 @@
 
 
 
+	/* Lock over handle lookup. */
+	LockHandle();
+
+
+
+
+
 				{
 					/* Look up the address from the handle */
 					psRGXRemoveBlockFromFreeListOUT->eError =
-						PVRSRVLookupHandle(psConnection->psHandleBase,
+						PVRSRVLookupHandleUnlocked(psConnection->psHandleBase,
 											(void **) &pssFreeListInt,
-											psRGXRemoveBlockFromFreeListIN->hsFreeList,
-											PVRSRV_HANDLE_TYPE_RGX_FREELIST);
+											hsFreeList,
+											PVRSRV_HANDLE_TYPE_RGX_FREELIST,
+											IMG_TRUE);
 					if(psRGXRemoveBlockFromFreeListOUT->eError != PVRSRV_OK)
 					{
+						UnlockHandle();
 						goto RGXRemoveBlockFromFreeList_exit;
 					}
 				}
-
+	/* Release now we have looked up handles. */
+	UnlockHandle();
 
 	psRGXRemoveBlockFromFreeListOUT->eError =
 		RGXRemoveBlockFromFreeListKM(
@@ -790,9 +1207,31 @@
 
 RGXRemoveBlockFromFreeList_exit:
 
+	/* Lock over handle lookup cleanup. */
+	LockHandle();
+
+
+
+
+
+
+				{
+					/* Unreference the previously looked up handle */
+						if(pssFreeListInt)
+						{
+							PVRSRVReleaseHandleUnlocked(psConnection->psHandleBase,
+											hsFreeList,
+											PVRSRV_HANDLE_TYPE_RGX_FREELIST);
+						}
+				}
+	/* Release now we have cleaned up look up handles. */
+	UnlockHandle();
+
+
 	return 0;
 }
 
+
 static IMG_INT
 PVRSRVBridgeRGXCreateRenderContext(IMG_UINT32 ui32DispatchTableEntry,
 					  PVRSRV_BRIDGE_IN_RGXCREATERENDERCONTEXT *psRGXCreateRenderContextIN,
@@ -800,50 +1239,91 @@
 					 CONNECTION_DATA *psConnection)
 {
 	IMG_BYTE *psFrameworkCmdInt = NULL;
+	IMG_HANDLE hPrivData = psRGXCreateRenderContextIN->hPrivData;
 	IMG_HANDLE hPrivDataInt = NULL;
 	RGX_SERVER_RENDER_CONTEXT * psRenderContextInt = NULL;
 
+	IMG_UINT32 ui32NextOffset = 0;
+	IMG_BYTE   *pArrayArgsBuffer = NULL;
+#if !defined(INTEGRITY_OS)
+	IMG_BOOL bHaveEnoughSpace = IMG_FALSE;
+#endif
+
+	IMG_UINT32 ui32BufferSize = 
+			(psRGXCreateRenderContextIN->ui32FrameworkCmdize * sizeof(IMG_BYTE)) +
+			0;
 
 
 
-	if (psRGXCreateRenderContextIN->ui32FrameworkCmdize != 0)
+
+
+	if (ui32BufferSize != 0)
 	{
-		psFrameworkCmdInt = OSAllocMemNoStats(psRGXCreateRenderContextIN->ui32FrameworkCmdize * sizeof(IMG_BYTE));
-		if (!psFrameworkCmdInt)
+#if !defined(INTEGRITY_OS)
+		/* Try to use remainder of input buffer for copies if possible, word-aligned for safety. */
+		IMG_UINT32 ui32InBufferOffset = PVR_ALIGN(sizeof(*psRGXCreateRenderContextIN), sizeof(unsigned long));
+		IMG_UINT32 ui32InBufferExcessSize = ui32InBufferOffset >= PVRSRV_MAX_BRIDGE_IN_SIZE ? 0 :
+			PVRSRV_MAX_BRIDGE_IN_SIZE - ui32InBufferOffset;
+
+		bHaveEnoughSpace = ui32BufferSize <= ui32InBufferExcessSize;
+		if (bHaveEnoughSpace)
 		{
-			psRGXCreateRenderContextOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
-	
-			goto RGXCreateRenderContext_exit;
+			IMG_BYTE *pInputBuffer = (IMG_BYTE *)psRGXCreateRenderContextIN;
+
+			pArrayArgsBuffer = &pInputBuffer[ui32InBufferOffset];		}
+		else
+#endif
+		{
+			pArrayArgsBuffer = OSAllocMemNoStats(ui32BufferSize);
+
+			if(!pArrayArgsBuffer)
+			{
+				psRGXCreateRenderContextOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
+				goto RGXCreateRenderContext_exit;
+			}
 		}
 	}
 
-			/* Copy the data over */
-			if ( !OSAccessOK(PVR_VERIFY_READ, (void*) psRGXCreateRenderContextIN->psFrameworkCmd, psRGXCreateRenderContextIN->ui32FrameworkCmdize * sizeof(IMG_BYTE))
-				|| (OSCopyFromUser(NULL, psFrameworkCmdInt, psRGXCreateRenderContextIN->psFrameworkCmd,
-				psRGXCreateRenderContextIN->ui32FrameworkCmdize * sizeof(IMG_BYTE)) != PVRSRV_OK) )
-			{
-				psRGXCreateRenderContextOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
+	if (psRGXCreateRenderContextIN->ui32FrameworkCmdize != 0)
+	{
+		psFrameworkCmdInt = (IMG_BYTE*)(((IMG_UINT8 *)pArrayArgsBuffer) + ui32NextOffset);
+		ui32NextOffset += psRGXCreateRenderContextIN->ui32FrameworkCmdize * sizeof(IMG_BYTE);
+	}
 
-				goto RGXCreateRenderContext_exit;
+			/* Copy the data over */
+			if (psRGXCreateRenderContextIN->ui32FrameworkCmdize * sizeof(IMG_BYTE) > 0)
+			{
+				if ( OSCopyFromUser(NULL, psFrameworkCmdInt, psRGXCreateRenderContextIN->psFrameworkCmd, psRGXCreateRenderContextIN->ui32FrameworkCmdize * sizeof(IMG_BYTE)) != PVRSRV_OK )
+				{
+					psRGXCreateRenderContextOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
+
+					goto RGXCreateRenderContext_exit;
+				}
 			}
 
-	PMRLock();
+	/* Lock over handle lookup. */
+	LockHandle();
+
+
+
 
 
 				{
 					/* Look up the address from the handle */
 					psRGXCreateRenderContextOUT->eError =
-						PVRSRVLookupHandle(psConnection->psHandleBase,
+						PVRSRVLookupHandleUnlocked(psConnection->psHandleBase,
 											(void **) &hPrivDataInt,
-											psRGXCreateRenderContextIN->hPrivData,
-											PVRSRV_HANDLE_TYPE_DEV_PRIV_DATA);
+											hPrivData,
+											PVRSRV_HANDLE_TYPE_DEV_PRIV_DATA,
+											IMG_TRUE);
 					if(psRGXCreateRenderContextOUT->eError != PVRSRV_OK)
 					{
-						PMRUnlock();
+						UnlockHandle();
 						goto RGXCreateRenderContext_exit;
 					}
 				}
-
+	/* Release now we have looked up handles. */
+	UnlockHandle();
 
 	psRGXCreateRenderContextOUT->eError =
 		PVRSRVRGXCreateRenderContextKM(psConnection, OSGetDevData(psConnection),
@@ -857,13 +1337,18 @@
 	/* Exit early if bridged call fails */
 	if(psRGXCreateRenderContextOUT->eError != PVRSRV_OK)
 	{
-		PMRUnlock();
 		goto RGXCreateRenderContext_exit;
 	}
-	PMRUnlock();
+
+	/* Lock over handle creation. */
+	LockHandle();
 
 
-	psRGXCreateRenderContextOUT->eError = PVRSRVAllocHandle(psConnection->psHandleBase,
+
+
+
+	psRGXCreateRenderContextOUT->eError = PVRSRVAllocHandleUnlocked(psConnection->psHandleBase,
+
 							&psRGXCreateRenderContextOUT->hRenderContext,
 							(void *) psRenderContextInt,
 							PVRSRV_HANDLE_TYPE_RGX_SERVER_RENDER_CONTEXT,
@@ -871,13 +1356,37 @@
 							,(PFN_HANDLE_RELEASE)&PVRSRVRGXDestroyRenderContextKM);
 	if (psRGXCreateRenderContextOUT->eError != PVRSRV_OK)
 	{
+		UnlockHandle();
 		goto RGXCreateRenderContext_exit;
 	}
 
+	/* Release now we have created handles. */
+	UnlockHandle();
 
 
 
 RGXCreateRenderContext_exit:
+
+	/* Lock over handle lookup cleanup. */
+	LockHandle();
+
+
+
+
+
+
+				{
+					/* Unreference the previously looked up handle */
+						if(hPrivDataInt)
+						{
+							PVRSRVReleaseHandleUnlocked(psConnection->psHandleBase,
+											hPrivData,
+											PVRSRV_HANDLE_TYPE_DEV_PRIV_DATA);
+						}
+				}
+	/* Release now we have cleaned up look up handles. */
+	UnlockHandle();
+
 	if (psRGXCreateRenderContextOUT->eError != PVRSRV_OK)
 	{
 		if (psRenderContextInt)
@@ -886,12 +1395,21 @@
 		}
 	}
 
-	if (psFrameworkCmdInt)
-		OSFreeMemNoStats(psFrameworkCmdInt);
+	/* Allocated space should be equal to the last updated offset */
+	PVR_ASSERT(ui32BufferSize == ui32NextOffset);
+
+#if defined(INTEGRITY_OS)
+	if(pArrayArgsBuffer)
+#else
+	if(!bHaveEnoughSpace && pArrayArgsBuffer)
+#endif
+		OSFreeMemNoStats(pArrayArgsBuffer);
+
 
 	return 0;
 }
 
+
 static IMG_INT
 PVRSRVBridgeRGXDestroyRenderContext(IMG_UINT32 ui32DispatchTableEntry,
 					  PVRSRV_BRIDGE_IN_RGXDESTROYRENDERCONTEXT *psRGXDestroyRenderContextIN,
@@ -903,36 +1421,53 @@
 
 
 
-	PMRLock();
+
+
+
+
+	/* Lock over handle destruction. */
+	LockHandle();
+
 
 
 
 
 	psRGXDestroyRenderContextOUT->eError =
-		PVRSRVReleaseHandle(psConnection->psHandleBase,
+		PVRSRVReleaseHandleUnlocked(psConnection->psHandleBase,
 					(IMG_HANDLE) psRGXDestroyRenderContextIN->hCleanupCookie,
 					PVRSRV_HANDLE_TYPE_RGX_SERVER_RENDER_CONTEXT);
-	if ((psRGXDestroyRenderContextOUT->eError != PVRSRV_OK) && (psRGXDestroyRenderContextOUT->eError != PVRSRV_ERROR_RETRY))
+	if ((psRGXDestroyRenderContextOUT->eError != PVRSRV_OK) &&
+	    (psRGXDestroyRenderContextOUT->eError != PVRSRV_ERROR_RETRY))
 	{
+		PVR_DPF((PVR_DBG_ERROR,
+		        "PVRSRVBridgeRGXDestroyRenderContext: %s",
+		        PVRSRVGetErrorStringKM(psRGXDestroyRenderContextOUT->eError)));
 		PVR_ASSERT(0);
-		PMRUnlock();
+		UnlockHandle();
 		goto RGXDestroyRenderContext_exit;
 	}
 
-	PMRUnlock();
+	/* Release now we have destroyed handles. */
+	UnlockHandle();
+
 
 
 RGXDestroyRenderContext_exit:
 
+
+
+
 	return 0;
 }
 
+
 static IMG_INT
 PVRSRVBridgeRGXKickTA3D(IMG_UINT32 ui32DispatchTableEntry,
 					  PVRSRV_BRIDGE_IN_RGXKICKTA3D *psRGXKickTA3DIN,
 					  PVRSRV_BRIDGE_OUT_RGXKICKTA3D *psRGXKickTA3DOUT,
 					 CONNECTION_DATA *psConnection)
 {
+	IMG_HANDLE hRenderContext = psRGXKickTA3DIN->hRenderContext;
 	RGX_SERVER_RENDER_CONTEXT * psRenderContextInt = NULL;
 	SYNC_PRIMITIVE_BLOCK * *psClientTAFenceSyncPrimBlockInt = NULL;
 	IMG_HANDLE *hClientTAFenceSyncPrimBlockInt2 = NULL;
@@ -956,529 +1491,484 @@
 	IMG_UINT32 *ui32Server3DSyncFlagsInt = NULL;
 	SERVER_SYNC_PRIMITIVE * *psServer3DSyncsInt = NULL;
 	IMG_HANDLE *hServer3DSyncsInt2 = NULL;
+	IMG_HANDLE hPRFenceUFOSyncPrimBlock = psRGXKickTA3DIN->hPRFenceUFOSyncPrimBlock;
 	SYNC_PRIMITIVE_BLOCK * psPRFenceUFOSyncPrimBlockInt = NULL;
 	IMG_CHAR *uiUpdateFenceNameInt = NULL;
 	IMG_BYTE *psTACmdInt = NULL;
 	IMG_BYTE *ps3DPRCmdInt = NULL;
 	IMG_BYTE *ps3DCmdInt = NULL;
+	IMG_HANDLE hRTDataCleanup = psRGXKickTA3DIN->hRTDataCleanup;
 	RGX_RTDATA_CLEANUP_DATA * psRTDataCleanupInt = NULL;
+	IMG_HANDLE hZBuffer = psRGXKickTA3DIN->hZBuffer;
 	RGX_ZSBUFFER_DATA * psZBufferInt = NULL;
+	IMG_HANDLE hSBuffer = psRGXKickTA3DIN->hSBuffer;
 	RGX_ZSBUFFER_DATA * psSBufferInt = NULL;
 	IMG_UINT32 *ui32SyncPMRFlagsInt = NULL;
 	PMR * *psSyncPMRsInt = NULL;
 	IMG_HANDLE *hSyncPMRsInt2 = NULL;
 
+	IMG_UINT32 ui32NextOffset = 0;
+	IMG_BYTE   *pArrayArgsBuffer = NULL;
+#if !defined(INTEGRITY_OS)
+	IMG_BOOL bHaveEnoughSpace = IMG_FALSE;
+#endif
+
+	IMG_UINT32 ui32BufferSize = 
+			(psRGXKickTA3DIN->ui32ClientTAFenceCount * sizeof(SYNC_PRIMITIVE_BLOCK *)) +
+			(psRGXKickTA3DIN->ui32ClientTAFenceCount * sizeof(IMG_HANDLE)) +
+			(psRGXKickTA3DIN->ui32ClientTAFenceCount * sizeof(IMG_UINT32)) +
+			(psRGXKickTA3DIN->ui32ClientTAFenceCount * sizeof(IMG_UINT32)) +
+			(psRGXKickTA3DIN->ui32ClientTAUpdateCount * sizeof(SYNC_PRIMITIVE_BLOCK *)) +
+			(psRGXKickTA3DIN->ui32ClientTAUpdateCount * sizeof(IMG_HANDLE)) +
+			(psRGXKickTA3DIN->ui32ClientTAUpdateCount * sizeof(IMG_UINT32)) +
+			(psRGXKickTA3DIN->ui32ClientTAUpdateCount * sizeof(IMG_UINT32)) +
+			(psRGXKickTA3DIN->ui32ServerTASyncPrims * sizeof(IMG_UINT32)) +
+			(psRGXKickTA3DIN->ui32ServerTASyncPrims * sizeof(SERVER_SYNC_PRIMITIVE *)) +
+			(psRGXKickTA3DIN->ui32ServerTASyncPrims * sizeof(IMG_HANDLE)) +
+			(psRGXKickTA3DIN->ui32Client3DFenceCount * sizeof(SYNC_PRIMITIVE_BLOCK *)) +
+			(psRGXKickTA3DIN->ui32Client3DFenceCount * sizeof(IMG_HANDLE)) +
+			(psRGXKickTA3DIN->ui32Client3DFenceCount * sizeof(IMG_UINT32)) +
+			(psRGXKickTA3DIN->ui32Client3DFenceCount * sizeof(IMG_UINT32)) +
+			(psRGXKickTA3DIN->ui32Client3DUpdateCount * sizeof(SYNC_PRIMITIVE_BLOCK *)) +
+			(psRGXKickTA3DIN->ui32Client3DUpdateCount * sizeof(IMG_HANDLE)) +
+			(psRGXKickTA3DIN->ui32Client3DUpdateCount * sizeof(IMG_UINT32)) +
+			(psRGXKickTA3DIN->ui32Client3DUpdateCount * sizeof(IMG_UINT32)) +
+			(psRGXKickTA3DIN->ui32Server3DSyncPrims * sizeof(IMG_UINT32)) +
+			(psRGXKickTA3DIN->ui32Server3DSyncPrims * sizeof(SERVER_SYNC_PRIMITIVE *)) +
+			(psRGXKickTA3DIN->ui32Server3DSyncPrims * sizeof(IMG_HANDLE)) +
+			(32 * sizeof(IMG_CHAR)) +
+			(psRGXKickTA3DIN->ui32TACmdSize * sizeof(IMG_BYTE)) +
+			(psRGXKickTA3DIN->ui323DPRCmdSize * sizeof(IMG_BYTE)) +
+			(psRGXKickTA3DIN->ui323DCmdSize * sizeof(IMG_BYTE)) +
+			(psRGXKickTA3DIN->ui32SyncPMRCount * sizeof(IMG_UINT32)) +
+			(psRGXKickTA3DIN->ui32SyncPMRCount * sizeof(PMR *)) +
+			(psRGXKickTA3DIN->ui32SyncPMRCount * sizeof(IMG_HANDLE)) +
+			0;
 
 
 
+
+
+	if (ui32BufferSize != 0)
+	{
+#if !defined(INTEGRITY_OS)
+		/* Try to use remainder of input buffer for copies if possible, word-aligned for safety. */
+		IMG_UINT32 ui32InBufferOffset = PVR_ALIGN(sizeof(*psRGXKickTA3DIN), sizeof(unsigned long));
+		IMG_UINT32 ui32InBufferExcessSize = ui32InBufferOffset >= PVRSRV_MAX_BRIDGE_IN_SIZE ? 0 :
+			PVRSRV_MAX_BRIDGE_IN_SIZE - ui32InBufferOffset;
+
+		bHaveEnoughSpace = ui32BufferSize <= ui32InBufferExcessSize;
+		if (bHaveEnoughSpace)
+		{
+			IMG_BYTE *pInputBuffer = (IMG_BYTE *)psRGXKickTA3DIN;
+
+			pArrayArgsBuffer = &pInputBuffer[ui32InBufferOffset];		}
+		else
+#endif
+		{
+			pArrayArgsBuffer = OSAllocMemNoStats(ui32BufferSize);
+
+			if(!pArrayArgsBuffer)
+			{
+				psRGXKickTA3DOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
+				goto RGXKickTA3D_exit;
+			}
+		}
+	}
+
 	if (psRGXKickTA3DIN->ui32ClientTAFenceCount != 0)
 	{
-		psClientTAFenceSyncPrimBlockInt = OSAllocMemNoStats(psRGXKickTA3DIN->ui32ClientTAFenceCount * sizeof(SYNC_PRIMITIVE_BLOCK *));
-		if (!psClientTAFenceSyncPrimBlockInt)
-		{
-			psRGXKickTA3DOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
-	
-			goto RGXKickTA3D_exit;
-		}
-		hClientTAFenceSyncPrimBlockInt2 = OSAllocMemNoStats(psRGXKickTA3DIN->ui32ClientTAFenceCount * sizeof(IMG_HANDLE));
-		if (!hClientTAFenceSyncPrimBlockInt2)
-		{
-			psRGXKickTA3DOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
-	
-			goto RGXKickTA3D_exit;
-		}
+		psClientTAFenceSyncPrimBlockInt = (SYNC_PRIMITIVE_BLOCK **)(((IMG_UINT8 *)pArrayArgsBuffer) + ui32NextOffset);
+		ui32NextOffset += psRGXKickTA3DIN->ui32ClientTAFenceCount * sizeof(SYNC_PRIMITIVE_BLOCK *);
+		hClientTAFenceSyncPrimBlockInt2 = (IMG_HANDLE *)(((IMG_UINT8 *)pArrayArgsBuffer) + ui32NextOffset); 
+		ui32NextOffset += psRGXKickTA3DIN->ui32ClientTAFenceCount * sizeof(IMG_HANDLE);
 	}
 
 			/* Copy the data over */
-			if ( !OSAccessOK(PVR_VERIFY_READ, (void*) psRGXKickTA3DIN->phClientTAFenceSyncPrimBlock, psRGXKickTA3DIN->ui32ClientTAFenceCount * sizeof(IMG_HANDLE))
-				|| (OSCopyFromUser(NULL, hClientTAFenceSyncPrimBlockInt2, psRGXKickTA3DIN->phClientTAFenceSyncPrimBlock,
-				psRGXKickTA3DIN->ui32ClientTAFenceCount * sizeof(IMG_HANDLE)) != PVRSRV_OK) )
+			if (psRGXKickTA3DIN->ui32ClientTAFenceCount * sizeof(IMG_HANDLE) > 0)
 			{
-				psRGXKickTA3DOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
+				if ( OSCopyFromUser(NULL, hClientTAFenceSyncPrimBlockInt2, psRGXKickTA3DIN->phClientTAFenceSyncPrimBlock, psRGXKickTA3DIN->ui32ClientTAFenceCount * sizeof(IMG_HANDLE)) != PVRSRV_OK )
+				{
+					psRGXKickTA3DOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
 
-				goto RGXKickTA3D_exit;
+					goto RGXKickTA3D_exit;
+				}
 			}
 	if (psRGXKickTA3DIN->ui32ClientTAFenceCount != 0)
 	{
-		ui32ClientTAFenceSyncOffsetInt = OSAllocMemNoStats(psRGXKickTA3DIN->ui32ClientTAFenceCount * sizeof(IMG_UINT32));
-		if (!ui32ClientTAFenceSyncOffsetInt)
-		{
-			psRGXKickTA3DOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
-	
-			goto RGXKickTA3D_exit;
-		}
+		ui32ClientTAFenceSyncOffsetInt = (IMG_UINT32*)(((IMG_UINT8 *)pArrayArgsBuffer) + ui32NextOffset);
+		ui32NextOffset += psRGXKickTA3DIN->ui32ClientTAFenceCount * sizeof(IMG_UINT32);
 	}
 
 			/* Copy the data over */
-			if ( !OSAccessOK(PVR_VERIFY_READ, (void*) psRGXKickTA3DIN->pui32ClientTAFenceSyncOffset, psRGXKickTA3DIN->ui32ClientTAFenceCount * sizeof(IMG_UINT32))
-				|| (OSCopyFromUser(NULL, ui32ClientTAFenceSyncOffsetInt, psRGXKickTA3DIN->pui32ClientTAFenceSyncOffset,
-				psRGXKickTA3DIN->ui32ClientTAFenceCount * sizeof(IMG_UINT32)) != PVRSRV_OK) )
+			if (psRGXKickTA3DIN->ui32ClientTAFenceCount * sizeof(IMG_UINT32) > 0)
 			{
-				psRGXKickTA3DOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
+				if ( OSCopyFromUser(NULL, ui32ClientTAFenceSyncOffsetInt, psRGXKickTA3DIN->pui32ClientTAFenceSyncOffset, psRGXKickTA3DIN->ui32ClientTAFenceCount * sizeof(IMG_UINT32)) != PVRSRV_OK )
+				{
+					psRGXKickTA3DOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
 
-				goto RGXKickTA3D_exit;
+					goto RGXKickTA3D_exit;
+				}
 			}
 	if (psRGXKickTA3DIN->ui32ClientTAFenceCount != 0)
 	{
-		ui32ClientTAFenceValueInt = OSAllocMemNoStats(psRGXKickTA3DIN->ui32ClientTAFenceCount * sizeof(IMG_UINT32));
-		if (!ui32ClientTAFenceValueInt)
-		{
-			psRGXKickTA3DOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
-	
-			goto RGXKickTA3D_exit;
-		}
+		ui32ClientTAFenceValueInt = (IMG_UINT32*)(((IMG_UINT8 *)pArrayArgsBuffer) + ui32NextOffset);
+		ui32NextOffset += psRGXKickTA3DIN->ui32ClientTAFenceCount * sizeof(IMG_UINT32);
 	}
 
 			/* Copy the data over */
-			if ( !OSAccessOK(PVR_VERIFY_READ, (void*) psRGXKickTA3DIN->pui32ClientTAFenceValue, psRGXKickTA3DIN->ui32ClientTAFenceCount * sizeof(IMG_UINT32))
-				|| (OSCopyFromUser(NULL, ui32ClientTAFenceValueInt, psRGXKickTA3DIN->pui32ClientTAFenceValue,
-				psRGXKickTA3DIN->ui32ClientTAFenceCount * sizeof(IMG_UINT32)) != PVRSRV_OK) )
+			if (psRGXKickTA3DIN->ui32ClientTAFenceCount * sizeof(IMG_UINT32) > 0)
 			{
-				psRGXKickTA3DOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
+				if ( OSCopyFromUser(NULL, ui32ClientTAFenceValueInt, psRGXKickTA3DIN->pui32ClientTAFenceValue, psRGXKickTA3DIN->ui32ClientTAFenceCount * sizeof(IMG_UINT32)) != PVRSRV_OK )
+				{
+					psRGXKickTA3DOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
 
-				goto RGXKickTA3D_exit;
+					goto RGXKickTA3D_exit;
+				}
 			}
 	if (psRGXKickTA3DIN->ui32ClientTAUpdateCount != 0)
 	{
-		psClientTAUpdateSyncPrimBlockInt = OSAllocMemNoStats(psRGXKickTA3DIN->ui32ClientTAUpdateCount * sizeof(SYNC_PRIMITIVE_BLOCK *));
-		if (!psClientTAUpdateSyncPrimBlockInt)
-		{
-			psRGXKickTA3DOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
-	
-			goto RGXKickTA3D_exit;
-		}
-		hClientTAUpdateSyncPrimBlockInt2 = OSAllocMemNoStats(psRGXKickTA3DIN->ui32ClientTAUpdateCount * sizeof(IMG_HANDLE));
-		if (!hClientTAUpdateSyncPrimBlockInt2)
-		{
-			psRGXKickTA3DOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
-	
-			goto RGXKickTA3D_exit;
-		}
+		psClientTAUpdateSyncPrimBlockInt = (SYNC_PRIMITIVE_BLOCK **)(((IMG_UINT8 *)pArrayArgsBuffer) + ui32NextOffset);
+		ui32NextOffset += psRGXKickTA3DIN->ui32ClientTAUpdateCount * sizeof(SYNC_PRIMITIVE_BLOCK *);
+		hClientTAUpdateSyncPrimBlockInt2 = (IMG_HANDLE *)(((IMG_UINT8 *)pArrayArgsBuffer) + ui32NextOffset); 
+		ui32NextOffset += psRGXKickTA3DIN->ui32ClientTAUpdateCount * sizeof(IMG_HANDLE);
 	}
 
 			/* Copy the data over */
-			if ( !OSAccessOK(PVR_VERIFY_READ, (void*) psRGXKickTA3DIN->phClientTAUpdateSyncPrimBlock, psRGXKickTA3DIN->ui32ClientTAUpdateCount * sizeof(IMG_HANDLE))
-				|| (OSCopyFromUser(NULL, hClientTAUpdateSyncPrimBlockInt2, psRGXKickTA3DIN->phClientTAUpdateSyncPrimBlock,
-				psRGXKickTA3DIN->ui32ClientTAUpdateCount * sizeof(IMG_HANDLE)) != PVRSRV_OK) )
+			if (psRGXKickTA3DIN->ui32ClientTAUpdateCount * sizeof(IMG_HANDLE) > 0)
 			{
-				psRGXKickTA3DOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
+				if ( OSCopyFromUser(NULL, hClientTAUpdateSyncPrimBlockInt2, psRGXKickTA3DIN->phClientTAUpdateSyncPrimBlock, psRGXKickTA3DIN->ui32ClientTAUpdateCount * sizeof(IMG_HANDLE)) != PVRSRV_OK )
+				{
+					psRGXKickTA3DOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
 
-				goto RGXKickTA3D_exit;
+					goto RGXKickTA3D_exit;
+				}
 			}
 	if (psRGXKickTA3DIN->ui32ClientTAUpdateCount != 0)
 	{
-		ui32ClientTAUpdateSyncOffsetInt = OSAllocMemNoStats(psRGXKickTA3DIN->ui32ClientTAUpdateCount * sizeof(IMG_UINT32));
-		if (!ui32ClientTAUpdateSyncOffsetInt)
-		{
-			psRGXKickTA3DOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
-	
-			goto RGXKickTA3D_exit;
-		}
+		ui32ClientTAUpdateSyncOffsetInt = (IMG_UINT32*)(((IMG_UINT8 *)pArrayArgsBuffer) + ui32NextOffset);
+		ui32NextOffset += psRGXKickTA3DIN->ui32ClientTAUpdateCount * sizeof(IMG_UINT32);
 	}
 
 			/* Copy the data over */
-			if ( !OSAccessOK(PVR_VERIFY_READ, (void*) psRGXKickTA3DIN->pui32ClientTAUpdateSyncOffset, psRGXKickTA3DIN->ui32ClientTAUpdateCount * sizeof(IMG_UINT32))
-				|| (OSCopyFromUser(NULL, ui32ClientTAUpdateSyncOffsetInt, psRGXKickTA3DIN->pui32ClientTAUpdateSyncOffset,
-				psRGXKickTA3DIN->ui32ClientTAUpdateCount * sizeof(IMG_UINT32)) != PVRSRV_OK) )
+			if (psRGXKickTA3DIN->ui32ClientTAUpdateCount * sizeof(IMG_UINT32) > 0)
 			{
-				psRGXKickTA3DOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
+				if ( OSCopyFromUser(NULL, ui32ClientTAUpdateSyncOffsetInt, psRGXKickTA3DIN->pui32ClientTAUpdateSyncOffset, psRGXKickTA3DIN->ui32ClientTAUpdateCount * sizeof(IMG_UINT32)) != PVRSRV_OK )
+				{
+					psRGXKickTA3DOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
 
-				goto RGXKickTA3D_exit;
+					goto RGXKickTA3D_exit;
+				}
 			}
 	if (psRGXKickTA3DIN->ui32ClientTAUpdateCount != 0)
 	{
-		ui32ClientTAUpdateValueInt = OSAllocMemNoStats(psRGXKickTA3DIN->ui32ClientTAUpdateCount * sizeof(IMG_UINT32));
-		if (!ui32ClientTAUpdateValueInt)
-		{
-			psRGXKickTA3DOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
-	
-			goto RGXKickTA3D_exit;
-		}
+		ui32ClientTAUpdateValueInt = (IMG_UINT32*)(((IMG_UINT8 *)pArrayArgsBuffer) + ui32NextOffset);
+		ui32NextOffset += psRGXKickTA3DIN->ui32ClientTAUpdateCount * sizeof(IMG_UINT32);
 	}
 
 			/* Copy the data over */
-			if ( !OSAccessOK(PVR_VERIFY_READ, (void*) psRGXKickTA3DIN->pui32ClientTAUpdateValue, psRGXKickTA3DIN->ui32ClientTAUpdateCount * sizeof(IMG_UINT32))
-				|| (OSCopyFromUser(NULL, ui32ClientTAUpdateValueInt, psRGXKickTA3DIN->pui32ClientTAUpdateValue,
-				psRGXKickTA3DIN->ui32ClientTAUpdateCount * sizeof(IMG_UINT32)) != PVRSRV_OK) )
+			if (psRGXKickTA3DIN->ui32ClientTAUpdateCount * sizeof(IMG_UINT32) > 0)
 			{
-				psRGXKickTA3DOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
+				if ( OSCopyFromUser(NULL, ui32ClientTAUpdateValueInt, psRGXKickTA3DIN->pui32ClientTAUpdateValue, psRGXKickTA3DIN->ui32ClientTAUpdateCount * sizeof(IMG_UINT32)) != PVRSRV_OK )
+				{
+					psRGXKickTA3DOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
 
-				goto RGXKickTA3D_exit;
+					goto RGXKickTA3D_exit;
+				}
 			}
 	if (psRGXKickTA3DIN->ui32ServerTASyncPrims != 0)
 	{
-		ui32ServerTASyncFlagsInt = OSAllocMemNoStats(psRGXKickTA3DIN->ui32ServerTASyncPrims * sizeof(IMG_UINT32));
-		if (!ui32ServerTASyncFlagsInt)
-		{
-			psRGXKickTA3DOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
-	
-			goto RGXKickTA3D_exit;
-		}
+		ui32ServerTASyncFlagsInt = (IMG_UINT32*)(((IMG_UINT8 *)pArrayArgsBuffer) + ui32NextOffset);
+		ui32NextOffset += psRGXKickTA3DIN->ui32ServerTASyncPrims * sizeof(IMG_UINT32);
 	}
 
 			/* Copy the data over */
-			if ( !OSAccessOK(PVR_VERIFY_READ, (void*) psRGXKickTA3DIN->pui32ServerTASyncFlags, psRGXKickTA3DIN->ui32ServerTASyncPrims * sizeof(IMG_UINT32))
-				|| (OSCopyFromUser(NULL, ui32ServerTASyncFlagsInt, psRGXKickTA3DIN->pui32ServerTASyncFlags,
-				psRGXKickTA3DIN->ui32ServerTASyncPrims * sizeof(IMG_UINT32)) != PVRSRV_OK) )
+			if (psRGXKickTA3DIN->ui32ServerTASyncPrims * sizeof(IMG_UINT32) > 0)
 			{
-				psRGXKickTA3DOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
+				if ( OSCopyFromUser(NULL, ui32ServerTASyncFlagsInt, psRGXKickTA3DIN->pui32ServerTASyncFlags, psRGXKickTA3DIN->ui32ServerTASyncPrims * sizeof(IMG_UINT32)) != PVRSRV_OK )
+				{
+					psRGXKickTA3DOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
 
-				goto RGXKickTA3D_exit;
+					goto RGXKickTA3D_exit;
+				}
 			}
 	if (psRGXKickTA3DIN->ui32ServerTASyncPrims != 0)
 	{
-		psServerTASyncsInt = OSAllocMemNoStats(psRGXKickTA3DIN->ui32ServerTASyncPrims * sizeof(SERVER_SYNC_PRIMITIVE *));
-		if (!psServerTASyncsInt)
-		{
-			psRGXKickTA3DOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
-	
-			goto RGXKickTA3D_exit;
-		}
-		hServerTASyncsInt2 = OSAllocMemNoStats(psRGXKickTA3DIN->ui32ServerTASyncPrims * sizeof(IMG_HANDLE));
-		if (!hServerTASyncsInt2)
-		{
-			psRGXKickTA3DOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
-	
-			goto RGXKickTA3D_exit;
-		}
+		psServerTASyncsInt = (SERVER_SYNC_PRIMITIVE **)(((IMG_UINT8 *)pArrayArgsBuffer) + ui32NextOffset);
+		ui32NextOffset += psRGXKickTA3DIN->ui32ServerTASyncPrims * sizeof(SERVER_SYNC_PRIMITIVE *);
+		hServerTASyncsInt2 = (IMG_HANDLE *)(((IMG_UINT8 *)pArrayArgsBuffer) + ui32NextOffset); 
+		ui32NextOffset += psRGXKickTA3DIN->ui32ServerTASyncPrims * sizeof(IMG_HANDLE);
 	}
 
 			/* Copy the data over */
-			if ( !OSAccessOK(PVR_VERIFY_READ, (void*) psRGXKickTA3DIN->phServerTASyncs, psRGXKickTA3DIN->ui32ServerTASyncPrims * sizeof(IMG_HANDLE))
-				|| (OSCopyFromUser(NULL, hServerTASyncsInt2, psRGXKickTA3DIN->phServerTASyncs,
-				psRGXKickTA3DIN->ui32ServerTASyncPrims * sizeof(IMG_HANDLE)) != PVRSRV_OK) )
+			if (psRGXKickTA3DIN->ui32ServerTASyncPrims * sizeof(IMG_HANDLE) > 0)
 			{
-				psRGXKickTA3DOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
+				if ( OSCopyFromUser(NULL, hServerTASyncsInt2, psRGXKickTA3DIN->phServerTASyncs, psRGXKickTA3DIN->ui32ServerTASyncPrims * sizeof(IMG_HANDLE)) != PVRSRV_OK )
+				{
+					psRGXKickTA3DOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
 
-				goto RGXKickTA3D_exit;
+					goto RGXKickTA3D_exit;
+				}
 			}
 	if (psRGXKickTA3DIN->ui32Client3DFenceCount != 0)
 	{
-		psClient3DFenceSyncPrimBlockInt = OSAllocMemNoStats(psRGXKickTA3DIN->ui32Client3DFenceCount * sizeof(SYNC_PRIMITIVE_BLOCK *));
-		if (!psClient3DFenceSyncPrimBlockInt)
-		{
-			psRGXKickTA3DOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
-	
-			goto RGXKickTA3D_exit;
-		}
-		hClient3DFenceSyncPrimBlockInt2 = OSAllocMemNoStats(psRGXKickTA3DIN->ui32Client3DFenceCount * sizeof(IMG_HANDLE));
-		if (!hClient3DFenceSyncPrimBlockInt2)
-		{
-			psRGXKickTA3DOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
-	
-			goto RGXKickTA3D_exit;
-		}
+		psClient3DFenceSyncPrimBlockInt = (SYNC_PRIMITIVE_BLOCK **)(((IMG_UINT8 *)pArrayArgsBuffer) + ui32NextOffset);
+		ui32NextOffset += psRGXKickTA3DIN->ui32Client3DFenceCount * sizeof(SYNC_PRIMITIVE_BLOCK *);
+		hClient3DFenceSyncPrimBlockInt2 = (IMG_HANDLE *)(((IMG_UINT8 *)pArrayArgsBuffer) + ui32NextOffset); 
+		ui32NextOffset += psRGXKickTA3DIN->ui32Client3DFenceCount * sizeof(IMG_HANDLE);
 	}
 
 			/* Copy the data over */
-			if ( !OSAccessOK(PVR_VERIFY_READ, (void*) psRGXKickTA3DIN->phClient3DFenceSyncPrimBlock, psRGXKickTA3DIN->ui32Client3DFenceCount * sizeof(IMG_HANDLE))
-				|| (OSCopyFromUser(NULL, hClient3DFenceSyncPrimBlockInt2, psRGXKickTA3DIN->phClient3DFenceSyncPrimBlock,
-				psRGXKickTA3DIN->ui32Client3DFenceCount * sizeof(IMG_HANDLE)) != PVRSRV_OK) )
+			if (psRGXKickTA3DIN->ui32Client3DFenceCount * sizeof(IMG_HANDLE) > 0)
 			{
-				psRGXKickTA3DOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
+				if ( OSCopyFromUser(NULL, hClient3DFenceSyncPrimBlockInt2, psRGXKickTA3DIN->phClient3DFenceSyncPrimBlock, psRGXKickTA3DIN->ui32Client3DFenceCount * sizeof(IMG_HANDLE)) != PVRSRV_OK )
+				{
+					psRGXKickTA3DOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
 
-				goto RGXKickTA3D_exit;
+					goto RGXKickTA3D_exit;
+				}
 			}
 	if (psRGXKickTA3DIN->ui32Client3DFenceCount != 0)
 	{
-		ui32Client3DFenceSyncOffsetInt = OSAllocMemNoStats(psRGXKickTA3DIN->ui32Client3DFenceCount * sizeof(IMG_UINT32));
-		if (!ui32Client3DFenceSyncOffsetInt)
-		{
-			psRGXKickTA3DOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
-	
-			goto RGXKickTA3D_exit;
-		}
+		ui32Client3DFenceSyncOffsetInt = (IMG_UINT32*)(((IMG_UINT8 *)pArrayArgsBuffer) + ui32NextOffset);
+		ui32NextOffset += psRGXKickTA3DIN->ui32Client3DFenceCount * sizeof(IMG_UINT32);
 	}
 
 			/* Copy the data over */
-			if ( !OSAccessOK(PVR_VERIFY_READ, (void*) psRGXKickTA3DIN->pui32Client3DFenceSyncOffset, psRGXKickTA3DIN->ui32Client3DFenceCount * sizeof(IMG_UINT32))
-				|| (OSCopyFromUser(NULL, ui32Client3DFenceSyncOffsetInt, psRGXKickTA3DIN->pui32Client3DFenceSyncOffset,
-				psRGXKickTA3DIN->ui32Client3DFenceCount * sizeof(IMG_UINT32)) != PVRSRV_OK) )
+			if (psRGXKickTA3DIN->ui32Client3DFenceCount * sizeof(IMG_UINT32) > 0)
 			{
-				psRGXKickTA3DOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
+				if ( OSCopyFromUser(NULL, ui32Client3DFenceSyncOffsetInt, psRGXKickTA3DIN->pui32Client3DFenceSyncOffset, psRGXKickTA3DIN->ui32Client3DFenceCount * sizeof(IMG_UINT32)) != PVRSRV_OK )
+				{
+					psRGXKickTA3DOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
 
-				goto RGXKickTA3D_exit;
+					goto RGXKickTA3D_exit;
+				}
 			}
 	if (psRGXKickTA3DIN->ui32Client3DFenceCount != 0)
 	{
-		ui32Client3DFenceValueInt = OSAllocMemNoStats(psRGXKickTA3DIN->ui32Client3DFenceCount * sizeof(IMG_UINT32));
-		if (!ui32Client3DFenceValueInt)
-		{
-			psRGXKickTA3DOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
-	
-			goto RGXKickTA3D_exit;
-		}
+		ui32Client3DFenceValueInt = (IMG_UINT32*)(((IMG_UINT8 *)pArrayArgsBuffer) + ui32NextOffset);
+		ui32NextOffset += psRGXKickTA3DIN->ui32Client3DFenceCount * sizeof(IMG_UINT32);
 	}
 
 			/* Copy the data over */
-			if ( !OSAccessOK(PVR_VERIFY_READ, (void*) psRGXKickTA3DIN->pui32Client3DFenceValue, psRGXKickTA3DIN->ui32Client3DFenceCount * sizeof(IMG_UINT32))
-				|| (OSCopyFromUser(NULL, ui32Client3DFenceValueInt, psRGXKickTA3DIN->pui32Client3DFenceValue,
-				psRGXKickTA3DIN->ui32Client3DFenceCount * sizeof(IMG_UINT32)) != PVRSRV_OK) )
+			if (psRGXKickTA3DIN->ui32Client3DFenceCount * sizeof(IMG_UINT32) > 0)
 			{
-				psRGXKickTA3DOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
+				if ( OSCopyFromUser(NULL, ui32Client3DFenceValueInt, psRGXKickTA3DIN->pui32Client3DFenceValue, psRGXKickTA3DIN->ui32Client3DFenceCount * sizeof(IMG_UINT32)) != PVRSRV_OK )
+				{
+					psRGXKickTA3DOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
 
-				goto RGXKickTA3D_exit;
+					goto RGXKickTA3D_exit;
+				}
 			}
 	if (psRGXKickTA3DIN->ui32Client3DUpdateCount != 0)
 	{
-		psClient3DUpdateSyncPrimBlockInt = OSAllocMemNoStats(psRGXKickTA3DIN->ui32Client3DUpdateCount * sizeof(SYNC_PRIMITIVE_BLOCK *));
-		if (!psClient3DUpdateSyncPrimBlockInt)
-		{
-			psRGXKickTA3DOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
-	
-			goto RGXKickTA3D_exit;
-		}
-		hClient3DUpdateSyncPrimBlockInt2 = OSAllocMemNoStats(psRGXKickTA3DIN->ui32Client3DUpdateCount * sizeof(IMG_HANDLE));
-		if (!hClient3DUpdateSyncPrimBlockInt2)
-		{
-			psRGXKickTA3DOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
-	
-			goto RGXKickTA3D_exit;
-		}
+		psClient3DUpdateSyncPrimBlockInt = (SYNC_PRIMITIVE_BLOCK **)(((IMG_UINT8 *)pArrayArgsBuffer) + ui32NextOffset);
+		ui32NextOffset += psRGXKickTA3DIN->ui32Client3DUpdateCount * sizeof(SYNC_PRIMITIVE_BLOCK *);
+		hClient3DUpdateSyncPrimBlockInt2 = (IMG_HANDLE *)(((IMG_UINT8 *)pArrayArgsBuffer) + ui32NextOffset); 
+		ui32NextOffset += psRGXKickTA3DIN->ui32Client3DUpdateCount * sizeof(IMG_HANDLE);
 	}
 
 			/* Copy the data over */
-			if ( !OSAccessOK(PVR_VERIFY_READ, (void*) psRGXKickTA3DIN->phClient3DUpdateSyncPrimBlock, psRGXKickTA3DIN->ui32Client3DUpdateCount * sizeof(IMG_HANDLE))
-				|| (OSCopyFromUser(NULL, hClient3DUpdateSyncPrimBlockInt2, psRGXKickTA3DIN->phClient3DUpdateSyncPrimBlock,
-				psRGXKickTA3DIN->ui32Client3DUpdateCount * sizeof(IMG_HANDLE)) != PVRSRV_OK) )
+			if (psRGXKickTA3DIN->ui32Client3DUpdateCount * sizeof(IMG_HANDLE) > 0)
 			{
-				psRGXKickTA3DOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
+				if ( OSCopyFromUser(NULL, hClient3DUpdateSyncPrimBlockInt2, psRGXKickTA3DIN->phClient3DUpdateSyncPrimBlock, psRGXKickTA3DIN->ui32Client3DUpdateCount * sizeof(IMG_HANDLE)) != PVRSRV_OK )
+				{
+					psRGXKickTA3DOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
 
-				goto RGXKickTA3D_exit;
+					goto RGXKickTA3D_exit;
+				}
 			}
 	if (psRGXKickTA3DIN->ui32Client3DUpdateCount != 0)
 	{
-		ui32Client3DUpdateSyncOffsetInt = OSAllocMemNoStats(psRGXKickTA3DIN->ui32Client3DUpdateCount * sizeof(IMG_UINT32));
-		if (!ui32Client3DUpdateSyncOffsetInt)
-		{
-			psRGXKickTA3DOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
-	
-			goto RGXKickTA3D_exit;
-		}
+		ui32Client3DUpdateSyncOffsetInt = (IMG_UINT32*)(((IMG_UINT8 *)pArrayArgsBuffer) + ui32NextOffset);
+		ui32NextOffset += psRGXKickTA3DIN->ui32Client3DUpdateCount * sizeof(IMG_UINT32);
 	}
 
 			/* Copy the data over */
-			if ( !OSAccessOK(PVR_VERIFY_READ, (void*) psRGXKickTA3DIN->pui32Client3DUpdateSyncOffset, psRGXKickTA3DIN->ui32Client3DUpdateCount * sizeof(IMG_UINT32))
-				|| (OSCopyFromUser(NULL, ui32Client3DUpdateSyncOffsetInt, psRGXKickTA3DIN->pui32Client3DUpdateSyncOffset,
-				psRGXKickTA3DIN->ui32Client3DUpdateCount * sizeof(IMG_UINT32)) != PVRSRV_OK) )
+			if (psRGXKickTA3DIN->ui32Client3DUpdateCount * sizeof(IMG_UINT32) > 0)
 			{
-				psRGXKickTA3DOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
+				if ( OSCopyFromUser(NULL, ui32Client3DUpdateSyncOffsetInt, psRGXKickTA3DIN->pui32Client3DUpdateSyncOffset, psRGXKickTA3DIN->ui32Client3DUpdateCount * sizeof(IMG_UINT32)) != PVRSRV_OK )
+				{
+					psRGXKickTA3DOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
 
-				goto RGXKickTA3D_exit;
+					goto RGXKickTA3D_exit;
+				}
 			}
 	if (psRGXKickTA3DIN->ui32Client3DUpdateCount != 0)
 	{
-		ui32Client3DUpdateValueInt = OSAllocMemNoStats(psRGXKickTA3DIN->ui32Client3DUpdateCount * sizeof(IMG_UINT32));
-		if (!ui32Client3DUpdateValueInt)
-		{
-			psRGXKickTA3DOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
-	
-			goto RGXKickTA3D_exit;
-		}
+		ui32Client3DUpdateValueInt = (IMG_UINT32*)(((IMG_UINT8 *)pArrayArgsBuffer) + ui32NextOffset);
+		ui32NextOffset += psRGXKickTA3DIN->ui32Client3DUpdateCount * sizeof(IMG_UINT32);
 	}
 
 			/* Copy the data over */
-			if ( !OSAccessOK(PVR_VERIFY_READ, (void*) psRGXKickTA3DIN->pui32Client3DUpdateValue, psRGXKickTA3DIN->ui32Client3DUpdateCount * sizeof(IMG_UINT32))
-				|| (OSCopyFromUser(NULL, ui32Client3DUpdateValueInt, psRGXKickTA3DIN->pui32Client3DUpdateValue,
-				psRGXKickTA3DIN->ui32Client3DUpdateCount * sizeof(IMG_UINT32)) != PVRSRV_OK) )
+			if (psRGXKickTA3DIN->ui32Client3DUpdateCount * sizeof(IMG_UINT32) > 0)
 			{
-				psRGXKickTA3DOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
+				if ( OSCopyFromUser(NULL, ui32Client3DUpdateValueInt, psRGXKickTA3DIN->pui32Client3DUpdateValue, psRGXKickTA3DIN->ui32Client3DUpdateCount * sizeof(IMG_UINT32)) != PVRSRV_OK )
+				{
+					psRGXKickTA3DOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
 
-				goto RGXKickTA3D_exit;
+					goto RGXKickTA3D_exit;
+				}
 			}
 	if (psRGXKickTA3DIN->ui32Server3DSyncPrims != 0)
 	{
-		ui32Server3DSyncFlagsInt = OSAllocMemNoStats(psRGXKickTA3DIN->ui32Server3DSyncPrims * sizeof(IMG_UINT32));
-		if (!ui32Server3DSyncFlagsInt)
-		{
-			psRGXKickTA3DOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
-	
-			goto RGXKickTA3D_exit;
-		}
+		ui32Server3DSyncFlagsInt = (IMG_UINT32*)(((IMG_UINT8 *)pArrayArgsBuffer) + ui32NextOffset);
+		ui32NextOffset += psRGXKickTA3DIN->ui32Server3DSyncPrims * sizeof(IMG_UINT32);
 	}
 
 			/* Copy the data over */
-			if ( !OSAccessOK(PVR_VERIFY_READ, (void*) psRGXKickTA3DIN->pui32Server3DSyncFlags, psRGXKickTA3DIN->ui32Server3DSyncPrims * sizeof(IMG_UINT32))
-				|| (OSCopyFromUser(NULL, ui32Server3DSyncFlagsInt, psRGXKickTA3DIN->pui32Server3DSyncFlags,
-				psRGXKickTA3DIN->ui32Server3DSyncPrims * sizeof(IMG_UINT32)) != PVRSRV_OK) )
+			if (psRGXKickTA3DIN->ui32Server3DSyncPrims * sizeof(IMG_UINT32) > 0)
 			{
-				psRGXKickTA3DOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
+				if ( OSCopyFromUser(NULL, ui32Server3DSyncFlagsInt, psRGXKickTA3DIN->pui32Server3DSyncFlags, psRGXKickTA3DIN->ui32Server3DSyncPrims * sizeof(IMG_UINT32)) != PVRSRV_OK )
+				{
+					psRGXKickTA3DOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
 
-				goto RGXKickTA3D_exit;
+					goto RGXKickTA3D_exit;
+				}
 			}
 	if (psRGXKickTA3DIN->ui32Server3DSyncPrims != 0)
 	{
-		psServer3DSyncsInt = OSAllocMemNoStats(psRGXKickTA3DIN->ui32Server3DSyncPrims * sizeof(SERVER_SYNC_PRIMITIVE *));
-		if (!psServer3DSyncsInt)
-		{
-			psRGXKickTA3DOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
-	
-			goto RGXKickTA3D_exit;
-		}
-		hServer3DSyncsInt2 = OSAllocMemNoStats(psRGXKickTA3DIN->ui32Server3DSyncPrims * sizeof(IMG_HANDLE));
-		if (!hServer3DSyncsInt2)
-		{
-			psRGXKickTA3DOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
-	
-			goto RGXKickTA3D_exit;
-		}
+		psServer3DSyncsInt = (SERVER_SYNC_PRIMITIVE **)(((IMG_UINT8 *)pArrayArgsBuffer) + ui32NextOffset);
+		ui32NextOffset += psRGXKickTA3DIN->ui32Server3DSyncPrims * sizeof(SERVER_SYNC_PRIMITIVE *);
+		hServer3DSyncsInt2 = (IMG_HANDLE *)(((IMG_UINT8 *)pArrayArgsBuffer) + ui32NextOffset); 
+		ui32NextOffset += psRGXKickTA3DIN->ui32Server3DSyncPrims * sizeof(IMG_HANDLE);
 	}
 
 			/* Copy the data over */
-			if ( !OSAccessOK(PVR_VERIFY_READ, (void*) psRGXKickTA3DIN->phServer3DSyncs, psRGXKickTA3DIN->ui32Server3DSyncPrims * sizeof(IMG_HANDLE))
-				|| (OSCopyFromUser(NULL, hServer3DSyncsInt2, psRGXKickTA3DIN->phServer3DSyncs,
-				psRGXKickTA3DIN->ui32Server3DSyncPrims * sizeof(IMG_HANDLE)) != PVRSRV_OK) )
+			if (psRGXKickTA3DIN->ui32Server3DSyncPrims * sizeof(IMG_HANDLE) > 0)
 			{
-				psRGXKickTA3DOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
+				if ( OSCopyFromUser(NULL, hServer3DSyncsInt2, psRGXKickTA3DIN->phServer3DSyncs, psRGXKickTA3DIN->ui32Server3DSyncPrims * sizeof(IMG_HANDLE)) != PVRSRV_OK )
+				{
+					psRGXKickTA3DOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
 
-				goto RGXKickTA3D_exit;
+					goto RGXKickTA3D_exit;
+				}
 			}
 	
 	{
-		uiUpdateFenceNameInt = OSAllocMemNoStats(32 * sizeof(IMG_CHAR));
-		if (!uiUpdateFenceNameInt)
-		{
-			psRGXKickTA3DOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
-	
-			goto RGXKickTA3D_exit;
-		}
+		uiUpdateFenceNameInt = (IMG_CHAR*)(((IMG_UINT8 *)pArrayArgsBuffer) + ui32NextOffset);
+		ui32NextOffset += 32 * sizeof(IMG_CHAR);
 	}
 
 			/* Copy the data over */
-			if ( !OSAccessOK(PVR_VERIFY_READ, (void*) psRGXKickTA3DIN->puiUpdateFenceName, 32 * sizeof(IMG_CHAR))
-				|| (OSCopyFromUser(NULL, uiUpdateFenceNameInt, psRGXKickTA3DIN->puiUpdateFenceName,
-				32 * sizeof(IMG_CHAR)) != PVRSRV_OK) )
+			if (32 * sizeof(IMG_CHAR) > 0)
 			{
-				psRGXKickTA3DOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
+				if ( OSCopyFromUser(NULL, uiUpdateFenceNameInt, psRGXKickTA3DIN->puiUpdateFenceName, 32 * sizeof(IMG_CHAR)) != PVRSRV_OK )
+				{
+					psRGXKickTA3DOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
 
-				goto RGXKickTA3D_exit;
+					goto RGXKickTA3D_exit;
+				}
 			}
 	if (psRGXKickTA3DIN->ui32TACmdSize != 0)
 	{
-		psTACmdInt = OSAllocMemNoStats(psRGXKickTA3DIN->ui32TACmdSize * sizeof(IMG_BYTE));
-		if (!psTACmdInt)
-		{
-			psRGXKickTA3DOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
-	
-			goto RGXKickTA3D_exit;
-		}
+		psTACmdInt = (IMG_BYTE*)(((IMG_UINT8 *)pArrayArgsBuffer) + ui32NextOffset);
+		ui32NextOffset += psRGXKickTA3DIN->ui32TACmdSize * sizeof(IMG_BYTE);
 	}
 
 			/* Copy the data over */
-			if ( !OSAccessOK(PVR_VERIFY_READ, (void*) psRGXKickTA3DIN->psTACmd, psRGXKickTA3DIN->ui32TACmdSize * sizeof(IMG_BYTE))
-				|| (OSCopyFromUser(NULL, psTACmdInt, psRGXKickTA3DIN->psTACmd,
-				psRGXKickTA3DIN->ui32TACmdSize * sizeof(IMG_BYTE)) != PVRSRV_OK) )
+			if (psRGXKickTA3DIN->ui32TACmdSize * sizeof(IMG_BYTE) > 0)
 			{
-				psRGXKickTA3DOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
+				if ( OSCopyFromUser(NULL, psTACmdInt, psRGXKickTA3DIN->psTACmd, psRGXKickTA3DIN->ui32TACmdSize * sizeof(IMG_BYTE)) != PVRSRV_OK )
+				{
+					psRGXKickTA3DOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
 
-				goto RGXKickTA3D_exit;
+					goto RGXKickTA3D_exit;
+				}
 			}
 	if (psRGXKickTA3DIN->ui323DPRCmdSize != 0)
 	{
-		ps3DPRCmdInt = OSAllocMemNoStats(psRGXKickTA3DIN->ui323DPRCmdSize * sizeof(IMG_BYTE));
-		if (!ps3DPRCmdInt)
-		{
-			psRGXKickTA3DOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
-	
-			goto RGXKickTA3D_exit;
-		}
+		ps3DPRCmdInt = (IMG_BYTE*)(((IMG_UINT8 *)pArrayArgsBuffer) + ui32NextOffset);
+		ui32NextOffset += psRGXKickTA3DIN->ui323DPRCmdSize * sizeof(IMG_BYTE);
 	}
 
 			/* Copy the data over */
-			if ( !OSAccessOK(PVR_VERIFY_READ, (void*) psRGXKickTA3DIN->ps3DPRCmd, psRGXKickTA3DIN->ui323DPRCmdSize * sizeof(IMG_BYTE))
-				|| (OSCopyFromUser(NULL, ps3DPRCmdInt, psRGXKickTA3DIN->ps3DPRCmd,
-				psRGXKickTA3DIN->ui323DPRCmdSize * sizeof(IMG_BYTE)) != PVRSRV_OK) )
+			if (psRGXKickTA3DIN->ui323DPRCmdSize * sizeof(IMG_BYTE) > 0)
 			{
-				psRGXKickTA3DOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
+				if ( OSCopyFromUser(NULL, ps3DPRCmdInt, psRGXKickTA3DIN->ps3DPRCmd, psRGXKickTA3DIN->ui323DPRCmdSize * sizeof(IMG_BYTE)) != PVRSRV_OK )
+				{
+					psRGXKickTA3DOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
 
-				goto RGXKickTA3D_exit;
+					goto RGXKickTA3D_exit;
+				}
 			}
 	if (psRGXKickTA3DIN->ui323DCmdSize != 0)
 	{
-		ps3DCmdInt = OSAllocMemNoStats(psRGXKickTA3DIN->ui323DCmdSize * sizeof(IMG_BYTE));
-		if (!ps3DCmdInt)
-		{
-			psRGXKickTA3DOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
-	
-			goto RGXKickTA3D_exit;
-		}
+		ps3DCmdInt = (IMG_BYTE*)(((IMG_UINT8 *)pArrayArgsBuffer) + ui32NextOffset);
+		ui32NextOffset += psRGXKickTA3DIN->ui323DCmdSize * sizeof(IMG_BYTE);
 	}
 
 			/* Copy the data over */
-			if ( !OSAccessOK(PVR_VERIFY_READ, (void*) psRGXKickTA3DIN->ps3DCmd, psRGXKickTA3DIN->ui323DCmdSize * sizeof(IMG_BYTE))
-				|| (OSCopyFromUser(NULL, ps3DCmdInt, psRGXKickTA3DIN->ps3DCmd,
-				psRGXKickTA3DIN->ui323DCmdSize * sizeof(IMG_BYTE)) != PVRSRV_OK) )
+			if (psRGXKickTA3DIN->ui323DCmdSize * sizeof(IMG_BYTE) > 0)
 			{
-				psRGXKickTA3DOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
+				if ( OSCopyFromUser(NULL, ps3DCmdInt, psRGXKickTA3DIN->ps3DCmd, psRGXKickTA3DIN->ui323DCmdSize * sizeof(IMG_BYTE)) != PVRSRV_OK )
+				{
+					psRGXKickTA3DOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
 
-				goto RGXKickTA3D_exit;
+					goto RGXKickTA3D_exit;
+				}
 			}
 	if (psRGXKickTA3DIN->ui32SyncPMRCount != 0)
 	{
-		ui32SyncPMRFlagsInt = OSAllocMemNoStats(psRGXKickTA3DIN->ui32SyncPMRCount * sizeof(IMG_UINT32));
-		if (!ui32SyncPMRFlagsInt)
-		{
-			psRGXKickTA3DOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
-	
-			goto RGXKickTA3D_exit;
-		}
+		ui32SyncPMRFlagsInt = (IMG_UINT32*)(((IMG_UINT8 *)pArrayArgsBuffer) + ui32NextOffset);
+		ui32NextOffset += psRGXKickTA3DIN->ui32SyncPMRCount * sizeof(IMG_UINT32);
 	}
 
 			/* Copy the data over */
-			if ( !OSAccessOK(PVR_VERIFY_READ, (void*) psRGXKickTA3DIN->pui32SyncPMRFlags, psRGXKickTA3DIN->ui32SyncPMRCount * sizeof(IMG_UINT32))
-				|| (OSCopyFromUser(NULL, ui32SyncPMRFlagsInt, psRGXKickTA3DIN->pui32SyncPMRFlags,
-				psRGXKickTA3DIN->ui32SyncPMRCount * sizeof(IMG_UINT32)) != PVRSRV_OK) )
+			if (psRGXKickTA3DIN->ui32SyncPMRCount * sizeof(IMG_UINT32) > 0)
 			{
-				psRGXKickTA3DOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
+				if ( OSCopyFromUser(NULL, ui32SyncPMRFlagsInt, psRGXKickTA3DIN->pui32SyncPMRFlags, psRGXKickTA3DIN->ui32SyncPMRCount * sizeof(IMG_UINT32)) != PVRSRV_OK )
+				{
+					psRGXKickTA3DOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
 
-				goto RGXKickTA3D_exit;
+					goto RGXKickTA3D_exit;
+				}
 			}
 	if (psRGXKickTA3DIN->ui32SyncPMRCount != 0)
 	{
-		psSyncPMRsInt = OSAllocMemNoStats(psRGXKickTA3DIN->ui32SyncPMRCount * sizeof(PMR *));
-		if (!psSyncPMRsInt)
-		{
-			psRGXKickTA3DOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
-	
-			goto RGXKickTA3D_exit;
-		}
-		hSyncPMRsInt2 = OSAllocMemNoStats(psRGXKickTA3DIN->ui32SyncPMRCount * sizeof(IMG_HANDLE));
-		if (!hSyncPMRsInt2)
-		{
-			psRGXKickTA3DOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
-	
-			goto RGXKickTA3D_exit;
-		}
+		psSyncPMRsInt = (PMR **)(((IMG_UINT8 *)pArrayArgsBuffer) + ui32NextOffset);
+		ui32NextOffset += psRGXKickTA3DIN->ui32SyncPMRCount * sizeof(PMR *);
+		hSyncPMRsInt2 = (IMG_HANDLE *)(((IMG_UINT8 *)pArrayArgsBuffer) + ui32NextOffset); 
+		ui32NextOffset += psRGXKickTA3DIN->ui32SyncPMRCount * sizeof(IMG_HANDLE);
 	}
 
 			/* Copy the data over */
-			if ( !OSAccessOK(PVR_VERIFY_READ, (void*) psRGXKickTA3DIN->phSyncPMRs, psRGXKickTA3DIN->ui32SyncPMRCount * sizeof(IMG_HANDLE))
-				|| (OSCopyFromUser(NULL, hSyncPMRsInt2, psRGXKickTA3DIN->phSyncPMRs,
-				psRGXKickTA3DIN->ui32SyncPMRCount * sizeof(IMG_HANDLE)) != PVRSRV_OK) )
+			if (psRGXKickTA3DIN->ui32SyncPMRCount * sizeof(IMG_HANDLE) > 0)
 			{
-				psRGXKickTA3DOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
+				if ( OSCopyFromUser(NULL, hSyncPMRsInt2, psRGXKickTA3DIN->phSyncPMRs, psRGXKickTA3DIN->ui32SyncPMRCount * sizeof(IMG_HANDLE)) != PVRSRV_OK )
+				{
+					psRGXKickTA3DOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
 
-				goto RGXKickTA3D_exit;
+					goto RGXKickTA3D_exit;
+				}
 			}
 
-	PMRLock();
+	/* Lock over handle lookup. */
+	LockHandle();
+
+
+
 
 
 				{
 					/* Look up the address from the handle */
 					psRGXKickTA3DOUT->eError =
-						PVRSRVLookupHandle(psConnection->psHandleBase,
+						PVRSRVLookupHandleUnlocked(psConnection->psHandleBase,
 											(void **) &psRenderContextInt,
-											psRGXKickTA3DIN->hRenderContext,
-											PVRSRV_HANDLE_TYPE_RGX_SERVER_RENDER_CONTEXT);
+											hRenderContext,
+											PVRSRV_HANDLE_TYPE_RGX_SERVER_RENDER_CONTEXT,
+											IMG_TRUE);
 					if(psRGXKickTA3DOUT->eError != PVRSRV_OK)
 					{
-						PMRUnlock();
+						UnlockHandle();
 						goto RGXKickTA3D_exit;
 					}
 				}
 
 
+
+
+
 	{
 		IMG_UINT32 i;
 
@@ -1487,20 +1977,24 @@
 				{
 					/* Look up the address from the handle */
 					psRGXKickTA3DOUT->eError =
-						PVRSRVLookupHandle(psConnection->psHandleBase,
+						PVRSRVLookupHandleUnlocked(psConnection->psHandleBase,
 											(void **) &psClientTAFenceSyncPrimBlockInt[i],
 											hClientTAFenceSyncPrimBlockInt2[i],
-											PVRSRV_HANDLE_TYPE_SYNC_PRIMITIVE_BLOCK);
+											PVRSRV_HANDLE_TYPE_SYNC_PRIMITIVE_BLOCK,
+											IMG_TRUE);
 					if(psRGXKickTA3DOUT->eError != PVRSRV_OK)
 					{
-						PMRUnlock();
+						UnlockHandle();
 						goto RGXKickTA3D_exit;
 					}
 				}
-
 		}
 	}
 
+
+
+
+
 	{
 		IMG_UINT32 i;
 
@@ -1509,20 +2003,24 @@
 				{
 					/* Look up the address from the handle */
 					psRGXKickTA3DOUT->eError =
-						PVRSRVLookupHandle(psConnection->psHandleBase,
+						PVRSRVLookupHandleUnlocked(psConnection->psHandleBase,
 											(void **) &psClientTAUpdateSyncPrimBlockInt[i],
 											hClientTAUpdateSyncPrimBlockInt2[i],
-											PVRSRV_HANDLE_TYPE_SYNC_PRIMITIVE_BLOCK);
+											PVRSRV_HANDLE_TYPE_SYNC_PRIMITIVE_BLOCK,
+											IMG_TRUE);
 					if(psRGXKickTA3DOUT->eError != PVRSRV_OK)
 					{
-						PMRUnlock();
+						UnlockHandle();
 						goto RGXKickTA3D_exit;
 					}
 				}
-
 		}
 	}
 
+
+
+
+
 	{
 		IMG_UINT32 i;
 
@@ -1531,20 +2029,24 @@
 				{
 					/* Look up the address from the handle */
 					psRGXKickTA3DOUT->eError =
-						PVRSRVLookupHandle(psConnection->psHandleBase,
+						PVRSRVLookupHandleUnlocked(psConnection->psHandleBase,
 											(void **) &psServerTASyncsInt[i],
 											hServerTASyncsInt2[i],
-											PVRSRV_HANDLE_TYPE_SERVER_SYNC_PRIMITIVE);
+											PVRSRV_HANDLE_TYPE_SERVER_SYNC_PRIMITIVE,
+											IMG_TRUE);
 					if(psRGXKickTA3DOUT->eError != PVRSRV_OK)
 					{
-						PMRUnlock();
+						UnlockHandle();
 						goto RGXKickTA3D_exit;
 					}
 				}
-
 		}
 	}
 
+
+
+
+
 	{
 		IMG_UINT32 i;
 
@@ -1553,20 +2055,24 @@
 				{
 					/* Look up the address from the handle */
 					psRGXKickTA3DOUT->eError =
-						PVRSRVLookupHandle(psConnection->psHandleBase,
+						PVRSRVLookupHandleUnlocked(psConnection->psHandleBase,
 											(void **) &psClient3DFenceSyncPrimBlockInt[i],
 											hClient3DFenceSyncPrimBlockInt2[i],
-											PVRSRV_HANDLE_TYPE_SYNC_PRIMITIVE_BLOCK);
+											PVRSRV_HANDLE_TYPE_SYNC_PRIMITIVE_BLOCK,
+											IMG_TRUE);
 					if(psRGXKickTA3DOUT->eError != PVRSRV_OK)
 					{
-						PMRUnlock();
+						UnlockHandle();
 						goto RGXKickTA3D_exit;
 					}
 				}
-
 		}
 	}
 
+
+
+
+
 	{
 		IMG_UINT32 i;
 
@@ -1575,20 +2081,24 @@
 				{
 					/* Look up the address from the handle */
 					psRGXKickTA3DOUT->eError =
-						PVRSRVLookupHandle(psConnection->psHandleBase,
+						PVRSRVLookupHandleUnlocked(psConnection->psHandleBase,
 											(void **) &psClient3DUpdateSyncPrimBlockInt[i],
 											hClient3DUpdateSyncPrimBlockInt2[i],
-											PVRSRV_HANDLE_TYPE_SYNC_PRIMITIVE_BLOCK);
+											PVRSRV_HANDLE_TYPE_SYNC_PRIMITIVE_BLOCK,
+											IMG_TRUE);
 					if(psRGXKickTA3DOUT->eError != PVRSRV_OK)
 					{
-						PMRUnlock();
+						UnlockHandle();
 						goto RGXKickTA3D_exit;
 					}
 				}
-
 		}
 	}
 
+
+
+
+
 	{
 		IMG_UINT32 i;
 
@@ -1597,83 +2107,103 @@
 				{
 					/* Look up the address from the handle */
 					psRGXKickTA3DOUT->eError =
-						PVRSRVLookupHandle(psConnection->psHandleBase,
+						PVRSRVLookupHandleUnlocked(psConnection->psHandleBase,
 											(void **) &psServer3DSyncsInt[i],
 											hServer3DSyncsInt2[i],
-											PVRSRV_HANDLE_TYPE_SERVER_SYNC_PRIMITIVE);
+											PVRSRV_HANDLE_TYPE_SERVER_SYNC_PRIMITIVE,
+											IMG_TRUE);
 					if(psRGXKickTA3DOUT->eError != PVRSRV_OK)
 					{
-						PMRUnlock();
+						UnlockHandle();
 						goto RGXKickTA3D_exit;
 					}
 				}
-
 		}
 	}
 
+
+
+
+
 				{
 					/* Look up the address from the handle */
 					psRGXKickTA3DOUT->eError =
-						PVRSRVLookupHandle(psConnection->psHandleBase,
+						PVRSRVLookupHandleUnlocked(psConnection->psHandleBase,
 											(void **) &psPRFenceUFOSyncPrimBlockInt,
-											psRGXKickTA3DIN->hPRFenceUFOSyncPrimBlock,
-											PVRSRV_HANDLE_TYPE_SYNC_PRIMITIVE_BLOCK);
+											hPRFenceUFOSyncPrimBlock,
+											PVRSRV_HANDLE_TYPE_SYNC_PRIMITIVE_BLOCK,
+											IMG_TRUE);
 					if(psRGXKickTA3DOUT->eError != PVRSRV_OK)
 					{
-						PMRUnlock();
+						UnlockHandle();
 						goto RGXKickTA3D_exit;
 					}
 				}
 
 
+
+
+
 				if (psRGXKickTA3DIN->hRTDataCleanup)
 				{
 					/* Look up the address from the handle */
 					psRGXKickTA3DOUT->eError =
-						PVRSRVLookupHandle(psConnection->psHandleBase,
+						PVRSRVLookupHandleUnlocked(psConnection->psHandleBase,
 											(void **) &psRTDataCleanupInt,
-											psRGXKickTA3DIN->hRTDataCleanup,
-											PVRSRV_HANDLE_TYPE_RGX_RTDATA_CLEANUP);
+											hRTDataCleanup,
+											PVRSRV_HANDLE_TYPE_RGX_RTDATA_CLEANUP,
+											IMG_TRUE);
 					if(psRGXKickTA3DOUT->eError != PVRSRV_OK)
 					{
-						PMRUnlock();
+						UnlockHandle();
 						goto RGXKickTA3D_exit;
 					}
 				}
 
 
+
+
+
 				if (psRGXKickTA3DIN->hZBuffer)
 				{
 					/* Look up the address from the handle */
 					psRGXKickTA3DOUT->eError =
-						PVRSRVLookupHandle(psConnection->psHandleBase,
+						PVRSRVLookupHandleUnlocked(psConnection->psHandleBase,
 											(void **) &psZBufferInt,
-											psRGXKickTA3DIN->hZBuffer,
-											PVRSRV_HANDLE_TYPE_RGX_FWIF_ZSBUFFER);
+											hZBuffer,
+											PVRSRV_HANDLE_TYPE_RGX_FWIF_ZSBUFFER,
+											IMG_TRUE);
 					if(psRGXKickTA3DOUT->eError != PVRSRV_OK)
 					{
-						PMRUnlock();
+						UnlockHandle();
 						goto RGXKickTA3D_exit;
 					}
 				}
 
 
+
+
+
 				if (psRGXKickTA3DIN->hSBuffer)
 				{
 					/* Look up the address from the handle */
 					psRGXKickTA3DOUT->eError =
-						PVRSRVLookupHandle(psConnection->psHandleBase,
+						PVRSRVLookupHandleUnlocked(psConnection->psHandleBase,
 											(void **) &psSBufferInt,
-											psRGXKickTA3DIN->hSBuffer,
-											PVRSRV_HANDLE_TYPE_RGX_FWIF_ZSBUFFER);
+											hSBuffer,
+											PVRSRV_HANDLE_TYPE_RGX_FWIF_ZSBUFFER,
+											IMG_TRUE);
 					if(psRGXKickTA3DOUT->eError != PVRSRV_OK)
 					{
-						PMRUnlock();
+						UnlockHandle();
 						goto RGXKickTA3D_exit;
 					}
 				}
 
 
+
+
+
 	{
 		IMG_UINT32 i;
 
@@ -1682,23 +2212,26 @@
 				{
 					/* Look up the address from the handle */
 					psRGXKickTA3DOUT->eError =
-						PVRSRVLookupHandle(psConnection->psHandleBase,
+						PVRSRVLookupHandleUnlocked(psConnection->psHandleBase,
 											(void **) &psSyncPMRsInt[i],
 											hSyncPMRsInt2[i],
-											PVRSRV_HANDLE_TYPE_PHYSMEM_PMR);
+											PVRSRV_HANDLE_TYPE_PHYSMEM_PMR,
+											IMG_TRUE);
 					if(psRGXKickTA3DOUT->eError != PVRSRV_OK)
 					{
-						PMRUnlock();
+						UnlockHandle();
 						goto RGXKickTA3D_exit;
 					}
 				}
-
 		}
 	}
+	/* Release now we have looked up handles. */
+	UnlockHandle();
 
 	psRGXKickTA3DOUT->eError =
 		PVRSRVRGXKickTA3DKM(
 					psRenderContextInt,
+					psRGXKickTA3DIN->ui32ClientCacheOpSeqNum,
 					psRGXKickTA3DIN->ui32ClientTAFenceCount,
 					psClientTAFenceSyncPrimBlockInt,
 					ui32ClientTAFenceSyncOffsetInt,
@@ -1735,13 +2268,12 @@
 					psRGXKickTA3DIN->ui323DCmdSize,
 					ps3DCmdInt,
 					psRGXKickTA3DIN->ui32ExtJobRef,
-					psRGXKickTA3DIN->ui32IntJobRef,
 					psRGXKickTA3DIN->bbLastTAInScene,
 					psRGXKickTA3DIN->bbKickTA,
 					psRGXKickTA3DIN->bbKickPR,
 					psRGXKickTA3DIN->bbKick3D,
 					psRGXKickTA3DIN->bbAbort,
-					psRGXKickTA3DIN->bbPDumpContinuous,
+					psRGXKickTA3DIN->ui32PDumpFlags,
 					psRTDataCleanupInt,
 					psZBufferInt,
 					psSBufferInt,
@@ -1751,81 +2283,280 @@
 					&psRGXKickTA3DOUT->bbCommittedRefCounts3D,
 					psRGXKickTA3DIN->ui32SyncPMRCount,
 					ui32SyncPMRFlagsInt,
-					psSyncPMRsInt);
-	PMRUnlock();
+					psSyncPMRsInt,
+					psRGXKickTA3DIN->ui32RenderTargetSize,
+					psRGXKickTA3DIN->ui32NumberOfDrawCalls,
+					psRGXKickTA3DIN->ui32NumberOfIndices,
+					psRGXKickTA3DIN->ui32NumberOfMRTs,
+					psRGXKickTA3DIN->ui64Deadline);
 
 
 
 
 RGXKickTA3D_exit:
-	if (psClientTAFenceSyncPrimBlockInt)
-		OSFreeMemNoStats(psClientTAFenceSyncPrimBlockInt);
+
+	/* Lock over handle lookup cleanup. */
+	LockHandle();
+
+
+
+
+
+
+				{
+					/* Unreference the previously looked up handle */
+						if(psRenderContextInt)
+						{
+							PVRSRVReleaseHandleUnlocked(psConnection->psHandleBase,
+											hRenderContext,
+											PVRSRV_HANDLE_TYPE_RGX_SERVER_RENDER_CONTEXT);
+						}
+				}
+
+
+
+
+
+
 	if (hClientTAFenceSyncPrimBlockInt2)
-		OSFreeMemNoStats(hClientTAFenceSyncPrimBlockInt2);
-	if (ui32ClientTAFenceSyncOffsetInt)
-		OSFreeMemNoStats(ui32ClientTAFenceSyncOffsetInt);
-	if (ui32ClientTAFenceValueInt)
-		OSFreeMemNoStats(ui32ClientTAFenceValueInt);
-	if (psClientTAUpdateSyncPrimBlockInt)
-		OSFreeMemNoStats(psClientTAUpdateSyncPrimBlockInt);
+	{
+		IMG_UINT32 i;
+
+		for (i=0;i<psRGXKickTA3DIN->ui32ClientTAFenceCount;i++)
+		{
+				{
+					/* Unreference the previously looked up handle */
+						if(psClientTAFenceSyncPrimBlockInt[i])
+						{
+							PVRSRVReleaseHandleUnlocked(psConnection->psHandleBase,
+											hClientTAFenceSyncPrimBlockInt2[i],
+											PVRSRV_HANDLE_TYPE_SYNC_PRIMITIVE_BLOCK);
+						}
+				}
+		}
+	}
+
+
+
+
+
+
 	if (hClientTAUpdateSyncPrimBlockInt2)
-		OSFreeMemNoStats(hClientTAUpdateSyncPrimBlockInt2);
-	if (ui32ClientTAUpdateSyncOffsetInt)
-		OSFreeMemNoStats(ui32ClientTAUpdateSyncOffsetInt);
-	if (ui32ClientTAUpdateValueInt)
-		OSFreeMemNoStats(ui32ClientTAUpdateValueInt);
-	if (ui32ServerTASyncFlagsInt)
-		OSFreeMemNoStats(ui32ServerTASyncFlagsInt);
-	if (psServerTASyncsInt)
-		OSFreeMemNoStats(psServerTASyncsInt);
+	{
+		IMG_UINT32 i;
+
+		for (i=0;i<psRGXKickTA3DIN->ui32ClientTAUpdateCount;i++)
+		{
+				{
+					/* Unreference the previously looked up handle */
+						if(psClientTAUpdateSyncPrimBlockInt[i])
+						{
+							PVRSRVReleaseHandleUnlocked(psConnection->psHandleBase,
+											hClientTAUpdateSyncPrimBlockInt2[i],
+											PVRSRV_HANDLE_TYPE_SYNC_PRIMITIVE_BLOCK);
+						}
+				}
+		}
+	}
+
+
+
+
+
+
 	if (hServerTASyncsInt2)
-		OSFreeMemNoStats(hServerTASyncsInt2);
-	if (psClient3DFenceSyncPrimBlockInt)
-		OSFreeMemNoStats(psClient3DFenceSyncPrimBlockInt);
+	{
+		IMG_UINT32 i;
+
+		for (i=0;i<psRGXKickTA3DIN->ui32ServerTASyncPrims;i++)
+		{
+				{
+					/* Unreference the previously looked up handle */
+						if(psServerTASyncsInt[i])
+						{
+							PVRSRVReleaseHandleUnlocked(psConnection->psHandleBase,
+											hServerTASyncsInt2[i],
+											PVRSRV_HANDLE_TYPE_SERVER_SYNC_PRIMITIVE);
+						}
+				}
+		}
+	}
+
+
+
+
+
+
 	if (hClient3DFenceSyncPrimBlockInt2)
-		OSFreeMemNoStats(hClient3DFenceSyncPrimBlockInt2);
-	if (ui32Client3DFenceSyncOffsetInt)
-		OSFreeMemNoStats(ui32Client3DFenceSyncOffsetInt);
-	if (ui32Client3DFenceValueInt)
-		OSFreeMemNoStats(ui32Client3DFenceValueInt);
-	if (psClient3DUpdateSyncPrimBlockInt)
-		OSFreeMemNoStats(psClient3DUpdateSyncPrimBlockInt);
+	{
+		IMG_UINT32 i;
+
+		for (i=0;i<psRGXKickTA3DIN->ui32Client3DFenceCount;i++)
+		{
+				{
+					/* Unreference the previously looked up handle */
+						if(psClient3DFenceSyncPrimBlockInt[i])
+						{
+							PVRSRVReleaseHandleUnlocked(psConnection->psHandleBase,
+											hClient3DFenceSyncPrimBlockInt2[i],
+											PVRSRV_HANDLE_TYPE_SYNC_PRIMITIVE_BLOCK);
+						}
+				}
+		}
+	}
+
+
+
+
+
+
 	if (hClient3DUpdateSyncPrimBlockInt2)
-		OSFreeMemNoStats(hClient3DUpdateSyncPrimBlockInt2);
-	if (ui32Client3DUpdateSyncOffsetInt)
-		OSFreeMemNoStats(ui32Client3DUpdateSyncOffsetInt);
-	if (ui32Client3DUpdateValueInt)
-		OSFreeMemNoStats(ui32Client3DUpdateValueInt);
-	if (ui32Server3DSyncFlagsInt)
-		OSFreeMemNoStats(ui32Server3DSyncFlagsInt);
-	if (psServer3DSyncsInt)
-		OSFreeMemNoStats(psServer3DSyncsInt);
+	{
+		IMG_UINT32 i;
+
+		for (i=0;i<psRGXKickTA3DIN->ui32Client3DUpdateCount;i++)
+		{
+				{
+					/* Unreference the previously looked up handle */
+						if(psClient3DUpdateSyncPrimBlockInt[i])
+						{
+							PVRSRVReleaseHandleUnlocked(psConnection->psHandleBase,
+											hClient3DUpdateSyncPrimBlockInt2[i],
+											PVRSRV_HANDLE_TYPE_SYNC_PRIMITIVE_BLOCK);
+						}
+				}
+		}
+	}
+
+
+
+
+
+
 	if (hServer3DSyncsInt2)
-		OSFreeMemNoStats(hServer3DSyncsInt2);
-	if (uiUpdateFenceNameInt)
-		OSFreeMemNoStats(uiUpdateFenceNameInt);
-	if (psTACmdInt)
-		OSFreeMemNoStats(psTACmdInt);
-	if (ps3DPRCmdInt)
-		OSFreeMemNoStats(ps3DPRCmdInt);
-	if (ps3DCmdInt)
-		OSFreeMemNoStats(ps3DCmdInt);
-	if (ui32SyncPMRFlagsInt)
-		OSFreeMemNoStats(ui32SyncPMRFlagsInt);
-	if (psSyncPMRsInt)
-		OSFreeMemNoStats(psSyncPMRsInt);
+	{
+		IMG_UINT32 i;
+
+		for (i=0;i<psRGXKickTA3DIN->ui32Server3DSyncPrims;i++)
+		{
+				{
+					/* Unreference the previously looked up handle */
+						if(psServer3DSyncsInt[i])
+						{
+							PVRSRVReleaseHandleUnlocked(psConnection->psHandleBase,
+											hServer3DSyncsInt2[i],
+											PVRSRV_HANDLE_TYPE_SERVER_SYNC_PRIMITIVE);
+						}
+				}
+		}
+	}
+
+
+
+
+
+				{
+					/* Unreference the previously looked up handle */
+						if(psPRFenceUFOSyncPrimBlockInt)
+						{
+							PVRSRVReleaseHandleUnlocked(psConnection->psHandleBase,
+											hPRFenceUFOSyncPrimBlock,
+											PVRSRV_HANDLE_TYPE_SYNC_PRIMITIVE_BLOCK);
+						}
+				}
+
+
+
+
+
+				if (psRGXKickTA3DIN->hRTDataCleanup)
+				{
+					/* Unreference the previously looked up handle */
+						if(psRTDataCleanupInt)
+						{
+							PVRSRVReleaseHandleUnlocked(psConnection->psHandleBase,
+											hRTDataCleanup,
+											PVRSRV_HANDLE_TYPE_RGX_RTDATA_CLEANUP);
+						}
+				}
+
+
+
+
+
+				if (psRGXKickTA3DIN->hZBuffer)
+				{
+					/* Unreference the previously looked up handle */
+						if(psZBufferInt)
+						{
+							PVRSRVReleaseHandleUnlocked(psConnection->psHandleBase,
+											hZBuffer,
+											PVRSRV_HANDLE_TYPE_RGX_FWIF_ZSBUFFER);
+						}
+				}
+
+
+
+
+
+				if (psRGXKickTA3DIN->hSBuffer)
+				{
+					/* Unreference the previously looked up handle */
+						if(psSBufferInt)
+						{
+							PVRSRVReleaseHandleUnlocked(psConnection->psHandleBase,
+											hSBuffer,
+											PVRSRV_HANDLE_TYPE_RGX_FWIF_ZSBUFFER);
+						}
+				}
+
+
+
+
+
+
 	if (hSyncPMRsInt2)
-		OSFreeMemNoStats(hSyncPMRsInt2);
+	{
+		IMG_UINT32 i;
+
+		for (i=0;i<psRGXKickTA3DIN->ui32SyncPMRCount;i++)
+		{
+				{
+					/* Unreference the previously looked up handle */
+						if(psSyncPMRsInt[i])
+						{
+							PVRSRVReleaseHandleUnlocked(psConnection->psHandleBase,
+											hSyncPMRsInt2[i],
+											PVRSRV_HANDLE_TYPE_PHYSMEM_PMR);
+						}
+				}
+		}
+	}
+	/* Release now we have cleaned up look up handles. */
+	UnlockHandle();
+
+	/* Allocated space should be equal to the last updated offset */
+	PVR_ASSERT(ui32BufferSize == ui32NextOffset);
+
+#if defined(INTEGRITY_OS)
+	if(pArrayArgsBuffer)
+#else
+	if(!bHaveEnoughSpace && pArrayArgsBuffer)
+#endif
+		OSFreeMemNoStats(pArrayArgsBuffer);
+
 
 	return 0;
 }
 
+
 static IMG_INT
 PVRSRVBridgeRGXSetRenderContextPriority(IMG_UINT32 ui32DispatchTableEntry,
 					  PVRSRV_BRIDGE_IN_RGXSETRENDERCONTEXTPRIORITY *psRGXSetRenderContextPriorityIN,
 					  PVRSRV_BRIDGE_OUT_RGXSETRENDERCONTEXTPRIORITY *psRGXSetRenderContextPriorityOUT,
 					 CONNECTION_DATA *psConnection)
 {
+	IMG_HANDLE hRenderContext = psRGXSetRenderContextPriorityIN->hRenderContext;
 	RGX_SERVER_RENDER_CONTEXT * psRenderContextInt = NULL;
 
 
@@ -1834,19 +2565,29 @@
 
 
 
+	/* Lock over handle lookup. */
+	LockHandle();
+
+
+
+
+
 				{
 					/* Look up the address from the handle */
 					psRGXSetRenderContextPriorityOUT->eError =
-						PVRSRVLookupHandle(psConnection->psHandleBase,
+						PVRSRVLookupHandleUnlocked(psConnection->psHandleBase,
 											(void **) &psRenderContextInt,
-											psRGXSetRenderContextPriorityIN->hRenderContext,
-											PVRSRV_HANDLE_TYPE_RGX_SERVER_RENDER_CONTEXT);
+											hRenderContext,
+											PVRSRV_HANDLE_TYPE_RGX_SERVER_RENDER_CONTEXT,
+											IMG_TRUE);
 					if(psRGXSetRenderContextPriorityOUT->eError != PVRSRV_OK)
 					{
+						UnlockHandle();
 						goto RGXSetRenderContextPriority_exit;
 					}
 				}
-
+	/* Release now we have looked up handles. */
+	UnlockHandle();
 
 	psRGXSetRenderContextPriorityOUT->eError =
 		PVRSRVRGXSetRenderContextPriorityKM(psConnection, OSGetDevData(psConnection),
@@ -1858,15 +2599,38 @@
 
 RGXSetRenderContextPriority_exit:
 
+	/* Lock over handle lookup cleanup. */
+	LockHandle();
+
+
+
+
+
+
+				{
+					/* Unreference the previously looked up handle */
+						if(psRenderContextInt)
+						{
+							PVRSRVReleaseHandleUnlocked(psConnection->psHandleBase,
+											hRenderContext,
+											PVRSRV_HANDLE_TYPE_RGX_SERVER_RENDER_CONTEXT);
+						}
+				}
+	/* Release now we have cleaned up look up handles. */
+	UnlockHandle();
+
+
 	return 0;
 }
 
+
 static IMG_INT
 PVRSRVBridgeRGXGetLastRenderContextResetReason(IMG_UINT32 ui32DispatchTableEntry,
 					  PVRSRV_BRIDGE_IN_RGXGETLASTRENDERCONTEXTRESETREASON *psRGXGetLastRenderContextResetReasonIN,
 					  PVRSRV_BRIDGE_OUT_RGXGETLASTRENDERCONTEXTRESETREASON *psRGXGetLastRenderContextResetReasonOUT,
 					 CONNECTION_DATA *psConnection)
 {
+	IMG_HANDLE hRenderContext = psRGXGetLastRenderContextResetReasonIN->hRenderContext;
 	RGX_SERVER_RENDER_CONTEXT * psRenderContextInt = NULL;
 
 
@@ -1875,19 +2639,29 @@
 
 
 
+	/* Lock over handle lookup. */
+	LockHandle();
+
+
+
+
+
 				{
 					/* Look up the address from the handle */
 					psRGXGetLastRenderContextResetReasonOUT->eError =
-						PVRSRVLookupHandle(psConnection->psHandleBase,
+						PVRSRVLookupHandleUnlocked(psConnection->psHandleBase,
 											(void **) &psRenderContextInt,
-											psRGXGetLastRenderContextResetReasonIN->hRenderContext,
-											PVRSRV_HANDLE_TYPE_RGX_SERVER_RENDER_CONTEXT);
+											hRenderContext,
+											PVRSRV_HANDLE_TYPE_RGX_SERVER_RENDER_CONTEXT,
+											IMG_TRUE);
 					if(psRGXGetLastRenderContextResetReasonOUT->eError != PVRSRV_OK)
 					{
+						UnlockHandle();
 						goto RGXGetLastRenderContextResetReason_exit;
 					}
 				}
-
+	/* Release now we have looked up handles. */
+	UnlockHandle();
 
 	psRGXGetLastRenderContextResetReasonOUT->eError =
 		PVRSRVRGXGetLastRenderContextResetReasonKM(
@@ -1900,15 +2674,38 @@
 
 RGXGetLastRenderContextResetReason_exit:
 
+	/* Lock over handle lookup cleanup. */
+	LockHandle();
+
+
+
+
+
+
+				{
+					/* Unreference the previously looked up handle */
+						if(psRenderContextInt)
+						{
+							PVRSRVReleaseHandleUnlocked(psConnection->psHandleBase,
+											hRenderContext,
+											PVRSRV_HANDLE_TYPE_RGX_SERVER_RENDER_CONTEXT);
+						}
+				}
+	/* Release now we have cleaned up look up handles. */
+	UnlockHandle();
+
+
 	return 0;
 }
 
+
 static IMG_INT
 PVRSRVBridgeRGXGetPartialRenderCount(IMG_UINT32 ui32DispatchTableEntry,
 					  PVRSRV_BRIDGE_IN_RGXGETPARTIALRENDERCOUNT *psRGXGetPartialRenderCountIN,
 					  PVRSRV_BRIDGE_OUT_RGXGETPARTIALRENDERCOUNT *psRGXGetPartialRenderCountOUT,
 					 CONNECTION_DATA *psConnection)
 {
+	IMG_HANDLE hHWRTDataMemDesc = psRGXGetPartialRenderCountIN->hHWRTDataMemDesc;
 	DEVMEM_MEMDESC * psHWRTDataMemDescInt = NULL;
 
 
@@ -1917,19 +2714,29 @@
 
 
 
+	/* Lock over handle lookup. */
+	LockHandle();
+
+
+
+
+
 				{
 					/* Look up the address from the handle */
 					psRGXGetPartialRenderCountOUT->eError =
-						PVRSRVLookupHandle(psConnection->psHandleBase,
+						PVRSRVLookupHandleUnlocked(psConnection->psHandleBase,
 											(void **) &psHWRTDataMemDescInt,
-											psRGXGetPartialRenderCountIN->hHWRTDataMemDesc,
-											PVRSRV_HANDLE_TYPE_RGX_FW_MEMDESC);
+											hHWRTDataMemDesc,
+											PVRSRV_HANDLE_TYPE_RGX_FW_MEMDESC,
+											IMG_TRUE);
 					if(psRGXGetPartialRenderCountOUT->eError != PVRSRV_OK)
 					{
+						UnlockHandle();
 						goto RGXGetPartialRenderCount_exit;
 					}
 				}
-
+	/* Release now we have looked up handles. */
+	UnlockHandle();
 
 	psRGXGetPartialRenderCountOUT->eError =
 		PVRSRVRGXGetPartialRenderCountKM(
@@ -1941,11 +2748,33 @@
 
 RGXGetPartialRenderCount_exit:
 
+	/* Lock over handle lookup cleanup. */
+	LockHandle();
+
+
+
+
+
+
+				{
+					/* Unreference the previously looked up handle */
+						if(psHWRTDataMemDescInt)
+						{
+							PVRSRVReleaseHandleUnlocked(psConnection->psHandleBase,
+											hHWRTDataMemDesc,
+											PVRSRV_HANDLE_TYPE_RGX_FW_MEMDESC);
+						}
+				}
+	/* Release now we have cleaned up look up handles. */
+	UnlockHandle();
+
+
 	return 0;
 }
 
 
 
+
 /* *************************************************************************** 
  * Server bridge dispatch related glue 
  */
@@ -2026,4 +2855,3 @@
 {
 	return PVRSRV_OK;
 }
-
diff --git a/drivers/staging/imgtec/rogue/generated/rgxtq2_bridge/common_rgxtq2_bridge.h b/drivers/staging/imgtec/rogue/generated/rgxtq2_bridge/common_rgxtq2_bridge.h
new file mode 100644
index 0000000..f3e2b65
--- /dev/null
+++ b/drivers/staging/imgtec/rogue/generated/rgxtq2_bridge/common_rgxtq2_bridge.h
@@ -0,0 +1,181 @@
+/*************************************************************************/ /*!
+@File
+@Title          Common bridge header for rgxtq2
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description    Declares common defines and structures used by both the client
+                and server side of the bridge for rgxtq2
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#ifndef COMMON_RGXTQ2_BRIDGE_H
+#define COMMON_RGXTQ2_BRIDGE_H
+
+#include <powervr/mem_types.h>
+
+#include "img_types.h"
+#include "pvrsrv_error.h"
+
+#include "rgx_bridge.h"
+#include <powervr/sync_external.h>
+
+
+#define PVRSRV_BRIDGE_RGXTQ2_CMD_FIRST			0
+#define PVRSRV_BRIDGE_RGXTQ2_RGXTDMCREATETRANSFERCONTEXT			PVRSRV_BRIDGE_RGXTQ2_CMD_FIRST+0
+#define PVRSRV_BRIDGE_RGXTQ2_RGXTDMDESTROYTRANSFERCONTEXT			PVRSRV_BRIDGE_RGXTQ2_CMD_FIRST+1
+#define PVRSRV_BRIDGE_RGXTQ2_RGXTDMSUBMITTRANSFER			PVRSRV_BRIDGE_RGXTQ2_CMD_FIRST+2
+#define PVRSRV_BRIDGE_RGXTQ2_RGXTDMSETTRANSFERCONTEXTPRIORITY			PVRSRV_BRIDGE_RGXTQ2_CMD_FIRST+3
+#define PVRSRV_BRIDGE_RGXTQ2_RGXTDMNOTIFYWRITEOFFSETUPDATE			PVRSRV_BRIDGE_RGXTQ2_CMD_FIRST+4
+#define PVRSRV_BRIDGE_RGXTQ2_CMD_LAST			(PVRSRV_BRIDGE_RGXTQ2_CMD_FIRST+4)
+
+
+/*******************************************
+            RGXTDMCreateTransferContext          
+ *******************************************/
+
+/* Bridge in structure for RGXTDMCreateTransferContext */
+typedef struct PVRSRV_BRIDGE_IN_RGXTDMCREATETRANSFERCONTEXT_TAG
+{
+	IMG_UINT32 ui32Priority;
+	IMG_DEV_VIRTADDR sMCUFenceAddr;
+	IMG_UINT32 ui32FrameworkCmdize;
+	IMG_BYTE * psFrameworkCmd;
+	IMG_HANDLE hPrivData;
+} __attribute__((packed)) PVRSRV_BRIDGE_IN_RGXTDMCREATETRANSFERCONTEXT;
+
+/* Bridge out structure for RGXTDMCreateTransferContext */
+typedef struct PVRSRV_BRIDGE_OUT_RGXTDMCREATETRANSFERCONTEXT_TAG
+{
+	IMG_HANDLE hTransferContext;
+	PVRSRV_ERROR eError;
+} __attribute__((packed)) PVRSRV_BRIDGE_OUT_RGXTDMCREATETRANSFERCONTEXT;
+
+
+/*******************************************
+            RGXTDMDestroyTransferContext          
+ *******************************************/
+
+/* Bridge in structure for RGXTDMDestroyTransferContext */
+typedef struct PVRSRV_BRIDGE_IN_RGXTDMDESTROYTRANSFERCONTEXT_TAG
+{
+	IMG_HANDLE hTransferContext;
+} __attribute__((packed)) PVRSRV_BRIDGE_IN_RGXTDMDESTROYTRANSFERCONTEXT;
+
+/* Bridge out structure for RGXTDMDestroyTransferContext */
+typedef struct PVRSRV_BRIDGE_OUT_RGXTDMDESTROYTRANSFERCONTEXT_TAG
+{
+	PVRSRV_ERROR eError;
+} __attribute__((packed)) PVRSRV_BRIDGE_OUT_RGXTDMDESTROYTRANSFERCONTEXT;
+
+
+/*******************************************
+            RGXTDMSubmitTransfer          
+ *******************************************/
+
+/* Bridge in structure for RGXTDMSubmitTransfer */
+typedef struct PVRSRV_BRIDGE_IN_RGXTDMSUBMITTRANSFER_TAG
+{
+	IMG_HANDLE hTransferContext;
+	IMG_UINT32 ui32PDumpFlags;
+	IMG_UINT32 ui32ClientCacheOpSeqNum;
+	IMG_UINT32 ui32ClientFenceCount;
+	IMG_HANDLE * phFenceUFOSyncPrimBlock;
+	IMG_UINT32 * pui32FenceSyncOffset;
+	IMG_UINT32 * pui32FenceValue;
+	IMG_UINT32 ui32ClientUpdateCount;
+	IMG_HANDLE * phUpdateUFOSyncPrimBlock;
+	IMG_UINT32 * pui32UpdateSyncOffset;
+	IMG_UINT32 * pui32UpdateValue;
+	IMG_UINT32 ui32ServerSyncCount;
+	IMG_UINT32 * pui32ServerSyncFlags;
+	IMG_HANDLE * phServerSync;
+	IMG_INT32 i32CheckFenceFD;
+	IMG_INT32 i32UpdateTimelineFD;
+	IMG_CHAR * puiUpdateFenceName;
+	IMG_UINT32 ui32CommandSize;
+	IMG_UINT8 * pui8FWCommand;
+	IMG_UINT32 ui32ExternalJobReference;
+	IMG_UINT32 ui32SyncPMRCount;
+	IMG_UINT32 * pui32SyncPMRFlags;
+	IMG_HANDLE * phSyncPMRs;
+} __attribute__((packed)) PVRSRV_BRIDGE_IN_RGXTDMSUBMITTRANSFER;
+
+/* Bridge out structure for RGXTDMSubmitTransfer */
+typedef struct PVRSRV_BRIDGE_OUT_RGXTDMSUBMITTRANSFER_TAG
+{
+	IMG_INT32 i32UpdateFenceFD;
+	PVRSRV_ERROR eError;
+} __attribute__((packed)) PVRSRV_BRIDGE_OUT_RGXTDMSUBMITTRANSFER;
+
+
+/*******************************************
+            RGXTDMSetTransferContextPriority          
+ *******************************************/
+
+/* Bridge in structure for RGXTDMSetTransferContextPriority */
+typedef struct PVRSRV_BRIDGE_IN_RGXTDMSETTRANSFERCONTEXTPRIORITY_TAG
+{
+	IMG_HANDLE hTransferContext;
+	IMG_UINT32 ui32Priority;
+} __attribute__((packed)) PVRSRV_BRIDGE_IN_RGXTDMSETTRANSFERCONTEXTPRIORITY;
+
+/* Bridge out structure for RGXTDMSetTransferContextPriority */
+typedef struct PVRSRV_BRIDGE_OUT_RGXTDMSETTRANSFERCONTEXTPRIORITY_TAG
+{
+	PVRSRV_ERROR eError;
+} __attribute__((packed)) PVRSRV_BRIDGE_OUT_RGXTDMSETTRANSFERCONTEXTPRIORITY;
+
+
+/*******************************************
+            RGXTDMNotifyWriteOffsetUpdate          
+ *******************************************/
+
+/* Bridge in structure for RGXTDMNotifyWriteOffsetUpdate */
+typedef struct PVRSRV_BRIDGE_IN_RGXTDMNOTIFYWRITEOFFSETUPDATE_TAG
+{
+	IMG_HANDLE hTransferContext;
+	IMG_UINT32 ui32PDumpFlags;
+} __attribute__((packed)) PVRSRV_BRIDGE_IN_RGXTDMNOTIFYWRITEOFFSETUPDATE;
+
+/* Bridge out structure for RGXTDMNotifyWriteOffsetUpdate */
+typedef struct PVRSRV_BRIDGE_OUT_RGXTDMNOTIFYWRITEOFFSETUPDATE_TAG
+{
+	PVRSRV_ERROR eError;
+} __attribute__((packed)) PVRSRV_BRIDGE_OUT_RGXTDMNOTIFYWRITEOFFSETUPDATE;
+
+
+#endif /* COMMON_RGXTQ2_BRIDGE_H */
diff --git a/drivers/staging/imgtec/rogue/generated/rgxtq2_bridge/server_rgxtq2_bridge.c b/drivers/staging/imgtec/rogue/generated/rgxtq2_bridge/server_rgxtq2_bridge.c
new file mode 100644
index 0000000..9f011c0
--- /dev/null
+++ b/drivers/staging/imgtec/rogue/generated/rgxtq2_bridge/server_rgxtq2_bridge.c
@@ -0,0 +1,1121 @@
+/*************************************************************************/ /*!
+@File
+@Title          Server bridge for rgxtq2
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description    Implements the server side of the bridge for rgxtq2
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#include <stddef.h>
+#include <asm/uaccess.h>
+
+#include "img_defs.h"
+
+#include "rgxtdmtransfer.h"
+
+
+#include "common_rgxtq2_bridge.h"
+
+#include "allocmem.h"
+#include "pvr_debug.h"
+#include "connection_server.h"
+#include "pvr_bridge.h"
+#include "rgx_bridge.h"
+#include "srvcore.h"
+#include "handle.h"
+
+#include <linux/slab.h>
+
+
+#include "rgx_bvnc_defs_km.h"
+
+
+
+
+/* ***************************************************************************
+ * Server-side bridge entry points
+ */
+ 
+static IMG_INT
+PVRSRVBridgeRGXTDMCreateTransferContext(IMG_UINT32 ui32DispatchTableEntry,
+					  PVRSRV_BRIDGE_IN_RGXTDMCREATETRANSFERCONTEXT *psRGXTDMCreateTransferContextIN,
+					  PVRSRV_BRIDGE_OUT_RGXTDMCREATETRANSFERCONTEXT *psRGXTDMCreateTransferContextOUT,
+					 CONNECTION_DATA *psConnection)
+{
+	IMG_BYTE *psFrameworkCmdInt = NULL;
+	IMG_HANDLE hPrivData = psRGXTDMCreateTransferContextIN->hPrivData;
+	IMG_HANDLE hPrivDataInt = NULL;
+	RGX_SERVER_TQ_TDM_CONTEXT * psTransferContextInt = NULL;
+
+	IMG_UINT32 ui32NextOffset = 0;
+	IMG_BYTE   *pArrayArgsBuffer = NULL;
+#if !defined(INTEGRITY_OS)
+	IMG_BOOL bHaveEnoughSpace = IMG_FALSE;
+#endif
+
+	IMG_UINT32 ui32BufferSize = 
+			(psRGXTDMCreateTransferContextIN->ui32FrameworkCmdize * sizeof(IMG_BYTE)) +
+			0;
+
+	{
+		PVRSRV_DEVICE_NODE *psDeviceNode = OSGetDevData(psConnection);
+
+		/* Check that device supports the required feature */
+		if ((psDeviceNode->pfnCheckDeviceFeature) &&
+			!psDeviceNode->pfnCheckDeviceFeature(psDeviceNode, RGX_FEATURE_FASTRENDER_DM_BIT_MASK))
+		{
+			psRGXTDMCreateTransferContextOUT->eError = PVRSRV_ERROR_NOT_SUPPORTED;
+
+			goto RGXTDMCreateTransferContext_exit;
+		}
+	}
+
+
+
+
+	if (ui32BufferSize != 0)
+	{
+#if !defined(INTEGRITY_OS)
+		/* Try to use remainder of input buffer for copies if possible, word-aligned for safety. */
+		IMG_UINT32 ui32InBufferOffset = PVR_ALIGN(sizeof(*psRGXTDMCreateTransferContextIN), sizeof(unsigned long));
+		IMG_UINT32 ui32InBufferExcessSize = ui32InBufferOffset >= PVRSRV_MAX_BRIDGE_IN_SIZE ? 0 :
+			PVRSRV_MAX_BRIDGE_IN_SIZE - ui32InBufferOffset;
+
+		bHaveEnoughSpace = ui32BufferSize <= ui32InBufferExcessSize;
+		if (bHaveEnoughSpace)
+		{
+			IMG_BYTE *pInputBuffer = (IMG_BYTE *)psRGXTDMCreateTransferContextIN;
+
+			pArrayArgsBuffer = &pInputBuffer[ui32InBufferOffset];		}
+		else
+#endif
+		{
+			pArrayArgsBuffer = OSAllocMemNoStats(ui32BufferSize);
+
+			if(!pArrayArgsBuffer)
+			{
+				psRGXTDMCreateTransferContextOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
+				goto RGXTDMCreateTransferContext_exit;
+			}
+		}
+	}
+
+	if (psRGXTDMCreateTransferContextIN->ui32FrameworkCmdize != 0)
+	{
+		psFrameworkCmdInt = (IMG_BYTE*)(((IMG_UINT8 *)pArrayArgsBuffer) + ui32NextOffset);
+		ui32NextOffset += psRGXTDMCreateTransferContextIN->ui32FrameworkCmdize * sizeof(IMG_BYTE);
+	}
+
+			/* Copy the data over */
+			if (psRGXTDMCreateTransferContextIN->ui32FrameworkCmdize * sizeof(IMG_BYTE) > 0)
+			{
+				if ( OSCopyFromUser(NULL, psFrameworkCmdInt, psRGXTDMCreateTransferContextIN->psFrameworkCmd, psRGXTDMCreateTransferContextIN->ui32FrameworkCmdize * sizeof(IMG_BYTE)) != PVRSRV_OK )
+				{
+					psRGXTDMCreateTransferContextOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
+
+					goto RGXTDMCreateTransferContext_exit;
+				}
+			}
+
+	/* Lock over handle lookup. */
+	LockHandle();
+
+
+
+
+
+				{
+					/* Look up the address from the handle */
+					psRGXTDMCreateTransferContextOUT->eError =
+						PVRSRVLookupHandleUnlocked(psConnection->psHandleBase,
+											(void **) &hPrivDataInt,
+											hPrivData,
+											PVRSRV_HANDLE_TYPE_DEV_PRIV_DATA,
+											IMG_TRUE);
+					if(psRGXTDMCreateTransferContextOUT->eError != PVRSRV_OK)
+					{
+						UnlockHandle();
+						goto RGXTDMCreateTransferContext_exit;
+					}
+				}
+	/* Release now we have looked up handles. */
+	UnlockHandle();
+
+	psRGXTDMCreateTransferContextOUT->eError =
+		PVRSRVRGXTDMCreateTransferContextKM(psConnection, OSGetDevData(psConnection),
+					psRGXTDMCreateTransferContextIN->ui32Priority,
+					psRGXTDMCreateTransferContextIN->sMCUFenceAddr,
+					psRGXTDMCreateTransferContextIN->ui32FrameworkCmdize,
+					psFrameworkCmdInt,
+					hPrivDataInt,
+					&psTransferContextInt);
+	/* Exit early if bridged call fails */
+	if(psRGXTDMCreateTransferContextOUT->eError != PVRSRV_OK)
+	{
+		goto RGXTDMCreateTransferContext_exit;
+	}
+
+	/* Lock over handle creation. */
+	LockHandle();
+
+
+
+
+
+	psRGXTDMCreateTransferContextOUT->eError = PVRSRVAllocHandleUnlocked(psConnection->psHandleBase,
+
+							&psRGXTDMCreateTransferContextOUT->hTransferContext,
+							(void *) psTransferContextInt,
+							PVRSRV_HANDLE_TYPE_RGX_SERVER_TQ_TDM_CONTEXT,
+							PVRSRV_HANDLE_ALLOC_FLAG_MULTI
+							,(PFN_HANDLE_RELEASE)&PVRSRVRGXTDMDestroyTransferContextKM);
+	if (psRGXTDMCreateTransferContextOUT->eError != PVRSRV_OK)
+	{
+		UnlockHandle();
+		goto RGXTDMCreateTransferContext_exit;
+	}
+
+	/* Release now we have created handles. */
+	UnlockHandle();
+
+
+
+RGXTDMCreateTransferContext_exit:
+
+	/* Lock over handle lookup cleanup. */
+	LockHandle();
+
+
+
+
+
+
+				{
+					/* Unreference the previously looked up handle */
+						if(hPrivDataInt)
+						{
+							PVRSRVReleaseHandleUnlocked(psConnection->psHandleBase,
+											hPrivData,
+											PVRSRV_HANDLE_TYPE_DEV_PRIV_DATA);
+						}
+				}
+	/* Release now we have cleaned up look up handles. */
+	UnlockHandle();
+
+	if (psRGXTDMCreateTransferContextOUT->eError != PVRSRV_OK)
+	{
+		if (psTransferContextInt)
+		{
+			PVRSRVRGXTDMDestroyTransferContextKM(psTransferContextInt);
+		}
+	}
+
+	/* Allocated space should be equal to the last updated offset */
+	PVR_ASSERT(ui32BufferSize == ui32NextOffset);
+
+#if defined(INTEGRITY_OS)
+	if(pArrayArgsBuffer)
+#else
+	if(!bHaveEnoughSpace && pArrayArgsBuffer)
+#endif
+		OSFreeMemNoStats(pArrayArgsBuffer);
+
+
+	return 0;
+}
+
+
+static IMG_INT
+PVRSRVBridgeRGXTDMDestroyTransferContext(IMG_UINT32 ui32DispatchTableEntry,
+					  PVRSRV_BRIDGE_IN_RGXTDMDESTROYTRANSFERCONTEXT *psRGXTDMDestroyTransferContextIN,
+					  PVRSRV_BRIDGE_OUT_RGXTDMDESTROYTRANSFERCONTEXT *psRGXTDMDestroyTransferContextOUT,
+					 CONNECTION_DATA *psConnection)
+{
+
+
+	{
+		PVRSRV_DEVICE_NODE *psDeviceNode = OSGetDevData(psConnection);
+
+		/* Check that device supports the required feature */
+		if ((psDeviceNode->pfnCheckDeviceFeature) &&
+			!psDeviceNode->pfnCheckDeviceFeature(psDeviceNode, RGX_FEATURE_FASTRENDER_DM_BIT_MASK))
+		{
+			psRGXTDMDestroyTransferContextOUT->eError = PVRSRV_ERROR_NOT_SUPPORTED;
+
+			goto RGXTDMDestroyTransferContext_exit;
+		}
+	}
+
+
+
+
+
+
+
+	/* Lock over handle destruction. */
+	LockHandle();
+
+
+
+
+
+	psRGXTDMDestroyTransferContextOUT->eError =
+		PVRSRVReleaseHandleUnlocked(psConnection->psHandleBase,
+					(IMG_HANDLE) psRGXTDMDestroyTransferContextIN->hTransferContext,
+					PVRSRV_HANDLE_TYPE_RGX_SERVER_TQ_TDM_CONTEXT);
+	if ((psRGXTDMDestroyTransferContextOUT->eError != PVRSRV_OK) &&
+	    (psRGXTDMDestroyTransferContextOUT->eError != PVRSRV_ERROR_RETRY))
+	{
+		PVR_DPF((PVR_DBG_ERROR,
+		        "PVRSRVBridgeRGXTDMDestroyTransferContext: %s",
+		        PVRSRVGetErrorStringKM(psRGXTDMDestroyTransferContextOUT->eError)));
+		PVR_ASSERT(0);
+		UnlockHandle();
+		goto RGXTDMDestroyTransferContext_exit;
+	}
+
+	/* Release now we have destroyed handles. */
+	UnlockHandle();
+
+
+
+RGXTDMDestroyTransferContext_exit:
+
+
+
+
+	return 0;
+}
+
+
+static IMG_INT
+PVRSRVBridgeRGXTDMSubmitTransfer(IMG_UINT32 ui32DispatchTableEntry,
+					  PVRSRV_BRIDGE_IN_RGXTDMSUBMITTRANSFER *psRGXTDMSubmitTransferIN,
+					  PVRSRV_BRIDGE_OUT_RGXTDMSUBMITTRANSFER *psRGXTDMSubmitTransferOUT,
+					 CONNECTION_DATA *psConnection)
+{
+	IMG_HANDLE hTransferContext = psRGXTDMSubmitTransferIN->hTransferContext;
+	RGX_SERVER_TQ_TDM_CONTEXT * psTransferContextInt = NULL;
+	SYNC_PRIMITIVE_BLOCK * *psFenceUFOSyncPrimBlockInt = NULL;
+	IMG_HANDLE *hFenceUFOSyncPrimBlockInt2 = NULL;
+	IMG_UINT32 *ui32FenceSyncOffsetInt = NULL;
+	IMG_UINT32 *ui32FenceValueInt = NULL;
+	SYNC_PRIMITIVE_BLOCK * *psUpdateUFOSyncPrimBlockInt = NULL;
+	IMG_HANDLE *hUpdateUFOSyncPrimBlockInt2 = NULL;
+	IMG_UINT32 *ui32UpdateSyncOffsetInt = NULL;
+	IMG_UINT32 *ui32UpdateValueInt = NULL;
+	IMG_UINT32 *ui32ServerSyncFlagsInt = NULL;
+	SERVER_SYNC_PRIMITIVE * *psServerSyncInt = NULL;
+	IMG_HANDLE *hServerSyncInt2 = NULL;
+	IMG_CHAR *uiUpdateFenceNameInt = NULL;
+	IMG_UINT8 *ui8FWCommandInt = NULL;
+	IMG_UINT32 *ui32SyncPMRFlagsInt = NULL;
+	PMR * *psSyncPMRsInt = NULL;
+	IMG_HANDLE *hSyncPMRsInt2 = NULL;
+
+	IMG_UINT32 ui32NextOffset = 0;
+	IMG_BYTE   *pArrayArgsBuffer = NULL;
+#if !defined(INTEGRITY_OS)
+	IMG_BOOL bHaveEnoughSpace = IMG_FALSE;
+#endif
+
+	IMG_UINT32 ui32BufferSize = 
+			(psRGXTDMSubmitTransferIN->ui32ClientFenceCount * sizeof(SYNC_PRIMITIVE_BLOCK *)) +
+			(psRGXTDMSubmitTransferIN->ui32ClientFenceCount * sizeof(IMG_HANDLE)) +
+			(psRGXTDMSubmitTransferIN->ui32ClientFenceCount * sizeof(IMG_UINT32)) +
+			(psRGXTDMSubmitTransferIN->ui32ClientFenceCount * sizeof(IMG_UINT32)) +
+			(psRGXTDMSubmitTransferIN->ui32ClientUpdateCount * sizeof(SYNC_PRIMITIVE_BLOCK *)) +
+			(psRGXTDMSubmitTransferIN->ui32ClientUpdateCount * sizeof(IMG_HANDLE)) +
+			(psRGXTDMSubmitTransferIN->ui32ClientUpdateCount * sizeof(IMG_UINT32)) +
+			(psRGXTDMSubmitTransferIN->ui32ClientUpdateCount * sizeof(IMG_UINT32)) +
+			(psRGXTDMSubmitTransferIN->ui32ServerSyncCount * sizeof(IMG_UINT32)) +
+			(psRGXTDMSubmitTransferIN->ui32ServerSyncCount * sizeof(SERVER_SYNC_PRIMITIVE *)) +
+			(psRGXTDMSubmitTransferIN->ui32ServerSyncCount * sizeof(IMG_HANDLE)) +
+			(32 * sizeof(IMG_CHAR)) +
+			(psRGXTDMSubmitTransferIN->ui32CommandSize * sizeof(IMG_UINT8)) +
+			(psRGXTDMSubmitTransferIN->ui32SyncPMRCount * sizeof(IMG_UINT32)) +
+			(psRGXTDMSubmitTransferIN->ui32SyncPMRCount * sizeof(PMR *)) +
+			(psRGXTDMSubmitTransferIN->ui32SyncPMRCount * sizeof(IMG_HANDLE)) +
+			0;
+
+	{
+		PVRSRV_DEVICE_NODE *psDeviceNode = OSGetDevData(psConnection);
+
+		/* Check that device supports the required feature */
+		if ((psDeviceNode->pfnCheckDeviceFeature) &&
+			!psDeviceNode->pfnCheckDeviceFeature(psDeviceNode, RGX_FEATURE_FASTRENDER_DM_BIT_MASK))
+		{
+			psRGXTDMSubmitTransferOUT->eError = PVRSRV_ERROR_NOT_SUPPORTED;
+
+			goto RGXTDMSubmitTransfer_exit;
+		}
+	}
+
+
+
+
+	if (ui32BufferSize != 0)
+	{
+#if !defined(INTEGRITY_OS)
+		/* Try to use remainder of input buffer for copies if possible, word-aligned for safety. */
+		IMG_UINT32 ui32InBufferOffset = PVR_ALIGN(sizeof(*psRGXTDMSubmitTransferIN), sizeof(unsigned long));
+		IMG_UINT32 ui32InBufferExcessSize = ui32InBufferOffset >= PVRSRV_MAX_BRIDGE_IN_SIZE ? 0 :
+			PVRSRV_MAX_BRIDGE_IN_SIZE - ui32InBufferOffset;
+
+		bHaveEnoughSpace = ui32BufferSize <= ui32InBufferExcessSize;
+		if (bHaveEnoughSpace)
+		{
+			IMG_BYTE *pInputBuffer = (IMG_BYTE *)psRGXTDMSubmitTransferIN;
+
+			pArrayArgsBuffer = &pInputBuffer[ui32InBufferOffset];		}
+		else
+#endif
+		{
+			pArrayArgsBuffer = OSAllocMemNoStats(ui32BufferSize);
+
+			if(!pArrayArgsBuffer)
+			{
+				psRGXTDMSubmitTransferOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
+				goto RGXTDMSubmitTransfer_exit;
+			}
+		}
+	}
+
+	if (psRGXTDMSubmitTransferIN->ui32ClientFenceCount != 0)
+	{
+		psFenceUFOSyncPrimBlockInt = (SYNC_PRIMITIVE_BLOCK **)(((IMG_UINT8 *)pArrayArgsBuffer) + ui32NextOffset);
+		ui32NextOffset += psRGXTDMSubmitTransferIN->ui32ClientFenceCount * sizeof(SYNC_PRIMITIVE_BLOCK *);
+		hFenceUFOSyncPrimBlockInt2 = (IMG_HANDLE *)(((IMG_UINT8 *)pArrayArgsBuffer) + ui32NextOffset); 
+		ui32NextOffset += psRGXTDMSubmitTransferIN->ui32ClientFenceCount * sizeof(IMG_HANDLE);
+	}
+
+			/* Copy the data over */
+			if (psRGXTDMSubmitTransferIN->ui32ClientFenceCount * sizeof(IMG_HANDLE) > 0)
+			{
+				if ( OSCopyFromUser(NULL, hFenceUFOSyncPrimBlockInt2, psRGXTDMSubmitTransferIN->phFenceUFOSyncPrimBlock, psRGXTDMSubmitTransferIN->ui32ClientFenceCount * sizeof(IMG_HANDLE)) != PVRSRV_OK )
+				{
+					psRGXTDMSubmitTransferOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
+
+					goto RGXTDMSubmitTransfer_exit;
+				}
+			}
+	if (psRGXTDMSubmitTransferIN->ui32ClientFenceCount != 0)
+	{
+		ui32FenceSyncOffsetInt = (IMG_UINT32*)(((IMG_UINT8 *)pArrayArgsBuffer) + ui32NextOffset);
+		ui32NextOffset += psRGXTDMSubmitTransferIN->ui32ClientFenceCount * sizeof(IMG_UINT32);
+	}
+
+			/* Copy the data over */
+			if (psRGXTDMSubmitTransferIN->ui32ClientFenceCount * sizeof(IMG_UINT32) > 0)
+			{
+				if ( OSCopyFromUser(NULL, ui32FenceSyncOffsetInt, psRGXTDMSubmitTransferIN->pui32FenceSyncOffset, psRGXTDMSubmitTransferIN->ui32ClientFenceCount * sizeof(IMG_UINT32)) != PVRSRV_OK )
+				{
+					psRGXTDMSubmitTransferOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
+
+					goto RGXTDMSubmitTransfer_exit;
+				}
+			}
+	if (psRGXTDMSubmitTransferIN->ui32ClientFenceCount != 0)
+	{
+		ui32FenceValueInt = (IMG_UINT32*)(((IMG_UINT8 *)pArrayArgsBuffer) + ui32NextOffset);
+		ui32NextOffset += psRGXTDMSubmitTransferIN->ui32ClientFenceCount * sizeof(IMG_UINT32);
+	}
+
+			/* Copy the data over */
+			if (psRGXTDMSubmitTransferIN->ui32ClientFenceCount * sizeof(IMG_UINT32) > 0)
+			{
+				if ( OSCopyFromUser(NULL, ui32FenceValueInt, psRGXTDMSubmitTransferIN->pui32FenceValue, psRGXTDMSubmitTransferIN->ui32ClientFenceCount * sizeof(IMG_UINT32)) != PVRSRV_OK )
+				{
+					psRGXTDMSubmitTransferOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
+
+					goto RGXTDMSubmitTransfer_exit;
+				}
+			}
+	if (psRGXTDMSubmitTransferIN->ui32ClientUpdateCount != 0)
+	{
+		psUpdateUFOSyncPrimBlockInt = (SYNC_PRIMITIVE_BLOCK **)(((IMG_UINT8 *)pArrayArgsBuffer) + ui32NextOffset);
+		ui32NextOffset += psRGXTDMSubmitTransferIN->ui32ClientUpdateCount * sizeof(SYNC_PRIMITIVE_BLOCK *);
+		hUpdateUFOSyncPrimBlockInt2 = (IMG_HANDLE *)(((IMG_UINT8 *)pArrayArgsBuffer) + ui32NextOffset); 
+		ui32NextOffset += psRGXTDMSubmitTransferIN->ui32ClientUpdateCount * sizeof(IMG_HANDLE);
+	}
+
+			/* Copy the data over */
+			if (psRGXTDMSubmitTransferIN->ui32ClientUpdateCount * sizeof(IMG_HANDLE) > 0)
+			{
+				if ( OSCopyFromUser(NULL, hUpdateUFOSyncPrimBlockInt2, psRGXTDMSubmitTransferIN->phUpdateUFOSyncPrimBlock, psRGXTDMSubmitTransferIN->ui32ClientUpdateCount * sizeof(IMG_HANDLE)) != PVRSRV_OK )
+				{
+					psRGXTDMSubmitTransferOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
+
+					goto RGXTDMSubmitTransfer_exit;
+				}
+			}
+	if (psRGXTDMSubmitTransferIN->ui32ClientUpdateCount != 0)
+	{
+		ui32UpdateSyncOffsetInt = (IMG_UINT32*)(((IMG_UINT8 *)pArrayArgsBuffer) + ui32NextOffset);
+		ui32NextOffset += psRGXTDMSubmitTransferIN->ui32ClientUpdateCount * sizeof(IMG_UINT32);
+	}
+
+			/* Copy the data over */
+			if (psRGXTDMSubmitTransferIN->ui32ClientUpdateCount * sizeof(IMG_UINT32) > 0)
+			{
+				if ( OSCopyFromUser(NULL, ui32UpdateSyncOffsetInt, psRGXTDMSubmitTransferIN->pui32UpdateSyncOffset, psRGXTDMSubmitTransferIN->ui32ClientUpdateCount * sizeof(IMG_UINT32)) != PVRSRV_OK )
+				{
+					psRGXTDMSubmitTransferOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
+
+					goto RGXTDMSubmitTransfer_exit;
+				}
+			}
+	if (psRGXTDMSubmitTransferIN->ui32ClientUpdateCount != 0)
+	{
+		ui32UpdateValueInt = (IMG_UINT32*)(((IMG_UINT8 *)pArrayArgsBuffer) + ui32NextOffset);
+		ui32NextOffset += psRGXTDMSubmitTransferIN->ui32ClientUpdateCount * sizeof(IMG_UINT32);
+	}
+
+			/* Copy the data over */
+			if (psRGXTDMSubmitTransferIN->ui32ClientUpdateCount * sizeof(IMG_UINT32) > 0)
+			{
+				if ( OSCopyFromUser(NULL, ui32UpdateValueInt, psRGXTDMSubmitTransferIN->pui32UpdateValue, psRGXTDMSubmitTransferIN->ui32ClientUpdateCount * sizeof(IMG_UINT32)) != PVRSRV_OK )
+				{
+					psRGXTDMSubmitTransferOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
+
+					goto RGXTDMSubmitTransfer_exit;
+				}
+			}
+	if (psRGXTDMSubmitTransferIN->ui32ServerSyncCount != 0)
+	{
+		ui32ServerSyncFlagsInt = (IMG_UINT32*)(((IMG_UINT8 *)pArrayArgsBuffer) + ui32NextOffset);
+		ui32NextOffset += psRGXTDMSubmitTransferIN->ui32ServerSyncCount * sizeof(IMG_UINT32);
+	}
+
+			/* Copy the data over */
+			if (psRGXTDMSubmitTransferIN->ui32ServerSyncCount * sizeof(IMG_UINT32) > 0)
+			{
+				if ( OSCopyFromUser(NULL, ui32ServerSyncFlagsInt, psRGXTDMSubmitTransferIN->pui32ServerSyncFlags, psRGXTDMSubmitTransferIN->ui32ServerSyncCount * sizeof(IMG_UINT32)) != PVRSRV_OK )
+				{
+					psRGXTDMSubmitTransferOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
+
+					goto RGXTDMSubmitTransfer_exit;
+				}
+			}
+	if (psRGXTDMSubmitTransferIN->ui32ServerSyncCount != 0)
+	{
+		psServerSyncInt = (SERVER_SYNC_PRIMITIVE **)(((IMG_UINT8 *)pArrayArgsBuffer) + ui32NextOffset);
+		ui32NextOffset += psRGXTDMSubmitTransferIN->ui32ServerSyncCount * sizeof(SERVER_SYNC_PRIMITIVE *);
+		hServerSyncInt2 = (IMG_HANDLE *)(((IMG_UINT8 *)pArrayArgsBuffer) + ui32NextOffset); 
+		ui32NextOffset += psRGXTDMSubmitTransferIN->ui32ServerSyncCount * sizeof(IMG_HANDLE);
+	}
+
+			/* Copy the data over */
+			if (psRGXTDMSubmitTransferIN->ui32ServerSyncCount * sizeof(IMG_HANDLE) > 0)
+			{
+				if ( OSCopyFromUser(NULL, hServerSyncInt2, psRGXTDMSubmitTransferIN->phServerSync, psRGXTDMSubmitTransferIN->ui32ServerSyncCount * sizeof(IMG_HANDLE)) != PVRSRV_OK )
+				{
+					psRGXTDMSubmitTransferOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
+
+					goto RGXTDMSubmitTransfer_exit;
+				}
+			}
+	
+	{
+		uiUpdateFenceNameInt = (IMG_CHAR*)(((IMG_UINT8 *)pArrayArgsBuffer) + ui32NextOffset);
+		ui32NextOffset += 32 * sizeof(IMG_CHAR);
+	}
+
+			/* Copy the data over */
+			if (32 * sizeof(IMG_CHAR) > 0)
+			{
+				if ( OSCopyFromUser(NULL, uiUpdateFenceNameInt, psRGXTDMSubmitTransferIN->puiUpdateFenceName, 32 * sizeof(IMG_CHAR)) != PVRSRV_OK )
+				{
+					psRGXTDMSubmitTransferOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
+
+					goto RGXTDMSubmitTransfer_exit;
+				}
+			}
+	if (psRGXTDMSubmitTransferIN->ui32CommandSize != 0)
+	{
+		ui8FWCommandInt = (IMG_UINT8*)(((IMG_UINT8 *)pArrayArgsBuffer) + ui32NextOffset);
+		ui32NextOffset += psRGXTDMSubmitTransferIN->ui32CommandSize * sizeof(IMG_UINT8);
+	}
+
+			/* Copy the data over */
+			if (psRGXTDMSubmitTransferIN->ui32CommandSize * sizeof(IMG_UINT8) > 0)
+			{
+				if ( OSCopyFromUser(NULL, ui8FWCommandInt, psRGXTDMSubmitTransferIN->pui8FWCommand, psRGXTDMSubmitTransferIN->ui32CommandSize * sizeof(IMG_UINT8)) != PVRSRV_OK )
+				{
+					psRGXTDMSubmitTransferOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
+
+					goto RGXTDMSubmitTransfer_exit;
+				}
+			}
+	if (psRGXTDMSubmitTransferIN->ui32SyncPMRCount != 0)
+	{
+		ui32SyncPMRFlagsInt = (IMG_UINT32*)(((IMG_UINT8 *)pArrayArgsBuffer) + ui32NextOffset);
+		ui32NextOffset += psRGXTDMSubmitTransferIN->ui32SyncPMRCount * sizeof(IMG_UINT32);
+	}
+
+			/* Copy the data over */
+			if (psRGXTDMSubmitTransferIN->ui32SyncPMRCount * sizeof(IMG_UINT32) > 0)
+			{
+				if ( OSCopyFromUser(NULL, ui32SyncPMRFlagsInt, psRGXTDMSubmitTransferIN->pui32SyncPMRFlags, psRGXTDMSubmitTransferIN->ui32SyncPMRCount * sizeof(IMG_UINT32)) != PVRSRV_OK )
+				{
+					psRGXTDMSubmitTransferOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
+
+					goto RGXTDMSubmitTransfer_exit;
+				}
+			}
+	if (psRGXTDMSubmitTransferIN->ui32SyncPMRCount != 0)
+	{
+		psSyncPMRsInt = (PMR **)(((IMG_UINT8 *)pArrayArgsBuffer) + ui32NextOffset);
+		ui32NextOffset += psRGXTDMSubmitTransferIN->ui32SyncPMRCount * sizeof(PMR *);
+		hSyncPMRsInt2 = (IMG_HANDLE *)(((IMG_UINT8 *)pArrayArgsBuffer) + ui32NextOffset); 
+		ui32NextOffset += psRGXTDMSubmitTransferIN->ui32SyncPMRCount * sizeof(IMG_HANDLE);
+	}
+
+			/* Copy the data over */
+			if (psRGXTDMSubmitTransferIN->ui32SyncPMRCount * sizeof(IMG_HANDLE) > 0)
+			{
+				if ( OSCopyFromUser(NULL, hSyncPMRsInt2, psRGXTDMSubmitTransferIN->phSyncPMRs, psRGXTDMSubmitTransferIN->ui32SyncPMRCount * sizeof(IMG_HANDLE)) != PVRSRV_OK )
+				{
+					psRGXTDMSubmitTransferOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
+
+					goto RGXTDMSubmitTransfer_exit;
+				}
+			}
+
+	/* Lock over handle lookup. */
+	LockHandle();
+
+
+
+
+
+				{
+					/* Look up the address from the handle */
+					psRGXTDMSubmitTransferOUT->eError =
+						PVRSRVLookupHandleUnlocked(psConnection->psHandleBase,
+											(void **) &psTransferContextInt,
+											hTransferContext,
+											PVRSRV_HANDLE_TYPE_RGX_SERVER_TQ_TDM_CONTEXT,
+											IMG_TRUE);
+					if(psRGXTDMSubmitTransferOUT->eError != PVRSRV_OK)
+					{
+						UnlockHandle();
+						goto RGXTDMSubmitTransfer_exit;
+					}
+				}
+
+
+
+
+
+	{
+		IMG_UINT32 i;
+
+		for (i=0;i<psRGXTDMSubmitTransferIN->ui32ClientFenceCount;i++)
+		{
+				{
+					/* Look up the address from the handle */
+					psRGXTDMSubmitTransferOUT->eError =
+						PVRSRVLookupHandleUnlocked(psConnection->psHandleBase,
+											(void **) &psFenceUFOSyncPrimBlockInt[i],
+											hFenceUFOSyncPrimBlockInt2[i],
+											PVRSRV_HANDLE_TYPE_SYNC_PRIMITIVE_BLOCK,
+											IMG_TRUE);
+					if(psRGXTDMSubmitTransferOUT->eError != PVRSRV_OK)
+					{
+						UnlockHandle();
+						goto RGXTDMSubmitTransfer_exit;
+					}
+				}
+		}
+	}
+
+
+
+
+
+	{
+		IMG_UINT32 i;
+
+		for (i=0;i<psRGXTDMSubmitTransferIN->ui32ClientUpdateCount;i++)
+		{
+				{
+					/* Look up the address from the handle */
+					psRGXTDMSubmitTransferOUT->eError =
+						PVRSRVLookupHandleUnlocked(psConnection->psHandleBase,
+											(void **) &psUpdateUFOSyncPrimBlockInt[i],
+											hUpdateUFOSyncPrimBlockInt2[i],
+											PVRSRV_HANDLE_TYPE_SYNC_PRIMITIVE_BLOCK,
+											IMG_TRUE);
+					if(psRGXTDMSubmitTransferOUT->eError != PVRSRV_OK)
+					{
+						UnlockHandle();
+						goto RGXTDMSubmitTransfer_exit;
+					}
+				}
+		}
+	}
+
+
+
+
+
+	{
+		IMG_UINT32 i;
+
+		for (i=0;i<psRGXTDMSubmitTransferIN->ui32ServerSyncCount;i++)
+		{
+				{
+					/* Look up the address from the handle */
+					psRGXTDMSubmitTransferOUT->eError =
+						PVRSRVLookupHandleUnlocked(psConnection->psHandleBase,
+											(void **) &psServerSyncInt[i],
+											hServerSyncInt2[i],
+											PVRSRV_HANDLE_TYPE_SERVER_SYNC_PRIMITIVE,
+											IMG_TRUE);
+					if(psRGXTDMSubmitTransferOUT->eError != PVRSRV_OK)
+					{
+						UnlockHandle();
+						goto RGXTDMSubmitTransfer_exit;
+					}
+				}
+		}
+	}
+
+
+
+
+
+	{
+		IMG_UINT32 i;
+
+		for (i=0;i<psRGXTDMSubmitTransferIN->ui32SyncPMRCount;i++)
+		{
+				{
+					/* Look up the address from the handle */
+					psRGXTDMSubmitTransferOUT->eError =
+						PVRSRVLookupHandleUnlocked(psConnection->psHandleBase,
+											(void **) &psSyncPMRsInt[i],
+											hSyncPMRsInt2[i],
+											PVRSRV_HANDLE_TYPE_PHYSMEM_PMR,
+											IMG_TRUE);
+					if(psRGXTDMSubmitTransferOUT->eError != PVRSRV_OK)
+					{
+						UnlockHandle();
+						goto RGXTDMSubmitTransfer_exit;
+					}
+				}
+		}
+	}
+	/* Release now we have looked up handles. */
+	UnlockHandle();
+
+	psRGXTDMSubmitTransferOUT->eError =
+		PVRSRVRGXTDMSubmitTransferKM(
+					psTransferContextInt,
+					psRGXTDMSubmitTransferIN->ui32PDumpFlags,
+					psRGXTDMSubmitTransferIN->ui32ClientCacheOpSeqNum,
+					psRGXTDMSubmitTransferIN->ui32ClientFenceCount,
+					psFenceUFOSyncPrimBlockInt,
+					ui32FenceSyncOffsetInt,
+					ui32FenceValueInt,
+					psRGXTDMSubmitTransferIN->ui32ClientUpdateCount,
+					psUpdateUFOSyncPrimBlockInt,
+					ui32UpdateSyncOffsetInt,
+					ui32UpdateValueInt,
+					psRGXTDMSubmitTransferIN->ui32ServerSyncCount,
+					ui32ServerSyncFlagsInt,
+					psServerSyncInt,
+					psRGXTDMSubmitTransferIN->i32CheckFenceFD,
+					psRGXTDMSubmitTransferIN->i32UpdateTimelineFD,
+					&psRGXTDMSubmitTransferOUT->i32UpdateFenceFD,
+					uiUpdateFenceNameInt,
+					psRGXTDMSubmitTransferIN->ui32CommandSize,
+					ui8FWCommandInt,
+					psRGXTDMSubmitTransferIN->ui32ExternalJobReference,
+					psRGXTDMSubmitTransferIN->ui32SyncPMRCount,
+					ui32SyncPMRFlagsInt,
+					psSyncPMRsInt);
+
+
+
+
+RGXTDMSubmitTransfer_exit:
+
+	/* Lock over handle lookup cleanup. */
+	LockHandle();
+
+
+
+
+
+
+				{
+					/* Unreference the previously looked up handle */
+						if(psTransferContextInt)
+						{
+							PVRSRVReleaseHandleUnlocked(psConnection->psHandleBase,
+											hTransferContext,
+											PVRSRV_HANDLE_TYPE_RGX_SERVER_TQ_TDM_CONTEXT);
+						}
+				}
+
+
+
+
+
+
+	if (hFenceUFOSyncPrimBlockInt2)
+	{
+		IMG_UINT32 i;
+
+		for (i=0;i<psRGXTDMSubmitTransferIN->ui32ClientFenceCount;i++)
+		{
+				{
+					/* Unreference the previously looked up handle */
+						if(psFenceUFOSyncPrimBlockInt[i])
+						{
+							PVRSRVReleaseHandleUnlocked(psConnection->psHandleBase,
+											hFenceUFOSyncPrimBlockInt2[i],
+											PVRSRV_HANDLE_TYPE_SYNC_PRIMITIVE_BLOCK);
+						}
+				}
+		}
+	}
+
+
+
+
+
+
+	if (hUpdateUFOSyncPrimBlockInt2)
+	{
+		IMG_UINT32 i;
+
+		for (i=0;i<psRGXTDMSubmitTransferIN->ui32ClientUpdateCount;i++)
+		{
+				{
+					/* Unreference the previously looked up handle */
+						if(psUpdateUFOSyncPrimBlockInt[i])
+						{
+							PVRSRVReleaseHandleUnlocked(psConnection->psHandleBase,
+											hUpdateUFOSyncPrimBlockInt2[i],
+											PVRSRV_HANDLE_TYPE_SYNC_PRIMITIVE_BLOCK);
+						}
+				}
+		}
+	}
+
+
+
+
+
+
+	if (hServerSyncInt2)
+	{
+		IMG_UINT32 i;
+
+		for (i=0;i<psRGXTDMSubmitTransferIN->ui32ServerSyncCount;i++)
+		{
+				{
+					/* Unreference the previously looked up handle */
+						if(psServerSyncInt[i])
+						{
+							PVRSRVReleaseHandleUnlocked(psConnection->psHandleBase,
+											hServerSyncInt2[i],
+											PVRSRV_HANDLE_TYPE_SERVER_SYNC_PRIMITIVE);
+						}
+				}
+		}
+	}
+
+
+
+
+
+
+	if (hSyncPMRsInt2)
+	{
+		IMG_UINT32 i;
+
+		for (i=0;i<psRGXTDMSubmitTransferIN->ui32SyncPMRCount;i++)
+		{
+				{
+					/* Unreference the previously looked up handle */
+						if(psSyncPMRsInt[i])
+						{
+							PVRSRVReleaseHandleUnlocked(psConnection->psHandleBase,
+											hSyncPMRsInt2[i],
+											PVRSRV_HANDLE_TYPE_PHYSMEM_PMR);
+						}
+				}
+		}
+	}
+	/* Release now we have cleaned up look up handles. */
+	UnlockHandle();
+
+	/* Allocated space should be equal to the last updated offset */
+	PVR_ASSERT(ui32BufferSize == ui32NextOffset);
+
+#if defined(INTEGRITY_OS)
+	if(pArrayArgsBuffer)
+#else
+	if(!bHaveEnoughSpace && pArrayArgsBuffer)
+#endif
+		OSFreeMemNoStats(pArrayArgsBuffer);
+
+
+	return 0;
+}
+
+
+static IMG_INT
+PVRSRVBridgeRGXTDMSetTransferContextPriority(IMG_UINT32 ui32DispatchTableEntry,
+					  PVRSRV_BRIDGE_IN_RGXTDMSETTRANSFERCONTEXTPRIORITY *psRGXTDMSetTransferContextPriorityIN,
+					  PVRSRV_BRIDGE_OUT_RGXTDMSETTRANSFERCONTEXTPRIORITY *psRGXTDMSetTransferContextPriorityOUT,
+					 CONNECTION_DATA *psConnection)
+{
+	IMG_HANDLE hTransferContext = psRGXTDMSetTransferContextPriorityIN->hTransferContext;
+	RGX_SERVER_TQ_TDM_CONTEXT * psTransferContextInt = NULL;
+
+
+	{
+		PVRSRV_DEVICE_NODE *psDeviceNode = OSGetDevData(psConnection);
+
+		/* Check that device supports the required feature */
+		if ((psDeviceNode->pfnCheckDeviceFeature) &&
+			!psDeviceNode->pfnCheckDeviceFeature(psDeviceNode, RGX_FEATURE_FASTRENDER_DM_BIT_MASK))
+		{
+			psRGXTDMSetTransferContextPriorityOUT->eError = PVRSRV_ERROR_NOT_SUPPORTED;
+
+			goto RGXTDMSetTransferContextPriority_exit;
+		}
+	}
+
+
+
+
+
+	/* Lock over handle lookup. */
+	LockHandle();
+
+
+
+
+
+				{
+					/* Look up the address from the handle */
+					psRGXTDMSetTransferContextPriorityOUT->eError =
+						PVRSRVLookupHandleUnlocked(psConnection->psHandleBase,
+											(void **) &psTransferContextInt,
+											hTransferContext,
+											PVRSRV_HANDLE_TYPE_RGX_SERVER_TQ_TDM_CONTEXT,
+											IMG_TRUE);
+					if(psRGXTDMSetTransferContextPriorityOUT->eError != PVRSRV_OK)
+					{
+						UnlockHandle();
+						goto RGXTDMSetTransferContextPriority_exit;
+					}
+				}
+	/* Release now we have looked up handles. */
+	UnlockHandle();
+
+	psRGXTDMSetTransferContextPriorityOUT->eError =
+		PVRSRVRGXTDMSetTransferContextPriorityKM(psConnection, OSGetDevData(psConnection),
+					psTransferContextInt,
+					psRGXTDMSetTransferContextPriorityIN->ui32Priority);
+
+
+
+
+RGXTDMSetTransferContextPriority_exit:
+
+	/* Lock over handle lookup cleanup. */
+	LockHandle();
+
+
+
+
+
+
+				{
+					/* Unreference the previously looked up handle */
+						if(psTransferContextInt)
+						{
+							PVRSRVReleaseHandleUnlocked(psConnection->psHandleBase,
+											hTransferContext,
+											PVRSRV_HANDLE_TYPE_RGX_SERVER_TQ_TDM_CONTEXT);
+						}
+				}
+	/* Release now we have cleaned up look up handles. */
+	UnlockHandle();
+
+
+	return 0;
+}
+
+
+static IMG_INT
+PVRSRVBridgeRGXTDMNotifyWriteOffsetUpdate(IMG_UINT32 ui32DispatchTableEntry,
+					  PVRSRV_BRIDGE_IN_RGXTDMNOTIFYWRITEOFFSETUPDATE *psRGXTDMNotifyWriteOffsetUpdateIN,
+					  PVRSRV_BRIDGE_OUT_RGXTDMNOTIFYWRITEOFFSETUPDATE *psRGXTDMNotifyWriteOffsetUpdateOUT,
+					 CONNECTION_DATA *psConnection)
+{
+	IMG_HANDLE hTransferContext = psRGXTDMNotifyWriteOffsetUpdateIN->hTransferContext;
+	RGX_SERVER_TQ_TDM_CONTEXT * psTransferContextInt = NULL;
+
+
+	{
+		PVRSRV_DEVICE_NODE *psDeviceNode = OSGetDevData(psConnection);
+
+		/* Check that device supports the required feature */
+		if ((psDeviceNode->pfnCheckDeviceFeature) &&
+			!psDeviceNode->pfnCheckDeviceFeature(psDeviceNode, RGX_FEATURE_FASTRENDER_DM_BIT_MASK))
+		{
+			psRGXTDMNotifyWriteOffsetUpdateOUT->eError = PVRSRV_ERROR_NOT_SUPPORTED;
+
+			goto RGXTDMNotifyWriteOffsetUpdate_exit;
+		}
+	}
+
+
+
+
+
+	/* Lock over handle lookup. */
+	LockHandle();
+
+
+
+
+
+				{
+					/* Look up the address from the handle */
+					psRGXTDMNotifyWriteOffsetUpdateOUT->eError =
+						PVRSRVLookupHandleUnlocked(psConnection->psHandleBase,
+											(void **) &psTransferContextInt,
+											hTransferContext,
+											PVRSRV_HANDLE_TYPE_RGX_SERVER_TQ_TDM_CONTEXT,
+											IMG_TRUE);
+					if(psRGXTDMNotifyWriteOffsetUpdateOUT->eError != PVRSRV_OK)
+					{
+						UnlockHandle();
+						goto RGXTDMNotifyWriteOffsetUpdate_exit;
+					}
+				}
+	/* Release now we have looked up handles. */
+	UnlockHandle();
+
+	psRGXTDMNotifyWriteOffsetUpdateOUT->eError =
+		PVRSRVRGXTDMNotifyWriteOffsetUpdateKM(
+					psTransferContextInt,
+					psRGXTDMNotifyWriteOffsetUpdateIN->ui32PDumpFlags);
+
+
+
+
+RGXTDMNotifyWriteOffsetUpdate_exit:
+
+	/* Lock over handle lookup cleanup. */
+	LockHandle();
+
+
+
+
+
+
+				{
+					/* Unreference the previously looked up handle */
+						if(psTransferContextInt)
+						{
+							PVRSRVReleaseHandleUnlocked(psConnection->psHandleBase,
+											hTransferContext,
+											PVRSRV_HANDLE_TYPE_RGX_SERVER_TQ_TDM_CONTEXT);
+						}
+				}
+	/* Release now we have cleaned up look up handles. */
+	UnlockHandle();
+
+
+	return 0;
+}
+
+
+
+
+/* *************************************************************************** 
+ * Server bridge dispatch related glue 
+ */
+
+static IMG_BOOL bUseLock = IMG_TRUE;
+
+PVRSRV_ERROR InitRGXTQ2Bridge(void);
+PVRSRV_ERROR DeinitRGXTQ2Bridge(void);
+
+/*
+ * Register all RGXTQ2 functions with services
+ */
+PVRSRV_ERROR InitRGXTQ2Bridge(void)
+{
+
+	SetDispatchTableEntry(PVRSRV_BRIDGE_RGXTQ2, PVRSRV_BRIDGE_RGXTQ2_RGXTDMCREATETRANSFERCONTEXT, PVRSRVBridgeRGXTDMCreateTransferContext,
+					NULL, bUseLock);
+
+	SetDispatchTableEntry(PVRSRV_BRIDGE_RGXTQ2, PVRSRV_BRIDGE_RGXTQ2_RGXTDMDESTROYTRANSFERCONTEXT, PVRSRVBridgeRGXTDMDestroyTransferContext,
+					NULL, bUseLock);
+
+	SetDispatchTableEntry(PVRSRV_BRIDGE_RGXTQ2, PVRSRV_BRIDGE_RGXTQ2_RGXTDMSUBMITTRANSFER, PVRSRVBridgeRGXTDMSubmitTransfer,
+					NULL, bUseLock);
+
+	SetDispatchTableEntry(PVRSRV_BRIDGE_RGXTQ2, PVRSRV_BRIDGE_RGXTQ2_RGXTDMSETTRANSFERCONTEXTPRIORITY, PVRSRVBridgeRGXTDMSetTransferContextPriority,
+					NULL, bUseLock);
+
+	SetDispatchTableEntry(PVRSRV_BRIDGE_RGXTQ2, PVRSRV_BRIDGE_RGXTQ2_RGXTDMNOTIFYWRITEOFFSETUPDATE, PVRSRVBridgeRGXTDMNotifyWriteOffsetUpdate,
+					NULL, bUseLock);
+
+
+	return PVRSRV_OK;
+}
+
+/*
+ * Unregister all rgxtq2 functions with services
+ */
+PVRSRV_ERROR DeinitRGXTQ2Bridge(void)
+{
+	return PVRSRV_OK;
+}
diff --git a/drivers/staging/imgtec/rogue/generated/rgxtq_bridge/common_rgxtq_bridge.h b/drivers/staging/imgtec/rogue/generated/rgxtq_bridge/common_rgxtq_bridge.h
index e8dfde0..899d9b9 100644
--- a/drivers/staging/imgtec/rogue/generated/rgxtq_bridge/common_rgxtq_bridge.h
+++ b/drivers/staging/imgtec/rogue/generated/rgxtq_bridge/common_rgxtq_bridge.h
@@ -2,8 +2,8 @@
 @File
 @Title          Common bridge header for rgxtq
 @Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
-@Description    Declares common defines and structures that are used by both
-                the client and sever side of the bridge for rgxtq
+@Description    Declares common defines and structures used by both the client
+                and server side of the bridge for rgxtq
 @License        Dual MIT/GPLv2
 
 The contents of this file are subject to the MIT license as set out below.
@@ -45,12 +45,13 @@
 #ifndef COMMON_RGXTQ_BRIDGE_H
 #define COMMON_RGXTQ_BRIDGE_H
 
+#include <powervr/mem_types.h>
+
 #include "img_types.h"
 #include "pvrsrv_error.h"
 
 #include "rgx_bridge.h"
-#include "sync_external.h"
-#include "rgx_fwif_shared.h"
+#include <powervr/sync_external.h>
 
 
 #define PVRSRV_BRIDGE_RGXTQ_CMD_FIRST			0
@@ -58,8 +59,7 @@
 #define PVRSRV_BRIDGE_RGXTQ_RGXDESTROYTRANSFERCONTEXT			PVRSRV_BRIDGE_RGXTQ_CMD_FIRST+1
 #define PVRSRV_BRIDGE_RGXTQ_RGXSUBMITTRANSFER			PVRSRV_BRIDGE_RGXTQ_CMD_FIRST+2
 #define PVRSRV_BRIDGE_RGXTQ_RGXSETTRANSFERCONTEXTPRIORITY			PVRSRV_BRIDGE_RGXTQ_CMD_FIRST+3
-#define PVRSRV_BRIDGE_RGXTQ_RGXKICKSYNCTRANSFER			PVRSRV_BRIDGE_RGXTQ_CMD_FIRST+4
-#define PVRSRV_BRIDGE_RGXTQ_CMD_LAST			(PVRSRV_BRIDGE_RGXTQ_CMD_FIRST+4)
+#define PVRSRV_BRIDGE_RGXTQ_CMD_LAST			(PVRSRV_BRIDGE_RGXTQ_CMD_FIRST+3)
 
 
 /*******************************************
@@ -109,6 +109,7 @@
 typedef struct PVRSRV_BRIDGE_IN_RGXSUBMITTRANSFER_TAG
 {
 	IMG_HANDLE hTransferContext;
+	IMG_UINT32 ui32ClientCacheOpSeqNum;
 	IMG_UINT32 ui32PrepareCount;
 	IMG_UINT32 * pui32ClientFenceCount;
 	IMG_HANDLE* * phFenceUFOSyncPrimBlock;
@@ -128,7 +129,6 @@
 	IMG_UINT8* * pui8FWCommand;
 	IMG_UINT32 * pui32TQPrepareFlags;
 	IMG_UINT32 ui32ExtJobRef;
-	IMG_UINT32 ui32IntJobRef;
 	IMG_UINT32 ui32SyncPMRCount;
 	IMG_UINT32 * pui32SyncPMRFlags;
 	IMG_HANDLE * phSyncPMRs;
@@ -160,39 +160,4 @@
 } __attribute__((packed)) PVRSRV_BRIDGE_OUT_RGXSETTRANSFERCONTEXTPRIORITY;
 
 
-/*******************************************
-            RGXKickSyncTransfer          
- *******************************************/
-
-/* Bridge in structure for RGXKickSyncTransfer */
-typedef struct PVRSRV_BRIDGE_IN_RGXKICKSYNCTRANSFER_TAG
-{
-	IMG_HANDLE hTransferContext;
-	IMG_UINT32 ui32ClientFenceCount;
-	IMG_HANDLE * phClientFenceUFOSyncPrimBlock;
-	IMG_UINT32 * pui32ClientFenceSyncOffset;
-	IMG_UINT32 * pui32ClientFenceValue;
-	IMG_UINT32 ui32ClientUpdateCount;
-	IMG_HANDLE * phClientUpdateUFOSyncPrimBlock;
-	IMG_UINT32 * pui32ClientUpdateSyncOffset;
-	IMG_UINT32 * pui32ClientUpdateValue;
-	IMG_UINT32 ui32ServerSyncCount;
-	IMG_UINT32 * pui32ServerSyncFlags;
-	IMG_HANDLE * phServerSyncs;
-	IMG_INT32 i32CheckFenceFD;
-	IMG_INT32 i32UpdateTimelineFD;
-	IMG_CHAR * puiUpdateFenceName;
-	IMG_UINT32 ui32TQPrepareFlags;
-	IMG_UINT32 ui32ExtJobRef;
-	IMG_UINT32 ui32IntJobRef;
-} __attribute__((packed)) PVRSRV_BRIDGE_IN_RGXKICKSYNCTRANSFER;
-
-/* Bridge out structure for RGXKickSyncTransfer */
-typedef struct PVRSRV_BRIDGE_OUT_RGXKICKSYNCTRANSFER_TAG
-{
-	IMG_INT32 i32UpdateFenceFD;
-	PVRSRV_ERROR eError;
-} __attribute__((packed)) PVRSRV_BRIDGE_OUT_RGXKICKSYNCTRANSFER;
-
-
 #endif /* COMMON_RGXTQ_BRIDGE_H */
diff --git a/drivers/staging/imgtec/rogue/generated/rgxtq_bridge/server_rgxtq_bridge.c b/drivers/staging/imgtec/rogue/generated/rgxtq_bridge/server_rgxtq_bridge.c
index 87b1554..f9d5370 100644
--- a/drivers/staging/imgtec/rogue/generated/rgxtq_bridge/server_rgxtq_bridge.c
+++ b/drivers/staging/imgtec/rogue/generated/rgxtq_bridge/server_rgxtq_bridge.c
@@ -64,6 +64,8 @@
 
 
 
+
+
 /* ***************************************************************************
  * Server-side bridge entry points
  */
@@ -75,50 +77,91 @@
 					 CONNECTION_DATA *psConnection)
 {
 	IMG_BYTE *psFrameworkCmdInt = NULL;
+	IMG_HANDLE hPrivData = psRGXCreateTransferContextIN->hPrivData;
 	IMG_HANDLE hPrivDataInt = NULL;
 	RGX_SERVER_TQ_CONTEXT * psTransferContextInt = NULL;
 
+	IMG_UINT32 ui32NextOffset = 0;
+	IMG_BYTE   *pArrayArgsBuffer = NULL;
+#if !defined(INTEGRITY_OS)
+	IMG_BOOL bHaveEnoughSpace = IMG_FALSE;
+#endif
+
+	IMG_UINT32 ui32BufferSize = 
+			(psRGXCreateTransferContextIN->ui32FrameworkCmdize * sizeof(IMG_BYTE)) +
+			0;
 
 
 
-	if (psRGXCreateTransferContextIN->ui32FrameworkCmdize != 0)
+
+
+	if (ui32BufferSize != 0)
 	{
-		psFrameworkCmdInt = OSAllocMemNoStats(psRGXCreateTransferContextIN->ui32FrameworkCmdize * sizeof(IMG_BYTE));
-		if (!psFrameworkCmdInt)
+#if !defined(INTEGRITY_OS)
+		/* Try to use remainder of input buffer for copies if possible, word-aligned for safety. */
+		IMG_UINT32 ui32InBufferOffset = PVR_ALIGN(sizeof(*psRGXCreateTransferContextIN), sizeof(unsigned long));
+		IMG_UINT32 ui32InBufferExcessSize = ui32InBufferOffset >= PVRSRV_MAX_BRIDGE_IN_SIZE ? 0 :
+			PVRSRV_MAX_BRIDGE_IN_SIZE - ui32InBufferOffset;
+
+		bHaveEnoughSpace = ui32BufferSize <= ui32InBufferExcessSize;
+		if (bHaveEnoughSpace)
 		{
-			psRGXCreateTransferContextOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
-	
-			goto RGXCreateTransferContext_exit;
+			IMG_BYTE *pInputBuffer = (IMG_BYTE *)psRGXCreateTransferContextIN;
+
+			pArrayArgsBuffer = &pInputBuffer[ui32InBufferOffset];		}
+		else
+#endif
+		{
+			pArrayArgsBuffer = OSAllocMemNoStats(ui32BufferSize);
+
+			if(!pArrayArgsBuffer)
+			{
+				psRGXCreateTransferContextOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
+				goto RGXCreateTransferContext_exit;
+			}
 		}
 	}
 
-			/* Copy the data over */
-			if ( !OSAccessOK(PVR_VERIFY_READ, (void*) psRGXCreateTransferContextIN->psFrameworkCmd, psRGXCreateTransferContextIN->ui32FrameworkCmdize * sizeof(IMG_BYTE))
-				|| (OSCopyFromUser(NULL, psFrameworkCmdInt, psRGXCreateTransferContextIN->psFrameworkCmd,
-				psRGXCreateTransferContextIN->ui32FrameworkCmdize * sizeof(IMG_BYTE)) != PVRSRV_OK) )
-			{
-				psRGXCreateTransferContextOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
+	if (psRGXCreateTransferContextIN->ui32FrameworkCmdize != 0)
+	{
+		psFrameworkCmdInt = (IMG_BYTE*)(((IMG_UINT8 *)pArrayArgsBuffer) + ui32NextOffset);
+		ui32NextOffset += psRGXCreateTransferContextIN->ui32FrameworkCmdize * sizeof(IMG_BYTE);
+	}
 
-				goto RGXCreateTransferContext_exit;
+			/* Copy the data over */
+			if (psRGXCreateTransferContextIN->ui32FrameworkCmdize * sizeof(IMG_BYTE) > 0)
+			{
+				if ( OSCopyFromUser(NULL, psFrameworkCmdInt, psRGXCreateTransferContextIN->psFrameworkCmd, psRGXCreateTransferContextIN->ui32FrameworkCmdize * sizeof(IMG_BYTE)) != PVRSRV_OK )
+				{
+					psRGXCreateTransferContextOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
+
+					goto RGXCreateTransferContext_exit;
+				}
 			}
 
-	PMRLock();
+	/* Lock over handle lookup. */
+	LockHandle();
+
+
+
 
 
 				{
 					/* Look up the address from the handle */
 					psRGXCreateTransferContextOUT->eError =
-						PVRSRVLookupHandle(psConnection->psHandleBase,
+						PVRSRVLookupHandleUnlocked(psConnection->psHandleBase,
 											(void **) &hPrivDataInt,
-											psRGXCreateTransferContextIN->hPrivData,
-											PVRSRV_HANDLE_TYPE_DEV_PRIV_DATA);
+											hPrivData,
+											PVRSRV_HANDLE_TYPE_DEV_PRIV_DATA,
+											IMG_TRUE);
 					if(psRGXCreateTransferContextOUT->eError != PVRSRV_OK)
 					{
-						PMRUnlock();
+						UnlockHandle();
 						goto RGXCreateTransferContext_exit;
 					}
 				}
-
+	/* Release now we have looked up handles. */
+	UnlockHandle();
 
 	psRGXCreateTransferContextOUT->eError =
 		PVRSRVRGXCreateTransferContextKM(psConnection, OSGetDevData(psConnection),
@@ -131,13 +174,18 @@
 	/* Exit early if bridged call fails */
 	if(psRGXCreateTransferContextOUT->eError != PVRSRV_OK)
 	{
-		PMRUnlock();
 		goto RGXCreateTransferContext_exit;
 	}
-	PMRUnlock();
+
+	/* Lock over handle creation. */
+	LockHandle();
 
 
-	psRGXCreateTransferContextOUT->eError = PVRSRVAllocHandle(psConnection->psHandleBase,
+
+
+
+	psRGXCreateTransferContextOUT->eError = PVRSRVAllocHandleUnlocked(psConnection->psHandleBase,
+
 							&psRGXCreateTransferContextOUT->hTransferContext,
 							(void *) psTransferContextInt,
 							PVRSRV_HANDLE_TYPE_RGX_SERVER_TQ_CONTEXT,
@@ -145,13 +193,37 @@
 							,(PFN_HANDLE_RELEASE)&PVRSRVRGXDestroyTransferContextKM);
 	if (psRGXCreateTransferContextOUT->eError != PVRSRV_OK)
 	{
+		UnlockHandle();
 		goto RGXCreateTransferContext_exit;
 	}
 
+	/* Release now we have created handles. */
+	UnlockHandle();
 
 
 
 RGXCreateTransferContext_exit:
+
+	/* Lock over handle lookup cleanup. */
+	LockHandle();
+
+
+
+
+
+
+				{
+					/* Unreference the previously looked up handle */
+						if(hPrivDataInt)
+						{
+							PVRSRVReleaseHandleUnlocked(psConnection->psHandleBase,
+											hPrivData,
+											PVRSRV_HANDLE_TYPE_DEV_PRIV_DATA);
+						}
+				}
+	/* Release now we have cleaned up look up handles. */
+	UnlockHandle();
+
 	if (psRGXCreateTransferContextOUT->eError != PVRSRV_OK)
 	{
 		if (psTransferContextInt)
@@ -160,12 +232,21 @@
 		}
 	}
 
-	if (psFrameworkCmdInt)
-		OSFreeMemNoStats(psFrameworkCmdInt);
+	/* Allocated space should be equal to the last updated offset */
+	PVR_ASSERT(ui32BufferSize == ui32NextOffset);
+
+#if defined(INTEGRITY_OS)
+	if(pArrayArgsBuffer)
+#else
+	if(!bHaveEnoughSpace && pArrayArgsBuffer)
+#endif
+		OSFreeMemNoStats(pArrayArgsBuffer);
+
 
 	return 0;
 }
 
+
 static IMG_INT
 PVRSRVBridgeRGXDestroyTransferContext(IMG_UINT32 ui32DispatchTableEntry,
 					  PVRSRV_BRIDGE_IN_RGXDESTROYTRANSFERCONTEXT *psRGXDestroyTransferContextIN,
@@ -177,36 +258,53 @@
 
 
 
-	PMRLock();
+
+
+
+
+	/* Lock over handle destruction. */
+	LockHandle();
+
 
 
 
 
 	psRGXDestroyTransferContextOUT->eError =
-		PVRSRVReleaseHandle(psConnection->psHandleBase,
+		PVRSRVReleaseHandleUnlocked(psConnection->psHandleBase,
 					(IMG_HANDLE) psRGXDestroyTransferContextIN->hTransferContext,
 					PVRSRV_HANDLE_TYPE_RGX_SERVER_TQ_CONTEXT);
-	if ((psRGXDestroyTransferContextOUT->eError != PVRSRV_OK) && (psRGXDestroyTransferContextOUT->eError != PVRSRV_ERROR_RETRY))
+	if ((psRGXDestroyTransferContextOUT->eError != PVRSRV_OK) &&
+	    (psRGXDestroyTransferContextOUT->eError != PVRSRV_ERROR_RETRY))
 	{
+		PVR_DPF((PVR_DBG_ERROR,
+		        "PVRSRVBridgeRGXDestroyTransferContext: %s",
+		        PVRSRVGetErrorStringKM(psRGXDestroyTransferContextOUT->eError)));
 		PVR_ASSERT(0);
-		PMRUnlock();
+		UnlockHandle();
 		goto RGXDestroyTransferContext_exit;
 	}
 
-	PMRUnlock();
+	/* Release now we have destroyed handles. */
+	UnlockHandle();
+
 
 
 RGXDestroyTransferContext_exit:
 
+
+
+
 	return 0;
 }
 
+
 static IMG_INT
 PVRSRVBridgeRGXSubmitTransfer(IMG_UINT32 ui32DispatchTableEntry,
 					  PVRSRV_BRIDGE_IN_RGXSUBMITTRANSFER *psRGXSubmitTransferIN,
 					  PVRSRV_BRIDGE_OUT_RGXSUBMITTRANSFER *psRGXSubmitTransferOUT,
 					 CONNECTION_DATA *psConnection)
 {
+	IMG_HANDLE hTransferContext = psRGXSubmitTransferIN->hTransferContext;
 	RGX_SERVER_TQ_CONTEXT * psTransferContextInt = NULL;
 	IMG_UINT32 *ui32ClientFenceCountInt = NULL;
 	SYNC_PRIMITIVE_BLOCK * **psFenceUFOSyncPrimBlockInt = NULL;
@@ -230,91 +328,492 @@
 	PMR * *psSyncPMRsInt = NULL;
 	IMG_HANDLE *hSyncPMRsInt2 = NULL;
 
+	IMG_UINT32 ui32NextOffset = 0;
+	IMG_BYTE   *pArrayArgsBuffer = NULL;
+	IMG_BYTE   *pArrayArgsBuffer2 = NULL;
+#if !defined(INTEGRITY_OS)
+	IMG_BOOL bHaveEnoughSpace = IMG_FALSE;
+#endif
 
-
+	IMG_UINT32 ui32BufferSize = 
+			(psRGXSubmitTransferIN->ui32PrepareCount * sizeof(IMG_UINT32)) +
+			(psRGXSubmitTransferIN->ui32PrepareCount * sizeof(IMG_UINT32)) +
+			(psRGXSubmitTransferIN->ui32PrepareCount * sizeof(IMG_UINT32)) +
+			(32 * sizeof(IMG_CHAR)) +
+			(psRGXSubmitTransferIN->ui32PrepareCount * sizeof(IMG_UINT32)) +
+			(psRGXSubmitTransferIN->ui32PrepareCount * sizeof(IMG_UINT32)) +
+			(psRGXSubmitTransferIN->ui32SyncPMRCount * sizeof(IMG_UINT32)) +
+			(psRGXSubmitTransferIN->ui32SyncPMRCount * sizeof(PMR *)) +
+			(psRGXSubmitTransferIN->ui32SyncPMRCount * sizeof(IMG_HANDLE)) +
+			0;
+	IMG_UINT32 ui32BufferSize2 = 0;
+	IMG_UINT32 ui32NextOffset2 = 0;
 
 	if (psRGXSubmitTransferIN->ui32PrepareCount != 0)
 	{
-		ui32ClientFenceCountInt = OSAllocMemNoStats(psRGXSubmitTransferIN->ui32PrepareCount * sizeof(IMG_UINT32));
-		if (!ui32ClientFenceCountInt)
+
+		ui32BufferSize += psRGXSubmitTransferIN->ui32PrepareCount * sizeof(SYNC_PRIMITIVE_BLOCK **);
+		ui32BufferSize += psRGXSubmitTransferIN->ui32PrepareCount * sizeof(IMG_HANDLE **);
+		ui32BufferSize += psRGXSubmitTransferIN->ui32PrepareCount * sizeof(IMG_UINT32*);
+		ui32BufferSize += psRGXSubmitTransferIN->ui32PrepareCount * sizeof(IMG_UINT32*);
+		ui32BufferSize += psRGXSubmitTransferIN->ui32PrepareCount * sizeof(SYNC_PRIMITIVE_BLOCK **);
+		ui32BufferSize += psRGXSubmitTransferIN->ui32PrepareCount * sizeof(IMG_HANDLE **);
+		ui32BufferSize += psRGXSubmitTransferIN->ui32PrepareCount * sizeof(IMG_UINT32*);
+		ui32BufferSize += psRGXSubmitTransferIN->ui32PrepareCount * sizeof(IMG_UINT32*);
+		ui32BufferSize += psRGXSubmitTransferIN->ui32PrepareCount * sizeof(IMG_UINT32*);
+		ui32BufferSize += psRGXSubmitTransferIN->ui32PrepareCount * sizeof(SERVER_SYNC_PRIMITIVE **);
+		ui32BufferSize += psRGXSubmitTransferIN->ui32PrepareCount * sizeof(IMG_HANDLE **);
+		ui32BufferSize += psRGXSubmitTransferIN->ui32PrepareCount * sizeof(IMG_UINT8*);
+	}
+
+
+
+
+
+
+	if (ui32BufferSize != 0)
+	{
+#if !defined(INTEGRITY_OS)
+		/* Try to use remainder of input buffer for copies if possible, word-aligned for safety. */
+		IMG_UINT32 ui32InBufferOffset = PVR_ALIGN(sizeof(*psRGXSubmitTransferIN), sizeof(unsigned long));
+		IMG_UINT32 ui32InBufferExcessSize = ui32InBufferOffset >= PVRSRV_MAX_BRIDGE_IN_SIZE ? 0 :
+			PVRSRV_MAX_BRIDGE_IN_SIZE - ui32InBufferOffset;
+
+		bHaveEnoughSpace = ui32BufferSize <= ui32InBufferExcessSize;
+		if (bHaveEnoughSpace)
+		{
+			IMG_BYTE *pInputBuffer = (IMG_BYTE *)psRGXSubmitTransferIN;
+
+			pArrayArgsBuffer = &pInputBuffer[ui32InBufferOffset];		}
+		else
+#endif
+		{
+			pArrayArgsBuffer = OSAllocMemNoStats(ui32BufferSize);
+
+			if(!pArrayArgsBuffer)
+			{
+				psRGXSubmitTransferOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
+				goto RGXSubmitTransfer_exit;
+			}
+		}
+	}
+
+	if (psRGXSubmitTransferIN->ui32PrepareCount != 0)
+	{
+		ui32ClientFenceCountInt = (IMG_UINT32*)(((IMG_UINT8 *)pArrayArgsBuffer) + ui32NextOffset);
+		ui32NextOffset += psRGXSubmitTransferIN->ui32PrepareCount * sizeof(IMG_UINT32);
+	}
+
+			/* Copy the data over */
+			if (psRGXSubmitTransferIN->ui32PrepareCount * sizeof(IMG_UINT32) > 0)
+			{
+				if ( OSCopyFromUser(NULL, ui32ClientFenceCountInt, psRGXSubmitTransferIN->pui32ClientFenceCount, psRGXSubmitTransferIN->ui32PrepareCount * sizeof(IMG_UINT32)) != PVRSRV_OK )
+				{
+					psRGXSubmitTransferOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
+
+					goto RGXSubmitTransfer_exit;
+				}
+			}
+	if (psRGXSubmitTransferIN->ui32PrepareCount != 0)
+	{
+		/* Assigning psFenceUFOSyncPrimBlockInt to the right offset in the pool buffer for first dimension */
+		psFenceUFOSyncPrimBlockInt = (SYNC_PRIMITIVE_BLOCK ***)(((IMG_UINT8 *)pArrayArgsBuffer) + ui32NextOffset);
+		ui32NextOffset += psRGXSubmitTransferIN->ui32PrepareCount * sizeof(SYNC_PRIMITIVE_BLOCK **);
+		/* Assigning hFenceUFOSyncPrimBlockInt2 to the right offset in the pool buffer for first dimension */
+		hFenceUFOSyncPrimBlockInt2 = (IMG_HANDLE **)(((IMG_UINT8 *)pArrayArgsBuffer) + ui32NextOffset); 
+		ui32NextOffset += psRGXSubmitTransferIN->ui32PrepareCount * sizeof(IMG_HANDLE);
+	}
+
+	if (psRGXSubmitTransferIN->ui32PrepareCount != 0)
+	{
+		/* Assigning ui32FenceSyncOffsetInt to the right offset in the pool buffer for first dimension */
+		ui32FenceSyncOffsetInt = (IMG_UINT32**)(((IMG_UINT8 *)pArrayArgsBuffer) + ui32NextOffset);
+		ui32NextOffset += psRGXSubmitTransferIN->ui32PrepareCount * sizeof(IMG_UINT32*);
+	}
+
+	if (psRGXSubmitTransferIN->ui32PrepareCount != 0)
+	{
+		/* Assigning ui32FenceValueInt to the right offset in the pool buffer for first dimension */
+		ui32FenceValueInt = (IMG_UINT32**)(((IMG_UINT8 *)pArrayArgsBuffer) + ui32NextOffset);
+		ui32NextOffset += psRGXSubmitTransferIN->ui32PrepareCount * sizeof(IMG_UINT32*);
+	}
+
+	if (psRGXSubmitTransferIN->ui32PrepareCount != 0)
+	{
+		ui32ClientUpdateCountInt = (IMG_UINT32*)(((IMG_UINT8 *)pArrayArgsBuffer) + ui32NextOffset);
+		ui32NextOffset += psRGXSubmitTransferIN->ui32PrepareCount * sizeof(IMG_UINT32);
+	}
+
+			/* Copy the data over */
+			if (psRGXSubmitTransferIN->ui32PrepareCount * sizeof(IMG_UINT32) > 0)
+			{
+				if ( OSCopyFromUser(NULL, ui32ClientUpdateCountInt, psRGXSubmitTransferIN->pui32ClientUpdateCount, psRGXSubmitTransferIN->ui32PrepareCount * sizeof(IMG_UINT32)) != PVRSRV_OK )
+				{
+					psRGXSubmitTransferOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
+
+					goto RGXSubmitTransfer_exit;
+				}
+			}
+	if (psRGXSubmitTransferIN->ui32PrepareCount != 0)
+	{
+		/* Assigning psUpdateUFOSyncPrimBlockInt to the right offset in the pool buffer for first dimension */
+		psUpdateUFOSyncPrimBlockInt = (SYNC_PRIMITIVE_BLOCK ***)(((IMG_UINT8 *)pArrayArgsBuffer) + ui32NextOffset);
+		ui32NextOffset += psRGXSubmitTransferIN->ui32PrepareCount * sizeof(SYNC_PRIMITIVE_BLOCK **);
+		/* Assigning hUpdateUFOSyncPrimBlockInt2 to the right offset in the pool buffer for first dimension */
+		hUpdateUFOSyncPrimBlockInt2 = (IMG_HANDLE **)(((IMG_UINT8 *)pArrayArgsBuffer) + ui32NextOffset); 
+		ui32NextOffset += psRGXSubmitTransferIN->ui32PrepareCount * sizeof(IMG_HANDLE);
+	}
+
+	if (psRGXSubmitTransferIN->ui32PrepareCount != 0)
+	{
+		/* Assigning ui32UpdateSyncOffsetInt to the right offset in the pool buffer for first dimension */
+		ui32UpdateSyncOffsetInt = (IMG_UINT32**)(((IMG_UINT8 *)pArrayArgsBuffer) + ui32NextOffset);
+		ui32NextOffset += psRGXSubmitTransferIN->ui32PrepareCount * sizeof(IMG_UINT32*);
+	}
+
+	if (psRGXSubmitTransferIN->ui32PrepareCount != 0)
+	{
+		/* Assigning ui32UpdateValueInt to the right offset in the pool buffer for first dimension */
+		ui32UpdateValueInt = (IMG_UINT32**)(((IMG_UINT8 *)pArrayArgsBuffer) + ui32NextOffset);
+		ui32NextOffset += psRGXSubmitTransferIN->ui32PrepareCount * sizeof(IMG_UINT32*);
+	}
+
+	if (psRGXSubmitTransferIN->ui32PrepareCount != 0)
+	{
+		ui32ServerSyncCountInt = (IMG_UINT32*)(((IMG_UINT8 *)pArrayArgsBuffer) + ui32NextOffset);
+		ui32NextOffset += psRGXSubmitTransferIN->ui32PrepareCount * sizeof(IMG_UINT32);
+	}
+
+			/* Copy the data over */
+			if (psRGXSubmitTransferIN->ui32PrepareCount * sizeof(IMG_UINT32) > 0)
+			{
+				if ( OSCopyFromUser(NULL, ui32ServerSyncCountInt, psRGXSubmitTransferIN->pui32ServerSyncCount, psRGXSubmitTransferIN->ui32PrepareCount * sizeof(IMG_UINT32)) != PVRSRV_OK )
+				{
+					psRGXSubmitTransferOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
+
+					goto RGXSubmitTransfer_exit;
+				}
+			}
+	if (psRGXSubmitTransferIN->ui32PrepareCount != 0)
+	{
+		/* Assigning ui32ServerSyncFlagsInt to the right offset in the pool buffer for first dimension */
+		ui32ServerSyncFlagsInt = (IMG_UINT32**)(((IMG_UINT8 *)pArrayArgsBuffer) + ui32NextOffset);
+		ui32NextOffset += psRGXSubmitTransferIN->ui32PrepareCount * sizeof(IMG_UINT32*);
+	}
+
+	if (psRGXSubmitTransferIN->ui32PrepareCount != 0)
+	{
+		/* Assigning psServerSyncInt to the right offset in the pool buffer for first dimension */
+		psServerSyncInt = (SERVER_SYNC_PRIMITIVE ***)(((IMG_UINT8 *)pArrayArgsBuffer) + ui32NextOffset);
+		ui32NextOffset += psRGXSubmitTransferIN->ui32PrepareCount * sizeof(SERVER_SYNC_PRIMITIVE **);
+		/* Assigning hServerSyncInt2 to the right offset in the pool buffer for first dimension */
+		hServerSyncInt2 = (IMG_HANDLE **)(((IMG_UINT8 *)pArrayArgsBuffer) + ui32NextOffset); 
+		ui32NextOffset += psRGXSubmitTransferIN->ui32PrepareCount * sizeof(IMG_HANDLE);
+	}
+
+	
+	{
+		uiUpdateFenceNameInt = (IMG_CHAR*)(((IMG_UINT8 *)pArrayArgsBuffer) + ui32NextOffset);
+		ui32NextOffset += 32 * sizeof(IMG_CHAR);
+	}
+
+			/* Copy the data over */
+			if (32 * sizeof(IMG_CHAR) > 0)
+			{
+				if ( OSCopyFromUser(NULL, uiUpdateFenceNameInt, psRGXSubmitTransferIN->puiUpdateFenceName, 32 * sizeof(IMG_CHAR)) != PVRSRV_OK )
+				{
+					psRGXSubmitTransferOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
+
+					goto RGXSubmitTransfer_exit;
+				}
+			}
+	if (psRGXSubmitTransferIN->ui32PrepareCount != 0)
+	{
+		ui32CommandSizeInt = (IMG_UINT32*)(((IMG_UINT8 *)pArrayArgsBuffer) + ui32NextOffset);
+		ui32NextOffset += psRGXSubmitTransferIN->ui32PrepareCount * sizeof(IMG_UINT32);
+	}
+
+			/* Copy the data over */
+			if (psRGXSubmitTransferIN->ui32PrepareCount * sizeof(IMG_UINT32) > 0)
+			{
+				if ( OSCopyFromUser(NULL, ui32CommandSizeInt, psRGXSubmitTransferIN->pui32CommandSize, psRGXSubmitTransferIN->ui32PrepareCount * sizeof(IMG_UINT32)) != PVRSRV_OK )
+				{
+					psRGXSubmitTransferOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
+
+					goto RGXSubmitTransfer_exit;
+				}
+			}
+	if (psRGXSubmitTransferIN->ui32PrepareCount != 0)
+	{
+		/* Assigning ui8FWCommandInt to the right offset in the pool buffer for first dimension */
+		ui8FWCommandInt = (IMG_UINT8**)(((IMG_UINT8 *)pArrayArgsBuffer) + ui32NextOffset);
+		ui32NextOffset += psRGXSubmitTransferIN->ui32PrepareCount * sizeof(IMG_UINT8*);
+	}
+
+	if (psRGXSubmitTransferIN->ui32PrepareCount != 0)
+	{
+		ui32TQPrepareFlagsInt = (IMG_UINT32*)(((IMG_UINT8 *)pArrayArgsBuffer) + ui32NextOffset);
+		ui32NextOffset += psRGXSubmitTransferIN->ui32PrepareCount * sizeof(IMG_UINT32);
+	}
+
+			/* Copy the data over */
+			if (psRGXSubmitTransferIN->ui32PrepareCount * sizeof(IMG_UINT32) > 0)
+			{
+				if ( OSCopyFromUser(NULL, ui32TQPrepareFlagsInt, psRGXSubmitTransferIN->pui32TQPrepareFlags, psRGXSubmitTransferIN->ui32PrepareCount * sizeof(IMG_UINT32)) != PVRSRV_OK )
+				{
+					psRGXSubmitTransferOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
+
+					goto RGXSubmitTransfer_exit;
+				}
+			}
+	if (psRGXSubmitTransferIN->ui32SyncPMRCount != 0)
+	{
+		ui32SyncPMRFlagsInt = (IMG_UINT32*)(((IMG_UINT8 *)pArrayArgsBuffer) + ui32NextOffset);
+		ui32NextOffset += psRGXSubmitTransferIN->ui32SyncPMRCount * sizeof(IMG_UINT32);
+	}
+
+			/* Copy the data over */
+			if (psRGXSubmitTransferIN->ui32SyncPMRCount * sizeof(IMG_UINT32) > 0)
+			{
+				if ( OSCopyFromUser(NULL, ui32SyncPMRFlagsInt, psRGXSubmitTransferIN->pui32SyncPMRFlags, psRGXSubmitTransferIN->ui32SyncPMRCount * sizeof(IMG_UINT32)) != PVRSRV_OK )
+				{
+					psRGXSubmitTransferOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
+
+					goto RGXSubmitTransfer_exit;
+				}
+			}
+	if (psRGXSubmitTransferIN->ui32SyncPMRCount != 0)
+	{
+		psSyncPMRsInt = (PMR **)(((IMG_UINT8 *)pArrayArgsBuffer) + ui32NextOffset);
+		ui32NextOffset += psRGXSubmitTransferIN->ui32SyncPMRCount * sizeof(PMR *);
+		hSyncPMRsInt2 = (IMG_HANDLE *)(((IMG_UINT8 *)pArrayArgsBuffer) + ui32NextOffset); 
+		ui32NextOffset += psRGXSubmitTransferIN->ui32SyncPMRCount * sizeof(IMG_HANDLE);
+	}
+
+			/* Copy the data over */
+			if (psRGXSubmitTransferIN->ui32SyncPMRCount * sizeof(IMG_HANDLE) > 0)
+			{
+				if ( OSCopyFromUser(NULL, hSyncPMRsInt2, psRGXSubmitTransferIN->phSyncPMRs, psRGXSubmitTransferIN->ui32SyncPMRCount * sizeof(IMG_HANDLE)) != PVRSRV_OK )
+				{
+					psRGXSubmitTransferOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
+
+					goto RGXSubmitTransfer_exit;
+				}
+			}
+
+	if (psRGXSubmitTransferIN->ui32PrepareCount != 0)
+	{
+		IMG_UINT32 i;
+		for (i = 0; i < psRGXSubmitTransferIN->ui32PrepareCount; i++)
+		{
+			ui32BufferSize2 += ui32ClientFenceCountInt[i] * sizeof(SYNC_PRIMITIVE_BLOCK *);
+			ui32BufferSize2 += ui32ClientFenceCountInt[i] * sizeof(IMG_HANDLE *);
+			ui32BufferSize2 += ui32ClientFenceCountInt[i] * sizeof(IMG_UINT32);
+			ui32BufferSize2 += ui32ClientFenceCountInt[i] * sizeof(IMG_UINT32);
+			ui32BufferSize2 += ui32ClientUpdateCountInt[i] * sizeof(SYNC_PRIMITIVE_BLOCK *);
+			ui32BufferSize2 += ui32ClientUpdateCountInt[i] * sizeof(IMG_HANDLE *);
+			ui32BufferSize2 += ui32ClientUpdateCountInt[i] * sizeof(IMG_UINT32);
+			ui32BufferSize2 += ui32ClientUpdateCountInt[i] * sizeof(IMG_UINT32);
+			ui32BufferSize2 += ui32ServerSyncCountInt[i] * sizeof(IMG_UINT32);
+			ui32BufferSize2 += ui32ServerSyncCountInt[i] * sizeof(SERVER_SYNC_PRIMITIVE *);
+			ui32BufferSize2 += ui32ServerSyncCountInt[i] * sizeof(IMG_HANDLE *);
+			ui32BufferSize2 += ui32CommandSizeInt[i] * sizeof(IMG_UINT8);
+		}
+	}
+
+	if (ui32BufferSize2 != 0)
+	{
+		pArrayArgsBuffer2 = OSAllocMemNoStats(ui32BufferSize2);
+
+		if(!pArrayArgsBuffer2)
 		{
 			psRGXSubmitTransferOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
-	
 			goto RGXSubmitTransfer_exit;
 		}
 	}
 
-			/* Copy the data over */
-			if ( !OSAccessOK(PVR_VERIFY_READ, (void*) psRGXSubmitTransferIN->pui32ClientFenceCount, psRGXSubmitTransferIN->ui32PrepareCount * sizeof(IMG_UINT32))
-				|| (OSCopyFromUser(NULL, ui32ClientFenceCountInt, psRGXSubmitTransferIN->pui32ClientFenceCount,
-				psRGXSubmitTransferIN->ui32PrepareCount * sizeof(IMG_UINT32)) != PVRSRV_OK) )
+	if (psRGXSubmitTransferIN->ui32PrepareCount != 0)
+	{
+		IMG_UINT32 i;
+		for (i=0;i<psRGXSubmitTransferIN->ui32PrepareCount;i++)
+		{
+			/* Assigning each psFenceUFOSyncPrimBlockInt to the right offset in the pool buffer (this is the second dimension) */
+			psFenceUFOSyncPrimBlockInt[i] = (SYNC_PRIMITIVE_BLOCK **)(((IMG_UINT8 *)pArrayArgsBuffer2) + ui32NextOffset2);
+			ui32NextOffset2 += ui32ClientFenceCountInt[i] * sizeof(SYNC_PRIMITIVE_BLOCK *);
+			/* Assigning each hFenceUFOSyncPrimBlockInt2 to the right offset in the pool buffer (this is the second dimension) */
+			hFenceUFOSyncPrimBlockInt2[i] = (IMG_HANDLE *)(((IMG_UINT8 *)pArrayArgsBuffer2) + ui32NextOffset2); 
+			ui32NextOffset2 += ui32ClientFenceCountInt[i] * sizeof(IMG_HANDLE);
+		}
+	}
+	if (psRGXSubmitTransferIN->ui32PrepareCount != 0)
+	{
+		IMG_UINT32 i;
+		for (i=0;i<psRGXSubmitTransferIN->ui32PrepareCount;i++)
+		{
+			/* Assigning each ui32FenceSyncOffsetInt to the right offset in the pool buffer (this is the second dimension) */
+			ui32FenceSyncOffsetInt[i] = (IMG_UINT32*)(((IMG_UINT8 *)pArrayArgsBuffer2) + ui32NextOffset2);
+			ui32NextOffset2 += ui32ClientFenceCountInt[i] * sizeof(IMG_UINT32);
+		}
+	}
+	if (psRGXSubmitTransferIN->ui32PrepareCount != 0)
+	{
+		IMG_UINT32 i;
+		for (i=0;i<psRGXSubmitTransferIN->ui32PrepareCount;i++)
+		{
+			/* Assigning each ui32FenceValueInt to the right offset in the pool buffer (this is the second dimension) */
+			ui32FenceValueInt[i] = (IMG_UINT32*)(((IMG_UINT8 *)pArrayArgsBuffer2) + ui32NextOffset2);
+			ui32NextOffset2 += ui32ClientFenceCountInt[i] * sizeof(IMG_UINT32);
+		}
+	}
+	if (psRGXSubmitTransferIN->ui32PrepareCount != 0)
+	{
+		IMG_UINT32 i;
+		for (i=0;i<psRGXSubmitTransferIN->ui32PrepareCount;i++)
+		{
+			/* Assigning each psUpdateUFOSyncPrimBlockInt to the right offset in the pool buffer (this is the second dimension) */
+			psUpdateUFOSyncPrimBlockInt[i] = (SYNC_PRIMITIVE_BLOCK **)(((IMG_UINT8 *)pArrayArgsBuffer2) + ui32NextOffset2);
+			ui32NextOffset2 += ui32ClientUpdateCountInt[i] * sizeof(SYNC_PRIMITIVE_BLOCK *);
+			/* Assigning each hUpdateUFOSyncPrimBlockInt2 to the right offset in the pool buffer (this is the second dimension) */
+			hUpdateUFOSyncPrimBlockInt2[i] = (IMG_HANDLE *)(((IMG_UINT8 *)pArrayArgsBuffer2) + ui32NextOffset2); 
+			ui32NextOffset2 += ui32ClientUpdateCountInt[i] * sizeof(IMG_HANDLE);
+		}
+	}
+	if (psRGXSubmitTransferIN->ui32PrepareCount != 0)
+	{
+		IMG_UINT32 i;
+		for (i=0;i<psRGXSubmitTransferIN->ui32PrepareCount;i++)
+		{
+			/* Assigning each ui32UpdateSyncOffsetInt to the right offset in the pool buffer (this is the second dimension) */
+			ui32UpdateSyncOffsetInt[i] = (IMG_UINT32*)(((IMG_UINT8 *)pArrayArgsBuffer2) + ui32NextOffset2);
+			ui32NextOffset2 += ui32ClientUpdateCountInt[i] * sizeof(IMG_UINT32);
+		}
+	}
+	if (psRGXSubmitTransferIN->ui32PrepareCount != 0)
+	{
+		IMG_UINT32 i;
+		for (i=0;i<psRGXSubmitTransferIN->ui32PrepareCount;i++)
+		{
+			/* Assigning each ui32UpdateValueInt to the right offset in the pool buffer (this is the second dimension) */
+			ui32UpdateValueInt[i] = (IMG_UINT32*)(((IMG_UINT8 *)pArrayArgsBuffer2) + ui32NextOffset2);
+			ui32NextOffset2 += ui32ClientUpdateCountInt[i] * sizeof(IMG_UINT32);
+		}
+	}
+	if (psRGXSubmitTransferIN->ui32PrepareCount != 0)
+	{
+		IMG_UINT32 i;
+		for (i=0;i<psRGXSubmitTransferIN->ui32PrepareCount;i++)
+		{
+			/* Assigning each ui32ServerSyncFlagsInt to the right offset in the pool buffer (this is the second dimension) */
+			ui32ServerSyncFlagsInt[i] = (IMG_UINT32*)(((IMG_UINT8 *)pArrayArgsBuffer2) + ui32NextOffset2);
+			ui32NextOffset2 += ui32ServerSyncCountInt[i] * sizeof(IMG_UINT32);
+		}
+	}
+	if (psRGXSubmitTransferIN->ui32PrepareCount != 0)
+	{
+		IMG_UINT32 i;
+		for (i=0;i<psRGXSubmitTransferIN->ui32PrepareCount;i++)
+		{
+			/* Assigning each psServerSyncInt to the right offset in the pool buffer (this is the second dimension) */
+			psServerSyncInt[i] = (SERVER_SYNC_PRIMITIVE **)(((IMG_UINT8 *)pArrayArgsBuffer2) + ui32NextOffset2);
+			ui32NextOffset2 += ui32ServerSyncCountInt[i] * sizeof(SERVER_SYNC_PRIMITIVE *);
+			/* Assigning each hServerSyncInt2 to the right offset in the pool buffer (this is the second dimension) */
+			hServerSyncInt2[i] = (IMG_HANDLE *)(((IMG_UINT8 *)pArrayArgsBuffer2) + ui32NextOffset2); 
+			ui32NextOffset2 += ui32ServerSyncCountInt[i] * sizeof(IMG_HANDLE);
+		}
+	}
+	if (psRGXSubmitTransferIN->ui32PrepareCount != 0)
+	{
+		IMG_UINT32 i;
+		for (i=0;i<psRGXSubmitTransferIN->ui32PrepareCount;i++)
+		{
+			/* Assigning each ui8FWCommandInt to the right offset in the pool buffer (this is the second dimension) */
+			ui8FWCommandInt[i] = (IMG_UINT8*)(((IMG_UINT8 *)pArrayArgsBuffer2) + ui32NextOffset2);
+			ui32NextOffset2 += ui32CommandSizeInt[i] * sizeof(IMG_UINT8);
+		}
+	}
+
+	{
+		IMG_UINT32 i;
+		IMG_HANDLE **psPtr;
+
+		/* Loop over all the pointers in the array copying the data into the kernel */
+		for (i=0;i<psRGXSubmitTransferIN->ui32PrepareCount;i++)
+		{
+			/* Copy the pointer over from the client side */
+			if ( OSCopyFromUser(NULL, &psPtr, &psRGXSubmitTransferIN->phFenceUFOSyncPrimBlock[i],
+				sizeof(IMG_HANDLE **)) != PVRSRV_OK )
 			{
 				psRGXSubmitTransferOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
 
 				goto RGXSubmitTransfer_exit;
 			}
-	if (psRGXSubmitTransferIN->ui32PrepareCount != 0)
-	{
-		IMG_UINT32 ui32Pass=0;
-		IMG_UINT32 i;
-		IMG_UINT32 ui32AllocSize=0;
-		IMG_UINT32 ui32Size;
-		IMG_UINT8 *pui8Ptr = NULL;
-		IMG_UINT32 ui32AllocSize2=0;
-		IMG_UINT32 ui32Size2;
-		IMG_UINT8 *pui8Ptr2 = NULL;
 
-		/*
-			Two pass loop, 1st find out the size and 2nd allocation and set offsets.
-			Keeps allocation cost down and simplifies the free path
-		*/
-		for (ui32Pass=0;ui32Pass<2;ui32Pass++)
+			/* Copy the data over */
+			if ((ui32ClientFenceCountInt[i] * sizeof(IMG_HANDLE)) > 0)
+			{
+				if ( OSCopyFromUser(NULL, (hFenceUFOSyncPrimBlockInt2[i]), psPtr, (ui32ClientFenceCountInt[i] * sizeof(IMG_HANDLE))) != PVRSRV_OK )
+				{
+					psRGXSubmitTransferOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
+
+					goto RGXSubmitTransfer_exit;
+				}
+			}
+		}
+	}
+
+	{
+		IMG_UINT32 i;
+		IMG_UINT32 **psPtr;
+
+		/* Loop over all the pointers in the array copying the data into the kernel */
+		for (i=0;i<psRGXSubmitTransferIN->ui32PrepareCount;i++)
 		{
-			ui32Size = psRGXSubmitTransferIN->ui32PrepareCount * sizeof(SYNC_PRIMITIVE_BLOCK * *);
-			ui32Size2 = psRGXSubmitTransferIN->ui32PrepareCount * sizeof(IMG_HANDLE *);
-			if (ui32Pass == 0)
+			/* Copy the pointer over from the client side */
+			if ( OSCopyFromUser(NULL, &psPtr, &psRGXSubmitTransferIN->pui32FenceSyncOffset[i],
+				sizeof(IMG_UINT32 **)) != PVRSRV_OK )
 			{
-				ui32AllocSize += ui32Size;
-				ui32AllocSize2 += ui32Size2;
+				psRGXSubmitTransferOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
+
+				goto RGXSubmitTransfer_exit;
 			}
-			else
+
+			/* Copy the data over */
+			if ((ui32ClientFenceCountInt[i] * sizeof(IMG_UINT32)) > 0)
 			{
-				pui8Ptr = OSAllocMemNoStats(ui32AllocSize);
-				if (pui8Ptr == NULL)
+				if ( OSCopyFromUser(NULL, (ui32FenceSyncOffsetInt[i]), psPtr, (ui32ClientFenceCountInt[i] * sizeof(IMG_UINT32))) != PVRSRV_OK )
 				{
-					psRGXSubmitTransferOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
+					psRGXSubmitTransferOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
+
 					goto RGXSubmitTransfer_exit;
 				}
-				psFenceUFOSyncPrimBlockInt = (SYNC_PRIMITIVE_BLOCK * **) pui8Ptr;
-				pui8Ptr += ui32Size;
-				pui8Ptr2 = OSAllocMemNoStats(ui32AllocSize2);
-				if (pui8Ptr2 == NULL)
-				{
-					psRGXSubmitTransferOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
-					goto RGXSubmitTransfer_exit;
-				}
-				hFenceUFOSyncPrimBlockInt2 = (IMG_HANDLE **) pui8Ptr2;
-				pui8Ptr2 += ui32Size2;
 			}
-			
-			for (i=0;i<psRGXSubmitTransferIN->ui32PrepareCount;i++)
+		}
+	}
+
+	{
+		IMG_UINT32 i;
+		IMG_UINT32 **psPtr;
+
+		/* Loop over all the pointers in the array copying the data into the kernel */
+		for (i=0;i<psRGXSubmitTransferIN->ui32PrepareCount;i++)
+		{
+			/* Copy the pointer over from the client side */
+			if ( OSCopyFromUser(NULL, &psPtr, &psRGXSubmitTransferIN->pui32FenceValue[i],
+				sizeof(IMG_UINT32 **)) != PVRSRV_OK )
 			{
-				ui32Size = ui32ClientFenceCountInt[i] * sizeof(SYNC_PRIMITIVE_BLOCK *);		
-				ui32Size2 = ui32ClientFenceCountInt[i] * sizeof(IMG_HANDLE);		
-				if (ui32Size)
+				psRGXSubmitTransferOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
+
+				goto RGXSubmitTransfer_exit;
+			}
+
+			/* Copy the data over */
+			if ((ui32ClientFenceCountInt[i] * sizeof(IMG_UINT32)) > 0)
+			{
+				if ( OSCopyFromUser(NULL, (ui32FenceValueInt[i]), psPtr, (ui32ClientFenceCountInt[i] * sizeof(IMG_UINT32))) != PVRSRV_OK )
 				{
-					if (ui32Pass == 0)
-					{
-						ui32AllocSize += ui32Size;
-						ui32AllocSize2 += ui32Size2;
-					}
-					else
-					{
-						psFenceUFOSyncPrimBlockInt[i] = (SYNC_PRIMITIVE_BLOCK * *) pui8Ptr;
-						pui8Ptr += ui32Size;
-						hFenceUFOSyncPrimBlockInt2[i] = (IMG_HANDLE *) pui8Ptr2;
-						pui8Ptr2 += ui32Size2;
-					}
+					psRGXSubmitTransferOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
+
+					goto RGXSubmitTransfer_exit;
 				}
 			}
 		}
@@ -328,71 +827,23 @@
 		for (i=0;i<psRGXSubmitTransferIN->ui32PrepareCount;i++)
 		{
 			/* Copy the pointer over from the client side */
-			if ( !OSAccessOK(PVR_VERIFY_READ, (void*) &psRGXSubmitTransferIN->phFenceUFOSyncPrimBlock[i], sizeof(IMG_HANDLE **))
-				|| (OSCopyFromUser(NULL, &psPtr, &psRGXSubmitTransferIN->phFenceUFOSyncPrimBlock[i],
-				sizeof(IMG_HANDLE **)) != PVRSRV_OK) )
+			if ( OSCopyFromUser(NULL, &psPtr, &psRGXSubmitTransferIN->phUpdateUFOSyncPrimBlock[i],
+				sizeof(IMG_HANDLE **)) != PVRSRV_OK )
 			{
 				psRGXSubmitTransferOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
 
 				goto RGXSubmitTransfer_exit;
 			}
+
 			/* Copy the data over */
-			if ( !OSAccessOK(PVR_VERIFY_READ, (void*) psPtr, (ui32ClientFenceCountInt[i] * sizeof(IMG_HANDLE)))
-				|| (OSCopyFromUser(NULL, (hFenceUFOSyncPrimBlockInt2[i]), psPtr,
-				(ui32ClientFenceCountInt[i] * sizeof(IMG_HANDLE))) != PVRSRV_OK) )
+			if ((ui32ClientUpdateCountInt[i] * sizeof(IMG_HANDLE)) > 0)
 			{
-				psRGXSubmitTransferOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
-
-				goto RGXSubmitTransfer_exit;
-			}
-		}
-	}
-	if (psRGXSubmitTransferIN->ui32PrepareCount != 0)
-	{
-		IMG_UINT32 ui32Pass=0;
-		IMG_UINT32 i;
-		IMG_UINT32 ui32AllocSize=0;
-		IMG_UINT32 ui32Size;
-		IMG_UINT8 *pui8Ptr = NULL;
-
-		/*
-			Two pass loop, 1st find out the size and 2nd allocation and set offsets.
-			Keeps allocation cost down and simplifies the free path
-		*/
-		for (ui32Pass=0;ui32Pass<2;ui32Pass++)
-		{
-			ui32Size = psRGXSubmitTransferIN->ui32PrepareCount * sizeof(IMG_UINT32 *);
-			if (ui32Pass == 0)
-			{
-				ui32AllocSize += ui32Size;
-			}
-			else
-			{
-				pui8Ptr = OSAllocMemNoStats(ui32AllocSize);
-				if (pui8Ptr == NULL)
+				if ( OSCopyFromUser(NULL, (hUpdateUFOSyncPrimBlockInt2[i]), psPtr, (ui32ClientUpdateCountInt[i] * sizeof(IMG_HANDLE))) != PVRSRV_OK )
 				{
-					psRGXSubmitTransferOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
+					psRGXSubmitTransferOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
+
 					goto RGXSubmitTransfer_exit;
 				}
-				ui32FenceSyncOffsetInt = (IMG_UINT32 **) pui8Ptr;
-				pui8Ptr += ui32Size;
-			}
-			
-			for (i=0;i<psRGXSubmitTransferIN->ui32PrepareCount;i++)
-			{
-				ui32Size = ui32ClientFenceCountInt[i] * sizeof(IMG_UINT32);		
-				if (ui32Size)
-				{
-					if (ui32Pass == 0)
-					{
-						ui32AllocSize += ui32Size;
-					}
-					else
-					{
-						ui32FenceSyncOffsetInt[i] = (IMG_UINT32 *) pui8Ptr;
-						pui8Ptr += ui32Size;
-					}
-				}
 			}
 		}
 	}
@@ -405,71 +856,23 @@
 		for (i=0;i<psRGXSubmitTransferIN->ui32PrepareCount;i++)
 		{
 			/* Copy the pointer over from the client side */
-			if ( !OSAccessOK(PVR_VERIFY_READ, (void*) &psRGXSubmitTransferIN->pui32FenceSyncOffset[i], sizeof(IMG_UINT32 **))
-				|| (OSCopyFromUser(NULL, &psPtr, &psRGXSubmitTransferIN->pui32FenceSyncOffset[i],
-				sizeof(IMG_UINT32 **)) != PVRSRV_OK) )
+			if ( OSCopyFromUser(NULL, &psPtr, &psRGXSubmitTransferIN->pui32UpdateSyncOffset[i],
+				sizeof(IMG_UINT32 **)) != PVRSRV_OK )
 			{
 				psRGXSubmitTransferOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
 
 				goto RGXSubmitTransfer_exit;
 			}
+
 			/* Copy the data over */
-			if ( !OSAccessOK(PVR_VERIFY_READ, (void*) psPtr, (ui32ClientFenceCountInt[i] * sizeof(IMG_UINT32)))
-				|| (OSCopyFromUser(NULL, (ui32FenceSyncOffsetInt[i]), psPtr,
-				(ui32ClientFenceCountInt[i] * sizeof(IMG_UINT32))) != PVRSRV_OK) )
+			if ((ui32ClientUpdateCountInt[i] * sizeof(IMG_UINT32)) > 0)
 			{
-				psRGXSubmitTransferOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
-
-				goto RGXSubmitTransfer_exit;
-			}
-		}
-	}
-	if (psRGXSubmitTransferIN->ui32PrepareCount != 0)
-	{
-		IMG_UINT32 ui32Pass=0;
-		IMG_UINT32 i;
-		IMG_UINT32 ui32AllocSize=0;
-		IMG_UINT32 ui32Size;
-		IMG_UINT8 *pui8Ptr = NULL;
-
-		/*
-			Two pass loop, 1st find out the size and 2nd allocation and set offsets.
-			Keeps allocation cost down and simplifies the free path
-		*/
-		for (ui32Pass=0;ui32Pass<2;ui32Pass++)
-		{
-			ui32Size = psRGXSubmitTransferIN->ui32PrepareCount * sizeof(IMG_UINT32 *);
-			if (ui32Pass == 0)
-			{
-				ui32AllocSize += ui32Size;
-			}
-			else
-			{
-				pui8Ptr = OSAllocMemNoStats(ui32AllocSize);
-				if (pui8Ptr == NULL)
+				if ( OSCopyFromUser(NULL, (ui32UpdateSyncOffsetInt[i]), psPtr, (ui32ClientUpdateCountInt[i] * sizeof(IMG_UINT32))) != PVRSRV_OK )
 				{
-					psRGXSubmitTransferOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
+					psRGXSubmitTransferOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
+
 					goto RGXSubmitTransfer_exit;
 				}
-				ui32FenceValueInt = (IMG_UINT32 **) pui8Ptr;
-				pui8Ptr += ui32Size;
-			}
-			
-			for (i=0;i<psRGXSubmitTransferIN->ui32PrepareCount;i++)
-			{
-				ui32Size = ui32ClientFenceCountInt[i] * sizeof(IMG_UINT32);		
-				if (ui32Size)
-				{
-					if (ui32Pass == 0)
-					{
-						ui32AllocSize += ui32Size;
-					}
-					else
-					{
-						ui32FenceValueInt[i] = (IMG_UINT32 *) pui8Ptr;
-						pui8Ptr += ui32Size;
-					}
-				}
 			}
 		}
 	}
@@ -482,108 +885,52 @@
 		for (i=0;i<psRGXSubmitTransferIN->ui32PrepareCount;i++)
 		{
 			/* Copy the pointer over from the client side */
-			if ( !OSAccessOK(PVR_VERIFY_READ, (void*) &psRGXSubmitTransferIN->pui32FenceValue[i], sizeof(IMG_UINT32 **))
-				|| (OSCopyFromUser(NULL, &psPtr, &psRGXSubmitTransferIN->pui32FenceValue[i],
-				sizeof(IMG_UINT32 **)) != PVRSRV_OK) )
+			if ( OSCopyFromUser(NULL, &psPtr, &psRGXSubmitTransferIN->pui32UpdateValue[i],
+				sizeof(IMG_UINT32 **)) != PVRSRV_OK )
 			{
 				psRGXSubmitTransferOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
 
 				goto RGXSubmitTransfer_exit;
 			}
-			/* Copy the data over */
-			if ( !OSAccessOK(PVR_VERIFY_READ, (void*) psPtr, (ui32ClientFenceCountInt[i] * sizeof(IMG_UINT32)))
-				|| (OSCopyFromUser(NULL, (ui32FenceValueInt[i]), psPtr,
-				(ui32ClientFenceCountInt[i] * sizeof(IMG_UINT32))) != PVRSRV_OK) )
-			{
-				psRGXSubmitTransferOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
 
-				goto RGXSubmitTransfer_exit;
+			/* Copy the data over */
+			if ((ui32ClientUpdateCountInt[i] * sizeof(IMG_UINT32)) > 0)
+			{
+				if ( OSCopyFromUser(NULL, (ui32UpdateValueInt[i]), psPtr, (ui32ClientUpdateCountInt[i] * sizeof(IMG_UINT32))) != PVRSRV_OK )
+				{
+					psRGXSubmitTransferOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
+
+					goto RGXSubmitTransfer_exit;
+				}
 			}
 		}
 	}
-	if (psRGXSubmitTransferIN->ui32PrepareCount != 0)
-	{
-		ui32ClientUpdateCountInt = OSAllocMemNoStats(psRGXSubmitTransferIN->ui32PrepareCount * sizeof(IMG_UINT32));
-		if (!ui32ClientUpdateCountInt)
-		{
-			psRGXSubmitTransferOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
-	
-			goto RGXSubmitTransfer_exit;
-		}
-	}
 
-			/* Copy the data over */
-			if ( !OSAccessOK(PVR_VERIFY_READ, (void*) psRGXSubmitTransferIN->pui32ClientUpdateCount, psRGXSubmitTransferIN->ui32PrepareCount * sizeof(IMG_UINT32))
-				|| (OSCopyFromUser(NULL, ui32ClientUpdateCountInt, psRGXSubmitTransferIN->pui32ClientUpdateCount,
-				psRGXSubmitTransferIN->ui32PrepareCount * sizeof(IMG_UINT32)) != PVRSRV_OK) )
-			{
-				psRGXSubmitTransferOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
-
-				goto RGXSubmitTransfer_exit;
-			}
-	if (psRGXSubmitTransferIN->ui32PrepareCount != 0)
 	{
-		IMG_UINT32 ui32Pass=0;
 		IMG_UINT32 i;
-		IMG_UINT32 ui32AllocSize=0;
-		IMG_UINT32 ui32Size;
-		IMG_UINT8 *pui8Ptr = NULL;
-		IMG_UINT32 ui32AllocSize2=0;
-		IMG_UINT32 ui32Size2;
-		IMG_UINT8 *pui8Ptr2 = NULL;
+		IMG_UINT32 **psPtr;
 
-		/*
-			Two pass loop, 1st find out the size and 2nd allocation and set offsets.
-			Keeps allocation cost down and simplifies the free path
-		*/
-		for (ui32Pass=0;ui32Pass<2;ui32Pass++)
+		/* Loop over all the pointers in the array copying the data into the kernel */
+		for (i=0;i<psRGXSubmitTransferIN->ui32PrepareCount;i++)
 		{
-			ui32Size = psRGXSubmitTransferIN->ui32PrepareCount * sizeof(SYNC_PRIMITIVE_BLOCK * *);
-			ui32Size2 = psRGXSubmitTransferIN->ui32PrepareCount * sizeof(IMG_HANDLE *);
-			if (ui32Pass == 0)
+			/* Copy the pointer over from the client side */
+			if ( OSCopyFromUser(NULL, &psPtr, &psRGXSubmitTransferIN->pui32ServerSyncFlags[i],
+				sizeof(IMG_UINT32 **)) != PVRSRV_OK )
 			{
-				ui32AllocSize += ui32Size;
-				ui32AllocSize2 += ui32Size2;
+				psRGXSubmitTransferOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
+
+				goto RGXSubmitTransfer_exit;
 			}
-			else
+
+			/* Copy the data over */
+			if ((ui32ServerSyncCountInt[i] * sizeof(IMG_UINT32)) > 0)
 			{
-				pui8Ptr = OSAllocMemNoStats(ui32AllocSize);
-				if (pui8Ptr == NULL)
+				if ( OSCopyFromUser(NULL, (ui32ServerSyncFlagsInt[i]), psPtr, (ui32ServerSyncCountInt[i] * sizeof(IMG_UINT32))) != PVRSRV_OK )
 				{
-					psRGXSubmitTransferOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
+					psRGXSubmitTransferOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
+
 					goto RGXSubmitTransfer_exit;
 				}
-				psUpdateUFOSyncPrimBlockInt = (SYNC_PRIMITIVE_BLOCK * **) pui8Ptr;
-				pui8Ptr += ui32Size;
-				pui8Ptr2 = OSAllocMemNoStats(ui32AllocSize2);
-				if (pui8Ptr2 == NULL)
-				{
-					psRGXSubmitTransferOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
-					goto RGXSubmitTransfer_exit;
-				}
-				hUpdateUFOSyncPrimBlockInt2 = (IMG_HANDLE **) pui8Ptr2;
-				pui8Ptr2 += ui32Size2;
-			}
-			
-			for (i=0;i<psRGXSubmitTransferIN->ui32PrepareCount;i++)
-			{
-				ui32Size = ui32ClientUpdateCountInt[i] * sizeof(SYNC_PRIMITIVE_BLOCK *);		
-				ui32Size2 = ui32ClientUpdateCountInt[i] * sizeof(IMG_HANDLE);		
-				if (ui32Size)
-				{
-					if (ui32Pass == 0)
-					{
-						ui32AllocSize += ui32Size;
-						ui32AllocSize2 += ui32Size2;
-					}
-					else
-					{
-						psUpdateUFOSyncPrimBlockInt[i] = (SYNC_PRIMITIVE_BLOCK * *) pui8Ptr;
-						pui8Ptr += ui32Size;
-						hUpdateUFOSyncPrimBlockInt2[i] = (IMG_HANDLE *) pui8Ptr2;
-						pui8Ptr2 += ui32Size2;
-					}
-				}
 			}
 		}
 	}
@@ -596,456 +943,23 @@
 		for (i=0;i<psRGXSubmitTransferIN->ui32PrepareCount;i++)
 		{
 			/* Copy the pointer over from the client side */
-			if ( !OSAccessOK(PVR_VERIFY_READ, (void*) &psRGXSubmitTransferIN->phUpdateUFOSyncPrimBlock[i], sizeof(IMG_HANDLE **))
-				|| (OSCopyFromUser(NULL, &psPtr, &psRGXSubmitTransferIN->phUpdateUFOSyncPrimBlock[i],
-				sizeof(IMG_HANDLE **)) != PVRSRV_OK) )
+			if ( OSCopyFromUser(NULL, &psPtr, &psRGXSubmitTransferIN->phServerSync[i],
+				sizeof(IMG_HANDLE **)) != PVRSRV_OK )
 			{
 				psRGXSubmitTransferOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
 
 				goto RGXSubmitTransfer_exit;
 			}
+
 			/* Copy the data over */
-			if ( !OSAccessOK(PVR_VERIFY_READ, (void*) psPtr, (ui32ClientUpdateCountInt[i] * sizeof(IMG_HANDLE)))
-				|| (OSCopyFromUser(NULL, (hUpdateUFOSyncPrimBlockInt2[i]), psPtr,
-				(ui32ClientUpdateCountInt[i] * sizeof(IMG_HANDLE))) != PVRSRV_OK) )
+			if ((ui32ServerSyncCountInt[i] * sizeof(IMG_HANDLE)) > 0)
 			{
-				psRGXSubmitTransferOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
-
-				goto RGXSubmitTransfer_exit;
-			}
-		}
-	}
-	if (psRGXSubmitTransferIN->ui32PrepareCount != 0)
-	{
-		IMG_UINT32 ui32Pass=0;
-		IMG_UINT32 i;
-		IMG_UINT32 ui32AllocSize=0;
-		IMG_UINT32 ui32Size;
-		IMG_UINT8 *pui8Ptr = NULL;
-
-		/*
-			Two pass loop, 1st find out the size and 2nd allocation and set offsets.
-			Keeps allocation cost down and simplifies the free path
-		*/
-		for (ui32Pass=0;ui32Pass<2;ui32Pass++)
-		{
-			ui32Size = psRGXSubmitTransferIN->ui32PrepareCount * sizeof(IMG_UINT32 *);
-			if (ui32Pass == 0)
-			{
-				ui32AllocSize += ui32Size;
-			}
-			else
-			{
-				pui8Ptr = OSAllocMemNoStats(ui32AllocSize);
-				if (pui8Ptr == NULL)
+				if ( OSCopyFromUser(NULL, (hServerSyncInt2[i]), psPtr, (ui32ServerSyncCountInt[i] * sizeof(IMG_HANDLE))) != PVRSRV_OK )
 				{
-					psRGXSubmitTransferOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
+					psRGXSubmitTransferOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
+
 					goto RGXSubmitTransfer_exit;
 				}
-				ui32UpdateSyncOffsetInt = (IMG_UINT32 **) pui8Ptr;
-				pui8Ptr += ui32Size;
-			}
-			
-			for (i=0;i<psRGXSubmitTransferIN->ui32PrepareCount;i++)
-			{
-				ui32Size = ui32ClientUpdateCountInt[i] * sizeof(IMG_UINT32);		
-				if (ui32Size)
-				{
-					if (ui32Pass == 0)
-					{
-						ui32AllocSize += ui32Size;
-					}
-					else
-					{
-						ui32UpdateSyncOffsetInt[i] = (IMG_UINT32 *) pui8Ptr;
-						pui8Ptr += ui32Size;
-					}
-				}
-			}
-		}
-	}
-
-	{
-		IMG_UINT32 i;
-		IMG_UINT32 **psPtr;
-
-		/* Loop over all the pointers in the array copying the data into the kernel */
-		for (i=0;i<psRGXSubmitTransferIN->ui32PrepareCount;i++)
-		{
-			/* Copy the pointer over from the client side */
-			if ( !OSAccessOK(PVR_VERIFY_READ, (void*) &psRGXSubmitTransferIN->pui32UpdateSyncOffset[i], sizeof(IMG_UINT32 **))
-				|| (OSCopyFromUser(NULL, &psPtr, &psRGXSubmitTransferIN->pui32UpdateSyncOffset[i],
-				sizeof(IMG_UINT32 **)) != PVRSRV_OK) )
-			{
-				psRGXSubmitTransferOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
-
-				goto RGXSubmitTransfer_exit;
-			}
-			/* Copy the data over */
-			if ( !OSAccessOK(PVR_VERIFY_READ, (void*) psPtr, (ui32ClientUpdateCountInt[i] * sizeof(IMG_UINT32)))
-				|| (OSCopyFromUser(NULL, (ui32UpdateSyncOffsetInt[i]), psPtr,
-				(ui32ClientUpdateCountInt[i] * sizeof(IMG_UINT32))) != PVRSRV_OK) )
-			{
-				psRGXSubmitTransferOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
-
-				goto RGXSubmitTransfer_exit;
-			}
-		}
-	}
-	if (psRGXSubmitTransferIN->ui32PrepareCount != 0)
-	{
-		IMG_UINT32 ui32Pass=0;
-		IMG_UINT32 i;
-		IMG_UINT32 ui32AllocSize=0;
-		IMG_UINT32 ui32Size;
-		IMG_UINT8 *pui8Ptr = NULL;
-
-		/*
-			Two pass loop, 1st find out the size and 2nd allocation and set offsets.
-			Keeps allocation cost down and simplifies the free path
-		*/
-		for (ui32Pass=0;ui32Pass<2;ui32Pass++)
-		{
-			ui32Size = psRGXSubmitTransferIN->ui32PrepareCount * sizeof(IMG_UINT32 *);
-			if (ui32Pass == 0)
-			{
-				ui32AllocSize += ui32Size;
-			}
-			else
-			{
-				pui8Ptr = OSAllocMemNoStats(ui32AllocSize);
-				if (pui8Ptr == NULL)
-				{
-					psRGXSubmitTransferOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
-					goto RGXSubmitTransfer_exit;
-				}
-				ui32UpdateValueInt = (IMG_UINT32 **) pui8Ptr;
-				pui8Ptr += ui32Size;
-			}
-			
-			for (i=0;i<psRGXSubmitTransferIN->ui32PrepareCount;i++)
-			{
-				ui32Size = ui32ClientUpdateCountInt[i] * sizeof(IMG_UINT32);		
-				if (ui32Size)
-				{
-					if (ui32Pass == 0)
-					{
-						ui32AllocSize += ui32Size;
-					}
-					else
-					{
-						ui32UpdateValueInt[i] = (IMG_UINT32 *) pui8Ptr;
-						pui8Ptr += ui32Size;
-					}
-				}
-			}
-		}
-	}
-
-	{
-		IMG_UINT32 i;
-		IMG_UINT32 **psPtr;
-
-		/* Loop over all the pointers in the array copying the data into the kernel */
-		for (i=0;i<psRGXSubmitTransferIN->ui32PrepareCount;i++)
-		{
-			/* Copy the pointer over from the client side */
-			if ( !OSAccessOK(PVR_VERIFY_READ, (void*) &psRGXSubmitTransferIN->pui32UpdateValue[i], sizeof(IMG_UINT32 **))
-				|| (OSCopyFromUser(NULL, &psPtr, &psRGXSubmitTransferIN->pui32UpdateValue[i],
-				sizeof(IMG_UINT32 **)) != PVRSRV_OK) )
-			{
-				psRGXSubmitTransferOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
-
-				goto RGXSubmitTransfer_exit;
-			}
-			/* Copy the data over */
-			if ( !OSAccessOK(PVR_VERIFY_READ, (void*) psPtr, (ui32ClientUpdateCountInt[i] * sizeof(IMG_UINT32)))
-				|| (OSCopyFromUser(NULL, (ui32UpdateValueInt[i]), psPtr,
-				(ui32ClientUpdateCountInt[i] * sizeof(IMG_UINT32))) != PVRSRV_OK) )
-			{
-				psRGXSubmitTransferOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
-
-				goto RGXSubmitTransfer_exit;
-			}
-		}
-	}
-	if (psRGXSubmitTransferIN->ui32PrepareCount != 0)
-	{
-		ui32ServerSyncCountInt = OSAllocMemNoStats(psRGXSubmitTransferIN->ui32PrepareCount * sizeof(IMG_UINT32));
-		if (!ui32ServerSyncCountInt)
-		{
-			psRGXSubmitTransferOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
-	
-			goto RGXSubmitTransfer_exit;
-		}
-	}
-
-			/* Copy the data over */
-			if ( !OSAccessOK(PVR_VERIFY_READ, (void*) psRGXSubmitTransferIN->pui32ServerSyncCount, psRGXSubmitTransferIN->ui32PrepareCount * sizeof(IMG_UINT32))
-				|| (OSCopyFromUser(NULL, ui32ServerSyncCountInt, psRGXSubmitTransferIN->pui32ServerSyncCount,
-				psRGXSubmitTransferIN->ui32PrepareCount * sizeof(IMG_UINT32)) != PVRSRV_OK) )
-			{
-				psRGXSubmitTransferOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
-
-				goto RGXSubmitTransfer_exit;
-			}
-	if (psRGXSubmitTransferIN->ui32PrepareCount != 0)
-	{
-		IMG_UINT32 ui32Pass=0;
-		IMG_UINT32 i;
-		IMG_UINT32 ui32AllocSize=0;
-		IMG_UINT32 ui32Size;
-		IMG_UINT8 *pui8Ptr = NULL;
-
-		/*
-			Two pass loop, 1st find out the size and 2nd allocation and set offsets.
-			Keeps allocation cost down and simplifies the free path
-		*/
-		for (ui32Pass=0;ui32Pass<2;ui32Pass++)
-		{
-			ui32Size = psRGXSubmitTransferIN->ui32PrepareCount * sizeof(IMG_UINT32 *);
-			if (ui32Pass == 0)
-			{
-				ui32AllocSize += ui32Size;
-			}
-			else
-			{
-				pui8Ptr = OSAllocMemNoStats(ui32AllocSize);
-				if (pui8Ptr == NULL)
-				{
-					psRGXSubmitTransferOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
-					goto RGXSubmitTransfer_exit;
-				}
-				ui32ServerSyncFlagsInt = (IMG_UINT32 **) pui8Ptr;
-				pui8Ptr += ui32Size;
-			}
-			
-			for (i=0;i<psRGXSubmitTransferIN->ui32PrepareCount;i++)
-			{
-				ui32Size = ui32ServerSyncCountInt[i] * sizeof(IMG_UINT32);		
-				if (ui32Size)
-				{
-					if (ui32Pass == 0)
-					{
-						ui32AllocSize += ui32Size;
-					}
-					else
-					{
-						ui32ServerSyncFlagsInt[i] = (IMG_UINT32 *) pui8Ptr;
-						pui8Ptr += ui32Size;
-					}
-				}
-			}
-		}
-	}
-
-	{
-		IMG_UINT32 i;
-		IMG_UINT32 **psPtr;
-
-		/* Loop over all the pointers in the array copying the data into the kernel */
-		for (i=0;i<psRGXSubmitTransferIN->ui32PrepareCount;i++)
-		{
-			/* Copy the pointer over from the client side */
-			if ( !OSAccessOK(PVR_VERIFY_READ, (void*) &psRGXSubmitTransferIN->pui32ServerSyncFlags[i], sizeof(IMG_UINT32 **))
-				|| (OSCopyFromUser(NULL, &psPtr, &psRGXSubmitTransferIN->pui32ServerSyncFlags[i],
-				sizeof(IMG_UINT32 **)) != PVRSRV_OK) )
-			{
-				psRGXSubmitTransferOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
-
-				goto RGXSubmitTransfer_exit;
-			}
-			/* Copy the data over */
-			if ( !OSAccessOK(PVR_VERIFY_READ, (void*) psPtr, (ui32ServerSyncCountInt[i] * sizeof(IMG_UINT32)))
-				|| (OSCopyFromUser(NULL, (ui32ServerSyncFlagsInt[i]), psPtr,
-				(ui32ServerSyncCountInt[i] * sizeof(IMG_UINT32))) != PVRSRV_OK) )
-			{
-				psRGXSubmitTransferOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
-
-				goto RGXSubmitTransfer_exit;
-			}
-		}
-	}
-	if (psRGXSubmitTransferIN->ui32PrepareCount != 0)
-	{
-		IMG_UINT32 ui32Pass=0;
-		IMG_UINT32 i;
-		IMG_UINT32 ui32AllocSize=0;
-		IMG_UINT32 ui32Size;
-		IMG_UINT8 *pui8Ptr = NULL;
-		IMG_UINT32 ui32AllocSize2=0;
-		IMG_UINT32 ui32Size2;
-		IMG_UINT8 *pui8Ptr2 = NULL;
-
-		/*
-			Two pass loop, 1st find out the size and 2nd allocation and set offsets.
-			Keeps allocation cost down and simplifies the free path
-		*/
-		for (ui32Pass=0;ui32Pass<2;ui32Pass++)
-		{
-			ui32Size = psRGXSubmitTransferIN->ui32PrepareCount * sizeof(SERVER_SYNC_PRIMITIVE * *);
-			ui32Size2 = psRGXSubmitTransferIN->ui32PrepareCount * sizeof(IMG_HANDLE *);
-			if (ui32Pass == 0)
-			{
-				ui32AllocSize += ui32Size;
-				ui32AllocSize2 += ui32Size2;
-			}
-			else
-			{
-				pui8Ptr = OSAllocMemNoStats(ui32AllocSize);
-				if (pui8Ptr == NULL)
-				{
-					psRGXSubmitTransferOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
-					goto RGXSubmitTransfer_exit;
-				}
-				psServerSyncInt = (SERVER_SYNC_PRIMITIVE * **) pui8Ptr;
-				pui8Ptr += ui32Size;
-				pui8Ptr2 = OSAllocMemNoStats(ui32AllocSize2);
-				if (pui8Ptr2 == NULL)
-				{
-					psRGXSubmitTransferOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
-					goto RGXSubmitTransfer_exit;
-				}
-				hServerSyncInt2 = (IMG_HANDLE **) pui8Ptr2;
-				pui8Ptr2 += ui32Size2;
-			}
-			
-			for (i=0;i<psRGXSubmitTransferIN->ui32PrepareCount;i++)
-			{
-				ui32Size = ui32ServerSyncCountInt[i] * sizeof(SERVER_SYNC_PRIMITIVE *);		
-				ui32Size2 = ui32ServerSyncCountInt[i] * sizeof(IMG_HANDLE);		
-				if (ui32Size)
-				{
-					if (ui32Pass == 0)
-					{
-						ui32AllocSize += ui32Size;
-						ui32AllocSize2 += ui32Size2;
-					}
-					else
-					{
-						psServerSyncInt[i] = (SERVER_SYNC_PRIMITIVE * *) pui8Ptr;
-						pui8Ptr += ui32Size;
-						hServerSyncInt2[i] = (IMG_HANDLE *) pui8Ptr2;
-						pui8Ptr2 += ui32Size2;
-					}
-				}
-			}
-		}
-	}
-
-	{
-		IMG_UINT32 i;
-		IMG_HANDLE **psPtr;
-
-		/* Loop over all the pointers in the array copying the data into the kernel */
-		for (i=0;i<psRGXSubmitTransferIN->ui32PrepareCount;i++)
-		{
-			/* Copy the pointer over from the client side */
-			if ( !OSAccessOK(PVR_VERIFY_READ, (void*) &psRGXSubmitTransferIN->phServerSync[i], sizeof(IMG_HANDLE **))
-				|| (OSCopyFromUser(NULL, &psPtr, &psRGXSubmitTransferIN->phServerSync[i],
-				sizeof(IMG_HANDLE **)) != PVRSRV_OK) )
-			{
-				psRGXSubmitTransferOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
-
-				goto RGXSubmitTransfer_exit;
-			}
-			/* Copy the data over */
-			if ( !OSAccessOK(PVR_VERIFY_READ, (void*) psPtr, (ui32ServerSyncCountInt[i] * sizeof(IMG_HANDLE)))
-				|| (OSCopyFromUser(NULL, (hServerSyncInt2[i]), psPtr,
-				(ui32ServerSyncCountInt[i] * sizeof(IMG_HANDLE))) != PVRSRV_OK) )
-			{
-				psRGXSubmitTransferOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
-
-				goto RGXSubmitTransfer_exit;
-			}
-		}
-	}
-	
-	{
-		uiUpdateFenceNameInt = OSAllocMemNoStats(32 * sizeof(IMG_CHAR));
-		if (!uiUpdateFenceNameInt)
-		{
-			psRGXSubmitTransferOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
-	
-			goto RGXSubmitTransfer_exit;
-		}
-	}
-
-			/* Copy the data over */
-			if ( !OSAccessOK(PVR_VERIFY_READ, (void*) psRGXSubmitTransferIN->puiUpdateFenceName, 32 * sizeof(IMG_CHAR))
-				|| (OSCopyFromUser(NULL, uiUpdateFenceNameInt, psRGXSubmitTransferIN->puiUpdateFenceName,
-				32 * sizeof(IMG_CHAR)) != PVRSRV_OK) )
-			{
-				psRGXSubmitTransferOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
-
-				goto RGXSubmitTransfer_exit;
-			}
-	if (psRGXSubmitTransferIN->ui32PrepareCount != 0)
-	{
-		ui32CommandSizeInt = OSAllocMemNoStats(psRGXSubmitTransferIN->ui32PrepareCount * sizeof(IMG_UINT32));
-		if (!ui32CommandSizeInt)
-		{
-			psRGXSubmitTransferOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
-	
-			goto RGXSubmitTransfer_exit;
-		}
-	}
-
-			/* Copy the data over */
-			if ( !OSAccessOK(PVR_VERIFY_READ, (void*) psRGXSubmitTransferIN->pui32CommandSize, psRGXSubmitTransferIN->ui32PrepareCount * sizeof(IMG_UINT32))
-				|| (OSCopyFromUser(NULL, ui32CommandSizeInt, psRGXSubmitTransferIN->pui32CommandSize,
-				psRGXSubmitTransferIN->ui32PrepareCount * sizeof(IMG_UINT32)) != PVRSRV_OK) )
-			{
-				psRGXSubmitTransferOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
-
-				goto RGXSubmitTransfer_exit;
-			}
-	if (psRGXSubmitTransferIN->ui32PrepareCount != 0)
-	{
-		IMG_UINT32 ui32Pass=0;
-		IMG_UINT32 i;
-		IMG_UINT32 ui32AllocSize=0;
-		IMG_UINT32 ui32Size;
-		IMG_UINT8 *pui8Ptr = NULL;
-
-		/*
-			Two pass loop, 1st find out the size and 2nd allocation and set offsets.
-			Keeps allocation cost down and simplifies the free path
-		*/
-		for (ui32Pass=0;ui32Pass<2;ui32Pass++)
-		{
-			ui32Size = psRGXSubmitTransferIN->ui32PrepareCount * sizeof(IMG_UINT8 *);
-			if (ui32Pass == 0)
-			{
-				ui32AllocSize += ui32Size;
-			}
-			else
-			{
-				pui8Ptr = OSAllocMemNoStats(ui32AllocSize);
-				if (pui8Ptr == NULL)
-				{
-					psRGXSubmitTransferOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
-					goto RGXSubmitTransfer_exit;
-				}
-				ui8FWCommandInt = (IMG_UINT8 **) pui8Ptr;
-				pui8Ptr += ui32Size;
-			}
-			
-			for (i=0;i<psRGXSubmitTransferIN->ui32PrepareCount;i++)
-			{
-				ui32Size = ui32CommandSizeInt[i] * sizeof(IMG_UINT8);		
-				if (ui32Size)
-				{
-					if (ui32Pass == 0)
-					{
-						ui32AllocSize += ui32Size;
-					}
-					else
-					{
-						ui8FWCommandInt[i] = (IMG_UINT8 *) pui8Ptr;
-						pui8Ptr += ui32Size;
-					}
-				}
 			}
 		}
 	}
@@ -1058,111 +972,52 @@
 		for (i=0;i<psRGXSubmitTransferIN->ui32PrepareCount;i++)
 		{
 			/* Copy the pointer over from the client side */
-			if ( !OSAccessOK(PVR_VERIFY_READ, (void*) &psRGXSubmitTransferIN->pui8FWCommand[i], sizeof(IMG_UINT8 **))
-				|| (OSCopyFromUser(NULL, &psPtr, &psRGXSubmitTransferIN->pui8FWCommand[i],
-				sizeof(IMG_UINT8 **)) != PVRSRV_OK) )
+			if ( OSCopyFromUser(NULL, &psPtr, &psRGXSubmitTransferIN->pui8FWCommand[i],
+				sizeof(IMG_UINT8 **)) != PVRSRV_OK )
 			{
 				psRGXSubmitTransferOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
 
 				goto RGXSubmitTransfer_exit;
 			}
-			/* Copy the data over */
-			if ( !OSAccessOK(PVR_VERIFY_READ, (void*) psPtr, (ui32CommandSizeInt[i] * sizeof(IMG_UINT8)))
-				|| (OSCopyFromUser(NULL, (ui8FWCommandInt[i]), psPtr,
-				(ui32CommandSizeInt[i] * sizeof(IMG_UINT8))) != PVRSRV_OK) )
-			{
-				psRGXSubmitTransferOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
 
-				goto RGXSubmitTransfer_exit;
+			/* Copy the data over */
+			if ((ui32CommandSizeInt[i] * sizeof(IMG_UINT8)) > 0)
+			{
+				if ( OSCopyFromUser(NULL, (ui8FWCommandInt[i]), psPtr, (ui32CommandSizeInt[i] * sizeof(IMG_UINT8))) != PVRSRV_OK )
+				{
+					psRGXSubmitTransferOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
+
+					goto RGXSubmitTransfer_exit;
+				}
 			}
 		}
 	}
-	if (psRGXSubmitTransferIN->ui32PrepareCount != 0)
-	{
-		ui32TQPrepareFlagsInt = OSAllocMemNoStats(psRGXSubmitTransferIN->ui32PrepareCount * sizeof(IMG_UINT32));
-		if (!ui32TQPrepareFlagsInt)
-		{
-			psRGXSubmitTransferOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
-	
-			goto RGXSubmitTransfer_exit;
-		}
-	}
+	/* Lock over handle lookup. */
+	LockHandle();
 
-			/* Copy the data over */
-			if ( !OSAccessOK(PVR_VERIFY_READ, (void*) psRGXSubmitTransferIN->pui32TQPrepareFlags, psRGXSubmitTransferIN->ui32PrepareCount * sizeof(IMG_UINT32))
-				|| (OSCopyFromUser(NULL, ui32TQPrepareFlagsInt, psRGXSubmitTransferIN->pui32TQPrepareFlags,
-				psRGXSubmitTransferIN->ui32PrepareCount * sizeof(IMG_UINT32)) != PVRSRV_OK) )
-			{
-				psRGXSubmitTransferOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
 
-				goto RGXSubmitTransfer_exit;
-			}
-	if (psRGXSubmitTransferIN->ui32SyncPMRCount != 0)
-	{
-		ui32SyncPMRFlagsInt = OSAllocMemNoStats(psRGXSubmitTransferIN->ui32SyncPMRCount * sizeof(IMG_UINT32));
-		if (!ui32SyncPMRFlagsInt)
-		{
-			psRGXSubmitTransferOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
-	
-			goto RGXSubmitTransfer_exit;
-		}
-	}
 
-			/* Copy the data over */
-			if ( !OSAccessOK(PVR_VERIFY_READ, (void*) psRGXSubmitTransferIN->pui32SyncPMRFlags, psRGXSubmitTransferIN->ui32SyncPMRCount * sizeof(IMG_UINT32))
-				|| (OSCopyFromUser(NULL, ui32SyncPMRFlagsInt, psRGXSubmitTransferIN->pui32SyncPMRFlags,
-				psRGXSubmitTransferIN->ui32SyncPMRCount * sizeof(IMG_UINT32)) != PVRSRV_OK) )
-			{
-				psRGXSubmitTransferOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
-
-				goto RGXSubmitTransfer_exit;
-			}
-	if (psRGXSubmitTransferIN->ui32SyncPMRCount != 0)
-	{
-		psSyncPMRsInt = OSAllocMemNoStats(psRGXSubmitTransferIN->ui32SyncPMRCount * sizeof(PMR *));
-		if (!psSyncPMRsInt)
-		{
-			psRGXSubmitTransferOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
-	
-			goto RGXSubmitTransfer_exit;
-		}
-		hSyncPMRsInt2 = OSAllocMemNoStats(psRGXSubmitTransferIN->ui32SyncPMRCount * sizeof(IMG_HANDLE));
-		if (!hSyncPMRsInt2)
-		{
-			psRGXSubmitTransferOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
-	
-			goto RGXSubmitTransfer_exit;
-		}
-	}
-
-			/* Copy the data over */
-			if ( !OSAccessOK(PVR_VERIFY_READ, (void*) psRGXSubmitTransferIN->phSyncPMRs, psRGXSubmitTransferIN->ui32SyncPMRCount * sizeof(IMG_HANDLE))
-				|| (OSCopyFromUser(NULL, hSyncPMRsInt2, psRGXSubmitTransferIN->phSyncPMRs,
-				psRGXSubmitTransferIN->ui32SyncPMRCount * sizeof(IMG_HANDLE)) != PVRSRV_OK) )
-			{
-				psRGXSubmitTransferOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
-
-				goto RGXSubmitTransfer_exit;
-			}
-
-	PMRLock();
 
 
 				{
 					/* Look up the address from the handle */
 					psRGXSubmitTransferOUT->eError =
-						PVRSRVLookupHandle(psConnection->psHandleBase,
+						PVRSRVLookupHandleUnlocked(psConnection->psHandleBase,
 											(void **) &psTransferContextInt,
-											psRGXSubmitTransferIN->hTransferContext,
-											PVRSRV_HANDLE_TYPE_RGX_SERVER_TQ_CONTEXT);
+											hTransferContext,
+											PVRSRV_HANDLE_TYPE_RGX_SERVER_TQ_CONTEXT,
+											IMG_TRUE);
 					if(psRGXSubmitTransferOUT->eError != PVRSRV_OK)
 					{
-						PMRUnlock();
+						UnlockHandle();
 						goto RGXSubmitTransfer_exit;
 					}
 				}
 
 
+
+
+
 	{
 		IMG_UINT32 i;
 
@@ -1174,21 +1029,25 @@
 				{
 					/* Look up the address from the handle */
 					psRGXSubmitTransferOUT->eError =
-						PVRSRVLookupHandle(psConnection->psHandleBase,
+						PVRSRVLookupHandleUnlocked(psConnection->psHandleBase,
 											(void **) &psFenceUFOSyncPrimBlockInt[i][j],
 											hFenceUFOSyncPrimBlockInt2[i][j],
-											PVRSRV_HANDLE_TYPE_SYNC_PRIMITIVE_BLOCK);
+											PVRSRV_HANDLE_TYPE_SYNC_PRIMITIVE_BLOCK,
+											IMG_TRUE);
 					if(psRGXSubmitTransferOUT->eError != PVRSRV_OK)
 					{
-						PMRUnlock();
+						UnlockHandle();
 						goto RGXSubmitTransfer_exit;
 					}
 				}
-
 			}
 		}
 	}
 
+
+
+
+
 	{
 		IMG_UINT32 i;
 
@@ -1200,21 +1059,25 @@
 				{
 					/* Look up the address from the handle */
 					psRGXSubmitTransferOUT->eError =
-						PVRSRVLookupHandle(psConnection->psHandleBase,
+						PVRSRVLookupHandleUnlocked(psConnection->psHandleBase,
 											(void **) &psUpdateUFOSyncPrimBlockInt[i][j],
 											hUpdateUFOSyncPrimBlockInt2[i][j],
-											PVRSRV_HANDLE_TYPE_SYNC_PRIMITIVE_BLOCK);
+											PVRSRV_HANDLE_TYPE_SYNC_PRIMITIVE_BLOCK,
+											IMG_TRUE);
 					if(psRGXSubmitTransferOUT->eError != PVRSRV_OK)
 					{
-						PMRUnlock();
+						UnlockHandle();
 						goto RGXSubmitTransfer_exit;
 					}
 				}
-
 			}
 		}
 	}
 
+
+
+
+
 	{
 		IMG_UINT32 i;
 
@@ -1226,21 +1089,25 @@
 				{
 					/* Look up the address from the handle */
 					psRGXSubmitTransferOUT->eError =
-						PVRSRVLookupHandle(psConnection->psHandleBase,
+						PVRSRVLookupHandleUnlocked(psConnection->psHandleBase,
 											(void **) &psServerSyncInt[i][j],
 											hServerSyncInt2[i][j],
-											PVRSRV_HANDLE_TYPE_SERVER_SYNC_PRIMITIVE);
+											PVRSRV_HANDLE_TYPE_SERVER_SYNC_PRIMITIVE,
+											IMG_TRUE);
 					if(psRGXSubmitTransferOUT->eError != PVRSRV_OK)
 					{
-						PMRUnlock();
+						UnlockHandle();
 						goto RGXSubmitTransfer_exit;
 					}
 				}
-
 			}
 		}
 	}
 
+
+
+
+
 	{
 		IMG_UINT32 i;
 
@@ -1249,23 +1116,26 @@
 				{
 					/* Look up the address from the handle */
 					psRGXSubmitTransferOUT->eError =
-						PVRSRVLookupHandle(psConnection->psHandleBase,
+						PVRSRVLookupHandleUnlocked(psConnection->psHandleBase,
 											(void **) &psSyncPMRsInt[i],
 											hSyncPMRsInt2[i],
-											PVRSRV_HANDLE_TYPE_PHYSMEM_PMR);
+											PVRSRV_HANDLE_TYPE_PHYSMEM_PMR,
+											IMG_TRUE);
 					if(psRGXSubmitTransferOUT->eError != PVRSRV_OK)
 					{
-						PMRUnlock();
+						UnlockHandle();
 						goto RGXSubmitTransfer_exit;
 					}
 				}
-
 		}
 	}
+	/* Release now we have looked up handles. */
+	UnlockHandle();
 
 	psRGXSubmitTransferOUT->eError =
 		PVRSRVRGXSubmitTransferKM(
 					psTransferContextInt,
+					psRGXSubmitTransferIN->ui32ClientCacheOpSeqNum,
 					psRGXSubmitTransferIN->ui32PrepareCount,
 					ui32ClientFenceCountInt,
 					psFenceUFOSyncPrimBlockInt,
@@ -1286,490 +1156,235 @@
 					ui8FWCommandInt,
 					ui32TQPrepareFlagsInt,
 					psRGXSubmitTransferIN->ui32ExtJobRef,
-					psRGXSubmitTransferIN->ui32IntJobRef,
 					psRGXSubmitTransferIN->ui32SyncPMRCount,
 					ui32SyncPMRFlagsInt,
 					psSyncPMRsInt);
-	PMRUnlock();
 
 
 
 
 RGXSubmitTransfer_exit:
-	if (ui32ClientFenceCountInt)
-		OSFreeMemNoStats(ui32ClientFenceCountInt);
-	if (psFenceUFOSyncPrimBlockInt)
-		OSFreeMemNoStats(psFenceUFOSyncPrimBlockInt);
+
+	/* Lock over handle lookup cleanup. */
+	LockHandle();
+
+
+
+
+
+
+				{
+					/* Unreference the previously looked up handle */
+						if(psTransferContextInt)
+						{
+							PVRSRVReleaseHandleUnlocked(psConnection->psHandleBase,
+											hTransferContext,
+											PVRSRV_HANDLE_TYPE_RGX_SERVER_TQ_CONTEXT);
+						}
+				}
+
+
+
+
+
+
 	if (hFenceUFOSyncPrimBlockInt2)
-		OSFreeMemNoStats(hFenceUFOSyncPrimBlockInt2);
-	if (ui32FenceSyncOffsetInt)
-		OSFreeMemNoStats(ui32FenceSyncOffsetInt);
-	if (ui32FenceValueInt)
-		OSFreeMemNoStats(ui32FenceValueInt);
-	if (ui32ClientUpdateCountInt)
-		OSFreeMemNoStats(ui32ClientUpdateCountInt);
-	if (psUpdateUFOSyncPrimBlockInt)
-		OSFreeMemNoStats(psUpdateUFOSyncPrimBlockInt);
+	{
+		IMG_UINT32 i;
+
+		for (i=0;i<psRGXSubmitTransferIN->ui32PrepareCount;i++)
+		{
+			IMG_UINT32 j;
+			for (j=0;j<ui32ClientFenceCountInt[i];j++)
+			{
+				{
+					/* Unreference the previously looked up handle */
+						if(psFenceUFOSyncPrimBlockInt[i][j])
+						{
+							PVRSRVReleaseHandleUnlocked(psConnection->psHandleBase,
+											hFenceUFOSyncPrimBlockInt2[i][j],
+											PVRSRV_HANDLE_TYPE_SYNC_PRIMITIVE_BLOCK);
+						}
+				}
+			}
+		}
+	}
+
+
+
+
+
+
 	if (hUpdateUFOSyncPrimBlockInt2)
-		OSFreeMemNoStats(hUpdateUFOSyncPrimBlockInt2);
-	if (ui32UpdateSyncOffsetInt)
-		OSFreeMemNoStats(ui32UpdateSyncOffsetInt);
-	if (ui32UpdateValueInt)
-		OSFreeMemNoStats(ui32UpdateValueInt);
-	if (ui32ServerSyncCountInt)
-		OSFreeMemNoStats(ui32ServerSyncCountInt);
-	if (ui32ServerSyncFlagsInt)
-		OSFreeMemNoStats(ui32ServerSyncFlagsInt);
-	if (psServerSyncInt)
-		OSFreeMemNoStats(psServerSyncInt);
+	{
+		IMG_UINT32 i;
+
+		for (i=0;i<psRGXSubmitTransferIN->ui32PrepareCount;i++)
+		{
+			IMG_UINT32 j;
+			for (j=0;j<ui32ClientUpdateCountInt[i];j++)
+			{
+				{
+					/* Unreference the previously looked up handle */
+						if(psUpdateUFOSyncPrimBlockInt[i][j])
+						{
+							PVRSRVReleaseHandleUnlocked(psConnection->psHandleBase,
+											hUpdateUFOSyncPrimBlockInt2[i][j],
+											PVRSRV_HANDLE_TYPE_SYNC_PRIMITIVE_BLOCK);
+						}
+				}
+			}
+		}
+	}
+
+
+
+
+
+
 	if (hServerSyncInt2)
-		OSFreeMemNoStats(hServerSyncInt2);
-	if (uiUpdateFenceNameInt)
-		OSFreeMemNoStats(uiUpdateFenceNameInt);
-	if (ui32CommandSizeInt)
-		OSFreeMemNoStats(ui32CommandSizeInt);
-	if (ui8FWCommandInt)
-		OSFreeMemNoStats(ui8FWCommandInt);
-	if (ui32TQPrepareFlagsInt)
-		OSFreeMemNoStats(ui32TQPrepareFlagsInt);
-	if (ui32SyncPMRFlagsInt)
-		OSFreeMemNoStats(ui32SyncPMRFlagsInt);
-	if (psSyncPMRsInt)
-		OSFreeMemNoStats(psSyncPMRsInt);
+	{
+		IMG_UINT32 i;
+
+		for (i=0;i<psRGXSubmitTransferIN->ui32PrepareCount;i++)
+		{
+			IMG_UINT32 j;
+			for (j=0;j<ui32ServerSyncCountInt[i];j++)
+			{
+				{
+					/* Unreference the previously looked up handle */
+						if(psServerSyncInt[i][j])
+						{
+							PVRSRVReleaseHandleUnlocked(psConnection->psHandleBase,
+											hServerSyncInt2[i][j],
+											PVRSRV_HANDLE_TYPE_SERVER_SYNC_PRIMITIVE);
+						}
+				}
+			}
+		}
+	}
+
+
+
+
+
+
 	if (hSyncPMRsInt2)
-		OSFreeMemNoStats(hSyncPMRsInt2);
+	{
+		IMG_UINT32 i;
+
+		for (i=0;i<psRGXSubmitTransferIN->ui32SyncPMRCount;i++)
+		{
+				{
+					/* Unreference the previously looked up handle */
+						if(psSyncPMRsInt[i])
+						{
+							PVRSRVReleaseHandleUnlocked(psConnection->psHandleBase,
+											hSyncPMRsInt2[i],
+											PVRSRV_HANDLE_TYPE_PHYSMEM_PMR);
+						}
+				}
+		}
+	}
+	/* Release now we have cleaned up look up handles. */
+	UnlockHandle();
+
+	/* Allocated space should be equal to the last updated offset */
+	PVR_ASSERT(ui32BufferSize == ui32NextOffset);
+
+#if defined(INTEGRITY_OS)
+	if(pArrayArgsBuffer)
+#else
+	if(!bHaveEnoughSpace && pArrayArgsBuffer)
+#endif
+		OSFreeMemNoStats(pArrayArgsBuffer);
+
+	/* Allocated space should be equal to the last updated offset */
+	PVR_ASSERT(ui32BufferSize2 == ui32NextOffset2);
+
+	if(pArrayArgsBuffer2)
+		OSFreeMemNoStats(pArrayArgsBuffer2);
 
 	return 0;
 }
 
+
 static IMG_INT
 PVRSRVBridgeRGXSetTransferContextPriority(IMG_UINT32 ui32DispatchTableEntry,
 					  PVRSRV_BRIDGE_IN_RGXSETTRANSFERCONTEXTPRIORITY *psRGXSetTransferContextPriorityIN,
 					  PVRSRV_BRIDGE_OUT_RGXSETTRANSFERCONTEXTPRIORITY *psRGXSetTransferContextPriorityOUT,
 					 CONNECTION_DATA *psConnection)
 {
+	IMG_HANDLE hTransferContext = psRGXSetTransferContextPriorityIN->hTransferContext;
 	RGX_SERVER_TQ_CONTEXT * psTransferContextInt = NULL;
 
 
 
 
 
-#if defined(PDUMP)
-	PMRLock();
-#endif
+
+
+	/* Lock over handle lookup. */
+	LockHandle();
+
+
+
 
 
 				{
 					/* Look up the address from the handle */
 					psRGXSetTransferContextPriorityOUT->eError =
-						PVRSRVLookupHandle(psConnection->psHandleBase,
+						PVRSRVLookupHandleUnlocked(psConnection->psHandleBase,
 											(void **) &psTransferContextInt,
-											psRGXSetTransferContextPriorityIN->hTransferContext,
-											PVRSRV_HANDLE_TYPE_RGX_SERVER_TQ_CONTEXT);
+											hTransferContext,
+											PVRSRV_HANDLE_TYPE_RGX_SERVER_TQ_CONTEXT,
+											IMG_TRUE);
 					if(psRGXSetTransferContextPriorityOUT->eError != PVRSRV_OK)
 					{
-#if defined(PDUMP)
-						PMRUnlock();
-#endif
+						UnlockHandle();
 						goto RGXSetTransferContextPriority_exit;
 					}
 				}
-
+	/* Release now we have looked up handles. */
+	UnlockHandle();
 
 	psRGXSetTransferContextPriorityOUT->eError =
 		PVRSRVRGXSetTransferContextPriorityKM(psConnection, OSGetDevData(psConnection),
 					psTransferContextInt,
 					psRGXSetTransferContextPriorityIN->ui32Priority);
-#if defined(PDUMP)
-	PMRUnlock();
-#endif
 
 
 
 
 RGXSetTransferContextPriority_exit:
 
-	return 0;
-}
-
-static IMG_INT
-PVRSRVBridgeRGXKickSyncTransfer(IMG_UINT32 ui32DispatchTableEntry,
-					  PVRSRV_BRIDGE_IN_RGXKICKSYNCTRANSFER *psRGXKickSyncTransferIN,
-					  PVRSRV_BRIDGE_OUT_RGXKICKSYNCTRANSFER *psRGXKickSyncTransferOUT,
-					 CONNECTION_DATA *psConnection)
-{
-	RGX_SERVER_TQ_CONTEXT * psTransferContextInt = NULL;
-	SYNC_PRIMITIVE_BLOCK * *psClientFenceUFOSyncPrimBlockInt = NULL;
-	IMG_HANDLE *hClientFenceUFOSyncPrimBlockInt2 = NULL;
-	IMG_UINT32 *ui32ClientFenceSyncOffsetInt = NULL;
-	IMG_UINT32 *ui32ClientFenceValueInt = NULL;
-	SYNC_PRIMITIVE_BLOCK * *psClientUpdateUFOSyncPrimBlockInt = NULL;
-	IMG_HANDLE *hClientUpdateUFOSyncPrimBlockInt2 = NULL;
-	IMG_UINT32 *ui32ClientUpdateSyncOffsetInt = NULL;
-	IMG_UINT32 *ui32ClientUpdateValueInt = NULL;
-	IMG_UINT32 *ui32ServerSyncFlagsInt = NULL;
-	SERVER_SYNC_PRIMITIVE * *psServerSyncsInt = NULL;
-	IMG_HANDLE *hServerSyncsInt2 = NULL;
-	IMG_CHAR *uiUpdateFenceNameInt = NULL;
+	/* Lock over handle lookup cleanup. */
+	LockHandle();
 
 
 
 
-	if (psRGXKickSyncTransferIN->ui32ClientFenceCount != 0)
-	{
-		psClientFenceUFOSyncPrimBlockInt = OSAllocMemNoStats(psRGXKickSyncTransferIN->ui32ClientFenceCount * sizeof(SYNC_PRIMITIVE_BLOCK *));
-		if (!psClientFenceUFOSyncPrimBlockInt)
-		{
-			psRGXKickSyncTransferOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
-	
-			goto RGXKickSyncTransfer_exit;
-		}
-		hClientFenceUFOSyncPrimBlockInt2 = OSAllocMemNoStats(psRGXKickSyncTransferIN->ui32ClientFenceCount * sizeof(IMG_HANDLE));
-		if (!hClientFenceUFOSyncPrimBlockInt2)
-		{
-			psRGXKickSyncTransferOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
-	
-			goto RGXKickSyncTransfer_exit;
-		}
-	}
-
-			/* Copy the data over */
-			if ( !OSAccessOK(PVR_VERIFY_READ, (void*) psRGXKickSyncTransferIN->phClientFenceUFOSyncPrimBlock, psRGXKickSyncTransferIN->ui32ClientFenceCount * sizeof(IMG_HANDLE))
-				|| (OSCopyFromUser(NULL, hClientFenceUFOSyncPrimBlockInt2, psRGXKickSyncTransferIN->phClientFenceUFOSyncPrimBlock,
-				psRGXKickSyncTransferIN->ui32ClientFenceCount * sizeof(IMG_HANDLE)) != PVRSRV_OK) )
-			{
-				psRGXKickSyncTransferOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
-
-				goto RGXKickSyncTransfer_exit;
-			}
-	if (psRGXKickSyncTransferIN->ui32ClientFenceCount != 0)
-	{
-		ui32ClientFenceSyncOffsetInt = OSAllocMemNoStats(psRGXKickSyncTransferIN->ui32ClientFenceCount * sizeof(IMG_UINT32));
-		if (!ui32ClientFenceSyncOffsetInt)
-		{
-			psRGXKickSyncTransferOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
-	
-			goto RGXKickSyncTransfer_exit;
-		}
-	}
-
-			/* Copy the data over */
-			if ( !OSAccessOK(PVR_VERIFY_READ, (void*) psRGXKickSyncTransferIN->pui32ClientFenceSyncOffset, psRGXKickSyncTransferIN->ui32ClientFenceCount * sizeof(IMG_UINT32))
-				|| (OSCopyFromUser(NULL, ui32ClientFenceSyncOffsetInt, psRGXKickSyncTransferIN->pui32ClientFenceSyncOffset,
-				psRGXKickSyncTransferIN->ui32ClientFenceCount * sizeof(IMG_UINT32)) != PVRSRV_OK) )
-			{
-				psRGXKickSyncTransferOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
-
-				goto RGXKickSyncTransfer_exit;
-			}
-	if (psRGXKickSyncTransferIN->ui32ClientFenceCount != 0)
-	{
-		ui32ClientFenceValueInt = OSAllocMemNoStats(psRGXKickSyncTransferIN->ui32ClientFenceCount * sizeof(IMG_UINT32));
-		if (!ui32ClientFenceValueInt)
-		{
-			psRGXKickSyncTransferOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
-	
-			goto RGXKickSyncTransfer_exit;
-		}
-	}
-
-			/* Copy the data over */
-			if ( !OSAccessOK(PVR_VERIFY_READ, (void*) psRGXKickSyncTransferIN->pui32ClientFenceValue, psRGXKickSyncTransferIN->ui32ClientFenceCount * sizeof(IMG_UINT32))
-				|| (OSCopyFromUser(NULL, ui32ClientFenceValueInt, psRGXKickSyncTransferIN->pui32ClientFenceValue,
-				psRGXKickSyncTransferIN->ui32ClientFenceCount * sizeof(IMG_UINT32)) != PVRSRV_OK) )
-			{
-				psRGXKickSyncTransferOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
-
-				goto RGXKickSyncTransfer_exit;
-			}
-	if (psRGXKickSyncTransferIN->ui32ClientUpdateCount != 0)
-	{
-		psClientUpdateUFOSyncPrimBlockInt = OSAllocMemNoStats(psRGXKickSyncTransferIN->ui32ClientUpdateCount * sizeof(SYNC_PRIMITIVE_BLOCK *));
-		if (!psClientUpdateUFOSyncPrimBlockInt)
-		{
-			psRGXKickSyncTransferOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
-	
-			goto RGXKickSyncTransfer_exit;
-		}
-		hClientUpdateUFOSyncPrimBlockInt2 = OSAllocMemNoStats(psRGXKickSyncTransferIN->ui32ClientUpdateCount * sizeof(IMG_HANDLE));
-		if (!hClientUpdateUFOSyncPrimBlockInt2)
-		{
-			psRGXKickSyncTransferOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
-	
-			goto RGXKickSyncTransfer_exit;
-		}
-	}
-
-			/* Copy the data over */
-			if ( !OSAccessOK(PVR_VERIFY_READ, (void*) psRGXKickSyncTransferIN->phClientUpdateUFOSyncPrimBlock, psRGXKickSyncTransferIN->ui32ClientUpdateCount * sizeof(IMG_HANDLE))
-				|| (OSCopyFromUser(NULL, hClientUpdateUFOSyncPrimBlockInt2, psRGXKickSyncTransferIN->phClientUpdateUFOSyncPrimBlock,
-				psRGXKickSyncTransferIN->ui32ClientUpdateCount * sizeof(IMG_HANDLE)) != PVRSRV_OK) )
-			{
-				psRGXKickSyncTransferOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
-
-				goto RGXKickSyncTransfer_exit;
-			}
-	if (psRGXKickSyncTransferIN->ui32ClientUpdateCount != 0)
-	{
-		ui32ClientUpdateSyncOffsetInt = OSAllocMemNoStats(psRGXKickSyncTransferIN->ui32ClientUpdateCount * sizeof(IMG_UINT32));
-		if (!ui32ClientUpdateSyncOffsetInt)
-		{
-			psRGXKickSyncTransferOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
-	
-			goto RGXKickSyncTransfer_exit;
-		}
-	}
-
-			/* Copy the data over */
-			if ( !OSAccessOK(PVR_VERIFY_READ, (void*) psRGXKickSyncTransferIN->pui32ClientUpdateSyncOffset, psRGXKickSyncTransferIN->ui32ClientUpdateCount * sizeof(IMG_UINT32))
-				|| (OSCopyFromUser(NULL, ui32ClientUpdateSyncOffsetInt, psRGXKickSyncTransferIN->pui32ClientUpdateSyncOffset,
-				psRGXKickSyncTransferIN->ui32ClientUpdateCount * sizeof(IMG_UINT32)) != PVRSRV_OK) )
-			{
-				psRGXKickSyncTransferOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
-
-				goto RGXKickSyncTransfer_exit;
-			}
-	if (psRGXKickSyncTransferIN->ui32ClientUpdateCount != 0)
-	{
-		ui32ClientUpdateValueInt = OSAllocMemNoStats(psRGXKickSyncTransferIN->ui32ClientUpdateCount * sizeof(IMG_UINT32));
-		if (!ui32ClientUpdateValueInt)
-		{
-			psRGXKickSyncTransferOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
-	
-			goto RGXKickSyncTransfer_exit;
-		}
-	}
-
-			/* Copy the data over */
-			if ( !OSAccessOK(PVR_VERIFY_READ, (void*) psRGXKickSyncTransferIN->pui32ClientUpdateValue, psRGXKickSyncTransferIN->ui32ClientUpdateCount * sizeof(IMG_UINT32))
-				|| (OSCopyFromUser(NULL, ui32ClientUpdateValueInt, psRGXKickSyncTransferIN->pui32ClientUpdateValue,
-				psRGXKickSyncTransferIN->ui32ClientUpdateCount * sizeof(IMG_UINT32)) != PVRSRV_OK) )
-			{
-				psRGXKickSyncTransferOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
-
-				goto RGXKickSyncTransfer_exit;
-			}
-	if (psRGXKickSyncTransferIN->ui32ServerSyncCount != 0)
-	{
-		ui32ServerSyncFlagsInt = OSAllocMemNoStats(psRGXKickSyncTransferIN->ui32ServerSyncCount * sizeof(IMG_UINT32));
-		if (!ui32ServerSyncFlagsInt)
-		{
-			psRGXKickSyncTransferOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
-	
-			goto RGXKickSyncTransfer_exit;
-		}
-	}
-
-			/* Copy the data over */
-			if ( !OSAccessOK(PVR_VERIFY_READ, (void*) psRGXKickSyncTransferIN->pui32ServerSyncFlags, psRGXKickSyncTransferIN->ui32ServerSyncCount * sizeof(IMG_UINT32))
-				|| (OSCopyFromUser(NULL, ui32ServerSyncFlagsInt, psRGXKickSyncTransferIN->pui32ServerSyncFlags,
-				psRGXKickSyncTransferIN->ui32ServerSyncCount * sizeof(IMG_UINT32)) != PVRSRV_OK) )
-			{
-				psRGXKickSyncTransferOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
-
-				goto RGXKickSyncTransfer_exit;
-			}
-	if (psRGXKickSyncTransferIN->ui32ServerSyncCount != 0)
-	{
-		psServerSyncsInt = OSAllocMemNoStats(psRGXKickSyncTransferIN->ui32ServerSyncCount * sizeof(SERVER_SYNC_PRIMITIVE *));
-		if (!psServerSyncsInt)
-		{
-			psRGXKickSyncTransferOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
-	
-			goto RGXKickSyncTransfer_exit;
-		}
-		hServerSyncsInt2 = OSAllocMemNoStats(psRGXKickSyncTransferIN->ui32ServerSyncCount * sizeof(IMG_HANDLE));
-		if (!hServerSyncsInt2)
-		{
-			psRGXKickSyncTransferOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
-	
-			goto RGXKickSyncTransfer_exit;
-		}
-	}
-
-			/* Copy the data over */
-			if ( !OSAccessOK(PVR_VERIFY_READ, (void*) psRGXKickSyncTransferIN->phServerSyncs, psRGXKickSyncTransferIN->ui32ServerSyncCount * sizeof(IMG_HANDLE))
-				|| (OSCopyFromUser(NULL, hServerSyncsInt2, psRGXKickSyncTransferIN->phServerSyncs,
-				psRGXKickSyncTransferIN->ui32ServerSyncCount * sizeof(IMG_HANDLE)) != PVRSRV_OK) )
-			{
-				psRGXKickSyncTransferOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
-
-				goto RGXKickSyncTransfer_exit;
-			}
-	
-	{
-		uiUpdateFenceNameInt = OSAllocMemNoStats(32 * sizeof(IMG_CHAR));
-		if (!uiUpdateFenceNameInt)
-		{
-			psRGXKickSyncTransferOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
-	
-			goto RGXKickSyncTransfer_exit;
-		}
-	}
-
-			/* Copy the data over */
-			if ( !OSAccessOK(PVR_VERIFY_READ, (void*) psRGXKickSyncTransferIN->puiUpdateFenceName, 32 * sizeof(IMG_CHAR))
-				|| (OSCopyFromUser(NULL, uiUpdateFenceNameInt, psRGXKickSyncTransferIN->puiUpdateFenceName,
-				32 * sizeof(IMG_CHAR)) != PVRSRV_OK) )
-			{
-				psRGXKickSyncTransferOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
-
-				goto RGXKickSyncTransfer_exit;
-			}
-
-#if defined(PDUMP)
-	PMRLock();
-#endif
 
 
 				{
-					/* Look up the address from the handle */
-					psRGXKickSyncTransferOUT->eError =
-						PVRSRVLookupHandle(psConnection->psHandleBase,
-											(void **) &psTransferContextInt,
-											psRGXKickSyncTransferIN->hTransferContext,
+					/* Unreference the previously looked up handle */
+						if(psTransferContextInt)
+						{
+							PVRSRVReleaseHandleUnlocked(psConnection->psHandleBase,
+											hTransferContext,
 											PVRSRV_HANDLE_TYPE_RGX_SERVER_TQ_CONTEXT);
-					if(psRGXKickSyncTransferOUT->eError != PVRSRV_OK)
-					{
-#if defined(PDUMP)
-						PMRUnlock();
-#endif
-						goto RGXKickSyncTransfer_exit;
-					}
+						}
 				}
+	/* Release now we have cleaned up look up handles. */
+	UnlockHandle();
 
 
-	{
-		IMG_UINT32 i;
-
-		for (i=0;i<psRGXKickSyncTransferIN->ui32ClientFenceCount;i++)
-		{
-				{
-					/* Look up the address from the handle */
-					psRGXKickSyncTransferOUT->eError =
-						PVRSRVLookupHandle(psConnection->psHandleBase,
-											(void **) &psClientFenceUFOSyncPrimBlockInt[i],
-											hClientFenceUFOSyncPrimBlockInt2[i],
-											PVRSRV_HANDLE_TYPE_SYNC_PRIMITIVE_BLOCK);
-					if(psRGXKickSyncTransferOUT->eError != PVRSRV_OK)
-					{
-#if defined(PDUMP)
-						PMRUnlock();
-#endif
-						goto RGXKickSyncTransfer_exit;
-					}
-				}
-
-		}
-	}
-
-	{
-		IMG_UINT32 i;
-
-		for (i=0;i<psRGXKickSyncTransferIN->ui32ClientUpdateCount;i++)
-		{
-				{
-					/* Look up the address from the handle */
-					psRGXKickSyncTransferOUT->eError =
-						PVRSRVLookupHandle(psConnection->psHandleBase,
-											(void **) &psClientUpdateUFOSyncPrimBlockInt[i],
-											hClientUpdateUFOSyncPrimBlockInt2[i],
-											PVRSRV_HANDLE_TYPE_SYNC_PRIMITIVE_BLOCK);
-					if(psRGXKickSyncTransferOUT->eError != PVRSRV_OK)
-					{
-#if defined(PDUMP)
-						PMRUnlock();
-#endif
-						goto RGXKickSyncTransfer_exit;
-					}
-				}
-
-		}
-	}
-
-	{
-		IMG_UINT32 i;
-
-		for (i=0;i<psRGXKickSyncTransferIN->ui32ServerSyncCount;i++)
-		{
-				{
-					/* Look up the address from the handle */
-					psRGXKickSyncTransferOUT->eError =
-						PVRSRVLookupHandle(psConnection->psHandleBase,
-											(void **) &psServerSyncsInt[i],
-											hServerSyncsInt2[i],
-											PVRSRV_HANDLE_TYPE_SERVER_SYNC_PRIMITIVE);
-					if(psRGXKickSyncTransferOUT->eError != PVRSRV_OK)
-					{
-#if defined(PDUMP)
-						PMRUnlock();
-#endif
-						goto RGXKickSyncTransfer_exit;
-					}
-				}
-
-		}
-	}
-
-	psRGXKickSyncTransferOUT->eError =
-		PVRSRVRGXKickSyncTransferKM(
-					psTransferContextInt,
-					psRGXKickSyncTransferIN->ui32ClientFenceCount,
-					psClientFenceUFOSyncPrimBlockInt,
-					ui32ClientFenceSyncOffsetInt,
-					ui32ClientFenceValueInt,
-					psRGXKickSyncTransferIN->ui32ClientUpdateCount,
-					psClientUpdateUFOSyncPrimBlockInt,
-					ui32ClientUpdateSyncOffsetInt,
-					ui32ClientUpdateValueInt,
-					psRGXKickSyncTransferIN->ui32ServerSyncCount,
-					ui32ServerSyncFlagsInt,
-					psServerSyncsInt,
-					psRGXKickSyncTransferIN->i32CheckFenceFD,
-					psRGXKickSyncTransferIN->i32UpdateTimelineFD,
-					&psRGXKickSyncTransferOUT->i32UpdateFenceFD,
-					uiUpdateFenceNameInt,
-					psRGXKickSyncTransferIN->ui32TQPrepareFlags,
-					psRGXKickSyncTransferIN->ui32ExtJobRef,
-					psRGXKickSyncTransferIN->ui32IntJobRef);
-#if defined(PDUMP)
-	PMRUnlock();
-#endif
-
-
-
-
-RGXKickSyncTransfer_exit:
-	if (psClientFenceUFOSyncPrimBlockInt)
-		OSFreeMemNoStats(psClientFenceUFOSyncPrimBlockInt);
-	if (hClientFenceUFOSyncPrimBlockInt2)
-		OSFreeMemNoStats(hClientFenceUFOSyncPrimBlockInt2);
-	if (ui32ClientFenceSyncOffsetInt)
-		OSFreeMemNoStats(ui32ClientFenceSyncOffsetInt);
-	if (ui32ClientFenceValueInt)
-		OSFreeMemNoStats(ui32ClientFenceValueInt);
-	if (psClientUpdateUFOSyncPrimBlockInt)
-		OSFreeMemNoStats(psClientUpdateUFOSyncPrimBlockInt);
-	if (hClientUpdateUFOSyncPrimBlockInt2)
-		OSFreeMemNoStats(hClientUpdateUFOSyncPrimBlockInt2);
-	if (ui32ClientUpdateSyncOffsetInt)
-		OSFreeMemNoStats(ui32ClientUpdateSyncOffsetInt);
-	if (ui32ClientUpdateValueInt)
-		OSFreeMemNoStats(ui32ClientUpdateValueInt);
-	if (ui32ServerSyncFlagsInt)
-		OSFreeMemNoStats(ui32ServerSyncFlagsInt);
-	if (psServerSyncsInt)
-		OSFreeMemNoStats(psServerSyncsInt);
-	if (hServerSyncsInt2)
-		OSFreeMemNoStats(hServerSyncsInt2);
-	if (uiUpdateFenceNameInt)
-		OSFreeMemNoStats(uiUpdateFenceNameInt);
-
 	return 0;
 }
 
 
 
+
 /* *************************************************************************** 
  * Server bridge dispatch related glue 
  */
@@ -1797,9 +1412,6 @@
 	SetDispatchTableEntry(PVRSRV_BRIDGE_RGXTQ, PVRSRV_BRIDGE_RGXTQ_RGXSETTRANSFERCONTEXTPRIORITY, PVRSRVBridgeRGXSetTransferContextPriority,
 					NULL, bUseLock);
 
-	SetDispatchTableEntry(PVRSRV_BRIDGE_RGXTQ, PVRSRV_BRIDGE_RGXTQ_RGXKICKSYNCTRANSFER, PVRSRVBridgeRGXKickSyncTransfer,
-					NULL, bUseLock);
-
 
 	return PVRSRV_OK;
 }
@@ -1811,4 +1423,3 @@
 {
 	return PVRSRV_OK;
 }
-
diff --git a/drivers/staging/imgtec/rogue/generated/ri_bridge/common_ri_bridge.h b/drivers/staging/imgtec/rogue/generated/ri_bridge/common_ri_bridge.h
index 3c5fa89..71f2fba 100644
--- a/drivers/staging/imgtec/rogue/generated/ri_bridge/common_ri_bridge.h
+++ b/drivers/staging/imgtec/rogue/generated/ri_bridge/common_ri_bridge.h
@@ -2,8 +2,8 @@
 @File
 @Title          Common bridge header for ri
 @Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
-@Description    Declares common defines and structures that are used by both
-                the client and sever side of the bridge for ri
+@Description    Declares common defines and structures used by both the client
+                and server side of the bridge for ri
 @License        Dual MIT/GPLv2
 
 The contents of this file are subject to the MIT license as set out below.
@@ -45,6 +45,8 @@
 #ifndef COMMON_RI_BRIDGE_H
 #define COMMON_RI_BRIDGE_H
 
+#include <powervr/mem_types.h>
+
 #include "img_types.h"
 #include "pvrsrv_error.h"
 
diff --git a/drivers/staging/imgtec/rogue/generated/ri_bridge/server_ri_bridge.c b/drivers/staging/imgtec/rogue/generated/ri_bridge/server_ri_bridge.c
index ed059c1..c1553c2 100644
--- a/drivers/staging/imgtec/rogue/generated/ri_bridge/server_ri_bridge.c
+++ b/drivers/staging/imgtec/rogue/generated/ri_bridge/server_ri_bridge.c
@@ -64,6 +64,8 @@
 
 
 
+
+
 /* ***************************************************************************
  * Server-side bridge entry points
  */
@@ -74,48 +76,91 @@
 					  PVRSRV_BRIDGE_OUT_RIWRITEPMRENTRY *psRIWritePMREntryOUT,
 					 CONNECTION_DATA *psConnection)
 {
+	IMG_HANDLE hPMRHandle = psRIWritePMREntryIN->hPMRHandle;
 	PMR * psPMRHandleInt = NULL;
 	IMG_CHAR *uiTextAInt = NULL;
 
+	IMG_UINT32 ui32NextOffset = 0;
+	IMG_BYTE   *pArrayArgsBuffer = NULL;
+#if !defined(INTEGRITY_OS)
+	IMG_BOOL bHaveEnoughSpace = IMG_FALSE;
+#endif
+
+	IMG_UINT32 ui32BufferSize = 
+			(psRIWritePMREntryIN->ui32TextASize * sizeof(IMG_CHAR)) +
+			0;
 
 
 
-	if (psRIWritePMREntryIN->ui32TextASize != 0)
+
+
+	if (ui32BufferSize != 0)
 	{
-		uiTextAInt = OSAllocMemNoStats(psRIWritePMREntryIN->ui32TextASize * sizeof(IMG_CHAR));
-		if (!uiTextAInt)
+#if !defined(INTEGRITY_OS)
+		/* Try to use remainder of input buffer for copies if possible, word-aligned for safety. */
+		IMG_UINT32 ui32InBufferOffset = PVR_ALIGN(sizeof(*psRIWritePMREntryIN), sizeof(unsigned long));
+		IMG_UINT32 ui32InBufferExcessSize = ui32InBufferOffset >= PVRSRV_MAX_BRIDGE_IN_SIZE ? 0 :
+			PVRSRV_MAX_BRIDGE_IN_SIZE - ui32InBufferOffset;
+
+		bHaveEnoughSpace = ui32BufferSize <= ui32InBufferExcessSize;
+		if (bHaveEnoughSpace)
 		{
-			psRIWritePMREntryOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
-	
-			goto RIWritePMREntry_exit;
+			IMG_BYTE *pInputBuffer = (IMG_BYTE *)psRIWritePMREntryIN;
+
+			pArrayArgsBuffer = &pInputBuffer[ui32InBufferOffset];		}
+		else
+#endif
+		{
+			pArrayArgsBuffer = OSAllocMemNoStats(ui32BufferSize);
+
+			if(!pArrayArgsBuffer)
+			{
+				psRIWritePMREntryOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
+				goto RIWritePMREntry_exit;
+			}
 		}
 	}
 
-			/* Copy the data over */
-			if ( !OSAccessOK(PVR_VERIFY_READ, (void*) psRIWritePMREntryIN->puiTextA, psRIWritePMREntryIN->ui32TextASize * sizeof(IMG_CHAR))
-				|| (OSCopyFromUser(NULL, uiTextAInt, psRIWritePMREntryIN->puiTextA,
-				psRIWritePMREntryIN->ui32TextASize * sizeof(IMG_CHAR)) != PVRSRV_OK) )
-			{
-				psRIWritePMREntryOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
+	if (psRIWritePMREntryIN->ui32TextASize != 0)
+	{
+		uiTextAInt = (IMG_CHAR*)(((IMG_UINT8 *)pArrayArgsBuffer) + ui32NextOffset);
+		ui32NextOffset += psRIWritePMREntryIN->ui32TextASize * sizeof(IMG_CHAR);
+	}
 
-				goto RIWritePMREntry_exit;
+			/* Copy the data over */
+			if (psRIWritePMREntryIN->ui32TextASize * sizeof(IMG_CHAR) > 0)
+			{
+				if ( OSCopyFromUser(NULL, uiTextAInt, psRIWritePMREntryIN->puiTextA, psRIWritePMREntryIN->ui32TextASize * sizeof(IMG_CHAR)) != PVRSRV_OK )
+				{
+					psRIWritePMREntryOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
+
+					goto RIWritePMREntry_exit;
+				}
 			}
 
+	/* Lock over handle lookup. */
+	LockHandle();
+
+
+
 
 
 				{
 					/* Look up the address from the handle */
 					psRIWritePMREntryOUT->eError =
-						PVRSRVLookupHandle(psConnection->psHandleBase,
+						PVRSRVLookupHandleUnlocked(psConnection->psHandleBase,
 											(void **) &psPMRHandleInt,
-											psRIWritePMREntryIN->hPMRHandle,
-											PVRSRV_HANDLE_TYPE_PHYSMEM_PMR);
+											hPMRHandle,
+											PVRSRV_HANDLE_TYPE_PHYSMEM_PMR,
+											IMG_TRUE);
 					if(psRIWritePMREntryOUT->eError != PVRSRV_OK)
 					{
+						UnlockHandle();
 						goto RIWritePMREntry_exit;
 					}
 				}
-
+	/* Release now we have looked up handles. */
+	UnlockHandle();
 
 	psRIWritePMREntryOUT->eError =
 		RIWritePMREntryKM(
@@ -128,61 +173,134 @@
 
 
 RIWritePMREntry_exit:
-	if (uiTextAInt)
-		OSFreeMemNoStats(uiTextAInt);
+
+	/* Lock over handle lookup cleanup. */
+	LockHandle();
+
+
+
+
+
+
+				{
+					/* Unreference the previously looked up handle */
+						if(psPMRHandleInt)
+						{
+							PVRSRVReleaseHandleUnlocked(psConnection->psHandleBase,
+											hPMRHandle,
+											PVRSRV_HANDLE_TYPE_PHYSMEM_PMR);
+						}
+				}
+	/* Release now we have cleaned up look up handles. */
+	UnlockHandle();
+
+	/* Allocated space should be equal to the last updated offset */
+	PVR_ASSERT(ui32BufferSize == ui32NextOffset);
+
+#if defined(INTEGRITY_OS)
+	if(pArrayArgsBuffer)
+#else
+	if(!bHaveEnoughSpace && pArrayArgsBuffer)
+#endif
+		OSFreeMemNoStats(pArrayArgsBuffer);
+
 
 	return 0;
 }
 
+
 static IMG_INT
 PVRSRVBridgeRIWriteMEMDESCEntry(IMG_UINT32 ui32DispatchTableEntry,
 					  PVRSRV_BRIDGE_IN_RIWRITEMEMDESCENTRY *psRIWriteMEMDESCEntryIN,
 					  PVRSRV_BRIDGE_OUT_RIWRITEMEMDESCENTRY *psRIWriteMEMDESCEntryOUT,
 					 CONNECTION_DATA *psConnection)
 {
+	IMG_HANDLE hPMRHandle = psRIWriteMEMDESCEntryIN->hPMRHandle;
 	PMR * psPMRHandleInt = NULL;
 	IMG_CHAR *uiTextBInt = NULL;
 	RI_HANDLE psRIHandleInt = NULL;
 
+	IMG_UINT32 ui32NextOffset = 0;
+	IMG_BYTE   *pArrayArgsBuffer = NULL;
+#if !defined(INTEGRITY_OS)
+	IMG_BOOL bHaveEnoughSpace = IMG_FALSE;
+#endif
+
+	IMG_UINT32 ui32BufferSize = 
+			(psRIWriteMEMDESCEntryIN->ui32TextBSize * sizeof(IMG_CHAR)) +
+			0;
 
 
 
-	if (psRIWriteMEMDESCEntryIN->ui32TextBSize != 0)
+
+
+	if (ui32BufferSize != 0)
 	{
-		uiTextBInt = OSAllocMemNoStats(psRIWriteMEMDESCEntryIN->ui32TextBSize * sizeof(IMG_CHAR));
-		if (!uiTextBInt)
+#if !defined(INTEGRITY_OS)
+		/* Try to use remainder of input buffer for copies if possible, word-aligned for safety. */
+		IMG_UINT32 ui32InBufferOffset = PVR_ALIGN(sizeof(*psRIWriteMEMDESCEntryIN), sizeof(unsigned long));
+		IMG_UINT32 ui32InBufferExcessSize = ui32InBufferOffset >= PVRSRV_MAX_BRIDGE_IN_SIZE ? 0 :
+			PVRSRV_MAX_BRIDGE_IN_SIZE - ui32InBufferOffset;
+
+		bHaveEnoughSpace = ui32BufferSize <= ui32InBufferExcessSize;
+		if (bHaveEnoughSpace)
 		{
-			psRIWriteMEMDESCEntryOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
-	
-			goto RIWriteMEMDESCEntry_exit;
+			IMG_BYTE *pInputBuffer = (IMG_BYTE *)psRIWriteMEMDESCEntryIN;
+
+			pArrayArgsBuffer = &pInputBuffer[ui32InBufferOffset];		}
+		else
+#endif
+		{
+			pArrayArgsBuffer = OSAllocMemNoStats(ui32BufferSize);
+
+			if(!pArrayArgsBuffer)
+			{
+				psRIWriteMEMDESCEntryOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
+				goto RIWriteMEMDESCEntry_exit;
+			}
 		}
 	}
 
-			/* Copy the data over */
-			if ( !OSAccessOK(PVR_VERIFY_READ, (void*) psRIWriteMEMDESCEntryIN->puiTextB, psRIWriteMEMDESCEntryIN->ui32TextBSize * sizeof(IMG_CHAR))
-				|| (OSCopyFromUser(NULL, uiTextBInt, psRIWriteMEMDESCEntryIN->puiTextB,
-				psRIWriteMEMDESCEntryIN->ui32TextBSize * sizeof(IMG_CHAR)) != PVRSRV_OK) )
-			{
-				psRIWriteMEMDESCEntryOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
+	if (psRIWriteMEMDESCEntryIN->ui32TextBSize != 0)
+	{
+		uiTextBInt = (IMG_CHAR*)(((IMG_UINT8 *)pArrayArgsBuffer) + ui32NextOffset);
+		ui32NextOffset += psRIWriteMEMDESCEntryIN->ui32TextBSize * sizeof(IMG_CHAR);
+	}
 
-				goto RIWriteMEMDESCEntry_exit;
+			/* Copy the data over */
+			if (psRIWriteMEMDESCEntryIN->ui32TextBSize * sizeof(IMG_CHAR) > 0)
+			{
+				if ( OSCopyFromUser(NULL, uiTextBInt, psRIWriteMEMDESCEntryIN->puiTextB, psRIWriteMEMDESCEntryIN->ui32TextBSize * sizeof(IMG_CHAR)) != PVRSRV_OK )
+				{
+					psRIWriteMEMDESCEntryOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
+
+					goto RIWriteMEMDESCEntry_exit;
+				}
 			}
 
+	/* Lock over handle lookup. */
+	LockHandle();
+
+
+
 
 
 				{
 					/* Look up the address from the handle */
 					psRIWriteMEMDESCEntryOUT->eError =
-						PVRSRVLookupHandle(psConnection->psHandleBase,
+						PVRSRVLookupHandleUnlocked(psConnection->psHandleBase,
 											(void **) &psPMRHandleInt,
-											psRIWriteMEMDESCEntryIN->hPMRHandle,
-											PVRSRV_HANDLE_TYPE_PHYSMEM_PMR);
+											hPMRHandle,
+											PVRSRV_HANDLE_TYPE_PHYSMEM_PMR,
+											IMG_TRUE);
 					if(psRIWriteMEMDESCEntryOUT->eError != PVRSRV_OK)
 					{
+						UnlockHandle();
 						goto RIWriteMEMDESCEntry_exit;
 					}
 				}
-
+	/* Release now we have looked up handles. */
+	UnlockHandle();
 
 	psRIWriteMEMDESCEntryOUT->eError =
 		RIWriteMEMDESCEntryKM(
@@ -201,8 +319,15 @@
 		goto RIWriteMEMDESCEntry_exit;
 	}
 
+	/* Lock over handle creation. */
+	LockHandle();
 
-	psRIWriteMEMDESCEntryOUT->eError = PVRSRVAllocHandle(psConnection->psHandleBase,
+
+
+
+
+	psRIWriteMEMDESCEntryOUT->eError = PVRSRVAllocHandleUnlocked(psConnection->psHandleBase,
+
 							&psRIWriteMEMDESCEntryOUT->hRIHandle,
 							(void *) psRIHandleInt,
 							PVRSRV_HANDLE_TYPE_RI_HANDLE,
@@ -210,13 +335,37 @@
 							,(PFN_HANDLE_RELEASE)&RIDeleteMEMDESCEntryKM);
 	if (psRIWriteMEMDESCEntryOUT->eError != PVRSRV_OK)
 	{
+		UnlockHandle();
 		goto RIWriteMEMDESCEntry_exit;
 	}
 
+	/* Release now we have created handles. */
+	UnlockHandle();
 
 
 
 RIWriteMEMDESCEntry_exit:
+
+	/* Lock over handle lookup cleanup. */
+	LockHandle();
+
+
+
+
+
+
+				{
+					/* Unreference the previously looked up handle */
+						if(psPMRHandleInt)
+						{
+							PVRSRVReleaseHandleUnlocked(psConnection->psHandleBase,
+											hPMRHandle,
+											PVRSRV_HANDLE_TYPE_PHYSMEM_PMR);
+						}
+				}
+	/* Release now we have cleaned up look up handles. */
+	UnlockHandle();
+
 	if (psRIWriteMEMDESCEntryOUT->eError != PVRSRV_OK)
 	{
 		if (psRIHandleInt)
@@ -225,12 +374,21 @@
 		}
 	}
 
-	if (uiTextBInt)
-		OSFreeMemNoStats(uiTextBInt);
+	/* Allocated space should be equal to the last updated offset */
+	PVR_ASSERT(ui32BufferSize == ui32NextOffset);
+
+#if defined(INTEGRITY_OS)
+	if(pArrayArgsBuffer)
+#else
+	if(!bHaveEnoughSpace && pArrayArgsBuffer)
+#endif
+		OSFreeMemNoStats(pArrayArgsBuffer);
+
 
 	return 0;
 }
 
+
 static IMG_INT
 PVRSRVBridgeRIWriteProcListEntry(IMG_UINT32 ui32DispatchTableEntry,
 					  PVRSRV_BRIDGE_IN_RIWRITEPROCLISTENTRY *psRIWriteProcListEntryIN,
@@ -240,32 +398,65 @@
 	IMG_CHAR *uiTextBInt = NULL;
 	RI_HANDLE psRIHandleInt = NULL;
 
+	IMG_UINT32 ui32NextOffset = 0;
+	IMG_BYTE   *pArrayArgsBuffer = NULL;
+#if !defined(INTEGRITY_OS)
+	IMG_BOOL bHaveEnoughSpace = IMG_FALSE;
+#endif
+
+	IMG_UINT32 ui32BufferSize = 
+			(psRIWriteProcListEntryIN->ui32TextBSize * sizeof(IMG_CHAR)) +
+			0;
 
 
 
-	if (psRIWriteProcListEntryIN->ui32TextBSize != 0)
+
+
+	if (ui32BufferSize != 0)
 	{
-		uiTextBInt = OSAllocMemNoStats(psRIWriteProcListEntryIN->ui32TextBSize * sizeof(IMG_CHAR));
-		if (!uiTextBInt)
+#if !defined(INTEGRITY_OS)
+		/* Try to use remainder of input buffer for copies if possible, word-aligned for safety. */
+		IMG_UINT32 ui32InBufferOffset = PVR_ALIGN(sizeof(*psRIWriteProcListEntryIN), sizeof(unsigned long));
+		IMG_UINT32 ui32InBufferExcessSize = ui32InBufferOffset >= PVRSRV_MAX_BRIDGE_IN_SIZE ? 0 :
+			PVRSRV_MAX_BRIDGE_IN_SIZE - ui32InBufferOffset;
+
+		bHaveEnoughSpace = ui32BufferSize <= ui32InBufferExcessSize;
+		if (bHaveEnoughSpace)
 		{
-			psRIWriteProcListEntryOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
-	
-			goto RIWriteProcListEntry_exit;
+			IMG_BYTE *pInputBuffer = (IMG_BYTE *)psRIWriteProcListEntryIN;
+
+			pArrayArgsBuffer = &pInputBuffer[ui32InBufferOffset];		}
+		else
+#endif
+		{
+			pArrayArgsBuffer = OSAllocMemNoStats(ui32BufferSize);
+
+			if(!pArrayArgsBuffer)
+			{
+				psRIWriteProcListEntryOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
+				goto RIWriteProcListEntry_exit;
+			}
 		}
 	}
 
+	if (psRIWriteProcListEntryIN->ui32TextBSize != 0)
+	{
+		uiTextBInt = (IMG_CHAR*)(((IMG_UINT8 *)pArrayArgsBuffer) + ui32NextOffset);
+		ui32NextOffset += psRIWriteProcListEntryIN->ui32TextBSize * sizeof(IMG_CHAR);
+	}
+
 			/* Copy the data over */
-			if ( !OSAccessOK(PVR_VERIFY_READ, (void*) psRIWriteProcListEntryIN->puiTextB, psRIWriteProcListEntryIN->ui32TextBSize * sizeof(IMG_CHAR))
-				|| (OSCopyFromUser(NULL, uiTextBInt, psRIWriteProcListEntryIN->puiTextB,
-				psRIWriteProcListEntryIN->ui32TextBSize * sizeof(IMG_CHAR)) != PVRSRV_OK) )
+			if (psRIWriteProcListEntryIN->ui32TextBSize * sizeof(IMG_CHAR) > 0)
 			{
-				psRIWriteProcListEntryOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
+				if ( OSCopyFromUser(NULL, uiTextBInt, psRIWriteProcListEntryIN->puiTextB, psRIWriteProcListEntryIN->ui32TextBSize * sizeof(IMG_CHAR)) != PVRSRV_OK )
+				{
+					psRIWriteProcListEntryOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
 
-				goto RIWriteProcListEntry_exit;
+					goto RIWriteProcListEntry_exit;
+				}
 			}
 
 
-
 	psRIWriteProcListEntryOUT->eError =
 		RIWriteProcListEntryKM(
 					psRIWriteProcListEntryIN->ui32TextBSize,
@@ -280,8 +471,15 @@
 		goto RIWriteProcListEntry_exit;
 	}
 
+	/* Lock over handle creation. */
+	LockHandle();
 
-	psRIWriteProcListEntryOUT->eError = PVRSRVAllocHandle(psConnection->psHandleBase,
+
+
+
+
+	psRIWriteProcListEntryOUT->eError = PVRSRVAllocHandleUnlocked(psConnection->psHandleBase,
+
 							&psRIWriteProcListEntryOUT->hRIHandle,
 							(void *) psRIHandleInt,
 							PVRSRV_HANDLE_TYPE_RI_HANDLE,
@@ -289,13 +487,19 @@
 							,(PFN_HANDLE_RELEASE)&RIDeleteMEMDESCEntryKM);
 	if (psRIWriteProcListEntryOUT->eError != PVRSRV_OK)
 	{
+		UnlockHandle();
 		goto RIWriteProcListEntry_exit;
 	}
 
+	/* Release now we have created handles. */
+	UnlockHandle();
 
 
 
 RIWriteProcListEntry_exit:
+
+
+
 	if (psRIWriteProcListEntryOUT->eError != PVRSRV_OK)
 	{
 		if (psRIHandleInt)
@@ -304,18 +508,28 @@
 		}
 	}
 
-	if (uiTextBInt)
-		OSFreeMemNoStats(uiTextBInt);
+	/* Allocated space should be equal to the last updated offset */
+	PVR_ASSERT(ui32BufferSize == ui32NextOffset);
+
+#if defined(INTEGRITY_OS)
+	if(pArrayArgsBuffer)
+#else
+	if(!bHaveEnoughSpace && pArrayArgsBuffer)
+#endif
+		OSFreeMemNoStats(pArrayArgsBuffer);
+
 
 	return 0;
 }
 
+
 static IMG_INT
 PVRSRVBridgeRIUpdateMEMDESCAddr(IMG_UINT32 ui32DispatchTableEntry,
 					  PVRSRV_BRIDGE_IN_RIUPDATEMEMDESCADDR *psRIUpdateMEMDESCAddrIN,
 					  PVRSRV_BRIDGE_OUT_RIUPDATEMEMDESCADDR *psRIUpdateMEMDESCAddrOUT,
 					 CONNECTION_DATA *psConnection)
 {
+	IMG_HANDLE hRIHandle = psRIUpdateMEMDESCAddrIN->hRIHandle;
 	RI_HANDLE psRIHandleInt = NULL;
 
 
@@ -324,19 +538,29 @@
 
 
 
+	/* Lock over handle lookup. */
+	LockHandle();
+
+
+
+
+
 				{
 					/* Look up the address from the handle */
 					psRIUpdateMEMDESCAddrOUT->eError =
-						PVRSRVLookupHandle(psConnection->psHandleBase,
+						PVRSRVLookupHandleUnlocked(psConnection->psHandleBase,
 											(void **) &psRIHandleInt,
-											psRIUpdateMEMDESCAddrIN->hRIHandle,
-											PVRSRV_HANDLE_TYPE_RI_HANDLE);
+											hRIHandle,
+											PVRSRV_HANDLE_TYPE_RI_HANDLE,
+											IMG_TRUE);
 					if(psRIUpdateMEMDESCAddrOUT->eError != PVRSRV_OK)
 					{
+						UnlockHandle();
 						goto RIUpdateMEMDESCAddr_exit;
 					}
 				}
-
+	/* Release now we have looked up handles. */
+	UnlockHandle();
 
 	psRIUpdateMEMDESCAddrOUT->eError =
 		RIUpdateMEMDESCAddrKM(
@@ -348,15 +572,38 @@
 
 RIUpdateMEMDESCAddr_exit:
 
+	/* Lock over handle lookup cleanup. */
+	LockHandle();
+
+
+
+
+
+
+				{
+					/* Unreference the previously looked up handle */
+						if(psRIHandleInt)
+						{
+							PVRSRVReleaseHandleUnlocked(psConnection->psHandleBase,
+											hRIHandle,
+											PVRSRV_HANDLE_TYPE_RI_HANDLE);
+						}
+				}
+	/* Release now we have cleaned up look up handles. */
+	UnlockHandle();
+
+
 	return 0;
 }
 
+
 static IMG_INT
 PVRSRVBridgeRIUpdateMEMDESCPinning(IMG_UINT32 ui32DispatchTableEntry,
 					  PVRSRV_BRIDGE_IN_RIUPDATEMEMDESCPINNING *psRIUpdateMEMDESCPinningIN,
 					  PVRSRV_BRIDGE_OUT_RIUPDATEMEMDESCPINNING *psRIUpdateMEMDESCPinningOUT,
 					 CONNECTION_DATA *psConnection)
 {
+	IMG_HANDLE hRIHandle = psRIUpdateMEMDESCPinningIN->hRIHandle;
 	RI_HANDLE psRIHandleInt = NULL;
 
 
@@ -365,19 +612,29 @@
 
 
 
+	/* Lock over handle lookup. */
+	LockHandle();
+
+
+
+
+
 				{
 					/* Look up the address from the handle */
 					psRIUpdateMEMDESCPinningOUT->eError =
-						PVRSRVLookupHandle(psConnection->psHandleBase,
+						PVRSRVLookupHandleUnlocked(psConnection->psHandleBase,
 											(void **) &psRIHandleInt,
-											psRIUpdateMEMDESCPinningIN->hRIHandle,
-											PVRSRV_HANDLE_TYPE_RI_HANDLE);
+											hRIHandle,
+											PVRSRV_HANDLE_TYPE_RI_HANDLE,
+											IMG_TRUE);
 					if(psRIUpdateMEMDESCPinningOUT->eError != PVRSRV_OK)
 					{
+						UnlockHandle();
 						goto RIUpdateMEMDESCPinning_exit;
 					}
 				}
-
+	/* Release now we have looked up handles. */
+	UnlockHandle();
 
 	psRIUpdateMEMDESCPinningOUT->eError =
 		RIUpdateMEMDESCPinningKM(
@@ -389,15 +646,38 @@
 
 RIUpdateMEMDESCPinning_exit:
 
+	/* Lock over handle lookup cleanup. */
+	LockHandle();
+
+
+
+
+
+
+				{
+					/* Unreference the previously looked up handle */
+						if(psRIHandleInt)
+						{
+							PVRSRVReleaseHandleUnlocked(psConnection->psHandleBase,
+											hRIHandle,
+											PVRSRV_HANDLE_TYPE_RI_HANDLE);
+						}
+				}
+	/* Release now we have cleaned up look up handles. */
+	UnlockHandle();
+
+
 	return 0;
 }
 
+
 static IMG_INT
 PVRSRVBridgeRIUpdateMEMDESCBacking(IMG_UINT32 ui32DispatchTableEntry,
 					  PVRSRV_BRIDGE_IN_RIUPDATEMEMDESCBACKING *psRIUpdateMEMDESCBackingIN,
 					  PVRSRV_BRIDGE_OUT_RIUPDATEMEMDESCBACKING *psRIUpdateMEMDESCBackingOUT,
 					 CONNECTION_DATA *psConnection)
 {
+	IMG_HANDLE hRIHandle = psRIUpdateMEMDESCBackingIN->hRIHandle;
 	RI_HANDLE psRIHandleInt = NULL;
 
 
@@ -406,19 +686,29 @@
 
 
 
+	/* Lock over handle lookup. */
+	LockHandle();
+
+
+
+
+
 				{
 					/* Look up the address from the handle */
 					psRIUpdateMEMDESCBackingOUT->eError =
-						PVRSRVLookupHandle(psConnection->psHandleBase,
+						PVRSRVLookupHandleUnlocked(psConnection->psHandleBase,
 											(void **) &psRIHandleInt,
-											psRIUpdateMEMDESCBackingIN->hRIHandle,
-											PVRSRV_HANDLE_TYPE_RI_HANDLE);
+											hRIHandle,
+											PVRSRV_HANDLE_TYPE_RI_HANDLE,
+											IMG_TRUE);
 					if(psRIUpdateMEMDESCBackingOUT->eError != PVRSRV_OK)
 					{
+						UnlockHandle();
 						goto RIUpdateMEMDESCBacking_exit;
 					}
 				}
-
+	/* Release now we have looked up handles. */
+	UnlockHandle();
 
 	psRIUpdateMEMDESCBackingOUT->eError =
 		RIUpdateMEMDESCBackingKM(
@@ -430,9 +720,31 @@
 
 RIUpdateMEMDESCBacking_exit:
 
+	/* Lock over handle lookup cleanup. */
+	LockHandle();
+
+
+
+
+
+
+				{
+					/* Unreference the previously looked up handle */
+						if(psRIHandleInt)
+						{
+							PVRSRVReleaseHandleUnlocked(psConnection->psHandleBase,
+											hRIHandle,
+											PVRSRV_HANDLE_TYPE_RI_HANDLE);
+						}
+				}
+	/* Release now we have cleaned up look up handles. */
+	UnlockHandle();
+
+
 	return 0;
 }
 
+
 static IMG_INT
 PVRSRVBridgeRIDeleteMEMDESCEntry(IMG_UINT32 ui32DispatchTableEntry,
 					  PVRSRV_BRIDGE_IN_RIDELETEMEMDESCENTRY *psRIDeleteMEMDESCEntryIN,
@@ -448,29 +760,49 @@
 
 
 
+	/* Lock over handle destruction. */
+	LockHandle();
+
+
+
+
+
 	psRIDeleteMEMDESCEntryOUT->eError =
-		PVRSRVReleaseHandle(psConnection->psHandleBase,
+		PVRSRVReleaseHandleUnlocked(psConnection->psHandleBase,
 					(IMG_HANDLE) psRIDeleteMEMDESCEntryIN->hRIHandle,
 					PVRSRV_HANDLE_TYPE_RI_HANDLE);
-	if ((psRIDeleteMEMDESCEntryOUT->eError != PVRSRV_OK) && (psRIDeleteMEMDESCEntryOUT->eError != PVRSRV_ERROR_RETRY))
+	if ((psRIDeleteMEMDESCEntryOUT->eError != PVRSRV_OK) &&
+	    (psRIDeleteMEMDESCEntryOUT->eError != PVRSRV_ERROR_RETRY))
 	{
+		PVR_DPF((PVR_DBG_ERROR,
+		        "PVRSRVBridgeRIDeleteMEMDESCEntry: %s",
+		        PVRSRVGetErrorStringKM(psRIDeleteMEMDESCEntryOUT->eError)));
 		PVR_ASSERT(0);
+		UnlockHandle();
 		goto RIDeleteMEMDESCEntry_exit;
 	}
 
+	/* Release now we have destroyed handles. */
+	UnlockHandle();
+
 
 
 RIDeleteMEMDESCEntry_exit:
 
+
+
+
 	return 0;
 }
 
+
 static IMG_INT
 PVRSRVBridgeRIDumpList(IMG_UINT32 ui32DispatchTableEntry,
 					  PVRSRV_BRIDGE_IN_RIDUMPLIST *psRIDumpListIN,
 					  PVRSRV_BRIDGE_OUT_RIDUMPLIST *psRIDumpListOUT,
 					 CONNECTION_DATA *psConnection)
 {
+	IMG_HANDLE hPMRHandle = psRIDumpListIN->hPMRHandle;
 	PMR * psPMRHandleInt = NULL;
 
 
@@ -479,19 +811,29 @@
 
 
 
+	/* Lock over handle lookup. */
+	LockHandle();
+
+
+
+
+
 				{
 					/* Look up the address from the handle */
 					psRIDumpListOUT->eError =
-						PVRSRVLookupHandle(psConnection->psHandleBase,
+						PVRSRVLookupHandleUnlocked(psConnection->psHandleBase,
 											(void **) &psPMRHandleInt,
-											psRIDumpListIN->hPMRHandle,
-											PVRSRV_HANDLE_TYPE_PHYSMEM_PMR);
+											hPMRHandle,
+											PVRSRV_HANDLE_TYPE_PHYSMEM_PMR,
+											IMG_TRUE);
 					if(psRIDumpListOUT->eError != PVRSRV_OK)
 					{
+						UnlockHandle();
 						goto RIDumpList_exit;
 					}
 				}
-
+	/* Release now we have looked up handles. */
+	UnlockHandle();
 
 	psRIDumpListOUT->eError =
 		RIDumpListKM(
@@ -502,9 +844,31 @@
 
 RIDumpList_exit:
 
+	/* Lock over handle lookup cleanup. */
+	LockHandle();
+
+
+
+
+
+
+				{
+					/* Unreference the previously looked up handle */
+						if(psPMRHandleInt)
+						{
+							PVRSRVReleaseHandleUnlocked(psConnection->psHandleBase,
+											hPMRHandle,
+											PVRSRV_HANDLE_TYPE_PHYSMEM_PMR);
+						}
+				}
+	/* Release now we have cleaned up look up handles. */
+	UnlockHandle();
+
+
 	return 0;
 }
 
+
 static IMG_INT
 PVRSRVBridgeRIDumpAll(IMG_UINT32 ui32DispatchTableEntry,
 					  PVRSRV_BRIDGE_IN_RIDUMPALL *psRIDumpAllIN,
@@ -512,6 +876,8 @@
 					 CONNECTION_DATA *psConnection)
 {
 
+
+
 	PVR_UNREFERENCED_PARAMETER(psConnection);
 	PVR_UNREFERENCED_PARAMETER(psRIDumpAllIN);
 
@@ -519,7 +885,6 @@
 
 
 
-
 	psRIDumpAllOUT->eError =
 		RIDumpAllKM(
 					);
@@ -528,9 +893,13 @@
 
 
 
+
+
+
 	return 0;
 }
 
+
 static IMG_INT
 PVRSRVBridgeRIDumpProcess(IMG_UINT32 ui32DispatchTableEntry,
 					  PVRSRV_BRIDGE_IN_RIDUMPPROCESS *psRIDumpProcessIN,
@@ -538,9 +907,10 @@
 					 CONNECTION_DATA *psConnection)
 {
 
-	PVR_UNREFERENCED_PARAMETER(psConnection);
 
 
+	PVR_UNREFERENCED_PARAMETER(psConnection);
+
 
 
 
@@ -553,11 +923,15 @@
 
 
 
+
+
+
 	return 0;
 }
 
 
 
+
 /* *************************************************************************** 
  * Server bridge dispatch related glue 
  */
@@ -614,4 +988,3 @@
 {
 	return PVRSRV_OK;
 }
-
diff --git a/drivers/staging/imgtec/rogue/generated/srvcore_bridge/common_srvcore_bridge.h b/drivers/staging/imgtec/rogue/generated/srvcore_bridge/common_srvcore_bridge.h
index aecf4c0..58bd2f8 100644
--- a/drivers/staging/imgtec/rogue/generated/srvcore_bridge/common_srvcore_bridge.h
+++ b/drivers/staging/imgtec/rogue/generated/srvcore_bridge/common_srvcore_bridge.h
@@ -2,8 +2,8 @@
 @File
 @Title          Common bridge header for srvcore
 @Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
-@Description    Declares common defines and structures that are used by both
-                the client and sever side of the bridge for srvcore
+@Description    Declares common defines and structures used by both the client
+                and server side of the bridge for srvcore
 @License        Dual MIT/GPLv2
 
 The contents of this file are subject to the MIT license as set out below.
@@ -45,11 +45,13 @@
 #ifndef COMMON_SRVCORE_BRIDGE_H
 #define COMMON_SRVCORE_BRIDGE_H
 
+#include <powervr/mem_types.h>
+
 #include "img_types.h"
 #include "pvrsrv_error.h"
 
 #include "pvrsrv_device_types.h"
-#include "cache_external.h"
+#include "cache_ops.h"
 
 
 #define PVRSRV_BRIDGE_SRVCORE_CMD_FIRST			0
@@ -64,9 +66,9 @@
 #define PVRSRV_BRIDGE_SRVCORE_DUMPDEBUGINFO			PVRSRV_BRIDGE_SRVCORE_CMD_FIRST+8
 #define PVRSRV_BRIDGE_SRVCORE_GETDEVCLOCKSPEED			PVRSRV_BRIDGE_SRVCORE_CMD_FIRST+9
 #define PVRSRV_BRIDGE_SRVCORE_HWOPTIMEOUT			PVRSRV_BRIDGE_SRVCORE_CMD_FIRST+10
-#define PVRSRV_BRIDGE_SRVCORE_KICKDEVICES			PVRSRV_BRIDGE_SRVCORE_CMD_FIRST+11
-#define PVRSRV_BRIDGE_SRVCORE_RESETHWRLOGS			PVRSRV_BRIDGE_SRVCORE_CMD_FIRST+12
-#define PVRSRV_BRIDGE_SRVCORE_SOFTRESET			PVRSRV_BRIDGE_SRVCORE_CMD_FIRST+13
+#define PVRSRV_BRIDGE_SRVCORE_ALIGNMENTCHECK			PVRSRV_BRIDGE_SRVCORE_CMD_FIRST+11
+#define PVRSRV_BRIDGE_SRVCORE_GETDEVICESTATUS			PVRSRV_BRIDGE_SRVCORE_CMD_FIRST+12
+#define PVRSRV_BRIDGE_SRVCORE_EVENTOBJECTWAITTIMEOUT			PVRSRV_BRIDGE_SRVCORE_CMD_FIRST+13
 #define PVRSRV_BRIDGE_SRVCORE_CMD_LAST			(PVRSRV_BRIDGE_SRVCORE_CMD_FIRST+13)
 
 
@@ -87,7 +89,9 @@
 typedef struct PVRSRV_BRIDGE_OUT_CONNECT_TAG
 {
 	IMG_UINT8 ui8KernelArch;
-	IMG_UINT32 ui32Log2PageSize;
+	IMG_UINT32 ui32CapabilityFlags;
+	IMG_UINT32 ui32PVRBridges;
+	IMG_UINT32 ui32RGXBridges;
 	PVRSRV_ERROR eError;
 } __attribute__((packed)) PVRSRV_BRIDGE_OUT_CONNECT;
 
@@ -267,55 +271,57 @@
 
 
 /*******************************************
-            KickDevices          
+            AlignmentCheck          
  *******************************************/
 
-/* Bridge in structure for KickDevices */
-typedef struct PVRSRV_BRIDGE_IN_KICKDEVICES_TAG
+/* Bridge in structure for AlignmentCheck */
+typedef struct PVRSRV_BRIDGE_IN_ALIGNMENTCHECK_TAG
 {
-	 IMG_UINT32 ui32EmptyStructPlaceholder;
-} __attribute__((packed)) PVRSRV_BRIDGE_IN_KICKDEVICES;
+	IMG_UINT32 ui32AlignChecksSize;
+	IMG_UINT32 * pui32AlignChecks;
+} __attribute__((packed)) PVRSRV_BRIDGE_IN_ALIGNMENTCHECK;
 
-/* Bridge out structure for KickDevices */
-typedef struct PVRSRV_BRIDGE_OUT_KICKDEVICES_TAG
+/* Bridge out structure for AlignmentCheck */
+typedef struct PVRSRV_BRIDGE_OUT_ALIGNMENTCHECK_TAG
 {
 	PVRSRV_ERROR eError;
-} __attribute__((packed)) PVRSRV_BRIDGE_OUT_KICKDEVICES;
+} __attribute__((packed)) PVRSRV_BRIDGE_OUT_ALIGNMENTCHECK;
 
 
 /*******************************************
-            ResetHWRLogs          
+            GetDeviceStatus          
  *******************************************/
 
-/* Bridge in structure for ResetHWRLogs */
-typedef struct PVRSRV_BRIDGE_IN_RESETHWRLOGS_TAG
+/* Bridge in structure for GetDeviceStatus */
+typedef struct PVRSRV_BRIDGE_IN_GETDEVICESTATUS_TAG
 {
 	 IMG_UINT32 ui32EmptyStructPlaceholder;
-} __attribute__((packed)) PVRSRV_BRIDGE_IN_RESETHWRLOGS;
+} __attribute__((packed)) PVRSRV_BRIDGE_IN_GETDEVICESTATUS;
 
-/* Bridge out structure for ResetHWRLogs */
-typedef struct PVRSRV_BRIDGE_OUT_RESETHWRLOGS_TAG
+/* Bridge out structure for GetDeviceStatus */
+typedef struct PVRSRV_BRIDGE_OUT_GETDEVICESTATUS_TAG
 {
+	IMG_UINT32 ui32DeviceSatus;
 	PVRSRV_ERROR eError;
-} __attribute__((packed)) PVRSRV_BRIDGE_OUT_RESETHWRLOGS;
+} __attribute__((packed)) PVRSRV_BRIDGE_OUT_GETDEVICESTATUS;
 
 
 /*******************************************
-            SoftReset          
+            EventObjectWaitTimeout          
  *******************************************/
 
-/* Bridge in structure for SoftReset */
-typedef struct PVRSRV_BRIDGE_IN_SOFTRESET_TAG
+/* Bridge in structure for EventObjectWaitTimeout */
+typedef struct PVRSRV_BRIDGE_IN_EVENTOBJECTWAITTIMEOUT_TAG
 {
-	IMG_UINT64 ui64ResetValue1;
-	IMG_UINT64 ui64ResetValue2;
-} __attribute__((packed)) PVRSRV_BRIDGE_IN_SOFTRESET;
+	IMG_HANDLE hOSEventKM;
+	IMG_UINT64 ui64uiTimeoutus;
+} __attribute__((packed)) PVRSRV_BRIDGE_IN_EVENTOBJECTWAITTIMEOUT;
 
-/* Bridge out structure for SoftReset */
-typedef struct PVRSRV_BRIDGE_OUT_SOFTRESET_TAG
+/* Bridge out structure for EventObjectWaitTimeout */
+typedef struct PVRSRV_BRIDGE_OUT_EVENTOBJECTWAITTIMEOUT_TAG
 {
 	PVRSRV_ERROR eError;
-} __attribute__((packed)) PVRSRV_BRIDGE_OUT_SOFTRESET;
+} __attribute__((packed)) PVRSRV_BRIDGE_OUT_EVENTOBJECTWAITTIMEOUT;
 
 
 #endif /* COMMON_SRVCORE_BRIDGE_H */
diff --git a/drivers/staging/imgtec/rogue/generated/srvcore_bridge/server_srvcore_bridge.c b/drivers/staging/imgtec/rogue/generated/srvcore_bridge/server_srvcore_bridge.c
index 596d549..eb9e2a2 100644
--- a/drivers/staging/imgtec/rogue/generated/srvcore_bridge/server_srvcore_bridge.c
+++ b/drivers/staging/imgtec/rogue/generated/srvcore_bridge/server_srvcore_bridge.c
@@ -47,7 +47,6 @@
 #include "img_defs.h"
 
 #include "srvcore.h"
-#include "pvrsrv.h"
 
 
 #include "common_srvcore_bridge.h"
@@ -65,6 +64,8 @@
 
 
 
+
+
 /* ***************************************************************************
  * Server-side bridge entry points
  */
@@ -82,6 +83,7 @@
 
 
 
+
 	psConnectOUT->eError =
 		PVRSRVConnectKM(psConnection, OSGetDevData(psConnection),
 					psConnectIN->ui32Flags,
@@ -89,7 +91,12 @@
 					psConnectIN->ui32ClientDDKVersion,
 					psConnectIN->ui32ClientDDKBuild,
 					&psConnectOUT->ui8KernelArch,
-					&psConnectOUT->ui32Log2PageSize);
+					&psConnectOUT->ui32CapabilityFlags,
+					&psConnectOUT->ui32PVRBridges,
+					&psConnectOUT->ui32RGXBridges);
+
+
+
 
 
 
@@ -98,6 +105,7 @@
 	return 0;
 }
 
+
 static IMG_INT
 PVRSRVBridgeDisconnect(IMG_UINT32 ui32DispatchTableEntry,
 					  PVRSRV_BRIDGE_IN_DISCONNECT *psDisconnectIN,
@@ -105,6 +113,8 @@
 					 CONNECTION_DATA *psConnection)
 {
 
+
+
 	PVR_UNREFERENCED_PARAMETER(psConnection);
 	PVR_UNREFERENCED_PARAMETER(psDisconnectIN);
 
@@ -112,7 +122,6 @@
 
 
 
-
 	psDisconnectOUT->eError =
 		PVRSRVDisconnectKM(
 					);
@@ -121,9 +130,13 @@
 
 
 
+
+
+
 	return 0;
 }
 
+
 static IMG_INT
 PVRSRVBridgeInitSrvDisconnect(IMG_UINT32 ui32DispatchTableEntry,
 					  PVRSRV_BRIDGE_IN_INITSRVDISCONNECT *psInitSrvDisconnectIN,
@@ -135,14 +148,16 @@
 
 
 
-	PMRLock();
+
 
 
 	psInitSrvDisconnectOUT->eError =
 		PVRSRVInitSrvDisconnectKM(psConnection, OSGetDevData(psConnection),
 					psInitSrvDisconnectIN->bInitSuccesful,
 					psInitSrvDisconnectIN->ui32ClientBuildOptions);
-	PMRUnlock();
+
+
+
 
 
 
@@ -151,6 +166,7 @@
 	return 0;
 }
 
+
 static IMG_INT
 PVRSRVBridgeAcquireGlobalEventObject(IMG_UINT32 ui32DispatchTableEntry,
 					  PVRSRV_BRIDGE_IN_ACQUIREGLOBALEVENTOBJECT *psAcquireGlobalEventObjectIN,
@@ -159,15 +175,16 @@
 {
 	IMG_HANDLE hGlobalEventObjectInt = NULL;
 
+
+
 	PVR_UNREFERENCED_PARAMETER(psAcquireGlobalEventObjectIN);
 
 
 
 
 
-
 	psAcquireGlobalEventObjectOUT->eError =
-		AcquireGlobalEventObjectServer(
+		PVRSRVAcquireGlobalEventObjectKM(
 					&hGlobalEventObjectInt);
 	/* Exit early if bridged call fails */
 	if(psAcquireGlobalEventObjectOUT->eError != PVRSRV_OK)
@@ -175,27 +192,40 @@
 		goto AcquireGlobalEventObject_exit;
 	}
 
+	/* Lock over handle creation. */
+	LockHandle();
 
-	psAcquireGlobalEventObjectOUT->eError = PVRSRVAllocHandle(psConnection->psHandleBase,
+
+
+
+
+	psAcquireGlobalEventObjectOUT->eError = PVRSRVAllocHandleUnlocked(psConnection->psHandleBase,
+
 							&psAcquireGlobalEventObjectOUT->hGlobalEventObject,
 							(void *) hGlobalEventObjectInt,
 							PVRSRV_HANDLE_TYPE_SHARED_EVENT_OBJECT,
 							PVRSRV_HANDLE_ALLOC_FLAG_MULTI
-							,(PFN_HANDLE_RELEASE)&ReleaseGlobalEventObjectServer);
+							,(PFN_HANDLE_RELEASE)&PVRSRVReleaseGlobalEventObjectKM);
 	if (psAcquireGlobalEventObjectOUT->eError != PVRSRV_OK)
 	{
+		UnlockHandle();
 		goto AcquireGlobalEventObject_exit;
 	}
 
+	/* Release now we have created handles. */
+	UnlockHandle();
 
 
 
 AcquireGlobalEventObject_exit:
+
+
+
 	if (psAcquireGlobalEventObjectOUT->eError != PVRSRV_OK)
 	{
 		if (hGlobalEventObjectInt)
 		{
-			ReleaseGlobalEventObjectServer(hGlobalEventObjectInt);
+			PVRSRVReleaseGlobalEventObjectKM(hGlobalEventObjectInt);
 		}
 	}
 
@@ -203,6 +233,7 @@
 	return 0;
 }
 
+
 static IMG_INT
 PVRSRVBridgeReleaseGlobalEventObject(IMG_UINT32 ui32DispatchTableEntry,
 					  PVRSRV_BRIDGE_IN_RELEASEGLOBALEVENTOBJECT *psReleaseGlobalEventObjectIN,
@@ -218,29 +249,49 @@
 
 
 
+	/* Lock over handle destruction. */
+	LockHandle();
+
+
+
+
+
 	psReleaseGlobalEventObjectOUT->eError =
-		PVRSRVReleaseHandle(psConnection->psHandleBase,
+		PVRSRVReleaseHandleUnlocked(psConnection->psHandleBase,
 					(IMG_HANDLE) psReleaseGlobalEventObjectIN->hGlobalEventObject,
 					PVRSRV_HANDLE_TYPE_SHARED_EVENT_OBJECT);
-	if ((psReleaseGlobalEventObjectOUT->eError != PVRSRV_OK) && (psReleaseGlobalEventObjectOUT->eError != PVRSRV_ERROR_RETRY))
+	if ((psReleaseGlobalEventObjectOUT->eError != PVRSRV_OK) &&
+	    (psReleaseGlobalEventObjectOUT->eError != PVRSRV_ERROR_RETRY))
 	{
+		PVR_DPF((PVR_DBG_ERROR,
+		        "PVRSRVBridgeReleaseGlobalEventObject: %s",
+		        PVRSRVGetErrorStringKM(psReleaseGlobalEventObjectOUT->eError)));
 		PVR_ASSERT(0);
+		UnlockHandle();
 		goto ReleaseGlobalEventObject_exit;
 	}
 
+	/* Release now we have destroyed handles. */
+	UnlockHandle();
+
 
 
 ReleaseGlobalEventObject_exit:
 
+
+
+
 	return 0;
 }
 
+
 static IMG_INT
 PVRSRVBridgeEventObjectOpen(IMG_UINT32 ui32DispatchTableEntry,
 					  PVRSRV_BRIDGE_IN_EVENTOBJECTOPEN *psEventObjectOpenIN,
 					  PVRSRV_BRIDGE_OUT_EVENTOBJECTOPEN *psEventObjectOpenOUT,
 					 CONNECTION_DATA *psConnection)
 {
+	IMG_HANDLE hEventObject = psEventObjectOpenIN->hEventObject;
 	IMG_HANDLE hEventObjectInt = NULL;
 	IMG_HANDLE hOSEventInt = NULL;
 
@@ -250,19 +301,29 @@
 
 
 
+	/* Lock over handle lookup. */
+	LockHandle();
+
+
+
+
+
 				{
 					/* Look up the address from the handle */
 					psEventObjectOpenOUT->eError =
-						PVRSRVLookupHandle(psConnection->psHandleBase,
+						PVRSRVLookupHandleUnlocked(psConnection->psHandleBase,
 											(void **) &hEventObjectInt,
-											psEventObjectOpenIN->hEventObject,
-											PVRSRV_HANDLE_TYPE_SHARED_EVENT_OBJECT);
+											hEventObject,
+											PVRSRV_HANDLE_TYPE_SHARED_EVENT_OBJECT,
+											IMG_TRUE);
 					if(psEventObjectOpenOUT->eError != PVRSRV_OK)
 					{
+						UnlockHandle();
 						goto EventObjectOpen_exit;
 					}
 				}
-
+	/* Release now we have looked up handles. */
+	UnlockHandle();
 
 	psEventObjectOpenOUT->eError =
 		OSEventObjectOpen(
@@ -274,8 +335,15 @@
 		goto EventObjectOpen_exit;
 	}
 
+	/* Lock over handle creation. */
+	LockHandle();
 
-	psEventObjectOpenOUT->eError = PVRSRVAllocHandle(psConnection->psHandleBase,
+
+
+
+
+	psEventObjectOpenOUT->eError = PVRSRVAllocHandleUnlocked(psConnection->psHandleBase,
+
 							&psEventObjectOpenOUT->hOSEvent,
 							(void *) hOSEventInt,
 							PVRSRV_HANDLE_TYPE_EVENT_OBJECT_CONNECT,
@@ -283,13 +351,37 @@
 							,(PFN_HANDLE_RELEASE)&OSEventObjectClose);
 	if (psEventObjectOpenOUT->eError != PVRSRV_OK)
 	{
+		UnlockHandle();
 		goto EventObjectOpen_exit;
 	}
 
+	/* Release now we have created handles. */
+	UnlockHandle();
 
 
 
 EventObjectOpen_exit:
+
+	/* Lock over handle lookup cleanup. */
+	LockHandle();
+
+
+
+
+
+
+				{
+					/* Unreference the previously looked up handle */
+						if(hEventObjectInt)
+						{
+							PVRSRVReleaseHandleUnlocked(psConnection->psHandleBase,
+											hEventObject,
+											PVRSRV_HANDLE_TYPE_SHARED_EVENT_OBJECT);
+						}
+				}
+	/* Release now we have cleaned up look up handles. */
+	UnlockHandle();
+
 	if (psEventObjectOpenOUT->eError != PVRSRV_OK)
 	{
 		if (hOSEventInt)
@@ -302,12 +394,14 @@
 	return 0;
 }
 
+
 static IMG_INT
 PVRSRVBridgeEventObjectWait(IMG_UINT32 ui32DispatchTableEntry,
 					  PVRSRV_BRIDGE_IN_EVENTOBJECTWAIT *psEventObjectWaitIN,
 					  PVRSRV_BRIDGE_OUT_EVENTOBJECTWAIT *psEventObjectWaitOUT,
 					 CONNECTION_DATA *psConnection)
 {
+	IMG_HANDLE hOSEventKM = psEventObjectWaitIN->hOSEventKM;
 	IMG_HANDLE hOSEventKMInt = NULL;
 
 
@@ -316,19 +410,29 @@
 
 
 
+	/* Lock over handle lookup. */
+	LockHandle();
+
+
+
+
+
 				{
 					/* Look up the address from the handle */
 					psEventObjectWaitOUT->eError =
-						PVRSRVLookupHandle(psConnection->psHandleBase,
+						PVRSRVLookupHandleUnlocked(psConnection->psHandleBase,
 											(void **) &hOSEventKMInt,
-											psEventObjectWaitIN->hOSEventKM,
-											PVRSRV_HANDLE_TYPE_EVENT_OBJECT_CONNECT);
+											hOSEventKM,
+											PVRSRV_HANDLE_TYPE_EVENT_OBJECT_CONNECT,
+											IMG_TRUE);
 					if(psEventObjectWaitOUT->eError != PVRSRV_OK)
 					{
+						UnlockHandle();
 						goto EventObjectWait_exit;
 					}
 				}
-
+	/* Release now we have looked up handles. */
+	UnlockHandle();
 
 	psEventObjectWaitOUT->eError =
 		OSEventObjectWait(
@@ -339,9 +443,31 @@
 
 EventObjectWait_exit:
 
+	/* Lock over handle lookup cleanup. */
+	LockHandle();
+
+
+
+
+
+
+				{
+					/* Unreference the previously looked up handle */
+						if(hOSEventKMInt)
+						{
+							PVRSRVReleaseHandleUnlocked(psConnection->psHandleBase,
+											hOSEventKM,
+											PVRSRV_HANDLE_TYPE_EVENT_OBJECT_CONNECT);
+						}
+				}
+	/* Release now we have cleaned up look up handles. */
+	UnlockHandle();
+
+
 	return 0;
 }
 
+
 static IMG_INT
 PVRSRVBridgeEventObjectClose(IMG_UINT32 ui32DispatchTableEntry,
 					  PVRSRV_BRIDGE_IN_EVENTOBJECTCLOSE *psEventObjectCloseIN,
@@ -357,23 +483,42 @@
 
 
 
+	/* Lock over handle destruction. */
+	LockHandle();
+
+
+
+
+
 	psEventObjectCloseOUT->eError =
-		PVRSRVReleaseHandle(psConnection->psHandleBase,
+		PVRSRVReleaseHandleUnlocked(psConnection->psHandleBase,
 					(IMG_HANDLE) psEventObjectCloseIN->hOSEventKM,
 					PVRSRV_HANDLE_TYPE_EVENT_OBJECT_CONNECT);
-	if ((psEventObjectCloseOUT->eError != PVRSRV_OK) && (psEventObjectCloseOUT->eError != PVRSRV_ERROR_RETRY))
+	if ((psEventObjectCloseOUT->eError != PVRSRV_OK) &&
+	    (psEventObjectCloseOUT->eError != PVRSRV_ERROR_RETRY))
 	{
+		PVR_DPF((PVR_DBG_ERROR,
+		        "PVRSRVBridgeEventObjectClose: %s",
+		        PVRSRVGetErrorStringKM(psEventObjectCloseOUT->eError)));
 		PVR_ASSERT(0);
+		UnlockHandle();
 		goto EventObjectClose_exit;
 	}
 
+	/* Release now we have destroyed handles. */
+	UnlockHandle();
+
 
 
 EventObjectClose_exit:
 
+
+
+
 	return 0;
 }
 
+
 static IMG_INT
 PVRSRVBridgeDumpDebugInfo(IMG_UINT32 ui32DispatchTableEntry,
 					  PVRSRV_BRIDGE_IN_DUMPDEBUGINFO *psDumpDebugInfoIN,
@@ -381,7 +526,7 @@
 					 CONNECTION_DATA *psConnection)
 {
 
-	PVR_UNREFERENCED_PARAMETER(psConnection);
+
 
 
 
@@ -389,16 +534,20 @@
 
 
 	psDumpDebugInfoOUT->eError =
-		PVRSRVDumpDebugInfoKM(
+		PVRSRVDumpDebugInfoKM(psConnection, OSGetDevData(psConnection),
 					psDumpDebugInfoIN->ui32ui32VerbLevel);
 
 
 
 
 
+
+
+
 	return 0;
 }
 
+
 static IMG_INT
 PVRSRVBridgeGetDevClockSpeed(IMG_UINT32 ui32DispatchTableEntry,
 					  PVRSRV_BRIDGE_IN_GETDEVCLOCKSPEED *psGetDevClockSpeedIN,
@@ -406,9 +555,10 @@
 					 CONNECTION_DATA *psConnection)
 {
 
-	PVR_UNREFERENCED_PARAMETER(psGetDevClockSpeedIN);
 
 
+	PVR_UNREFERENCED_PARAMETER(psGetDevClockSpeedIN);
+
 
 
 
@@ -421,9 +571,13 @@
 
 
 
+
+
+
 	return 0;
 }
 
+
 static IMG_INT
 PVRSRVBridgeHWOpTimeout(IMG_UINT32 ui32DispatchTableEntry,
 					  PVRSRV_BRIDGE_IN_HWOPTIMEOUT *psHWOpTimeoutIN,
@@ -431,93 +585,148 @@
 					 CONNECTION_DATA *psConnection)
 {
 
-	PVR_UNREFERENCED_PARAMETER(psConnection);
+
+
 	PVR_UNREFERENCED_PARAMETER(psHWOpTimeoutIN);
 
 
 
 
 
-
 	psHWOpTimeoutOUT->eError =
-		PVRSRVHWOpTimeoutKM(
+		PVRSRVHWOpTimeoutKM(psConnection, OSGetDevData(psConnection)
 					);
 
 
 
 
 
+
+
+
 	return 0;
 }
 
+
+#if defined(SUPPORT_KERNEL_SRVINIT)
 static IMG_INT
-PVRSRVBridgeKickDevices(IMG_UINT32 ui32DispatchTableEntry,
-					  PVRSRV_BRIDGE_IN_KICKDEVICES *psKickDevicesIN,
-					  PVRSRV_BRIDGE_OUT_KICKDEVICES *psKickDevicesOUT,
+PVRSRVBridgeAlignmentCheck(IMG_UINT32 ui32DispatchTableEntry,
+					  PVRSRV_BRIDGE_IN_ALIGNMENTCHECK *psAlignmentCheckIN,
+					  PVRSRV_BRIDGE_OUT_ALIGNMENTCHECK *psAlignmentCheckOUT,
 					 CONNECTION_DATA *psConnection)
 {
+	IMG_UINT32 *ui32AlignChecksInt = NULL;
 
-	PVR_UNREFERENCED_PARAMETER(psConnection);
-	PVR_UNREFERENCED_PARAMETER(psKickDevicesIN);
+	IMG_UINT32 ui32NextOffset = 0;
+	IMG_BYTE   *pArrayArgsBuffer = NULL;
+#if !defined(INTEGRITY_OS)
+	IMG_BOOL bHaveEnoughSpace = IMG_FALSE;
+#endif
+
+	IMG_UINT32 ui32BufferSize = 
+			(psAlignmentCheckIN->ui32AlignChecksSize * sizeof(IMG_UINT32)) +
+			0;
 
 
 
 
 
+	if (ui32BufferSize != 0)
+	{
+#if !defined(INTEGRITY_OS)
+		/* Try to use remainder of input buffer for copies if possible, word-aligned for safety. */
+		IMG_UINT32 ui32InBufferOffset = PVR_ALIGN(sizeof(*psAlignmentCheckIN), sizeof(unsigned long));
+		IMG_UINT32 ui32InBufferExcessSize = ui32InBufferOffset >= PVRSRV_MAX_BRIDGE_IN_SIZE ? 0 :
+			PVRSRV_MAX_BRIDGE_IN_SIZE - ui32InBufferOffset;
 
-	psKickDevicesOUT->eError =
-		PVRSRVKickDevicesKM(
-					);
+		bHaveEnoughSpace = ui32BufferSize <= ui32InBufferExcessSize;
+		if (bHaveEnoughSpace)
+		{
+			IMG_BYTE *pInputBuffer = (IMG_BYTE *)psAlignmentCheckIN;
+
+			pArrayArgsBuffer = &pInputBuffer[ui32InBufferOffset];		}
+		else
+#endif
+		{
+			pArrayArgsBuffer = OSAllocMemNoStats(ui32BufferSize);
+
+			if(!pArrayArgsBuffer)
+			{
+				psAlignmentCheckOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
+				goto AlignmentCheck_exit;
+			}
+		}
+	}
+
+	if (psAlignmentCheckIN->ui32AlignChecksSize != 0)
+	{
+		ui32AlignChecksInt = (IMG_UINT32*)(((IMG_UINT8 *)pArrayArgsBuffer) + ui32NextOffset);
+		ui32NextOffset += psAlignmentCheckIN->ui32AlignChecksSize * sizeof(IMG_UINT32);
+	}
+
+			/* Copy the data over */
+			if (psAlignmentCheckIN->ui32AlignChecksSize * sizeof(IMG_UINT32) > 0)
+			{
+				if ( OSCopyFromUser(NULL, ui32AlignChecksInt, psAlignmentCheckIN->pui32AlignChecks, psAlignmentCheckIN->ui32AlignChecksSize * sizeof(IMG_UINT32)) != PVRSRV_OK )
+				{
+					psAlignmentCheckOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
+
+					goto AlignmentCheck_exit;
+				}
+			}
+
+
+	psAlignmentCheckOUT->eError =
+		PVRSRVAlignmentCheckKM(psConnection, OSGetDevData(psConnection),
+					psAlignmentCheckIN->ui32AlignChecksSize,
+					ui32AlignChecksInt);
 
 
 
 
+AlignmentCheck_exit:
+
+
+
+	/* Allocated space should be equal to the last updated offset */
+	PVR_ASSERT(ui32BufferSize == ui32NextOffset);
+
+#if defined(INTEGRITY_OS)
+	if(pArrayArgsBuffer)
+#else
+	if(!bHaveEnoughSpace && pArrayArgsBuffer)
+#endif
+		OSFreeMemNoStats(pArrayArgsBuffer);
+
 
 	return 0;
 }
 
-static IMG_INT
-PVRSRVBridgeResetHWRLogs(IMG_UINT32 ui32DispatchTableEntry,
-					  PVRSRV_BRIDGE_IN_RESETHWRLOGS *psResetHWRLogsIN,
-					  PVRSRV_BRIDGE_OUT_RESETHWRLOGS *psResetHWRLogsOUT,
-					 CONNECTION_DATA *psConnection)
-{
-
-	PVR_UNREFERENCED_PARAMETER(psResetHWRLogsIN);
-
-
-
-
-
-
-	psResetHWRLogsOUT->eError =
-		PVRSRVResetHWRLogsKM(psConnection, OSGetDevData(psConnection)
-					);
-
-
-
-
-
-	return 0;
-}
+#else
+#define PVRSRVBridgeAlignmentCheck NULL
+#endif
 
 static IMG_INT
-PVRSRVBridgeSoftReset(IMG_UINT32 ui32DispatchTableEntry,
-					  PVRSRV_BRIDGE_IN_SOFTRESET *psSoftResetIN,
-					  PVRSRV_BRIDGE_OUT_SOFTRESET *psSoftResetOUT,
+PVRSRVBridgeGetDeviceStatus(IMG_UINT32 ui32DispatchTableEntry,
+					  PVRSRV_BRIDGE_IN_GETDEVICESTATUS *psGetDeviceStatusIN,
+					  PVRSRV_BRIDGE_OUT_GETDEVICESTATUS *psGetDeviceStatusOUT,
 					 CONNECTION_DATA *psConnection)
 {
 
 
 
+	PVR_UNREFERENCED_PARAMETER(psGetDeviceStatusIN);
 
 
 
 
-	psSoftResetOUT->eError =
-		PVRSRVSoftResetKM(psConnection, OSGetDevData(psConnection),
-					psSoftResetIN->ui64ResetValue1,
-					psSoftResetIN->ui64ResetValue2);
+
+	psGetDeviceStatusOUT->eError =
+		PVRSRVGetDeviceStatusKM(psConnection, OSGetDevData(psConnection),
+					&psGetDeviceStatusOUT->ui32DeviceSatus);
+
+
+
 
 
 
@@ -527,6 +736,81 @@
 }
 
 
+static IMG_INT
+PVRSRVBridgeEventObjectWaitTimeout(IMG_UINT32 ui32DispatchTableEntry,
+					  PVRSRV_BRIDGE_IN_EVENTOBJECTWAITTIMEOUT *psEventObjectWaitTimeoutIN,
+					  PVRSRV_BRIDGE_OUT_EVENTOBJECTWAITTIMEOUT *psEventObjectWaitTimeoutOUT,
+					 CONNECTION_DATA *psConnection)
+{
+	IMG_HANDLE hOSEventKM = psEventObjectWaitTimeoutIN->hOSEventKM;
+	IMG_HANDLE hOSEventKMInt = NULL;
+
+
+
+
+
+
+
+	/* Lock over handle lookup. */
+	LockHandle();
+
+
+
+
+
+				{
+					/* Look up the address from the handle */
+					psEventObjectWaitTimeoutOUT->eError =
+						PVRSRVLookupHandleUnlocked(psConnection->psHandleBase,
+											(void **) &hOSEventKMInt,
+											hOSEventKM,
+											PVRSRV_HANDLE_TYPE_EVENT_OBJECT_CONNECT,
+											IMG_TRUE);
+					if(psEventObjectWaitTimeoutOUT->eError != PVRSRV_OK)
+					{
+						UnlockHandle();
+						goto EventObjectWaitTimeout_exit;
+					}
+				}
+	/* Release now we have looked up handles. */
+	UnlockHandle();
+
+	psEventObjectWaitTimeoutOUT->eError =
+		OSEventObjectWaitTimeout(
+					hOSEventKMInt,
+					psEventObjectWaitTimeoutIN->ui64uiTimeoutus);
+
+
+
+
+EventObjectWaitTimeout_exit:
+
+	/* Lock over handle lookup cleanup. */
+	LockHandle();
+
+
+
+
+
+
+				{
+					/* Unreference the previously looked up handle */
+						if(hOSEventKMInt)
+						{
+							PVRSRVReleaseHandleUnlocked(psConnection->psHandleBase,
+											hOSEventKM,
+											PVRSRV_HANDLE_TYPE_EVENT_OBJECT_CONNECT);
+						}
+				}
+	/* Release now we have cleaned up look up handles. */
+	UnlockHandle();
+
+
+	return 0;
+}
+
+
+
 
 /* *************************************************************************** 
  * Server bridge dispatch related glue 
@@ -576,13 +860,13 @@
 	SetDispatchTableEntry(PVRSRV_BRIDGE_SRVCORE, PVRSRV_BRIDGE_SRVCORE_HWOPTIMEOUT, PVRSRVBridgeHWOpTimeout,
 					NULL, bUseLock);
 
-	SetDispatchTableEntry(PVRSRV_BRIDGE_SRVCORE, PVRSRV_BRIDGE_SRVCORE_KICKDEVICES, PVRSRVBridgeKickDevices,
+	SetDispatchTableEntry(PVRSRV_BRIDGE_SRVCORE, PVRSRV_BRIDGE_SRVCORE_ALIGNMENTCHECK, PVRSRVBridgeAlignmentCheck,
 					NULL, bUseLock);
 
-	SetDispatchTableEntry(PVRSRV_BRIDGE_SRVCORE, PVRSRV_BRIDGE_SRVCORE_RESETHWRLOGS, PVRSRVBridgeResetHWRLogs,
+	SetDispatchTableEntry(PVRSRV_BRIDGE_SRVCORE, PVRSRV_BRIDGE_SRVCORE_GETDEVICESTATUS, PVRSRVBridgeGetDeviceStatus,
 					NULL, bUseLock);
 
-	SetDispatchTableEntry(PVRSRV_BRIDGE_SRVCORE, PVRSRV_BRIDGE_SRVCORE_SOFTRESET, PVRSRVBridgeSoftReset,
+	SetDispatchTableEntry(PVRSRV_BRIDGE_SRVCORE, PVRSRV_BRIDGE_SRVCORE_EVENTOBJECTWAITTIMEOUT, PVRSRVBridgeEventObjectWaitTimeout,
 					NULL, bUseLock);
 
 
@@ -596,4 +880,3 @@
 {
 	return PVRSRV_OK;
 }
-
diff --git a/drivers/staging/imgtec/rogue/generated/sync_bridge/client_sync_bridge.h b/drivers/staging/imgtec/rogue/generated/sync_bridge/client_sync_bridge.h
index 612ad05..b533be8 100644
--- a/drivers/staging/imgtec/rogue/generated/sync_bridge/client_sync_bridge.h
+++ b/drivers/staging/imgtec/rogue/generated/sync_bridge/client_sync_bridge.h
@@ -72,18 +72,6 @@
 							       IMG_HANDLE hSyncHandle,
 							       IMG_UINT32 ui32Value);
 
-IMG_INTERNAL PVRSRV_ERROR IMG_CALLCONV BridgeSyncRecordRemoveByHandle(IMG_HANDLE hBridge,
-								      IMG_HANDLE hhRecord);
-
-IMG_INTERNAL PVRSRV_ERROR IMG_CALLCONV BridgeSyncRecordAdd(IMG_HANDLE hBridge,
-							   IMG_HANDLE *phhRecord,
-							   IMG_HANDLE hhServerSyncPrimBlock,
-							   IMG_UINT32 ui32ui32FwBlockAddr,
-							   IMG_UINT32 ui32ui32SyncOffset,
-							   IMG_BOOL bbServerSync,
-							   IMG_UINT32 ui32ClassNameSize,
-							   const IMG_CHAR *puiClassName);
-
 IMG_INTERNAL PVRSRV_ERROR IMG_CALLCONV BridgeServerSyncAlloc(IMG_HANDLE hBridge,
 							     IMG_HANDLE *phSyncHandle,
 							     IMG_UINT32 *pui32SyncPrimVAddr,
@@ -165,5 +153,14 @@
 							      IMG_DEVMEM_SIZE_T uiPacketSize,
 							      IMG_DEVMEM_SIZE_T uiBufferSize);
 
+IMG_INTERNAL PVRSRV_ERROR IMG_CALLCONV BridgeSyncAllocEvent(IMG_HANDLE hBridge,
+							    IMG_BOOL bServerSync,
+							    IMG_UINT32 ui32FWAddr,
+							    IMG_UINT32 ui32ClassNameSize,
+							    const IMG_CHAR *puiClassName);
+
+IMG_INTERNAL PVRSRV_ERROR IMG_CALLCONV BridgeSyncFreeEvent(IMG_HANDLE hBridge,
+							   IMG_UINT32 ui32FWAddr);
+
 
 #endif /* CLIENT_SYNC_BRIDGE_H */
diff --git a/drivers/staging/imgtec/rogue/generated/sync_bridge/client_sync_direct_bridge.c b/drivers/staging/imgtec/rogue/generated/sync_bridge/client_sync_direct_bridge.c
index edb4d51..7378dd5 100644
--- a/drivers/staging/imgtec/rogue/generated/sync_bridge/client_sync_direct_bridge.c
+++ b/drivers/staging/imgtec/rogue/generated/sync_bridge/client_sync_direct_bridge.c
@@ -48,6 +48,7 @@
 #include "pdumpdefs.h"
 #include "devicemem_typedefs.h"
 
+#include "sync.h"
 #include "sync_server.h"
 #include "pdump.h"
 
@@ -130,52 +131,6 @@
 	return eError;
 }
 
-IMG_INTERNAL PVRSRV_ERROR IMG_CALLCONV BridgeSyncRecordRemoveByHandle(IMG_HANDLE hBridge,
-								      IMG_HANDLE hhRecord)
-{
-	PVRSRV_ERROR eError;
-	SYNC_RECORD_HANDLE pshRecordInt;
-	PVR_UNREFERENCED_PARAMETER(hBridge);
-
-	pshRecordInt = (SYNC_RECORD_HANDLE) hhRecord;
-
-	eError =
-		PVRSRVSyncRecordRemoveByHandleKM(
-					pshRecordInt);
-
-	return eError;
-}
-
-IMG_INTERNAL PVRSRV_ERROR IMG_CALLCONV BridgeSyncRecordAdd(IMG_HANDLE hBridge,
-							   IMG_HANDLE *phhRecord,
-							   IMG_HANDLE hhServerSyncPrimBlock,
-							   IMG_UINT32 ui32ui32FwBlockAddr,
-							   IMG_UINT32 ui32ui32SyncOffset,
-							   IMG_BOOL bbServerSync,
-							   IMG_UINT32 ui32ClassNameSize,
-							   const IMG_CHAR *puiClassName)
-{
-	PVRSRV_ERROR eError;
-	SYNC_RECORD_HANDLE pshRecordInt;
-	SYNC_PRIMITIVE_BLOCK * pshServerSyncPrimBlockInt;
-	PVR_UNREFERENCED_PARAMETER(hBridge);
-
-	pshServerSyncPrimBlockInt = (SYNC_PRIMITIVE_BLOCK *) hhServerSyncPrimBlock;
-
-	eError =
-		PVRSRVSyncRecordAddKM(
-					&pshRecordInt,
-					pshServerSyncPrimBlockInt,
-					ui32ui32FwBlockAddr,
-					ui32ui32SyncOffset,
-					bbServerSync,
-					ui32ClassNameSize,
-					puiClassName);
-
-	*phhRecord = pshRecordInt;
-	return eError;
-}
-
 IMG_INTERNAL PVRSRV_ERROR IMG_CALLCONV BridgeServerSyncAlloc(IMG_HANDLE hBridge,
 							     IMG_HANDLE *phSyncHandle,
 							     IMG_UINT32 *pui32SyncPrimVAddr,
@@ -378,6 +333,7 @@
 							   IMG_HANDLE hSyncHandle,
 							   IMG_UINT32 ui32Offset)
 {
+#if defined(PDUMP)
 	PVRSRV_ERROR eError;
 	SYNC_PRIMITIVE_BLOCK * psSyncHandleInt;
 	PVR_UNREFERENCED_PARAMETER(hBridge);
@@ -390,6 +346,13 @@
 					ui32Offset);
 
 	return eError;
+#else
+	PVR_UNREFERENCED_PARAMETER(hBridge);
+	PVR_UNREFERENCED_PARAMETER(hSyncHandle);
+	PVR_UNREFERENCED_PARAMETER(ui32Offset);
+
+	return PVRSRV_ERROR_NOT_IMPLEMENTED;
+#endif
 }
 
 IMG_INTERNAL PVRSRV_ERROR IMG_CALLCONV BridgeSyncPrimPDumpValue(IMG_HANDLE hBridge,
@@ -397,6 +360,7 @@
 								IMG_UINT32 ui32Offset,
 								IMG_UINT32 ui32Value)
 {
+#if defined(PDUMP)
 	PVRSRV_ERROR eError;
 	SYNC_PRIMITIVE_BLOCK * psSyncHandleInt;
 	PVR_UNREFERENCED_PARAMETER(hBridge);
@@ -410,6 +374,14 @@
 					ui32Value);
 
 	return eError;
+#else
+	PVR_UNREFERENCED_PARAMETER(hBridge);
+	PVR_UNREFERENCED_PARAMETER(hSyncHandle);
+	PVR_UNREFERENCED_PARAMETER(ui32Offset);
+	PVR_UNREFERENCED_PARAMETER(ui32Value);
+
+	return PVRSRV_ERROR_NOT_IMPLEMENTED;
+#endif
 }
 
 IMG_INTERNAL PVRSRV_ERROR IMG_CALLCONV BridgeSyncPrimPDumpPol(IMG_HANDLE hBridge,
@@ -420,6 +392,7 @@
 							      PDUMP_POLL_OPERATOR eOperator,
 							      PDUMP_FLAGS_T uiPDumpFlags)
 {
+#if defined(PDUMP)
 	PVRSRV_ERROR eError;
 	SYNC_PRIMITIVE_BLOCK * psSyncHandleInt;
 	PVR_UNREFERENCED_PARAMETER(hBridge);
@@ -436,6 +409,17 @@
 					uiPDumpFlags);
 
 	return eError;
+#else
+	PVR_UNREFERENCED_PARAMETER(hBridge);
+	PVR_UNREFERENCED_PARAMETER(hSyncHandle);
+	PVR_UNREFERENCED_PARAMETER(ui32Offset);
+	PVR_UNREFERENCED_PARAMETER(ui32Value);
+	PVR_UNREFERENCED_PARAMETER(ui32Mask);
+	PVR_UNREFERENCED_PARAMETER(eOperator);
+	PVR_UNREFERENCED_PARAMETER(uiPDumpFlags);
+
+	return PVRSRV_ERROR_NOT_IMPLEMENTED;
+#endif
 }
 
 IMG_INTERNAL PVRSRV_ERROR IMG_CALLCONV BridgeSyncPrimOpPDumpPol(IMG_HANDLE hBridge,
@@ -443,6 +427,7 @@
 								PDUMP_POLL_OPERATOR eOperator,
 								PDUMP_FLAGS_T uiPDumpFlags)
 {
+#if defined(PDUMP)
 	PVRSRV_ERROR eError;
 	SERVER_OP_COOKIE * psServerCookieInt;
 	PVR_UNREFERENCED_PARAMETER(hBridge);
@@ -456,6 +441,14 @@
 					uiPDumpFlags);
 
 	return eError;
+#else
+	PVR_UNREFERENCED_PARAMETER(hBridge);
+	PVR_UNREFERENCED_PARAMETER(hServerCookie);
+	PVR_UNREFERENCED_PARAMETER(eOperator);
+	PVR_UNREFERENCED_PARAMETER(uiPDumpFlags);
+
+	return PVRSRV_ERROR_NOT_IMPLEMENTED;
+#endif
 }
 
 IMG_INTERNAL PVRSRV_ERROR IMG_CALLCONV BridgeSyncPrimPDumpCBP(IMG_HANDLE hBridge,
@@ -465,6 +458,7 @@
 							      IMG_DEVMEM_SIZE_T uiPacketSize,
 							      IMG_DEVMEM_SIZE_T uiBufferSize)
 {
+#if defined(PDUMP)
 	PVRSRV_ERROR eError;
 	SYNC_PRIMITIVE_BLOCK * psSyncHandleInt;
 	PVR_UNREFERENCED_PARAMETER(hBridge);
@@ -480,5 +474,49 @@
 					uiBufferSize);
 
 	return eError;
+#else
+	PVR_UNREFERENCED_PARAMETER(hBridge);
+	PVR_UNREFERENCED_PARAMETER(hSyncHandle);
+	PVR_UNREFERENCED_PARAMETER(ui32Offset);
+	PVR_UNREFERENCED_PARAMETER(uiWriteOffset);
+	PVR_UNREFERENCED_PARAMETER(uiPacketSize);
+	PVR_UNREFERENCED_PARAMETER(uiBufferSize);
+
+	return PVRSRV_ERROR_NOT_IMPLEMENTED;
+#endif
+}
+
+IMG_INTERNAL PVRSRV_ERROR IMG_CALLCONV BridgeSyncAllocEvent(IMG_HANDLE hBridge,
+							    IMG_BOOL bServerSync,
+							    IMG_UINT32 ui32FWAddr,
+							    IMG_UINT32 ui32ClassNameSize,
+							    const IMG_CHAR *puiClassName)
+{
+	PVRSRV_ERROR eError;
+	PVR_UNREFERENCED_PARAMETER(hBridge);
+
+
+	eError =
+		PVRSRVSyncAllocEventKM(
+					bServerSync,
+					ui32FWAddr,
+					ui32ClassNameSize,
+					puiClassName);
+
+	return eError;
+}
+
+IMG_INTERNAL PVRSRV_ERROR IMG_CALLCONV BridgeSyncFreeEvent(IMG_HANDLE hBridge,
+							   IMG_UINT32 ui32FWAddr)
+{
+	PVRSRV_ERROR eError;
+	PVR_UNREFERENCED_PARAMETER(hBridge);
+
+
+	eError =
+		PVRSRVSyncFreeEventKM(
+					ui32FWAddr);
+
+	return eError;
 }
 
diff --git a/drivers/staging/imgtec/rogue/generated/sync_bridge/common_sync_bridge.h b/drivers/staging/imgtec/rogue/generated/sync_bridge/common_sync_bridge.h
index 8c43e4bf..6003b42 100644
--- a/drivers/staging/imgtec/rogue/generated/sync_bridge/common_sync_bridge.h
+++ b/drivers/staging/imgtec/rogue/generated/sync_bridge/common_sync_bridge.h
@@ -2,8 +2,8 @@
 @File
 @Title          Common bridge header for sync
 @Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
-@Description    Declares common defines and structures that are used by both
-                the client and sever side of the bridge for sync
+@Description    Declares common defines and structures used by both the client
+                and server side of the bridge for sync
 @License        Dual MIT/GPLv2
 
 The contents of this file are subject to the MIT license as set out below.
@@ -45,6 +45,8 @@
 #ifndef COMMON_SYNC_BRIDGE_H
 #define COMMON_SYNC_BRIDGE_H
 
+#include <powervr/mem_types.h>
+
 #include "img_types.h"
 #include "pvrsrv_error.h"
 
@@ -58,22 +60,22 @@
 #define PVRSRV_BRIDGE_SYNC_FREESYNCPRIMITIVEBLOCK			PVRSRV_BRIDGE_SYNC_CMD_FIRST+1
 #define PVRSRV_BRIDGE_SYNC_SYNCPRIMSET			PVRSRV_BRIDGE_SYNC_CMD_FIRST+2
 #define PVRSRV_BRIDGE_SYNC_SERVERSYNCPRIMSET			PVRSRV_BRIDGE_SYNC_CMD_FIRST+3
-#define PVRSRV_BRIDGE_SYNC_SYNCRECORDREMOVEBYHANDLE			PVRSRV_BRIDGE_SYNC_CMD_FIRST+4
-#define PVRSRV_BRIDGE_SYNC_SYNCRECORDADD			PVRSRV_BRIDGE_SYNC_CMD_FIRST+5
-#define PVRSRV_BRIDGE_SYNC_SERVERSYNCALLOC			PVRSRV_BRIDGE_SYNC_CMD_FIRST+6
-#define PVRSRV_BRIDGE_SYNC_SERVERSYNCFREE			PVRSRV_BRIDGE_SYNC_CMD_FIRST+7
-#define PVRSRV_BRIDGE_SYNC_SERVERSYNCQUEUEHWOP			PVRSRV_BRIDGE_SYNC_CMD_FIRST+8
-#define PVRSRV_BRIDGE_SYNC_SERVERSYNCGETSTATUS			PVRSRV_BRIDGE_SYNC_CMD_FIRST+9
-#define PVRSRV_BRIDGE_SYNC_SYNCPRIMOPCREATE			PVRSRV_BRIDGE_SYNC_CMD_FIRST+10
-#define PVRSRV_BRIDGE_SYNC_SYNCPRIMOPTAKE			PVRSRV_BRIDGE_SYNC_CMD_FIRST+11
-#define PVRSRV_BRIDGE_SYNC_SYNCPRIMOPREADY			PVRSRV_BRIDGE_SYNC_CMD_FIRST+12
-#define PVRSRV_BRIDGE_SYNC_SYNCPRIMOPCOMPLETE			PVRSRV_BRIDGE_SYNC_CMD_FIRST+13
-#define PVRSRV_BRIDGE_SYNC_SYNCPRIMOPDESTROY			PVRSRV_BRIDGE_SYNC_CMD_FIRST+14
-#define PVRSRV_BRIDGE_SYNC_SYNCPRIMPDUMP			PVRSRV_BRIDGE_SYNC_CMD_FIRST+15
-#define PVRSRV_BRIDGE_SYNC_SYNCPRIMPDUMPVALUE			PVRSRV_BRIDGE_SYNC_CMD_FIRST+16
-#define PVRSRV_BRIDGE_SYNC_SYNCPRIMPDUMPPOL			PVRSRV_BRIDGE_SYNC_CMD_FIRST+17
-#define PVRSRV_BRIDGE_SYNC_SYNCPRIMOPPDUMPPOL			PVRSRV_BRIDGE_SYNC_CMD_FIRST+18
-#define PVRSRV_BRIDGE_SYNC_SYNCPRIMPDUMPCBP			PVRSRV_BRIDGE_SYNC_CMD_FIRST+19
+#define PVRSRV_BRIDGE_SYNC_SERVERSYNCALLOC			PVRSRV_BRIDGE_SYNC_CMD_FIRST+4
+#define PVRSRV_BRIDGE_SYNC_SERVERSYNCFREE			PVRSRV_BRIDGE_SYNC_CMD_FIRST+5
+#define PVRSRV_BRIDGE_SYNC_SERVERSYNCQUEUEHWOP			PVRSRV_BRIDGE_SYNC_CMD_FIRST+6
+#define PVRSRV_BRIDGE_SYNC_SERVERSYNCGETSTATUS			PVRSRV_BRIDGE_SYNC_CMD_FIRST+7
+#define PVRSRV_BRIDGE_SYNC_SYNCPRIMOPCREATE			PVRSRV_BRIDGE_SYNC_CMD_FIRST+8
+#define PVRSRV_BRIDGE_SYNC_SYNCPRIMOPTAKE			PVRSRV_BRIDGE_SYNC_CMD_FIRST+9
+#define PVRSRV_BRIDGE_SYNC_SYNCPRIMOPREADY			PVRSRV_BRIDGE_SYNC_CMD_FIRST+10
+#define PVRSRV_BRIDGE_SYNC_SYNCPRIMOPCOMPLETE			PVRSRV_BRIDGE_SYNC_CMD_FIRST+11
+#define PVRSRV_BRIDGE_SYNC_SYNCPRIMOPDESTROY			PVRSRV_BRIDGE_SYNC_CMD_FIRST+12
+#define PVRSRV_BRIDGE_SYNC_SYNCPRIMPDUMP			PVRSRV_BRIDGE_SYNC_CMD_FIRST+13
+#define PVRSRV_BRIDGE_SYNC_SYNCPRIMPDUMPVALUE			PVRSRV_BRIDGE_SYNC_CMD_FIRST+14
+#define PVRSRV_BRIDGE_SYNC_SYNCPRIMPDUMPPOL			PVRSRV_BRIDGE_SYNC_CMD_FIRST+15
+#define PVRSRV_BRIDGE_SYNC_SYNCPRIMOPPDUMPPOL			PVRSRV_BRIDGE_SYNC_CMD_FIRST+16
+#define PVRSRV_BRIDGE_SYNC_SYNCPRIMPDUMPCBP			PVRSRV_BRIDGE_SYNC_CMD_FIRST+17
+#define PVRSRV_BRIDGE_SYNC_SYNCALLOCEVENT			PVRSRV_BRIDGE_SYNC_CMD_FIRST+18
+#define PVRSRV_BRIDGE_SYNC_SYNCFREEEVENT			PVRSRV_BRIDGE_SYNC_CMD_FIRST+19
 #define PVRSRV_BRIDGE_SYNC_CMD_LAST			(PVRSRV_BRIDGE_SYNC_CMD_FIRST+19)
 
 
@@ -153,46 +155,6 @@
 
 
 /*******************************************
-            SyncRecordRemoveByHandle          
- *******************************************/
-
-/* Bridge in structure for SyncRecordRemoveByHandle */
-typedef struct PVRSRV_BRIDGE_IN_SYNCRECORDREMOVEBYHANDLE_TAG
-{
-	IMG_HANDLE hhRecord;
-} __attribute__((packed)) PVRSRV_BRIDGE_IN_SYNCRECORDREMOVEBYHANDLE;
-
-/* Bridge out structure for SyncRecordRemoveByHandle */
-typedef struct PVRSRV_BRIDGE_OUT_SYNCRECORDREMOVEBYHANDLE_TAG
-{
-	PVRSRV_ERROR eError;
-} __attribute__((packed)) PVRSRV_BRIDGE_OUT_SYNCRECORDREMOVEBYHANDLE;
-
-
-/*******************************************
-            SyncRecordAdd          
- *******************************************/
-
-/* Bridge in structure for SyncRecordAdd */
-typedef struct PVRSRV_BRIDGE_IN_SYNCRECORDADD_TAG
-{
-	IMG_HANDLE hhServerSyncPrimBlock;
-	IMG_UINT32 ui32ui32FwBlockAddr;
-	IMG_UINT32 ui32ui32SyncOffset;
-	IMG_BOOL bbServerSync;
-	IMG_UINT32 ui32ClassNameSize;
-	const IMG_CHAR * puiClassName;
-} __attribute__((packed)) PVRSRV_BRIDGE_IN_SYNCRECORDADD;
-
-/* Bridge out structure for SyncRecordAdd */
-typedef struct PVRSRV_BRIDGE_OUT_SYNCRECORDADD_TAG
-{
-	IMG_HANDLE hhRecord;
-	PVRSRV_ERROR eError;
-} __attribute__((packed)) PVRSRV_BRIDGE_OUT_SYNCRECORDADD;
-
-
-/*******************************************
             ServerSyncAlloc          
  *******************************************/
 
@@ -477,4 +439,41 @@
 } __attribute__((packed)) PVRSRV_BRIDGE_OUT_SYNCPRIMPDUMPCBP;
 
 
+/*******************************************
+            SyncAllocEvent          
+ *******************************************/
+
+/* Bridge in structure for SyncAllocEvent */
+typedef struct PVRSRV_BRIDGE_IN_SYNCALLOCEVENT_TAG
+{
+	IMG_BOOL bServerSync;
+	IMG_UINT32 ui32FWAddr;
+	IMG_UINT32 ui32ClassNameSize;
+	const IMG_CHAR * puiClassName;
+} __attribute__((packed)) PVRSRV_BRIDGE_IN_SYNCALLOCEVENT;
+
+/* Bridge out structure for SyncAllocEvent */
+typedef struct PVRSRV_BRIDGE_OUT_SYNCALLOCEVENT_TAG
+{
+	PVRSRV_ERROR eError;
+} __attribute__((packed)) PVRSRV_BRIDGE_OUT_SYNCALLOCEVENT;
+
+
+/*******************************************
+            SyncFreeEvent          
+ *******************************************/
+
+/* Bridge in structure for SyncFreeEvent */
+typedef struct PVRSRV_BRIDGE_IN_SYNCFREEEVENT_TAG
+{
+	IMG_UINT32 ui32FWAddr;
+} __attribute__((packed)) PVRSRV_BRIDGE_IN_SYNCFREEEVENT;
+
+/* Bridge out structure for SyncFreeEvent */
+typedef struct PVRSRV_BRIDGE_OUT_SYNCFREEEVENT_TAG
+{
+	PVRSRV_ERROR eError;
+} __attribute__((packed)) PVRSRV_BRIDGE_OUT_SYNCFREEEVENT;
+
+
 #endif /* COMMON_SYNC_BRIDGE_H */
diff --git a/drivers/staging/imgtec/rogue/generated/sync_bridge/server_sync_bridge.c b/drivers/staging/imgtec/rogue/generated/sync_bridge/server_sync_bridge.c
index da6176a..746c4a2 100644
--- a/drivers/staging/imgtec/rogue/generated/sync_bridge/server_sync_bridge.c
+++ b/drivers/staging/imgtec/rogue/generated/sync_bridge/server_sync_bridge.c
@@ -46,6 +46,7 @@
 
 #include "img_defs.h"
 
+#include "sync.h"
 #include "sync_server.h"
 #include "pdump.h"
 
@@ -65,6 +66,8 @@
 
 
 
+
+
 /* ***************************************************************************
  * Server-side bridge entry points
  */
@@ -78,14 +81,14 @@
 	SYNC_PRIMITIVE_BLOCK * psSyncHandleInt = NULL;
 	PMR * pshSyncPMRInt = NULL;
 
+
+
 	PVR_UNREFERENCED_PARAMETER(psAllocSyncPrimitiveBlockIN);
 
 
 	psAllocSyncPrimitiveBlockOUT->hSyncHandle = NULL;
 
 
-	PMRLock();
-
 
 	psAllocSyncPrimitiveBlockOUT->eError =
 		PVRSRVAllocSyncPrimitiveBlockKM(psConnection, OSGetDevData(psConnection),
@@ -96,13 +99,18 @@
 	/* Exit early if bridged call fails */
 	if(psAllocSyncPrimitiveBlockOUT->eError != PVRSRV_OK)
 	{
-		PMRUnlock();
 		goto AllocSyncPrimitiveBlock_exit;
 	}
-	PMRUnlock();
+
+	/* Lock over handle creation. */
+	LockHandle();
 
 
-	psAllocSyncPrimitiveBlockOUT->eError = PVRSRVAllocHandle(psConnection->psHandleBase,
+
+
+
+	psAllocSyncPrimitiveBlockOUT->eError = PVRSRVAllocHandleUnlocked(psConnection->psHandleBase,
+
 							&psAllocSyncPrimitiveBlockOUT->hSyncHandle,
 							(void *) psSyncHandleInt,
 							PVRSRV_HANDLE_TYPE_SYNC_PRIMITIVE_BLOCK,
@@ -110,11 +118,17 @@
 							,(PFN_HANDLE_RELEASE)&PVRSRVFreeSyncPrimitiveBlockKM);
 	if (psAllocSyncPrimitiveBlockOUT->eError != PVRSRV_OK)
 	{
+		UnlockHandle();
 		goto AllocSyncPrimitiveBlock_exit;
 	}
 
 
-	psAllocSyncPrimitiveBlockOUT->eError = PVRSRVAllocSubHandle(psConnection->psHandleBase,
+
+
+
+
+	psAllocSyncPrimitiveBlockOUT->eError = PVRSRVAllocSubHandleUnlocked(psConnection->psHandleBase,
+
 							&psAllocSyncPrimitiveBlockOUT->hhSyncPMR,
 							(void *) pshSyncPMRInt,
 							PVRSRV_HANDLE_TYPE_PMR_LOCAL_EXPORT_HANDLE,
@@ -122,22 +136,38 @@
 							,psAllocSyncPrimitiveBlockOUT->hSyncHandle);
 	if (psAllocSyncPrimitiveBlockOUT->eError != PVRSRV_OK)
 	{
+		UnlockHandle();
 		goto AllocSyncPrimitiveBlock_exit;
 	}
 
+	/* Release now we have created handles. */
+	UnlockHandle();
 
 
 
 AllocSyncPrimitiveBlock_exit:
+
+
+
 	if (psAllocSyncPrimitiveBlockOUT->eError != PVRSRV_OK)
 	{
+		/* Lock over handle creation cleanup. */
+		LockHandle();
 		if (psAllocSyncPrimitiveBlockOUT->hSyncHandle)
 		{
-			PVRSRV_ERROR eError = PVRSRVReleaseHandle(psConnection->psHandleBase,
+
+
+			PVRSRV_ERROR eError = PVRSRVReleaseHandleUnlocked(psConnection->psHandleBase,
 						(IMG_HANDLE) psAllocSyncPrimitiveBlockOUT->hSyncHandle,
 						PVRSRV_HANDLE_TYPE_SYNC_PRIMITIVE_BLOCK);
-
-			/* Releasing the handle should free/destroy/release the resource. This should never fail... */
+			if ((eError != PVRSRV_OK) && (eError != PVRSRV_ERROR_RETRY))
+			{
+				PVR_DPF((PVR_DBG_ERROR,
+				        "PVRSRVBridgeAllocSyncPrimitiveBlock: %s",
+				        PVRSRVGetErrorStringKM(eError)));
+			}
+			/* Releasing the handle should free/destroy/release the resource.
+			 * This should never fail... */
 			PVR_ASSERT((eError == PVRSRV_OK) || (eError == PVRSRV_ERROR_RETRY));
 
 			/* Avoid freeing/destroying/releasing the resource a second time below */
@@ -145,6 +175,8 @@
 		}
 
 
+		/* Release now we have cleaned up creation handles. */
+		UnlockHandle();
 		if (psSyncHandleInt)
 		{
 			PVRSRVFreeSyncPrimitiveBlockKM(psSyncHandleInt);
@@ -155,6 +187,7 @@
 	return 0;
 }
 
+
 static IMG_INT
 PVRSRVBridgeFreeSyncPrimitiveBlock(IMG_UINT32 ui32DispatchTableEntry,
 					  PVRSRV_BRIDGE_IN_FREESYNCPRIMITIVEBLOCK *psFreeSyncPrimitiveBlockIN,
@@ -166,36 +199,53 @@
 
 
 
-	PMRLock();
+
+
+
+
+	/* Lock over handle destruction. */
+	LockHandle();
+
 
 
 
 
 	psFreeSyncPrimitiveBlockOUT->eError =
-		PVRSRVReleaseHandle(psConnection->psHandleBase,
+		PVRSRVReleaseHandleUnlocked(psConnection->psHandleBase,
 					(IMG_HANDLE) psFreeSyncPrimitiveBlockIN->hSyncHandle,
 					PVRSRV_HANDLE_TYPE_SYNC_PRIMITIVE_BLOCK);
-	if ((psFreeSyncPrimitiveBlockOUT->eError != PVRSRV_OK) && (psFreeSyncPrimitiveBlockOUT->eError != PVRSRV_ERROR_RETRY))
+	if ((psFreeSyncPrimitiveBlockOUT->eError != PVRSRV_OK) &&
+	    (psFreeSyncPrimitiveBlockOUT->eError != PVRSRV_ERROR_RETRY))
 	{
+		PVR_DPF((PVR_DBG_ERROR,
+		        "PVRSRVBridgeFreeSyncPrimitiveBlock: %s",
+		        PVRSRVGetErrorStringKM(psFreeSyncPrimitiveBlockOUT->eError)));
 		PVR_ASSERT(0);
-		PMRUnlock();
+		UnlockHandle();
 		goto FreeSyncPrimitiveBlock_exit;
 	}
 
-	PMRUnlock();
+	/* Release now we have destroyed handles. */
+	UnlockHandle();
+
 
 
 FreeSyncPrimitiveBlock_exit:
 
+
+
+
 	return 0;
 }
 
+
 static IMG_INT
 PVRSRVBridgeSyncPrimSet(IMG_UINT32 ui32DispatchTableEntry,
 					  PVRSRV_BRIDGE_IN_SYNCPRIMSET *psSyncPrimSetIN,
 					  PVRSRV_BRIDGE_OUT_SYNCPRIMSET *psSyncPrimSetOUT,
 					 CONNECTION_DATA *psConnection)
 {
+	IMG_HANDLE hSyncHandle = psSyncPrimSetIN->hSyncHandle;
 	SYNC_PRIMITIVE_BLOCK * psSyncHandleInt = NULL;
 
 
@@ -204,19 +254,29 @@
 
 
 
+	/* Lock over handle lookup. */
+	LockHandle();
+
+
+
+
+
 				{
 					/* Look up the address from the handle */
 					psSyncPrimSetOUT->eError =
-						PVRSRVLookupHandle(psConnection->psHandleBase,
+						PVRSRVLookupHandleUnlocked(psConnection->psHandleBase,
 											(void **) &psSyncHandleInt,
-											psSyncPrimSetIN->hSyncHandle,
-											PVRSRV_HANDLE_TYPE_SYNC_PRIMITIVE_BLOCK);
+											hSyncHandle,
+											PVRSRV_HANDLE_TYPE_SYNC_PRIMITIVE_BLOCK,
+											IMG_TRUE);
 					if(psSyncPrimSetOUT->eError != PVRSRV_OK)
 					{
+						UnlockHandle();
 						goto SyncPrimSet_exit;
 					}
 				}
-
+	/* Release now we have looked up handles. */
+	UnlockHandle();
 
 	psSyncPrimSetOUT->eError =
 		PVRSRVSyncPrimSetKM(
@@ -229,15 +289,38 @@
 
 SyncPrimSet_exit:
 
+	/* Lock over handle lookup cleanup. */
+	LockHandle();
+
+
+
+
+
+
+				{
+					/* Unreference the previously looked up handle */
+						if(psSyncHandleInt)
+						{
+							PVRSRVReleaseHandleUnlocked(psConnection->psHandleBase,
+											hSyncHandle,
+											PVRSRV_HANDLE_TYPE_SYNC_PRIMITIVE_BLOCK);
+						}
+				}
+	/* Release now we have cleaned up look up handles. */
+	UnlockHandle();
+
+
 	return 0;
 }
 
+
 static IMG_INT
 PVRSRVBridgeServerSyncPrimSet(IMG_UINT32 ui32DispatchTableEntry,
 					  PVRSRV_BRIDGE_IN_SERVERSYNCPRIMSET *psServerSyncPrimSetIN,
 					  PVRSRV_BRIDGE_OUT_SERVERSYNCPRIMSET *psServerSyncPrimSetOUT,
 					 CONNECTION_DATA *psConnection)
 {
+	IMG_HANDLE hSyncHandle = psServerSyncPrimSetIN->hSyncHandle;
 	SERVER_SYNC_PRIMITIVE * psSyncHandleInt = NULL;
 
 
@@ -246,19 +329,29 @@
 
 
 
+	/* Lock over handle lookup. */
+	LockHandle();
+
+
+
+
+
 				{
 					/* Look up the address from the handle */
 					psServerSyncPrimSetOUT->eError =
-						PVRSRVLookupHandle(psConnection->psHandleBase,
+						PVRSRVLookupHandleUnlocked(psConnection->psHandleBase,
 											(void **) &psSyncHandleInt,
-											psServerSyncPrimSetIN->hSyncHandle,
-											PVRSRV_HANDLE_TYPE_SERVER_SYNC_PRIMITIVE);
+											hSyncHandle,
+											PVRSRV_HANDLE_TYPE_SERVER_SYNC_PRIMITIVE,
+											IMG_TRUE);
 					if(psServerSyncPrimSetOUT->eError != PVRSRV_OK)
 					{
+						UnlockHandle();
 						goto ServerSyncPrimSet_exit;
 					}
 				}
-
+	/* Release now we have looked up handles. */
+	UnlockHandle();
 
 	psServerSyncPrimSetOUT->eError =
 		PVRSRVServerSyncPrimSetKM(
@@ -270,136 +363,31 @@
 
 ServerSyncPrimSet_exit:
 
-	return 0;
-}
-
-static IMG_INT
-PVRSRVBridgeSyncRecordRemoveByHandle(IMG_UINT32 ui32DispatchTableEntry,
-					  PVRSRV_BRIDGE_IN_SYNCRECORDREMOVEBYHANDLE *psSyncRecordRemoveByHandleIN,
-					  PVRSRV_BRIDGE_OUT_SYNCRECORDREMOVEBYHANDLE *psSyncRecordRemoveByHandleOUT,
-					 CONNECTION_DATA *psConnection)
-{
+	/* Lock over handle lookup cleanup. */
+	LockHandle();
 
 
 
 
 
 
-
-
-
-	psSyncRecordRemoveByHandleOUT->eError =
-		PVRSRVReleaseHandle(psConnection->psHandleBase,
-					(IMG_HANDLE) psSyncRecordRemoveByHandleIN->hhRecord,
-					PVRSRV_HANDLE_TYPE_SYNC_RECORD_HANDLE);
-	if ((psSyncRecordRemoveByHandleOUT->eError != PVRSRV_OK) && (psSyncRecordRemoveByHandleOUT->eError != PVRSRV_ERROR_RETRY))
-	{
-		PVR_ASSERT(0);
-		goto SyncRecordRemoveByHandle_exit;
-	}
-
-
-
-SyncRecordRemoveByHandle_exit:
-
-	return 0;
-}
-
-static IMG_INT
-PVRSRVBridgeSyncRecordAdd(IMG_UINT32 ui32DispatchTableEntry,
-					  PVRSRV_BRIDGE_IN_SYNCRECORDADD *psSyncRecordAddIN,
-					  PVRSRV_BRIDGE_OUT_SYNCRECORDADD *psSyncRecordAddOUT,
-					 CONNECTION_DATA *psConnection)
-{
-	SYNC_RECORD_HANDLE pshRecordInt = NULL;
-	SYNC_PRIMITIVE_BLOCK * pshServerSyncPrimBlockInt = NULL;
-	IMG_CHAR *uiClassNameInt = NULL;
-
-
-
-
-	if (psSyncRecordAddIN->ui32ClassNameSize != 0)
-	{
-		uiClassNameInt = OSAllocMemNoStats(psSyncRecordAddIN->ui32ClassNameSize * sizeof(IMG_CHAR));
-		if (!uiClassNameInt)
-		{
-			psSyncRecordAddOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
-	
-			goto SyncRecordAdd_exit;
-		}
-	}
-
-			/* Copy the data over */
-			if ( !OSAccessOK(PVR_VERIFY_READ, (void*) psSyncRecordAddIN->puiClassName, psSyncRecordAddIN->ui32ClassNameSize * sizeof(IMG_CHAR))
-				|| (OSCopyFromUser(NULL, uiClassNameInt, psSyncRecordAddIN->puiClassName,
-				psSyncRecordAddIN->ui32ClassNameSize * sizeof(IMG_CHAR)) != PVRSRV_OK) )
-			{
-				psSyncRecordAddOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
-
-				goto SyncRecordAdd_exit;
-			}
-
-
-
 				{
-					/* Look up the address from the handle */
-					psSyncRecordAddOUT->eError =
-						PVRSRVLookupHandle(psConnection->psHandleBase,
-											(void **) &pshServerSyncPrimBlockInt,
-											psSyncRecordAddIN->hhServerSyncPrimBlock,
-											PVRSRV_HANDLE_TYPE_SYNC_PRIMITIVE_BLOCK);
-					if(psSyncRecordAddOUT->eError != PVRSRV_OK)
-					{
-						goto SyncRecordAdd_exit;
-					}
+					/* Unreference the previously looked up handle */
+						if(psSyncHandleInt)
+						{
+							PVRSRVReleaseHandleUnlocked(psConnection->psHandleBase,
+											hSyncHandle,
+											PVRSRV_HANDLE_TYPE_SERVER_SYNC_PRIMITIVE);
+						}
 				}
+	/* Release now we have cleaned up look up handles. */
+	UnlockHandle();
 
 
-	psSyncRecordAddOUT->eError =
-		PVRSRVSyncRecordAddKM(
-					&pshRecordInt,
-					pshServerSyncPrimBlockInt,
-					psSyncRecordAddIN->ui32ui32FwBlockAddr,
-					psSyncRecordAddIN->ui32ui32SyncOffset,
-					psSyncRecordAddIN->bbServerSync,
-					psSyncRecordAddIN->ui32ClassNameSize,
-					uiClassNameInt);
-	/* Exit early if bridged call fails */
-	if(psSyncRecordAddOUT->eError != PVRSRV_OK)
-	{
-		goto SyncRecordAdd_exit;
-	}
-
-
-	psSyncRecordAddOUT->eError = PVRSRVAllocHandle(psConnection->psHandleBase,
-							&psSyncRecordAddOUT->hhRecord,
-							(void *) pshRecordInt,
-							PVRSRV_HANDLE_TYPE_SYNC_RECORD_HANDLE,
-							PVRSRV_HANDLE_ALLOC_FLAG_NONE
-							,(PFN_HANDLE_RELEASE)&PVRSRVSyncRecordRemoveByHandleKM);
-	if (psSyncRecordAddOUT->eError != PVRSRV_OK)
-	{
-		goto SyncRecordAdd_exit;
-	}
-
-
-
-
-SyncRecordAdd_exit:
-	if (psSyncRecordAddOUT->eError != PVRSRV_OK)
-	{
-		if (pshRecordInt)
-		{
-			PVRSRVSyncRecordRemoveByHandleKM(pshRecordInt);
-		}
-	}
-
-	if (uiClassNameInt)
-		OSFreeMemNoStats(uiClassNameInt);
-
 	return 0;
 }
 
+
 static IMG_INT
 PVRSRVBridgeServerSyncAlloc(IMG_UINT32 ui32DispatchTableEntry,
 					  PVRSRV_BRIDGE_IN_SERVERSYNCALLOC *psServerSyncAllocIN,
@@ -409,34 +397,64 @@
 	SERVER_SYNC_PRIMITIVE * psSyncHandleInt = NULL;
 	IMG_CHAR *uiClassNameInt = NULL;
 
+	IMG_UINT32 ui32NextOffset = 0;
+	IMG_BYTE   *pArrayArgsBuffer = NULL;
+#if !defined(INTEGRITY_OS)
+	IMG_BOOL bHaveEnoughSpace = IMG_FALSE;
+#endif
+
+	IMG_UINT32 ui32BufferSize = 
+			(psServerSyncAllocIN->ui32ClassNameSize * sizeof(IMG_CHAR)) +
+			0;
 
 
 
-	if (psServerSyncAllocIN->ui32ClassNameSize != 0)
+
+
+	if (ui32BufferSize != 0)
 	{
-		uiClassNameInt = OSAllocMemNoStats(psServerSyncAllocIN->ui32ClassNameSize * sizeof(IMG_CHAR));
-		if (!uiClassNameInt)
+#if !defined(INTEGRITY_OS)
+		/* Try to use remainder of input buffer for copies if possible, word-aligned for safety. */
+		IMG_UINT32 ui32InBufferOffset = PVR_ALIGN(sizeof(*psServerSyncAllocIN), sizeof(unsigned long));
+		IMG_UINT32 ui32InBufferExcessSize = ui32InBufferOffset >= PVRSRV_MAX_BRIDGE_IN_SIZE ? 0 :
+			PVRSRV_MAX_BRIDGE_IN_SIZE - ui32InBufferOffset;
+
+		bHaveEnoughSpace = ui32BufferSize <= ui32InBufferExcessSize;
+		if (bHaveEnoughSpace)
 		{
-			psServerSyncAllocOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
-	
-			goto ServerSyncAlloc_exit;
+			IMG_BYTE *pInputBuffer = (IMG_BYTE *)psServerSyncAllocIN;
+
+			pArrayArgsBuffer = &pInputBuffer[ui32InBufferOffset];		}
+		else
+#endif
+		{
+			pArrayArgsBuffer = OSAllocMemNoStats(ui32BufferSize);
+
+			if(!pArrayArgsBuffer)
+			{
+				psServerSyncAllocOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
+				goto ServerSyncAlloc_exit;
+			}
 		}
 	}
 
+	if (psServerSyncAllocIN->ui32ClassNameSize != 0)
+	{
+		uiClassNameInt = (IMG_CHAR*)(((IMG_UINT8 *)pArrayArgsBuffer) + ui32NextOffset);
+		ui32NextOffset += psServerSyncAllocIN->ui32ClassNameSize * sizeof(IMG_CHAR);
+	}
+
 			/* Copy the data over */
-			if ( !OSAccessOK(PVR_VERIFY_READ, (void*) psServerSyncAllocIN->puiClassName, psServerSyncAllocIN->ui32ClassNameSize * sizeof(IMG_CHAR))
-				|| (OSCopyFromUser(NULL, uiClassNameInt, psServerSyncAllocIN->puiClassName,
-				psServerSyncAllocIN->ui32ClassNameSize * sizeof(IMG_CHAR)) != PVRSRV_OK) )
+			if (psServerSyncAllocIN->ui32ClassNameSize * sizeof(IMG_CHAR) > 0)
 			{
-				psServerSyncAllocOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
+				if ( OSCopyFromUser(NULL, uiClassNameInt, psServerSyncAllocIN->puiClassName, psServerSyncAllocIN->ui32ClassNameSize * sizeof(IMG_CHAR)) != PVRSRV_OK )
+				{
+					psServerSyncAllocOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
 
-				goto ServerSyncAlloc_exit;
+					goto ServerSyncAlloc_exit;
+				}
 			}
 
-#if defined(PDUMP)
-	PMRLock();
-#endif
-
 
 	psServerSyncAllocOUT->eError =
 		PVRSRVServerSyncAllocKM(psConnection, OSGetDevData(psConnection),
@@ -447,17 +465,18 @@
 	/* Exit early if bridged call fails */
 	if(psServerSyncAllocOUT->eError != PVRSRV_OK)
 	{
-#if defined(PDUMP)
-		PMRUnlock();
-#endif
 		goto ServerSyncAlloc_exit;
 	}
-#if defined(PDUMP)
-	PMRUnlock();
-#endif
+
+	/* Lock over handle creation. */
+	LockHandle();
 
 
-	psServerSyncAllocOUT->eError = PVRSRVAllocHandle(psConnection->psHandleBase,
+
+
+
+	psServerSyncAllocOUT->eError = PVRSRVAllocHandleUnlocked(psConnection->psHandleBase,
+
 							&psServerSyncAllocOUT->hSyncHandle,
 							(void *) psSyncHandleInt,
 							PVRSRV_HANDLE_TYPE_SERVER_SYNC_PRIMITIVE,
@@ -465,13 +484,19 @@
 							,(PFN_HANDLE_RELEASE)&PVRSRVServerSyncFreeKM);
 	if (psServerSyncAllocOUT->eError != PVRSRV_OK)
 	{
+		UnlockHandle();
 		goto ServerSyncAlloc_exit;
 	}
 
+	/* Release now we have created handles. */
+	UnlockHandle();
 
 
 
 ServerSyncAlloc_exit:
+
+
+
 	if (psServerSyncAllocOUT->eError != PVRSRV_OK)
 	{
 		if (psSyncHandleInt)
@@ -480,12 +505,21 @@
 		}
 	}
 
-	if (uiClassNameInt)
-		OSFreeMemNoStats(uiClassNameInt);
+	/* Allocated space should be equal to the last updated offset */
+	PVR_ASSERT(ui32BufferSize == ui32NextOffset);
+
+#if defined(INTEGRITY_OS)
+	if(pArrayArgsBuffer)
+#else
+	if(!bHaveEnoughSpace && pArrayArgsBuffer)
+#endif
+		OSFreeMemNoStats(pArrayArgsBuffer);
+
 
 	return 0;
 }
 
+
 static IMG_INT
 PVRSRVBridgeServerSyncFree(IMG_UINT32 ui32DispatchTableEntry,
 					  PVRSRV_BRIDGE_IN_SERVERSYNCFREE *psServerSyncFreeIN,
@@ -501,56 +535,80 @@
 
 
 
+	/* Lock over handle destruction. */
+	LockHandle();
+
+
+
+
+
 	psServerSyncFreeOUT->eError =
-		PVRSRVReleaseHandle(psConnection->psHandleBase,
+		PVRSRVReleaseHandleUnlocked(psConnection->psHandleBase,
 					(IMG_HANDLE) psServerSyncFreeIN->hSyncHandle,
 					PVRSRV_HANDLE_TYPE_SERVER_SYNC_PRIMITIVE);
-	if ((psServerSyncFreeOUT->eError != PVRSRV_OK) && (psServerSyncFreeOUT->eError != PVRSRV_ERROR_RETRY))
+	if ((psServerSyncFreeOUT->eError != PVRSRV_OK) &&
+	    (psServerSyncFreeOUT->eError != PVRSRV_ERROR_RETRY))
 	{
+		PVR_DPF((PVR_DBG_ERROR,
+		        "PVRSRVBridgeServerSyncFree: %s",
+		        PVRSRVGetErrorStringKM(psServerSyncFreeOUT->eError)));
 		PVR_ASSERT(0);
+		UnlockHandle();
 		goto ServerSyncFree_exit;
 	}
 
+	/* Release now we have destroyed handles. */
+	UnlockHandle();
+
 
 
 ServerSyncFree_exit:
 
+
+
+
 	return 0;
 }
 
+
 static IMG_INT
 PVRSRVBridgeServerSyncQueueHWOp(IMG_UINT32 ui32DispatchTableEntry,
 					  PVRSRV_BRIDGE_IN_SERVERSYNCQUEUEHWOP *psServerSyncQueueHWOpIN,
 					  PVRSRV_BRIDGE_OUT_SERVERSYNCQUEUEHWOP *psServerSyncQueueHWOpOUT,
 					 CONNECTION_DATA *psConnection)
 {
+	IMG_HANDLE hSyncHandle = psServerSyncQueueHWOpIN->hSyncHandle;
 	SERVER_SYNC_PRIMITIVE * psSyncHandleInt = NULL;
 
 
 
 
 
-#if defined(PDUMP)
-	PMRLock();
-#endif
+
+
+	/* Lock over handle lookup. */
+	LockHandle();
+
+
+
 
 
 				{
 					/* Look up the address from the handle */
 					psServerSyncQueueHWOpOUT->eError =
-						PVRSRVLookupHandle(psConnection->psHandleBase,
+						PVRSRVLookupHandleUnlocked(psConnection->psHandleBase,
 											(void **) &psSyncHandleInt,
-											psServerSyncQueueHWOpIN->hSyncHandle,
-											PVRSRV_HANDLE_TYPE_SERVER_SYNC_PRIMITIVE);
+											hSyncHandle,
+											PVRSRV_HANDLE_TYPE_SERVER_SYNC_PRIMITIVE,
+											IMG_TRUE);
 					if(psServerSyncQueueHWOpOUT->eError != PVRSRV_OK)
 					{
-#if defined(PDUMP)
-						PMRUnlock();
-#endif
+						UnlockHandle();
 						goto ServerSyncQueueHWOp_exit;
 					}
 				}
-
+	/* Release now we have looked up handles. */
+	UnlockHandle();
 
 	psServerSyncQueueHWOpOUT->eError =
 		PVRSRVServerSyncQueueHWOpKM(
@@ -558,18 +616,37 @@
 					psServerSyncQueueHWOpIN->bbUpdate,
 					&psServerSyncQueueHWOpOUT->ui32FenceValue,
 					&psServerSyncQueueHWOpOUT->ui32UpdateValue);
-#if defined(PDUMP)
-	PMRUnlock();
-#endif
 
 
 
 
 ServerSyncQueueHWOp_exit:
 
+	/* Lock over handle lookup cleanup. */
+	LockHandle();
+
+
+
+
+
+
+				{
+					/* Unreference the previously looked up handle */
+						if(psSyncHandleInt)
+						{
+							PVRSRVReleaseHandleUnlocked(psConnection->psHandleBase,
+											hSyncHandle,
+											PVRSRV_HANDLE_TYPE_SERVER_SYNC_PRIMITIVE);
+						}
+				}
+	/* Release now we have cleaned up look up handles. */
+	UnlockHandle();
+
+
 	return 0;
 }
 
+
 static IMG_INT
 PVRSRVBridgeServerSyncGetStatus(IMG_UINT32 ui32DispatchTableEntry,
 					  PVRSRV_BRIDGE_IN_SERVERSYNCGETSTATUS *psServerSyncGetStatusIN,
@@ -583,6 +660,22 @@
 	IMG_UINT32 *pui32CurrentOpInt = NULL;
 	IMG_UINT32 *pui32NextOpInt = NULL;
 
+	IMG_UINT32 ui32NextOffset = 0;
+	IMG_BYTE   *pArrayArgsBuffer = NULL;
+#if !defined(INTEGRITY_OS)
+	IMG_BOOL bHaveEnoughSpace = IMG_FALSE;
+#endif
+
+	IMG_UINT32 ui32BufferSize = 
+			(psServerSyncGetStatusIN->ui32SyncCount * sizeof(SERVER_SYNC_PRIMITIVE *)) +
+			(psServerSyncGetStatusIN->ui32SyncCount * sizeof(IMG_HANDLE)) +
+			(psServerSyncGetStatusIN->ui32SyncCount * sizeof(IMG_UINT32)) +
+			(psServerSyncGetStatusIN->ui32SyncCount * sizeof(IMG_UINT32)) +
+			(psServerSyncGetStatusIN->ui32SyncCount * sizeof(IMG_UINT32)) +
+			(psServerSyncGetStatusIN->ui32SyncCount * sizeof(IMG_UINT32)) +
+			0;
+
+
 
 	psServerSyncGetStatusOUT->pui32UID = psServerSyncGetStatusIN->pui32UID;
 	psServerSyncGetStatusOUT->pui32FWAddr = psServerSyncGetStatusIN->pui32FWAddr;
@@ -590,78 +683,81 @@
 	psServerSyncGetStatusOUT->pui32NextOp = psServerSyncGetStatusIN->pui32NextOp;
 
 
+	if (ui32BufferSize != 0)
+	{
+#if !defined(INTEGRITY_OS)
+		/* Try to use remainder of input buffer for copies if possible, word-aligned for safety. */
+		IMG_UINT32 ui32InBufferOffset = PVR_ALIGN(sizeof(*psServerSyncGetStatusIN), sizeof(unsigned long));
+		IMG_UINT32 ui32InBufferExcessSize = ui32InBufferOffset >= PVRSRV_MAX_BRIDGE_IN_SIZE ? 0 :
+			PVRSRV_MAX_BRIDGE_IN_SIZE - ui32InBufferOffset;
+
+		bHaveEnoughSpace = ui32BufferSize <= ui32InBufferExcessSize;
+		if (bHaveEnoughSpace)
+		{
+			IMG_BYTE *pInputBuffer = (IMG_BYTE *)psServerSyncGetStatusIN;
+
+			pArrayArgsBuffer = &pInputBuffer[ui32InBufferOffset];		}
+		else
+#endif
+		{
+			pArrayArgsBuffer = OSAllocMemNoStats(ui32BufferSize);
+
+			if(!pArrayArgsBuffer)
+			{
+				psServerSyncGetStatusOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
+				goto ServerSyncGetStatus_exit;
+			}
+		}
+	}
+
 	if (psServerSyncGetStatusIN->ui32SyncCount != 0)
 	{
-		psSyncHandleInt = OSAllocMemNoStats(psServerSyncGetStatusIN->ui32SyncCount * sizeof(SERVER_SYNC_PRIMITIVE *));
-		if (!psSyncHandleInt)
-		{
-			psServerSyncGetStatusOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
-	
-			goto ServerSyncGetStatus_exit;
-		}
-		hSyncHandleInt2 = OSAllocMemNoStats(psServerSyncGetStatusIN->ui32SyncCount * sizeof(IMG_HANDLE));
-		if (!hSyncHandleInt2)
-		{
-			psServerSyncGetStatusOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
-	
-			goto ServerSyncGetStatus_exit;
-		}
+		psSyncHandleInt = (SERVER_SYNC_PRIMITIVE **)(((IMG_UINT8 *)pArrayArgsBuffer) + ui32NextOffset);
+		ui32NextOffset += psServerSyncGetStatusIN->ui32SyncCount * sizeof(SERVER_SYNC_PRIMITIVE *);
+		hSyncHandleInt2 = (IMG_HANDLE *)(((IMG_UINT8 *)pArrayArgsBuffer) + ui32NextOffset); 
+		ui32NextOffset += psServerSyncGetStatusIN->ui32SyncCount * sizeof(IMG_HANDLE);
 	}
 
 			/* Copy the data over */
-			if ( !OSAccessOK(PVR_VERIFY_READ, (void*) psServerSyncGetStatusIN->phSyncHandle, psServerSyncGetStatusIN->ui32SyncCount * sizeof(IMG_HANDLE))
-				|| (OSCopyFromUser(NULL, hSyncHandleInt2, psServerSyncGetStatusIN->phSyncHandle,
-				psServerSyncGetStatusIN->ui32SyncCount * sizeof(IMG_HANDLE)) != PVRSRV_OK) )
+			if (psServerSyncGetStatusIN->ui32SyncCount * sizeof(IMG_HANDLE) > 0)
 			{
-				psServerSyncGetStatusOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
+				if ( OSCopyFromUser(NULL, hSyncHandleInt2, psServerSyncGetStatusIN->phSyncHandle, psServerSyncGetStatusIN->ui32SyncCount * sizeof(IMG_HANDLE)) != PVRSRV_OK )
+				{
+					psServerSyncGetStatusOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
 
-				goto ServerSyncGetStatus_exit;
+					goto ServerSyncGetStatus_exit;
+				}
 			}
 	if (psServerSyncGetStatusIN->ui32SyncCount != 0)
 	{
-		pui32UIDInt = OSAllocMemNoStats(psServerSyncGetStatusIN->ui32SyncCount * sizeof(IMG_UINT32));
-		if (!pui32UIDInt)
-		{
-			psServerSyncGetStatusOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
-	
-			goto ServerSyncGetStatus_exit;
-		}
+		pui32UIDInt = (IMG_UINT32*)(((IMG_UINT8 *)pArrayArgsBuffer) + ui32NextOffset);
+		ui32NextOffset += psServerSyncGetStatusIN->ui32SyncCount * sizeof(IMG_UINT32);
 	}
 
 	if (psServerSyncGetStatusIN->ui32SyncCount != 0)
 	{
-		pui32FWAddrInt = OSAllocMemNoStats(psServerSyncGetStatusIN->ui32SyncCount * sizeof(IMG_UINT32));
-		if (!pui32FWAddrInt)
-		{
-			psServerSyncGetStatusOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
-	
-			goto ServerSyncGetStatus_exit;
-		}
+		pui32FWAddrInt = (IMG_UINT32*)(((IMG_UINT8 *)pArrayArgsBuffer) + ui32NextOffset);
+		ui32NextOffset += psServerSyncGetStatusIN->ui32SyncCount * sizeof(IMG_UINT32);
 	}
 
 	if (psServerSyncGetStatusIN->ui32SyncCount != 0)
 	{
-		pui32CurrentOpInt = OSAllocMemNoStats(psServerSyncGetStatusIN->ui32SyncCount * sizeof(IMG_UINT32));
-		if (!pui32CurrentOpInt)
-		{
-			psServerSyncGetStatusOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
-	
-			goto ServerSyncGetStatus_exit;
-		}
+		pui32CurrentOpInt = (IMG_UINT32*)(((IMG_UINT8 *)pArrayArgsBuffer) + ui32NextOffset);
+		ui32NextOffset += psServerSyncGetStatusIN->ui32SyncCount * sizeof(IMG_UINT32);
 	}
 
 	if (psServerSyncGetStatusIN->ui32SyncCount != 0)
 	{
-		pui32NextOpInt = OSAllocMemNoStats(psServerSyncGetStatusIN->ui32SyncCount * sizeof(IMG_UINT32));
-		if (!pui32NextOpInt)
-		{
-			psServerSyncGetStatusOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
-	
-			goto ServerSyncGetStatus_exit;
-		}
+		pui32NextOpInt = (IMG_UINT32*)(((IMG_UINT8 *)pArrayArgsBuffer) + ui32NextOffset);
+		ui32NextOffset += psServerSyncGetStatusIN->ui32SyncCount * sizeof(IMG_UINT32);
 	}
 
 
+	/* Lock over handle lookup. */
+	LockHandle();
+
+
+
 
 
 	{
@@ -672,18 +768,21 @@
 				{
 					/* Look up the address from the handle */
 					psServerSyncGetStatusOUT->eError =
-						PVRSRVLookupHandle(psConnection->psHandleBase,
+						PVRSRVLookupHandleUnlocked(psConnection->psHandleBase,
 											(void **) &psSyncHandleInt[i],
 											hSyncHandleInt2[i],
-											PVRSRV_HANDLE_TYPE_SERVER_SYNC_PRIMITIVE);
+											PVRSRV_HANDLE_TYPE_SERVER_SYNC_PRIMITIVE,
+											IMG_TRUE);
 					if(psServerSyncGetStatusOUT->eError != PVRSRV_OK)
 					{
+						UnlockHandle();
 						goto ServerSyncGetStatus_exit;
 					}
 				}
-
 		}
 	}
+	/* Release now we have looked up handles. */
+	UnlockHandle();
 
 	psServerSyncGetStatusOUT->eError =
 		PVRSRVServerSyncGetStatusKM(
@@ -696,60 +795,97 @@
 
 
 
-	if ( !OSAccessOK(PVR_VERIFY_WRITE, (void*) psServerSyncGetStatusOUT->pui32UID, (psServerSyncGetStatusIN->ui32SyncCount * sizeof(IMG_UINT32)))
-		|| (OSCopyToUser(NULL, psServerSyncGetStatusOUT->pui32UID, pui32UIDInt,
-		(psServerSyncGetStatusIN->ui32SyncCount * sizeof(IMG_UINT32))) != PVRSRV_OK) )
+	if ((psServerSyncGetStatusIN->ui32SyncCount * sizeof(IMG_UINT32)) > 0)
 	{
-		psServerSyncGetStatusOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
+		if ( OSCopyToUser(NULL, psServerSyncGetStatusOUT->pui32UID, pui32UIDInt,
+			(psServerSyncGetStatusIN->ui32SyncCount * sizeof(IMG_UINT32))) != PVRSRV_OK )
+		{
+			psServerSyncGetStatusOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
 
-		goto ServerSyncGetStatus_exit;
+			goto ServerSyncGetStatus_exit;
+		}
 	}
 
-	if ( !OSAccessOK(PVR_VERIFY_WRITE, (void*) psServerSyncGetStatusOUT->pui32FWAddr, (psServerSyncGetStatusIN->ui32SyncCount * sizeof(IMG_UINT32)))
-		|| (OSCopyToUser(NULL, psServerSyncGetStatusOUT->pui32FWAddr, pui32FWAddrInt,
-		(psServerSyncGetStatusIN->ui32SyncCount * sizeof(IMG_UINT32))) != PVRSRV_OK) )
+	if ((psServerSyncGetStatusIN->ui32SyncCount * sizeof(IMG_UINT32)) > 0)
 	{
-		psServerSyncGetStatusOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
+		if ( OSCopyToUser(NULL, psServerSyncGetStatusOUT->pui32FWAddr, pui32FWAddrInt,
+			(psServerSyncGetStatusIN->ui32SyncCount * sizeof(IMG_UINT32))) != PVRSRV_OK )
+		{
+			psServerSyncGetStatusOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
 
-		goto ServerSyncGetStatus_exit;
+			goto ServerSyncGetStatus_exit;
+		}
 	}
 
-	if ( !OSAccessOK(PVR_VERIFY_WRITE, (void*) psServerSyncGetStatusOUT->pui32CurrentOp, (psServerSyncGetStatusIN->ui32SyncCount * sizeof(IMG_UINT32)))
-		|| (OSCopyToUser(NULL, psServerSyncGetStatusOUT->pui32CurrentOp, pui32CurrentOpInt,
-		(psServerSyncGetStatusIN->ui32SyncCount * sizeof(IMG_UINT32))) != PVRSRV_OK) )
+	if ((psServerSyncGetStatusIN->ui32SyncCount * sizeof(IMG_UINT32)) > 0)
 	{
-		psServerSyncGetStatusOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
+		if ( OSCopyToUser(NULL, psServerSyncGetStatusOUT->pui32CurrentOp, pui32CurrentOpInt,
+			(psServerSyncGetStatusIN->ui32SyncCount * sizeof(IMG_UINT32))) != PVRSRV_OK )
+		{
+			psServerSyncGetStatusOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
 
-		goto ServerSyncGetStatus_exit;
+			goto ServerSyncGetStatus_exit;
+		}
 	}
 
-	if ( !OSAccessOK(PVR_VERIFY_WRITE, (void*) psServerSyncGetStatusOUT->pui32NextOp, (psServerSyncGetStatusIN->ui32SyncCount * sizeof(IMG_UINT32)))
-		|| (OSCopyToUser(NULL, psServerSyncGetStatusOUT->pui32NextOp, pui32NextOpInt,
-		(psServerSyncGetStatusIN->ui32SyncCount * sizeof(IMG_UINT32))) != PVRSRV_OK) )
+	if ((psServerSyncGetStatusIN->ui32SyncCount * sizeof(IMG_UINT32)) > 0)
 	{
-		psServerSyncGetStatusOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
+		if ( OSCopyToUser(NULL, psServerSyncGetStatusOUT->pui32NextOp, pui32NextOpInt,
+			(psServerSyncGetStatusIN->ui32SyncCount * sizeof(IMG_UINT32))) != PVRSRV_OK )
+		{
+			psServerSyncGetStatusOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
 
-		goto ServerSyncGetStatus_exit;
+			goto ServerSyncGetStatus_exit;
+		}
 	}
 
 
 ServerSyncGetStatus_exit:
-	if (psSyncHandleInt)
-		OSFreeMemNoStats(psSyncHandleInt);
+
+	/* Lock over handle lookup cleanup. */
+	LockHandle();
+
+
+
+
+
+
+
 	if (hSyncHandleInt2)
-		OSFreeMemNoStats(hSyncHandleInt2);
-	if (pui32UIDInt)
-		OSFreeMemNoStats(pui32UIDInt);
-	if (pui32FWAddrInt)
-		OSFreeMemNoStats(pui32FWAddrInt);
-	if (pui32CurrentOpInt)
-		OSFreeMemNoStats(pui32CurrentOpInt);
-	if (pui32NextOpInt)
-		OSFreeMemNoStats(pui32NextOpInt);
+	{
+		IMG_UINT32 i;
+
+		for (i=0;i<psServerSyncGetStatusIN->ui32SyncCount;i++)
+		{
+				{
+					/* Unreference the previously looked up handle */
+						if(psSyncHandleInt[i])
+						{
+							PVRSRVReleaseHandleUnlocked(psConnection->psHandleBase,
+											hSyncHandleInt2[i],
+											PVRSRV_HANDLE_TYPE_SERVER_SYNC_PRIMITIVE);
+						}
+				}
+		}
+	}
+	/* Release now we have cleaned up look up handles. */
+	UnlockHandle();
+
+	/* Allocated space should be equal to the last updated offset */
+	PVR_ASSERT(ui32BufferSize == ui32NextOffset);
+
+#if defined(INTEGRITY_OS)
+	if(pArrayArgsBuffer)
+#else
+	if(!bHaveEnoughSpace && pArrayArgsBuffer)
+#endif
+		OSFreeMemNoStats(pArrayArgsBuffer);
+
 
 	return 0;
 }
 
+
 static IMG_INT
 PVRSRVBridgeSyncPrimOpCreate(IMG_UINT32 ui32DispatchTableEntry,
 					  PVRSRV_BRIDGE_IN_SYNCPRIMOPCREATE *psSyncPrimOpCreateIN,
@@ -764,104 +900,126 @@
 	IMG_HANDLE *hServerSyncInt2 = NULL;
 	SERVER_OP_COOKIE * psServerCookieInt = NULL;
 
+	IMG_UINT32 ui32NextOffset = 0;
+	IMG_BYTE   *pArrayArgsBuffer = NULL;
+#if !defined(INTEGRITY_OS)
+	IMG_BOOL bHaveEnoughSpace = IMG_FALSE;
+#endif
+
+	IMG_UINT32 ui32BufferSize = 
+			(psSyncPrimOpCreateIN->ui32SyncBlockCount * sizeof(SYNC_PRIMITIVE_BLOCK *)) +
+			(psSyncPrimOpCreateIN->ui32SyncBlockCount * sizeof(IMG_HANDLE)) +
+			(psSyncPrimOpCreateIN->ui32ClientSyncCount * sizeof(IMG_UINT32)) +
+			(psSyncPrimOpCreateIN->ui32ClientSyncCount * sizeof(IMG_UINT32)) +
+			(psSyncPrimOpCreateIN->ui32ServerSyncCount * sizeof(SERVER_SYNC_PRIMITIVE *)) +
+			(psSyncPrimOpCreateIN->ui32ServerSyncCount * sizeof(IMG_HANDLE)) +
+			0;
 
 
 
+
+
+	if (ui32BufferSize != 0)
+	{
+#if !defined(INTEGRITY_OS)
+		/* Try to use remainder of input buffer for copies if possible, word-aligned for safety. */
+		IMG_UINT32 ui32InBufferOffset = PVR_ALIGN(sizeof(*psSyncPrimOpCreateIN), sizeof(unsigned long));
+		IMG_UINT32 ui32InBufferExcessSize = ui32InBufferOffset >= PVRSRV_MAX_BRIDGE_IN_SIZE ? 0 :
+			PVRSRV_MAX_BRIDGE_IN_SIZE - ui32InBufferOffset;
+
+		bHaveEnoughSpace = ui32BufferSize <= ui32InBufferExcessSize;
+		if (bHaveEnoughSpace)
+		{
+			IMG_BYTE *pInputBuffer = (IMG_BYTE *)psSyncPrimOpCreateIN;
+
+			pArrayArgsBuffer = &pInputBuffer[ui32InBufferOffset];		}
+		else
+#endif
+		{
+			pArrayArgsBuffer = OSAllocMemNoStats(ui32BufferSize);
+
+			if(!pArrayArgsBuffer)
+			{
+				psSyncPrimOpCreateOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
+				goto SyncPrimOpCreate_exit;
+			}
+		}
+	}
+
 	if (psSyncPrimOpCreateIN->ui32SyncBlockCount != 0)
 	{
-		psBlockListInt = OSAllocMemNoStats(psSyncPrimOpCreateIN->ui32SyncBlockCount * sizeof(SYNC_PRIMITIVE_BLOCK *));
-		if (!psBlockListInt)
-		{
-			psSyncPrimOpCreateOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
-	
-			goto SyncPrimOpCreate_exit;
-		}
-		hBlockListInt2 = OSAllocMemNoStats(psSyncPrimOpCreateIN->ui32SyncBlockCount * sizeof(IMG_HANDLE));
-		if (!hBlockListInt2)
-		{
-			psSyncPrimOpCreateOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
-	
-			goto SyncPrimOpCreate_exit;
-		}
+		psBlockListInt = (SYNC_PRIMITIVE_BLOCK **)(((IMG_UINT8 *)pArrayArgsBuffer) + ui32NextOffset);
+		ui32NextOffset += psSyncPrimOpCreateIN->ui32SyncBlockCount * sizeof(SYNC_PRIMITIVE_BLOCK *);
+		hBlockListInt2 = (IMG_HANDLE *)(((IMG_UINT8 *)pArrayArgsBuffer) + ui32NextOffset); 
+		ui32NextOffset += psSyncPrimOpCreateIN->ui32SyncBlockCount * sizeof(IMG_HANDLE);
 	}
 
 			/* Copy the data over */
-			if ( !OSAccessOK(PVR_VERIFY_READ, (void*) psSyncPrimOpCreateIN->phBlockList, psSyncPrimOpCreateIN->ui32SyncBlockCount * sizeof(IMG_HANDLE))
-				|| (OSCopyFromUser(NULL, hBlockListInt2, psSyncPrimOpCreateIN->phBlockList,
-				psSyncPrimOpCreateIN->ui32SyncBlockCount * sizeof(IMG_HANDLE)) != PVRSRV_OK) )
+			if (psSyncPrimOpCreateIN->ui32SyncBlockCount * sizeof(IMG_HANDLE) > 0)
 			{
-				psSyncPrimOpCreateOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
+				if ( OSCopyFromUser(NULL, hBlockListInt2, psSyncPrimOpCreateIN->phBlockList, psSyncPrimOpCreateIN->ui32SyncBlockCount * sizeof(IMG_HANDLE)) != PVRSRV_OK )
+				{
+					psSyncPrimOpCreateOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
 
-				goto SyncPrimOpCreate_exit;
+					goto SyncPrimOpCreate_exit;
+				}
 			}
 	if (psSyncPrimOpCreateIN->ui32ClientSyncCount != 0)
 	{
-		ui32SyncBlockIndexInt = OSAllocMemNoStats(psSyncPrimOpCreateIN->ui32ClientSyncCount * sizeof(IMG_UINT32));
-		if (!ui32SyncBlockIndexInt)
-		{
-			psSyncPrimOpCreateOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
-	
-			goto SyncPrimOpCreate_exit;
-		}
+		ui32SyncBlockIndexInt = (IMG_UINT32*)(((IMG_UINT8 *)pArrayArgsBuffer) + ui32NextOffset);
+		ui32NextOffset += psSyncPrimOpCreateIN->ui32ClientSyncCount * sizeof(IMG_UINT32);
 	}
 
 			/* Copy the data over */
-			if ( !OSAccessOK(PVR_VERIFY_READ, (void*) psSyncPrimOpCreateIN->pui32SyncBlockIndex, psSyncPrimOpCreateIN->ui32ClientSyncCount * sizeof(IMG_UINT32))
-				|| (OSCopyFromUser(NULL, ui32SyncBlockIndexInt, psSyncPrimOpCreateIN->pui32SyncBlockIndex,
-				psSyncPrimOpCreateIN->ui32ClientSyncCount * sizeof(IMG_UINT32)) != PVRSRV_OK) )
+			if (psSyncPrimOpCreateIN->ui32ClientSyncCount * sizeof(IMG_UINT32) > 0)
 			{
-				psSyncPrimOpCreateOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
+				if ( OSCopyFromUser(NULL, ui32SyncBlockIndexInt, psSyncPrimOpCreateIN->pui32SyncBlockIndex, psSyncPrimOpCreateIN->ui32ClientSyncCount * sizeof(IMG_UINT32)) != PVRSRV_OK )
+				{
+					psSyncPrimOpCreateOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
 
-				goto SyncPrimOpCreate_exit;
+					goto SyncPrimOpCreate_exit;
+				}
 			}
 	if (psSyncPrimOpCreateIN->ui32ClientSyncCount != 0)
 	{
-		ui32IndexInt = OSAllocMemNoStats(psSyncPrimOpCreateIN->ui32ClientSyncCount * sizeof(IMG_UINT32));
-		if (!ui32IndexInt)
-		{
-			psSyncPrimOpCreateOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
-	
-			goto SyncPrimOpCreate_exit;
-		}
+		ui32IndexInt = (IMG_UINT32*)(((IMG_UINT8 *)pArrayArgsBuffer) + ui32NextOffset);
+		ui32NextOffset += psSyncPrimOpCreateIN->ui32ClientSyncCount * sizeof(IMG_UINT32);
 	}
 
 			/* Copy the data over */
-			if ( !OSAccessOK(PVR_VERIFY_READ, (void*) psSyncPrimOpCreateIN->pui32Index, psSyncPrimOpCreateIN->ui32ClientSyncCount * sizeof(IMG_UINT32))
-				|| (OSCopyFromUser(NULL, ui32IndexInt, psSyncPrimOpCreateIN->pui32Index,
-				psSyncPrimOpCreateIN->ui32ClientSyncCount * sizeof(IMG_UINT32)) != PVRSRV_OK) )
+			if (psSyncPrimOpCreateIN->ui32ClientSyncCount * sizeof(IMG_UINT32) > 0)
 			{
-				psSyncPrimOpCreateOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
+				if ( OSCopyFromUser(NULL, ui32IndexInt, psSyncPrimOpCreateIN->pui32Index, psSyncPrimOpCreateIN->ui32ClientSyncCount * sizeof(IMG_UINT32)) != PVRSRV_OK )
+				{
+					psSyncPrimOpCreateOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
 
-				goto SyncPrimOpCreate_exit;
+					goto SyncPrimOpCreate_exit;
+				}
 			}
 	if (psSyncPrimOpCreateIN->ui32ServerSyncCount != 0)
 	{
-		psServerSyncInt = OSAllocMemNoStats(psSyncPrimOpCreateIN->ui32ServerSyncCount * sizeof(SERVER_SYNC_PRIMITIVE *));
-		if (!psServerSyncInt)
-		{
-			psSyncPrimOpCreateOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
-	
-			goto SyncPrimOpCreate_exit;
-		}
-		hServerSyncInt2 = OSAllocMemNoStats(psSyncPrimOpCreateIN->ui32ServerSyncCount * sizeof(IMG_HANDLE));
-		if (!hServerSyncInt2)
-		{
-			psSyncPrimOpCreateOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
-	
-			goto SyncPrimOpCreate_exit;
-		}
+		psServerSyncInt = (SERVER_SYNC_PRIMITIVE **)(((IMG_UINT8 *)pArrayArgsBuffer) + ui32NextOffset);
+		ui32NextOffset += psSyncPrimOpCreateIN->ui32ServerSyncCount * sizeof(SERVER_SYNC_PRIMITIVE *);
+		hServerSyncInt2 = (IMG_HANDLE *)(((IMG_UINT8 *)pArrayArgsBuffer) + ui32NextOffset); 
+		ui32NextOffset += psSyncPrimOpCreateIN->ui32ServerSyncCount * sizeof(IMG_HANDLE);
 	}
 
 			/* Copy the data over */
-			if ( !OSAccessOK(PVR_VERIFY_READ, (void*) psSyncPrimOpCreateIN->phServerSync, psSyncPrimOpCreateIN->ui32ServerSyncCount * sizeof(IMG_HANDLE))
-				|| (OSCopyFromUser(NULL, hServerSyncInt2, psSyncPrimOpCreateIN->phServerSync,
-				psSyncPrimOpCreateIN->ui32ServerSyncCount * sizeof(IMG_HANDLE)) != PVRSRV_OK) )
+			if (psSyncPrimOpCreateIN->ui32ServerSyncCount * sizeof(IMG_HANDLE) > 0)
 			{
-				psSyncPrimOpCreateOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
+				if ( OSCopyFromUser(NULL, hServerSyncInt2, psSyncPrimOpCreateIN->phServerSync, psSyncPrimOpCreateIN->ui32ServerSyncCount * sizeof(IMG_HANDLE)) != PVRSRV_OK )
+				{
+					psSyncPrimOpCreateOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
 
-				goto SyncPrimOpCreate_exit;
+					goto SyncPrimOpCreate_exit;
+				}
 			}
 
+	/* Lock over handle lookup. */
+	LockHandle();
+
+
+
 
 
 	{
@@ -872,19 +1030,24 @@
 				{
 					/* Look up the address from the handle */
 					psSyncPrimOpCreateOUT->eError =
-						PVRSRVLookupHandle(psConnection->psHandleBase,
+						PVRSRVLookupHandleUnlocked(psConnection->psHandleBase,
 											(void **) &psBlockListInt[i],
 											hBlockListInt2[i],
-											PVRSRV_HANDLE_TYPE_SYNC_PRIMITIVE_BLOCK);
+											PVRSRV_HANDLE_TYPE_SYNC_PRIMITIVE_BLOCK,
+											IMG_TRUE);
 					if(psSyncPrimOpCreateOUT->eError != PVRSRV_OK)
 					{
+						UnlockHandle();
 						goto SyncPrimOpCreate_exit;
 					}
 				}
-
 		}
 	}
 
+
+
+
+
 	{
 		IMG_UINT32 i;
 
@@ -893,18 +1056,21 @@
 				{
 					/* Look up the address from the handle */
 					psSyncPrimOpCreateOUT->eError =
-						PVRSRVLookupHandle(psConnection->psHandleBase,
+						PVRSRVLookupHandleUnlocked(psConnection->psHandleBase,
 											(void **) &psServerSyncInt[i],
 											hServerSyncInt2[i],
-											PVRSRV_HANDLE_TYPE_SERVER_SYNC_PRIMITIVE);
+											PVRSRV_HANDLE_TYPE_SERVER_SYNC_PRIMITIVE,
+											IMG_TRUE);
 					if(psSyncPrimOpCreateOUT->eError != PVRSRV_OK)
 					{
+						UnlockHandle();
 						goto SyncPrimOpCreate_exit;
 					}
 				}
-
 		}
 	}
+	/* Release now we have looked up handles. */
+	UnlockHandle();
 
 	psSyncPrimOpCreateOUT->eError =
 		PVRSRVSyncPrimOpCreateKM(
@@ -922,8 +1088,15 @@
 		goto SyncPrimOpCreate_exit;
 	}
 
+	/* Lock over handle creation. */
+	LockHandle();
 
-	psSyncPrimOpCreateOUT->eError = PVRSRVAllocHandle(psConnection->psHandleBase,
+
+
+
+
+	psSyncPrimOpCreateOUT->eError = PVRSRVAllocHandleUnlocked(psConnection->psHandleBase,
+
 							&psSyncPrimOpCreateOUT->hServerCookie,
 							(void *) psServerCookieInt,
 							PVRSRV_HANDLE_TYPE_SERVER_OP_COOKIE,
@@ -931,13 +1104,69 @@
 							,(PFN_HANDLE_RELEASE)&PVRSRVSyncPrimOpDestroyKM);
 	if (psSyncPrimOpCreateOUT->eError != PVRSRV_OK)
 	{
+		UnlockHandle();
 		goto SyncPrimOpCreate_exit;
 	}
 
+	/* Release now we have created handles. */
+	UnlockHandle();
+
+
+
+SyncPrimOpCreate_exit:
+
+	/* Lock over handle lookup cleanup. */
+	LockHandle();
+
+
+
+
+
+
+
+	if (hBlockListInt2)
+	{
+		IMG_UINT32 i;
+
+		for (i=0;i<psSyncPrimOpCreateIN->ui32SyncBlockCount;i++)
+		{
+				{
+					/* Unreference the previously looked up handle */
+						if(psBlockListInt[i])
+						{
+							PVRSRVReleaseHandleUnlocked(psConnection->psHandleBase,
+											hBlockListInt2[i],
+											PVRSRV_HANDLE_TYPE_SYNC_PRIMITIVE_BLOCK);
+						}
+				}
+		}
+	}
+
 
 
 
-SyncPrimOpCreate_exit:
+
+
+	if (hServerSyncInt2)
+	{
+		IMG_UINT32 i;
+
+		for (i=0;i<psSyncPrimOpCreateIN->ui32ServerSyncCount;i++)
+		{
+				{
+					/* Unreference the previously looked up handle */
+						if(psServerSyncInt[i])
+						{
+							PVRSRVReleaseHandleUnlocked(psConnection->psHandleBase,
+											hServerSyncInt2[i],
+											PVRSRV_HANDLE_TYPE_SERVER_SYNC_PRIMITIVE);
+						}
+				}
+		}
+	}
+	/* Release now we have cleaned up look up handles. */
+	UnlockHandle();
+
 	if (psSyncPrimOpCreateOUT->eError != PVRSRV_OK)
 	{
 		if (psServerCookieInt)
@@ -946,133 +1175,166 @@
 		}
 	}
 
-	if (psBlockListInt)
-		OSFreeMemNoStats(psBlockListInt);
-	if (hBlockListInt2)
-		OSFreeMemNoStats(hBlockListInt2);
-	if (ui32SyncBlockIndexInt)
-		OSFreeMemNoStats(ui32SyncBlockIndexInt);
-	if (ui32IndexInt)
-		OSFreeMemNoStats(ui32IndexInt);
-	if (psServerSyncInt)
-		OSFreeMemNoStats(psServerSyncInt);
-	if (hServerSyncInt2)
-		OSFreeMemNoStats(hServerSyncInt2);
+	/* Allocated space should be equal to the last updated offset */
+	PVR_ASSERT(ui32BufferSize == ui32NextOffset);
+
+#if defined(INTEGRITY_OS)
+	if(pArrayArgsBuffer)
+#else
+	if(!bHaveEnoughSpace && pArrayArgsBuffer)
+#endif
+		OSFreeMemNoStats(pArrayArgsBuffer);
+
 
 	return 0;
 }
 
+
 static IMG_INT
 PVRSRVBridgeSyncPrimOpTake(IMG_UINT32 ui32DispatchTableEntry,
 					  PVRSRV_BRIDGE_IN_SYNCPRIMOPTAKE *psSyncPrimOpTakeIN,
 					  PVRSRV_BRIDGE_OUT_SYNCPRIMOPTAKE *psSyncPrimOpTakeOUT,
 					 CONNECTION_DATA *psConnection)
 {
+	IMG_HANDLE hServerCookie = psSyncPrimOpTakeIN->hServerCookie;
 	SERVER_OP_COOKIE * psServerCookieInt = NULL;
 	IMG_UINT32 *ui32FlagsInt = NULL;
 	IMG_UINT32 *ui32FenceValueInt = NULL;
 	IMG_UINT32 *ui32UpdateValueInt = NULL;
 	IMG_UINT32 *ui32ServerFlagsInt = NULL;
 
+	IMG_UINT32 ui32NextOffset = 0;
+	IMG_BYTE   *pArrayArgsBuffer = NULL;
+#if !defined(INTEGRITY_OS)
+	IMG_BOOL bHaveEnoughSpace = IMG_FALSE;
+#endif
+
+	IMG_UINT32 ui32BufferSize = 
+			(psSyncPrimOpTakeIN->ui32ClientSyncCount * sizeof(IMG_UINT32)) +
+			(psSyncPrimOpTakeIN->ui32ClientSyncCount * sizeof(IMG_UINT32)) +
+			(psSyncPrimOpTakeIN->ui32ClientSyncCount * sizeof(IMG_UINT32)) +
+			(psSyncPrimOpTakeIN->ui32ServerSyncCount * sizeof(IMG_UINT32)) +
+			0;
 
 
 
-	if (psSyncPrimOpTakeIN->ui32ClientSyncCount != 0)
+
+
+	if (ui32BufferSize != 0)
 	{
-		ui32FlagsInt = OSAllocMemNoStats(psSyncPrimOpTakeIN->ui32ClientSyncCount * sizeof(IMG_UINT32));
-		if (!ui32FlagsInt)
+#if !defined(INTEGRITY_OS)
+		/* Try to use remainder of input buffer for copies if possible, word-aligned for safety. */
+		IMG_UINT32 ui32InBufferOffset = PVR_ALIGN(sizeof(*psSyncPrimOpTakeIN), sizeof(unsigned long));
+		IMG_UINT32 ui32InBufferExcessSize = ui32InBufferOffset >= PVRSRV_MAX_BRIDGE_IN_SIZE ? 0 :
+			PVRSRV_MAX_BRIDGE_IN_SIZE - ui32InBufferOffset;
+
+		bHaveEnoughSpace = ui32BufferSize <= ui32InBufferExcessSize;
+		if (bHaveEnoughSpace)
 		{
-			psSyncPrimOpTakeOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
-	
-			goto SyncPrimOpTake_exit;
+			IMG_BYTE *pInputBuffer = (IMG_BYTE *)psSyncPrimOpTakeIN;
+
+			pArrayArgsBuffer = &pInputBuffer[ui32InBufferOffset];		}
+		else
+#endif
+		{
+			pArrayArgsBuffer = OSAllocMemNoStats(ui32BufferSize);
+
+			if(!pArrayArgsBuffer)
+			{
+				psSyncPrimOpTakeOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
+				goto SyncPrimOpTake_exit;
+			}
 		}
 	}
 
-			/* Copy the data over */
-			if ( !OSAccessOK(PVR_VERIFY_READ, (void*) psSyncPrimOpTakeIN->pui32Flags, psSyncPrimOpTakeIN->ui32ClientSyncCount * sizeof(IMG_UINT32))
-				|| (OSCopyFromUser(NULL, ui32FlagsInt, psSyncPrimOpTakeIN->pui32Flags,
-				psSyncPrimOpTakeIN->ui32ClientSyncCount * sizeof(IMG_UINT32)) != PVRSRV_OK) )
-			{
-				psSyncPrimOpTakeOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
+	if (psSyncPrimOpTakeIN->ui32ClientSyncCount != 0)
+	{
+		ui32FlagsInt = (IMG_UINT32*)(((IMG_UINT8 *)pArrayArgsBuffer) + ui32NextOffset);
+		ui32NextOffset += psSyncPrimOpTakeIN->ui32ClientSyncCount * sizeof(IMG_UINT32);
+	}
 
-				goto SyncPrimOpTake_exit;
+			/* Copy the data over */
+			if (psSyncPrimOpTakeIN->ui32ClientSyncCount * sizeof(IMG_UINT32) > 0)
+			{
+				if ( OSCopyFromUser(NULL, ui32FlagsInt, psSyncPrimOpTakeIN->pui32Flags, psSyncPrimOpTakeIN->ui32ClientSyncCount * sizeof(IMG_UINT32)) != PVRSRV_OK )
+				{
+					psSyncPrimOpTakeOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
+
+					goto SyncPrimOpTake_exit;
+				}
 			}
 	if (psSyncPrimOpTakeIN->ui32ClientSyncCount != 0)
 	{
-		ui32FenceValueInt = OSAllocMemNoStats(psSyncPrimOpTakeIN->ui32ClientSyncCount * sizeof(IMG_UINT32));
-		if (!ui32FenceValueInt)
-		{
-			psSyncPrimOpTakeOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
-	
-			goto SyncPrimOpTake_exit;
-		}
+		ui32FenceValueInt = (IMG_UINT32*)(((IMG_UINT8 *)pArrayArgsBuffer) + ui32NextOffset);
+		ui32NextOffset += psSyncPrimOpTakeIN->ui32ClientSyncCount * sizeof(IMG_UINT32);
 	}
 
 			/* Copy the data over */
-			if ( !OSAccessOK(PVR_VERIFY_READ, (void*) psSyncPrimOpTakeIN->pui32FenceValue, psSyncPrimOpTakeIN->ui32ClientSyncCount * sizeof(IMG_UINT32))
-				|| (OSCopyFromUser(NULL, ui32FenceValueInt, psSyncPrimOpTakeIN->pui32FenceValue,
-				psSyncPrimOpTakeIN->ui32ClientSyncCount * sizeof(IMG_UINT32)) != PVRSRV_OK) )
+			if (psSyncPrimOpTakeIN->ui32ClientSyncCount * sizeof(IMG_UINT32) > 0)
 			{
-				psSyncPrimOpTakeOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
+				if ( OSCopyFromUser(NULL, ui32FenceValueInt, psSyncPrimOpTakeIN->pui32FenceValue, psSyncPrimOpTakeIN->ui32ClientSyncCount * sizeof(IMG_UINT32)) != PVRSRV_OK )
+				{
+					psSyncPrimOpTakeOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
 
-				goto SyncPrimOpTake_exit;
+					goto SyncPrimOpTake_exit;
+				}
 			}
 	if (psSyncPrimOpTakeIN->ui32ClientSyncCount != 0)
 	{
-		ui32UpdateValueInt = OSAllocMemNoStats(psSyncPrimOpTakeIN->ui32ClientSyncCount * sizeof(IMG_UINT32));
-		if (!ui32UpdateValueInt)
-		{
-			psSyncPrimOpTakeOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
-	
-			goto SyncPrimOpTake_exit;
-		}
+		ui32UpdateValueInt = (IMG_UINT32*)(((IMG_UINT8 *)pArrayArgsBuffer) + ui32NextOffset);
+		ui32NextOffset += psSyncPrimOpTakeIN->ui32ClientSyncCount * sizeof(IMG_UINT32);
 	}
 
 			/* Copy the data over */
-			if ( !OSAccessOK(PVR_VERIFY_READ, (void*) psSyncPrimOpTakeIN->pui32UpdateValue, psSyncPrimOpTakeIN->ui32ClientSyncCount * sizeof(IMG_UINT32))
-				|| (OSCopyFromUser(NULL, ui32UpdateValueInt, psSyncPrimOpTakeIN->pui32UpdateValue,
-				psSyncPrimOpTakeIN->ui32ClientSyncCount * sizeof(IMG_UINT32)) != PVRSRV_OK) )
+			if (psSyncPrimOpTakeIN->ui32ClientSyncCount * sizeof(IMG_UINT32) > 0)
 			{
-				psSyncPrimOpTakeOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
+				if ( OSCopyFromUser(NULL, ui32UpdateValueInt, psSyncPrimOpTakeIN->pui32UpdateValue, psSyncPrimOpTakeIN->ui32ClientSyncCount * sizeof(IMG_UINT32)) != PVRSRV_OK )
+				{
+					psSyncPrimOpTakeOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
 
-				goto SyncPrimOpTake_exit;
+					goto SyncPrimOpTake_exit;
+				}
 			}
 	if (psSyncPrimOpTakeIN->ui32ServerSyncCount != 0)
 	{
-		ui32ServerFlagsInt = OSAllocMemNoStats(psSyncPrimOpTakeIN->ui32ServerSyncCount * sizeof(IMG_UINT32));
-		if (!ui32ServerFlagsInt)
-		{
-			psSyncPrimOpTakeOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
-	
-			goto SyncPrimOpTake_exit;
-		}
+		ui32ServerFlagsInt = (IMG_UINT32*)(((IMG_UINT8 *)pArrayArgsBuffer) + ui32NextOffset);
+		ui32NextOffset += psSyncPrimOpTakeIN->ui32ServerSyncCount * sizeof(IMG_UINT32);
 	}
 
 			/* Copy the data over */
-			if ( !OSAccessOK(PVR_VERIFY_READ, (void*) psSyncPrimOpTakeIN->pui32ServerFlags, psSyncPrimOpTakeIN->ui32ServerSyncCount * sizeof(IMG_UINT32))
-				|| (OSCopyFromUser(NULL, ui32ServerFlagsInt, psSyncPrimOpTakeIN->pui32ServerFlags,
-				psSyncPrimOpTakeIN->ui32ServerSyncCount * sizeof(IMG_UINT32)) != PVRSRV_OK) )
+			if (psSyncPrimOpTakeIN->ui32ServerSyncCount * sizeof(IMG_UINT32) > 0)
 			{
-				psSyncPrimOpTakeOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
+				if ( OSCopyFromUser(NULL, ui32ServerFlagsInt, psSyncPrimOpTakeIN->pui32ServerFlags, psSyncPrimOpTakeIN->ui32ServerSyncCount * sizeof(IMG_UINT32)) != PVRSRV_OK )
+				{
+					psSyncPrimOpTakeOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
 
-				goto SyncPrimOpTake_exit;
+					goto SyncPrimOpTake_exit;
+				}
 			}
 
+	/* Lock over handle lookup. */
+	LockHandle();
+
+
+
 
 
 				{
 					/* Look up the address from the handle */
 					psSyncPrimOpTakeOUT->eError =
-						PVRSRVLookupHandle(psConnection->psHandleBase,
+						PVRSRVLookupHandleUnlocked(psConnection->psHandleBase,
 											(void **) &psServerCookieInt,
-											psSyncPrimOpTakeIN->hServerCookie,
-											PVRSRV_HANDLE_TYPE_SERVER_OP_COOKIE);
+											hServerCookie,
+											PVRSRV_HANDLE_TYPE_SERVER_OP_COOKIE,
+											IMG_TRUE);
 					if(psSyncPrimOpTakeOUT->eError != PVRSRV_OK)
 					{
+						UnlockHandle();
 						goto SyncPrimOpTake_exit;
 					}
 				}
-
+	/* Release now we have looked up handles. */
+	UnlockHandle();
 
 	psSyncPrimOpTakeOUT->eError =
 		PVRSRVSyncPrimOpTakeKM(
@@ -1088,24 +1350,49 @@
 
 
 SyncPrimOpTake_exit:
-	if (ui32FlagsInt)
-		OSFreeMemNoStats(ui32FlagsInt);
-	if (ui32FenceValueInt)
-		OSFreeMemNoStats(ui32FenceValueInt);
-	if (ui32UpdateValueInt)
-		OSFreeMemNoStats(ui32UpdateValueInt);
-	if (ui32ServerFlagsInt)
-		OSFreeMemNoStats(ui32ServerFlagsInt);
+
+	/* Lock over handle lookup cleanup. */
+	LockHandle();
+
+
+
+
+
+
+				{
+					/* Unreference the previously looked up handle */
+						if(psServerCookieInt)
+						{
+							PVRSRVReleaseHandleUnlocked(psConnection->psHandleBase,
+											hServerCookie,
+											PVRSRV_HANDLE_TYPE_SERVER_OP_COOKIE);
+						}
+				}
+	/* Release now we have cleaned up look up handles. */
+	UnlockHandle();
+
+	/* Allocated space should be equal to the last updated offset */
+	PVR_ASSERT(ui32BufferSize == ui32NextOffset);
+
+#if defined(INTEGRITY_OS)
+	if(pArrayArgsBuffer)
+#else
+	if(!bHaveEnoughSpace && pArrayArgsBuffer)
+#endif
+		OSFreeMemNoStats(pArrayArgsBuffer);
+
 
 	return 0;
 }
 
+
 static IMG_INT
 PVRSRVBridgeSyncPrimOpReady(IMG_UINT32 ui32DispatchTableEntry,
 					  PVRSRV_BRIDGE_IN_SYNCPRIMOPREADY *psSyncPrimOpReadyIN,
 					  PVRSRV_BRIDGE_OUT_SYNCPRIMOPREADY *psSyncPrimOpReadyOUT,
 					 CONNECTION_DATA *psConnection)
 {
+	IMG_HANDLE hServerCookie = psSyncPrimOpReadyIN->hServerCookie;
 	SERVER_OP_COOKIE * psServerCookieInt = NULL;
 
 
@@ -1114,19 +1401,29 @@
 
 
 
+	/* Lock over handle lookup. */
+	LockHandle();
+
+
+
+
+
 				{
 					/* Look up the address from the handle */
 					psSyncPrimOpReadyOUT->eError =
-						PVRSRVLookupHandle(psConnection->psHandleBase,
+						PVRSRVLookupHandleUnlocked(psConnection->psHandleBase,
 											(void **) &psServerCookieInt,
-											psSyncPrimOpReadyIN->hServerCookie,
-											PVRSRV_HANDLE_TYPE_SERVER_OP_COOKIE);
+											hServerCookie,
+											PVRSRV_HANDLE_TYPE_SERVER_OP_COOKIE,
+											IMG_TRUE);
 					if(psSyncPrimOpReadyOUT->eError != PVRSRV_OK)
 					{
+						UnlockHandle();
 						goto SyncPrimOpReady_exit;
 					}
 				}
-
+	/* Release now we have looked up handles. */
+	UnlockHandle();
 
 	psSyncPrimOpReadyOUT->eError =
 		PVRSRVSyncPrimOpReadyKM(
@@ -1138,15 +1435,38 @@
 
 SyncPrimOpReady_exit:
 
+	/* Lock over handle lookup cleanup. */
+	LockHandle();
+
+
+
+
+
+
+				{
+					/* Unreference the previously looked up handle */
+						if(psServerCookieInt)
+						{
+							PVRSRVReleaseHandleUnlocked(psConnection->psHandleBase,
+											hServerCookie,
+											PVRSRV_HANDLE_TYPE_SERVER_OP_COOKIE);
+						}
+				}
+	/* Release now we have cleaned up look up handles. */
+	UnlockHandle();
+
+
 	return 0;
 }
 
+
 static IMG_INT
 PVRSRVBridgeSyncPrimOpComplete(IMG_UINT32 ui32DispatchTableEntry,
 					  PVRSRV_BRIDGE_IN_SYNCPRIMOPCOMPLETE *psSyncPrimOpCompleteIN,
 					  PVRSRV_BRIDGE_OUT_SYNCPRIMOPCOMPLETE *psSyncPrimOpCompleteOUT,
 					 CONNECTION_DATA *psConnection)
 {
+	IMG_HANDLE hServerCookie = psSyncPrimOpCompleteIN->hServerCookie;
 	SERVER_OP_COOKIE * psServerCookieInt = NULL;
 
 
@@ -1155,19 +1475,29 @@
 
 
 
+	/* Lock over handle lookup. */
+	LockHandle();
+
+
+
+
+
 				{
 					/* Look up the address from the handle */
 					psSyncPrimOpCompleteOUT->eError =
-						PVRSRVLookupHandle(psConnection->psHandleBase,
+						PVRSRVLookupHandleUnlocked(psConnection->psHandleBase,
 											(void **) &psServerCookieInt,
-											psSyncPrimOpCompleteIN->hServerCookie,
-											PVRSRV_HANDLE_TYPE_SERVER_OP_COOKIE);
+											hServerCookie,
+											PVRSRV_HANDLE_TYPE_SERVER_OP_COOKIE,
+											IMG_TRUE);
 					if(psSyncPrimOpCompleteOUT->eError != PVRSRV_OK)
 					{
+						UnlockHandle();
 						goto SyncPrimOpComplete_exit;
 					}
 				}
-
+	/* Release now we have looked up handles. */
+	UnlockHandle();
 
 	psSyncPrimOpCompleteOUT->eError =
 		PVRSRVSyncPrimOpCompleteKM(
@@ -1178,9 +1508,31 @@
 
 SyncPrimOpComplete_exit:
 
+	/* Lock over handle lookup cleanup. */
+	LockHandle();
+
+
+
+
+
+
+				{
+					/* Unreference the previously looked up handle */
+						if(psServerCookieInt)
+						{
+							PVRSRVReleaseHandleUnlocked(psConnection->psHandleBase,
+											hServerCookie,
+											PVRSRV_HANDLE_TYPE_SERVER_OP_COOKIE);
+						}
+				}
+	/* Release now we have cleaned up look up handles. */
+	UnlockHandle();
+
+
 	return 0;
 }
 
+
 static IMG_INT
 PVRSRVBridgeSyncPrimOpDestroy(IMG_UINT32 ui32DispatchTableEntry,
 					  PVRSRV_BRIDGE_IN_SYNCPRIMOPDESTROY *psSyncPrimOpDestroyIN,
@@ -1196,118 +1548,207 @@
 
 
 
+	/* Lock over handle destruction. */
+	LockHandle();
+
+
+
+
+
 	psSyncPrimOpDestroyOUT->eError =
-		PVRSRVReleaseHandle(psConnection->psHandleBase,
+		PVRSRVReleaseHandleUnlocked(psConnection->psHandleBase,
 					(IMG_HANDLE) psSyncPrimOpDestroyIN->hServerCookie,
 					PVRSRV_HANDLE_TYPE_SERVER_OP_COOKIE);
-	if ((psSyncPrimOpDestroyOUT->eError != PVRSRV_OK) && (psSyncPrimOpDestroyOUT->eError != PVRSRV_ERROR_RETRY))
+	if ((psSyncPrimOpDestroyOUT->eError != PVRSRV_OK) &&
+	    (psSyncPrimOpDestroyOUT->eError != PVRSRV_ERROR_RETRY))
 	{
+		PVR_DPF((PVR_DBG_ERROR,
+		        "PVRSRVBridgeSyncPrimOpDestroy: %s",
+		        PVRSRVGetErrorStringKM(psSyncPrimOpDestroyOUT->eError)));
 		PVR_ASSERT(0);
+		UnlockHandle();
 		goto SyncPrimOpDestroy_exit;
 	}
 
+	/* Release now we have destroyed handles. */
+	UnlockHandle();
+
 
 
 SyncPrimOpDestroy_exit:
 
+
+
+
 	return 0;
 }
 
+
+#if defined(PDUMP)
 static IMG_INT
 PVRSRVBridgeSyncPrimPDump(IMG_UINT32 ui32DispatchTableEntry,
 					  PVRSRV_BRIDGE_IN_SYNCPRIMPDUMP *psSyncPrimPDumpIN,
 					  PVRSRV_BRIDGE_OUT_SYNCPRIMPDUMP *psSyncPrimPDumpOUT,
 					 CONNECTION_DATA *psConnection)
 {
+	IMG_HANDLE hSyncHandle = psSyncPrimPDumpIN->hSyncHandle;
 	SYNC_PRIMITIVE_BLOCK * psSyncHandleInt = NULL;
 
 
 
 
 
-	PMRLock();
+
+
+	/* Lock over handle lookup. */
+	LockHandle();
+
+
+
 
 
 				{
 					/* Look up the address from the handle */
 					psSyncPrimPDumpOUT->eError =
-						PVRSRVLookupHandle(psConnection->psHandleBase,
+						PVRSRVLookupHandleUnlocked(psConnection->psHandleBase,
 											(void **) &psSyncHandleInt,
-											psSyncPrimPDumpIN->hSyncHandle,
-											PVRSRV_HANDLE_TYPE_SYNC_PRIMITIVE_BLOCK);
+											hSyncHandle,
+											PVRSRV_HANDLE_TYPE_SYNC_PRIMITIVE_BLOCK,
+											IMG_TRUE);
 					if(psSyncPrimPDumpOUT->eError != PVRSRV_OK)
 					{
-						PMRUnlock();
+						UnlockHandle();
 						goto SyncPrimPDump_exit;
 					}
 				}
-
+	/* Release now we have looked up handles. */
+	UnlockHandle();
 
 	psSyncPrimPDumpOUT->eError =
 		PVRSRVSyncPrimPDumpKM(
 					psSyncHandleInt,
 					psSyncPrimPDumpIN->ui32Offset);
-	PMRUnlock();
 
 
 
 
 SyncPrimPDump_exit:
 
+	/* Lock over handle lookup cleanup. */
+	LockHandle();
+
+
+
+
+
+
+				{
+					/* Unreference the previously looked up handle */
+						if(psSyncHandleInt)
+						{
+							PVRSRVReleaseHandleUnlocked(psConnection->psHandleBase,
+											hSyncHandle,
+											PVRSRV_HANDLE_TYPE_SYNC_PRIMITIVE_BLOCK);
+						}
+				}
+	/* Release now we have cleaned up look up handles. */
+	UnlockHandle();
+
+
 	return 0;
 }
 
+#else
+#define PVRSRVBridgeSyncPrimPDump NULL
+#endif
+
+#if defined(PDUMP)
 static IMG_INT
 PVRSRVBridgeSyncPrimPDumpValue(IMG_UINT32 ui32DispatchTableEntry,
 					  PVRSRV_BRIDGE_IN_SYNCPRIMPDUMPVALUE *psSyncPrimPDumpValueIN,
 					  PVRSRV_BRIDGE_OUT_SYNCPRIMPDUMPVALUE *psSyncPrimPDumpValueOUT,
 					 CONNECTION_DATA *psConnection)
 {
+	IMG_HANDLE hSyncHandle = psSyncPrimPDumpValueIN->hSyncHandle;
 	SYNC_PRIMITIVE_BLOCK * psSyncHandleInt = NULL;
 
 
 
 
 
-	PMRLock();
+
+
+	/* Lock over handle lookup. */
+	LockHandle();
+
+
+
 
 
 				{
 					/* Look up the address from the handle */
 					psSyncPrimPDumpValueOUT->eError =
-						PVRSRVLookupHandle(psConnection->psHandleBase,
+						PVRSRVLookupHandleUnlocked(psConnection->psHandleBase,
 											(void **) &psSyncHandleInt,
-											psSyncPrimPDumpValueIN->hSyncHandle,
-											PVRSRV_HANDLE_TYPE_SYNC_PRIMITIVE_BLOCK);
+											hSyncHandle,
+											PVRSRV_HANDLE_TYPE_SYNC_PRIMITIVE_BLOCK,
+											IMG_TRUE);
 					if(psSyncPrimPDumpValueOUT->eError != PVRSRV_OK)
 					{
-						PMRUnlock();
+						UnlockHandle();
 						goto SyncPrimPDumpValue_exit;
 					}
 				}
-
+	/* Release now we have looked up handles. */
+	UnlockHandle();
 
 	psSyncPrimPDumpValueOUT->eError =
 		PVRSRVSyncPrimPDumpValueKM(
 					psSyncHandleInt,
 					psSyncPrimPDumpValueIN->ui32Offset,
 					psSyncPrimPDumpValueIN->ui32Value);
-	PMRUnlock();
 
 
 
 
 SyncPrimPDumpValue_exit:
 
+	/* Lock over handle lookup cleanup. */
+	LockHandle();
+
+
+
+
+
+
+				{
+					/* Unreference the previously looked up handle */
+						if(psSyncHandleInt)
+						{
+							PVRSRVReleaseHandleUnlocked(psConnection->psHandleBase,
+											hSyncHandle,
+											PVRSRV_HANDLE_TYPE_SYNC_PRIMITIVE_BLOCK);
+						}
+				}
+	/* Release now we have cleaned up look up handles. */
+	UnlockHandle();
+
+
 	return 0;
 }
 
+#else
+#define PVRSRVBridgeSyncPrimPDumpValue NULL
+#endif
+
+#if defined(PDUMP)
 static IMG_INT
 PVRSRVBridgeSyncPrimPDumpPol(IMG_UINT32 ui32DispatchTableEntry,
 					  PVRSRV_BRIDGE_IN_SYNCPRIMPDUMPPOL *psSyncPrimPDumpPolIN,
 					  PVRSRV_BRIDGE_OUT_SYNCPRIMPDUMPPOL *psSyncPrimPDumpPolOUT,
 					 CONNECTION_DATA *psConnection)
 {
+	IMG_HANDLE hSyncHandle = psSyncPrimPDumpPolIN->hSyncHandle;
 	SYNC_PRIMITIVE_BLOCK * psSyncHandleInt = NULL;
 
 
@@ -1316,19 +1757,29 @@
 
 
 
+	/* Lock over handle lookup. */
+	LockHandle();
+
+
+
+
+
 				{
 					/* Look up the address from the handle */
 					psSyncPrimPDumpPolOUT->eError =
-						PVRSRVLookupHandle(psConnection->psHandleBase,
+						PVRSRVLookupHandleUnlocked(psConnection->psHandleBase,
 											(void **) &psSyncHandleInt,
-											psSyncPrimPDumpPolIN->hSyncHandle,
-											PVRSRV_HANDLE_TYPE_SYNC_PRIMITIVE_BLOCK);
+											hSyncHandle,
+											PVRSRV_HANDLE_TYPE_SYNC_PRIMITIVE_BLOCK,
+											IMG_TRUE);
 					if(psSyncPrimPDumpPolOUT->eError != PVRSRV_OK)
 					{
+						UnlockHandle();
 						goto SyncPrimPDumpPol_exit;
 					}
 				}
-
+	/* Release now we have looked up handles. */
+	UnlockHandle();
 
 	psSyncPrimPDumpPolOUT->eError =
 		PVRSRVSyncPrimPDumpPolKM(
@@ -1344,15 +1795,42 @@
 
 SyncPrimPDumpPol_exit:
 
+	/* Lock over handle lookup cleanup. */
+	LockHandle();
+
+
+
+
+
+
+				{
+					/* Unreference the previously looked up handle */
+						if(psSyncHandleInt)
+						{
+							PVRSRVReleaseHandleUnlocked(psConnection->psHandleBase,
+											hSyncHandle,
+											PVRSRV_HANDLE_TYPE_SYNC_PRIMITIVE_BLOCK);
+						}
+				}
+	/* Release now we have cleaned up look up handles. */
+	UnlockHandle();
+
+
 	return 0;
 }
 
+#else
+#define PVRSRVBridgeSyncPrimPDumpPol NULL
+#endif
+
+#if defined(PDUMP)
 static IMG_INT
 PVRSRVBridgeSyncPrimOpPDumpPol(IMG_UINT32 ui32DispatchTableEntry,
 					  PVRSRV_BRIDGE_IN_SYNCPRIMOPPDUMPPOL *psSyncPrimOpPDumpPolIN,
 					  PVRSRV_BRIDGE_OUT_SYNCPRIMOPPDUMPPOL *psSyncPrimOpPDumpPolOUT,
 					 CONNECTION_DATA *psConnection)
 {
+	IMG_HANDLE hServerCookie = psSyncPrimOpPDumpPolIN->hServerCookie;
 	SERVER_OP_COOKIE * psServerCookieInt = NULL;
 
 
@@ -1361,19 +1839,29 @@
 
 
 
+	/* Lock over handle lookup. */
+	LockHandle();
+
+
+
+
+
 				{
 					/* Look up the address from the handle */
 					psSyncPrimOpPDumpPolOUT->eError =
-						PVRSRVLookupHandle(psConnection->psHandleBase,
+						PVRSRVLookupHandleUnlocked(psConnection->psHandleBase,
 											(void **) &psServerCookieInt,
-											psSyncPrimOpPDumpPolIN->hServerCookie,
-											PVRSRV_HANDLE_TYPE_SERVER_OP_COOKIE);
+											hServerCookie,
+											PVRSRV_HANDLE_TYPE_SERVER_OP_COOKIE,
+											IMG_TRUE);
 					if(psSyncPrimOpPDumpPolOUT->eError != PVRSRV_OK)
 					{
+						UnlockHandle();
 						goto SyncPrimOpPDumpPol_exit;
 					}
 				}
-
+	/* Release now we have looked up handles. */
+	UnlockHandle();
 
 	psSyncPrimOpPDumpPolOUT->eError =
 		PVRSRVSyncPrimOpPDumpPolKM(
@@ -1386,15 +1874,42 @@
 
 SyncPrimOpPDumpPol_exit:
 
+	/* Lock over handle lookup cleanup. */
+	LockHandle();
+
+
+
+
+
+
+				{
+					/* Unreference the previously looked up handle */
+						if(psServerCookieInt)
+						{
+							PVRSRVReleaseHandleUnlocked(psConnection->psHandleBase,
+											hServerCookie,
+											PVRSRV_HANDLE_TYPE_SERVER_OP_COOKIE);
+						}
+				}
+	/* Release now we have cleaned up look up handles. */
+	UnlockHandle();
+
+
 	return 0;
 }
 
+#else
+#define PVRSRVBridgeSyncPrimOpPDumpPol NULL
+#endif
+
+#if defined(PDUMP)
 static IMG_INT
 PVRSRVBridgeSyncPrimPDumpCBP(IMG_UINT32 ui32DispatchTableEntry,
 					  PVRSRV_BRIDGE_IN_SYNCPRIMPDUMPCBP *psSyncPrimPDumpCBPIN,
 					  PVRSRV_BRIDGE_OUT_SYNCPRIMPDUMPCBP *psSyncPrimPDumpCBPOUT,
 					 CONNECTION_DATA *psConnection)
 {
+	IMG_HANDLE hSyncHandle = psSyncPrimPDumpCBPIN->hSyncHandle;
 	SYNC_PRIMITIVE_BLOCK * psSyncHandleInt = NULL;
 
 
@@ -1403,19 +1918,29 @@
 
 
 
+	/* Lock over handle lookup. */
+	LockHandle();
+
+
+
+
+
 				{
 					/* Look up the address from the handle */
 					psSyncPrimPDumpCBPOUT->eError =
-						PVRSRVLookupHandle(psConnection->psHandleBase,
+						PVRSRVLookupHandleUnlocked(psConnection->psHandleBase,
 											(void **) &psSyncHandleInt,
-											psSyncPrimPDumpCBPIN->hSyncHandle,
-											PVRSRV_HANDLE_TYPE_SYNC_PRIMITIVE_BLOCK);
+											hSyncHandle,
+											PVRSRV_HANDLE_TYPE_SYNC_PRIMITIVE_BLOCK,
+											IMG_TRUE);
 					if(psSyncPrimPDumpCBPOUT->eError != PVRSRV_OK)
 					{
+						UnlockHandle();
 						goto SyncPrimPDumpCBP_exit;
 					}
 				}
-
+	/* Release now we have looked up handles. */
+	UnlockHandle();
 
 	psSyncPrimPDumpCBPOUT->eError =
 		PVRSRVSyncPrimPDumpCBPKM(
@@ -1430,9 +1955,161 @@
 
 SyncPrimPDumpCBP_exit:
 
+	/* Lock over handle lookup cleanup. */
+	LockHandle();
+
+
+
+
+
+
+				{
+					/* Unreference the previously looked up handle */
+						if(psSyncHandleInt)
+						{
+							PVRSRVReleaseHandleUnlocked(psConnection->psHandleBase,
+											hSyncHandle,
+											PVRSRV_HANDLE_TYPE_SYNC_PRIMITIVE_BLOCK);
+						}
+				}
+	/* Release now we have cleaned up look up handles. */
+	UnlockHandle();
+
+
 	return 0;
 }
 
+#else
+#define PVRSRVBridgeSyncPrimPDumpCBP NULL
+#endif
+
+static IMG_INT
+PVRSRVBridgeSyncAllocEvent(IMG_UINT32 ui32DispatchTableEntry,
+					  PVRSRV_BRIDGE_IN_SYNCALLOCEVENT *psSyncAllocEventIN,
+					  PVRSRV_BRIDGE_OUT_SYNCALLOCEVENT *psSyncAllocEventOUT,
+					 CONNECTION_DATA *psConnection)
+{
+	IMG_CHAR *uiClassNameInt = NULL;
+
+	IMG_UINT32 ui32NextOffset = 0;
+	IMG_BYTE   *pArrayArgsBuffer = NULL;
+#if !defined(INTEGRITY_OS)
+	IMG_BOOL bHaveEnoughSpace = IMG_FALSE;
+#endif
+
+	IMG_UINT32 ui32BufferSize = 
+			(psSyncAllocEventIN->ui32ClassNameSize * sizeof(IMG_CHAR)) +
+			0;
+
+
+	PVR_UNREFERENCED_PARAMETER(psConnection);
+
+
+
+	if (ui32BufferSize != 0)
+	{
+#if !defined(INTEGRITY_OS)
+		/* Try to use remainder of input buffer for copies if possible, word-aligned for safety. */
+		IMG_UINT32 ui32InBufferOffset = PVR_ALIGN(sizeof(*psSyncAllocEventIN), sizeof(unsigned long));
+		IMG_UINT32 ui32InBufferExcessSize = ui32InBufferOffset >= PVRSRV_MAX_BRIDGE_IN_SIZE ? 0 :
+			PVRSRV_MAX_BRIDGE_IN_SIZE - ui32InBufferOffset;
+
+		bHaveEnoughSpace = ui32BufferSize <= ui32InBufferExcessSize;
+		if (bHaveEnoughSpace)
+		{
+			IMG_BYTE *pInputBuffer = (IMG_BYTE *)psSyncAllocEventIN;
+
+			pArrayArgsBuffer = &pInputBuffer[ui32InBufferOffset];		}
+		else
+#endif
+		{
+			pArrayArgsBuffer = OSAllocMemNoStats(ui32BufferSize);
+
+			if(!pArrayArgsBuffer)
+			{
+				psSyncAllocEventOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
+				goto SyncAllocEvent_exit;
+			}
+		}
+	}
+
+	if (psSyncAllocEventIN->ui32ClassNameSize != 0)
+	{
+		uiClassNameInt = (IMG_CHAR*)(((IMG_UINT8 *)pArrayArgsBuffer) + ui32NextOffset);
+		ui32NextOffset += psSyncAllocEventIN->ui32ClassNameSize * sizeof(IMG_CHAR);
+	}
+
+			/* Copy the data over */
+			if (psSyncAllocEventIN->ui32ClassNameSize * sizeof(IMG_CHAR) > 0)
+			{
+				if ( OSCopyFromUser(NULL, uiClassNameInt, psSyncAllocEventIN->puiClassName, psSyncAllocEventIN->ui32ClassNameSize * sizeof(IMG_CHAR)) != PVRSRV_OK )
+				{
+					psSyncAllocEventOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
+
+					goto SyncAllocEvent_exit;
+				}
+			}
+
+
+	psSyncAllocEventOUT->eError =
+		PVRSRVSyncAllocEventKM(
+					psSyncAllocEventIN->bServerSync,
+					psSyncAllocEventIN->ui32FWAddr,
+					psSyncAllocEventIN->ui32ClassNameSize,
+					uiClassNameInt);
+
+
+
+
+SyncAllocEvent_exit:
+
+
+
+	/* Allocated space should be equal to the last updated offset */
+	PVR_ASSERT(ui32BufferSize == ui32NextOffset);
+
+#if defined(INTEGRITY_OS)
+	if(pArrayArgsBuffer)
+#else
+	if(!bHaveEnoughSpace && pArrayArgsBuffer)
+#endif
+		OSFreeMemNoStats(pArrayArgsBuffer);
+
+
+	return 0;
+}
+
+
+static IMG_INT
+PVRSRVBridgeSyncFreeEvent(IMG_UINT32 ui32DispatchTableEntry,
+					  PVRSRV_BRIDGE_IN_SYNCFREEEVENT *psSyncFreeEventIN,
+					  PVRSRV_BRIDGE_OUT_SYNCFREEEVENT *psSyncFreeEventOUT,
+					 CONNECTION_DATA *psConnection)
+{
+
+
+
+	PVR_UNREFERENCED_PARAMETER(psConnection);
+
+
+
+
+
+	psSyncFreeEventOUT->eError =
+		PVRSRVSyncFreeEventKM(
+					psSyncFreeEventIN->ui32FWAddr);
+
+
+
+
+
+
+
+
+	return 0;
+}
+
+
 
 
 /* *************************************************************************** 
@@ -1462,12 +2139,6 @@
 	SetDispatchTableEntry(PVRSRV_BRIDGE_SYNC, PVRSRV_BRIDGE_SYNC_SERVERSYNCPRIMSET, PVRSRVBridgeServerSyncPrimSet,
 					NULL, bUseLock);
 
-	SetDispatchTableEntry(PVRSRV_BRIDGE_SYNC, PVRSRV_BRIDGE_SYNC_SYNCRECORDREMOVEBYHANDLE, PVRSRVBridgeSyncRecordRemoveByHandle,
-					NULL, bUseLock);
-
-	SetDispatchTableEntry(PVRSRV_BRIDGE_SYNC, PVRSRV_BRIDGE_SYNC_SYNCRECORDADD, PVRSRVBridgeSyncRecordAdd,
-					NULL, bUseLock);
-
 	SetDispatchTableEntry(PVRSRV_BRIDGE_SYNC, PVRSRV_BRIDGE_SYNC_SERVERSYNCALLOC, PVRSRVBridgeServerSyncAlloc,
 					NULL, bUseLock);
 
@@ -1510,6 +2181,12 @@
 	SetDispatchTableEntry(PVRSRV_BRIDGE_SYNC, PVRSRV_BRIDGE_SYNC_SYNCPRIMPDUMPCBP, PVRSRVBridgeSyncPrimPDumpCBP,
 					NULL, bUseLock);
 
+	SetDispatchTableEntry(PVRSRV_BRIDGE_SYNC, PVRSRV_BRIDGE_SYNC_SYNCALLOCEVENT, PVRSRVBridgeSyncAllocEvent,
+					NULL, bUseLock);
+
+	SetDispatchTableEntry(PVRSRV_BRIDGE_SYNC, PVRSRV_BRIDGE_SYNC_SYNCFREEEVENT, PVRSRVBridgeSyncFreeEvent,
+					NULL, bUseLock);
+
 
 	return PVRSRV_OK;
 }
@@ -1521,4 +2198,3 @@
 {
 	return PVRSRV_OK;
 }
-
diff --git a/drivers/staging/imgtec/rogue/generated/cachegeneric_bridge/client_cachegeneric_bridge.h b/drivers/staging/imgtec/rogue/generated/synctracking_bridge/client_synctracking_bridge.h
similarity index 75%
copy from drivers/staging/imgtec/rogue/generated/cachegeneric_bridge/client_cachegeneric_bridge.h
copy to drivers/staging/imgtec/rogue/generated/synctracking_bridge/client_synctracking_bridge.h
index 839a17a..ce11130 100644
--- a/drivers/staging/imgtec/rogue/generated/cachegeneric_bridge/client_cachegeneric_bridge.h
+++ b/drivers/staging/imgtec/rogue/generated/synctracking_bridge/client_synctracking_bridge.h
@@ -1,8 +1,8 @@
 /*************************************************************************/ /*!
 @File
-@Title          Client bridge header for cachegeneric
+@Title          Client bridge header for synctracking
 @Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
-@Description    Exports the client bridge functions for cachegeneric
+@Description    Exports the client bridge functions for synctracking
 @License        Dual MIT/GPLv2
 
 The contents of this file are subject to the MIT license as set out below.
@@ -41,8 +41,8 @@
 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */ /**************************************************************************/
 
-#ifndef CLIENT_CACHEGENERIC_BRIDGE_H
-#define CLIENT_CACHEGENERIC_BRIDGE_H
+#ifndef CLIENT_SYNCTRACKING_BRIDGE_H
+#define CLIENT_SYNCTRACKING_BRIDGE_H
 
 #include "img_defs.h"
 #include "pvrsrv_error.h"
@@ -52,13 +52,19 @@
 #include "pvr_bridge.h"
 #endif
 
-#include "common_cachegeneric_bridge.h"
+#include "common_synctracking_bridge.h"
 
-IMG_INTERNAL PVRSRV_ERROR IMG_CALLCONV BridgeCacheOpQueue(IMG_HANDLE hBridge,
-							  IMG_HANDLE hPMR,
-							  IMG_DEVMEM_OFFSET_T uiOffset,
-							  IMG_DEVMEM_SIZE_T uiSize,
-							  PVRSRV_CACHE_OP iuCacheOp);
+IMG_INTERNAL PVRSRV_ERROR IMG_CALLCONV BridgeSyncRecordRemoveByHandle(IMG_HANDLE hBridge,
+								      IMG_HANDLE hhRecord);
+
+IMG_INTERNAL PVRSRV_ERROR IMG_CALLCONV BridgeSyncRecordAdd(IMG_HANDLE hBridge,
+							   IMG_HANDLE *phhRecord,
+							   IMG_HANDLE hhServerSyncPrimBlock,
+							   IMG_UINT32 ui32ui32FwBlockAddr,
+							   IMG_UINT32 ui32ui32SyncOffset,
+							   IMG_BOOL bbServerSync,
+							   IMG_UINT32 ui32ClassNameSize,
+							   const IMG_CHAR *puiClassName);
 
 
-#endif /* CLIENT_CACHEGENERIC_BRIDGE_H */
+#endif /* CLIENT_SYNCTRACKING_BRIDGE_H */
diff --git a/drivers/staging/imgtec/rogue/generated/cachegeneric_bridge/client_cachegeneric_direct_bridge.c b/drivers/staging/imgtec/rogue/generated/synctracking_bridge/client_synctracking_direct_bridge.c
similarity index 65%
copy from drivers/staging/imgtec/rogue/generated/cachegeneric_bridge/client_cachegeneric_direct_bridge.c
copy to drivers/staging/imgtec/rogue/generated/synctracking_bridge/client_synctracking_direct_bridge.c
index d0cdf5a..3568038 100644
--- a/drivers/staging/imgtec/rogue/generated/cachegeneric_bridge/client_cachegeneric_direct_bridge.c
+++ b/drivers/staging/imgtec/rogue/generated/synctracking_bridge/client_synctracking_direct_bridge.c
@@ -1,5 +1,5 @@
 /*************************************************************************/ /*!
-@Title          Direct client bridge for cachegeneric
+@Title          Direct client bridge for synctracking
 @Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
 @License        Dual MIT/GPLv2
 
@@ -39,35 +39,59 @@
 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */ /**************************************************************************/
 
-#include "client_cachegeneric_bridge.h"
+#include "client_synctracking_bridge.h"
 #include "img_defs.h"
 #include "pvr_debug.h"
 
 /* Module specific includes */
-#include "cache_external.h"
 
-#include "cache_generic.h"
+#include "sync.h"
+#include "sync_server.h"
 
 
-IMG_INTERNAL PVRSRV_ERROR IMG_CALLCONV BridgeCacheOpQueue(IMG_HANDLE hBridge,
-							  IMG_HANDLE hPMR,
-							  IMG_DEVMEM_OFFSET_T uiOffset,
-							  IMG_DEVMEM_SIZE_T uiSize,
-							  PVRSRV_CACHE_OP iuCacheOp)
+IMG_INTERNAL PVRSRV_ERROR IMG_CALLCONV BridgeSyncRecordRemoveByHandle(IMG_HANDLE hBridge,
+								      IMG_HANDLE hhRecord)
 {
 	PVRSRV_ERROR eError;
-	PMR * psPMRInt;
+	SYNC_RECORD_HANDLE pshRecordInt;
 	PVR_UNREFERENCED_PARAMETER(hBridge);
 
-	psPMRInt = (PMR *) hPMR;
+	pshRecordInt = (SYNC_RECORD_HANDLE) hhRecord;
 
 	eError =
-		CacheOpQueue(
-					psPMRInt,
-					uiOffset,
-					uiSize,
-					iuCacheOp);
+		PVRSRVSyncRecordRemoveByHandleKM(
+					pshRecordInt);
 
 	return eError;
 }
 
+IMG_INTERNAL PVRSRV_ERROR IMG_CALLCONV BridgeSyncRecordAdd(IMG_HANDLE hBridge,
+							   IMG_HANDLE *phhRecord,
+							   IMG_HANDLE hhServerSyncPrimBlock,
+							   IMG_UINT32 ui32ui32FwBlockAddr,
+							   IMG_UINT32 ui32ui32SyncOffset,
+							   IMG_BOOL bbServerSync,
+							   IMG_UINT32 ui32ClassNameSize,
+							   const IMG_CHAR *puiClassName)
+{
+	PVRSRV_ERROR eError;
+	SYNC_RECORD_HANDLE pshRecordInt;
+	SYNC_PRIMITIVE_BLOCK * pshServerSyncPrimBlockInt;
+
+	pshServerSyncPrimBlockInt = (SYNC_PRIMITIVE_BLOCK *) hhServerSyncPrimBlock;
+
+	eError =
+		PVRSRVSyncRecordAddKM(NULL, (PVRSRV_DEVICE_NODE *)((void*) hBridge)
+		,
+					&pshRecordInt,
+					pshServerSyncPrimBlockInt,
+					ui32ui32FwBlockAddr,
+					ui32ui32SyncOffset,
+					bbServerSync,
+					ui32ClassNameSize,
+					puiClassName);
+
+	*phhRecord = pshRecordInt;
+	return eError;
+}
+
diff --git a/drivers/staging/imgtec/rogue/generated/synctracking_bridge/common_synctracking_bridge.h b/drivers/staging/imgtec/rogue/generated/synctracking_bridge/common_synctracking_bridge.h
new file mode 100644
index 0000000..edc856f
--- /dev/null
+++ b/drivers/staging/imgtec/rogue/generated/synctracking_bridge/common_synctracking_bridge.h
@@ -0,0 +1,101 @@
+/*************************************************************************/ /*!
+@File
+@Title          Common bridge header for synctracking
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description    Declares common defines and structures used by both the client
+                and server side of the bridge for synctracking
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#ifndef COMMON_SYNCTRACKING_BRIDGE_H
+#define COMMON_SYNCTRACKING_BRIDGE_H
+
+#include <powervr/mem_types.h>
+
+#include "img_types.h"
+#include "pvrsrv_error.h"
+
+
+
+#define PVRSRV_BRIDGE_SYNCTRACKING_CMD_FIRST			0
+#define PVRSRV_BRIDGE_SYNCTRACKING_SYNCRECORDREMOVEBYHANDLE			PVRSRV_BRIDGE_SYNCTRACKING_CMD_FIRST+0
+#define PVRSRV_BRIDGE_SYNCTRACKING_SYNCRECORDADD			PVRSRV_BRIDGE_SYNCTRACKING_CMD_FIRST+1
+#define PVRSRV_BRIDGE_SYNCTRACKING_CMD_LAST			(PVRSRV_BRIDGE_SYNCTRACKING_CMD_FIRST+1)
+
+
+/*******************************************
+            SyncRecordRemoveByHandle          
+ *******************************************/
+
+/* Bridge in structure for SyncRecordRemoveByHandle */
+typedef struct PVRSRV_BRIDGE_IN_SYNCRECORDREMOVEBYHANDLE_TAG
+{
+	IMG_HANDLE hhRecord;
+} __attribute__((packed)) PVRSRV_BRIDGE_IN_SYNCRECORDREMOVEBYHANDLE;
+
+/* Bridge out structure for SyncRecordRemoveByHandle */
+typedef struct PVRSRV_BRIDGE_OUT_SYNCRECORDREMOVEBYHANDLE_TAG
+{
+	PVRSRV_ERROR eError;
+} __attribute__((packed)) PVRSRV_BRIDGE_OUT_SYNCRECORDREMOVEBYHANDLE;
+
+
+/*******************************************
+            SyncRecordAdd          
+ *******************************************/
+
+/* Bridge in structure for SyncRecordAdd */
+typedef struct PVRSRV_BRIDGE_IN_SYNCRECORDADD_TAG
+{
+	IMG_HANDLE hhServerSyncPrimBlock;
+	IMG_UINT32 ui32ui32FwBlockAddr;
+	IMG_UINT32 ui32ui32SyncOffset;
+	IMG_BOOL bbServerSync;
+	IMG_UINT32 ui32ClassNameSize;
+	const IMG_CHAR * puiClassName;
+} __attribute__((packed)) PVRSRV_BRIDGE_IN_SYNCRECORDADD;
+
+/* Bridge out structure for SyncRecordAdd */
+typedef struct PVRSRV_BRIDGE_OUT_SYNCRECORDADD_TAG
+{
+	IMG_HANDLE hhRecord;
+	PVRSRV_ERROR eError;
+} __attribute__((packed)) PVRSRV_BRIDGE_OUT_SYNCRECORDADD;
+
+
+#endif /* COMMON_SYNCTRACKING_BRIDGE_H */
diff --git a/drivers/staging/imgtec/rogue/generated/synctracking_bridge/server_synctracking_bridge.c b/drivers/staging/imgtec/rogue/generated/synctracking_bridge/server_synctracking_bridge.c
new file mode 100644
index 0000000..9c9508d
--- /dev/null
+++ b/drivers/staging/imgtec/rogue/generated/synctracking_bridge/server_synctracking_bridge.c
@@ -0,0 +1,336 @@
+/*************************************************************************/ /*!
+@File
+@Title          Server bridge for synctracking
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description    Implements the server side of the bridge for synctracking
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#include <stddef.h>
+#include <asm/uaccess.h>
+
+#include "img_defs.h"
+
+#include "sync.h"
+#include "sync_server.h"
+
+
+#include "common_synctracking_bridge.h"
+
+#include "allocmem.h"
+#include "pvr_debug.h"
+#include "connection_server.h"
+#include "pvr_bridge.h"
+#include "rgx_bridge.h"
+#include "srvcore.h"
+#include "handle.h"
+
+#include <linux/slab.h>
+
+
+
+
+
+
+/* ***************************************************************************
+ * Server-side bridge entry points
+ */
+ 
+static IMG_INT
+PVRSRVBridgeSyncRecordRemoveByHandle(IMG_UINT32 ui32DispatchTableEntry,
+					  PVRSRV_BRIDGE_IN_SYNCRECORDREMOVEBYHANDLE *psSyncRecordRemoveByHandleIN,
+					  PVRSRV_BRIDGE_OUT_SYNCRECORDREMOVEBYHANDLE *psSyncRecordRemoveByHandleOUT,
+					 CONNECTION_DATA *psConnection)
+{
+
+
+
+
+
+
+
+
+
+	/* Lock over handle destruction. */
+	LockHandle();
+
+
+
+
+
+	psSyncRecordRemoveByHandleOUT->eError =
+		PVRSRVReleaseHandleUnlocked(psConnection->psHandleBase,
+					(IMG_HANDLE) psSyncRecordRemoveByHandleIN->hhRecord,
+					PVRSRV_HANDLE_TYPE_SYNC_RECORD_HANDLE);
+	if ((psSyncRecordRemoveByHandleOUT->eError != PVRSRV_OK) &&
+	    (psSyncRecordRemoveByHandleOUT->eError != PVRSRV_ERROR_RETRY))
+	{
+		PVR_DPF((PVR_DBG_ERROR,
+		        "PVRSRVBridgeSyncRecordRemoveByHandle: %s",
+		        PVRSRVGetErrorStringKM(psSyncRecordRemoveByHandleOUT->eError)));
+		PVR_ASSERT(0);
+		UnlockHandle();
+		goto SyncRecordRemoveByHandle_exit;
+	}
+
+	/* Release now we have destroyed handles. */
+	UnlockHandle();
+
+
+
+SyncRecordRemoveByHandle_exit:
+
+
+
+
+	return 0;
+}
+
+
+static IMG_INT
+PVRSRVBridgeSyncRecordAdd(IMG_UINT32 ui32DispatchTableEntry,
+					  PVRSRV_BRIDGE_IN_SYNCRECORDADD *psSyncRecordAddIN,
+					  PVRSRV_BRIDGE_OUT_SYNCRECORDADD *psSyncRecordAddOUT,
+					 CONNECTION_DATA *psConnection)
+{
+	SYNC_RECORD_HANDLE pshRecordInt = NULL;
+	IMG_HANDLE hhServerSyncPrimBlock = psSyncRecordAddIN->hhServerSyncPrimBlock;
+	SYNC_PRIMITIVE_BLOCK * pshServerSyncPrimBlockInt = NULL;
+	IMG_CHAR *uiClassNameInt = NULL;
+
+	IMG_UINT32 ui32NextOffset = 0;
+	IMG_BYTE   *pArrayArgsBuffer = NULL;
+#if !defined(INTEGRITY_OS)
+	IMG_BOOL bHaveEnoughSpace = IMG_FALSE;
+#endif
+
+	IMG_UINT32 ui32BufferSize = 
+			(psSyncRecordAddIN->ui32ClassNameSize * sizeof(IMG_CHAR)) +
+			0;
+
+
+
+
+
+	if (ui32BufferSize != 0)
+	{
+#if !defined(INTEGRITY_OS)
+		/* Try to use remainder of input buffer for copies if possible, word-aligned for safety. */
+		IMG_UINT32 ui32InBufferOffset = PVR_ALIGN(sizeof(*psSyncRecordAddIN), sizeof(unsigned long));
+		IMG_UINT32 ui32InBufferExcessSize = ui32InBufferOffset >= PVRSRV_MAX_BRIDGE_IN_SIZE ? 0 :
+			PVRSRV_MAX_BRIDGE_IN_SIZE - ui32InBufferOffset;
+
+		bHaveEnoughSpace = ui32BufferSize <= ui32InBufferExcessSize;
+		if (bHaveEnoughSpace)
+		{
+			IMG_BYTE *pInputBuffer = (IMG_BYTE *)psSyncRecordAddIN;
+
+			pArrayArgsBuffer = &pInputBuffer[ui32InBufferOffset];		}
+		else
+#endif
+		{
+			pArrayArgsBuffer = OSAllocMemNoStats(ui32BufferSize);
+
+			if(!pArrayArgsBuffer)
+			{
+				psSyncRecordAddOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
+				goto SyncRecordAdd_exit;
+			}
+		}
+	}
+
+	if (psSyncRecordAddIN->ui32ClassNameSize != 0)
+	{
+		uiClassNameInt = (IMG_CHAR*)(((IMG_UINT8 *)pArrayArgsBuffer) + ui32NextOffset);
+		ui32NextOffset += psSyncRecordAddIN->ui32ClassNameSize * sizeof(IMG_CHAR);
+	}
+
+			/* Copy the data over */
+			if (psSyncRecordAddIN->ui32ClassNameSize * sizeof(IMG_CHAR) > 0)
+			{
+				if ( OSCopyFromUser(NULL, uiClassNameInt, psSyncRecordAddIN->puiClassName, psSyncRecordAddIN->ui32ClassNameSize * sizeof(IMG_CHAR)) != PVRSRV_OK )
+				{
+					psSyncRecordAddOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
+
+					goto SyncRecordAdd_exit;
+				}
+			}
+
+	/* Lock over handle lookup. */
+	LockHandle();
+
+
+
+
+
+				{
+					/* Look up the address from the handle */
+					psSyncRecordAddOUT->eError =
+						PVRSRVLookupHandleUnlocked(psConnection->psHandleBase,
+											(void **) &pshServerSyncPrimBlockInt,
+											hhServerSyncPrimBlock,
+											PVRSRV_HANDLE_TYPE_SYNC_PRIMITIVE_BLOCK,
+											IMG_TRUE);
+					if(psSyncRecordAddOUT->eError != PVRSRV_OK)
+					{
+						UnlockHandle();
+						goto SyncRecordAdd_exit;
+					}
+				}
+	/* Release now we have looked up handles. */
+	UnlockHandle();
+
+	psSyncRecordAddOUT->eError =
+		PVRSRVSyncRecordAddKM(psConnection, OSGetDevData(psConnection),
+					&pshRecordInt,
+					pshServerSyncPrimBlockInt,
+					psSyncRecordAddIN->ui32ui32FwBlockAddr,
+					psSyncRecordAddIN->ui32ui32SyncOffset,
+					psSyncRecordAddIN->bbServerSync,
+					psSyncRecordAddIN->ui32ClassNameSize,
+					uiClassNameInt);
+	/* Exit early if bridged call fails */
+	if(psSyncRecordAddOUT->eError != PVRSRV_OK)
+	{
+		goto SyncRecordAdd_exit;
+	}
+
+	/* Lock over handle creation. */
+	LockHandle();
+
+
+
+
+
+	psSyncRecordAddOUT->eError = PVRSRVAllocHandleUnlocked(psConnection->psHandleBase,
+
+							&psSyncRecordAddOUT->hhRecord,
+							(void *) pshRecordInt,
+							PVRSRV_HANDLE_TYPE_SYNC_RECORD_HANDLE,
+							PVRSRV_HANDLE_ALLOC_FLAG_NONE
+							,(PFN_HANDLE_RELEASE)&PVRSRVSyncRecordRemoveByHandleKM);
+	if (psSyncRecordAddOUT->eError != PVRSRV_OK)
+	{
+		UnlockHandle();
+		goto SyncRecordAdd_exit;
+	}
+
+	/* Release now we have created handles. */
+	UnlockHandle();
+
+
+
+SyncRecordAdd_exit:
+
+	/* Lock over handle lookup cleanup. */
+	LockHandle();
+
+
+
+
+
+
+				{
+					/* Unreference the previously looked up handle */
+						if(pshServerSyncPrimBlockInt)
+						{
+							PVRSRVReleaseHandleUnlocked(psConnection->psHandleBase,
+											hhServerSyncPrimBlock,
+											PVRSRV_HANDLE_TYPE_SYNC_PRIMITIVE_BLOCK);
+						}
+				}
+	/* Release now we have cleaned up look up handles. */
+	UnlockHandle();
+
+	if (psSyncRecordAddOUT->eError != PVRSRV_OK)
+	{
+		if (pshRecordInt)
+		{
+			PVRSRVSyncRecordRemoveByHandleKM(pshRecordInt);
+		}
+	}
+
+	/* Allocated space should be equal to the last updated offset */
+	PVR_ASSERT(ui32BufferSize == ui32NextOffset);
+
+#if defined(INTEGRITY_OS)
+	if(pArrayArgsBuffer)
+#else
+	if(!bHaveEnoughSpace && pArrayArgsBuffer)
+#endif
+		OSFreeMemNoStats(pArrayArgsBuffer);
+
+
+	return 0;
+}
+
+
+
+
+/* *************************************************************************** 
+ * Server bridge dispatch related glue 
+ */
+
+static IMG_BOOL bUseLock = IMG_TRUE;
+
+PVRSRV_ERROR InitSYNCTRACKINGBridge(void);
+PVRSRV_ERROR DeinitSYNCTRACKINGBridge(void);
+
+/*
+ * Register all SYNCTRACKING functions with services
+ */
+PVRSRV_ERROR InitSYNCTRACKINGBridge(void)
+{
+
+	SetDispatchTableEntry(PVRSRV_BRIDGE_SYNCTRACKING, PVRSRV_BRIDGE_SYNCTRACKING_SYNCRECORDREMOVEBYHANDLE, PVRSRVBridgeSyncRecordRemoveByHandle,
+					NULL, bUseLock);
+
+	SetDispatchTableEntry(PVRSRV_BRIDGE_SYNCTRACKING, PVRSRV_BRIDGE_SYNCTRACKING_SYNCRECORDADD, PVRSRVBridgeSyncRecordAdd,
+					NULL, bUseLock);
+
+
+	return PVRSRV_OK;
+}
+
+/*
+ * Unregister all synctracking functions with services
+ */
+PVRSRV_ERROR DeinitSYNCTRACKINGBridge(void)
+{
+	return PVRSRV_OK;
+}
diff --git a/drivers/staging/imgtec/rogue/generated/timerquery_bridge/common_timerquery_bridge.h b/drivers/staging/imgtec/rogue/generated/timerquery_bridge/common_timerquery_bridge.h
index a79d9ea1..ed544f2 100644
--- a/drivers/staging/imgtec/rogue/generated/timerquery_bridge/common_timerquery_bridge.h
+++ b/drivers/staging/imgtec/rogue/generated/timerquery_bridge/common_timerquery_bridge.h
@@ -2,8 +2,8 @@
 @File
 @Title          Common bridge header for timerquery
 @Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
-@Description    Declares common defines and structures that are used by both
-                the client and sever side of the bridge for timerquery
+@Description    Declares common defines and structures used by both the client
+                and server side of the bridge for timerquery
 @License        Dual MIT/GPLv2
 
 The contents of this file are subject to the MIT license as set out below.
@@ -45,6 +45,8 @@
 #ifndef COMMON_TIMERQUERY_BRIDGE_H
 #define COMMON_TIMERQUERY_BRIDGE_H
 
+#include <powervr/mem_types.h>
+
 #include "img_types.h"
 #include "pvrsrv_error.h"
 
diff --git a/drivers/staging/imgtec/rogue/generated/timerquery_bridge/server_timerquery_bridge.c b/drivers/staging/imgtec/rogue/generated/timerquery_bridge/server_timerquery_bridge.c
index 51e5de7..fbd7c10 100644
--- a/drivers/staging/imgtec/rogue/generated/timerquery_bridge/server_timerquery_bridge.c
+++ b/drivers/staging/imgtec/rogue/generated/timerquery_bridge/server_timerquery_bridge.c
@@ -64,6 +64,8 @@
 
 
 
+
+
 /* ***************************************************************************
  * Server-side bridge entry points
  */
@@ -81,6 +83,7 @@
 
 
 
+
 	psRGXBeginTimerQueryOUT->eError =
 		PVRSRVRGXBeginTimerQueryKM(psConnection, OSGetDevData(psConnection),
 					psRGXBeginTimerQueryIN->ui32QueryId);
@@ -89,9 +92,13 @@
 
 
 
+
+
+
 	return 0;
 }
 
+
 static IMG_INT
 PVRSRVBridgeRGXEndTimerQuery(IMG_UINT32 ui32DispatchTableEntry,
 					  PVRSRV_BRIDGE_IN_RGXENDTIMERQUERY *psRGXEndTimerQueryIN,
@@ -99,9 +106,10 @@
 					 CONNECTION_DATA *psConnection)
 {
 
-	PVR_UNREFERENCED_PARAMETER(psRGXEndTimerQueryIN);
 
 
+	PVR_UNREFERENCED_PARAMETER(psRGXEndTimerQueryIN);
+
 
 
 
@@ -114,9 +122,13 @@
 
 
 
+
+
+
 	return 0;
 }
 
+
 static IMG_INT
 PVRSRVBridgeRGXQueryTimer(IMG_UINT32 ui32DispatchTableEntry,
 					  PVRSRV_BRIDGE_IN_RGXQUERYTIMER *psRGXQueryTimerIN,
@@ -130,6 +142,7 @@
 
 
 
+
 	psRGXQueryTimerOUT->eError =
 		PVRSRVRGXQueryTimerKM(psConnection, OSGetDevData(psConnection),
 					psRGXQueryTimerIN->ui32QueryId,
@@ -140,9 +153,13 @@
 
 
 
+
+
+
 	return 0;
 }
 
+
 static IMG_INT
 PVRSRVBridgeRGXCurrentTime(IMG_UINT32 ui32DispatchTableEntry,
 					  PVRSRV_BRIDGE_IN_RGXCURRENTTIME *psRGXCurrentTimeIN,
@@ -150,9 +167,10 @@
 					 CONNECTION_DATA *psConnection)
 {
 
-	PVR_UNREFERENCED_PARAMETER(psRGXCurrentTimeIN);
 
 
+	PVR_UNREFERENCED_PARAMETER(psRGXCurrentTimeIN);
+
 
 
 
@@ -165,11 +183,15 @@
 
 
 
+
+
+
 	return 0;
 }
 
 
 
+
 /* *************************************************************************** 
  * Server bridge dispatch related glue 
  */
@@ -208,4 +230,3 @@
 {
 	return PVRSRV_OK;
 }
-
diff --git a/drivers/staging/imgtec/rogue/handle.c b/drivers/staging/imgtec/rogue/handle.c
index be0d688..d0f8aae 100644
--- a/drivers/staging/imgtec/rogue/handle.c
+++ b/drivers/staging/imgtec/rogue/handle.c
@@ -108,8 +108,10 @@
 	/* List entry for sibling subhandles */
 	HANDLE_LIST sSiblings;
 
-	/* Reference count, always 1 unless handle is shared */
-	IMG_UINT32 ui32Refs;
+	/* Reference count. The pfnReleaseData callback gets called when the
+	 * reference count hits zero
+	 */
+	IMG_UINT32 ui32RefCount;
 } HANDLE_DATA;
 
 struct _HANDLE_BASE_
@@ -123,6 +125,9 @@
 	 * pointers to handles.
 	 */
 	HASH_TABLE *psHashTab;
+
+	/* Can be connection, process, global */
+	PVRSRV_HANDLE_BASE_TYPE eType;
 };
 
 /*
@@ -168,6 +173,42 @@
  */
 PVRSRV_HANDLE_BASE *gpsKernelHandleBase = NULL;
 
+/* Increase the reference count on the given handle.
+ * The handle lock must already be acquired.
+ * Returns: the reference count after the increment
+ */
+static inline IMG_UINT32 _HandleRef(HANDLE_DATA *psHandleData)
+{
+#if defined PVRSRV_DEBUG_HANDLE_LOCK
+	if(!OSLockIsLocked(gHandleLock))
+	{
+		PVR_DPF((PVR_DBG_ERROR, "%s: Handle lock is not locked", __func__));
+		OSDumpStack();
+	}
+#endif
+	psHandleData->ui32RefCount++;
+	return psHandleData->ui32RefCount;
+}
+
+/* Decrease the reference count on the given handle.
+ * The handle lock must already be acquired.
+ * Returns: the reference count after the decrement
+ */
+static inline IMG_UINT32 _HandleUnref(HANDLE_DATA *psHandleData)
+{
+#if defined PVRSRV_DEBUG_HANDLE_LOCK
+	if(!OSLockIsLocked(gHandleLock))
+	{
+		PVR_DPF((PVR_DBG_ERROR, "%s: Handle lock is not locked", __func__));
+		OSDumpStack();
+	}
+#endif
+	PVR_ASSERT(psHandleData->ui32RefCount > 0);
+	psHandleData->ui32RefCount--;
+
+	return psHandleData->ui32RefCount;
+}
+
 /*!
 ******************************************************************************
 
@@ -842,7 +883,13 @@
 		return eError;
 	}
 
-	PVR_ASSERT(psHandleData->ui32Refs > 0);
+	if(_HandleUnref(psHandleData) > 0)
+	{
+		/* this handle still has references so do not destroy it
+		 * or the underlying object yet
+		 */
+		return PVRSRV_OK;
+	}
 
 	/* Call the release data callback for each reference on the handle */
 	if (psHandleData->pfnReleaseData != NULL)
@@ -856,6 +903,9 @@
 				 hHandle,
 				 (IMG_UINT32)psHandleData->eType));
 
+			/* the caller should retry, so retain a reference on the handle */
+			_HandleRef(psHandleData);
+
 			return eError;
 		}
 		else if (eError != PVRSRV_OK)
@@ -864,14 +914,6 @@
 		}
 	}
 
-	psHandleData->ui32Refs--;
-	if (psHandleData->ui32Refs > 0)
-	{
-		/* Reference count still positive, only possible for shared handles */
-		PVR_ASSERT(TEST_ALLOC_FLAG(psHandleData, PVRSRV_HANDLE_ALLOC_FLAG_SHARED));
-		return PVRSRV_OK;
-	}
-
 	if (!TEST_ALLOC_FLAG(psHandleData, PVRSRV_HANDLE_ALLOC_FLAG_MULTI))
 	{
 		HAND_KEY aKey;
@@ -1042,7 +1084,7 @@
 	psNewHandleData->eFlag = eFlag;
 	psNewHandleData->pvData = pvData;
 	psNewHandleData->pfnReleaseData = pfnReleaseData;
-	psNewHandleData->ui32Refs = 1;
+	psNewHandleData->ui32RefCount = 1;
 
 	InitParentList(psNewHandleData);
 #if defined(DEBUG)
@@ -1093,7 +1135,41 @@
 			       PVRSRV_HANDLE_ALLOC_FLAG eFlag,
 			       PFN_HANDLE_RELEASE pfnReleaseData)
 {
-	IMG_HANDLE hHandle;
+	PVRSRV_ERROR eError;
+
+	LockHandle();
+	eError = PVRSRVAllocHandleUnlocked(psBase, phHandle, pvData, eType, eFlag, pfnReleaseData);
+	UnlockHandle();
+
+	return eError;
+}
+
+/*!
+******************************************************************************
+
+ @Function	PVRSRVAllocHandleUnlocked
+
+ @Description	Allocate a handle without acquiring/releasing the handle
+		lock. The function assumes you hold the lock when called.
+
+ @Input		phHandle - location for new handle
+		pvData - pointer to resource to be associated with the handle
+		eType - the type of resource
+		pfnReleaseData - Function to release resource at handle release
+		                 time
+
+ @Output	phHandle - points to new handle
+
+ @Return	Error code or PVRSRV_OK
+
+******************************************************************************/
+PVRSRV_ERROR PVRSRVAllocHandleUnlocked(PVRSRV_HANDLE_BASE *psBase,
+			       IMG_HANDLE *phHandle,
+			       void *pvData,
+			       PVRSRV_HANDLE_TYPE eType,
+			       PVRSRV_HANDLE_ALLOC_FLAG eFlag,
+			       PFN_HANDLE_RELEASE pfnReleaseData)
+{
 	PVRSRV_ERROR eError;
 
 	*phHandle = NULL;
@@ -1102,65 +1178,23 @@
 	PVR_ASSERT(eType != PVRSRV_HANDLE_TYPE_NONE);
 	PVR_ASSERT(gpsHandleFuncs);
 
-	LockHandle();
 	if (psBase == NULL)
 	{
 		PVR_DPF((PVR_DBG_ERROR, "PVRSRVAllocHandle: Missing handle base"));
 		eError = PVRSRV_ERROR_INVALID_PARAMS;
-		goto ExitUnlock;
+		goto Exit;
 	}
 
 	if (pfnReleaseData == NULL)
 	{
 		PVR_DPF((PVR_DBG_ERROR, "PVRSRVAllocHandle: Missing release function"));
 		eError = PVRSRV_ERROR_INVALID_PARAMS;
-		goto ExitUnlock;
-	}
-
-	if (!TEST_FLAG(eFlag, PVRSRV_HANDLE_ALLOC_FLAG_MULTI))
-	{
-		/* See if there is already a handle for this data pointer */
-		hHandle = FindHandle(psBase, pvData, eType, NULL);
-		if (hHandle != NULL)
-		{
-			HANDLE_DATA *psHandleData = NULL;
-
-			eError = GetHandleData(psBase, &psHandleData, hHandle, eType);
-			if (eError != PVRSRV_OK)
-			{
-				PVR_DPF((PVR_DBG_ERROR,
-					 "PVRSRVAllocHandle: Lookup of existing handle failed (%s)",
-					 PVRSRVGetErrorStringKM(eError)));
-				goto ExitUnlock;
-			}
-
-			/*
-			 * If the client is willing to share a handle, and the
-			 * existing handle is marked as shareable, return the
-			 * existing handle.
-			 */
-			if (TEST_FLAG(psHandleData->eFlag & eFlag, PVRSRV_HANDLE_ALLOC_FLAG_SHARED))
-			{
-				/* The same release function should be used for shared handles */
-				PVR_ASSERT(psHandleData->pfnReleaseData == pfnReleaseData);
-
-				psHandleData->ui32Refs++;
-				*phHandle = hHandle;
-
-				eError = PVRSRV_OK;
-				goto ExitUnlock;
-			}
-
-			eError = PVRSRV_ERROR_HANDLE_NOT_SHAREABLE;
-			goto ExitUnlock;
-		}
+		goto Exit;
 	}
 
 	eError = AllocHandle(psBase, phHandle, pvData, eType, eFlag, NULL, pfnReleaseData);
 
-ExitUnlock:
-	UnlockHandle();
-
+Exit:
 	return eError;
 }
 
@@ -1188,6 +1222,40 @@
 				  PVRSRV_HANDLE_ALLOC_FLAG eFlag,
 				  IMG_HANDLE hParent)
 {
+	PVRSRV_ERROR eError;
+
+	LockHandle();
+	eError = PVRSRVAllocSubHandleUnlocked(psBase, phHandle, pvData, eType, eFlag, hParent);
+	UnlockHandle();
+
+	return eError;
+}
+
+/*!
+******************************************************************************
+
+ @Function	PVRSRVAllocSubHandleUnlocked
+
+ @Description	Allocate a subhandle without acquiring/releasing the
+		handle lock. The function assumes you hold the lock when called.
+
+ @Input		phHandle - location for new subhandle
+		pvData - pointer to resource to be associated with the subhandle
+		eType - the type of resource
+		hParent - parent handle
+
+ @Output	phHandle - points to new subhandle
+
+ @Return	Error code or PVRSRV_OK
+
+******************************************************************************/
+PVRSRV_ERROR PVRSRVAllocSubHandleUnlocked(PVRSRV_HANDLE_BASE *psBase,
+				  IMG_HANDLE *phHandle,
+				  void *pvData,
+				  PVRSRV_HANDLE_TYPE eType,
+				  PVRSRV_HANDLE_ALLOC_FLAG eFlag,
+				  IMG_HANDLE hParent)
+{
 	HANDLE_DATA *psPHandleData = NULL;
 	HANDLE_DATA *psCHandleData = NULL;
 	IMG_HANDLE hParentKey;
@@ -1200,13 +1268,11 @@
 	PVR_ASSERT(eType != PVRSRV_HANDLE_TYPE_NONE);
 	PVR_ASSERT(gpsHandleFuncs);
 
-	LockHandle();
-
 	if (psBase == NULL)
 	{
 		PVR_DPF((PVR_DBG_ERROR, "PVRSRVAllocSubHandle: Missing handle base"));
 		eError = PVRSRV_ERROR_INVALID_PARAMS;
-		goto ExitUnlock;
+		goto Exit;
 	}
 
 	hParentKey = TEST_FLAG(eFlag, PVRSRV_HANDLE_ALLOC_FLAG_PRIVATE) ? hParent : NULL;
@@ -1216,49 +1282,13 @@
 	if (eError != PVRSRV_OK)
 	{
 		PVR_DPF((PVR_DBG_ERROR, "PVRSRVAllocSubHandle: Failed to get parent handle structure"));
-		goto ExitUnlock;
-	}
-
-	if (!TEST_FLAG(eFlag, PVRSRV_HANDLE_ALLOC_FLAG_MULTI))
-	{
-		/* See if there is already a handle for this data pointer */
-		hHandle = FindHandle(psBase, pvData, eType, hParentKey);
-		if (hHandle != NULL)
-		{
-			eError = GetHandleData(psBase, &psCHandleData, hHandle, eType);
-			if (eError != PVRSRV_OK)
-			{
-				PVR_DPF((PVR_DBG_ERROR, "PVRSRVAllocSubHandle: Lookup of existing handle failed"));
-				goto ExitUnlock;
-			}
-
-			PVR_ASSERT(hParentKey != NULL && ParentHandle(psCHandleData) == hParent);
-
-			/*
-			 * If the client is willing to share a handle, the
-			 * existing handle is marked as shareable, and the
-			 * existing handle has the same parent, return the
-			 * existing handle.
-			 */
-			if (TEST_FLAG(psCHandleData->eFlag & eFlag, PVRSRV_HANDLE_ALLOC_FLAG_SHARED) && 
-			    ParentHandle(psCHandleData) == hParent)
-			{
-				psCHandleData->ui32Refs++;
-				*phHandle = hHandle;
-
-				eError = PVRSRV_OK;
-				goto ExitUnlock;
-			}
-
-			eError = PVRSRV_ERROR_HANDLE_NOT_SHAREABLE;
-			goto ExitUnlock;
-		}
+		goto Exit;
 	}
 
 	eError = AllocHandle(psBase, &hHandle, pvData, eType, eFlag, hParentKey, NULL);
 	if (eError != PVRSRV_OK)
 	{
-		goto ExitUnlock;
+		goto Exit;
 	}
 
 	eError = GetHandleData(psBase, &psCHandleData, hHandle, PVRSRV_HANDLE_TYPE_NONE);
@@ -1270,7 +1300,7 @@
 		   can't also get it's handle structure. Otherwise something has gone badly wrong. */
 		PVR_ASSERT(eError == PVRSRV_OK);
 
-		goto ExitUnlock;
+		goto Exit;
 	}
 
 	/*
@@ -1284,7 +1314,7 @@
 		PVR_DPF((PVR_DBG_ERROR, "PVRSRVAllocSubHandle: Failed to get parent handle structure"));
 
 		(void)FreeHandle(psBase, hHandle, eType, NULL);
-		goto ExitUnlock;
+		goto Exit;
 	}
 
 	eError = AdoptChild(psBase, psPHandleData, psCHandleData);
@@ -1293,16 +1323,14 @@
 		PVR_DPF((PVR_DBG_ERROR, "PVRSRVAllocSubHandle: Parent handle failed to adopt subhandle"));
 
 		(void)FreeHandle(psBase, hHandle, eType, NULL);
-		goto ExitUnlock;
+		goto Exit;
 	}
 
 	*phHandle = hHandle;
 
 	eError = PVRSRV_OK;
 
-ExitUnlock:
-	UnlockHandle();
-
+Exit:
 	return eError;
 }
 
@@ -1327,6 +1355,38 @@
 			      void *pvData,
 			      PVRSRV_HANDLE_TYPE eType)
 {
+	PVRSRV_ERROR eError;
+
+	LockHandle();
+	eError = PVRSRVFindHandleUnlocked(psBase, phHandle, pvData, eType);
+	UnlockHandle();
+
+	return eError;
+}
+
+/*!
+******************************************************************************
+
+ @Function	PVRSRVFindHandleUnlocked
+
+ @Description	Find handle corresponding to a resource pointer without
+		acquiring/releasing the handle lock. The function assumes you hold
+		the lock when called.
+
+ @Input		phHandle - location for returned handle
+		pvData - pointer to resource to be associated with the handle
+		eType - the type of resource
+
+ @Output	phHandle - points to handle
+
+ @Return	Error code or PVRSRV_OK
+
+******************************************************************************/
+PVRSRV_ERROR PVRSRVFindHandleUnlocked(PVRSRV_HANDLE_BASE *psBase,
+			      IMG_HANDLE *phHandle,
+			      void *pvData,
+			      PVRSRV_HANDLE_TYPE eType)
+{
 	IMG_HANDLE hHandle;
 	PVRSRV_ERROR eError;
 
@@ -1334,30 +1394,30 @@
 	PVR_ASSERT(eType != PVRSRV_HANDLE_TYPE_NONE);
 	PVR_ASSERT(gpsHandleFuncs);
 
-	LockHandle();
-
 	if (psBase == NULL)
 	{
 		PVR_DPF((PVR_DBG_ERROR, "PVRSRVFindHandle: Missing handle base"));
 		eError = PVRSRV_ERROR_INVALID_PARAMS;
-		goto ExitUnlock;
+		goto Exit;
 	}
 
 	/* See if there is a handle for this data pointer */
 	hHandle = FindHandle(psBase, pvData, eType, NULL);
 	if (hHandle == NULL)
 	{
+		PVR_DPF((PVR_DBG_ERROR,
+			 "PVRSRVFindHandle: Error finding handle. Type %u",
+			 eType));
+
 		eError = PVRSRV_ERROR_HANDLE_NOT_FOUND;
-		goto ExitUnlock;
+		goto Exit;
 	}
 
 	*phHandle = hHandle;
 
 	eError = PVRSRV_OK;
 
-ExitUnlock:
-	UnlockHandle();
-
+Exit:
 	return eError;
 
 }
@@ -1372,6 +1432,8 @@
  @Input		ppvData - location to return data pointer
 		hHandle - handle from client
 		eType - handle type
+		bRef - If TRUE, a reference will be added on the handle if the
+		       lookup is successful.
 
  @Output	ppvData - points to the data pointer
 
@@ -1381,7 +1443,43 @@
 PVRSRV_ERROR PVRSRVLookupHandle(PVRSRV_HANDLE_BASE *psBase,
 				void **ppvData,
 				IMG_HANDLE hHandle,
-				PVRSRV_HANDLE_TYPE eType)
+				PVRSRV_HANDLE_TYPE eType,
+				IMG_BOOL bRef)
+{
+	PVRSRV_ERROR eError;
+
+	LockHandle();
+	eError = PVRSRVLookupHandleUnlocked(psBase, ppvData, hHandle, eType, bRef);
+	UnlockHandle();
+
+	return eError;
+}
+
+/*!
+******************************************************************************
+
+ @Function	PVRSRVLookupHandleUnlocked
+
+ @Description	Lookup the data pointer corresponding to a handle without
+ 		acquiring/releasing the handle lock. The function assumes you
+		hold the lock when called.
+
+ @Input		ppvData - location to return data pointer
+		hHandle - handle from client
+		eType - handle type
+		bRef - If TRUE, a reference will be added on the handle if the
+		       lookup is successful.
+
+ @Output	ppvData - points to the data pointer
+
+ @Return	Error code or PVRSRV_OK
+
+******************************************************************************/
+PVRSRV_ERROR PVRSRVLookupHandleUnlocked(PVRSRV_HANDLE_BASE *psBase,
+				void **ppvData,
+				IMG_HANDLE hHandle,
+				PVRSRV_HANDLE_TYPE eType,
+				IMG_BOOL bRef)
 {
 	HANDLE_DATA *psHandleData = NULL;
 	PVRSRV_ERROR eError;
@@ -1390,33 +1488,37 @@
 	PVR_ASSERT(eType != PVRSRV_HANDLE_TYPE_NONE);
 	PVR_ASSERT(gpsHandleFuncs);
 
-	LockHandle();
-
 	if (psBase == NULL)
 	{
 		PVR_DPF((PVR_DBG_ERROR, "PVRSRVLookupHandle: Missing handle base"));
 		eError = PVRSRV_ERROR_INVALID_PARAMS;
-		goto ExitUnlock;
+		goto Exit;
 	}
 
 	eError = GetHandleData(psBase, &psHandleData, hHandle, eType);
 	if (eError != PVRSRV_OK)
 	{
 		PVR_DPF((PVR_DBG_ERROR,
-			 "PVRSRVLookupHandle: Error looking up handle (%s)",
-			 PVRSRVGetErrorStringKM(eError)));
+			 "PVRSRVLookupHandle: Error looking up handle (%s). Handle %p, type %u",
+			 PVRSRVGetErrorStringKM(eError),
+			 (void*) hHandle,
+			 eType));
 #if defined(DEBUG) || defined(PVRSRV_NEED_PVR_DPF)
 		OSDumpStack();
 #endif
-		goto ExitUnlock;
+		goto Exit;
+	}
+
+	if(bRef)
+	{
+		_HandleRef(psHandleData);
 	}
 
 	*ppvData = psHandleData->pvData;
 
 	eError = PVRSRV_OK;
 
-ExitUnlock:
-	UnlockHandle();
+Exit:
 
 	return eError;
 }
@@ -1465,8 +1567,10 @@
 	if (eError != PVRSRV_OK)
 	{
 		PVR_DPF((PVR_DBG_ERROR,
-			 "PVRSRVLookupSubHandle: Error looking up subhandle (%s)",
-			 PVRSRVGetErrorStringKM(eError)));
+			 "PVRSRVLookupSubHandle: Error looking up subhandle (%s). Handle %p, type %u",
+			 PVRSRVGetErrorStringKM(eError),
+			 (void*) hHandle,
+			 eType));
 		OSDumpStack();
 		goto ExitUnlock;
 	}
@@ -1536,8 +1640,9 @@
 	if (eError != PVRSRV_OK)
 	{
 		PVR_DPF((PVR_DBG_ERROR,
-			 "PVRSRVGetParentHandle: Error looking up subhandle (%s)",
-			 PVRSRVGetErrorStringKM(eError)));
+			 "PVRSRVGetParentHandle: Error looking up subhandle (%s). Type %u",
+			 PVRSRVGetErrorStringKM(eError),
+			 eType));
 		OSDumpStack();
 		goto ExitUnlock;
 	}
@@ -1571,23 +1676,49 @@
 {
 	PVRSRV_ERROR eError;
 
+	LockHandle();
+	eError = PVRSRVReleaseHandleUnlocked(psBase, hHandle, eType);
+	UnlockHandle();
+
+	return eError;
+}
+
+
+/*!
+******************************************************************************
+
+ @Function	PVRSRVReleaseHandleUnlocked
+
+ @Description	Release a handle that is no longer needed without
+ 		acquiring/releasing the handle lock. The function assumes you
+		hold the lock when called.
+
+ @Input 	hHandle - handle from client
+		eType - handle type
+
+ @Return	Error code or PVRSRV_OK
+
+******************************************************************************/
+PVRSRV_ERROR PVRSRVReleaseHandleUnlocked(PVRSRV_HANDLE_BASE *psBase,
+				 IMG_HANDLE hHandle,
+				 PVRSRV_HANDLE_TYPE eType)
+{
+	PVRSRV_ERROR eError;
+
 	/* PVRSRV_HANDLE_TYPE_NONE is reserved for internal use */
 	PVR_ASSERT(eType != PVRSRV_HANDLE_TYPE_NONE);
 	PVR_ASSERT(gpsHandleFuncs);
 
-	LockHandle();
-
 	if (psBase == NULL)
 	{
 		PVR_DPF((PVR_DBG_ERROR, "PVRSRVReleaseHandle: Missing handle base"));
 		eError = PVRSRV_ERROR_INVALID_PARAMS;
-		goto ExitUnlock;
+		goto Exit;
 	}
 
 	eError = FreeHandle(psBase, hHandle, eType, NULL);
 
-ExitUnlock:
-	UnlockHandle();
+Exit:
 
 	return eError;
 }
@@ -1641,7 +1772,8 @@
  @Return	Error code or PVRSRV_OK
 
 ******************************************************************************/
-PVRSRV_ERROR PVRSRVAllocHandleBase(PVRSRV_HANDLE_BASE **ppsBase)
+PVRSRV_ERROR PVRSRVAllocHandleBase(PVRSRV_HANDLE_BASE **ppsBase,
+                                   PVRSRV_HANDLE_BASE_TYPE eType)
 {
 	PVRSRV_HANDLE_BASE *psBase;
 	PVRSRV_ERROR eError;
@@ -1668,6 +1800,8 @@
 		goto ErrorUnlock;
 	}
 
+	psBase->eType = eType;
+
 	eError = gpsHandleFuncs->pfnCreateHandleBase(&psBase->psImplBase);
 	if (eError != PVRSRV_OK)
 	{
@@ -1743,6 +1877,46 @@
 
 	return PVRSRV_OK;
 }
+
+/* Print a handle in the handle base. Used with the iterator callback. */
+static PVRSRV_ERROR ListHandlesInBase(IMG_HANDLE hHandle, void *pvData)
+{
+	PVRSRV_HANDLE_BASE *psBase = (PVRSRV_HANDLE_BASE*) pvData;
+	HANDLE_DATA *psHandleData = NULL;
+	PVRSRV_ERROR eError;
+
+	PVR_ASSERT(gpsHandleFuncs);
+
+	if (psBase == NULL)
+	{
+		PVR_DPF((PVR_DBG_ERROR, "%s: Missing base", __func__));
+		return PVRSRV_ERROR_INVALID_PARAMS;
+	}
+
+	eError = GetHandleData(psBase,
+			       &psHandleData,
+			       hHandle,
+			       PVRSRV_HANDLE_TYPE_NONE);
+	if (eError != PVRSRV_OK)
+	{
+		PVR_DPF((PVR_DBG_ERROR, "%s: Couldn't get handle data for handle", __func__));
+		return eError;
+	}
+
+	if (psHandleData != NULL)
+	{
+		PVR_DPF((PVR_DBG_WARNING, "    Handle: %6u, Type: %3u, Refs: %3u",
+				(IMG_UINT32) (uintptr_t) psHandleData->hHandle,
+				psHandleData->eType,
+				psHandleData->ui32RefCount));
+
+	}
+
+	return PVRSRV_OK;
+}
+
+
+
 #endif /* defined(DEBUG) */
 
 typedef struct FREE_HANDLE_DATA_TAG
@@ -1803,9 +1977,9 @@
 		return PVRSRV_OK;
 	}
 
-	PVR_ASSERT(psHandleData->ui32Refs > 0);
+	PVR_ASSERT(psHandleData->ui32RefCount > 0);
 
-	while (psHandleData->ui32Refs != 0)
+	while (psHandleData->ui32RefCount != 0)
 	{
 		if (psHandleData->pfnReleaseData != NULL)
 		{
@@ -1826,7 +2000,7 @@
 			}
 		}
 
-		psHandleData->ui32Refs--;
+		_HandleUnref(psHandleData);
 	}
 
 	if (!TEST_ALLOC_FLAG(psHandleData, PVRSRV_HANDLE_ALLOC_FLAG_MULTI))
@@ -1862,12 +2036,10 @@
 		PVR_DPF((PVR_DBG_MESSAGE, "FreeResourceByCriteria: Lock timeout (timeout: %llu)",
 								            psData->ui64MaxBridgeTime));
 		UnlockHandle();
-		PMRUnlock();
 		OSReleaseBridgeLock();
 		/* Invoke the scheduler to check if other processes are waiting for the lock */
 		OSReleaseThreadQuanta();
 		OSAcquireBridgeLock();
-		PMRLock();
 		LockHandle();
 		/* Set again lock timeout and reset the counter */
 		psData->ui64TimeStart = OSClockns64();
@@ -1884,14 +2056,15 @@
 	PVRSRV_HANDLE_TYPE_RGX_FW_MEMDESC,
 	PVRSRV_HANDLE_TYPE_RGX_RTDATA_CLEANUP,
 	PVRSRV_HANDLE_TYPE_RGX_FREELIST,
-	PVRSRV_HANDLE_TYPE_RGX_RPM_CONTEXT_CLEANUP,
 	PVRSRV_HANDLE_TYPE_RGX_RPM_FREELIST,
+	PVRSRV_HANDLE_TYPE_RGX_SERVER_RPM_CONTEXT,
 	PVRSRV_HANDLE_TYPE_RGX_MEMORY_BLOCK,
 	PVRSRV_HANDLE_TYPE_RGX_POPULATION,
 	PVRSRV_HANDLE_TYPE_RGX_FWIF_ZSBUFFER,
 	PVRSRV_HANDLE_TYPE_RGX_FWIF_RENDERTARGET,
 	PVRSRV_HANDLE_TYPE_RGX_SERVER_RENDER_CONTEXT,
 	PVRSRV_HANDLE_TYPE_RGX_SERVER_TQ_CONTEXT,
+	PVRSRV_HANDLE_TYPE_RGX_SERVER_TQ_TDM_CONTEXT,
 	PVRSRV_HANDLE_TYPE_RGX_SERVER_COMPUTE_CONTEXT,
 	PVRSRV_HANDLE_TYPE_RGX_SERVER_RAY_CONTEXT,
 	PVRSRV_HANDLE_TYPE_RGX_SERVER_KICKSYNC_CONTEXT,
@@ -1918,7 +2091,6 @@
 	PVRSRV_HANDLE_TYPE_DC_DISPLAY_CONTEXT,
 	PVRSRV_HANDLE_TYPE_DC_DEVICE,
 	PVRSRV_HANDLE_TYPE_PVR_TL_SD,
-	PVRSRV_HANDLE_TYPE_DEV_NODE,
 	PVRSRV_HANDLE_TYPE_MM_PLAT_CLEANUP
 };
 
@@ -1951,26 +2123,9 @@
 	sHandleData.ui64TimeStart = OSClockns64();
 	sHandleData.ui64MaxBridgeTime = ui64MaxBridgeTime;
 
-	for (i = 0; i < ARRAY_SIZE(g_aeOrderedFreeList); i++)
-	{
-		sHandleData.eHandleFreeType = g_aeOrderedFreeList[i];
-
-		/* Make sure all handles have been freed before destroying the handle base */
-		eError = gpsHandleFuncs->pfnIterateOverHandles(psBase->psImplBase,
-							       &FreeHandleDataWrapper,
-							       (void *)&sHandleData);
-		if (eError != PVRSRV_OK)
-		{
-			goto ExitUnlock;
-		}
-	}
 
 #if defined(DEBUG)
-	/*
-	 * As we're freeing handles based on type, make sure all
-	 * handles have actually had their data freed to avoid
-	 * resources being leaked
-	 */
+
 	sCountData.psBase = psBase;
 
 	eError = gpsHandleFuncs->pfnIterateOverHandles(psBase->psImplBase,
@@ -1986,14 +2141,50 @@
 
 	if (sCountData.uiHandleDataCount != 0)
 	{
-		PVR_DPF((PVR_DBG_ERROR,
-			 "PVRSRVFreeHandleBase: Found %u handles that need freeing for handle base %p",
+		IMG_BOOL bList = sCountData.uiHandleDataCount < HANDLE_DEBUG_LISTING_MAX_NUM;
+
+		PVR_DPF((PVR_DBG_WARNING,
+			 "%s: %u remaining handles in handle base 0x%p "
+			 "(PVRSRV_HANDLE_BASE_TYPE %u). %s",
+			 __func__,
 			 sCountData.uiHandleDataCount,
-			 psBase));
-		PVR_ASSERT(0);
+			 psBase,
+			 psBase->eType,
+			 bList ? "Check handle.h for a type reference":
+					 "Skipping details, too many items..."));
+
+		if (bList)
+		{
+			PVR_DPF((PVR_DBG_WARNING, "-------- Listing Handles --------"));
+			eError = gpsHandleFuncs->pfnIterateOverHandles(psBase->psImplBase,
+										   &ListHandlesInBase,
+										   psBase);
+			PVR_DPF((PVR_DBG_WARNING, "-------- Done Listing    --------"));
+		}
 	}
+
 #endif /* defined(DEBUG) */
 
+	/*
+	 * As we're freeing handles based on type, make sure all
+	 * handles have actually had their data freed to avoid
+	 * resources being leaked
+	 */
+	for (i = 0; i < ARRAY_SIZE(g_aeOrderedFreeList); i++)
+	{
+		sHandleData.eHandleFreeType = g_aeOrderedFreeList[i];
+
+		/* Make sure all handles have been freed before destroying the handle base */
+		eError = gpsHandleFuncs->pfnIterateOverHandles(psBase->psImplBase,
+							       &FreeHandleDataWrapper,
+							       (void *)&sHandleData);
+		if (eError != PVRSRV_OK)
+		{
+			goto ExitUnlock;
+		}
+	}
+
+
 	if (psBase->psHashTab != NULL)
 	{
 		HASH_Delete(psBase->psHashTab);
@@ -2052,7 +2243,8 @@
 		goto ErrorHandleDeinit;
 	}
 
-	eError = PVRSRVAllocHandleBase(&gpsKernelHandleBase);
+	eError = PVRSRVAllocHandleBase(&gpsKernelHandleBase,
+	                               PVRSRV_HANDLE_BASE_TYPE_GLOBAL);
 	if (eError != PVRSRV_OK)
 	{
 		PVR_DPF((PVR_DBG_ERROR,
diff --git a/drivers/staging/imgtec/rogue/handle.h b/drivers/staging/imgtec/rogue/handle.h
index 5da9417..fd90d8a 100644
--- a/drivers/staging/imgtec/rogue/handle.h
+++ b/drivers/staging/imgtec/rogue/handle.h
@@ -67,11 +67,6 @@
  * For handles that have a definite lifetime, where the corresponding
  * resource is explicitly created and destroyed, eFlag should be zero.
  *
- * If the resource is not explicitly created and destroyed, eFlag should be
- * set to PVRSRV_HANDLE_ALLOC_FLAG_SHARED.  For a given process, the same
- * handle will be returned each time a handle for the resource is allocated
- * with the PVRSRV_HANDLE_ALLOC_FLAG_SHARED flag.
- *
  * If a particular resource may be referenced multiple times by a
  * given process, setting eFlag to PVRSRV_HANDLE_ALLOC_FLAG_MULTI
  * will allow multiple handles to be allocated for the resource.
@@ -128,7 +123,6 @@
 typedef enum
 {
 	PVRSRV_HANDLE_TYPE_NONE = 0,
-	PVRSRV_HANDLE_TYPE_DEV_NODE,
 	PVRSRV_HANDLE_TYPE_SHARED_EVENT_OBJECT,
 	PVRSRV_HANDLE_TYPE_EVENT_OBJECT_CONNECT,
 	PVRSRV_HANDLE_TYPE_PMR_LOCAL_EXPORT_HANDLE,
@@ -143,11 +137,12 @@
 	PVRSRV_HANDLE_TYPE_RGX_FW_MEMDESC,
 	PVRSRV_HANDLE_TYPE_RGX_RTDATA_CLEANUP,
 	PVRSRV_HANDLE_TYPE_RGX_FREELIST,
-	PVRSRV_HANDLE_TYPE_RGX_RPM_CONTEXT_CLEANUP,
+	PVRSRV_HANDLE_TYPE_RGX_SERVER_RPM_CONTEXT,
 	PVRSRV_HANDLE_TYPE_RGX_RPM_FREELIST,
 	PVRSRV_HANDLE_TYPE_RGX_MEMORY_BLOCK,
 	PVRSRV_HANDLE_TYPE_RGX_SERVER_RENDER_CONTEXT,
 	PVRSRV_HANDLE_TYPE_RGX_SERVER_TQ_CONTEXT,
+	PVRSRV_HANDLE_TYPE_RGX_SERVER_TQ_TDM_CONTEXT,
 	PVRSRV_HANDLE_TYPE_RGX_SERVER_COMPUTE_CONTEXT,
 	PVRSRV_HANDLE_TYPE_RGX_SERVER_RAY_CONTEXT,
 	PVRSRV_HANDLE_TYPE_RGX_SERVER_KICKSYNC_CONTEXT,
@@ -168,45 +163,67 @@
 	PVRSRV_HANDLE_TYPE_PVR_TL_SD,
 	PVRSRV_HANDLE_TYPE_RI_HANDLE,
 	PVRSRV_HANDLE_TYPE_DEV_PRIV_DATA,
-	PVRSRV_HANDLE_TYPE_MM_PLAT_CLEANUP
+	PVRSRV_HANDLE_TYPE_MM_PLAT_CLEANUP,
+	PVRSRV_HANDLE_TYPE_WORKEST_RETURN_DATA
 } PVRSRV_HANDLE_TYPE;
 
 typedef enum
 {
+	PVRSRV_HANDLE_BASE_TYPE_CONNECTION,
+	PVRSRV_HANDLE_BASE_TYPE_PROCESS,
+	PVRSRV_HANDLE_BASE_TYPE_GLOBAL
+} PVRSRV_HANDLE_BASE_TYPE;
+
+
+typedef enum
+{
 	/* No flags */
 	PVRSRV_HANDLE_ALLOC_FLAG_NONE = 		0,
-	/* Share a handle that already exists for a given data pointer */
-	PVRSRV_HANDLE_ALLOC_FLAG_SHARED = 		0x01,
 	/* Muliple handles can point at the given data pointer */
-	PVRSRV_HANDLE_ALLOC_FLAG_MULTI = 		0x02,
+	PVRSRV_HANDLE_ALLOC_FLAG_MULTI = 		0x01,
 	/* Subhandles are allocated in a private handle space */
-	PVRSRV_HANDLE_ALLOC_FLAG_PRIVATE = 		0x04
+	PVRSRV_HANDLE_ALLOC_FLAG_PRIVATE = 		0x02
 } PVRSRV_HANDLE_ALLOC_FLAG;
 
 typedef struct _HANDLE_BASE_ PVRSRV_HANDLE_BASE;
 
+typedef struct _PROCESS_HANDLE_BASE_
+{
+	PVRSRV_HANDLE_BASE *psHandleBase;
+	ATOMIC_T iRefCount;
+
+} PROCESS_HANDLE_BASE;
+
 extern PVRSRV_HANDLE_BASE *gpsKernelHandleBase;
 #define	KERNEL_HANDLE_BASE (gpsKernelHandleBase)
 
+#define HANDLE_DEBUG_LISTING_MAX_NUM 20
+
 typedef PVRSRV_ERROR (*PFN_HANDLE_RELEASE)(void *pvData);
 
 PVRSRV_ERROR PVRSRVAllocHandle(PVRSRV_HANDLE_BASE *psBase, IMG_HANDLE *phHandle, void *pvData, PVRSRV_HANDLE_TYPE eType, PVRSRV_HANDLE_ALLOC_FLAG eFlag, PFN_HANDLE_RELEASE pfnReleaseData);
+PVRSRV_ERROR PVRSRVAllocHandleUnlocked(PVRSRV_HANDLE_BASE *psBase, IMG_HANDLE *phHandle, void *pvData, PVRSRV_HANDLE_TYPE eType, PVRSRV_HANDLE_ALLOC_FLAG eFlag, PFN_HANDLE_RELEASE pfnReleaseData);
 
 PVRSRV_ERROR PVRSRVAllocSubHandle(PVRSRV_HANDLE_BASE *psBase, IMG_HANDLE *phHandle, void *pvData, PVRSRV_HANDLE_TYPE eType, PVRSRV_HANDLE_ALLOC_FLAG eFlag, IMG_HANDLE hParent);
+PVRSRV_ERROR PVRSRVAllocSubHandleUnlocked(PVRSRV_HANDLE_BASE *psBase, IMG_HANDLE *phHandle, void *pvData, PVRSRV_HANDLE_TYPE eType, PVRSRV_HANDLE_ALLOC_FLAG eFlag, IMG_HANDLE hParent);
 
 PVRSRV_ERROR PVRSRVFindHandle(PVRSRV_HANDLE_BASE *psBase, IMG_HANDLE *phHandle, void *pvData, PVRSRV_HANDLE_TYPE eType);
+PVRSRV_ERROR PVRSRVFindHandleUnlocked(PVRSRV_HANDLE_BASE *psBase, IMG_HANDLE *phHandle, void *pvData, PVRSRV_HANDLE_TYPE eType);
 
-PVRSRV_ERROR PVRSRVLookupHandle(PVRSRV_HANDLE_BASE *psBase, void **ppvData, IMG_HANDLE hHandle, PVRSRV_HANDLE_TYPE eType);
+PVRSRV_ERROR PVRSRVLookupHandle(PVRSRV_HANDLE_BASE *psBase, void **ppvData, IMG_HANDLE hHandle, PVRSRV_HANDLE_TYPE eType, IMG_BOOL bRef);
+PVRSRV_ERROR PVRSRVLookupHandleUnlocked(PVRSRV_HANDLE_BASE *psBase, void **ppvData, IMG_HANDLE hHandle, PVRSRV_HANDLE_TYPE eType, IMG_BOOL bRef);
 
 PVRSRV_ERROR PVRSRVLookupSubHandle(PVRSRV_HANDLE_BASE *psBase, void **ppvData, IMG_HANDLE hHandle, PVRSRV_HANDLE_TYPE eType, IMG_HANDLE hAncestor);
 
 PVRSRV_ERROR PVRSRVGetParentHandle(PVRSRV_HANDLE_BASE *psBase, IMG_HANDLE *phParent, IMG_HANDLE hHandle, PVRSRV_HANDLE_TYPE eType);
 
 PVRSRV_ERROR PVRSRVReleaseHandle(PVRSRV_HANDLE_BASE *psBase, IMG_HANDLE hHandle, PVRSRV_HANDLE_TYPE eType);
+PVRSRV_ERROR PVRSRVReleaseHandleUnlocked(PVRSRV_HANDLE_BASE *psBase, IMG_HANDLE hHandle, PVRSRV_HANDLE_TYPE eType);
 
 PVRSRV_ERROR PVRSRVPurgeHandles(PVRSRV_HANDLE_BASE *psBase);
 
-PVRSRV_ERROR PVRSRVAllocHandleBase(PVRSRV_HANDLE_BASE **ppsBase);
+PVRSRV_ERROR PVRSRVAllocHandleBase(PVRSRV_HANDLE_BASE **ppsBase,
+                                   PVRSRV_HANDLE_BASE_TYPE eType);
 
 PVRSRV_ERROR PVRSRVFreeHandleBase(PVRSRV_HANDLE_BASE *psBase, IMG_UINT64 ui64MaxBridgeTime);
 
diff --git a/drivers/staging/imgtec/rogue/handle_idr.c b/drivers/staging/imgtec/rogue/handle_idr.c
index d18df75..a203ebd 100644
--- a/drivers/staging/imgtec/rogue/handle_idr.c
+++ b/drivers/staging/imgtec/rogue/handle_idr.c
@@ -389,12 +389,6 @@
 {
 	PVR_ASSERT(psBase);
 
-	if (psBase->ui32TotalHandCount != 0)
-	{
-		PVR_DPF((PVR_DBG_WARNING, "%s: Handles still exist (%u found)", 
-			 __FUNCTION__, psBase->ui32TotalHandCount));
-	}
-
 #if (LINUX_VERSION_CODE < KERNEL_VERSION(3,9,0))
 	idr_remove_all(&psBase->sIdr);
 #endif
diff --git a/drivers/staging/imgtec/rogue/hash.c b/drivers/staging/imgtec/rogue/hash.c
index 9444bcf..b098dfe 100644
--- a/drivers/staging/imgtec/rogue/hash.c
+++ b/drivers/staging/imgtec/rogue/hash.c
@@ -187,6 +187,7 @@
 @Input          pBucket       The bucket
 @Input          ppBucketTable The hash table
 @Input          uSize         The size of the hash table
+@Return         PVRSRV_ERROR
 */ /**************************************************************************/
 static void
 _ChainInsert (HASH_TABLE *pHash, BUCKET *pBucket, BUCKET **ppBucketTable, IMG_UINT32 uSize)
@@ -211,6 +212,7 @@
 @Input          uOldSize     The size of the old hash table
 @Input          ppNewTable   The new hash table
 @Input          uNewSize     The size of the new hash table
+@Return         None
 */ /**************************************************************************/
 static void
 _Rehash (HASH_TABLE *pHash,
@@ -384,6 +386,12 @@
 			bDoCheck = IMG_FALSE;
 		}
 	}
+#if defined(PVRSRV_FORCE_UNLOAD_IF_BAD_STATE)
+	else
+	{
+		bDoCheck = IMG_FALSE;
+	}
+#endif
 #endif
 	if (pHash != NULL)
     {
@@ -395,8 +403,20 @@
 		}
 		if(pHash->uCount != 0)
 		{
-			PVR_DPF ((PVR_DBG_ERROR, "HASH_Delete: leak detected in hash table!"));
-			PVR_DPF ((PVR_DBG_ERROR, "Likely Cause: client drivers not freeing alocations before destroying devmemcontext"));
+			IMG_UINT32 uiEntriesLeft = pHash->uCount;
+			IMG_UINT32 i;
+			PVR_DPF ((PVR_DBG_ERROR, "%s: Leak detected in hash table!", __func__));
+			PVR_DPF ((PVR_DBG_ERROR, "%s: Likely Cause: client drivers not freeing allocations before destroying devmemcontext", __func__));
+			PVR_DPF ((PVR_DBG_ERROR, "%s: Removing remaining %u hash entries.", __func__, uiEntriesLeft));
+
+			for (i = 0; i < uiEntriesLeft; i++)
+			{
+#if defined(__linux__) && defined(__KERNEL__)
+				OSFreeMemNoStats(pHash->ppBucketTable[i]);
+#else
+				OSFreeMem(pHash->ppBucketTable[i]);
+#endif
+			}
 		}
 #if defined(__linux__) && defined(__KERNEL__)
 		OSFreeMemNoStats(pHash->ppBucketTable);
@@ -642,7 +662,6 @@
     return PVRSRV_OK;
 }
 
-
 #ifdef HASH_TRACE
 /*************************************************************************/ /*!
 @Function       HASH_Dump
diff --git a/drivers/staging/imgtec/rogue/hostfunc.c b/drivers/staging/imgtec/rogue/hostfunc.c
index 00628f4..b0bf414 100644
--- a/drivers/staging/imgtec/rogue/hostfunc.c
+++ b/drivers/staging/imgtec/rogue/hostfunc.c
@@ -39,7 +39,6 @@
 IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */ /**************************************************************************/
-#include <linux/version.h>
 #include <linux/errno.h>
 #include <linux/module.h>
 #include <linux/fs.h>
@@ -49,11 +48,7 @@
 #include <linux/string.h>
 #include <asm/page.h>
 #include <linux/vmalloc.h>
-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,15))
 #include <linux/mutex.h>
-#else
-#include <asm/semaphore.h>
-#endif
 #include <linux/hardirq.h>
 
 #if defined(SUPPORT_DBGDRV_EVENT_OBJECTS)
@@ -70,113 +65,6 @@
 #include "hostfunc.h"
 #include "dbgdriv.h"
 
-#if defined(PVRSRV_NEED_PVR_DPF) && !defined(SUPPORT_DRM)
-IMG_UINT32	gPVRDebugLevel = (DBGPRIV_FATAL | DBGPRIV_ERROR | DBGPRIV_WARNING |
-		DBGPRIV_CALLTRACE); /* Added call trace level to support PVR_LOGging of state in debug driver */
-
-#define PVR_STRING_TERMINATOR		'\0'
-#define PVR_IS_FILE_SEPARATOR(character) ( ((character) == '\\') || ((character) == '/') )
-
-/******************************************************************************/
-
-
-/*----------------------------------------------------------------------------
-<function>
-	FUNCTION   : PVRSRVDebugPrintf
-	PURPOSE    : To output a debug message to the user
-	PARAMETERS : In : uDebugLevel - The current debug level
-	             In : pszFile - The source file generating the message
-	             In : uLine - The line of the source file
-	             In : pszFormat - The message format string
-	             In : ... - Zero or more arguments for use by the format string
-	RETURNS    : None
-</function>
-------------------------------------------------------------------------------*/
-void PVRSRVDebugPrintf	(
-						IMG_UINT32	ui32DebugLevel,
-						const IMG_CHAR*	pszFileName,
-						IMG_UINT32	ui32Line,
-						const IMG_CHAR*	pszFormat,
-						...
-					)
-{
-	IMG_BOOL bTrace;
-	IMG_CHAR *pszLeafName;
-
-	pszLeafName = (char *)strrchr (pszFileName, '/');
-
-	if (pszLeafName)
-	{
-		pszFileName = pszLeafName;
-	}
-
-	bTrace = (IMG_BOOL)(ui32DebugLevel & DBGPRIV_CALLTRACE) ? IMG_TRUE : IMG_FALSE;
-
-	if (gPVRDebugLevel & ui32DebugLevel)
-	{
-		va_list vaArgs;
-		static char szBuffer[512];
-
-		va_start (vaArgs, pszFormat);
-
-		/* Add in the level of warning */
-		if (bTrace == IMG_FALSE)
-		{
-			switch(ui32DebugLevel)
-			{
-				case DBGPRIV_FATAL:
-				{
-					strcpy (szBuffer, "PVR_K:(Fatal): ");
-					break;
-				}
-				case DBGPRIV_ERROR:
-				{
-					strcpy (szBuffer, "PVR_K:(Error): ");
-					break;
-				}
-				case DBGPRIV_WARNING:
-				{
-					strcpy (szBuffer, "PVR_K:(Warning): ");
-					break;
-				}
-				case DBGPRIV_MESSAGE:
-				{
-					strcpy (szBuffer, "PVR_K:(Message): ");
-					break;
-				}
-				case DBGPRIV_VERBOSE:
-				{
-					strcpy (szBuffer, "PVR_K:(Verbose): ");
-					break;
-				}
-				default:
-				{
-					strcpy (szBuffer, "PVR_K:()");
-					break;
-				}
-			}
-		}
-		else
-		{
-			strcpy (szBuffer, "PVR_K: ");
-		}
-
-		vsprintf (&szBuffer[strlen(szBuffer)], pszFormat, vaArgs);
-
- 		/*
- 		 * Metrics and Traces don't need a location
- 		 */
- 		if (bTrace == IMG_FALSE)
-		{
-			sprintf (&szBuffer[strlen(szBuffer)], " [%d, %s]", (int)ui32Line, pszFileName);
-		}
-
-		printk(KERN_INFO "%s\n", szBuffer);
-
-		va_end (vaArgs);
-	}
-}
-#endif	/* defined(PVRSRV_NEED_PVR_DPF) && !defined(SUPPORT_DRM) */
 
 /*!
 ******************************************************************************
diff --git a/drivers/staging/imgtec/rogue/htbinit.c b/drivers/staging/imgtec/rogue/htbinit.c
deleted file mode 100644
index 4764c2c..0000000
--- a/drivers/staging/imgtec/rogue/htbinit.c
+++ /dev/null
@@ -1,129 +0,0 @@
-/*************************************************************************/ /*!
-@File
-@Title          Host trace buffer initialisation routines
-@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
-@License        Dual MIT/GPLv2
-
-The contents of this file are subject to the MIT license as set out below.
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-Alternatively, the contents of this file may be used under the terms of
-the GNU General Public License Version 2 ("GPL") in which case the provisions
-of GPL are applicable instead of those above.
-
-If you wish to allow use of your version of this file only under the terms of
-GPL, and not to allow others to use your version of this file under the terms
-of the MIT license, indicate your decision by deleting the provisions above
-and replace them with the notice and other provisions required by GPL as set
-out in the file called "GPL-COPYING" included in this distribution. If you do
-not delete the provisions above, a recipient may use your version of this file
-under the terms of either the MIT license or GPL.
-
-This License is also included in this distribution in the file called
-"MIT-COPYING".
-
-EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
-PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
-BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
-PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
-COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
-IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
-CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-*/ /**************************************************************************/
-
-#include "img_defs.h"
-#include "pvr_debug.h"
-#include "srvinit.h"
-#include "srvinit_param.h"
-#include "htbuffer_types.h"
-#include "htbuffer_init.h"
-
-/* apphint map of name vs. enable flag */
-static SRV_INIT_PARAM_UINT32_LOOKUP asLogGroupTable[] = {
-#define X(a, b) { #b, HTB_LOG_GROUP_FLAG_NAME(b) },
-	HTB_LOG_SFGROUPLIST
-#undef X
-};
-/* apphint map of arg vs. OpMode */
-static SRV_INIT_PARAM_UINT32_LOOKUP asOpModeTable[] = {
-	{ "droplatest", HTB_OPMODE_DROPLATEST},
-	{ "dropoldest", HTB_OPMODE_DROPOLDEST},
-	/* HTB should never be started in HTB_OPMODE_BLOCK
-	 * as this can lead to deadlocks
-	 */
-};
-/* apphint map of arg vs. LogMode */
-static SRV_INIT_PARAM_UINT32_LOOKUP asLogModeTable[] = {
-	{ "all", HTB_LOGMODE_ALLPID},
-	{ "restricted", HTB_LOGMODE_RESTRICTEDPID}
-};
-
-
-/* setup apphint root and associated data from the apphint maps */
-/* Future improvements: AppHint parsing will need to be reworked to support more than 32 Log Groups */
-SrvInitParamInitUINT32BitField( EnableHTBLogGroup,     0,                       asLogGroupTable);
-SrvInitParamInitUINT32List(     HTBOperationMode,      HTB_OPMODE_DROPLATEST,   asOpModeTable);
-SrvInitParamInitUINT32List(     HTBLogMode,            HTB_LOGMODE_ALLPID,      asLogModeTable);
-SrvInitParamInitUINT32(         HTBufferSize,          0x1000 );
-
-/* Future improvements: */
-SrvInitParamInitBOOL(           EnableHTBPID,          0);
-SrvInitParamInitUINT32(         HTBLogLevel,           0);
-
-IMG_INTERNAL void
-_ParseHTBAppHints(SHARED_DEV_CONNECTION hServices)
-{
-	PVRSRV_ERROR eError;
-	void * pvParamState = NULL;
-	IMG_UINT32 ui32LogType;
-	IMG_BOOL bAnyLogGroupConfigured;
-	HTB_LOGMODE_CTRL eLogMode;
-
-	IMG_CHAR * szBufferName = "PVRHTBuffer";
-	IMG_UINT32 ui32BufferSize;
-	HTB_OPMODE_CTRL eOpMode;
-
-	/* Services initialisation parameters */
-	pvParamState = SrvInitParamOpen();
-
-	bAnyLogGroupConfigured = SrvInitParamGetUINT32BitField(pvParamState, EnableHTBLogGroup, ui32LogType);
-	SrvInitParamGetUINT32List(pvParamState, HTBOperationMode, eOpMode);
-	SrvInitParamGetUINT32(pvParamState, HTBufferSize, ui32BufferSize);
-	SrvInitParamGetUINT32List(pvParamState, HTBLogMode, eLogMode);
-
-	/* future improvements:
-	 * PID should be enabled against a process name
-	 * LogLevel requires SF change
-	 */
-	{
-	IMG_BOOL bEnablePID;
-	IMG_UINT32 ui32LogLevel;
-	SrvInitParamGetBOOL(pvParamState, EnableHTBPID, bEnablePID);
-	SrvInitParamGetUINT32(pvParamState, HTBLogLevel, ui32LogLevel);
-	}
-
-	eError = HTBConfigure(hServices, szBufferName, ui32BufferSize);
-	PVR_LOGG_IF_ERROR(eError, "PVRSRVHTBConfigure", cleanup);
-
-	if (bAnyLogGroupConfigured)
-	{
-		eError = HTBControl(hServices, 1, &ui32LogType, 0, 0, eLogMode, eOpMode);
-		PVR_LOGG_IF_ERROR(eError, "PVRSRVHTBControl", cleanup);
-	}
-
-cleanup:
-	SrvInitParamClose(pvParamState);
-}
-
-/******************************************************************************
- End of file (htbinit.c)
-*****************************************************************************/
diff --git a/drivers/staging/imgtec/rogue/htbserver.c b/drivers/staging/imgtec/rogue/htbserver.c
index 2eff4ab..a4cc3c4 100644
--- a/drivers/staging/imgtec/rogue/htbserver.c
+++ b/drivers/staging/imgtec/rogue/htbserver.c
@@ -47,12 +47,16 @@
 
 #include "htbserver.h"
 #include "htbuffer.h"
+#include "htbuffer_types.h"
 #include "tlstream.h"
-#include "pvr_tlcommon.h"
+#include "pvrsrv_tlcommon.h"
 #include "img_types.h"
 #include "pvrsrv_error.h"
 #include "osfunc.h"
 #include "allocmem.h"
+#include "pvr_notifier.h"
+#include "pvrsrv.h"
+#include "pvrsrv_apphint.h"
 
 /* size of circular buffer controlling the maximum number of concurrent PIDs logged */
 #define HTB_MAX_NUM_PID 8
@@ -147,8 +151,102 @@
 
 
 /************************************************************************/ /*!
+ @Function      _HTBLogDebugInfo
+ @Description   Debug dump handler used to dump the state of the HTB module.
+                Called for each verbosity level during a debug dump. Function
+                only prints state when called for High verbosity.
+
+ @Input         hDebugRequestHandle See PFN_DBGREQ_NOTIFY
+
+ @Input         ui32VerbLevel       See PFN_DBGREQ_NOTIFY
+
+ @Input         pfnDumpDebugPrintf  See PFN_DBGREQ_NOTIFY
+
+ @Input         pvDumpDebugFile     See PFN_DBGREQ_NOTIFY
+
+*/ /**************************************************************************/
+static void _HTBLogDebugInfo(
+		PVRSRV_DBGREQ_HANDLE hDebugRequestHandle,
+		IMG_UINT32 ui32VerbLevel,
+		DUMPDEBUG_PRINTF_FUNC *pfnDumpDebugPrintf,
+		void *pvDumpDebugFile
+)
+{
+	PVR_UNREFERENCED_PARAMETER(hDebugRequestHandle);
+
+	if (ui32VerbLevel == DEBUG_REQUEST_VERBOSITY_HIGH)
+	{
+
+		if (g_bConfigured)
+		{
+			IMG_INT i;
+
+			PVR_DUMPDEBUG_LOG("------[ HTB Log state: On ]------");
+
+			PVR_DUMPDEBUG_LOG("HTB Log mode: %d", g_sCtrl.eLogMode);
+			PVR_DUMPDEBUG_LOG("HTB Log level: %d", g_sCtrl.ui32LogLevel);
+			PVR_DUMPDEBUG_LOG("HTB Buffer Opmode: %d", g_sCtrl.eOpMode);
+
+			for (i=0; i < HTB_FLAG_NUM_EL; i++)
+			{
+				PVR_DUMPDEBUG_LOG("HTB Log group %d: %x", i, g_auiHTBGroupEnable[i]);
+			}
+		}
+		else
+		{
+			PVR_DUMPDEBUG_LOG("------[ HTB Log state: Off ]------");
+		}
+	}
+}
+
+/************************************************************************/ /*!
+ @Function      HTBDeviceCreate
+ @Description   Initialisation actions for HTB at device creation.
+
+ @Input         psDeviceNode    Reference to the device node in context
+
+ @Return        eError          Internal services call returned eError error
+                                number
+*/ /**************************************************************************/
+PVRSRV_ERROR
+HTBDeviceCreate(
+		PVRSRV_DEVICE_NODE *psDeviceNode
+)
+{
+	PVRSRV_ERROR eError = PVRSRV_OK;
+
+	eError = PVRSRVRegisterDbgRequestNotify(&psDeviceNode->hHtbDbgReqNotify,
+			psDeviceNode, &_HTBLogDebugInfo, DEBUG_REQUEST_HTB, NULL);
+	PVR_LOG_IF_ERROR(eError, "PVRSRVRegisterDbgRequestNotify");
+
+	return eError;
+}
+
+/************************************************************************/ /*!
+ @Function      HTBIDeviceDestroy
+ @Description   De-initialisation actions for HTB at device destruction.
+
+ @Input         psDeviceNode    Reference to the device node in context
+
+*/ /**************************************************************************/
+void
+HTBDeviceDestroy(
+		PVRSRV_DEVICE_NODE *psDeviceNode
+)
+{
+	if (psDeviceNode->hHtbDbgReqNotify)
+	{
+		/* No much we can do if it fails, driver unloading */
+		(void)PVRSRVUnregisterDbgRequestNotify(psDeviceNode->hHtbDbgReqNotify);
+		psDeviceNode->hHtbDbgReqNotify = NULL;
+	}
+}
+
+
+/************************************************************************/ /*!
  @Function      HTBDeInit
- @Description   Close the Host Trace Buffer and free all resources
+ @Description   Close the Host Trace Buffer and free all resources. Must
+                perform a no-op if already de-initialised.
 
  @Return        eError          Internal services call returned eError error
                                 number
@@ -173,6 +271,56 @@
 
 
 /*************************************************************************/ /*!
+ AppHint interface functions
+*/ /**************************************************************************/
+static
+PVRSRV_ERROR _HTBSetLogGroup(const PVRSRV_DEVICE_NODE *psDeviceNode,
+                             const void *psPrivate,
+                             IMG_UINT32 ui32Value)
+{
+	PVR_UNREFERENCED_PARAMETER(psDeviceNode);
+	PVR_UNREFERENCED_PARAMETER(psPrivate);
+
+	return HTBControlKM(1, &ui32Value, 0, 0,
+	                    HTB_LOGMODE_UNDEF, HTB_OPMODE_UNDEF);
+}
+
+static
+PVRSRV_ERROR _HTBReadLogGroup(const PVRSRV_DEVICE_NODE *psDeviceNode,
+                              const void *psPrivate,
+                              IMG_UINT32 *pui32Value)
+{
+	PVR_UNREFERENCED_PARAMETER(psDeviceNode);
+	PVR_UNREFERENCED_PARAMETER(psPrivate);
+
+	*pui32Value = g_auiHTBGroupEnable[0];
+	return PVRSRV_OK;
+}
+
+static
+PVRSRV_ERROR _HTBSetOpMode(const PVRSRV_DEVICE_NODE *psDeviceNode,
+                           const void *psPrivate,
+                           IMG_UINT32 ui32Value)
+{
+	PVR_UNREFERENCED_PARAMETER(psDeviceNode);
+	PVR_UNREFERENCED_PARAMETER(psPrivate);
+
+	return HTBControlKM(0, NULL, 0, 0, HTB_LOGMODE_UNDEF, ui32Value);
+}
+
+static
+PVRSRV_ERROR _HTBReadOpMode(const PVRSRV_DEVICE_NODE *psDeviceNode,
+                            const void *psPrivate,
+                            IMG_UINT32 *pui32Value)
+{
+	PVR_UNREFERENCED_PARAMETER(psDeviceNode);
+	PVR_UNREFERENCED_PARAMETER(psPrivate);
+
+	*pui32Value = (IMG_UINT32)g_sCtrl.eOpMode;
+	return PVRSRV_OK;
+}
+
+/*************************************************************************/ /*!
  @Function      HTBConfigureKM
  @Description   Configure or update the configuration of the Host Trace Buffer
 
@@ -207,6 +355,17 @@
 		g_sCtrl.ui32PIDHead = 0;
 		g_sCtrl.eLogMode = HTB_LOGMODE_ALLPID;
 		g_sCtrl.bLogDropSignalled = IMG_FALSE;
+
+		PVRSRVAppHintRegisterHandlersUINT32(APPHINT_ID_EnableHTBLogGroup,
+		                                    _HTBReadLogGroup,
+		                                    _HTBSetLogGroup,
+		                                    NULL,
+		                                    NULL);
+		PVRSRVAppHintRegisterHandlersUINT32(APPHINT_ID_HTBOperationMode,
+		                                    _HTBReadOpMode,
+		                                    _HTBSetOpMode,
+		                                    NULL,
+		                                    NULL);
 	}
 	else
 	{
@@ -309,7 +468,7 @@
 	/* HTB_LOGMODE_ALLPID overrides ui32EnablePID */
 	if ( HTB_LOGMODE_ALLPID == eLogMode )
 	{
-		OSMemSet(g_sCtrl.aui32EnablePID, 0, sizeof(g_sCtrl.aui32EnablePID));
+		OSCachedMemSet(g_sCtrl.aui32EnablePID, 0, sizeof(g_sCtrl.aui32EnablePID));
 		g_sCtrl.ui32PIDCount = 0;
 		g_sCtrl.ui32PIDHead = 0;
 	}
@@ -365,7 +524,6 @@
 	return eError;
 }
 
-
 /*************************************************************************/ /*!
 */ /**************************************************************************/
 static IMG_BOOL
diff --git a/drivers/staging/imgtec/rogue/htbserver.h b/drivers/staging/imgtec/rogue/htbserver.h
index 1411f4f..670e83a 100644
--- a/drivers/staging/imgtec/rogue/htbserver.h
+++ b/drivers/staging/imgtec/rogue/htbserver.h
@@ -71,10 +71,39 @@
 
 #include "img_types.h"
 #include "pvrsrv_error.h"
+#include "pvrsrv.h"
 #include "htbuffer.h"
 
 
 /************************************************************************/ /*!
+ @Function      HTBIDeviceCreate
+ @Description   Initialisation actions for HTB at device creation.
+
+ @Input         psDeviceNode    Reference to the device node in context
+
+ @Return        eError          Internal services call returned eError error
+                                number
+*/ /**************************************************************************/
+PVRSRV_ERROR
+HTBDeviceCreate(
+		PVRSRV_DEVICE_NODE *psDeviceNode
+);
+
+
+/************************************************************************/ /*!
+ @Function      HTBIDeviceDestroy
+ @Description   De-initialisation actions for HTB at device destruction.
+
+ @Input         psDeviceNode    Reference to the device node in context
+
+*/ /**************************************************************************/
+void
+HTBDeviceDestroy(
+		PVRSRV_DEVICE_NODE *psDeviceNode
+);
+
+
+/************************************************************************/ /*!
  @Function      HTBDeInit
  @Description   Close the Host Trace Buffer and free all resources
 
diff --git a/drivers/staging/imgtec/rogue/htbuffer.c b/drivers/staging/imgtec/rogue/htbuffer.c
index dfe078d..b2f2006 100644
--- a/drivers/staging/imgtec/rogue/htbuffer.c
+++ b/drivers/staging/imgtec/rogue/htbuffer.c
@@ -140,15 +140,11 @@
 static PVRSRV_ERROR
 _HTBLog(IMG_HANDLE hSrvHandle, IMG_UINT32 PID, IMG_UINT32 ui32TimeStampus, HTB_LOG_SFids SF, va_list args)
 {
+#if defined(__KERNEL__)
 	IMG_UINT32 i;
 	IMG_UINT32 ui32NumArgs = HTB_SF_PARAMNUM(SF);
 	IMG_UINT32 aui32Args[HTB_LOG_MAX_PARAMS];
 
-#if !defined(__KERNEL__)
-	PVR_ASSERT(0=="HTB Logging in UM is not yet supported");
-	return PVRSRV_ERROR_NOT_SUPPORTED;
-#endif
-
 	PVR_ASSERT(ui32NumArgs <= HTB_LOG_MAX_PARAMS);
 	ui32NumArgs = (ui32NumArgs>HTB_LOG_MAX_PARAMS)? HTB_LOG_MAX_PARAMS: ui32NumArgs;
 
@@ -159,6 +155,16 @@
 	}
 
 	return BridgeHTBLog(hSrvHandle, PID, ui32TimeStampus, SF, ui32NumArgs, aui32Args);
+#else
+	PVR_UNREFERENCED_PARAMETER(hSrvHandle);
+	PVR_UNREFERENCED_PARAMETER(PID);
+	PVR_UNREFERENCED_PARAMETER(ui32TimeStampus);
+	PVR_UNREFERENCED_PARAMETER(SF);
+	PVR_UNREFERENCED_PARAMETER(args);
+
+	PVR_ASSERT(0=="HTB Logging in UM is not yet supported");
+	return PVRSRV_ERROR_NOT_SUPPORTED;
+#endif
 }
 
 
@@ -182,7 +188,7 @@
 
 */ /**************************************************************************/
 IMG_INTERNAL PVRSRV_ERROR
-HTBLog(IMG_HANDLE hSrvHandle, IMG_UINT32 PID, IMG_UINT32 ui32TimeStampus, HTB_LOG_SFids SF, ...)
+HTBLog(IMG_HANDLE hSrvHandle, IMG_UINT32 PID, IMG_UINT32 ui32TimeStampus, IMG_UINT32 SF, ...)
 {
 	PVRSRV_ERROR eError;
 	va_list args;
@@ -205,7 +211,7 @@
 
 */ /**************************************************************************/
 IMG_INTERNAL PVRSRV_ERROR
-HTBLogSimple(IMG_HANDLE hSrvHandle, HTB_LOG_SFids SF, ...)
+HTBLogSimple(IMG_HANDLE hSrvHandle, IMG_UINT32 SF, ...)
 {
 	PVRSRV_ERROR eError;
 	va_list args;
diff --git a/drivers/staging/imgtec/rogue/htbuffer.h b/drivers/staging/imgtec/rogue/htbuffer.h
index f95c1dd..888a041 100644
--- a/drivers/staging/imgtec/rogue/htbuffer.h
+++ b/drivers/staging/imgtec/rogue/htbuffer.h
@@ -91,7 +91,7 @@
 
 */ /**************************************************************************/
 IMG_INTERNAL PVRSRV_ERROR
-HTBLog(IMG_HANDLE hSrvHandle, IMG_UINT32 PID, IMG_UINT32 ui32TimeStampus, HTB_LOG_SFids SF, ...);
+HTBLog(IMG_HANDLE hSrvHandle, IMG_UINT32 PID, IMG_UINT32 ui32TimeStampus, IMG_UINT32 SF, ...);
 
 
 /*************************************************************************/ /*!
@@ -106,7 +106,7 @@
 
 */ /**************************************************************************/
 IMG_INTERNAL PVRSRV_ERROR
-HTBLogSimple(IMG_HANDLE hSrvHandle, HTB_LOG_SFids SF, ...);
+HTBLogSimple(IMG_HANDLE hSrvHandle, IMG_UINT32 SF, ...);
 
 
 
diff --git a/drivers/staging/imgtec/rogue/htbuffer_sf.h b/drivers/staging/imgtec/rogue/htbuffer_sf.h
index 8c1935e..517c384 100644
--- a/drivers/staging/imgtec/rogue/htbuffer_sf.h
+++ b/drivers/staging/imgtec/rogue/htbuffer_sf.h
@@ -60,10 +60,10 @@
 
 
 /* String used in pvrdebug -h output */
-#define HTB_LOG_GROUPS_STRING_LIST   "ctrl,mmu,sync,main"
+#define HTB_LOG_GROUPS_STRING_LIST   "ctrl,mmu,sync,main,brg"
 
 /* Used in print statements to display log group state, one %s per group defined */
-#define HTB_LOG_ENABLED_GROUPS_LIST_PFSPEC  "%s%s%s%s"
+#define HTB_LOG_ENABLED_GROUPS_LIST_PFSPEC  "%s%s%s%s%s"
 
 /* Available log groups - Master template
  *
@@ -82,6 +82,7 @@
 	X( HTB_GROUP_MMU,      MMU   )                        \
 	X( HTB_GROUP_SYNC,     SYNC  )                        \
 	X( HTB_GROUP_MAIN,     MAIN  )                        \
+	X( HTB_GROUP_BRG,      BRG  )                         \
 /* Debug group HTB_GROUP_DBG must always be last */       \
 	X( HTB_GROUP_DBG,      DBG   )
 
@@ -133,6 +134,9 @@
 X( 7,  HTB_GROUP_MAIN,  HTB_SF_MAIN_KICK_UNCOUNTED,     "Kick (uncounted) for all DMs\n", 0) \
 X( 8,  HTB_GROUP_MAIN,  HTB_SF_MAIN_FWCCB_CMD,          "FW CCB Cmd: %d\n", 1) \
 \
+X( 1,  HTB_GROUP_BRG,   HTB_SF_BRG_BRIDGE_CALL,         "Bridge call: start: %010u: bid %03d fid %d\n", 3) \
+X( 2,  HTB_GROUP_BRG,   HTB_SF_BRG_BRIDGE_CALL_ERR,     "Bridge call: start: %010u: bid %03d fid %d error %d\n", 4) \
+\
 X( 1,  HTB_GROUP_DBG,   HTB_SF_DBG_INTPAIR,             "0x%8.8x 0x%8.8x\n", 2) \
 \
 X( 65535, HTB_GROUP_NONE, HTB_SF_LAST,                  "You should not use this string\n", 15)
diff --git a/drivers/staging/imgtec/rogue/htbuffer_types.h b/drivers/staging/imgtec/rogue/htbuffer_types.h
index 92a824e..c4f19b3 100644
--- a/drivers/staging/imgtec/rogue/htbuffer_types.h
+++ b/drivers/staging/imgtec/rogue/htbuffer_types.h
@@ -60,35 +60,6 @@
 
 #define HTB_GROUP_ENABLED(SF) (g_auiHTBGroupEnable[HTB_LOG_GROUP_FLAG_GROUP(HTB_SF_GID(SF))] & HTB_LOG_GROUP_FLAG(HTB_SF_GID(SF)))
 
-
-
-/**************************************************************************
-from log_helper.h for later
- **************************************************************************/
-#if 0
-#include "htbuffer_sf.h"
-
-static IMG_CHAR *groups[]= {
-#define X(A,B) #B,
-	HTB_LOG_SFGROUPLIST
-#undef X
-};
-
-typedef struct {
-	IMG_UINT32 id;
-	IMG_CHAR *name;
-} tuple; /*  pair of string format id and string formats */
-
-/*  The tuple pairs that will be generated using XMacros will be stored here.
- *   This macro definition must match the definition of SFids in htb_sf.h */
-tuple SFs[]= {
-#define X(a, b, c, d, e) { HTB_LOG_CREATESFID(a,b,e) , d },
-	HTB_LOG_SFIDLIST
-#undef X
-};
-#endif
-
-
 /*************************************************************************/ /*!
  Host Trace Buffer operation mode
  Care must be taken if changing this enum to ensure the MapFlags[] array
diff --git a/drivers/staging/imgtec/rogue/hwdefs/km/configs/rgxconfig_km_4.V.2.52.h b/drivers/staging/imgtec/rogue/hwdefs/km/configs/rgxconfig_km_10.V.2.26.h
similarity index 69%
copy from drivers/staging/imgtec/rogue/hwdefs/km/configs/rgxconfig_km_4.V.2.52.h
copy to drivers/staging/imgtec/rogue/hwdefs/km/configs/rgxconfig_km_10.V.2.26.h
index 0462d6f..89c2e94 100644
--- a/drivers/staging/imgtec/rogue/hwdefs/km/configs/rgxconfig_km_4.V.2.52.h
+++ b/drivers/staging/imgtec/rogue/hwdefs/km/configs/rgxconfig_km_10.V.2.26.h
@@ -1,5 +1,5 @@
 /*************************************************************************/ /*!
-@Title          RGX Config BVNC 4.V.2.52
+@Title          RGX Config BVNC 10.V.2.26
 @Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
 @License        Dual MIT/GPLv2
 
@@ -39,41 +39,60 @@
 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */ /**************************************************************************/
 
-#ifndef _RGXCONFIG_KM_4_V_2_52_H_
-#define _RGXCONFIG_KM_4_V_2_52_H_
+#ifndef _RGXCONFIG_KM_10_V_2_26_H_
+#define _RGXCONFIG_KM_10_V_2_26_H_
 
-/***** Automatically generated file (22/02/2016 07:00:34): Do not edit manually ********************/
-/***** Timestamp:  (22/02/2016 07:00:34)************************************************************/
+/***** Automatically generated file (11/04/2017 07:00:42): Do not edit manually ********************/
+/***** Timestamp:  (11/04/2017 07:00:42)************************************************************/
 
-#define RGX_BNC_KM_B 4
+#define RGX_BNC_KM_B 10
 #define RGX_BNC_KM_N 2
-#define RGX_BNC_KM_C 52
+#define RGX_BNC_KM_C 26
 
 /******************************************************************************
  * DDK Defines
  *****************************************************************************/
-#define RGX_FEATURE_NUM_CLUSTERS (2)
-#define RGX_FEATURE_SLC_SIZE_IN_BYTES (128*1024)
-#define RGX_FEATURE_PHYS_BUS_WIDTH (40)
-#define RGX_FEATURE_PERFBUS 
 #define RGX_FEATURE_AXI_ACELITE 
-#define RGX_FEATURE_CLUSTER_GROUPING 
-#define RGX_FEATURE_SLC_CACHE_LINE_SIZE_BITS (512)
-#define RGX_FEATURE_DYNAMIC_DUST_POWER 
+#define RGX_FEATURE_PHYS_BUS_WIDTH (40)
 #define RGX_FEATURE_VIRTUAL_ADDRESS_SPACE_BITS (40)
-#define RGX_FEATURE_TLA 
+#define RGX_FEATURE_PERFBUS 
 #define RGX_FEATURE_GS_RTA_SUPPORT 
-#define RGX_FEATURE_TPU_CEM_DATAMASTER_GLOBAL_REGISTERS 
-#define RGX_FEATURE_NUM_ISP_IPP_PIPES (8)
-#define RGX_FEATURE_META (LTP218)
-#define RGX_FEATURE_TPU_FILTERING_MODE_CONTROL 
-#define RGX_FEATURE_XT_TOP_INFRASTRUCTURE 
-#define RGX_FEATURE_COMPUTE_MORTON_CAPABLE 
-#define RGX_FEATURE_FBCDC_ARCHITECTURE (2)
-#define RGX_FEATURE_GPU_VIRTUALISATION 
-#define RGX_FEATURE_META_COREMEM_SIZE (32)
 #define RGX_FEATURE_COMPUTE 
+#define RGX_FEATURE_COMPUTE_MORTON_CAPABLE 
 #define RGX_FEATURE_COMPUTE_OVERLAP 
+#define RGX_FEATURE_TPU_FILTERING_MODE_CONTROL 
+#define RGX_FEATURE_TPU_CEM_DATAMASTER_GLOBAL_REGISTERS 
+#define RGX_FEATURE_SCALABLE_VDM_GPP 
+#define RGX_FEATURE_VDM_DRAWINDIRECT 
+#define RGX_FEATURE_SLC_VIVT 
+#define RGX_FEATURE_VDM_OBJECT_LEVEL_LLS 
+#define RGX_FEATURE_PDS_PER_DUST 
+#define RGX_FEATURE_META (MTP219)
+#define RGX_FEATURE_COMPUTE_OVERLAP_WITH_BARRIERS 
+#define RGX_FEATURE_TESSELLATION 
+#define RGX_FEATURE_TPU_DM_GLOBAL_REGISTERS 
+#define RGX_FEATURE_PDS_TEMPSIZE8 
+#define RGX_FEATURE_META_DMA 
+#define RGX_FEATURE_META_DMA_CHANNEL_COUNT (4)
+#define RGX_FEATURE_META_COREMEM_BANKS (8)
+#define RGX_FEATURE_META_COREMEM_SIZE (256)
+#define RGX_FEATURE_FBCDC_ARCHITECTURE (3)
+#define RGX_FEATURE_SLC_CACHE_LINE_SIZE_BITS (512)
+#define RGX_FEATURE_GPU_VIRTUALISATION 
+#define RGX_FEATURE_SLC_HYBRID_CACHELINE_64_128 
+#define RGX_FEATURE_FASTRENDER_DM 
+#define RGX_FEATURE_CDM_CONTROL_STREAM_FORMAT (2)
+#define RGX_FEATURE_SIGNAL_SNOOPING 
+#define RGX_FEATURE_SYS_BUS_SECURE_RESET 
+#define RGX_FEATURE_NUM_CLUSTERS (2)
+#define RGX_FEATURE_NUM_ISP_IPP_PIPES (8)
+#define RGX_FEATURE_SLC_SIZE_IN_KILOBYTES (128)
+#define RGX_FEATURE_SLC_BANKS (2)
+#define RGX_FEATURE_SCALABLE_TE_ARCH (1)
+#define RGX_FEATURE_SCALABLE_VCE (1)
+#define RGX_FEATURE_S7_CACHE_HIERARCHY 
+#define RGX_FEATURE_S7_TOP_INFRASTRUCTURE 
+#define RGX_FEATURE_CLUSTER_GROUPING 
 
 
-#endif /* _RGXCONFIG_4_V_2_52_H_ */
+#endif /* _RGXCONFIG_10_V_2_26_H_ */
diff --git a/drivers/staging/imgtec/rogue/hwdefs/km/configs/rgxconfig_km_4.V.2.52.h b/drivers/staging/imgtec/rogue/hwdefs/km/configs/rgxconfig_km_10.V.4.25.h
similarity index 68%
copy from drivers/staging/imgtec/rogue/hwdefs/km/configs/rgxconfig_km_4.V.2.52.h
copy to drivers/staging/imgtec/rogue/hwdefs/km/configs/rgxconfig_km_10.V.4.25.h
index 0462d6f..dd86af6 100644
--- a/drivers/staging/imgtec/rogue/hwdefs/km/configs/rgxconfig_km_4.V.2.52.h
+++ b/drivers/staging/imgtec/rogue/hwdefs/km/configs/rgxconfig_km_10.V.4.25.h
@@ -1,5 +1,5 @@
 /*************************************************************************/ /*!
-@Title          RGX Config BVNC 4.V.2.52
+@Title          RGX Config BVNC 10.V.4.25
 @Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
 @License        Dual MIT/GPLv2
 
@@ -39,41 +39,60 @@
 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */ /**************************************************************************/
 
-#ifndef _RGXCONFIG_KM_4_V_2_52_H_
-#define _RGXCONFIG_KM_4_V_2_52_H_
+#ifndef _RGXCONFIG_KM_10_V_4_25_H_
+#define _RGXCONFIG_KM_10_V_4_25_H_
 
-/***** Automatically generated file (22/02/2016 07:00:34): Do not edit manually ********************/
-/***** Timestamp:  (22/02/2016 07:00:34)************************************************************/
+/***** Automatically generated file (11/04/2017 07:00:43): Do not edit manually ********************/
+/***** Timestamp:  (11/04/2017 07:00:43)************************************************************/
 
-#define RGX_BNC_KM_B 4
-#define RGX_BNC_KM_N 2
-#define RGX_BNC_KM_C 52
+#define RGX_BNC_KM_B 10
+#define RGX_BNC_KM_N 4
+#define RGX_BNC_KM_C 25
 
 /******************************************************************************
  * DDK Defines
  *****************************************************************************/
-#define RGX_FEATURE_NUM_CLUSTERS (2)
-#define RGX_FEATURE_SLC_SIZE_IN_BYTES (128*1024)
-#define RGX_FEATURE_PHYS_BUS_WIDTH (40)
-#define RGX_FEATURE_PERFBUS 
 #define RGX_FEATURE_AXI_ACELITE 
-#define RGX_FEATURE_CLUSTER_GROUPING 
-#define RGX_FEATURE_SLC_CACHE_LINE_SIZE_BITS (512)
-#define RGX_FEATURE_DYNAMIC_DUST_POWER 
+#define RGX_FEATURE_PHYS_BUS_WIDTH (40)
 #define RGX_FEATURE_VIRTUAL_ADDRESS_SPACE_BITS (40)
-#define RGX_FEATURE_TLA 
+#define RGX_FEATURE_PERFBUS 
 #define RGX_FEATURE_GS_RTA_SUPPORT 
-#define RGX_FEATURE_TPU_CEM_DATAMASTER_GLOBAL_REGISTERS 
-#define RGX_FEATURE_NUM_ISP_IPP_PIPES (8)
-#define RGX_FEATURE_META (LTP218)
-#define RGX_FEATURE_TPU_FILTERING_MODE_CONTROL 
-#define RGX_FEATURE_XT_TOP_INFRASTRUCTURE 
-#define RGX_FEATURE_COMPUTE_MORTON_CAPABLE 
-#define RGX_FEATURE_FBCDC_ARCHITECTURE (2)
-#define RGX_FEATURE_GPU_VIRTUALISATION 
-#define RGX_FEATURE_META_COREMEM_SIZE (32)
 #define RGX_FEATURE_COMPUTE 
+#define RGX_FEATURE_COMPUTE_MORTON_CAPABLE 
 #define RGX_FEATURE_COMPUTE_OVERLAP 
+#define RGX_FEATURE_TPU_FILTERING_MODE_CONTROL 
+#define RGX_FEATURE_TPU_CEM_DATAMASTER_GLOBAL_REGISTERS 
+#define RGX_FEATURE_SCALABLE_VDM_GPP 
+#define RGX_FEATURE_VDM_DRAWINDIRECT 
+#define RGX_FEATURE_SLC_VIVT 
+#define RGX_FEATURE_VDM_OBJECT_LEVEL_LLS 
+#define RGX_FEATURE_PDS_PER_DUST 
+#define RGX_FEATURE_META (MTP219)
+#define RGX_FEATURE_COMPUTE_OVERLAP_WITH_BARRIERS 
+#define RGX_FEATURE_TESSELLATION 
+#define RGX_FEATURE_TPU_DM_GLOBAL_REGISTERS 
+#define RGX_FEATURE_PDS_TEMPSIZE8 
+#define RGX_FEATURE_META_DMA 
+#define RGX_FEATURE_META_DMA_CHANNEL_COUNT (4)
+#define RGX_FEATURE_META_COREMEM_BANKS (8)
+#define RGX_FEATURE_META_COREMEM_SIZE (256)
+#define RGX_FEATURE_FBCDC_ARCHITECTURE (3)
+#define RGX_FEATURE_SLC_CACHE_LINE_SIZE_BITS (512)
+#define RGX_FEATURE_GPU_VIRTUALISATION 
+#define RGX_FEATURE_SLC_HYBRID_CACHELINE_64_128 
+#define RGX_FEATURE_FASTRENDER_DM 
+#define RGX_FEATURE_CDM_CONTROL_STREAM_FORMAT (2)
+#define RGX_FEATURE_SIGNAL_SNOOPING 
+#define RGX_FEATURE_SYS_BUS_SECURE_RESET 
+#define RGX_FEATURE_NUM_CLUSTERS (4)
+#define RGX_FEATURE_NUM_ISP_IPP_PIPES (8)
+#define RGX_FEATURE_SLC_SIZE_IN_KILOBYTES (512)
+#define RGX_FEATURE_SLC_BANKS (4)
+#define RGX_FEATURE_SCALABLE_TE_ARCH (1)
+#define RGX_FEATURE_SCALABLE_VCE (1)
+#define RGX_FEATURE_S7_CACHE_HIERARCHY 
+#define RGX_FEATURE_S7_TOP_INFRASTRUCTURE 
+#define RGX_FEATURE_CLUSTER_GROUPING 
 
 
-#endif /* _RGXCONFIG_4_V_2_52_H_ */
+#endif /* _RGXCONFIG_10_V_4_25_H_ */
diff --git a/drivers/staging/imgtec/rogue/hwdefs/km/configs/rgxconfig_km_12.V.1.20.h b/drivers/staging/imgtec/rogue/hwdefs/km/configs/rgxconfig_km_12.V.1.20.h
index 1e18cab..5566126 100644
--- a/drivers/staging/imgtec/rogue/hwdefs/km/configs/rgxconfig_km_12.V.1.20.h
+++ b/drivers/staging/imgtec/rogue/hwdefs/km/configs/rgxconfig_km_12.V.1.20.h
@@ -42,8 +42,8 @@
 #ifndef _RGXCONFIG_KM_12_V_1_20_H_
 #define _RGXCONFIG_KM_12_V_1_20_H_
 
-/***** Automatically generated file (5/12/2015 8:14:27 AM): Do not edit manually ********************/
-/***** Timestamp:  (5/12/2015 8:14:27 AM)************************************************************/
+/***** Automatically generated file (24/08/2016 07:01:08): Do not edit manually ********************/
+/***** Timestamp:  (24/08/2016 07:01:08)************************************************************/
 
 #define RGX_BNC_KM_B 12
 #define RGX_BNC_KM_N 1
@@ -62,6 +62,7 @@
 #define RGX_FEATURE_SLC_SIZE_IN_BYTES (0*1024)
 #define RGX_FEATURE_META_COREMEM_SIZE (0)
 #define RGX_FEATURE_COMPUTE 
+#define RGX_FEATURE_ROGUEXE 
 
 
 #endif /* _RGXCONFIG_12_V_1_20_H_ */
diff --git a/drivers/staging/imgtec/rogue/hwdefs/km/configs/rgxconfig_km_12.V.1.48.h b/drivers/staging/imgtec/rogue/hwdefs/km/configs/rgxconfig_km_12.V.1.48.h
index 3853bff..375f8f6 100644
--- a/drivers/staging/imgtec/rogue/hwdefs/km/configs/rgxconfig_km_12.V.1.48.h
+++ b/drivers/staging/imgtec/rogue/hwdefs/km/configs/rgxconfig_km_12.V.1.48.h
@@ -42,8 +42,8 @@
 #ifndef _RGXCONFIG_KM_12_V_1_48_H_
 #define _RGXCONFIG_KM_12_V_1_48_H_
 
-/***** Automatically generated file (5/12/2015 8:14:26 AM): Do not edit manually ********************/
-/***** Timestamp:  (5/12/2015 8:14:26 AM)************************************************************/
+/***** Automatically generated file (24/08/2016 07:01:08): Do not edit manually ********************/
+/***** Timestamp:  (24/08/2016 07:01:08)************************************************************/
 
 #define RGX_BNC_KM_B 12
 #define RGX_BNC_KM_N 1
@@ -63,6 +63,7 @@
 #define RGX_FEATURE_FBCDC_ARCHITECTURE (1)
 #define RGX_FEATURE_META_COREMEM_SIZE (0)
 #define RGX_FEATURE_COMPUTE 
+#define RGX_FEATURE_ROGUEXE 
 
 
 #endif /* _RGXCONFIG_12_V_1_48_H_ */
diff --git a/drivers/staging/imgtec/rogue/hwdefs/km/configs/rgxconfig_km_15.V.1.64.h b/drivers/staging/imgtec/rogue/hwdefs/km/configs/rgxconfig_km_15.V.1.64.h
index 5685f72..2846583 100644
--- a/drivers/staging/imgtec/rogue/hwdefs/km/configs/rgxconfig_km_15.V.1.64.h
+++ b/drivers/staging/imgtec/rogue/hwdefs/km/configs/rgxconfig_km_15.V.1.64.h
@@ -42,8 +42,8 @@
 #ifndef _RGXCONFIG_KM_15_V_1_64_H_
 #define _RGXCONFIG_KM_15_V_1_64_H_
 
-/***** Automatically generated file (23/07/2015 12:44:38): Do not edit manually ********************/
-/***** Timestamp:  (23/07/2015 12:44:38)************************************************************/
+/***** Automatically generated file (24/08/2016 07:01:09): Do not edit manually ********************/
+/***** Timestamp:  (24/08/2016 07:01:09)************************************************************/
 
 #define RGX_BNC_KM_B 15
 #define RGX_BNC_KM_N 1
@@ -68,6 +68,7 @@
 #define RGX_FEATURE_SLC_SIZE_IN_BYTES (64*1024)
 #define RGX_FEATURE_META_COREMEM_SIZE (0)
 #define RGX_FEATURE_COMPUTE 
+#define RGX_FEATURE_ROGUEXE 
 
 
 #endif /* _RGXCONFIG_15_V_1_64_H_ */
diff --git a/drivers/staging/imgtec/rogue/hwdefs/km/configs/rgxconfig_km_4.V.2.52.h b/drivers/staging/imgtec/rogue/hwdefs/km/configs/rgxconfig_km_22.V.208.312.h
similarity index 74%
copy from drivers/staging/imgtec/rogue/hwdefs/km/configs/rgxconfig_km_4.V.2.52.h
copy to drivers/staging/imgtec/rogue/hwdefs/km/configs/rgxconfig_km_22.V.208.312.h
index 0462d6f..6ca1c46 100644
--- a/drivers/staging/imgtec/rogue/hwdefs/km/configs/rgxconfig_km_4.V.2.52.h
+++ b/drivers/staging/imgtec/rogue/hwdefs/km/configs/rgxconfig_km_22.V.208.312.h
@@ -1,5 +1,5 @@
 /*************************************************************************/ /*!
-@Title          RGX Config BVNC 4.V.2.52
+@Title          RGX Config BVNC 22.V.208.312
 @Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
 @License        Dual MIT/GPLv2
 
@@ -39,41 +39,37 @@
 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */ /**************************************************************************/
 
-#ifndef _RGXCONFIG_KM_4_V_2_52_H_
-#define _RGXCONFIG_KM_4_V_2_52_H_
+#ifndef _RGXCONFIG_KM_22_V_208_312_H_
+#define _RGXCONFIG_KM_22_V_208_312_H_
 
-/***** Automatically generated file (22/02/2016 07:00:34): Do not edit manually ********************/
-/***** Timestamp:  (22/02/2016 07:00:34)************************************************************/
+/***** Automatically generated file (26/08/2016 07:00:44): Do not edit manually ********************/
+/***** Timestamp:  (26/08/2016 07:00:44)************************************************************/
 
-#define RGX_BNC_KM_B 4
-#define RGX_BNC_KM_N 2
-#define RGX_BNC_KM_C 52
+#define RGX_BNC_KM_B 22
+#define RGX_BNC_KM_N 208
+#define RGX_BNC_KM_C 312
 
 /******************************************************************************
  * DDK Defines
  *****************************************************************************/
 #define RGX_FEATURE_NUM_CLUSTERS (2)
-#define RGX_FEATURE_SLC_SIZE_IN_BYTES (128*1024)
-#define RGX_FEATURE_PHYS_BUS_WIDTH (40)
+#define RGX_FEATURE_PHYS_BUS_WIDTH (32)
 #define RGX_FEATURE_PERFBUS 
 #define RGX_FEATURE_AXI_ACELITE 
-#define RGX_FEATURE_CLUSTER_GROUPING 
 #define RGX_FEATURE_SLC_CACHE_LINE_SIZE_BITS (512)
-#define RGX_FEATURE_DYNAMIC_DUST_POWER 
 #define RGX_FEATURE_VIRTUAL_ADDRESS_SPACE_BITS (40)
-#define RGX_FEATURE_TLA 
 #define RGX_FEATURE_GS_RTA_SUPPORT 
-#define RGX_FEATURE_TPU_CEM_DATAMASTER_GLOBAL_REGISTERS 
-#define RGX_FEATURE_NUM_ISP_IPP_PIPES (8)
-#define RGX_FEATURE_META (LTP218)
-#define RGX_FEATURE_TPU_FILTERING_MODE_CONTROL 
-#define RGX_FEATURE_XT_TOP_INFRASTRUCTURE 
-#define RGX_FEATURE_COMPUTE_MORTON_CAPABLE 
-#define RGX_FEATURE_FBCDC_ARCHITECTURE (2)
+#define RGX_FEATURE_NUM_ISP_IPP_PIPES (4)
+#define RGX_FEATURE_FBCDC_ARCHITECTURE (1)
 #define RGX_FEATURE_GPU_VIRTUALISATION 
-#define RGX_FEATURE_META_COREMEM_SIZE (32)
+#define RGX_FEATURE_SLC_SIZE_IN_BYTES (64*1024)
 #define RGX_FEATURE_COMPUTE 
-#define RGX_FEATURE_COMPUTE_OVERLAP 
+#define RGX_FEATURE_SINGLE_BIF 
+#define RGX_FEATURE_PBE2_IN_XE 
+#define RGX_FEATURE_MIPS 
+#define RGX_FEATURE_PBVNC_COREID_REG 
+#define RGX_FEATURE_SYS_BUS_SECURE_RESET 
+#define RGX_FEATURE_ROGUEXE 
 
 
-#endif /* _RGXCONFIG_4_V_2_52_H_ */
+#endif /* _RGXCONFIG_22_V_208_312_H_ */
diff --git a/drivers/staging/imgtec/rogue/hwdefs/km/configs/rgxconfig_km_4.V.2.52.h b/drivers/staging/imgtec/rogue/hwdefs/km/configs/rgxconfig_km_22.V.208.316.h
similarity index 74%
copy from drivers/staging/imgtec/rogue/hwdefs/km/configs/rgxconfig_km_4.V.2.52.h
copy to drivers/staging/imgtec/rogue/hwdefs/km/configs/rgxconfig_km_22.V.208.316.h
index 0462d6f..2150e11 100644
--- a/drivers/staging/imgtec/rogue/hwdefs/km/configs/rgxconfig_km_4.V.2.52.h
+++ b/drivers/staging/imgtec/rogue/hwdefs/km/configs/rgxconfig_km_22.V.208.316.h
@@ -1,5 +1,5 @@
 /*************************************************************************/ /*!
-@Title          RGX Config BVNC 4.V.2.52
+@Title          RGX Config BVNC 22.V.208.316
 @Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
 @License        Dual MIT/GPLv2
 
@@ -39,41 +39,37 @@
 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */ /**************************************************************************/
 
-#ifndef _RGXCONFIG_KM_4_V_2_52_H_
-#define _RGXCONFIG_KM_4_V_2_52_H_
+#ifndef _RGXCONFIG_KM_22_V_208_316_H_
+#define _RGXCONFIG_KM_22_V_208_316_H_
 
-/***** Automatically generated file (22/02/2016 07:00:34): Do not edit manually ********************/
-/***** Timestamp:  (22/02/2016 07:00:34)************************************************************/
+/***** Automatically generated file (17/01/2017 07:00:49): Do not edit manually ********************/
+/***** Timestamp:  (17/01/2017 07:00:49)************************************************************/
 
-#define RGX_BNC_KM_B 4
-#define RGX_BNC_KM_N 2
-#define RGX_BNC_KM_C 52
+#define RGX_BNC_KM_B 22
+#define RGX_BNC_KM_N 208
+#define RGX_BNC_KM_C 316
 
 /******************************************************************************
  * DDK Defines
  *****************************************************************************/
 #define RGX_FEATURE_NUM_CLUSTERS (2)
-#define RGX_FEATURE_SLC_SIZE_IN_BYTES (128*1024)
-#define RGX_FEATURE_PHYS_BUS_WIDTH (40)
+#define RGX_FEATURE_PHYS_BUS_WIDTH (32)
 #define RGX_FEATURE_PERFBUS 
 #define RGX_FEATURE_AXI_ACELITE 
-#define RGX_FEATURE_CLUSTER_GROUPING 
 #define RGX_FEATURE_SLC_CACHE_LINE_SIZE_BITS (512)
-#define RGX_FEATURE_DYNAMIC_DUST_POWER 
 #define RGX_FEATURE_VIRTUAL_ADDRESS_SPACE_BITS (40)
-#define RGX_FEATURE_TLA 
 #define RGX_FEATURE_GS_RTA_SUPPORT 
-#define RGX_FEATURE_TPU_CEM_DATAMASTER_GLOBAL_REGISTERS 
-#define RGX_FEATURE_NUM_ISP_IPP_PIPES (8)
-#define RGX_FEATURE_META (LTP218)
-#define RGX_FEATURE_TPU_FILTERING_MODE_CONTROL 
-#define RGX_FEATURE_XT_TOP_INFRASTRUCTURE 
-#define RGX_FEATURE_COMPUTE_MORTON_CAPABLE 
-#define RGX_FEATURE_FBCDC_ARCHITECTURE (2)
+#define RGX_FEATURE_NUM_ISP_IPP_PIPES (12)
+#define RGX_FEATURE_FBCDC_ARCHITECTURE (1)
 #define RGX_FEATURE_GPU_VIRTUALISATION 
-#define RGX_FEATURE_META_COREMEM_SIZE (32)
+#define RGX_FEATURE_SLC_SIZE_IN_BYTES (64*1024)
 #define RGX_FEATURE_COMPUTE 
-#define RGX_FEATURE_COMPUTE_OVERLAP 
+#define RGX_FEATURE_SINGLE_BIF 
+#define RGX_FEATURE_PBE2_IN_XE 
+#define RGX_FEATURE_MIPS 
+#define RGX_FEATURE_PBVNC_COREID_REG 
+#define RGX_FEATURE_SYS_BUS_SECURE_RESET 
+#define RGX_FEATURE_ROGUEXE 
 
 
-#endif /* _RGXCONFIG_4_V_2_52_H_ */
+#endif /* _RGXCONFIG_22_V_208_316_H_ */
diff --git a/drivers/staging/imgtec/rogue/hwdefs/km/configs/rgxconfig_km_4.V.2.52.h b/drivers/staging/imgtec/rogue/hwdefs/km/configs/rgxconfig_km_22.V.21.11.h
similarity index 73%
copy from drivers/staging/imgtec/rogue/hwdefs/km/configs/rgxconfig_km_4.V.2.52.h
copy to drivers/staging/imgtec/rogue/hwdefs/km/configs/rgxconfig_km_22.V.21.11.h
index 0462d6f..b8ad5c3c 100644
--- a/drivers/staging/imgtec/rogue/hwdefs/km/configs/rgxconfig_km_4.V.2.52.h
+++ b/drivers/staging/imgtec/rogue/hwdefs/km/configs/rgxconfig_km_22.V.21.11.h
@@ -1,5 +1,5 @@
 /*************************************************************************/ /*!
-@Title          RGX Config BVNC 4.V.2.52
+@Title          RGX Config BVNC 22.V.21.11
 @Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
 @License        Dual MIT/GPLv2
 
@@ -39,41 +39,37 @@
 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */ /**************************************************************************/
 
-#ifndef _RGXCONFIG_KM_4_V_2_52_H_
-#define _RGXCONFIG_KM_4_V_2_52_H_
+#ifndef _RGXCONFIG_KM_22_V_21_11_H_
+#define _RGXCONFIG_KM_22_V_21_11_H_
 
-/***** Automatically generated file (22/02/2016 07:00:34): Do not edit manually ********************/
-/***** Timestamp:  (22/02/2016 07:00:34)************************************************************/
+/***** Automatically generated file (14/11/2016 07:00:35): Do not edit manually ********************/
+/***** Timestamp:  (14/11/2016 07:00:35)************************************************************/
 
-#define RGX_BNC_KM_B 4
-#define RGX_BNC_KM_N 2
-#define RGX_BNC_KM_C 52
+#define RGX_BNC_KM_B 22
+#define RGX_BNC_KM_N 21
+#define RGX_BNC_KM_C 11
 
 /******************************************************************************
  * DDK Defines
  *****************************************************************************/
-#define RGX_FEATURE_NUM_CLUSTERS (2)
-#define RGX_FEATURE_SLC_SIZE_IN_BYTES (128*1024)
-#define RGX_FEATURE_PHYS_BUS_WIDTH (40)
+#define RGX_FEATURE_PHYS_BUS_WIDTH (32)
 #define RGX_FEATURE_PERFBUS 
 #define RGX_FEATURE_AXI_ACELITE 
-#define RGX_FEATURE_CLUSTER_GROUPING 
 #define RGX_FEATURE_SLC_CACHE_LINE_SIZE_BITS (512)
-#define RGX_FEATURE_DYNAMIC_DUST_POWER 
+#define RGX_FEATURE_NUM_CLUSTERS (1)
 #define RGX_FEATURE_VIRTUAL_ADDRESS_SPACE_BITS (40)
-#define RGX_FEATURE_TLA 
+#define RGX_FEATURE_SLC_BANKS (1)
 #define RGX_FEATURE_GS_RTA_SUPPORT 
-#define RGX_FEATURE_TPU_CEM_DATAMASTER_GLOBAL_REGISTERS 
-#define RGX_FEATURE_NUM_ISP_IPP_PIPES (8)
-#define RGX_FEATURE_META (LTP218)
-#define RGX_FEATURE_TPU_FILTERING_MODE_CONTROL 
-#define RGX_FEATURE_XT_TOP_INFRASTRUCTURE 
-#define RGX_FEATURE_COMPUTE_MORTON_CAPABLE 
-#define RGX_FEATURE_FBCDC_ARCHITECTURE (2)
+#define RGX_FEATURE_NUM_ISP_IPP_PIPES (1)
 #define RGX_FEATURE_GPU_VIRTUALISATION 
-#define RGX_FEATURE_META_COREMEM_SIZE (32)
 #define RGX_FEATURE_COMPUTE 
-#define RGX_FEATURE_COMPUTE_OVERLAP 
+#define RGX_FEATURE_SINGLE_BIF 
+#define RGX_FEATURE_PBE2_IN_XE 
+#define RGX_FEATURE_MIPS 
+#define RGX_FEATURE_SLCSIZE8 
+#define RGX_FEATURE_PBVNC_COREID_REG 
+#define RGX_FEATURE_SYS_BUS_SECURE_RESET 
+#define RGX_FEATURE_ROGUEXE 
 
 
-#endif /* _RGXCONFIG_4_V_2_52_H_ */
+#endif /* _RGXCONFIG_22_V_21_11_H_ */
diff --git a/drivers/staging/imgtec/rogue/hwdefs/km/configs/rgxconfig_km_4.V.2.52.h b/drivers/staging/imgtec/rogue/hwdefs/km/configs/rgxconfig_km_22.V.21.16.h
similarity index 73%
copy from drivers/staging/imgtec/rogue/hwdefs/km/configs/rgxconfig_km_4.V.2.52.h
copy to drivers/staging/imgtec/rogue/hwdefs/km/configs/rgxconfig_km_22.V.21.16.h
index 0462d6f..5292f59 100644
--- a/drivers/staging/imgtec/rogue/hwdefs/km/configs/rgxconfig_km_4.V.2.52.h
+++ b/drivers/staging/imgtec/rogue/hwdefs/km/configs/rgxconfig_km_22.V.21.16.h
@@ -1,5 +1,5 @@
 /*************************************************************************/ /*!
-@Title          RGX Config BVNC 4.V.2.52
+@Title          RGX Config BVNC 22.V.21.16
 @Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
 @License        Dual MIT/GPLv2
 
@@ -39,41 +39,37 @@
 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */ /**************************************************************************/
 
-#ifndef _RGXCONFIG_KM_4_V_2_52_H_
-#define _RGXCONFIG_KM_4_V_2_52_H_
+#ifndef _RGXCONFIG_KM_22_V_21_16_H_
+#define _RGXCONFIG_KM_22_V_21_16_H_
 
-/***** Automatically generated file (22/02/2016 07:00:34): Do not edit manually ********************/
-/***** Timestamp:  (22/02/2016 07:00:34)************************************************************/
+/***** Automatically generated file (08/02/2017 07:00:50): Do not edit manually ********************/
+/***** Timestamp:  (08/02/2017 07:00:50)************************************************************/
 
-#define RGX_BNC_KM_B 4
-#define RGX_BNC_KM_N 2
-#define RGX_BNC_KM_C 52
+#define RGX_BNC_KM_B 22
+#define RGX_BNC_KM_N 21
+#define RGX_BNC_KM_C 16
 
 /******************************************************************************
  * DDK Defines
  *****************************************************************************/
-#define RGX_FEATURE_NUM_CLUSTERS (2)
-#define RGX_FEATURE_SLC_SIZE_IN_BYTES (128*1024)
-#define RGX_FEATURE_PHYS_BUS_WIDTH (40)
+#define RGX_FEATURE_PHYS_BUS_WIDTH (32)
 #define RGX_FEATURE_PERFBUS 
 #define RGX_FEATURE_AXI_ACELITE 
-#define RGX_FEATURE_CLUSTER_GROUPING 
 #define RGX_FEATURE_SLC_CACHE_LINE_SIZE_BITS (512)
-#define RGX_FEATURE_DYNAMIC_DUST_POWER 
+#define RGX_FEATURE_NUM_CLUSTERS (1)
 #define RGX_FEATURE_VIRTUAL_ADDRESS_SPACE_BITS (40)
-#define RGX_FEATURE_TLA 
+#define RGX_FEATURE_SLC_BANKS (1)
 #define RGX_FEATURE_GS_RTA_SUPPORT 
-#define RGX_FEATURE_TPU_CEM_DATAMASTER_GLOBAL_REGISTERS 
-#define RGX_FEATURE_NUM_ISP_IPP_PIPES (8)
-#define RGX_FEATURE_META (LTP218)
-#define RGX_FEATURE_TPU_FILTERING_MODE_CONTROL 
-#define RGX_FEATURE_XT_TOP_INFRASTRUCTURE 
-#define RGX_FEATURE_COMPUTE_MORTON_CAPABLE 
-#define RGX_FEATURE_FBCDC_ARCHITECTURE (2)
+#define RGX_FEATURE_NUM_ISP_IPP_PIPES (2)
 #define RGX_FEATURE_GPU_VIRTUALISATION 
-#define RGX_FEATURE_META_COREMEM_SIZE (32)
 #define RGX_FEATURE_COMPUTE 
-#define RGX_FEATURE_COMPUTE_OVERLAP 
+#define RGX_FEATURE_SINGLE_BIF 
+#define RGX_FEATURE_PBE2_IN_XE 
+#define RGX_FEATURE_MIPS 
+#define RGX_FEATURE_SLCSIZE8 
+#define RGX_FEATURE_PBVNC_COREID_REG 
+#define RGX_FEATURE_SYS_BUS_SECURE_RESET 
+#define RGX_FEATURE_ROGUEXE 
 
 
-#endif /* _RGXCONFIG_4_V_2_52_H_ */
+#endif /* _RGXCONFIG_22_V_21_16_H_ */
diff --git a/drivers/staging/imgtec/rogue/hwdefs/km/configs/rgxconfig_km_4.V.2.52.h b/drivers/staging/imgtec/rogue/hwdefs/km/configs/rgxconfig_km_22.V.22.22.h
similarity index 73%
copy from drivers/staging/imgtec/rogue/hwdefs/km/configs/rgxconfig_km_4.V.2.52.h
copy to drivers/staging/imgtec/rogue/hwdefs/km/configs/rgxconfig_km_22.V.22.22.h
index 0462d6f..655b096 100644
--- a/drivers/staging/imgtec/rogue/hwdefs/km/configs/rgxconfig_km_4.V.2.52.h
+++ b/drivers/staging/imgtec/rogue/hwdefs/km/configs/rgxconfig_km_22.V.22.22.h
@@ -1,5 +1,5 @@
 /*************************************************************************/ /*!
-@Title          RGX Config BVNC 4.V.2.52
+@Title          RGX Config BVNC 22.V.22.22
 @Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
 @License        Dual MIT/GPLv2
 
@@ -39,41 +39,36 @@
 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */ /**************************************************************************/
 
-#ifndef _RGXCONFIG_KM_4_V_2_52_H_
-#define _RGXCONFIG_KM_4_V_2_52_H_
+#ifndef _RGXCONFIG_KM_22_V_22_22_H_
+#define _RGXCONFIG_KM_22_V_22_22_H_
 
-/***** Automatically generated file (22/02/2016 07:00:34): Do not edit manually ********************/
-/***** Timestamp:  (22/02/2016 07:00:34)************************************************************/
+/***** Automatically generated file (26/08/2016 07:00:43): Do not edit manually ********************/
+/***** Timestamp:  (26/08/2016 07:00:43)************************************************************/
 
-#define RGX_BNC_KM_B 4
-#define RGX_BNC_KM_N 2
-#define RGX_BNC_KM_C 52
+#define RGX_BNC_KM_B 22
+#define RGX_BNC_KM_N 22
+#define RGX_BNC_KM_C 22
 
 /******************************************************************************
  * DDK Defines
  *****************************************************************************/
-#define RGX_FEATURE_NUM_CLUSTERS (2)
-#define RGX_FEATURE_SLC_SIZE_IN_BYTES (128*1024)
-#define RGX_FEATURE_PHYS_BUS_WIDTH (40)
+#define RGX_FEATURE_PHYS_BUS_WIDTH (32)
 #define RGX_FEATURE_PERFBUS 
 #define RGX_FEATURE_AXI_ACELITE 
-#define RGX_FEATURE_CLUSTER_GROUPING 
 #define RGX_FEATURE_SLC_CACHE_LINE_SIZE_BITS (512)
-#define RGX_FEATURE_DYNAMIC_DUST_POWER 
+#define RGX_FEATURE_NUM_CLUSTERS (1)
 #define RGX_FEATURE_VIRTUAL_ADDRESS_SPACE_BITS (40)
-#define RGX_FEATURE_TLA 
+#define RGX_FEATURE_SLC_SIZE_IN_BYTES (16*1024)
+#define RGX_FEATURE_SLC_BANKS (1)
 #define RGX_FEATURE_GS_RTA_SUPPORT 
-#define RGX_FEATURE_TPU_CEM_DATAMASTER_GLOBAL_REGISTERS 
-#define RGX_FEATURE_NUM_ISP_IPP_PIPES (8)
-#define RGX_FEATURE_META (LTP218)
-#define RGX_FEATURE_TPU_FILTERING_MODE_CONTROL 
-#define RGX_FEATURE_XT_TOP_INFRASTRUCTURE 
-#define RGX_FEATURE_COMPUTE_MORTON_CAPABLE 
-#define RGX_FEATURE_FBCDC_ARCHITECTURE (2)
+#define RGX_FEATURE_NUM_ISP_IPP_PIPES (1)
 #define RGX_FEATURE_GPU_VIRTUALISATION 
-#define RGX_FEATURE_META_COREMEM_SIZE (32)
 #define RGX_FEATURE_COMPUTE 
-#define RGX_FEATURE_COMPUTE_OVERLAP 
+#define RGX_FEATURE_SINGLE_BIF 
+#define RGX_FEATURE_PBE2_IN_XE 
+#define RGX_FEATURE_MIPS 
+#define RGX_FEATURE_PBVNC_COREID_REG 
+#define RGX_FEATURE_ROGUEXE 
 
 
-#endif /* _RGXCONFIG_4_V_2_52_H_ */
+#endif /* _RGXCONFIG_22_V_22_22_H_ */
diff --git a/drivers/staging/imgtec/rogue/hwdefs/km/configs/rgxconfig_km_4.V.2.52.h b/drivers/staging/imgtec/rogue/hwdefs/km/configs/rgxconfig_km_22.V.22.23.h
similarity index 73%
copy from drivers/staging/imgtec/rogue/hwdefs/km/configs/rgxconfig_km_4.V.2.52.h
copy to drivers/staging/imgtec/rogue/hwdefs/km/configs/rgxconfig_km_22.V.22.23.h
index 0462d6f..da162f6 100644
--- a/drivers/staging/imgtec/rogue/hwdefs/km/configs/rgxconfig_km_4.V.2.52.h
+++ b/drivers/staging/imgtec/rogue/hwdefs/km/configs/rgxconfig_km_22.V.22.23.h
@@ -1,5 +1,5 @@
 /*************************************************************************/ /*!
-@Title          RGX Config BVNC 4.V.2.52
+@Title          RGX Config BVNC 22.V.22.23
 @Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
 @License        Dual MIT/GPLv2
 
@@ -39,41 +39,37 @@
 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */ /**************************************************************************/
 
-#ifndef _RGXCONFIG_KM_4_V_2_52_H_
-#define _RGXCONFIG_KM_4_V_2_52_H_
+#ifndef _RGXCONFIG_KM_22_V_22_23_H_
+#define _RGXCONFIG_KM_22_V_22_23_H_
 
-/***** Automatically generated file (22/02/2016 07:00:34): Do not edit manually ********************/
-/***** Timestamp:  (22/02/2016 07:00:34)************************************************************/
+/***** Automatically generated file (26/08/2016 07:00:43): Do not edit manually ********************/
+/***** Timestamp:  (26/08/2016 07:00:43)************************************************************/
 
-#define RGX_BNC_KM_B 4
-#define RGX_BNC_KM_N 2
-#define RGX_BNC_KM_C 52
+#define RGX_BNC_KM_B 22
+#define RGX_BNC_KM_N 22
+#define RGX_BNC_KM_C 23
 
 /******************************************************************************
  * DDK Defines
  *****************************************************************************/
-#define RGX_FEATURE_NUM_CLUSTERS (2)
-#define RGX_FEATURE_SLC_SIZE_IN_BYTES (128*1024)
-#define RGX_FEATURE_PHYS_BUS_WIDTH (40)
+#define RGX_FEATURE_PHYS_BUS_WIDTH (32)
 #define RGX_FEATURE_PERFBUS 
 #define RGX_FEATURE_AXI_ACELITE 
-#define RGX_FEATURE_CLUSTER_GROUPING 
 #define RGX_FEATURE_SLC_CACHE_LINE_SIZE_BITS (512)
-#define RGX_FEATURE_DYNAMIC_DUST_POWER 
+#define RGX_FEATURE_NUM_CLUSTERS (1)
 #define RGX_FEATURE_VIRTUAL_ADDRESS_SPACE_BITS (40)
-#define RGX_FEATURE_TLA 
+#define RGX_FEATURE_SLC_SIZE_IN_BYTES (16*1024)
+#define RGX_FEATURE_SLC_BANKS (1)
 #define RGX_FEATURE_GS_RTA_SUPPORT 
-#define RGX_FEATURE_TPU_CEM_DATAMASTER_GLOBAL_REGISTERS 
-#define RGX_FEATURE_NUM_ISP_IPP_PIPES (8)
-#define RGX_FEATURE_META (LTP218)
-#define RGX_FEATURE_TPU_FILTERING_MODE_CONTROL 
-#define RGX_FEATURE_XT_TOP_INFRASTRUCTURE 
-#define RGX_FEATURE_COMPUTE_MORTON_CAPABLE 
-#define RGX_FEATURE_FBCDC_ARCHITECTURE (2)
+#define RGX_FEATURE_NUM_ISP_IPP_PIPES (1)
 #define RGX_FEATURE_GPU_VIRTUALISATION 
-#define RGX_FEATURE_META_COREMEM_SIZE (32)
 #define RGX_FEATURE_COMPUTE 
-#define RGX_FEATURE_COMPUTE_OVERLAP 
+#define RGX_FEATURE_SINGLE_BIF 
+#define RGX_FEATURE_PBE2_IN_XE 
+#define RGX_FEATURE_MIPS 
+#define RGX_FEATURE_PBVNC_COREID_REG 
+#define RGX_FEATURE_SYS_BUS_SECURE_RESET 
+#define RGX_FEATURE_ROGUEXE 
 
 
-#endif /* _RGXCONFIG_4_V_2_52_H_ */
+#endif /* _RGXCONFIG_22_V_22_23_H_ */
diff --git a/drivers/staging/imgtec/rogue/hwdefs/km/configs/rgxconfig_km_4.V.2.52.h b/drivers/staging/imgtec/rogue/hwdefs/km/configs/rgxconfig_km_22.V.22.25.h
similarity index 73%
copy from drivers/staging/imgtec/rogue/hwdefs/km/configs/rgxconfig_km_4.V.2.52.h
copy to drivers/staging/imgtec/rogue/hwdefs/km/configs/rgxconfig_km_22.V.22.25.h
index 0462d6f..7355335 100644
--- a/drivers/staging/imgtec/rogue/hwdefs/km/configs/rgxconfig_km_4.V.2.52.h
+++ b/drivers/staging/imgtec/rogue/hwdefs/km/configs/rgxconfig_km_22.V.22.25.h
@@ -1,5 +1,5 @@
 /*************************************************************************/ /*!
-@Title          RGX Config BVNC 4.V.2.52
+@Title          RGX Config BVNC 22.V.22.25
 @Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
 @License        Dual MIT/GPLv2
 
@@ -39,41 +39,37 @@
 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */ /**************************************************************************/
 
-#ifndef _RGXCONFIG_KM_4_V_2_52_H_
-#define _RGXCONFIG_KM_4_V_2_52_H_
+#ifndef _RGXCONFIG_KM_22_V_22_25_H_
+#define _RGXCONFIG_KM_22_V_22_25_H_
 
-/***** Automatically generated file (22/02/2016 07:00:34): Do not edit manually ********************/
-/***** Timestamp:  (22/02/2016 07:00:34)************************************************************/
+/***** Automatically generated file (08/02/2017 07:00:50): Do not edit manually ********************/
+/***** Timestamp:  (08/02/2017 07:00:50)************************************************************/
 
-#define RGX_BNC_KM_B 4
-#define RGX_BNC_KM_N 2
-#define RGX_BNC_KM_C 52
+#define RGX_BNC_KM_B 22
+#define RGX_BNC_KM_N 22
+#define RGX_BNC_KM_C 25
 
 /******************************************************************************
  * DDK Defines
  *****************************************************************************/
-#define RGX_FEATURE_NUM_CLUSTERS (2)
-#define RGX_FEATURE_SLC_SIZE_IN_BYTES (128*1024)
-#define RGX_FEATURE_PHYS_BUS_WIDTH (40)
+#define RGX_FEATURE_PHYS_BUS_WIDTH (32)
 #define RGX_FEATURE_PERFBUS 
 #define RGX_FEATURE_AXI_ACELITE 
-#define RGX_FEATURE_CLUSTER_GROUPING 
 #define RGX_FEATURE_SLC_CACHE_LINE_SIZE_BITS (512)
-#define RGX_FEATURE_DYNAMIC_DUST_POWER 
+#define RGX_FEATURE_NUM_CLUSTERS (1)
 #define RGX_FEATURE_VIRTUAL_ADDRESS_SPACE_BITS (40)
-#define RGX_FEATURE_TLA 
+#define RGX_FEATURE_SLC_SIZE_IN_BYTES (16*1024)
+#define RGX_FEATURE_SLC_BANKS (1)
 #define RGX_FEATURE_GS_RTA_SUPPORT 
-#define RGX_FEATURE_TPU_CEM_DATAMASTER_GLOBAL_REGISTERS 
-#define RGX_FEATURE_NUM_ISP_IPP_PIPES (8)
-#define RGX_FEATURE_META (LTP218)
-#define RGX_FEATURE_TPU_FILTERING_MODE_CONTROL 
-#define RGX_FEATURE_XT_TOP_INFRASTRUCTURE 
-#define RGX_FEATURE_COMPUTE_MORTON_CAPABLE 
-#define RGX_FEATURE_FBCDC_ARCHITECTURE (2)
+#define RGX_FEATURE_NUM_ISP_IPP_PIPES (2)
 #define RGX_FEATURE_GPU_VIRTUALISATION 
-#define RGX_FEATURE_META_COREMEM_SIZE (32)
 #define RGX_FEATURE_COMPUTE 
-#define RGX_FEATURE_COMPUTE_OVERLAP 
+#define RGX_FEATURE_SINGLE_BIF 
+#define RGX_FEATURE_PBE2_IN_XE 
+#define RGX_FEATURE_MIPS 
+#define RGX_FEATURE_PBVNC_COREID_REG 
+#define RGX_FEATURE_SYS_BUS_SECURE_RESET 
+#define RGX_FEATURE_ROGUEXE 
 
 
-#endif /* _RGXCONFIG_4_V_2_52_H_ */
+#endif /* _RGXCONFIG_22_V_22_25_H_ */
diff --git a/drivers/staging/imgtec/rogue/hwdefs/km/configs/rgxconfig_km_4.V.2.52.h b/drivers/staging/imgtec/rogue/hwdefs/km/configs/rgxconfig_km_22.V.22.27.h
similarity index 73%
copy from drivers/staging/imgtec/rogue/hwdefs/km/configs/rgxconfig_km_4.V.2.52.h
copy to drivers/staging/imgtec/rogue/hwdefs/km/configs/rgxconfig_km_22.V.22.27.h
index 0462d6f..f639123 100644
--- a/drivers/staging/imgtec/rogue/hwdefs/km/configs/rgxconfig_km_4.V.2.52.h
+++ b/drivers/staging/imgtec/rogue/hwdefs/km/configs/rgxconfig_km_22.V.22.27.h
@@ -1,5 +1,5 @@
 /*************************************************************************/ /*!
-@Title          RGX Config BVNC 4.V.2.52
+@Title          RGX Config BVNC 22.V.22.27
 @Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
 @License        Dual MIT/GPLv2
 
@@ -39,41 +39,37 @@
 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */ /**************************************************************************/
 
-#ifndef _RGXCONFIG_KM_4_V_2_52_H_
-#define _RGXCONFIG_KM_4_V_2_52_H_
+#ifndef _RGXCONFIG_KM_22_V_22_27_H_
+#define _RGXCONFIG_KM_22_V_22_27_H_
 
-/***** Automatically generated file (22/02/2016 07:00:34): Do not edit manually ********************/
-/***** Timestamp:  (22/02/2016 07:00:34)************************************************************/
+/***** Automatically generated file (26/08/2016 07:00:43): Do not edit manually ********************/
+/***** Timestamp:  (26/08/2016 07:00:43)************************************************************/
 
-#define RGX_BNC_KM_B 4
-#define RGX_BNC_KM_N 2
-#define RGX_BNC_KM_C 52
+#define RGX_BNC_KM_B 22
+#define RGX_BNC_KM_N 22
+#define RGX_BNC_KM_C 27
 
 /******************************************************************************
  * DDK Defines
  *****************************************************************************/
-#define RGX_FEATURE_NUM_CLUSTERS (2)
-#define RGX_FEATURE_SLC_SIZE_IN_BYTES (128*1024)
-#define RGX_FEATURE_PHYS_BUS_WIDTH (40)
+#define RGX_FEATURE_PHYS_BUS_WIDTH (32)
 #define RGX_FEATURE_PERFBUS 
 #define RGX_FEATURE_AXI_ACELITE 
-#define RGX_FEATURE_CLUSTER_GROUPING 
 #define RGX_FEATURE_SLC_CACHE_LINE_SIZE_BITS (512)
-#define RGX_FEATURE_DYNAMIC_DUST_POWER 
+#define RGX_FEATURE_NUM_CLUSTERS (1)
 #define RGX_FEATURE_VIRTUAL_ADDRESS_SPACE_BITS (40)
-#define RGX_FEATURE_TLA 
+#define RGX_FEATURE_SLC_SIZE_IN_BYTES (16*1024)
+#define RGX_FEATURE_SLC_BANKS (1)
 #define RGX_FEATURE_GS_RTA_SUPPORT 
-#define RGX_FEATURE_TPU_CEM_DATAMASTER_GLOBAL_REGISTERS 
-#define RGX_FEATURE_NUM_ISP_IPP_PIPES (8)
-#define RGX_FEATURE_META (LTP218)
-#define RGX_FEATURE_TPU_FILTERING_MODE_CONTROL 
-#define RGX_FEATURE_XT_TOP_INFRASTRUCTURE 
-#define RGX_FEATURE_COMPUTE_MORTON_CAPABLE 
-#define RGX_FEATURE_FBCDC_ARCHITECTURE (2)
+#define RGX_FEATURE_NUM_ISP_IPP_PIPES (1)
 #define RGX_FEATURE_GPU_VIRTUALISATION 
-#define RGX_FEATURE_META_COREMEM_SIZE (32)
 #define RGX_FEATURE_COMPUTE 
-#define RGX_FEATURE_COMPUTE_OVERLAP 
+#define RGX_FEATURE_SINGLE_BIF 
+#define RGX_FEATURE_PBE2_IN_XE 
+#define RGX_FEATURE_MIPS 
+#define RGX_FEATURE_PBVNC_COREID_REG 
+#define RGX_FEATURE_SYS_BUS_SECURE_RESET 
+#define RGX_FEATURE_ROGUEXE 
 
 
-#endif /* _RGXCONFIG_4_V_2_52_H_ */
+#endif /* _RGXCONFIG_22_V_22_27_H_ */
diff --git a/drivers/staging/imgtec/rogue/hwdefs/km/configs/rgxconfig_km_4.V.2.52.h b/drivers/staging/imgtec/rogue/hwdefs/km/configs/rgxconfig_km_22.V.22.29.h
similarity index 73%
copy from drivers/staging/imgtec/rogue/hwdefs/km/configs/rgxconfig_km_4.V.2.52.h
copy to drivers/staging/imgtec/rogue/hwdefs/km/configs/rgxconfig_km_22.V.22.29.h
index 0462d6f..0462945 100644
--- a/drivers/staging/imgtec/rogue/hwdefs/km/configs/rgxconfig_km_4.V.2.52.h
+++ b/drivers/staging/imgtec/rogue/hwdefs/km/configs/rgxconfig_km_22.V.22.29.h
@@ -1,5 +1,5 @@
 /*************************************************************************/ /*!
-@Title          RGX Config BVNC 4.V.2.52
+@Title          RGX Config BVNC 22.V.22.29
 @Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
 @License        Dual MIT/GPLv2
 
@@ -39,41 +39,37 @@
 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */ /**************************************************************************/
 
-#ifndef _RGXCONFIG_KM_4_V_2_52_H_
-#define _RGXCONFIG_KM_4_V_2_52_H_
+#ifndef _RGXCONFIG_KM_22_V_22_29_H_
+#define _RGXCONFIG_KM_22_V_22_29_H_
 
-/***** Automatically generated file (22/02/2016 07:00:34): Do not edit manually ********************/
-/***** Timestamp:  (22/02/2016 07:00:34)************************************************************/
+/***** Automatically generated file (08/02/2017 07:00:49): Do not edit manually ********************/
+/***** Timestamp:  (08/02/2017 07:00:49)************************************************************/
 
-#define RGX_BNC_KM_B 4
-#define RGX_BNC_KM_N 2
-#define RGX_BNC_KM_C 52
+#define RGX_BNC_KM_B 22
+#define RGX_BNC_KM_N 22
+#define RGX_BNC_KM_C 29
 
 /******************************************************************************
  * DDK Defines
  *****************************************************************************/
-#define RGX_FEATURE_NUM_CLUSTERS (2)
-#define RGX_FEATURE_SLC_SIZE_IN_BYTES (128*1024)
-#define RGX_FEATURE_PHYS_BUS_WIDTH (40)
+#define RGX_FEATURE_PHYS_BUS_WIDTH (32)
 #define RGX_FEATURE_PERFBUS 
 #define RGX_FEATURE_AXI_ACELITE 
-#define RGX_FEATURE_CLUSTER_GROUPING 
 #define RGX_FEATURE_SLC_CACHE_LINE_SIZE_BITS (512)
-#define RGX_FEATURE_DYNAMIC_DUST_POWER 
+#define RGX_FEATURE_NUM_CLUSTERS (1)
 #define RGX_FEATURE_VIRTUAL_ADDRESS_SPACE_BITS (40)
-#define RGX_FEATURE_TLA 
+#define RGX_FEATURE_SLC_SIZE_IN_BYTES (16*1024)
+#define RGX_FEATURE_SLC_BANKS (1)
 #define RGX_FEATURE_GS_RTA_SUPPORT 
-#define RGX_FEATURE_TPU_CEM_DATAMASTER_GLOBAL_REGISTERS 
-#define RGX_FEATURE_NUM_ISP_IPP_PIPES (8)
-#define RGX_FEATURE_META (LTP218)
-#define RGX_FEATURE_TPU_FILTERING_MODE_CONTROL 
-#define RGX_FEATURE_XT_TOP_INFRASTRUCTURE 
-#define RGX_FEATURE_COMPUTE_MORTON_CAPABLE 
-#define RGX_FEATURE_FBCDC_ARCHITECTURE (2)
+#define RGX_FEATURE_NUM_ISP_IPP_PIPES (2)
 #define RGX_FEATURE_GPU_VIRTUALISATION 
-#define RGX_FEATURE_META_COREMEM_SIZE (32)
 #define RGX_FEATURE_COMPUTE 
-#define RGX_FEATURE_COMPUTE_OVERLAP 
+#define RGX_FEATURE_SINGLE_BIF 
+#define RGX_FEATURE_PBE2_IN_XE 
+#define RGX_FEATURE_MIPS 
+#define RGX_FEATURE_PBVNC_COREID_REG 
+#define RGX_FEATURE_SYS_BUS_SECURE_RESET 
+#define RGX_FEATURE_ROGUEXE 
 
 
-#endif /* _RGXCONFIG_4_V_2_52_H_ */
+#endif /* _RGXCONFIG_22_V_22_29_H_ */
diff --git a/drivers/staging/imgtec/rogue/hwdefs/km/configs/rgxconfig_km_4.V.2.52.h b/drivers/staging/imgtec/rogue/hwdefs/km/configs/rgxconfig_km_22.V.54.24.h
similarity index 73%
copy from drivers/staging/imgtec/rogue/hwdefs/km/configs/rgxconfig_km_4.V.2.52.h
copy to drivers/staging/imgtec/rogue/hwdefs/km/configs/rgxconfig_km_22.V.54.24.h
index 0462d6f..75a238f 100644
--- a/drivers/staging/imgtec/rogue/hwdefs/km/configs/rgxconfig_km_4.V.2.52.h
+++ b/drivers/staging/imgtec/rogue/hwdefs/km/configs/rgxconfig_km_22.V.54.24.h
@@ -1,5 +1,5 @@
 /*************************************************************************/ /*!
-@Title          RGX Config BVNC 4.V.2.52
+@Title          RGX Config BVNC 22.V.54.24
 @Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
 @License        Dual MIT/GPLv2
 
@@ -39,41 +39,36 @@
 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */ /**************************************************************************/
 
-#ifndef _RGXCONFIG_KM_4_V_2_52_H_
-#define _RGXCONFIG_KM_4_V_2_52_H_
+#ifndef _RGXCONFIG_KM_22_V_54_24_H_
+#define _RGXCONFIG_KM_22_V_54_24_H_
 
-/***** Automatically generated file (22/02/2016 07:00:34): Do not edit manually ********************/
-/***** Timestamp:  (22/02/2016 07:00:34)************************************************************/
+/***** Automatically generated file (26/08/2016 07:00:43): Do not edit manually ********************/
+/***** Timestamp:  (26/08/2016 07:00:43)************************************************************/
 
-#define RGX_BNC_KM_B 4
-#define RGX_BNC_KM_N 2
-#define RGX_BNC_KM_C 52
+#define RGX_BNC_KM_B 22
+#define RGX_BNC_KM_N 54
+#define RGX_BNC_KM_C 24
 
 /******************************************************************************
  * DDK Defines
  *****************************************************************************/
-#define RGX_FEATURE_NUM_CLUSTERS (2)
-#define RGX_FEATURE_SLC_SIZE_IN_BYTES (128*1024)
-#define RGX_FEATURE_PHYS_BUS_WIDTH (40)
+#define RGX_FEATURE_PHYS_BUS_WIDTH (32)
 #define RGX_FEATURE_PERFBUS 
 #define RGX_FEATURE_AXI_ACELITE 
-#define RGX_FEATURE_CLUSTER_GROUPING 
 #define RGX_FEATURE_SLC_CACHE_LINE_SIZE_BITS (512)
-#define RGX_FEATURE_DYNAMIC_DUST_POWER 
+#define RGX_FEATURE_NUM_CLUSTERS (1)
 #define RGX_FEATURE_VIRTUAL_ADDRESS_SPACE_BITS (40)
-#define RGX_FEATURE_TLA 
+#define RGX_FEATURE_SLC_BANKS (1)
 #define RGX_FEATURE_GS_RTA_SUPPORT 
-#define RGX_FEATURE_TPU_CEM_DATAMASTER_GLOBAL_REGISTERS 
-#define RGX_FEATURE_NUM_ISP_IPP_PIPES (8)
-#define RGX_FEATURE_META (LTP218)
-#define RGX_FEATURE_TPU_FILTERING_MODE_CONTROL 
-#define RGX_FEATURE_XT_TOP_INFRASTRUCTURE 
-#define RGX_FEATURE_COMPUTE_MORTON_CAPABLE 
-#define RGX_FEATURE_FBCDC_ARCHITECTURE (2)
+#define RGX_FEATURE_NUM_ISP_IPP_PIPES (3)
 #define RGX_FEATURE_GPU_VIRTUALISATION 
-#define RGX_FEATURE_META_COREMEM_SIZE (32)
+#define RGX_FEATURE_SLC_SIZE_IN_BYTES (64*1024)
 #define RGX_FEATURE_COMPUTE 
-#define RGX_FEATURE_COMPUTE_OVERLAP 
+#define RGX_FEATURE_SINGLE_BIF 
+#define RGX_FEATURE_PBE2_IN_XE 
+#define RGX_FEATURE_MIPS 
+#define RGX_FEATURE_PBVNC_COREID_REG 
+#define RGX_FEATURE_ROGUEXE 
 
 
-#endif /* _RGXCONFIG_4_V_2_52_H_ */
+#endif /* _RGXCONFIG_22_V_54_24_H_ */
diff --git a/drivers/staging/imgtec/rogue/hwdefs/km/configs/rgxconfig_km_4.V.2.52.h b/drivers/staging/imgtec/rogue/hwdefs/km/configs/rgxconfig_km_22.V.54.25.h
similarity index 73%
copy from drivers/staging/imgtec/rogue/hwdefs/km/configs/rgxconfig_km_4.V.2.52.h
copy to drivers/staging/imgtec/rogue/hwdefs/km/configs/rgxconfig_km_22.V.54.25.h
index 0462d6f..2eeea71 100644
--- a/drivers/staging/imgtec/rogue/hwdefs/km/configs/rgxconfig_km_4.V.2.52.h
+++ b/drivers/staging/imgtec/rogue/hwdefs/km/configs/rgxconfig_km_22.V.54.25.h
@@ -1,5 +1,5 @@
 /*************************************************************************/ /*!
-@Title          RGX Config BVNC 4.V.2.52
+@Title          RGX Config BVNC 22.V.54.25
 @Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
 @License        Dual MIT/GPLv2
 
@@ -39,41 +39,37 @@
 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */ /**************************************************************************/
 
-#ifndef _RGXCONFIG_KM_4_V_2_52_H_
-#define _RGXCONFIG_KM_4_V_2_52_H_
+#ifndef _RGXCONFIG_KM_22_V_54_25_H_
+#define _RGXCONFIG_KM_22_V_54_25_H_
 
-/***** Automatically generated file (22/02/2016 07:00:34): Do not edit manually ********************/
-/***** Timestamp:  (22/02/2016 07:00:34)************************************************************/
+/***** Automatically generated file (26/08/2016 07:00:43): Do not edit manually ********************/
+/***** Timestamp:  (26/08/2016 07:00:43)************************************************************/
 
-#define RGX_BNC_KM_B 4
-#define RGX_BNC_KM_N 2
-#define RGX_BNC_KM_C 52
+#define RGX_BNC_KM_B 22
+#define RGX_BNC_KM_N 54
+#define RGX_BNC_KM_C 25
 
 /******************************************************************************
  * DDK Defines
  *****************************************************************************/
-#define RGX_FEATURE_NUM_CLUSTERS (2)
-#define RGX_FEATURE_SLC_SIZE_IN_BYTES (128*1024)
-#define RGX_FEATURE_PHYS_BUS_WIDTH (40)
+#define RGX_FEATURE_PHYS_BUS_WIDTH (32)
 #define RGX_FEATURE_PERFBUS 
 #define RGX_FEATURE_AXI_ACELITE 
-#define RGX_FEATURE_CLUSTER_GROUPING 
 #define RGX_FEATURE_SLC_CACHE_LINE_SIZE_BITS (512)
-#define RGX_FEATURE_DYNAMIC_DUST_POWER 
+#define RGX_FEATURE_NUM_CLUSTERS (1)
 #define RGX_FEATURE_VIRTUAL_ADDRESS_SPACE_BITS (40)
-#define RGX_FEATURE_TLA 
+#define RGX_FEATURE_SLC_BANKS (1)
 #define RGX_FEATURE_GS_RTA_SUPPORT 
-#define RGX_FEATURE_TPU_CEM_DATAMASTER_GLOBAL_REGISTERS 
-#define RGX_FEATURE_NUM_ISP_IPP_PIPES (8)
-#define RGX_FEATURE_META (LTP218)
-#define RGX_FEATURE_TPU_FILTERING_MODE_CONTROL 
-#define RGX_FEATURE_XT_TOP_INFRASTRUCTURE 
-#define RGX_FEATURE_COMPUTE_MORTON_CAPABLE 
-#define RGX_FEATURE_FBCDC_ARCHITECTURE (2)
+#define RGX_FEATURE_NUM_ISP_IPP_PIPES (3)
 #define RGX_FEATURE_GPU_VIRTUALISATION 
-#define RGX_FEATURE_META_COREMEM_SIZE (32)
+#define RGX_FEATURE_SLC_SIZE_IN_BYTES (64*1024)
 #define RGX_FEATURE_COMPUTE 
-#define RGX_FEATURE_COMPUTE_OVERLAP 
+#define RGX_FEATURE_SINGLE_BIF 
+#define RGX_FEATURE_PBE2_IN_XE 
+#define RGX_FEATURE_MIPS 
+#define RGX_FEATURE_PBVNC_COREID_REG 
+#define RGX_FEATURE_SYS_BUS_SECURE_RESET 
+#define RGX_FEATURE_ROGUEXE 
 
 
-#endif /* _RGXCONFIG_4_V_2_52_H_ */
+#endif /* _RGXCONFIG_22_V_54_25_H_ */
diff --git a/drivers/staging/imgtec/rogue/hwdefs/km/configs/rgxconfig_km_4.V.2.52.h b/drivers/staging/imgtec/rogue/hwdefs/km/configs/rgxconfig_km_22.V.54.30.h
similarity index 73%
copy from drivers/staging/imgtec/rogue/hwdefs/km/configs/rgxconfig_km_4.V.2.52.h
copy to drivers/staging/imgtec/rogue/hwdefs/km/configs/rgxconfig_km_22.V.54.30.h
index 0462d6f..fc506af 100644
--- a/drivers/staging/imgtec/rogue/hwdefs/km/configs/rgxconfig_km_4.V.2.52.h
+++ b/drivers/staging/imgtec/rogue/hwdefs/km/configs/rgxconfig_km_22.V.54.30.h
@@ -1,5 +1,5 @@
 /*************************************************************************/ /*!
-@Title          RGX Config BVNC 4.V.2.52
+@Title          RGX Config BVNC 22.V.54.30
 @Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
 @License        Dual MIT/GPLv2
 
@@ -39,41 +39,37 @@
 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */ /**************************************************************************/
 
-#ifndef _RGXCONFIG_KM_4_V_2_52_H_
-#define _RGXCONFIG_KM_4_V_2_52_H_
+#ifndef _RGXCONFIG_KM_22_V_54_30_H_
+#define _RGXCONFIG_KM_22_V_54_30_H_
 
-/***** Automatically generated file (22/02/2016 07:00:34): Do not edit manually ********************/
-/***** Timestamp:  (22/02/2016 07:00:34)************************************************************/
+/***** Automatically generated file (26/08/2016 07:00:43): Do not edit manually ********************/
+/***** Timestamp:  (26/08/2016 07:00:43)************************************************************/
 
-#define RGX_BNC_KM_B 4
-#define RGX_BNC_KM_N 2
-#define RGX_BNC_KM_C 52
+#define RGX_BNC_KM_B 22
+#define RGX_BNC_KM_N 54
+#define RGX_BNC_KM_C 30
 
 /******************************************************************************
  * DDK Defines
  *****************************************************************************/
-#define RGX_FEATURE_NUM_CLUSTERS (2)
-#define RGX_FEATURE_SLC_SIZE_IN_BYTES (128*1024)
-#define RGX_FEATURE_PHYS_BUS_WIDTH (40)
+#define RGX_FEATURE_PHYS_BUS_WIDTH (32)
 #define RGX_FEATURE_PERFBUS 
 #define RGX_FEATURE_AXI_ACELITE 
-#define RGX_FEATURE_CLUSTER_GROUPING 
 #define RGX_FEATURE_SLC_CACHE_LINE_SIZE_BITS (512)
-#define RGX_FEATURE_DYNAMIC_DUST_POWER 
+#define RGX_FEATURE_NUM_CLUSTERS (1)
 #define RGX_FEATURE_VIRTUAL_ADDRESS_SPACE_BITS (40)
-#define RGX_FEATURE_TLA 
+#define RGX_FEATURE_SLC_BANKS (1)
 #define RGX_FEATURE_GS_RTA_SUPPORT 
-#define RGX_FEATURE_TPU_CEM_DATAMASTER_GLOBAL_REGISTERS 
-#define RGX_FEATURE_NUM_ISP_IPP_PIPES (8)
-#define RGX_FEATURE_META (LTP218)
-#define RGX_FEATURE_TPU_FILTERING_MODE_CONTROL 
-#define RGX_FEATURE_XT_TOP_INFRASTRUCTURE 
-#define RGX_FEATURE_COMPUTE_MORTON_CAPABLE 
-#define RGX_FEATURE_FBCDC_ARCHITECTURE (2)
+#define RGX_FEATURE_NUM_ISP_IPP_PIPES (4)
 #define RGX_FEATURE_GPU_VIRTUALISATION 
-#define RGX_FEATURE_META_COREMEM_SIZE (32)
+#define RGX_FEATURE_SLC_SIZE_IN_BYTES (64*1024)
 #define RGX_FEATURE_COMPUTE 
-#define RGX_FEATURE_COMPUTE_OVERLAP 
+#define RGX_FEATURE_SINGLE_BIF 
+#define RGX_FEATURE_PBE2_IN_XE 
+#define RGX_FEATURE_MIPS 
+#define RGX_FEATURE_PBVNC_COREID_REG 
+#define RGX_FEATURE_SYS_BUS_SECURE_RESET 
+#define RGX_FEATURE_ROGUEXE 
 
 
-#endif /* _RGXCONFIG_4_V_2_52_H_ */
+#endif /* _RGXCONFIG_22_V_54_30_H_ */
diff --git a/drivers/staging/imgtec/rogue/hwdefs/km/configs/rgxconfig_km_4.V.2.52.h b/drivers/staging/imgtec/rogue/hwdefs/km/configs/rgxconfig_km_22.V.54.328.h
similarity index 73%
copy from drivers/staging/imgtec/rogue/hwdefs/km/configs/rgxconfig_km_4.V.2.52.h
copy to drivers/staging/imgtec/rogue/hwdefs/km/configs/rgxconfig_km_22.V.54.328.h
index 0462d6f..84540cd 100644
--- a/drivers/staging/imgtec/rogue/hwdefs/km/configs/rgxconfig_km_4.V.2.52.h
+++ b/drivers/staging/imgtec/rogue/hwdefs/km/configs/rgxconfig_km_22.V.54.328.h
@@ -1,5 +1,5 @@
 /*************************************************************************/ /*!
-@Title          RGX Config BVNC 4.V.2.52
+@Title          RGX Config BVNC 22.V.54.328
 @Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
 @License        Dual MIT/GPLv2
 
@@ -39,41 +39,38 @@
 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */ /**************************************************************************/
 
-#ifndef _RGXCONFIG_KM_4_V_2_52_H_
-#define _RGXCONFIG_KM_4_V_2_52_H_
+#ifndef _RGXCONFIG_KM_22_V_54_328_H_
+#define _RGXCONFIG_KM_22_V_54_328_H_
 
-/***** Automatically generated file (22/02/2016 07:00:34): Do not edit manually ********************/
-/***** Timestamp:  (22/02/2016 07:00:34)************************************************************/
+/***** Automatically generated file (26/08/2016 07:00:43): Do not edit manually ********************/
+/***** Timestamp:  (26/08/2016 07:00:43)************************************************************/
 
-#define RGX_BNC_KM_B 4
-#define RGX_BNC_KM_N 2
-#define RGX_BNC_KM_C 52
+#define RGX_BNC_KM_B 22
+#define RGX_BNC_KM_N 54
+#define RGX_BNC_KM_C 328
 
 /******************************************************************************
  * DDK Defines
  *****************************************************************************/
-#define RGX_FEATURE_NUM_CLUSTERS (2)
-#define RGX_FEATURE_SLC_SIZE_IN_BYTES (128*1024)
-#define RGX_FEATURE_PHYS_BUS_WIDTH (40)
+#define RGX_FEATURE_PHYS_BUS_WIDTH (32)
 #define RGX_FEATURE_PERFBUS 
 #define RGX_FEATURE_AXI_ACELITE 
-#define RGX_FEATURE_CLUSTER_GROUPING 
 #define RGX_FEATURE_SLC_CACHE_LINE_SIZE_BITS (512)
-#define RGX_FEATURE_DYNAMIC_DUST_POWER 
+#define RGX_FEATURE_NUM_CLUSTERS (1)
 #define RGX_FEATURE_VIRTUAL_ADDRESS_SPACE_BITS (40)
-#define RGX_FEATURE_TLA 
+#define RGX_FEATURE_SLC_BANKS (1)
 #define RGX_FEATURE_GS_RTA_SUPPORT 
-#define RGX_FEATURE_TPU_CEM_DATAMASTER_GLOBAL_REGISTERS 
-#define RGX_FEATURE_NUM_ISP_IPP_PIPES (8)
-#define RGX_FEATURE_META (LTP218)
-#define RGX_FEATURE_TPU_FILTERING_MODE_CONTROL 
-#define RGX_FEATURE_XT_TOP_INFRASTRUCTURE 
-#define RGX_FEATURE_COMPUTE_MORTON_CAPABLE 
-#define RGX_FEATURE_FBCDC_ARCHITECTURE (2)
+#define RGX_FEATURE_NUM_ISP_IPP_PIPES (4)
+#define RGX_FEATURE_FBCDC_ARCHITECTURE (1)
 #define RGX_FEATURE_GPU_VIRTUALISATION 
-#define RGX_FEATURE_META_COREMEM_SIZE (32)
+#define RGX_FEATURE_SLC_SIZE_IN_BYTES (64*1024)
 #define RGX_FEATURE_COMPUTE 
-#define RGX_FEATURE_COMPUTE_OVERLAP 
+#define RGX_FEATURE_SINGLE_BIF 
+#define RGX_FEATURE_PBE2_IN_XE 
+#define RGX_FEATURE_MIPS 
+#define RGX_FEATURE_PBVNC_COREID_REG 
+#define RGX_FEATURE_SYS_BUS_SECURE_RESET 
+#define RGX_FEATURE_ROGUEXE 
 
 
-#endif /* _RGXCONFIG_4_V_2_52_H_ */
+#endif /* _RGXCONFIG_22_V_54_328_H_ */
diff --git a/drivers/staging/imgtec/rogue/hwdefs/km/configs/rgxconfig_km_4.V.2.52.h b/drivers/staging/imgtec/rogue/hwdefs/km/configs/rgxconfig_km_22.V.54.330.h
similarity index 73%
copy from drivers/staging/imgtec/rogue/hwdefs/km/configs/rgxconfig_km_4.V.2.52.h
copy to drivers/staging/imgtec/rogue/hwdefs/km/configs/rgxconfig_km_22.V.54.330.h
index 0462d6f..47615d9 100644
--- a/drivers/staging/imgtec/rogue/hwdefs/km/configs/rgxconfig_km_4.V.2.52.h
+++ b/drivers/staging/imgtec/rogue/hwdefs/km/configs/rgxconfig_km_22.V.54.330.h
@@ -1,5 +1,5 @@
 /*************************************************************************/ /*!
-@Title          RGX Config BVNC 4.V.2.52
+@Title          RGX Config BVNC 22.V.54.330
 @Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
 @License        Dual MIT/GPLv2
 
@@ -39,41 +39,38 @@
 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */ /**************************************************************************/
 
-#ifndef _RGXCONFIG_KM_4_V_2_52_H_
-#define _RGXCONFIG_KM_4_V_2_52_H_
+#ifndef _RGXCONFIG_KM_22_V_54_330_H_
+#define _RGXCONFIG_KM_22_V_54_330_H_
 
-/***** Automatically generated file (22/02/2016 07:00:34): Do not edit manually ********************/
-/***** Timestamp:  (22/02/2016 07:00:34)************************************************************/
+/***** Automatically generated file (26/08/2016 07:00:43): Do not edit manually ********************/
+/***** Timestamp:  (26/08/2016 07:00:43)************************************************************/
 
-#define RGX_BNC_KM_B 4
-#define RGX_BNC_KM_N 2
-#define RGX_BNC_KM_C 52
+#define RGX_BNC_KM_B 22
+#define RGX_BNC_KM_N 54
+#define RGX_BNC_KM_C 330
 
 /******************************************************************************
  * DDK Defines
  *****************************************************************************/
-#define RGX_FEATURE_NUM_CLUSTERS (2)
-#define RGX_FEATURE_SLC_SIZE_IN_BYTES (128*1024)
-#define RGX_FEATURE_PHYS_BUS_WIDTH (40)
+#define RGX_FEATURE_PHYS_BUS_WIDTH (32)
 #define RGX_FEATURE_PERFBUS 
 #define RGX_FEATURE_AXI_ACELITE 
-#define RGX_FEATURE_CLUSTER_GROUPING 
 #define RGX_FEATURE_SLC_CACHE_LINE_SIZE_BITS (512)
-#define RGX_FEATURE_DYNAMIC_DUST_POWER 
+#define RGX_FEATURE_NUM_CLUSTERS (1)
 #define RGX_FEATURE_VIRTUAL_ADDRESS_SPACE_BITS (40)
-#define RGX_FEATURE_TLA 
+#define RGX_FEATURE_SLC_BANKS (1)
 #define RGX_FEATURE_GS_RTA_SUPPORT 
-#define RGX_FEATURE_TPU_CEM_DATAMASTER_GLOBAL_REGISTERS 
-#define RGX_FEATURE_NUM_ISP_IPP_PIPES (8)
-#define RGX_FEATURE_META (LTP218)
-#define RGX_FEATURE_TPU_FILTERING_MODE_CONTROL 
-#define RGX_FEATURE_XT_TOP_INFRASTRUCTURE 
-#define RGX_FEATURE_COMPUTE_MORTON_CAPABLE 
-#define RGX_FEATURE_FBCDC_ARCHITECTURE (2)
+#define RGX_FEATURE_NUM_ISP_IPP_PIPES (4)
+#define RGX_FEATURE_FBCDC_ARCHITECTURE (1)
 #define RGX_FEATURE_GPU_VIRTUALISATION 
-#define RGX_FEATURE_META_COREMEM_SIZE (32)
+#define RGX_FEATURE_SLC_SIZE_IN_BYTES (64*1024)
 #define RGX_FEATURE_COMPUTE 
-#define RGX_FEATURE_COMPUTE_OVERLAP 
+#define RGX_FEATURE_SINGLE_BIF 
+#define RGX_FEATURE_PBE2_IN_XE 
+#define RGX_FEATURE_MIPS 
+#define RGX_FEATURE_PBVNC_COREID_REG 
+#define RGX_FEATURE_SYS_BUS_SECURE_RESET 
+#define RGX_FEATURE_ROGUEXE 
 
 
-#endif /* _RGXCONFIG_4_V_2_52_H_ */
+#endif /* _RGXCONFIG_22_V_54_330_H_ */
diff --git a/drivers/staging/imgtec/rogue/hwdefs/km/configs/rgxconfig_km_5.V.1.46.h b/drivers/staging/imgtec/rogue/hwdefs/km/configs/rgxconfig_km_5.V.1.46.h
index 2added3..c633fda 100644
--- a/drivers/staging/imgtec/rogue/hwdefs/km/configs/rgxconfig_km_5.V.1.46.h
+++ b/drivers/staging/imgtec/rogue/hwdefs/km/configs/rgxconfig_km_5.V.1.46.h
@@ -42,8 +42,8 @@
 #ifndef _RGXCONFIG_KM_5_V_1_46_H_
 #define _RGXCONFIG_KM_5_V_1_46_H_
 
-/***** Automatically generated file (23/07/2015 12:44:37): Do not edit manually ********************/
-/***** Timestamp:  (23/07/2015 12:44:37)************************************************************/
+/***** Automatically generated file (24/08/2016 07:01:08): Do not edit manually ********************/
+/***** Timestamp:  (24/08/2016 07:01:08)************************************************************/
 
 #define RGX_BNC_KM_B 5
 #define RGX_BNC_KM_N 1
@@ -67,6 +67,7 @@
 #define RGX_FEATURE_FBCDC_ARCHITECTURE (1)
 #define RGX_FEATURE_META_COREMEM_SIZE (0)
 #define RGX_FEATURE_COMPUTE 
+#define RGX_FEATURE_ROGUEXE 
 
 
 #endif /* _RGXCONFIG_5_V_1_46_H_ */
diff --git a/drivers/staging/imgtec/rogue/hwdefs/km/configs/rgxconfig_km_4.V.2.52.h b/drivers/staging/imgtec/rogue/hwdefs/km/configs/rgxconfig_km_6.V.4.35.h
similarity index 91%
rename from drivers/staging/imgtec/rogue/hwdefs/km/configs/rgxconfig_km_4.V.2.52.h
rename to drivers/staging/imgtec/rogue/hwdefs/km/configs/rgxconfig_km_6.V.4.35.h
index 0462d6f..0a7925d 100644
--- a/drivers/staging/imgtec/rogue/hwdefs/km/configs/rgxconfig_km_4.V.2.52.h
+++ b/drivers/staging/imgtec/rogue/hwdefs/km/configs/rgxconfig_km_6.V.4.35.h
@@ -1,5 +1,5 @@
 /*************************************************************************/ /*!
-@Title          RGX Config BVNC 4.V.2.52
+@Title          RGX Config BVNC 6.V.4.35
 @Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
 @License        Dual MIT/GPLv2
 
@@ -39,20 +39,20 @@
 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */ /**************************************************************************/
 
-#ifndef _RGXCONFIG_KM_4_V_2_52_H_
-#define _RGXCONFIG_KM_4_V_2_52_H_
+#ifndef _RGXCONFIG_KM_6_V_4_35_H_
+#define _RGXCONFIG_KM_6_V_4_35_H_
 
 /***** Automatically generated file (22/02/2016 07:00:34): Do not edit manually ********************/
 /***** Timestamp:  (22/02/2016 07:00:34)************************************************************/
 
-#define RGX_BNC_KM_B 4
-#define RGX_BNC_KM_N 2
-#define RGX_BNC_KM_C 52
+#define RGX_BNC_KM_B 6
+#define RGX_BNC_KM_N 4
+#define RGX_BNC_KM_C 35
 
 /******************************************************************************
  * DDK Defines
  *****************************************************************************/
-#define RGX_FEATURE_NUM_CLUSTERS (2)
+#define RGX_FEATURE_NUM_CLUSTERS (4)
 #define RGX_FEATURE_SLC_SIZE_IN_BYTES (128*1024)
 #define RGX_FEATURE_PHYS_BUS_WIDTH (40)
 #define RGX_FEATURE_PERFBUS 
@@ -61,6 +61,7 @@
 #define RGX_FEATURE_SLC_CACHE_LINE_SIZE_BITS (512)
 #define RGX_FEATURE_DYNAMIC_DUST_POWER 
 #define RGX_FEATURE_VIRTUAL_ADDRESS_SPACE_BITS (40)
+#define RGX_FEATURE_RAY_TRACING 
 #define RGX_FEATURE_TLA 
 #define RGX_FEATURE_GS_RTA_SUPPORT 
 #define RGX_FEATURE_TPU_CEM_DATAMASTER_GLOBAL_REGISTERS 
@@ -70,10 +71,9 @@
 #define RGX_FEATURE_XT_TOP_INFRASTRUCTURE 
 #define RGX_FEATURE_COMPUTE_MORTON_CAPABLE 
 #define RGX_FEATURE_FBCDC_ARCHITECTURE (2)
-#define RGX_FEATURE_GPU_VIRTUALISATION 
 #define RGX_FEATURE_META_COREMEM_SIZE (32)
 #define RGX_FEATURE_COMPUTE 
 #define RGX_FEATURE_COMPUTE_OVERLAP 
 
 
-#endif /* _RGXCONFIG_4_V_2_52_H_ */
+#endif /* _RGXCONFIG_6_V_4_35_H_ */
diff --git a/drivers/staging/imgtec/rogue/hwdefs/km/cores/rgxcore_km_1.33.2.5.h b/drivers/staging/imgtec/rogue/hwdefs/km/cores/rgxcore_km_1.33.2.5.h
index f94f194..8b40dd0 100644
--- a/drivers/staging/imgtec/rogue/hwdefs/km/cores/rgxcore_km_1.33.2.5.h
+++ b/drivers/staging/imgtec/rogue/hwdefs/km/cores/rgxcore_km_1.33.2.5.h
@@ -42,8 +42,8 @@
 #ifndef _RGXCORE_KM_1_33_2_5_H_
 #define _RGXCORE_KM_1_33_2_5_H_
 
-/***** Automatically generated file (26/08/2015 09:15:02): Do not edit manually ********************/
-/***** Timestamp:  (26/08/2015 09:15:02)************************************************************/
+/***** Automatically generated file (20/02/2017 07:01:19): Do not edit manually ********************/
+/***** Timestamp:  (20/02/2017 07:01:19)************************************************************/
 /***** CS: @2106753 ******************************************************************/
 
 
diff --git a/drivers/staging/imgtec/rogue/hwdefs/km/cores/rgxcore_km_1.39.4.19.h b/drivers/staging/imgtec/rogue/hwdefs/km/cores/rgxcore_km_1.39.4.19.h
index 7678e0a..e718bee 100644
--- a/drivers/staging/imgtec/rogue/hwdefs/km/cores/rgxcore_km_1.39.4.19.h
+++ b/drivers/staging/imgtec/rogue/hwdefs/km/cores/rgxcore_km_1.39.4.19.h
@@ -42,8 +42,8 @@
 #ifndef _RGXCORE_KM_1_39_4_19_H_
 #define _RGXCORE_KM_1_39_4_19_H_
 
-/***** Automatically generated file (26/08/2015 09:15:02): Do not edit manually ********************/
-/***** Timestamp:  (26/08/2015 09:15:02)************************************************************/
+/***** Automatically generated file (20/02/2017 07:01:19): Do not edit manually ********************/
+/***** Timestamp:  (20/02/2017 07:01:19)************************************************************/
 /***** CS: @2784771 ******************************************************************/
 
 
diff --git a/drivers/staging/imgtec/rogue/hwdefs/km/cores/rgxcore_km_1.48.2.0.h b/drivers/staging/imgtec/rogue/hwdefs/km/cores/rgxcore_km_1.48.2.0.h
index 7df2b7b..a88ec7a 100644
--- a/drivers/staging/imgtec/rogue/hwdefs/km/cores/rgxcore_km_1.48.2.0.h
+++ b/drivers/staging/imgtec/rogue/hwdefs/km/cores/rgxcore_km_1.48.2.0.h
@@ -42,8 +42,8 @@
 #ifndef _RGXCORE_KM_1_48_2_0_H_
 #define _RGXCORE_KM_1_48_2_0_H_
 
-/***** Automatically generated file (26/08/2015 09:15:02): Do not edit manually ********************/
-/***** Timestamp:  (26/08/2015 09:15:02)************************************************************/
+/***** Automatically generated file (20/02/2017 07:01:19): Do not edit manually ********************/
+/***** Timestamp:  (20/02/2017 07:01:19)************************************************************/
 /***** CS: @2523218 ******************************************************************/
 
 
diff --git a/drivers/staging/imgtec/rogue/hwdefs/km/cores/rgxcore_km_1.72.4.12.h b/drivers/staging/imgtec/rogue/hwdefs/km/cores/rgxcore_km_1.72.4.12.h
index 550b8e0..3bc0581 100644
--- a/drivers/staging/imgtec/rogue/hwdefs/km/cores/rgxcore_km_1.72.4.12.h
+++ b/drivers/staging/imgtec/rogue/hwdefs/km/cores/rgxcore_km_1.72.4.12.h
@@ -42,8 +42,8 @@
 #ifndef _RGXCORE_KM_1_72_4_12_H_
 #define _RGXCORE_KM_1_72_4_12_H_
 
-/***** Automatically generated file (23/07/2015 09:37:59): Do not edit manually ********************/
-/***** Timestamp:  (23/07/2015 09:37:59)************************************************************/
+/***** Automatically generated file (20/02/2017 07:01:19): Do not edit manually ********************/
+/***** Timestamp:  (20/02/2017 07:01:19)************************************************************/
 /***** CS: @2646650 ******************************************************************/
 
 
diff --git a/drivers/staging/imgtec/rogue/hwdefs/km/cores/rgxcore_km_1.75.2.20.h b/drivers/staging/imgtec/rogue/hwdefs/km/cores/rgxcore_km_1.75.2.20.h
index 9dc9f31..5835ad0 100644
--- a/drivers/staging/imgtec/rogue/hwdefs/km/cores/rgxcore_km_1.75.2.20.h
+++ b/drivers/staging/imgtec/rogue/hwdefs/km/cores/rgxcore_km_1.75.2.20.h
@@ -42,8 +42,8 @@
 #ifndef _RGXCORE_KM_1_75_2_20_H_
 #define _RGXCORE_KM_1_75_2_20_H_
 
-/***** Automatically generated file (26/08/2015 09:15:07): Do not edit manually ********************/
-/***** Timestamp:  (26/08/2015 09:15:07)************************************************************/
+/***** Automatically generated file (20/02/2017 07:01:19): Do not edit manually ********************/
+/***** Timestamp:  (20/02/2017 07:01:19)************************************************************/
 /***** CS: @2309075 ******************************************************************/
 
 
diff --git a/drivers/staging/imgtec/rogue/hwdefs/km/cores/rgxcore_km_1.75.2.30.h b/drivers/staging/imgtec/rogue/hwdefs/km/cores/rgxcore_km_1.75.2.30.h
index 0a3f0ae..17369b9 100644
--- a/drivers/staging/imgtec/rogue/hwdefs/km/cores/rgxcore_km_1.75.2.30.h
+++ b/drivers/staging/imgtec/rogue/hwdefs/km/cores/rgxcore_km_1.75.2.30.h
@@ -42,8 +42,8 @@
 #ifndef _RGXCORE_KM_1_75_2_30_H_
 #define _RGXCORE_KM_1_75_2_30_H_
 
-/***** Automatically generated file (26/08/2015 09:15:07): Do not edit manually ********************/
-/***** Timestamp:  (26/08/2015 09:15:07)************************************************************/
+/***** Automatically generated file (20/02/2017 07:01:19): Do not edit manually ********************/
+/***** Timestamp:  (20/02/2017 07:01:19)************************************************************/
 /***** CS: @2309075 ******************************************************************/
 
 
diff --git a/drivers/staging/imgtec/rogue/hwdefs/km/cores/rgxcore_km_1.76.4.6.h b/drivers/staging/imgtec/rogue/hwdefs/km/cores/rgxcore_km_1.76.4.6.h
index c7e04ed..b1127c8 100644
--- a/drivers/staging/imgtec/rogue/hwdefs/km/cores/rgxcore_km_1.76.4.6.h
+++ b/drivers/staging/imgtec/rogue/hwdefs/km/cores/rgxcore_km_1.76.4.6.h
@@ -42,8 +42,8 @@
 #ifndef _RGXCORE_KM_1_76_4_6_H_
 #define _RGXCORE_KM_1_76_4_6_H_
 
-/***** Automatically generated file (23/07/2015 09:37:59): Do not edit manually ********************/
-/***** Timestamp:  (23/07/2015 09:37:59)************************************************************/
+/***** Automatically generated file (20/02/2017 07:01:19): Do not edit manually ********************/
+/***** Timestamp:  (20/02/2017 07:01:19)************************************************************/
 /***** CS: @2318404 ******************************************************************/
 
 
diff --git a/drivers/staging/imgtec/rogue/hwdefs/km/cores/rgxcore_km_1.81.4.15.h b/drivers/staging/imgtec/rogue/hwdefs/km/cores/rgxcore_km_1.81.4.15.h
index 923c480..d27bf7f 100644
--- a/drivers/staging/imgtec/rogue/hwdefs/km/cores/rgxcore_km_1.81.4.15.h
+++ b/drivers/staging/imgtec/rogue/hwdefs/km/cores/rgxcore_km_1.81.4.15.h
@@ -42,8 +42,8 @@
 #ifndef _RGXCORE_KM_1_81_4_15_H_
 #define _RGXCORE_KM_1_81_4_15_H_
 
-/***** Automatically generated file (26/08/2015 09:15:07): Do not edit manually ********************/
-/***** Timestamp:  (26/08/2015 09:15:07)************************************************************/
+/***** Automatically generated file (20/02/2017 07:01:19): Do not edit manually ********************/
+/***** Timestamp:  (20/02/2017 07:01:19)************************************************************/
 /***** CS: @2373516 ******************************************************************/
 
 
diff --git a/drivers/staging/imgtec/rogue/hwdefs/km/cores/rgxcore_km_1.82.4.5.h b/drivers/staging/imgtec/rogue/hwdefs/km/cores/rgxcore_km_1.82.4.5.h
index 94632e3..8257262 100644
--- a/drivers/staging/imgtec/rogue/hwdefs/km/cores/rgxcore_km_1.82.4.5.h
+++ b/drivers/staging/imgtec/rogue/hwdefs/km/cores/rgxcore_km_1.82.4.5.h
@@ -42,8 +42,8 @@
 #ifndef _RGXCORE_KM_1_82_4_5_H_
 #define _RGXCORE_KM_1_82_4_5_H_
 
-/***** Automatically generated file (23/07/2015 09:37:59): Do not edit manually ********************/
-/***** Timestamp:  (23/07/2015 09:37:59)************************************************************/
+/***** Automatically generated file (20/02/2017 07:01:20): Do not edit manually ********************/
+/***** Timestamp:  (20/02/2017 07:01:20)************************************************************/
 /***** CS: @2503111 ******************************************************************/
 
 
diff --git a/drivers/staging/imgtec/rogue/hwdefs/km/cores/rgxcore_km_4.32.2.52.h b/drivers/staging/imgtec/rogue/hwdefs/km/cores/rgxcore_km_10.22.4.25.h
similarity index 83%
copy from drivers/staging/imgtec/rogue/hwdefs/km/cores/rgxcore_km_4.32.2.52.h
copy to drivers/staging/imgtec/rogue/hwdefs/km/cores/rgxcore_km_10.22.4.25.h
index 8455edc..fb30e17 100644
--- a/drivers/staging/imgtec/rogue/hwdefs/km/cores/rgxcore_km_4.32.2.52.h
+++ b/drivers/staging/imgtec/rogue/hwdefs/km/cores/rgxcore_km_10.22.4.25.h
@@ -1,5 +1,5 @@
 /*************************************************************************/ /*!
-@Title          RGX Core BVNC 4.32.2.52
+@Title          RGX Core BVNC 10.22.4.25
 @Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
 @License        Dual MIT/GPLv2
 
@@ -39,29 +39,27 @@
 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */ /**************************************************************************/
 
-#ifndef _RGXCORE_KM_4_32_2_52_H_
-#define _RGXCORE_KM_4_32_2_52_H_
+#ifndef _RGXCORE_KM_10_22_4_25_H_
+#define _RGXCORE_KM_10_22_4_25_H_
 
-/***** Automatically generated file (07/09/2015 09:24:24): Do not edit manually ********************/
-/***** Timestamp:  (07/09/2015 09:24:24)************************************************************/
-/***** CS: @2966609 ******************************************************************/
+/***** Automatically generated file (29/11/2016 07:01:41): Do not edit manually ********************/
+/***** Timestamp:  (29/11/2016 07:01:41)************************************************************/
+/***** CS: @3943572 ******************************************************************/
 
 
 /******************************************************************************
- * BVNC = 4.32.2.52 
+ * BVNC = 10.22.4.25 
  *****************************************************************************/
-#define RGX_BVNC_KM_B 4
-#define RGX_BVNC_KM_V 32
-#define RGX_BVNC_KM_N 2
-#define RGX_BVNC_KM_C 52
+#define RGX_BVNC_KM_B 10
+#define RGX_BVNC_KM_V 22
+#define RGX_BVNC_KM_N 4
+#define RGX_BVNC_KM_C 25
 
 /******************************************************************************
  * Errata 
  *****************************************************************************/
 
-#define FIX_HW_BRN_50767
-#define FIX_HW_BRN_54441
-#define FIX_HW_BRN_57193
+#define FIX_HW_BRN_62204
 
 
  
@@ -71,7 +69,11 @@
 #define HW_ERN_36400
 #define HW_ERN_42290
 #define HW_ERN_42606
+#define HW_ERN_45914
+#define HW_ERN_46066
+#define HW_ERN_47025
+#define HW_ERN_50539
 
 
 
-#endif /* _RGXCORE_KM_4_32_2_52_H_ */
+#endif /* _RGXCORE_KM_10_22_4_25_H_ */
diff --git a/drivers/staging/imgtec/rogue/hwdefs/km/cores/rgxcore_km_4.32.2.52.h b/drivers/staging/imgtec/rogue/hwdefs/km/cores/rgxcore_km_10.30.2.26.h
similarity index 84%
copy from drivers/staging/imgtec/rogue/hwdefs/km/cores/rgxcore_km_4.32.2.52.h
copy to drivers/staging/imgtec/rogue/hwdefs/km/cores/rgxcore_km_10.30.2.26.h
index 8455edc..792da6d 100644
--- a/drivers/staging/imgtec/rogue/hwdefs/km/cores/rgxcore_km_4.32.2.52.h
+++ b/drivers/staging/imgtec/rogue/hwdefs/km/cores/rgxcore_km_10.30.2.26.h
@@ -1,5 +1,5 @@
 /*************************************************************************/ /*!
-@Title          RGX Core BVNC 4.32.2.52
+@Title          RGX Core BVNC 10.30.2.26
 @Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
 @License        Dual MIT/GPLv2
 
@@ -39,29 +39,27 @@
 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */ /**************************************************************************/
 
-#ifndef _RGXCORE_KM_4_32_2_52_H_
-#define _RGXCORE_KM_4_32_2_52_H_
+#ifndef _RGXCORE_KM_10_30_2_26_H_
+#define _RGXCORE_KM_10_30_2_26_H_
 
-/***** Automatically generated file (07/09/2015 09:24:24): Do not edit manually ********************/
-/***** Timestamp:  (07/09/2015 09:24:24)************************************************************/
-/***** CS: @2966609 ******************************************************************/
+/***** Automatically generated file (23/02/2017 15:15:18): Do not edit manually ********************/
+/***** Timestamp:  (23/02/2017 15:15:18)************************************************************/
+/***** CS: @3943572 ******************************************************************/
 
 
 /******************************************************************************
- * BVNC = 4.32.2.52 
+ * BVNC = 10.30.2.26 
  *****************************************************************************/
-#define RGX_BVNC_KM_B 4
-#define RGX_BVNC_KM_V 32
+#define RGX_BVNC_KM_B 10
+#define RGX_BVNC_KM_V 30
 #define RGX_BVNC_KM_N 2
-#define RGX_BVNC_KM_C 52
+#define RGX_BVNC_KM_C 26
 
 /******************************************************************************
  * Errata 
  *****************************************************************************/
 
-#define FIX_HW_BRN_50767
-#define FIX_HW_BRN_54441
-#define FIX_HW_BRN_57193
+#define FIX_HW_BRN_62204
 
 
  
@@ -71,7 +69,11 @@
 #define HW_ERN_36400
 #define HW_ERN_42290
 #define HW_ERN_42606
+#define HW_ERN_45914
+#define HW_ERN_46066
+#define HW_ERN_47025
+#define HW_ERN_50539
 
 
 
-#endif /* _RGXCORE_KM_4_32_2_52_H_ */
+#endif /* _RGXCORE_KM_10_30_2_26_H_ */
diff --git a/drivers/staging/imgtec/rogue/hwdefs/km/cores/rgxcore_km_4.32.2.52.h b/drivers/staging/imgtec/rogue/hwdefs/km/cores/rgxcore_km_10.32.4.25.h
similarity index 84%
copy from drivers/staging/imgtec/rogue/hwdefs/km/cores/rgxcore_km_4.32.2.52.h
copy to drivers/staging/imgtec/rogue/hwdefs/km/cores/rgxcore_km_10.32.4.25.h
index 8455edc..1e2e194 100644
--- a/drivers/staging/imgtec/rogue/hwdefs/km/cores/rgxcore_km_4.32.2.52.h
+++ b/drivers/staging/imgtec/rogue/hwdefs/km/cores/rgxcore_km_10.32.4.25.h
@@ -1,5 +1,5 @@
 /*************************************************************************/ /*!
-@Title          RGX Core BVNC 4.32.2.52
+@Title          RGX Core BVNC 10.32.4.25
 @Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
 @License        Dual MIT/GPLv2
 
@@ -39,29 +39,27 @@
 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */ /**************************************************************************/
 
-#ifndef _RGXCORE_KM_4_32_2_52_H_
-#define _RGXCORE_KM_4_32_2_52_H_
+#ifndef _RGXCORE_KM_10_32_4_25_H_
+#define _RGXCORE_KM_10_32_4_25_H_
 
-/***** Automatically generated file (07/09/2015 09:24:24): Do not edit manually ********************/
-/***** Timestamp:  (07/09/2015 09:24:24)************************************************************/
-/***** CS: @2966609 ******************************************************************/
+/***** Automatically generated file (29/11/2016 07:01:41): Do not edit manually ********************/
+/***** Timestamp:  (29/11/2016 07:01:41)************************************************************/
+/***** CS: @3976602 ******************************************************************/
 
 
 /******************************************************************************
- * BVNC = 4.32.2.52 
+ * BVNC = 10.32.4.25 
  *****************************************************************************/
-#define RGX_BVNC_KM_B 4
+#define RGX_BVNC_KM_B 10
 #define RGX_BVNC_KM_V 32
-#define RGX_BVNC_KM_N 2
-#define RGX_BVNC_KM_C 52
+#define RGX_BVNC_KM_N 4
+#define RGX_BVNC_KM_C 25
 
 /******************************************************************************
  * Errata 
  *****************************************************************************/
 
-#define FIX_HW_BRN_50767
-#define FIX_HW_BRN_54441
-#define FIX_HW_BRN_57193
+#define FIX_HW_BRN_62204
 
 
  
@@ -71,7 +69,11 @@
 #define HW_ERN_36400
 #define HW_ERN_42290
 #define HW_ERN_42606
+#define HW_ERN_45914
+#define HW_ERN_46066
+#define HW_ERN_47025
+#define HW_ERN_50539
 
 
 
-#endif /* _RGXCORE_KM_4_32_2_52_H_ */
+#endif /* _RGXCORE_KM_10_32_4_25_H_ */
diff --git a/drivers/staging/imgtec/rogue/hwdefs/km/cores/rgxcore_km_4.32.2.52.h b/drivers/staging/imgtec/rogue/hwdefs/km/cores/rgxcore_km_10.33.4.25.h
similarity index 83%
copy from drivers/staging/imgtec/rogue/hwdefs/km/cores/rgxcore_km_4.32.2.52.h
copy to drivers/staging/imgtec/rogue/hwdefs/km/cores/rgxcore_km_10.33.4.25.h
index 8455edc..dc8198a 100644
--- a/drivers/staging/imgtec/rogue/hwdefs/km/cores/rgxcore_km_4.32.2.52.h
+++ b/drivers/staging/imgtec/rogue/hwdefs/km/cores/rgxcore_km_10.33.4.25.h
@@ -1,5 +1,5 @@
 /*************************************************************************/ /*!
-@Title          RGX Core BVNC 4.32.2.52
+@Title          RGX Core BVNC 10.33.4.25
 @Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
 @License        Dual MIT/GPLv2
 
@@ -39,29 +39,27 @@
 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */ /**************************************************************************/
 
-#ifndef _RGXCORE_KM_4_32_2_52_H_
-#define _RGXCORE_KM_4_32_2_52_H_
+#ifndef _RGXCORE_KM_10_33_4_25_H_
+#define _RGXCORE_KM_10_33_4_25_H_
 
-/***** Automatically generated file (07/09/2015 09:24:24): Do not edit manually ********************/
-/***** Timestamp:  (07/09/2015 09:24:24)************************************************************/
-/***** CS: @2966609 ******************************************************************/
+/***** Automatically generated file (23/02/2017 15:15:18): Do not edit manually ********************/
+/***** Timestamp:  (23/02/2017 15:15:18)************************************************************/
+/***** CS: @4036299 ******************************************************************/
 
 
 /******************************************************************************
- * BVNC = 4.32.2.52 
+ * BVNC = 10.33.4.25 
  *****************************************************************************/
-#define RGX_BVNC_KM_B 4
-#define RGX_BVNC_KM_V 32
-#define RGX_BVNC_KM_N 2
-#define RGX_BVNC_KM_C 52
+#define RGX_BVNC_KM_B 10
+#define RGX_BVNC_KM_V 33
+#define RGX_BVNC_KM_N 4
+#define RGX_BVNC_KM_C 25
 
 /******************************************************************************
  * Errata 
  *****************************************************************************/
 
-#define FIX_HW_BRN_50767
-#define FIX_HW_BRN_54441
-#define FIX_HW_BRN_57193
+#define FIX_HW_BRN_62204
 
 
  
@@ -71,7 +69,11 @@
 #define HW_ERN_36400
 #define HW_ERN_42290
 #define HW_ERN_42606
+#define HW_ERN_45914
+#define HW_ERN_46066
+#define HW_ERN_47025
+#define HW_ERN_50539
 
 
 
-#endif /* _RGXCORE_KM_4_32_2_52_H_ */
+#endif /* _RGXCORE_KM_10_33_4_25_H_ */
diff --git a/drivers/staging/imgtec/rogue/hwdefs/km/cores/rgxcore_km_12.4.1.48.h b/drivers/staging/imgtec/rogue/hwdefs/km/cores/rgxcore_km_12.4.1.48.h
index c1e7ada..0bf4b61 100644
--- a/drivers/staging/imgtec/rogue/hwdefs/km/cores/rgxcore_km_12.4.1.48.h
+++ b/drivers/staging/imgtec/rogue/hwdefs/km/cores/rgxcore_km_12.4.1.48.h
@@ -42,8 +42,8 @@
 #ifndef _RGXCORE_KM_12_4_1_48_H_
 #define _RGXCORE_KM_12_4_1_48_H_
 
-/***** Automatically generated file (26/08/2015 09:15:07): Do not edit manually ********************/
-/***** Timestamp:  (26/08/2015 09:15:07)************************************************************/
+/***** Automatically generated file (20/02/2017 07:01:18): Do not edit manually ********************/
+/***** Timestamp:  (20/02/2017 07:01:18)************************************************************/
 /***** CS: @2989295 ******************************************************************/
 
 
@@ -60,6 +60,8 @@
  *****************************************************************************/
 
 #define FIX_HW_BRN_38344
+#define FIX_HW_BRN_43276
+#define FIX_HW_BRN_44871
 
 
  
diff --git a/drivers/staging/imgtec/rogue/hwdefs/km/cores/rgxcore_km_12.5.1.20.h b/drivers/staging/imgtec/rogue/hwdefs/km/cores/rgxcore_km_12.5.1.20.h
index f7a02a8..33c05fd 100644
--- a/drivers/staging/imgtec/rogue/hwdefs/km/cores/rgxcore_km_12.5.1.20.h
+++ b/drivers/staging/imgtec/rogue/hwdefs/km/cores/rgxcore_km_12.5.1.20.h
@@ -42,8 +42,8 @@
 #ifndef _RGXCORE_KM_12_5_1_20_H_
 #define _RGXCORE_KM_12_5_1_20_H_
 
-/***** Automatically generated file (23/07/2015 09:38:00): Do not edit manually ********************/
-/***** Timestamp:  (23/07/2015 09:38:00)************************************************************/
+/***** Automatically generated file (20/02/2017 07:01:19): Do not edit manually ********************/
+/***** Timestamp:  (20/02/2017 07:01:19)************************************************************/
 /***** CS: @3146507 ******************************************************************/
 
 
@@ -59,6 +59,8 @@
  * Errata 
  *****************************************************************************/
 
+#define FIX_HW_BRN_43276
+#define FIX_HW_BRN_44871
 
 
  
diff --git a/drivers/staging/imgtec/rogue/hwdefs/km/cores/rgxcore_km_15.5.1.64.h b/drivers/staging/imgtec/rogue/hwdefs/km/cores/rgxcore_km_15.5.1.64.h
index f906923..c77946c 100644
--- a/drivers/staging/imgtec/rogue/hwdefs/km/cores/rgxcore_km_15.5.1.64.h
+++ b/drivers/staging/imgtec/rogue/hwdefs/km/cores/rgxcore_km_15.5.1.64.h
@@ -42,8 +42,8 @@
 #ifndef _RGXCORE_KM_15_5_1_64_H_
 #define _RGXCORE_KM_15_5_1_64_H_
 
-/***** Automatically generated file (11/12/2015 08:48:34): Do not edit manually ********************/
-/***** Timestamp:  (11/12/2015 08:48:34)************************************************************/
+/***** Automatically generated file (20/02/2017 07:01:20): Do not edit manually ********************/
+/***** Timestamp:  (20/02/2017 07:01:20)************************************************************/
 /***** CS: @3846532 ******************************************************************/
 
 
@@ -59,6 +59,8 @@
  * Errata 
  *****************************************************************************/
 
+#define FIX_HW_BRN_43276
+#define FIX_HW_BRN_44871
 
 
  
diff --git a/drivers/staging/imgtec/rogue/hwdefs/km/cores/rgxcore_km_4.32.2.52.h b/drivers/staging/imgtec/rogue/hwdefs/km/cores/rgxcore_km_22.18.22.22.h
similarity index 82%
copy from drivers/staging/imgtec/rogue/hwdefs/km/cores/rgxcore_km_4.32.2.52.h
copy to drivers/staging/imgtec/rogue/hwdefs/km/cores/rgxcore_km_22.18.22.22.h
index 8455edc..0558361 100644
--- a/drivers/staging/imgtec/rogue/hwdefs/km/cores/rgxcore_km_4.32.2.52.h
+++ b/drivers/staging/imgtec/rogue/hwdefs/km/cores/rgxcore_km_22.18.22.22.h
@@ -1,5 +1,5 @@
 /*************************************************************************/ /*!
-@Title          RGX Core BVNC 4.32.2.52
+@Title          RGX Core BVNC 22.18.22.22
 @Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
 @License        Dual MIT/GPLv2
 
@@ -39,29 +39,32 @@
 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */ /**************************************************************************/
 
-#ifndef _RGXCORE_KM_4_32_2_52_H_
-#define _RGXCORE_KM_4_32_2_52_H_
+#ifndef _RGXCORE_KM_22_18_22_22_H_
+#define _RGXCORE_KM_22_18_22_22_H_
 
-/***** Automatically generated file (07/09/2015 09:24:24): Do not edit manually ********************/
-/***** Timestamp:  (07/09/2015 09:24:24)************************************************************/
-/***** CS: @2966609 ******************************************************************/
+/***** Automatically generated file (20/02/2017 07:01:19): Do not edit manually ********************/
+/***** Timestamp:  (20/02/2017 07:01:19)************************************************************/
+/***** CS: @3872583 ******************************************************************/
 
 
 /******************************************************************************
- * BVNC = 4.32.2.52 
+ * BVNC = 22.18.22.22 
  *****************************************************************************/
-#define RGX_BVNC_KM_B 4
-#define RGX_BVNC_KM_V 32
-#define RGX_BVNC_KM_N 2
-#define RGX_BVNC_KM_C 52
+#define RGX_BVNC_KM_B 22
+#define RGX_BVNC_KM_V 18
+#define RGX_BVNC_KM_N 22
+#define RGX_BVNC_KM_C 22
 
 /******************************************************************************
  * Errata 
  *****************************************************************************/
 
-#define FIX_HW_BRN_50767
-#define FIX_HW_BRN_54441
-#define FIX_HW_BRN_57193
+#define FIX_HW_BRN_43276
+#define FIX_HW_BRN_44871
+#define FIX_HW_BRN_55091
+#define FIX_HW_BRN_60084
+#define FIX_HW_BRN_61450
+#define FIX_HW_BRN_63027
 
 
  
@@ -69,9 +72,8 @@
  * Enhancements 
  *****************************************************************************/
 #define HW_ERN_36400
-#define HW_ERN_42290
 #define HW_ERN_42606
 
 
 
-#endif /* _RGXCORE_KM_4_32_2_52_H_ */
+#endif /* _RGXCORE_KM_22_18_22_22_H_ */
diff --git a/drivers/staging/imgtec/rogue/hwdefs/km/cores/rgxcore_km_4.32.2.52.h b/drivers/staging/imgtec/rogue/hwdefs/km/cores/rgxcore_km_22.26.54.24.h
similarity index 81%
copy from drivers/staging/imgtec/rogue/hwdefs/km/cores/rgxcore_km_4.32.2.52.h
copy to drivers/staging/imgtec/rogue/hwdefs/km/cores/rgxcore_km_22.26.54.24.h
index 8455edc..297215e 100644
--- a/drivers/staging/imgtec/rogue/hwdefs/km/cores/rgxcore_km_4.32.2.52.h
+++ b/drivers/staging/imgtec/rogue/hwdefs/km/cores/rgxcore_km_22.26.54.24.h
@@ -1,5 +1,5 @@
 /*************************************************************************/ /*!
-@Title          RGX Core BVNC 4.32.2.52
+@Title          RGX Core BVNC 22.26.54.24
 @Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
 @License        Dual MIT/GPLv2
 
@@ -39,29 +39,32 @@
 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */ /**************************************************************************/
 
-#ifndef _RGXCORE_KM_4_32_2_52_H_
-#define _RGXCORE_KM_4_32_2_52_H_
+#ifndef _RGXCORE_KM_22_26_54_24_H_
+#define _RGXCORE_KM_22_26_54_24_H_
 
-/***** Automatically generated file (07/09/2015 09:24:24): Do not edit manually ********************/
-/***** Timestamp:  (07/09/2015 09:24:24)************************************************************/
-/***** CS: @2966609 ******************************************************************/
+/***** Automatically generated file (20/02/2017 07:01:19): Do not edit manually ********************/
+/***** Timestamp:  (20/02/2017 07:01:19)************************************************************/
+/***** CS: @3943204 ******************************************************************/
 
 
 /******************************************************************************
- * BVNC = 4.32.2.52 
+ * BVNC = 22.26.54.24 
  *****************************************************************************/
-#define RGX_BVNC_KM_B 4
-#define RGX_BVNC_KM_V 32
-#define RGX_BVNC_KM_N 2
-#define RGX_BVNC_KM_C 52
+#define RGX_BVNC_KM_B 22
+#define RGX_BVNC_KM_V 26
+#define RGX_BVNC_KM_N 54
+#define RGX_BVNC_KM_C 24
 
 /******************************************************************************
  * Errata 
  *****************************************************************************/
 
-#define FIX_HW_BRN_50767
-#define FIX_HW_BRN_54441
-#define FIX_HW_BRN_57193
+#define FIX_HW_BRN_43276
+#define FIX_HW_BRN_44871
+#define FIX_HW_BRN_55091
+#define FIX_HW_BRN_60084
+#define FIX_HW_BRN_61450
+#define FIX_HW_BRN_63027
 
 
  
@@ -69,9 +72,9 @@
  * Enhancements 
  *****************************************************************************/
 #define HW_ERN_36400
-#define HW_ERN_42290
 #define HW_ERN_42606
+#define HW_ERN_57596
 
 
 
-#endif /* _RGXCORE_KM_4_32_2_52_H_ */
+#endif /* _RGXCORE_KM_22_26_54_24_H_ */
diff --git a/drivers/staging/imgtec/rogue/hwdefs/km/cores/rgxcore_km_4.32.2.52.h b/drivers/staging/imgtec/rogue/hwdefs/km/cores/rgxcore_km_22.28.22.23.h
similarity index 81%
copy from drivers/staging/imgtec/rogue/hwdefs/km/cores/rgxcore_km_4.32.2.52.h
copy to drivers/staging/imgtec/rogue/hwdefs/km/cores/rgxcore_km_22.28.22.23.h
index 8455edc..8601045 100644
--- a/drivers/staging/imgtec/rogue/hwdefs/km/cores/rgxcore_km_4.32.2.52.h
+++ b/drivers/staging/imgtec/rogue/hwdefs/km/cores/rgxcore_km_22.28.22.23.h
@@ -1,5 +1,5 @@
 /*************************************************************************/ /*!
-@Title          RGX Core BVNC 4.32.2.52
+@Title          RGX Core BVNC 22.28.22.23
 @Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
 @License        Dual MIT/GPLv2
 
@@ -39,29 +39,32 @@
 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */ /**************************************************************************/
 
-#ifndef _RGXCORE_KM_4_32_2_52_H_
-#define _RGXCORE_KM_4_32_2_52_H_
+#ifndef _RGXCORE_KM_22_28_22_23_H_
+#define _RGXCORE_KM_22_28_22_23_H_
 
-/***** Automatically generated file (07/09/2015 09:24:24): Do not edit manually ********************/
-/***** Timestamp:  (07/09/2015 09:24:24)************************************************************/
-/***** CS: @2966609 ******************************************************************/
+/***** Automatically generated file (20/02/2017 07:01:20): Do not edit manually ********************/
+/***** Timestamp:  (20/02/2017 07:01:20)************************************************************/
+/***** CS: @3969181 ******************************************************************/
 
 
 /******************************************************************************
- * BVNC = 4.32.2.52 
+ * BVNC = 22.28.22.23 
  *****************************************************************************/
-#define RGX_BVNC_KM_B 4
-#define RGX_BVNC_KM_V 32
-#define RGX_BVNC_KM_N 2
-#define RGX_BVNC_KM_C 52
+#define RGX_BVNC_KM_B 22
+#define RGX_BVNC_KM_V 28
+#define RGX_BVNC_KM_N 22
+#define RGX_BVNC_KM_C 23
 
 /******************************************************************************
  * Errata 
  *****************************************************************************/
 
-#define FIX_HW_BRN_50767
-#define FIX_HW_BRN_54441
-#define FIX_HW_BRN_57193
+#define FIX_HW_BRN_43276
+#define FIX_HW_BRN_44871
+#define FIX_HW_BRN_55091
+#define FIX_HW_BRN_60084
+#define FIX_HW_BRN_61450
+#define FIX_HW_BRN_63027
 
 
  
@@ -69,9 +72,9 @@
  * Enhancements 
  *****************************************************************************/
 #define HW_ERN_36400
-#define HW_ERN_42290
 #define HW_ERN_42606
+#define HW_ERN_57596
 
 
 
-#endif /* _RGXCORE_KM_4_32_2_52_H_ */
+#endif /* _RGXCORE_KM_22_28_22_23_H_ */
diff --git a/drivers/staging/imgtec/rogue/hwdefs/km/cores/rgxcore_km_4.32.2.52.h b/drivers/staging/imgtec/rogue/hwdefs/km/cores/rgxcore_km_22.29.22.27.h
similarity index 81%
copy from drivers/staging/imgtec/rogue/hwdefs/km/cores/rgxcore_km_4.32.2.52.h
copy to drivers/staging/imgtec/rogue/hwdefs/km/cores/rgxcore_km_22.29.22.27.h
index 8455edc..604b0c7 100644
--- a/drivers/staging/imgtec/rogue/hwdefs/km/cores/rgxcore_km_4.32.2.52.h
+++ b/drivers/staging/imgtec/rogue/hwdefs/km/cores/rgxcore_km_22.29.22.27.h
@@ -1,5 +1,5 @@
 /*************************************************************************/ /*!
-@Title          RGX Core BVNC 4.32.2.52
+@Title          RGX Core BVNC 22.29.22.27
 @Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
 @License        Dual MIT/GPLv2
 
@@ -39,29 +39,32 @@
 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */ /**************************************************************************/
 
-#ifndef _RGXCORE_KM_4_32_2_52_H_
-#define _RGXCORE_KM_4_32_2_52_H_
+#ifndef _RGXCORE_KM_22_29_22_27_H_
+#define _RGXCORE_KM_22_29_22_27_H_
 
-/***** Automatically generated file (07/09/2015 09:24:24): Do not edit manually ********************/
-/***** Timestamp:  (07/09/2015 09:24:24)************************************************************/
-/***** CS: @2966609 ******************************************************************/
+/***** Automatically generated file (20/02/2017 07:01:20): Do not edit manually ********************/
+/***** Timestamp:  (20/02/2017 07:01:20)************************************************************/
+/***** CS: @3976753 ******************************************************************/
 
 
 /******************************************************************************
- * BVNC = 4.32.2.52 
+ * BVNC = 22.29.22.27 
  *****************************************************************************/
-#define RGX_BVNC_KM_B 4
-#define RGX_BVNC_KM_V 32
-#define RGX_BVNC_KM_N 2
-#define RGX_BVNC_KM_C 52
+#define RGX_BVNC_KM_B 22
+#define RGX_BVNC_KM_V 29
+#define RGX_BVNC_KM_N 22
+#define RGX_BVNC_KM_C 27
 
 /******************************************************************************
  * Errata 
  *****************************************************************************/
 
-#define FIX_HW_BRN_50767
-#define FIX_HW_BRN_54441
-#define FIX_HW_BRN_57193
+#define FIX_HW_BRN_43276
+#define FIX_HW_BRN_44871
+#define FIX_HW_BRN_55091
+#define FIX_HW_BRN_60084
+#define FIX_HW_BRN_61450
+#define FIX_HW_BRN_63027
 
 
  
@@ -69,9 +72,9 @@
  * Enhancements 
  *****************************************************************************/
 #define HW_ERN_36400
-#define HW_ERN_42290
 #define HW_ERN_42606
+#define HW_ERN_57596
 
 
 
-#endif /* _RGXCORE_KM_4_32_2_52_H_ */
+#endif /* _RGXCORE_KM_22_29_22_27_H_ */
diff --git a/drivers/staging/imgtec/rogue/hwdefs/km/cores/rgxcore_km_4.32.2.52.h b/drivers/staging/imgtec/rogue/hwdefs/km/cores/rgxcore_km_22.30.54.25.h
similarity index 81%
copy from drivers/staging/imgtec/rogue/hwdefs/km/cores/rgxcore_km_4.32.2.52.h
copy to drivers/staging/imgtec/rogue/hwdefs/km/cores/rgxcore_km_22.30.54.25.h
index 8455edc..9ffffd6 100644
--- a/drivers/staging/imgtec/rogue/hwdefs/km/cores/rgxcore_km_4.32.2.52.h
+++ b/drivers/staging/imgtec/rogue/hwdefs/km/cores/rgxcore_km_22.30.54.25.h
@@ -1,5 +1,5 @@
 /*************************************************************************/ /*!
-@Title          RGX Core BVNC 4.32.2.52
+@Title          RGX Core BVNC 22.30.54.25
 @Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
 @License        Dual MIT/GPLv2
 
@@ -39,29 +39,32 @@
 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */ /**************************************************************************/
 
-#ifndef _RGXCORE_KM_4_32_2_52_H_
-#define _RGXCORE_KM_4_32_2_52_H_
+#ifndef _RGXCORE_KM_22_30_54_25_H_
+#define _RGXCORE_KM_22_30_54_25_H_
 
-/***** Automatically generated file (07/09/2015 09:24:24): Do not edit manually ********************/
-/***** Timestamp:  (07/09/2015 09:24:24)************************************************************/
-/***** CS: @2966609 ******************************************************************/
+/***** Automatically generated file (20/02/2017 07:01:20): Do not edit manually ********************/
+/***** Timestamp:  (20/02/2017 07:01:20)************************************************************/
+/***** CS: @4086500 ******************************************************************/
 
 
 /******************************************************************************
- * BVNC = 4.32.2.52 
+ * BVNC = 22.30.54.25 
  *****************************************************************************/
-#define RGX_BVNC_KM_B 4
-#define RGX_BVNC_KM_V 32
-#define RGX_BVNC_KM_N 2
-#define RGX_BVNC_KM_C 52
+#define RGX_BVNC_KM_B 22
+#define RGX_BVNC_KM_V 30
+#define RGX_BVNC_KM_N 54
+#define RGX_BVNC_KM_C 25
 
 /******************************************************************************
  * Errata 
  *****************************************************************************/
 
-#define FIX_HW_BRN_50767
-#define FIX_HW_BRN_54441
-#define FIX_HW_BRN_57193
+#define FIX_HW_BRN_43276
+#define FIX_HW_BRN_44871
+#define FIX_HW_BRN_55091
+#define FIX_HW_BRN_60084
+#define FIX_HW_BRN_61450
+#define FIX_HW_BRN_63027
 
 
  
@@ -69,9 +72,9 @@
  * Enhancements 
  *****************************************************************************/
 #define HW_ERN_36400
-#define HW_ERN_42290
 #define HW_ERN_42606
+#define HW_ERN_57596
 
 
 
-#endif /* _RGXCORE_KM_4_32_2_52_H_ */
+#endif /* _RGXCORE_KM_22_30_54_25_H_ */
diff --git a/drivers/staging/imgtec/rogue/hwdefs/km/cores/rgxcore_km_4.32.2.52.h b/drivers/staging/imgtec/rogue/hwdefs/km/cores/rgxcore_km_22.32.54.328.h
similarity index 82%
copy from drivers/staging/imgtec/rogue/hwdefs/km/cores/rgxcore_km_4.32.2.52.h
copy to drivers/staging/imgtec/rogue/hwdefs/km/cores/rgxcore_km_22.32.54.328.h
index 8455edc..0b88fd9 100644
--- a/drivers/staging/imgtec/rogue/hwdefs/km/cores/rgxcore_km_4.32.2.52.h
+++ b/drivers/staging/imgtec/rogue/hwdefs/km/cores/rgxcore_km_22.32.54.328.h
@@ -1,5 +1,5 @@
 /*************************************************************************/ /*!
-@Title          RGX Core BVNC 4.32.2.52
+@Title          RGX Core BVNC 22.32.54.328
 @Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
 @License        Dual MIT/GPLv2
 
@@ -39,29 +39,32 @@
 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */ /**************************************************************************/
 
-#ifndef _RGXCORE_KM_4_32_2_52_H_
-#define _RGXCORE_KM_4_32_2_52_H_
+#ifndef _RGXCORE_KM_22_32_54_328_H_
+#define _RGXCORE_KM_22_32_54_328_H_
 
-/***** Automatically generated file (07/09/2015 09:24:24): Do not edit manually ********************/
-/***** Timestamp:  (07/09/2015 09:24:24)************************************************************/
-/***** CS: @2966609 ******************************************************************/
+/***** Automatically generated file (20/02/2017 07:01:20): Do not edit manually ********************/
+/***** Timestamp:  (20/02/2017 07:01:20)************************************************************/
+/***** CS: @4048608 ******************************************************************/
 
 
 /******************************************************************************
- * BVNC = 4.32.2.52 
+ * BVNC = 22.32.54.328 
  *****************************************************************************/
-#define RGX_BVNC_KM_B 4
+#define RGX_BVNC_KM_B 22
 #define RGX_BVNC_KM_V 32
-#define RGX_BVNC_KM_N 2
-#define RGX_BVNC_KM_C 52
+#define RGX_BVNC_KM_N 54
+#define RGX_BVNC_KM_C 328
 
 /******************************************************************************
  * Errata 
  *****************************************************************************/
 
-#define FIX_HW_BRN_50767
-#define FIX_HW_BRN_54441
-#define FIX_HW_BRN_57193
+#define FIX_HW_BRN_43276
+#define FIX_HW_BRN_44871
+#define FIX_HW_BRN_55091
+#define FIX_HW_BRN_60084
+#define FIX_HW_BRN_61450
+#define FIX_HW_BRN_63027
 
 
  
@@ -74,4 +77,4 @@
 
 
 
-#endif /* _RGXCORE_KM_4_32_2_52_H_ */
+#endif /* _RGXCORE_KM_22_32_54_328_H_ */
diff --git a/drivers/staging/imgtec/rogue/hwdefs/km/cores/rgxcore_km_4.32.2.52.h b/drivers/staging/imgtec/rogue/hwdefs/km/cores/rgxcore_km_22.33.21.11.h
similarity index 81%
copy from drivers/staging/imgtec/rogue/hwdefs/km/cores/rgxcore_km_4.32.2.52.h
copy to drivers/staging/imgtec/rogue/hwdefs/km/cores/rgxcore_km_22.33.21.11.h
index 8455edc..e89e8966 100644
--- a/drivers/staging/imgtec/rogue/hwdefs/km/cores/rgxcore_km_4.32.2.52.h
+++ b/drivers/staging/imgtec/rogue/hwdefs/km/cores/rgxcore_km_22.33.21.11.h
@@ -1,5 +1,5 @@
 /*************************************************************************/ /*!
-@Title          RGX Core BVNC 4.32.2.52
+@Title          RGX Core BVNC 22.33.21.11
 @Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
 @License        Dual MIT/GPLv2
 
@@ -39,29 +39,32 @@
 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */ /**************************************************************************/
 
-#ifndef _RGXCORE_KM_4_32_2_52_H_
-#define _RGXCORE_KM_4_32_2_52_H_
+#ifndef _RGXCORE_KM_22_33_21_11_H_
+#define _RGXCORE_KM_22_33_21_11_H_
 
-/***** Automatically generated file (07/09/2015 09:24:24): Do not edit manually ********************/
-/***** Timestamp:  (07/09/2015 09:24:24)************************************************************/
-/***** CS: @2966609 ******************************************************************/
+/***** Automatically generated file (20/02/2017 07:01:19): Do not edit manually ********************/
+/***** Timestamp:  (20/02/2017 07:01:19)************************************************************/
+/***** CS: @4048565 ******************************************************************/
 
 
 /******************************************************************************
- * BVNC = 4.32.2.52 
+ * BVNC = 22.33.21.11 
  *****************************************************************************/
-#define RGX_BVNC_KM_B 4
-#define RGX_BVNC_KM_V 32
-#define RGX_BVNC_KM_N 2
-#define RGX_BVNC_KM_C 52
+#define RGX_BVNC_KM_B 22
+#define RGX_BVNC_KM_V 33
+#define RGX_BVNC_KM_N 21
+#define RGX_BVNC_KM_C 11
 
 /******************************************************************************
  * Errata 
  *****************************************************************************/
 
-#define FIX_HW_BRN_50767
-#define FIX_HW_BRN_54441
-#define FIX_HW_BRN_57193
+#define FIX_HW_BRN_43276
+#define FIX_HW_BRN_44871
+#define FIX_HW_BRN_55091
+#define FIX_HW_BRN_60084
+#define FIX_HW_BRN_61450
+#define FIX_HW_BRN_63027
 
 
  
@@ -69,9 +72,9 @@
  * Enhancements 
  *****************************************************************************/
 #define HW_ERN_36400
-#define HW_ERN_42290
 #define HW_ERN_42606
+#define HW_ERN_57596
 
 
 
-#endif /* _RGXCORE_KM_4_32_2_52_H_ */
+#endif /* _RGXCORE_KM_22_33_21_11_H_ */
diff --git a/drivers/staging/imgtec/rogue/hwdefs/km/cores/rgxcore_km_4.32.2.52.h b/drivers/staging/imgtec/rogue/hwdefs/km/cores/rgxcore_km_22.35.22.27.h
similarity index 81%
copy from drivers/staging/imgtec/rogue/hwdefs/km/cores/rgxcore_km_4.32.2.52.h
copy to drivers/staging/imgtec/rogue/hwdefs/km/cores/rgxcore_km_22.35.22.27.h
index 8455edc..de7022c 100644
--- a/drivers/staging/imgtec/rogue/hwdefs/km/cores/rgxcore_km_4.32.2.52.h
+++ b/drivers/staging/imgtec/rogue/hwdefs/km/cores/rgxcore_km_22.35.22.27.h
@@ -1,5 +1,5 @@
 /*************************************************************************/ /*!
-@Title          RGX Core BVNC 4.32.2.52
+@Title          RGX Core BVNC 22.35.22.27
 @Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
 @License        Dual MIT/GPLv2
 
@@ -39,29 +39,32 @@
 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */ /**************************************************************************/
 
-#ifndef _RGXCORE_KM_4_32_2_52_H_
-#define _RGXCORE_KM_4_32_2_52_H_
+#ifndef _RGXCORE_KM_22_35_22_27_H_
+#define _RGXCORE_KM_22_35_22_27_H_
 
-/***** Automatically generated file (07/09/2015 09:24:24): Do not edit manually ********************/
-/***** Timestamp:  (07/09/2015 09:24:24)************************************************************/
-/***** CS: @2966609 ******************************************************************/
+/***** Automatically generated file (20/02/2017 07:01:19): Do not edit manually ********************/
+/***** Timestamp:  (20/02/2017 07:01:19)************************************************************/
+/***** CS: @4005275 ******************************************************************/
 
 
 /******************************************************************************
- * BVNC = 4.32.2.52 
+ * BVNC = 22.35.22.27 
  *****************************************************************************/
-#define RGX_BVNC_KM_B 4
-#define RGX_BVNC_KM_V 32
-#define RGX_BVNC_KM_N 2
-#define RGX_BVNC_KM_C 52
+#define RGX_BVNC_KM_B 22
+#define RGX_BVNC_KM_V 35
+#define RGX_BVNC_KM_N 22
+#define RGX_BVNC_KM_C 27
 
 /******************************************************************************
  * Errata 
  *****************************************************************************/
 
-#define FIX_HW_BRN_50767
-#define FIX_HW_BRN_54441
-#define FIX_HW_BRN_57193
+#define FIX_HW_BRN_43276
+#define FIX_HW_BRN_44871
+#define FIX_HW_BRN_55091
+#define FIX_HW_BRN_60084
+#define FIX_HW_BRN_61450
+#define FIX_HW_BRN_63027
 
 
  
@@ -69,9 +72,9 @@
  * Enhancements 
  *****************************************************************************/
 #define HW_ERN_36400
-#define HW_ERN_42290
 #define HW_ERN_42606
+#define HW_ERN_57596
 
 
 
-#endif /* _RGXCORE_KM_4_32_2_52_H_ */
+#endif /* _RGXCORE_KM_22_35_22_27_H_ */
diff --git a/drivers/staging/imgtec/rogue/hwdefs/km/cores/rgxcore_km_4.32.2.52.h b/drivers/staging/imgtec/rogue/hwdefs/km/cores/rgxcore_km_22.40.54.30.h
similarity index 81%
copy from drivers/staging/imgtec/rogue/hwdefs/km/cores/rgxcore_km_4.32.2.52.h
copy to drivers/staging/imgtec/rogue/hwdefs/km/cores/rgxcore_km_22.40.54.30.h
index 8455edc..ac55756 100644
--- a/drivers/staging/imgtec/rogue/hwdefs/km/cores/rgxcore_km_4.32.2.52.h
+++ b/drivers/staging/imgtec/rogue/hwdefs/km/cores/rgxcore_km_22.40.54.30.h
@@ -1,5 +1,5 @@
 /*************************************************************************/ /*!
-@Title          RGX Core BVNC 4.32.2.52
+@Title          RGX Core BVNC 22.40.54.30
 @Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
 @License        Dual MIT/GPLv2
 
@@ -39,29 +39,32 @@
 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */ /**************************************************************************/
 
-#ifndef _RGXCORE_KM_4_32_2_52_H_
-#define _RGXCORE_KM_4_32_2_52_H_
+#ifndef _RGXCORE_KM_22_40_54_30_H_
+#define _RGXCORE_KM_22_40_54_30_H_
 
-/***** Automatically generated file (07/09/2015 09:24:24): Do not edit manually ********************/
-/***** Timestamp:  (07/09/2015 09:24:24)************************************************************/
-/***** CS: @2966609 ******************************************************************/
+/***** Automatically generated file (20/02/2017 07:01:20): Do not edit manually ********************/
+/***** Timestamp:  (20/02/2017 07:01:20)************************************************************/
+/***** CS: @4094817 ******************************************************************/
 
 
 /******************************************************************************
- * BVNC = 4.32.2.52 
+ * BVNC = 22.40.54.30 
  *****************************************************************************/
-#define RGX_BVNC_KM_B 4
-#define RGX_BVNC_KM_V 32
-#define RGX_BVNC_KM_N 2
-#define RGX_BVNC_KM_C 52
+#define RGX_BVNC_KM_B 22
+#define RGX_BVNC_KM_V 40
+#define RGX_BVNC_KM_N 54
+#define RGX_BVNC_KM_C 30
 
 /******************************************************************************
  * Errata 
  *****************************************************************************/
 
-#define FIX_HW_BRN_50767
-#define FIX_HW_BRN_54441
-#define FIX_HW_BRN_57193
+#define FIX_HW_BRN_43276
+#define FIX_HW_BRN_44871
+#define FIX_HW_BRN_55091
+#define FIX_HW_BRN_60084
+#define FIX_HW_BRN_61450
+#define FIX_HW_BRN_63027
 
 
  
@@ -69,9 +72,9 @@
  * Enhancements 
  *****************************************************************************/
 #define HW_ERN_36400
-#define HW_ERN_42290
 #define HW_ERN_42606
+#define HW_ERN_57596
 
 
 
-#endif /* _RGXCORE_KM_4_32_2_52_H_ */
+#endif /* _RGXCORE_KM_22_40_54_30_H_ */
diff --git a/drivers/staging/imgtec/rogue/hwdefs/km/cores/rgxcore_km_4.32.2.52.h b/drivers/staging/imgtec/rogue/hwdefs/km/cores/rgxcore_km_22.41.54.330.h
similarity index 82%
copy from drivers/staging/imgtec/rogue/hwdefs/km/cores/rgxcore_km_4.32.2.52.h
copy to drivers/staging/imgtec/rogue/hwdefs/km/cores/rgxcore_km_22.41.54.330.h
index 8455edc..09f71a5 100644
--- a/drivers/staging/imgtec/rogue/hwdefs/km/cores/rgxcore_km_4.32.2.52.h
+++ b/drivers/staging/imgtec/rogue/hwdefs/km/cores/rgxcore_km_22.41.54.330.h
@@ -1,5 +1,5 @@
 /*************************************************************************/ /*!
-@Title          RGX Core BVNC 4.32.2.52
+@Title          RGX Core BVNC 22.41.54.330
 @Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
 @License        Dual MIT/GPLv2
 
@@ -39,29 +39,32 @@
 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */ /**************************************************************************/
 
-#ifndef _RGXCORE_KM_4_32_2_52_H_
-#define _RGXCORE_KM_4_32_2_52_H_
+#ifndef _RGXCORE_KM_22_41_54_330_H_
+#define _RGXCORE_KM_22_41_54_330_H_
 
-/***** Automatically generated file (07/09/2015 09:24:24): Do not edit manually ********************/
-/***** Timestamp:  (07/09/2015 09:24:24)************************************************************/
-/***** CS: @2966609 ******************************************************************/
+/***** Automatically generated file (20/02/2017 07:01:20): Do not edit manually ********************/
+/***** Timestamp:  (20/02/2017 07:01:20)************************************************************/
+/***** CS: @4075207 ******************************************************************/
 
 
 /******************************************************************************
- * BVNC = 4.32.2.52 
+ * BVNC = 22.41.54.330 
  *****************************************************************************/
-#define RGX_BVNC_KM_B 4
-#define RGX_BVNC_KM_V 32
-#define RGX_BVNC_KM_N 2
-#define RGX_BVNC_KM_C 52
+#define RGX_BVNC_KM_B 22
+#define RGX_BVNC_KM_V 41
+#define RGX_BVNC_KM_N 54
+#define RGX_BVNC_KM_C 330
 
 /******************************************************************************
  * Errata 
  *****************************************************************************/
 
-#define FIX_HW_BRN_50767
-#define FIX_HW_BRN_54441
-#define FIX_HW_BRN_57193
+#define FIX_HW_BRN_43276
+#define FIX_HW_BRN_44871
+#define FIX_HW_BRN_55091
+#define FIX_HW_BRN_60084
+#define FIX_HW_BRN_61450
+#define FIX_HW_BRN_63027
 
 
  
@@ -74,4 +77,4 @@
 
 
 
-#endif /* _RGXCORE_KM_4_32_2_52_H_ */
+#endif /* _RGXCORE_KM_22_41_54_330_H_ */
diff --git a/drivers/staging/imgtec/rogue/hwdefs/km/cores/rgxcore_km_4.32.2.52.h b/drivers/staging/imgtec/rogue/hwdefs/km/cores/rgxcore_km_22.44.22.25.h
similarity index 81%
copy from drivers/staging/imgtec/rogue/hwdefs/km/cores/rgxcore_km_4.32.2.52.h
copy to drivers/staging/imgtec/rogue/hwdefs/km/cores/rgxcore_km_22.44.22.25.h
index 8455edc..4a727f3 100644
--- a/drivers/staging/imgtec/rogue/hwdefs/km/cores/rgxcore_km_4.32.2.52.h
+++ b/drivers/staging/imgtec/rogue/hwdefs/km/cores/rgxcore_km_22.44.22.25.h
@@ -1,5 +1,5 @@
 /*************************************************************************/ /*!
-@Title          RGX Core BVNC 4.32.2.52
+@Title          RGX Core BVNC 22.44.22.25
 @Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
 @License        Dual MIT/GPLv2
 
@@ -39,29 +39,32 @@
 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */ /**************************************************************************/
 
-#ifndef _RGXCORE_KM_4_32_2_52_H_
-#define _RGXCORE_KM_4_32_2_52_H_
+#ifndef _RGXCORE_KM_22_44_22_25_H_
+#define _RGXCORE_KM_22_44_22_25_H_
 
-/***** Automatically generated file (07/09/2015 09:24:24): Do not edit manually ********************/
-/***** Timestamp:  (07/09/2015 09:24:24)************************************************************/
-/***** CS: @2966609 ******************************************************************/
+/***** Automatically generated file (20/02/2017 07:01:19): Do not edit manually ********************/
+/***** Timestamp:  (20/02/2017 07:01:19)************************************************************/
+/***** CS: @4137146 ******************************************************************/
 
 
 /******************************************************************************
- * BVNC = 4.32.2.52 
+ * BVNC = 22.44.22.25 
  *****************************************************************************/
-#define RGX_BVNC_KM_B 4
-#define RGX_BVNC_KM_V 32
-#define RGX_BVNC_KM_N 2
-#define RGX_BVNC_KM_C 52
+#define RGX_BVNC_KM_B 22
+#define RGX_BVNC_KM_V 44
+#define RGX_BVNC_KM_N 22
+#define RGX_BVNC_KM_C 25
 
 /******************************************************************************
  * Errata 
  *****************************************************************************/
 
-#define FIX_HW_BRN_50767
-#define FIX_HW_BRN_54441
-#define FIX_HW_BRN_57193
+#define FIX_HW_BRN_43276
+#define FIX_HW_BRN_44871
+#define FIX_HW_BRN_55091
+#define FIX_HW_BRN_60084
+#define FIX_HW_BRN_61450
+#define FIX_HW_BRN_63027
 
 
  
@@ -69,9 +72,9 @@
  * Enhancements 
  *****************************************************************************/
 #define HW_ERN_36400
-#define HW_ERN_42290
 #define HW_ERN_42606
+#define HW_ERN_57596
 
 
 
-#endif /* _RGXCORE_KM_4_32_2_52_H_ */
+#endif /* _RGXCORE_KM_22_44_22_25_H_ */
diff --git a/drivers/staging/imgtec/rogue/hwdefs/km/cores/rgxcore_km_4.32.2.52.h b/drivers/staging/imgtec/rogue/hwdefs/km/cores/rgxcore_km_22.45.22.29.h
similarity index 81%
copy from drivers/staging/imgtec/rogue/hwdefs/km/cores/rgxcore_km_4.32.2.52.h
copy to drivers/staging/imgtec/rogue/hwdefs/km/cores/rgxcore_km_22.45.22.29.h
index 8455edc..af23862 100644
--- a/drivers/staging/imgtec/rogue/hwdefs/km/cores/rgxcore_km_4.32.2.52.h
+++ b/drivers/staging/imgtec/rogue/hwdefs/km/cores/rgxcore_km_22.45.22.29.h
@@ -1,5 +1,5 @@
 /*************************************************************************/ /*!
-@Title          RGX Core BVNC 4.32.2.52
+@Title          RGX Core BVNC 22.45.22.29
 @Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
 @License        Dual MIT/GPLv2
 
@@ -39,29 +39,32 @@
 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */ /**************************************************************************/
 
-#ifndef _RGXCORE_KM_4_32_2_52_H_
-#define _RGXCORE_KM_4_32_2_52_H_
+#ifndef _RGXCORE_KM_22_45_22_29_H_
+#define _RGXCORE_KM_22_45_22_29_H_
 
-/***** Automatically generated file (07/09/2015 09:24:24): Do not edit manually ********************/
-/***** Timestamp:  (07/09/2015 09:24:24)************************************************************/
-/***** CS: @2966609 ******************************************************************/
+/***** Automatically generated file (20/02/2017 07:01:20): Do not edit manually ********************/
+/***** Timestamp:  (20/02/2017 07:01:20)************************************************************/
+/***** CS: @4127311 ******************************************************************/
 
 
 /******************************************************************************
- * BVNC = 4.32.2.52 
+ * BVNC = 22.45.22.29 
  *****************************************************************************/
-#define RGX_BVNC_KM_B 4
-#define RGX_BVNC_KM_V 32
-#define RGX_BVNC_KM_N 2
-#define RGX_BVNC_KM_C 52
+#define RGX_BVNC_KM_B 22
+#define RGX_BVNC_KM_V 45
+#define RGX_BVNC_KM_N 22
+#define RGX_BVNC_KM_C 29
 
 /******************************************************************************
  * Errata 
  *****************************************************************************/
 
-#define FIX_HW_BRN_50767
-#define FIX_HW_BRN_54441
-#define FIX_HW_BRN_57193
+#define FIX_HW_BRN_43276
+#define FIX_HW_BRN_44871
+#define FIX_HW_BRN_55091
+#define FIX_HW_BRN_60084
+#define FIX_HW_BRN_61450
+#define FIX_HW_BRN_63027
 
 
  
@@ -69,9 +72,9 @@
  * Enhancements 
  *****************************************************************************/
 #define HW_ERN_36400
-#define HW_ERN_42290
 #define HW_ERN_42606
+#define HW_ERN_57596
 
 
 
-#endif /* _RGXCORE_KM_4_32_2_52_H_ */
+#endif /* _RGXCORE_KM_22_45_22_29_H_ */
diff --git a/drivers/staging/imgtec/rogue/hwdefs/km/cores/rgxcore_km_4.32.2.52.h b/drivers/staging/imgtec/rogue/hwdefs/km/cores/rgxcore_km_22.46.54.330.h
similarity index 82%
copy from drivers/staging/imgtec/rogue/hwdefs/km/cores/rgxcore_km_4.32.2.52.h
copy to drivers/staging/imgtec/rogue/hwdefs/km/cores/rgxcore_km_22.46.54.330.h
index 8455edc..5899f5b 100644
--- a/drivers/staging/imgtec/rogue/hwdefs/km/cores/rgxcore_km_4.32.2.52.h
+++ b/drivers/staging/imgtec/rogue/hwdefs/km/cores/rgxcore_km_22.46.54.330.h
@@ -1,5 +1,5 @@
 /*************************************************************************/ /*!
-@Title          RGX Core BVNC 4.32.2.52
+@Title          RGX Core BVNC 22.46.54.330
 @Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
 @License        Dual MIT/GPLv2
 
@@ -39,29 +39,32 @@
 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */ /**************************************************************************/
 
-#ifndef _RGXCORE_KM_4_32_2_52_H_
-#define _RGXCORE_KM_4_32_2_52_H_
+#ifndef _RGXCORE_KM_22_46_54_330_H_
+#define _RGXCORE_KM_22_46_54_330_H_
 
-/***** Automatically generated file (07/09/2015 09:24:24): Do not edit manually ********************/
-/***** Timestamp:  (07/09/2015 09:24:24)************************************************************/
-/***** CS: @2966609 ******************************************************************/
+/***** Automatically generated file (20/02/2017 07:01:20): Do not edit manually ********************/
+/***** Timestamp:  (20/02/2017 07:01:20)************************************************************/
+/***** CS: @4136505 ******************************************************************/
 
 
 /******************************************************************************
- * BVNC = 4.32.2.52 
+ * BVNC = 22.46.54.330 
  *****************************************************************************/
-#define RGX_BVNC_KM_B 4
-#define RGX_BVNC_KM_V 32
-#define RGX_BVNC_KM_N 2
-#define RGX_BVNC_KM_C 52
+#define RGX_BVNC_KM_B 22
+#define RGX_BVNC_KM_V 46
+#define RGX_BVNC_KM_N 54
+#define RGX_BVNC_KM_C 330
 
 /******************************************************************************
  * Errata 
  *****************************************************************************/
 
-#define FIX_HW_BRN_50767
-#define FIX_HW_BRN_54441
-#define FIX_HW_BRN_57193
+#define FIX_HW_BRN_43276
+#define FIX_HW_BRN_44871
+#define FIX_HW_BRN_55091
+#define FIX_HW_BRN_60084
+#define FIX_HW_BRN_61450
+#define FIX_HW_BRN_63027
 
 
  
@@ -74,4 +77,4 @@
 
 
 
-#endif /* _RGXCORE_KM_4_32_2_52_H_ */
+#endif /* _RGXCORE_KM_22_46_54_330_H_ */
diff --git a/drivers/staging/imgtec/rogue/hwdefs/km/cores/rgxcore_km_4.32.2.52.h b/drivers/staging/imgtec/rogue/hwdefs/km/cores/rgxcore_km_22.47.208.312.h
similarity index 83%
copy from drivers/staging/imgtec/rogue/hwdefs/km/cores/rgxcore_km_4.32.2.52.h
copy to drivers/staging/imgtec/rogue/hwdefs/km/cores/rgxcore_km_22.47.208.312.h
index 8455edc..8053060 100644
--- a/drivers/staging/imgtec/rogue/hwdefs/km/cores/rgxcore_km_4.32.2.52.h
+++ b/drivers/staging/imgtec/rogue/hwdefs/km/cores/rgxcore_km_22.47.208.312.h
@@ -1,5 +1,5 @@
 /*************************************************************************/ /*!
-@Title          RGX Core BVNC 4.32.2.52
+@Title          RGX Core BVNC 22.47.208.312
 @Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
 @License        Dual MIT/GPLv2
 
@@ -39,29 +39,29 @@
 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */ /**************************************************************************/
 
-#ifndef _RGXCORE_KM_4_32_2_52_H_
-#define _RGXCORE_KM_4_32_2_52_H_
+#ifndef _RGXCORE_KM_22_47_208_312_H_
+#define _RGXCORE_KM_22_47_208_312_H_
 
-/***** Automatically generated file (07/09/2015 09:24:24): Do not edit manually ********************/
-/***** Timestamp:  (07/09/2015 09:24:24)************************************************************/
-/***** CS: @2966609 ******************************************************************/
+/***** Automatically generated file (20/02/2017 07:01:20): Do not edit manually ********************/
+/***** Timestamp:  (20/02/2017 07:01:20)************************************************************/
+/***** CS: @4202467 ******************************************************************/
 
 
 /******************************************************************************
- * BVNC = 4.32.2.52 
+ * BVNC = 22.47.208.312 
  *****************************************************************************/
-#define RGX_BVNC_KM_B 4
-#define RGX_BVNC_KM_V 32
-#define RGX_BVNC_KM_N 2
-#define RGX_BVNC_KM_C 52
+#define RGX_BVNC_KM_B 22
+#define RGX_BVNC_KM_V 47
+#define RGX_BVNC_KM_N 208
+#define RGX_BVNC_KM_C 312
 
 /******************************************************************************
  * Errata 
  *****************************************************************************/
 
-#define FIX_HW_BRN_50767
-#define FIX_HW_BRN_54441
-#define FIX_HW_BRN_57193
+#define FIX_HW_BRN_55091
+#define FIX_HW_BRN_61450
+#define FIX_HW_BRN_63027
 
 
  
@@ -74,4 +74,4 @@
 
 
 
-#endif /* _RGXCORE_KM_4_32_2_52_H_ */
+#endif /* _RGXCORE_KM_22_47_208_312_H_ */
diff --git a/drivers/staging/imgtec/rogue/hwdefs/km/cores/rgxcore_km_4.32.2.52.h b/drivers/staging/imgtec/rogue/hwdefs/km/cores/rgxcore_km_22.48.54.30.h
similarity index 81%
copy from drivers/staging/imgtec/rogue/hwdefs/km/cores/rgxcore_km_4.32.2.52.h
copy to drivers/staging/imgtec/rogue/hwdefs/km/cores/rgxcore_km_22.48.54.30.h
index 8455edc..809ba6e 100644
--- a/drivers/staging/imgtec/rogue/hwdefs/km/cores/rgxcore_km_4.32.2.52.h
+++ b/drivers/staging/imgtec/rogue/hwdefs/km/cores/rgxcore_km_22.48.54.30.h
@@ -1,5 +1,5 @@
 /*************************************************************************/ /*!
-@Title          RGX Core BVNC 4.32.2.52
+@Title          RGX Core BVNC 22.48.54.30
 @Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
 @License        Dual MIT/GPLv2
 
@@ -39,29 +39,32 @@
 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */ /**************************************************************************/
 
-#ifndef _RGXCORE_KM_4_32_2_52_H_
-#define _RGXCORE_KM_4_32_2_52_H_
+#ifndef _RGXCORE_KM_22_48_54_30_H_
+#define _RGXCORE_KM_22_48_54_30_H_
 
-/***** Automatically generated file (07/09/2015 09:24:24): Do not edit manually ********************/
-/***** Timestamp:  (07/09/2015 09:24:24)************************************************************/
-/***** CS: @2966609 ******************************************************************/
+/***** Automatically generated file (20/02/2017 07:01:18): Do not edit manually ********************/
+/***** Timestamp:  (20/02/2017 07:01:18)************************************************************/
+/***** CS: @4158661 ******************************************************************/
 
 
 /******************************************************************************
- * BVNC = 4.32.2.52 
+ * BVNC = 22.48.54.30 
  *****************************************************************************/
-#define RGX_BVNC_KM_B 4
-#define RGX_BVNC_KM_V 32
-#define RGX_BVNC_KM_N 2
-#define RGX_BVNC_KM_C 52
+#define RGX_BVNC_KM_B 22
+#define RGX_BVNC_KM_V 48
+#define RGX_BVNC_KM_N 54
+#define RGX_BVNC_KM_C 30
 
 /******************************************************************************
  * Errata 
  *****************************************************************************/
 
-#define FIX_HW_BRN_50767
-#define FIX_HW_BRN_54441
-#define FIX_HW_BRN_57193
+#define FIX_HW_BRN_43276
+#define FIX_HW_BRN_44871
+#define FIX_HW_BRN_55091
+#define FIX_HW_BRN_60084
+#define FIX_HW_BRN_61450
+#define FIX_HW_BRN_63027
 
 
  
@@ -69,9 +72,9 @@
  * Enhancements 
  *****************************************************************************/
 #define HW_ERN_36400
-#define HW_ERN_42290
 #define HW_ERN_42606
+#define HW_ERN_57596
 
 
 
-#endif /* _RGXCORE_KM_4_32_2_52_H_ */
+#endif /* _RGXCORE_KM_22_48_54_30_H_ */
diff --git a/drivers/staging/imgtec/rogue/hwdefs/km/cores/rgxcore_km_4.32.2.52.h b/drivers/staging/imgtec/rogue/hwdefs/km/cores/rgxcore_km_22.49.21.16.h
similarity index 82%
copy from drivers/staging/imgtec/rogue/hwdefs/km/cores/rgxcore_km_4.32.2.52.h
copy to drivers/staging/imgtec/rogue/hwdefs/km/cores/rgxcore_km_22.49.21.16.h
index 8455edc..f4b7d04 100644
--- a/drivers/staging/imgtec/rogue/hwdefs/km/cores/rgxcore_km_4.32.2.52.h
+++ b/drivers/staging/imgtec/rogue/hwdefs/km/cores/rgxcore_km_22.49.21.16.h
@@ -1,5 +1,5 @@
 /*************************************************************************/ /*!
-@Title          RGX Core BVNC 4.32.2.52
+@Title          RGX Core BVNC 22.49.21.16
 @Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
 @License        Dual MIT/GPLv2
 
@@ -39,29 +39,30 @@
 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */ /**************************************************************************/
 
-#ifndef _RGXCORE_KM_4_32_2_52_H_
-#define _RGXCORE_KM_4_32_2_52_H_
+#ifndef _RGXCORE_KM_22_49_21_16_H_
+#define _RGXCORE_KM_22_49_21_16_H_
 
-/***** Automatically generated file (07/09/2015 09:24:24): Do not edit manually ********************/
-/***** Timestamp:  (07/09/2015 09:24:24)************************************************************/
-/***** CS: @2966609 ******************************************************************/
+/***** Automatically generated file (20/02/2017 07:01:19): Do not edit manually ********************/
+/***** Timestamp:  (20/02/2017 07:01:19)************************************************************/
+/***** CS: @4158766 ******************************************************************/
 
 
 /******************************************************************************
- * BVNC = 4.32.2.52 
+ * BVNC = 22.49.21.16 
  *****************************************************************************/
-#define RGX_BVNC_KM_B 4
-#define RGX_BVNC_KM_V 32
-#define RGX_BVNC_KM_N 2
-#define RGX_BVNC_KM_C 52
+#define RGX_BVNC_KM_B 22
+#define RGX_BVNC_KM_V 49
+#define RGX_BVNC_KM_N 21
+#define RGX_BVNC_KM_C 16
 
 /******************************************************************************
  * Errata 
  *****************************************************************************/
 
-#define FIX_HW_BRN_50767
-#define FIX_HW_BRN_54441
-#define FIX_HW_BRN_57193
+#define FIX_HW_BRN_55091
+#define FIX_HW_BRN_60084
+#define FIX_HW_BRN_61450
+#define FIX_HW_BRN_63027
 
 
  
@@ -69,9 +70,9 @@
  * Enhancements 
  *****************************************************************************/
 #define HW_ERN_36400
-#define HW_ERN_42290
 #define HW_ERN_42606
+#define HW_ERN_57596
 
 
 
-#endif /* _RGXCORE_KM_4_32_2_52_H_ */
+#endif /* _RGXCORE_KM_22_49_21_16_H_ */
diff --git a/drivers/staging/imgtec/rogue/hwdefs/km/cores/rgxcore_km_4.32.2.52.h b/drivers/staging/imgtec/rogue/hwdefs/km/cores/rgxcore_km_22.50.22.29.h
similarity index 81%
copy from drivers/staging/imgtec/rogue/hwdefs/km/cores/rgxcore_km_4.32.2.52.h
copy to drivers/staging/imgtec/rogue/hwdefs/km/cores/rgxcore_km_22.50.22.29.h
index 8455edc..d6ee92b 100644
--- a/drivers/staging/imgtec/rogue/hwdefs/km/cores/rgxcore_km_4.32.2.52.h
+++ b/drivers/staging/imgtec/rogue/hwdefs/km/cores/rgxcore_km_22.50.22.29.h
@@ -1,5 +1,5 @@
 /*************************************************************************/ /*!
-@Title          RGX Core BVNC 4.32.2.52
+@Title          RGX Core BVNC 22.50.22.29
 @Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
 @License        Dual MIT/GPLv2
 
@@ -39,29 +39,32 @@
 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */ /**************************************************************************/
 
-#ifndef _RGXCORE_KM_4_32_2_52_H_
-#define _RGXCORE_KM_4_32_2_52_H_
+#ifndef _RGXCORE_KM_22_50_22_29_H_
+#define _RGXCORE_KM_22_50_22_29_H_
 
-/***** Automatically generated file (07/09/2015 09:24:24): Do not edit manually ********************/
-/***** Timestamp:  (07/09/2015 09:24:24)************************************************************/
-/***** CS: @2966609 ******************************************************************/
+/***** Automatically generated file (20/02/2017 07:01:20): Do not edit manually ********************/
+/***** Timestamp:  (20/02/2017 07:01:20)************************************************************/
+/***** CS: @4156423 ******************************************************************/
 
 
 /******************************************************************************
- * BVNC = 4.32.2.52 
+ * BVNC = 22.50.22.29 
  *****************************************************************************/
-#define RGX_BVNC_KM_B 4
-#define RGX_BVNC_KM_V 32
-#define RGX_BVNC_KM_N 2
-#define RGX_BVNC_KM_C 52
+#define RGX_BVNC_KM_B 22
+#define RGX_BVNC_KM_V 50
+#define RGX_BVNC_KM_N 22
+#define RGX_BVNC_KM_C 29
 
 /******************************************************************************
  * Errata 
  *****************************************************************************/
 
-#define FIX_HW_BRN_50767
-#define FIX_HW_BRN_54441
-#define FIX_HW_BRN_57193
+#define FIX_HW_BRN_43276
+#define FIX_HW_BRN_44871
+#define FIX_HW_BRN_55091
+#define FIX_HW_BRN_60084
+#define FIX_HW_BRN_61450
+#define FIX_HW_BRN_63027
 
 
  
@@ -69,9 +72,9 @@
  * Enhancements 
  *****************************************************************************/
 #define HW_ERN_36400
-#define HW_ERN_42290
 #define HW_ERN_42606
+#define HW_ERN_57596
 
 
 
-#endif /* _RGXCORE_KM_4_32_2_52_H_ */
+#endif /* _RGXCORE_KM_22_50_22_29_H_ */
diff --git a/drivers/staging/imgtec/rogue/hwdefs/km/cores/rgxcore_km_4.32.2.52.h b/drivers/staging/imgtec/rogue/hwdefs/km/cores/rgxcore_km_22.55.54.30.h
similarity index 82%
copy from drivers/staging/imgtec/rogue/hwdefs/km/cores/rgxcore_km_4.32.2.52.h
copy to drivers/staging/imgtec/rogue/hwdefs/km/cores/rgxcore_km_22.55.54.30.h
index 8455edc..8afd36f 100644
--- a/drivers/staging/imgtec/rogue/hwdefs/km/cores/rgxcore_km_4.32.2.52.h
+++ b/drivers/staging/imgtec/rogue/hwdefs/km/cores/rgxcore_km_22.55.54.30.h
@@ -1,5 +1,5 @@
 /*************************************************************************/ /*!
-@Title          RGX Core BVNC 4.32.2.52
+@Title          RGX Core BVNC 22.55.54.30
 @Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
 @License        Dual MIT/GPLv2
 
@@ -39,29 +39,31 @@
 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */ /**************************************************************************/
 
-#ifndef _RGXCORE_KM_4_32_2_52_H_
-#define _RGXCORE_KM_4_32_2_52_H_
+#ifndef _RGXCORE_KM_22_55_54_30_H_
+#define _RGXCORE_KM_22_55_54_30_H_
 
-/***** Automatically generated file (07/09/2015 09:24:24): Do not edit manually ********************/
-/***** Timestamp:  (07/09/2015 09:24:24)************************************************************/
-/***** CS: @2966609 ******************************************************************/
+/***** Automatically generated file (20/02/2017 07:01:19): Do not edit manually ********************/
+/***** Timestamp:  (20/02/2017 07:01:19)************************************************************/
+/***** CS: @4230075 ******************************************************************/
 
 
 /******************************************************************************
- * BVNC = 4.32.2.52 
+ * BVNC = 22.55.54.30 
  *****************************************************************************/
-#define RGX_BVNC_KM_B 4
-#define RGX_BVNC_KM_V 32
-#define RGX_BVNC_KM_N 2
-#define RGX_BVNC_KM_C 52
+#define RGX_BVNC_KM_B 22
+#define RGX_BVNC_KM_V 55
+#define RGX_BVNC_KM_N 54
+#define RGX_BVNC_KM_C 30
 
 /******************************************************************************
  * Errata 
  *****************************************************************************/
 
-#define FIX_HW_BRN_50767
-#define FIX_HW_BRN_54441
-#define FIX_HW_BRN_57193
+#define FIX_HW_BRN_43276
+#define FIX_HW_BRN_44871
+#define FIX_HW_BRN_55091
+#define FIX_HW_BRN_60084
+#define FIX_HW_BRN_63027
 
 
  
@@ -69,9 +71,9 @@
  * Enhancements 
  *****************************************************************************/
 #define HW_ERN_36400
-#define HW_ERN_42290
 #define HW_ERN_42606
+#define HW_ERN_57596
 
 
 
-#endif /* _RGXCORE_KM_4_32_2_52_H_ */
+#endif /* _RGXCORE_KM_22_55_54_30_H_ */
diff --git a/drivers/staging/imgtec/rogue/hwdefs/km/cores/rgxcore_km_4.32.2.52.h b/drivers/staging/imgtec/rogue/hwdefs/km/cores/rgxcore_km_22.57.54.30.h
similarity index 81%
copy from drivers/staging/imgtec/rogue/hwdefs/km/cores/rgxcore_km_4.32.2.52.h
copy to drivers/staging/imgtec/rogue/hwdefs/km/cores/rgxcore_km_22.57.54.30.h
index 8455edc..55d979f 100644
--- a/drivers/staging/imgtec/rogue/hwdefs/km/cores/rgxcore_km_4.32.2.52.h
+++ b/drivers/staging/imgtec/rogue/hwdefs/km/cores/rgxcore_km_22.57.54.30.h
@@ -1,5 +1,5 @@
 /*************************************************************************/ /*!
-@Title          RGX Core BVNC 4.32.2.52
+@Title          RGX Core BVNC 22.57.54.30
 @Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
 @License        Dual MIT/GPLv2
 
@@ -39,29 +39,31 @@
 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */ /**************************************************************************/
 
-#ifndef _RGXCORE_KM_4_32_2_52_H_
-#define _RGXCORE_KM_4_32_2_52_H_
+#ifndef _RGXCORE_KM_22_57_54_30_H_
+#define _RGXCORE_KM_22_57_54_30_H_
 
-/***** Automatically generated file (07/09/2015 09:24:24): Do not edit manually ********************/
-/***** Timestamp:  (07/09/2015 09:24:24)************************************************************/
-/***** CS: @2966609 ******************************************************************/
+/***** Automatically generated file (20/02/2017 07:01:20): Do not edit manually ********************/
+/***** Timestamp:  (20/02/2017 07:01:20)************************************************************/
+/***** CS: @4279085 ******************************************************************/
 
 
 /******************************************************************************
- * BVNC = 4.32.2.52 
+ * BVNC = 22.57.54.30 
  *****************************************************************************/
-#define RGX_BVNC_KM_B 4
-#define RGX_BVNC_KM_V 32
-#define RGX_BVNC_KM_N 2
-#define RGX_BVNC_KM_C 52
+#define RGX_BVNC_KM_B 22
+#define RGX_BVNC_KM_V 57
+#define RGX_BVNC_KM_N 54
+#define RGX_BVNC_KM_C 30
 
 /******************************************************************************
  * Errata 
  *****************************************************************************/
 
-#define FIX_HW_BRN_50767
-#define FIX_HW_BRN_54441
-#define FIX_HW_BRN_57193
+#define FIX_HW_BRN_43276
+#define FIX_HW_BRN_44871
+#define FIX_HW_BRN_55091
+#define FIX_HW_BRN_60084
+#define FIX_HW_BRN_63027
 
 
  
@@ -69,9 +71,10 @@
  * Enhancements 
  *****************************************************************************/
 #define HW_ERN_36400
-#define HW_ERN_42290
 #define HW_ERN_42606
+#define HW_ERN_57596
+#define HW_ERN_61389
 
 
 
-#endif /* _RGXCORE_KM_4_32_2_52_H_ */
+#endif /* _RGXCORE_KM_22_57_54_30_H_ */
diff --git a/drivers/staging/imgtec/rogue/hwdefs/km/cores/rgxcore_km_4.32.2.52.h b/drivers/staging/imgtec/rogue/hwdefs/km/cores/rgxcore_km_22.58.22.25.h
similarity index 82%
copy from drivers/staging/imgtec/rogue/hwdefs/km/cores/rgxcore_km_4.32.2.52.h
copy to drivers/staging/imgtec/rogue/hwdefs/km/cores/rgxcore_km_22.58.22.25.h
index 8455edc..167a279 100644
--- a/drivers/staging/imgtec/rogue/hwdefs/km/cores/rgxcore_km_4.32.2.52.h
+++ b/drivers/staging/imgtec/rogue/hwdefs/km/cores/rgxcore_km_22.58.22.25.h
@@ -1,5 +1,5 @@
 /*************************************************************************/ /*!
-@Title          RGX Core BVNC 4.32.2.52
+@Title          RGX Core BVNC 22.58.22.25
 @Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
 @License        Dual MIT/GPLv2
 
@@ -39,29 +39,30 @@
 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */ /**************************************************************************/
 
-#ifndef _RGXCORE_KM_4_32_2_52_H_
-#define _RGXCORE_KM_4_32_2_52_H_
+#ifndef _RGXCORE_KM_22_58_22_25_H_
+#define _RGXCORE_KM_22_58_22_25_H_
 
-/***** Automatically generated file (07/09/2015 09:24:24): Do not edit manually ********************/
-/***** Timestamp:  (07/09/2015 09:24:24)************************************************************/
-/***** CS: @2966609 ******************************************************************/
+/***** Automatically generated file (20/02/2017 07:01:19): Do not edit manually ********************/
+/***** Timestamp:  (20/02/2017 07:01:19)************************************************************/
+/***** CS: @4279077 ******************************************************************/
 
 
 /******************************************************************************
- * BVNC = 4.32.2.52 
+ * BVNC = 22.58.22.25 
  *****************************************************************************/
-#define RGX_BVNC_KM_B 4
-#define RGX_BVNC_KM_V 32
-#define RGX_BVNC_KM_N 2
-#define RGX_BVNC_KM_C 52
+#define RGX_BVNC_KM_B 22
+#define RGX_BVNC_KM_V 58
+#define RGX_BVNC_KM_N 22
+#define RGX_BVNC_KM_C 25
 
 /******************************************************************************
  * Errata 
  *****************************************************************************/
 
-#define FIX_HW_BRN_50767
-#define FIX_HW_BRN_54441
-#define FIX_HW_BRN_57193
+#define FIX_HW_BRN_43276
+#define FIX_HW_BRN_44871
+#define FIX_HW_BRN_55091
+#define FIX_HW_BRN_63027
 
 
  
@@ -69,9 +70,10 @@
  * Enhancements 
  *****************************************************************************/
 #define HW_ERN_36400
-#define HW_ERN_42290
 #define HW_ERN_42606
+#define HW_ERN_57596
+#define HW_ERN_61389
 
 
 
-#endif /* _RGXCORE_KM_4_32_2_52_H_ */
+#endif /* _RGXCORE_KM_22_58_22_25_H_ */
diff --git a/drivers/staging/imgtec/rogue/hwdefs/km/cores/rgxcore_km_4.32.2.52.h b/drivers/staging/imgtec/rogue/hwdefs/km/cores/rgxcore_km_22.59.54.30.h
similarity index 82%
copy from drivers/staging/imgtec/rogue/hwdefs/km/cores/rgxcore_km_4.32.2.52.h
copy to drivers/staging/imgtec/rogue/hwdefs/km/cores/rgxcore_km_22.59.54.30.h
index 8455edc..4324248 100644
--- a/drivers/staging/imgtec/rogue/hwdefs/km/cores/rgxcore_km_4.32.2.52.h
+++ b/drivers/staging/imgtec/rogue/hwdefs/km/cores/rgxcore_km_22.59.54.30.h
@@ -1,5 +1,5 @@
 /*************************************************************************/ /*!
-@Title          RGX Core BVNC 4.32.2.52
+@Title          RGX Core BVNC 22.59.54.30
 @Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
 @License        Dual MIT/GPLv2
 
@@ -39,29 +39,30 @@
 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */ /**************************************************************************/
 
-#ifndef _RGXCORE_KM_4_32_2_52_H_
-#define _RGXCORE_KM_4_32_2_52_H_
+#ifndef _RGXCORE_KM_22_59_54_30_H_
+#define _RGXCORE_KM_22_59_54_30_H_
 
-/***** Automatically generated file (07/09/2015 09:24:24): Do not edit manually ********************/
-/***** Timestamp:  (07/09/2015 09:24:24)************************************************************/
-/***** CS: @2966609 ******************************************************************/
+/***** Automatically generated file (20/02/2017 07:01:20): Do not edit manually ********************/
+/***** Timestamp:  (20/02/2017 07:01:20)************************************************************/
+/***** CS: @4317182 ******************************************************************/
 
 
 /******************************************************************************
- * BVNC = 4.32.2.52 
+ * BVNC = 22.59.54.30 
  *****************************************************************************/
-#define RGX_BVNC_KM_B 4
-#define RGX_BVNC_KM_V 32
-#define RGX_BVNC_KM_N 2
-#define RGX_BVNC_KM_C 52
+#define RGX_BVNC_KM_B 22
+#define RGX_BVNC_KM_V 59
+#define RGX_BVNC_KM_N 54
+#define RGX_BVNC_KM_C 30
 
 /******************************************************************************
  * Errata 
  *****************************************************************************/
 
-#define FIX_HW_BRN_50767
-#define FIX_HW_BRN_54441
-#define FIX_HW_BRN_57193
+#define FIX_HW_BRN_43276
+#define FIX_HW_BRN_44871
+#define FIX_HW_BRN_55091
+#define FIX_HW_BRN_63027
 
 
  
@@ -69,9 +70,10 @@
  * Enhancements 
  *****************************************************************************/
 #define HW_ERN_36400
-#define HW_ERN_42290
 #define HW_ERN_42606
+#define HW_ERN_57596
+#define HW_ERN_61389
 
 
 
-#endif /* _RGXCORE_KM_4_32_2_52_H_ */
+#endif /* _RGXCORE_KM_22_59_54_30_H_ */
diff --git a/drivers/staging/imgtec/rogue/hwdefs/km/cores/rgxcore_km_4.32.2.52.h b/drivers/staging/imgtec/rogue/hwdefs/km/cores/rgxcore_km_22.62.21.16.h
similarity index 83%
copy from drivers/staging/imgtec/rogue/hwdefs/km/cores/rgxcore_km_4.32.2.52.h
copy to drivers/staging/imgtec/rogue/hwdefs/km/cores/rgxcore_km_22.62.21.16.h
index 8455edc..1387449 100644
--- a/drivers/staging/imgtec/rogue/hwdefs/km/cores/rgxcore_km_4.32.2.52.h
+++ b/drivers/staging/imgtec/rogue/hwdefs/km/cores/rgxcore_km_22.62.21.16.h
@@ -1,5 +1,5 @@
 /*************************************************************************/ /*!
-@Title          RGX Core BVNC 4.32.2.52
+@Title          RGX Core BVNC 22.62.21.16
 @Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
 @License        Dual MIT/GPLv2
 
@@ -39,29 +39,28 @@
 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */ /**************************************************************************/
 
-#ifndef _RGXCORE_KM_4_32_2_52_H_
-#define _RGXCORE_KM_4_32_2_52_H_
+#ifndef _RGXCORE_KM_22_62_21_16_H_
+#define _RGXCORE_KM_22_62_21_16_H_
 
-/***** Automatically generated file (07/09/2015 09:24:24): Do not edit manually ********************/
-/***** Timestamp:  (07/09/2015 09:24:24)************************************************************/
-/***** CS: @2966609 ******************************************************************/
+/***** Automatically generated file (20/02/2017 07:01:19): Do not edit manually ********************/
+/***** Timestamp:  (20/02/2017 07:01:19)************************************************************/
+/***** CS: @4339985 ******************************************************************/
 
 
 /******************************************************************************
- * BVNC = 4.32.2.52 
+ * BVNC = 22.62.21.16 
  *****************************************************************************/
-#define RGX_BVNC_KM_B 4
-#define RGX_BVNC_KM_V 32
-#define RGX_BVNC_KM_N 2
-#define RGX_BVNC_KM_C 52
+#define RGX_BVNC_KM_B 22
+#define RGX_BVNC_KM_V 62
+#define RGX_BVNC_KM_N 21
+#define RGX_BVNC_KM_C 16
 
 /******************************************************************************
  * Errata 
  *****************************************************************************/
 
-#define FIX_HW_BRN_50767
-#define FIX_HW_BRN_54441
-#define FIX_HW_BRN_57193
+#define FIX_HW_BRN_55091
+#define FIX_HW_BRN_63027
 
 
  
@@ -69,9 +68,10 @@
  * Enhancements 
  *****************************************************************************/
 #define HW_ERN_36400
-#define HW_ERN_42290
 #define HW_ERN_42606
+#define HW_ERN_57596
+#define HW_ERN_61389
 
 
 
-#endif /* _RGXCORE_KM_4_32_2_52_H_ */
+#endif /* _RGXCORE_KM_22_62_21_16_H_ */
diff --git a/drivers/staging/imgtec/rogue/hwdefs/km/cores/rgxcore_km_4.32.2.52.h b/drivers/staging/imgtec/rogue/hwdefs/km/cores/rgxcore_km_22.63.54.330.h
similarity index 82%
copy from drivers/staging/imgtec/rogue/hwdefs/km/cores/rgxcore_km_4.32.2.52.h
copy to drivers/staging/imgtec/rogue/hwdefs/km/cores/rgxcore_km_22.63.54.330.h
index 8455edc..0c09802 100644
--- a/drivers/staging/imgtec/rogue/hwdefs/km/cores/rgxcore_km_4.32.2.52.h
+++ b/drivers/staging/imgtec/rogue/hwdefs/km/cores/rgxcore_km_22.63.54.330.h
@@ -1,5 +1,5 @@
 /*************************************************************************/ /*!
-@Title          RGX Core BVNC 4.32.2.52
+@Title          RGX Core BVNC 22.63.54.330
 @Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
 @License        Dual MIT/GPLv2
 
@@ -39,29 +39,30 @@
 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */ /**************************************************************************/
 
-#ifndef _RGXCORE_KM_4_32_2_52_H_
-#define _RGXCORE_KM_4_32_2_52_H_
+#ifndef _RGXCORE_KM_22_63_54_330_H_
+#define _RGXCORE_KM_22_63_54_330_H_
 
-/***** Automatically generated file (07/09/2015 09:24:24): Do not edit manually ********************/
-/***** Timestamp:  (07/09/2015 09:24:24)************************************************************/
-/***** CS: @2966609 ******************************************************************/
+/***** Automatically generated file (20/02/2017 07:01:19): Do not edit manually ********************/
+/***** Timestamp:  (20/02/2017 07:01:19)************************************************************/
+/***** CS: @4400526 ******************************************************************/
 
 
 /******************************************************************************
- * BVNC = 4.32.2.52 
+ * BVNC = 22.63.54.330 
  *****************************************************************************/
-#define RGX_BVNC_KM_B 4
-#define RGX_BVNC_KM_V 32
-#define RGX_BVNC_KM_N 2
-#define RGX_BVNC_KM_C 52
+#define RGX_BVNC_KM_B 22
+#define RGX_BVNC_KM_V 63
+#define RGX_BVNC_KM_N 54
+#define RGX_BVNC_KM_C 330
 
 /******************************************************************************
  * Errata 
  *****************************************************************************/
 
-#define FIX_HW_BRN_50767
-#define FIX_HW_BRN_54441
-#define FIX_HW_BRN_57193
+#define FIX_HW_BRN_43276
+#define FIX_HW_BRN_44871
+#define FIX_HW_BRN_55091
+#define FIX_HW_BRN_63027
 
 
  
@@ -71,7 +72,8 @@
 #define HW_ERN_36400
 #define HW_ERN_42290
 #define HW_ERN_42606
+#define HW_ERN_61389
 
 
 
-#endif /* _RGXCORE_KM_4_32_2_52_H_ */
+#endif /* _RGXCORE_KM_22_63_54_330_H_ */
diff --git a/drivers/staging/imgtec/rogue/hwdefs/km/cores/rgxcore_km_4.32.2.52.h b/drivers/staging/imgtec/rogue/hwdefs/km/cores/rgxcore_km_22.67.54.30.h
similarity index 81%
copy from drivers/staging/imgtec/rogue/hwdefs/km/cores/rgxcore_km_4.32.2.52.h
copy to drivers/staging/imgtec/rogue/hwdefs/km/cores/rgxcore_km_22.67.54.30.h
index 8455edc..d2d9e1c 100644
--- a/drivers/staging/imgtec/rogue/hwdefs/km/cores/rgxcore_km_4.32.2.52.h
+++ b/drivers/staging/imgtec/rogue/hwdefs/km/cores/rgxcore_km_22.67.54.30.h
@@ -1,5 +1,5 @@
 /*************************************************************************/ /*!
-@Title          RGX Core BVNC 4.32.2.52
+@Title          RGX Core BVNC 22.67.54.30
 @Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
 @License        Dual MIT/GPLv2
 
@@ -39,29 +39,31 @@
 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */ /**************************************************************************/
 
-#ifndef _RGXCORE_KM_4_32_2_52_H_
-#define _RGXCORE_KM_4_32_2_52_H_
+#ifndef _RGXCORE_KM_22_67_54_30_H_
+#define _RGXCORE_KM_22_67_54_30_H_
 
-/***** Automatically generated file (07/09/2015 09:24:24): Do not edit manually ********************/
-/***** Timestamp:  (07/09/2015 09:24:24)************************************************************/
-/***** CS: @2966609 ******************************************************************/
+/***** Automatically generated file (20/02/2017 07:01:18): Do not edit manually ********************/
+/***** Timestamp:  (20/02/2017 07:01:18)************************************************************/
+/***** CS: @4339986 ******************************************************************/
 
 
 /******************************************************************************
- * BVNC = 4.32.2.52 
+ * BVNC = 22.67.54.30 
  *****************************************************************************/
-#define RGX_BVNC_KM_B 4
-#define RGX_BVNC_KM_V 32
-#define RGX_BVNC_KM_N 2
-#define RGX_BVNC_KM_C 52
+#define RGX_BVNC_KM_B 22
+#define RGX_BVNC_KM_V 67
+#define RGX_BVNC_KM_N 54
+#define RGX_BVNC_KM_C 30
 
 /******************************************************************************
  * Errata 
  *****************************************************************************/
 
-#define FIX_HW_BRN_50767
-#define FIX_HW_BRN_54441
-#define FIX_HW_BRN_57193
+#define FIX_HW_BRN_43276
+#define FIX_HW_BRN_44871
+#define FIX_HW_BRN_55091
+#define FIX_HW_BRN_60084
+#define FIX_HW_BRN_63027
 
 
  
@@ -69,9 +71,10 @@
  * Enhancements 
  *****************************************************************************/
 #define HW_ERN_36400
-#define HW_ERN_42290
 #define HW_ERN_42606
+#define HW_ERN_57596
+#define HW_ERN_61389
 
 
 
-#endif /* _RGXCORE_KM_4_32_2_52_H_ */
+#endif /* _RGXCORE_KM_22_67_54_30_H_ */
diff --git a/drivers/staging/imgtec/rogue/hwdefs/km/cores/rgxcore_km_4.32.2.52.h b/drivers/staging/imgtec/rogue/hwdefs/km/cores/rgxcore_km_22.68.54.30.h
similarity index 82%
copy from drivers/staging/imgtec/rogue/hwdefs/km/cores/rgxcore_km_4.32.2.52.h
copy to drivers/staging/imgtec/rogue/hwdefs/km/cores/rgxcore_km_22.68.54.30.h
index 8455edc..2fc5275 100644
--- a/drivers/staging/imgtec/rogue/hwdefs/km/cores/rgxcore_km_4.32.2.52.h
+++ b/drivers/staging/imgtec/rogue/hwdefs/km/cores/rgxcore_km_22.68.54.30.h
@@ -1,5 +1,5 @@
 /*************************************************************************/ /*!
-@Title          RGX Core BVNC 4.32.2.52
+@Title          RGX Core BVNC 22.68.54.30
 @Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
 @License        Dual MIT/GPLv2
 
@@ -39,29 +39,30 @@
 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */ /**************************************************************************/
 
-#ifndef _RGXCORE_KM_4_32_2_52_H_
-#define _RGXCORE_KM_4_32_2_52_H_
+#ifndef _RGXCORE_KM_22_68_54_30_H_
+#define _RGXCORE_KM_22_68_54_30_H_
 
-/***** Automatically generated file (07/09/2015 09:24:24): Do not edit manually ********************/
-/***** Timestamp:  (07/09/2015 09:24:24)************************************************************/
-/***** CS: @2966609 ******************************************************************/
+/***** Automatically generated file (20/02/2017 07:01:19): Do not edit manually ********************/
+/***** Timestamp:  (20/02/2017 07:01:19)************************************************************/
+/***** CS: @4339984 ******************************************************************/
 
 
 /******************************************************************************
- * BVNC = 4.32.2.52 
+ * BVNC = 22.68.54.30 
  *****************************************************************************/
-#define RGX_BVNC_KM_B 4
-#define RGX_BVNC_KM_V 32
-#define RGX_BVNC_KM_N 2
-#define RGX_BVNC_KM_C 52
+#define RGX_BVNC_KM_B 22
+#define RGX_BVNC_KM_V 68
+#define RGX_BVNC_KM_N 54
+#define RGX_BVNC_KM_C 30
 
 /******************************************************************************
  * Errata 
  *****************************************************************************/
 
-#define FIX_HW_BRN_50767
-#define FIX_HW_BRN_54441
-#define FIX_HW_BRN_57193
+#define FIX_HW_BRN_43276
+#define FIX_HW_BRN_44871
+#define FIX_HW_BRN_55091
+#define FIX_HW_BRN_63027
 
 
  
@@ -69,9 +70,10 @@
  * Enhancements 
  *****************************************************************************/
 #define HW_ERN_36400
-#define HW_ERN_42290
 #define HW_ERN_42606
+#define HW_ERN_57596
+#define HW_ERN_61389
 
 
 
-#endif /* _RGXCORE_KM_4_32_2_52_H_ */
+#endif /* _RGXCORE_KM_22_68_54_30_H_ */
diff --git a/drivers/staging/imgtec/rogue/hwdefs/km/cores/rgxcore_km_4.32.2.52.h b/drivers/staging/imgtec/rogue/hwdefs/km/cores/rgxcore_km_22.69.22.25.h
similarity index 82%
copy from drivers/staging/imgtec/rogue/hwdefs/km/cores/rgxcore_km_4.32.2.52.h
copy to drivers/staging/imgtec/rogue/hwdefs/km/cores/rgxcore_km_22.69.22.25.h
index 8455edc..35b4fdb 100644
--- a/drivers/staging/imgtec/rogue/hwdefs/km/cores/rgxcore_km_4.32.2.52.h
+++ b/drivers/staging/imgtec/rogue/hwdefs/km/cores/rgxcore_km_22.69.22.25.h
@@ -1,5 +1,5 @@
 /*************************************************************************/ /*!
-@Title          RGX Core BVNC 4.32.2.52
+@Title          RGX Core BVNC 22.69.22.25
 @Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
 @License        Dual MIT/GPLv2
 
@@ -39,29 +39,30 @@
 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */ /**************************************************************************/
 
-#ifndef _RGXCORE_KM_4_32_2_52_H_
-#define _RGXCORE_KM_4_32_2_52_H_
+#ifndef _RGXCORE_KM_22_69_22_25_H_
+#define _RGXCORE_KM_22_69_22_25_H_
 
-/***** Automatically generated file (07/09/2015 09:24:24): Do not edit manually ********************/
-/***** Timestamp:  (07/09/2015 09:24:24)************************************************************/
-/***** CS: @2966609 ******************************************************************/
+/***** Automatically generated file (20/02/2017 07:01:19): Do not edit manually ********************/
+/***** Timestamp:  (20/02/2017 07:01:19)************************************************************/
+/***** CS: @4339983 ******************************************************************/
 
 
 /******************************************************************************
- * BVNC = 4.32.2.52 
+ * BVNC = 22.69.22.25 
  *****************************************************************************/
-#define RGX_BVNC_KM_B 4
-#define RGX_BVNC_KM_V 32
-#define RGX_BVNC_KM_N 2
-#define RGX_BVNC_KM_C 52
+#define RGX_BVNC_KM_B 22
+#define RGX_BVNC_KM_V 69
+#define RGX_BVNC_KM_N 22
+#define RGX_BVNC_KM_C 25
 
 /******************************************************************************
  * Errata 
  *****************************************************************************/
 
-#define FIX_HW_BRN_50767
-#define FIX_HW_BRN_54441
-#define FIX_HW_BRN_57193
+#define FIX_HW_BRN_43276
+#define FIX_HW_BRN_44871
+#define FIX_HW_BRN_55091
+#define FIX_HW_BRN_63027
 
 
  
@@ -69,9 +70,10 @@
  * Enhancements 
  *****************************************************************************/
 #define HW_ERN_36400
-#define HW_ERN_42290
 #define HW_ERN_42606
+#define HW_ERN_57596
+#define HW_ERN_61389
 
 
 
-#endif /* _RGXCORE_KM_4_32_2_52_H_ */
+#endif /* _RGXCORE_KM_22_69_22_25_H_ */
diff --git a/drivers/staging/imgtec/rogue/hwdefs/km/cores/rgxcore_km_4.32.2.52.h b/drivers/staging/imgtec/rogue/hwdefs/km/cores/rgxcore_km_22.70.208.316.h
similarity index 83%
copy from drivers/staging/imgtec/rogue/hwdefs/km/cores/rgxcore_km_4.32.2.52.h
copy to drivers/staging/imgtec/rogue/hwdefs/km/cores/rgxcore_km_22.70.208.316.h
index 8455edc..7d1dd70 100644
--- a/drivers/staging/imgtec/rogue/hwdefs/km/cores/rgxcore_km_4.32.2.52.h
+++ b/drivers/staging/imgtec/rogue/hwdefs/km/cores/rgxcore_km_22.70.208.316.h
@@ -1,5 +1,5 @@
 /*************************************************************************/ /*!
-@Title          RGX Core BVNC 4.32.2.52
+@Title          RGX Core BVNC 22.70.208.316
 @Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
 @License        Dual MIT/GPLv2
 
@@ -39,29 +39,28 @@
 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */ /**************************************************************************/
 
-#ifndef _RGXCORE_KM_4_32_2_52_H_
-#define _RGXCORE_KM_4_32_2_52_H_
+#ifndef _RGXCORE_KM_22_70_208_316_H_
+#define _RGXCORE_KM_22_70_208_316_H_
 
-/***** Automatically generated file (07/09/2015 09:24:24): Do not edit manually ********************/
-/***** Timestamp:  (07/09/2015 09:24:24)************************************************************/
-/***** CS: @2966609 ******************************************************************/
+/***** Automatically generated file (20/02/2017 07:01:19): Do not edit manually ********************/
+/***** Timestamp:  (20/02/2017 07:01:19)************************************************************/
+/***** CS: @4476117 ******************************************************************/
 
 
 /******************************************************************************
- * BVNC = 4.32.2.52 
+ * BVNC = 22.70.208.316 
  *****************************************************************************/
-#define RGX_BVNC_KM_B 4
-#define RGX_BVNC_KM_V 32
-#define RGX_BVNC_KM_N 2
-#define RGX_BVNC_KM_C 52
+#define RGX_BVNC_KM_B 22
+#define RGX_BVNC_KM_V 70
+#define RGX_BVNC_KM_N 208
+#define RGX_BVNC_KM_C 316
 
 /******************************************************************************
  * Errata 
  *****************************************************************************/
 
-#define FIX_HW_BRN_50767
-#define FIX_HW_BRN_54441
-#define FIX_HW_BRN_57193
+#define FIX_HW_BRN_55091
+#define FIX_HW_BRN_63027
 
 
  
@@ -71,7 +70,8 @@
 #define HW_ERN_36400
 #define HW_ERN_42290
 #define HW_ERN_42606
+#define HW_ERN_61389
 
 
 
-#endif /* _RGXCORE_KM_4_32_2_52_H_ */
+#endif /* _RGXCORE_KM_22_70_208_316_H_ */
diff --git a/drivers/staging/imgtec/rogue/hwdefs/km/cores/rgxcore_km_4.29.2.51.h b/drivers/staging/imgtec/rogue/hwdefs/km/cores/rgxcore_km_4.29.2.51.h
index 80e6fb7..49e10f5 100644
--- a/drivers/staging/imgtec/rogue/hwdefs/km/cores/rgxcore_km_4.29.2.51.h
+++ b/drivers/staging/imgtec/rogue/hwdefs/km/cores/rgxcore_km_4.29.2.51.h
@@ -42,8 +42,8 @@
 #ifndef _RGXCORE_KM_4_29_2_51_H_
 #define _RGXCORE_KM_4_29_2_51_H_
 
-/***** Automatically generated file (07/09/2015 09:24:24): Do not edit manually ********************/
-/***** Timestamp:  (07/09/2015 09:24:24)************************************************************/
+/***** Automatically generated file (06/02/2017 07:01:06): Do not edit manually ********************/
+/***** Timestamp:  (06/02/2017 07:01:06)************************************************************/
 /***** CS: @2944502 ******************************************************************/
 
 
@@ -62,6 +62,7 @@
 #define FIX_HW_BRN_50767
 #define FIX_HW_BRN_54441
 #define FIX_HW_BRN_57193
+#define FIX_HW_BRN_63142
 
 
  
diff --git a/drivers/staging/imgtec/rogue/hwdefs/km/cores/rgxcore_km_4.31.4.55.h b/drivers/staging/imgtec/rogue/hwdefs/km/cores/rgxcore_km_4.31.4.55.h
index 2f98874..57f8e2d 100644
--- a/drivers/staging/imgtec/rogue/hwdefs/km/cores/rgxcore_km_4.31.4.55.h
+++ b/drivers/staging/imgtec/rogue/hwdefs/km/cores/rgxcore_km_4.31.4.55.h
@@ -42,8 +42,8 @@
 #ifndef _RGXCORE_KM_4_31_4_55_H_
 #define _RGXCORE_KM_4_31_4_55_H_
 
-/***** Automatically generated file (07/09/2015 09:24:24): Do not edit manually ********************/
-/***** Timestamp:  (07/09/2015 09:24:24)************************************************************/
+/***** Automatically generated file (06/02/2017 07:01:06): Do not edit manually ********************/
+/***** Timestamp:  (06/02/2017 07:01:06)************************************************************/
 /***** CS: @2919104 ******************************************************************/
 
 
@@ -62,6 +62,7 @@
 #define FIX_HW_BRN_50767
 #define FIX_HW_BRN_54441
 #define FIX_HW_BRN_57193
+#define FIX_HW_BRN_63142
 
 
  
diff --git a/drivers/staging/imgtec/rogue/hwdefs/km/cores/rgxcore_km_4.40.2.51.h b/drivers/staging/imgtec/rogue/hwdefs/km/cores/rgxcore_km_4.40.2.51.h
index 677c121..a85ac35 100644
--- a/drivers/staging/imgtec/rogue/hwdefs/km/cores/rgxcore_km_4.40.2.51.h
+++ b/drivers/staging/imgtec/rogue/hwdefs/km/cores/rgxcore_km_4.40.2.51.h
@@ -42,8 +42,8 @@
 #ifndef _RGXCORE_KM_4_40_2_51_H_
 #define _RGXCORE_KM_4_40_2_51_H_
 
-/***** Automatically generated file (07/09/2015 09:24:25): Do not edit manually ********************/
-/***** Timestamp:  (07/09/2015 09:24:25)************************************************************/
+/***** Automatically generated file (06/02/2017 07:01:06): Do not edit manually ********************/
+/***** Timestamp:  (06/02/2017 07:01:06)************************************************************/
 /***** CS: @3254374 ******************************************************************/
 
 
@@ -62,6 +62,7 @@
 #define FIX_HW_BRN_50767
 #define FIX_HW_BRN_54441
 #define FIX_HW_BRN_57193
+#define FIX_HW_BRN_63142
 
 
  
diff --git a/drivers/staging/imgtec/rogue/hwdefs/km/cores/rgxcore_km_4.41.2.57.h b/drivers/staging/imgtec/rogue/hwdefs/km/cores/rgxcore_km_4.41.2.57.h
index 285635c..ea14d9e 100644
--- a/drivers/staging/imgtec/rogue/hwdefs/km/cores/rgxcore_km_4.41.2.57.h
+++ b/drivers/staging/imgtec/rogue/hwdefs/km/cores/rgxcore_km_4.41.2.57.h
@@ -42,8 +42,8 @@
 #ifndef _RGXCORE_KM_4_41_2_57_H_
 #define _RGXCORE_KM_4_41_2_57_H_
 
-/***** Automatically generated file (07/09/2015 09:24:25): Do not edit manually ********************/
-/***** Timestamp:  (07/09/2015 09:24:25)************************************************************/
+/***** Automatically generated file (06/02/2017 07:01:05): Do not edit manually ********************/
+/***** Timestamp:  (06/02/2017 07:01:05)************************************************************/
 /***** CS: @3254338 ******************************************************************/
 
 
@@ -62,6 +62,7 @@
 #define FIX_HW_BRN_50767
 #define FIX_HW_BRN_54441
 #define FIX_HW_BRN_57193
+#define FIX_HW_BRN_63142
 
 
  
diff --git a/drivers/staging/imgtec/rogue/hwdefs/km/cores/rgxcore_km_4.42.4.53.h b/drivers/staging/imgtec/rogue/hwdefs/km/cores/rgxcore_km_4.42.4.53.h
index f177e88..e95381c 100644
--- a/drivers/staging/imgtec/rogue/hwdefs/km/cores/rgxcore_km_4.42.4.53.h
+++ b/drivers/staging/imgtec/rogue/hwdefs/km/cores/rgxcore_km_4.42.4.53.h
@@ -42,8 +42,8 @@
 #ifndef _RGXCORE_KM_4_42_4_53_H_
 #define _RGXCORE_KM_4_42_4_53_H_
 
-/***** Automatically generated file (07/09/2015 09:24:25): Do not edit manually ********************/
-/***** Timestamp:  (07/09/2015 09:24:25)************************************************************/
+/***** Automatically generated file (06/02/2017 07:01:06): Do not edit manually ********************/
+/***** Timestamp:  (06/02/2017 07:01:06)************************************************************/
 /***** CS: @3250390 ******************************************************************/
 
 
@@ -62,6 +62,7 @@
 #define FIX_HW_BRN_50767
 #define FIX_HW_BRN_54441
 #define FIX_HW_BRN_57193
+#define FIX_HW_BRN_63142
 
 
  
diff --git a/drivers/staging/imgtec/rogue/hwdefs/km/cores/rgxcore_km_4.43.6.62.h b/drivers/staging/imgtec/rogue/hwdefs/km/cores/rgxcore_km_4.43.6.62.h
index 3eea043..3c55e1c 100644
--- a/drivers/staging/imgtec/rogue/hwdefs/km/cores/rgxcore_km_4.43.6.62.h
+++ b/drivers/staging/imgtec/rogue/hwdefs/km/cores/rgxcore_km_4.43.6.62.h
@@ -42,8 +42,8 @@
 #ifndef _RGXCORE_KM_4_43_6_62_H_
 #define _RGXCORE_KM_4_43_6_62_H_
 
-/***** Automatically generated file (07/09/2015 09:24:25): Do not edit manually ********************/
-/***** Timestamp:  (07/09/2015 09:24:25)************************************************************/
+/***** Automatically generated file (06/02/2017 07:01:06): Do not edit manually ********************/
+/***** Timestamp:  (06/02/2017 07:01:06)************************************************************/
 /***** CS: @3253129 ******************************************************************/
 
 
@@ -62,6 +62,7 @@
 #define FIX_HW_BRN_50767
 #define FIX_HW_BRN_54441
 #define FIX_HW_BRN_57193
+#define FIX_HW_BRN_63142
 
 
  
diff --git a/drivers/staging/imgtec/rogue/hwdefs/km/cores/rgxcore_km_4.45.2.58.h b/drivers/staging/imgtec/rogue/hwdefs/km/cores/rgxcore_km_4.45.2.58.h
index 2588258..0001e9b 100644
--- a/drivers/staging/imgtec/rogue/hwdefs/km/cores/rgxcore_km_4.45.2.58.h
+++ b/drivers/staging/imgtec/rogue/hwdefs/km/cores/rgxcore_km_4.45.2.58.h
@@ -42,8 +42,8 @@
 #ifndef _RGXCORE_KM_4_45_2_58_H_
 #define _RGXCORE_KM_4_45_2_58_H_
 
-/***** Automatically generated file (27/08/2015 09:09:26): Do not edit manually ********************/
-/***** Timestamp:  (27/08/2015 09:09:26)************************************************************/
+/***** Automatically generated file (06/02/2017 07:01:06): Do not edit manually ********************/
+/***** Timestamp:  (06/02/2017 07:01:06)************************************************************/
 /***** CS: @3547765 ******************************************************************/
 
 
@@ -61,6 +61,7 @@
 
 #define FIX_HW_BRN_54441
 #define FIX_HW_BRN_57193
+#define FIX_HW_BRN_63142
 
 
  
diff --git a/drivers/staging/imgtec/rogue/hwdefs/km/cores/rgxcore_km_4.32.2.52.h b/drivers/staging/imgtec/rogue/hwdefs/km/cores/rgxcore_km_4.46.6.62.h
similarity index 86%
rename from drivers/staging/imgtec/rogue/hwdefs/km/cores/rgxcore_km_4.32.2.52.h
rename to drivers/staging/imgtec/rogue/hwdefs/km/cores/rgxcore_km_4.46.6.62.h
index 8455edc..d196dd0 100644
--- a/drivers/staging/imgtec/rogue/hwdefs/km/cores/rgxcore_km_4.32.2.52.h
+++ b/drivers/staging/imgtec/rogue/hwdefs/km/cores/rgxcore_km_4.46.6.62.h
@@ -1,5 +1,5 @@
 /*************************************************************************/ /*!
-@Title          RGX Core BVNC 4.32.2.52
+@Title          RGX Core BVNC 4.46.6.62
 @Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
 @License        Dual MIT/GPLv2
 
@@ -39,29 +39,29 @@
 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */ /**************************************************************************/
 
-#ifndef _RGXCORE_KM_4_32_2_52_H_
-#define _RGXCORE_KM_4_32_2_52_H_
+#ifndef _RGXCORE_KM_4_46_6_62_H_
+#define _RGXCORE_KM_4_46_6_62_H_
 
-/***** Automatically generated file (07/09/2015 09:24:24): Do not edit manually ********************/
-/***** Timestamp:  (07/09/2015 09:24:24)************************************************************/
-/***** CS: @2966609 ******************************************************************/
+/***** Automatically generated file (06/02/2017 07:01:05): Do not edit manually ********************/
+/***** Timestamp:  (06/02/2017 07:01:05)************************************************************/
+/***** CS: @4015666 ******************************************************************/
 
 
 /******************************************************************************
- * BVNC = 4.32.2.52 
+ * BVNC = 4.46.6.62 
  *****************************************************************************/
 #define RGX_BVNC_KM_B 4
-#define RGX_BVNC_KM_V 32
-#define RGX_BVNC_KM_N 2
-#define RGX_BVNC_KM_C 52
+#define RGX_BVNC_KM_V 46
+#define RGX_BVNC_KM_N 6
+#define RGX_BVNC_KM_C 62
 
 /******************************************************************************
  * Errata 
  *****************************************************************************/
 
 #define FIX_HW_BRN_50767
-#define FIX_HW_BRN_54441
 #define FIX_HW_BRN_57193
+#define FIX_HW_BRN_63142
 
 
  
@@ -74,4 +74,4 @@
 
 
 
-#endif /* _RGXCORE_KM_4_32_2_52_H_ */
+#endif /* _RGXCORE_KM_4_46_6_62_H_ */
diff --git a/drivers/staging/imgtec/rogue/hwdefs/km/cores/rgxcore_km_5.11.1.46.h b/drivers/staging/imgtec/rogue/hwdefs/km/cores/rgxcore_km_5.11.1.46.h
index 8e7ca99..0f426ca 100644
--- a/drivers/staging/imgtec/rogue/hwdefs/km/cores/rgxcore_km_5.11.1.46.h
+++ b/drivers/staging/imgtec/rogue/hwdefs/km/cores/rgxcore_km_5.11.1.46.h
@@ -42,8 +42,8 @@
 #ifndef _RGXCORE_KM_5_11_1_46_H_
 #define _RGXCORE_KM_5_11_1_46_H_
 
-/***** Automatically generated file (26/08/2015 09:15:10): Do not edit manually ********************/
-/***** Timestamp:  (26/08/2015 09:15:10)************************************************************/
+/***** Automatically generated file (20/02/2017 07:01:20): Do not edit manually ********************/
+/***** Timestamp:  (20/02/2017 07:01:20)************************************************************/
 /***** CS: @3485232 ******************************************************************/
 
 
@@ -60,6 +60,8 @@
  *****************************************************************************/
 
 #define FIX_HW_BRN_42321
+#define FIX_HW_BRN_43276
+#define FIX_HW_BRN_44871
 
 
  
diff --git a/drivers/staging/imgtec/rogue/hwdefs/km/cores/rgxcore_km_5.9.1.46.h b/drivers/staging/imgtec/rogue/hwdefs/km/cores/rgxcore_km_5.9.1.46.h
index 72b7e52..ac693ff 100644
--- a/drivers/staging/imgtec/rogue/hwdefs/km/cores/rgxcore_km_5.9.1.46.h
+++ b/drivers/staging/imgtec/rogue/hwdefs/km/cores/rgxcore_km_5.9.1.46.h
@@ -42,8 +42,8 @@
 #ifndef _RGXCORE_KM_5_9_1_46_H_
 #define _RGXCORE_KM_5_9_1_46_H_
 
-/***** Automatically generated file (23/07/2015 09:38:00): Do not edit manually ********************/
-/***** Timestamp:  (23/07/2015 09:38:00)************************************************************/
+/***** Automatically generated file (20/02/2017 07:01:19): Do not edit manually ********************/
+/***** Timestamp:  (20/02/2017 07:01:19)************************************************************/
 /***** CS: @2967148 ******************************************************************/
 
 
@@ -60,6 +60,8 @@
  *****************************************************************************/
 
 #define FIX_HW_BRN_38344
+#define FIX_HW_BRN_43276
+#define FIX_HW_BRN_44871
 
 
  
diff --git a/drivers/staging/imgtec/rogue/hwdefs/km/cores/rgxcore_km_4.32.2.52.h b/drivers/staging/imgtec/rogue/hwdefs/km/cores/rgxcore_km_6.34.4.35.h
similarity index 85%
copy from drivers/staging/imgtec/rogue/hwdefs/km/cores/rgxcore_km_4.32.2.52.h
copy to drivers/staging/imgtec/rogue/hwdefs/km/cores/rgxcore_km_6.34.4.35.h
index 8455edc..7e4f836 100644
--- a/drivers/staging/imgtec/rogue/hwdefs/km/cores/rgxcore_km_4.32.2.52.h
+++ b/drivers/staging/imgtec/rogue/hwdefs/km/cores/rgxcore_km_6.34.4.35.h
@@ -1,5 +1,5 @@
 /*************************************************************************/ /*!
-@Title          RGX Core BVNC 4.32.2.52
+@Title          RGX Core BVNC 6.34.4.35
 @Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
 @License        Dual MIT/GPLv2
 
@@ -39,29 +39,29 @@
 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */ /**************************************************************************/
 
-#ifndef _RGXCORE_KM_4_32_2_52_H_
-#define _RGXCORE_KM_4_32_2_52_H_
+#ifndef _RGXCORE_KM_6_34_4_35_H_
+#define _RGXCORE_KM_6_34_4_35_H_
 
-/***** Automatically generated file (07/09/2015 09:24:24): Do not edit manually ********************/
-/***** Timestamp:  (07/09/2015 09:24:24)************************************************************/
-/***** CS: @2966609 ******************************************************************/
+/***** Automatically generated file (06/02/2017 07:01:05): Do not edit manually ********************/
+/***** Timestamp:  (06/02/2017 07:01:05)************************************************************/
+/***** CS: @3533654 ******************************************************************/
 
 
 /******************************************************************************
- * BVNC = 4.32.2.52 
+ * BVNC = 6.34.4.35 
  *****************************************************************************/
-#define RGX_BVNC_KM_B 4
-#define RGX_BVNC_KM_V 32
-#define RGX_BVNC_KM_N 2
-#define RGX_BVNC_KM_C 52
+#define RGX_BVNC_KM_B 6
+#define RGX_BVNC_KM_V 34
+#define RGX_BVNC_KM_N 4
+#define RGX_BVNC_KM_C 35
 
 /******************************************************************************
  * Errata 
  *****************************************************************************/
 
-#define FIX_HW_BRN_50767
 #define FIX_HW_BRN_54441
 #define FIX_HW_BRN_57193
+#define FIX_HW_BRN_63142
 
 
  
@@ -74,4 +74,4 @@
 
 
 
-#endif /* _RGXCORE_KM_4_32_2_52_H_ */
+#endif /* _RGXCORE_KM_6_34_4_35_H_ */
diff --git a/drivers/staging/imgtec/rogue/hwdefs/km/cores/rgxcore_km_8.47.2.39.h b/drivers/staging/imgtec/rogue/hwdefs/km/cores/rgxcore_km_8.47.2.39.h
index 690c435..923614e 100644
--- a/drivers/staging/imgtec/rogue/hwdefs/km/cores/rgxcore_km_8.47.2.39.h
+++ b/drivers/staging/imgtec/rogue/hwdefs/km/cores/rgxcore_km_8.47.2.39.h
@@ -42,8 +42,8 @@
 #ifndef _RGXCORE_KM_8_47_2_39_H_
 #define _RGXCORE_KM_8_47_2_39_H_
 
-/***** Automatically generated file (20/08/2015 16:40:24): Do not edit manually ********************/
-/***** Timestamp:  (20/08/2015 16:40:24)************************************************************/
+/***** Automatically generated file (23/02/2017 15:15:18): Do not edit manually ********************/
+/***** Timestamp:  (23/02/2017 15:15:18)************************************************************/
 /***** CS: @3673034 ******************************************************************/
 
 
@@ -59,6 +59,8 @@
  * Errata 
  *****************************************************************************/
 
+#define FIX_HW_BRN_52563
+#define FIX_HW_BRN_62204
 
 
  
diff --git a/drivers/staging/imgtec/rogue/hwdefs/km/cores/rgxcore_km_8.48.2.39.h b/drivers/staging/imgtec/rogue/hwdefs/km/cores/rgxcore_km_8.48.2.39.h
index 5d2e495..0e4e85e 100644
--- a/drivers/staging/imgtec/rogue/hwdefs/km/cores/rgxcore_km_8.48.2.39.h
+++ b/drivers/staging/imgtec/rogue/hwdefs/km/cores/rgxcore_km_8.48.2.39.h
@@ -42,8 +42,8 @@
 #ifndef _RGXCORE_KM_8_48_2_39_H_
 #define _RGXCORE_KM_8_48_2_39_H_
 
-/***** Automatically generated file (16/10/2015 06:53:38): Do not edit manually ********************/
-/***** Timestamp:  (16/10/2015 06:53:38)************************************************************/
+/***** Automatically generated file (23/02/2017 15:15:18): Do not edit manually ********************/
+/***** Timestamp:  (23/02/2017 15:15:18)************************************************************/
 /***** CS: @3753485 ******************************************************************/
 
 
@@ -59,6 +59,8 @@
  * Errata 
  *****************************************************************************/
 
+#define FIX_HW_BRN_52563
+#define FIX_HW_BRN_62204
 
 
  
diff --git a/drivers/staging/imgtec/rogue/hwdefs/km/rgx_bvnc_defs_km.h b/drivers/staging/imgtec/rogue/hwdefs/km/rgx_bvnc_defs_km.h
new file mode 100644
index 0000000..e49d3dd
--- /dev/null
+++ b/drivers/staging/imgtec/rogue/hwdefs/km/rgx_bvnc_defs_km.h
@@ -0,0 +1,320 @@
+/*************************************************************************/ /*!
+@Title          Hardware definition file rgx_bvnc_defs_km.h
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+/**************************************************
+*       Auto generated file by BVNCTableGen.py    *
+*       This file should not be edited manually   *
+**************************************************/
+
+#ifndef _RGX_BVNC_DEFS_KM_H_
+#define _RGX_BVNC_DEFS_KM_H_
+
+#include "img_types.h"
+
+#define   BVNC_FIELD_WIDTH  (16U)
+
+#define	RGX_FEATURE_AXI_ACELITE_POS                                 	(0U)
+#define	RGX_FEATURE_AXI_ACELITE_BIT_MASK                            	(IMG_UINT64_C(0x0000000000000001))
+
+#define	RGX_FEATURE_CLUSTER_GROUPING_POS                            	(1U)
+#define	RGX_FEATURE_CLUSTER_GROUPING_BIT_MASK                       	(IMG_UINT64_C(0x0000000000000002))
+
+#define	RGX_FEATURE_COMPUTE_POS                                     	(2U)
+#define	RGX_FEATURE_COMPUTE_BIT_MASK                                	(IMG_UINT64_C(0x0000000000000004))
+
+#define	RGX_FEATURE_COMPUTE_MORTON_CAPABLE_POS                      	(3U)
+#define	RGX_FEATURE_COMPUTE_MORTON_CAPABLE_BIT_MASK                 	(IMG_UINT64_C(0x0000000000000008))
+
+#define	RGX_FEATURE_COMPUTE_OVERLAP_POS                             	(4U)
+#define	RGX_FEATURE_COMPUTE_OVERLAP_BIT_MASK                        	(IMG_UINT64_C(0x0000000000000010))
+
+#define	RGX_FEATURE_COMPUTE_OVERLAP_WITH_BARRIERS_POS               	(5U)
+#define	RGX_FEATURE_COMPUTE_OVERLAP_WITH_BARRIERS_BIT_MASK          	(IMG_UINT64_C(0x0000000000000020))
+
+#define	RGX_FEATURE_DYNAMIC_DUST_POWER_POS                          	(6U)
+#define	RGX_FEATURE_DYNAMIC_DUST_POWER_BIT_MASK                     	(IMG_UINT64_C(0x0000000000000040))
+
+#define	RGX_FEATURE_FASTRENDER_DM_POS                               	(7U)
+#define	RGX_FEATURE_FASTRENDER_DM_BIT_MASK                          	(IMG_UINT64_C(0x0000000000000080))
+
+#define	RGX_FEATURE_GPU_CPU_COHERENCY_POS                           	(8U)
+#define	RGX_FEATURE_GPU_CPU_COHERENCY_BIT_MASK                      	(IMG_UINT64_C(0x0000000000000100))
+
+#define	RGX_FEATURE_GPU_VIRTUALISATION_POS                          	(9U)
+#define	RGX_FEATURE_GPU_VIRTUALISATION_BIT_MASK                     	(IMG_UINT64_C(0x0000000000000200))
+
+#define	RGX_FEATURE_GS_RTA_SUPPORT_POS                              	(10U)
+#define	RGX_FEATURE_GS_RTA_SUPPORT_BIT_MASK                         	(IMG_UINT64_C(0x0000000000000400))
+
+#define	RGX_FEATURE_META_DMA_POS                                    	(11U)
+#define	RGX_FEATURE_META_DMA_BIT_MASK                               	(IMG_UINT64_C(0x0000000000000800))
+
+#define	RGX_FEATURE_MIPS_POS                                        	(12U)
+#define	RGX_FEATURE_MIPS_BIT_MASK                                   	(IMG_UINT64_C(0x0000000000001000))
+
+#define	RGX_FEATURE_PBE2_IN_XE_POS                                  	(13U)
+#define	RGX_FEATURE_PBE2_IN_XE_BIT_MASK                             	(IMG_UINT64_C(0x0000000000002000))
+
+#define	RGX_FEATURE_PBVNC_COREID_REG_POS                            	(14U)
+#define	RGX_FEATURE_PBVNC_COREID_REG_BIT_MASK                       	(IMG_UINT64_C(0x0000000000004000))
+
+#define	RGX_FEATURE_PDS_PER_DUST_POS                                	(15U)
+#define	RGX_FEATURE_PDS_PER_DUST_BIT_MASK                           	(IMG_UINT64_C(0x0000000000008000))
+
+#define	RGX_FEATURE_PDS_TEMPSIZE8_POS                               	(16U)
+#define	RGX_FEATURE_PDS_TEMPSIZE8_BIT_MASK                          	(IMG_UINT64_C(0x0000000000010000))
+
+#define	RGX_FEATURE_PERFBUS_POS                                     	(17U)
+#define	RGX_FEATURE_PERFBUS_BIT_MASK                                	(IMG_UINT64_C(0x0000000000020000))
+
+#define	RGX_FEATURE_RAY_TRACING_POS                                 	(18U)
+#define	RGX_FEATURE_RAY_TRACING_BIT_MASK                            	(IMG_UINT64_C(0x0000000000040000))
+
+#define	RGX_FEATURE_ROGUEXE_POS                                     	(19U)
+#define	RGX_FEATURE_ROGUEXE_BIT_MASK                                	(IMG_UINT64_C(0x0000000000080000))
+
+#define	RGX_FEATURE_S7_CACHE_HIERARCHY_POS                          	(20U)
+#define	RGX_FEATURE_S7_CACHE_HIERARCHY_BIT_MASK                     	(IMG_UINT64_C(0x0000000000100000))
+
+#define	RGX_FEATURE_S7_TOP_INFRASTRUCTURE_POS                       	(21U)
+#define	RGX_FEATURE_S7_TOP_INFRASTRUCTURE_BIT_MASK                  	(IMG_UINT64_C(0x0000000000200000))
+
+#define	RGX_FEATURE_SCALABLE_VDM_GPP_POS                            	(22U)
+#define	RGX_FEATURE_SCALABLE_VDM_GPP_BIT_MASK                       	(IMG_UINT64_C(0x0000000000400000))
+
+#define	RGX_FEATURE_SIGNAL_SNOOPING_POS                             	(23U)
+#define	RGX_FEATURE_SIGNAL_SNOOPING_BIT_MASK                        	(IMG_UINT64_C(0x0000000000800000))
+
+#define	RGX_FEATURE_SINGLE_BIF_POS                                  	(24U)
+#define	RGX_FEATURE_SINGLE_BIF_BIT_MASK                             	(IMG_UINT64_C(0x0000000001000000))
+
+#define	RGX_FEATURE_SLCSIZE8_POS                                    	(25U)
+#define	RGX_FEATURE_SLCSIZE8_BIT_MASK                               	(IMG_UINT64_C(0x0000000002000000))
+
+#define	RGX_FEATURE_SLC_HYBRID_CACHELINE_64_128_POS                 	(26U)
+#define	RGX_FEATURE_SLC_HYBRID_CACHELINE_64_128_BIT_MASK            	(IMG_UINT64_C(0x0000000004000000))
+
+#define	RGX_FEATURE_SLC_VIVT_POS                                    	(27U)
+#define	RGX_FEATURE_SLC_VIVT_BIT_MASK                               	(IMG_UINT64_C(0x0000000008000000))
+
+#define	RGX_FEATURE_SYS_BUS_SECURE_RESET_POS                        	(28U)
+#define	RGX_FEATURE_SYS_BUS_SECURE_RESET_BIT_MASK                   	(IMG_UINT64_C(0x0000000010000000))
+
+#define	RGX_FEATURE_TESSELLATION_POS                                	(29U)
+#define	RGX_FEATURE_TESSELLATION_BIT_MASK                           	(IMG_UINT64_C(0x0000000020000000))
+
+#define	RGX_FEATURE_TLA_POS                                         	(30U)
+#define	RGX_FEATURE_TLA_BIT_MASK                                    	(IMG_UINT64_C(0x0000000040000000))
+
+#define	RGX_FEATURE_TPU_CEM_DATAMASTER_GLOBAL_REGISTERS_POS         	(31U)
+#define	RGX_FEATURE_TPU_CEM_DATAMASTER_GLOBAL_REGISTERS_BIT_MASK    	(IMG_UINT64_C(0x0000000080000000))
+
+#define	RGX_FEATURE_TPU_DM_GLOBAL_REGISTERS_POS                     	(32U)
+#define	RGX_FEATURE_TPU_DM_GLOBAL_REGISTERS_BIT_MASK                	(IMG_UINT64_C(0x0000000100000000))
+
+#define	RGX_FEATURE_TPU_FILTERING_MODE_CONTROL_POS                  	(33U)
+#define	RGX_FEATURE_TPU_FILTERING_MODE_CONTROL_BIT_MASK             	(IMG_UINT64_C(0x0000000200000000))
+
+#define	RGX_FEATURE_VDM_DRAWINDIRECT_POS                            	(34U)
+#define	RGX_FEATURE_VDM_DRAWINDIRECT_BIT_MASK                       	(IMG_UINT64_C(0x0000000400000000))
+
+#define	RGX_FEATURE_VDM_OBJECT_LEVEL_LLS_POS                        	(35U)
+#define	RGX_FEATURE_VDM_OBJECT_LEVEL_LLS_BIT_MASK                   	(IMG_UINT64_C(0x0000000800000000))
+
+#define	RGX_FEATURE_XT_TOP_INFRASTRUCTURE_POS                       	(36U)
+#define	RGX_FEATURE_XT_TOP_INFRASTRUCTURE_BIT_MASK                  	(IMG_UINT64_C(0x0000001000000000))
+
+#define	RGX_FEATURE_CDM_CONTROL_STREAM_FORMAT_POS                   	(0U)
+#define	RGX_FEATURE_CDM_CONTROL_STREAM_FORMAT_BIT_MASK              	(IMG_UINT64_C(0x0000000000000003))
+
+#define	RGX_FEATURE_FBCDC_ARCHITECTURE_POS                          	(2U)
+#define	RGX_FEATURE_FBCDC_ARCHITECTURE_BIT_MASK                     	(IMG_UINT64_C(0x000000000000000C))
+
+#define	RGX_FEATURE_META_POS                                        	(4U)
+#define	RGX_FEATURE_META_BIT_MASK                                   	(IMG_UINT64_C(0x0000000000000030))
+
+#define	RGX_FEATURE_META_COREMEM_BANKS_POS                          	(6U)
+#define	RGX_FEATURE_META_COREMEM_BANKS_BIT_MASK                     	(IMG_UINT64_C(0x00000000000001C0))
+
+#define	RGX_FEATURE_META_COREMEM_SIZE_POS                           	(9U)
+#define	RGX_FEATURE_META_COREMEM_SIZE_BIT_MASK                      	(IMG_UINT64_C(0x0000000000000E00))
+
+#define	RGX_FEATURE_META_DMA_CHANNEL_COUNT_POS                      	(12U)
+#define	RGX_FEATURE_META_DMA_CHANNEL_COUNT_BIT_MASK                 	(IMG_UINT64_C(0x0000000000003000))
+
+#define	RGX_FEATURE_NUM_CLUSTERS_POS                                	(14U)
+#define	RGX_FEATURE_NUM_CLUSTERS_BIT_MASK                           	(IMG_UINT64_C(0x000000000003C000))
+
+#define	RGX_FEATURE_NUM_ISP_IPP_PIPES_POS                           	(18U)
+#define	RGX_FEATURE_NUM_ISP_IPP_PIPES_BIT_MASK                      	(IMG_UINT64_C(0x00000000003C0000))
+
+#define	RGX_FEATURE_PHYS_BUS_WIDTH_POS                              	(22U)
+#define	RGX_FEATURE_PHYS_BUS_WIDTH_BIT_MASK                         	(IMG_UINT64_C(0x0000000000C00000))
+
+#define	RGX_FEATURE_SCALABLE_TE_ARCH_POS                            	(24U)
+#define	RGX_FEATURE_SCALABLE_TE_ARCH_BIT_MASK                       	(IMG_UINT64_C(0x0000000003000000))
+
+#define	RGX_FEATURE_SCALABLE_VCE_POS                                	(26U)
+#define	RGX_FEATURE_SCALABLE_VCE_BIT_MASK                           	(IMG_UINT64_C(0x000000000C000000))
+
+#define	RGX_FEATURE_SLC_BANKS_POS                                   	(28U)
+#define	RGX_FEATURE_SLC_BANKS_BIT_MASK                              	(IMG_UINT64_C(0x0000000030000000))
+
+#define	RGX_FEATURE_SLC_CACHE_LINE_SIZE_BITS_POS                    	(30U)
+#define	RGX_FEATURE_SLC_CACHE_LINE_SIZE_BITS_BIT_MASK               	(IMG_UINT64_C(0x0000000040000000))
+
+#define	RGX_FEATURE_SLC_SIZE_IN_BYTES_POS                           	(31U)
+#define	RGX_FEATURE_SLC_SIZE_IN_BYTES_BIT_MASK                      	(IMG_UINT64_C(0x0000000380000000))
+
+#define	RGX_FEATURE_SLC_SIZE_IN_KILOBYTES_POS                       	(31U)
+#define	RGX_FEATURE_SLC_SIZE_IN_KILOBYTES_BIT_MASK                  	(IMG_UINT64_C(0x0000000380000000))
+
+#define	RGX_FEATURE_VIRTUAL_ADDRESS_SPACE_BITS_POS                  	(36U)
+#define	RGX_FEATURE_VIRTUAL_ADDRESS_SPACE_BITS_BIT_MASK             	(IMG_UINT64_C(0x0000001000000000))
+
+#define	HW_ERN_36400_POS                                            	(0U)
+#define	HW_ERN_36400_BIT_MASK                                       	(IMG_UINT64_C(0x0000000000000001))
+
+#define	FIX_HW_BRN_37200_POS                                        	(1U)
+#define	FIX_HW_BRN_37200_BIT_MASK                                   	(IMG_UINT64_C(0x0000000000000002))
+
+#define	FIX_HW_BRN_37918_POS                                        	(2U)
+#define	FIX_HW_BRN_37918_BIT_MASK                                   	(IMG_UINT64_C(0x0000000000000004))
+
+#define	FIX_HW_BRN_38344_POS                                        	(3U)
+#define	FIX_HW_BRN_38344_BIT_MASK                                   	(IMG_UINT64_C(0x0000000000000008))
+
+#define	HW_ERN_41805_POS                                            	(4U)
+#define	HW_ERN_41805_BIT_MASK                                       	(IMG_UINT64_C(0x0000000000000010))
+
+#define	HW_ERN_42290_POS                                            	(5U)
+#define	HW_ERN_42290_BIT_MASK                                       	(IMG_UINT64_C(0x0000000000000020))
+
+#define	FIX_HW_BRN_42321_POS                                        	(6U)
+#define	FIX_HW_BRN_42321_BIT_MASK                                   	(IMG_UINT64_C(0x0000000000000040))
+
+#define	FIX_HW_BRN_42480_POS                                        	(7U)
+#define	FIX_HW_BRN_42480_BIT_MASK                                   	(IMG_UINT64_C(0x0000000000000080))
+
+#define	HW_ERN_42606_POS                                            	(8U)
+#define	HW_ERN_42606_BIT_MASK                                       	(IMG_UINT64_C(0x0000000000000100))
+
+#define	FIX_HW_BRN_43276_POS                                        	(9U)
+#define	FIX_HW_BRN_43276_BIT_MASK                                   	(IMG_UINT64_C(0x0000000000000200))
+
+#define	FIX_HW_BRN_44455_POS                                        	(10U)
+#define	FIX_HW_BRN_44455_BIT_MASK                                   	(IMG_UINT64_C(0x0000000000000400))
+
+#define	FIX_HW_BRN_44871_POS                                        	(11U)
+#define	FIX_HW_BRN_44871_BIT_MASK                                   	(IMG_UINT64_C(0x0000000000000800))
+
+#define	HW_ERN_44885_POS                                            	(12U)
+#define	HW_ERN_44885_BIT_MASK                                       	(IMG_UINT64_C(0x0000000000001000))
+
+#define	HW_ERN_45914_POS                                            	(13U)
+#define	HW_ERN_45914_BIT_MASK                                       	(IMG_UINT64_C(0x0000000000002000))
+
+#define	HW_ERN_46066_POS                                            	(14U)
+#define	HW_ERN_46066_BIT_MASK                                       	(IMG_UINT64_C(0x0000000000004000))
+
+#define	HW_ERN_47025_POS                                            	(15U)
+#define	HW_ERN_47025_BIT_MASK                                       	(IMG_UINT64_C(0x0000000000008000))
+
+#define	HW_ERN_49144_POS                                            	(16U)
+#define	HW_ERN_49144_BIT_MASK                                       	(IMG_UINT64_C(0x0000000000010000))
+
+#define	HW_ERN_50539_POS                                            	(17U)
+#define	HW_ERN_50539_BIT_MASK                                       	(IMG_UINT64_C(0x0000000000020000))
+
+#define	FIX_HW_BRN_50767_POS                                        	(18U)
+#define	FIX_HW_BRN_50767_BIT_MASK                                   	(IMG_UINT64_C(0x0000000000040000))
+
+#define	FIX_HW_BRN_51281_POS                                        	(19U)
+#define	FIX_HW_BRN_51281_BIT_MASK                                   	(IMG_UINT64_C(0x0000000000080000))
+
+#define	HW_ERN_51468_POS                                            	(20U)
+#define	HW_ERN_51468_BIT_MASK                                       	(IMG_UINT64_C(0x0000000000100000))
+
+#define	FIX_HW_BRN_52402_POS                                        	(21U)
+#define	FIX_HW_BRN_52402_BIT_MASK                                   	(IMG_UINT64_C(0x0000000000200000))
+
+#define	FIX_HW_BRN_52563_POS                                        	(22U)
+#define	FIX_HW_BRN_52563_BIT_MASK                                   	(IMG_UINT64_C(0x0000000000400000))
+
+#define	FIX_HW_BRN_54141_POS                                        	(23U)
+#define	FIX_HW_BRN_54141_BIT_MASK                                   	(IMG_UINT64_C(0x0000000000800000))
+
+#define	FIX_HW_BRN_54441_POS                                        	(24U)
+#define	FIX_HW_BRN_54441_BIT_MASK                                   	(IMG_UINT64_C(0x0000000001000000))
+
+#define	FIX_HW_BRN_55091_POS                                        	(25U)
+#define	FIX_HW_BRN_55091_BIT_MASK                                   	(IMG_UINT64_C(0x0000000002000000))
+
+#define	FIX_HW_BRN_57193_POS                                        	(26U)
+#define	FIX_HW_BRN_57193_BIT_MASK                                   	(IMG_UINT64_C(0x0000000004000000))
+
+#define	HW_ERN_57596_POS                                            	(27U)
+#define	HW_ERN_57596_BIT_MASK                                       	(IMG_UINT64_C(0x0000000008000000))
+
+#define	FIX_HW_BRN_60084_POS                                        	(28U)
+#define	FIX_HW_BRN_60084_BIT_MASK                                   	(IMG_UINT64_C(0x0000000010000000))
+
+#define	HW_ERN_61389_POS                                            	(29U)
+#define	HW_ERN_61389_BIT_MASK                                       	(IMG_UINT64_C(0x0000000020000000))
+
+#define	FIX_HW_BRN_61450_POS                                        	(30U)
+#define	FIX_HW_BRN_61450_BIT_MASK                                   	(IMG_UINT64_C(0x0000000040000000))
+
+#define	FIX_HW_BRN_62204_POS                                        	(31U)
+#define	FIX_HW_BRN_62204_BIT_MASK                                   	(IMG_UINT64_C(0x0000000080000000))
+
+#define	FIX_HW_BRN_63027_POS                                        	(32U)
+#define	FIX_HW_BRN_63027_BIT_MASK                                   	(IMG_UINT64_C(0x0000000100000000))
+
+#define	FIX_HW_BRN_63142_POS                                        	(33U)
+#define	FIX_HW_BRN_63142_BIT_MASK                                   	(IMG_UINT64_C(0x0000000200000000))
+
+
+
+#endif /*_RGX_BVNC_DEFS_KM_H_ */
+
+
+
diff --git a/drivers/staging/imgtec/rogue/hwdefs/km/rgx_bvnc_table_km.h b/drivers/staging/imgtec/rogue/hwdefs/km/rgx_bvnc_table_km.h
new file mode 100644
index 0000000..c2db819
--- /dev/null
+++ b/drivers/staging/imgtec/rogue/hwdefs/km/rgx_bvnc_table_km.h
@@ -0,0 +1,207 @@
+/*************************************************************************/ /*!
+@Title          Hardware definition file rgx_bvnc_table_km.h
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+/**************************************************
+*       Auto generated file by BVNCTableGen.py    *
+*       This file should not be edited manually   *
+**************************************************/
+
+#ifndef _RGX_BVNC_TABLE_KM_H_
+#define _RGX_BVNC_TABLE_KM_H_
+
+#include "img_types.h"
+#include "rgxdefs_km.h"
+
+#define	CSF_MAX_VALUE	(1)
+static IMG_UINT32 CSF[] = {2, };
+
+#define	FBCDCArch_MAX_VALUE	(3)
+static IMG_UINT32 FBCDCArch[] = {1, 2, 3, };
+
+#define	MCRMB_MAX_VALUE	(2)
+static IMG_UINT32 MCRMB[] = {3, 8, };
+
+#define	MCRMS_MAX_VALUE	(5)
+static IMG_UINT32 MCRMS[] = {0, 32, 48, 64, 256, };
+
+#define	MDCC_MAX_VALUE	(1)
+static IMG_UINT32 MDCC[] = {4, };
+
+#define	NC_MAX_VALUE	(7)
+static IMG_UINT32 NC[] = {1, 2, 4, 6, 8, 12, 16, };
+
+#define	NIIP_MAX_VALUE	(11)
+static IMG_UINT32 NIIP[] = {1, 2, 3, 4, 6, 7, 8, 12, 16, 24, 32, };
+
+#define	PBW_MAX_VALUE	(3)
+static IMG_UINT32 PBW[] = {32, 38, 40, };
+
+#define	STEA_MAX_VALUE	(3)
+static IMG_UINT32 STEA[] = {1, 2, 4, };
+
+#define	SVCEA_MAX_VALUE	(4)
+static IMG_UINT32 SVCEA[] = {1, 2, 3, 4, };
+
+#define	SLCB_MAX_VALUE	(3)
+static IMG_UINT32 SLCB[] = {1, 2, 4, };
+
+#define	SLCCLSb_MAX_VALUE	(2)
+static IMG_UINT32 SLCCLSb[] = {512, 1024, };
+
+#define	SLCSKB_MAX_VALUE	(7)
+static IMG_UINT32 SLCSKB[] = {0, 16, 32, 64, 128, 256, 512, };
+
+#define	VASB_MAX_VALUE	(1)
+static IMG_UINT32 VASB[] = {40, };
+
+#define	META_MAX_VALUE	(4)
+static IMG_UINT32 META[] = {LTP217, LTP218, MTP218, MTP219, };
+
+
+IMG_UINT64    gaFeatures[][3]=
+{
+	{ 0x0001000000020000, 0x0000000040020415, 0x0000000200884020, },
+	{ 0x0001000000020005, 0x0000000040020415, 0x0000000200884020, },
+	{ 0x0001000000020014, 0x0000000040020415, 0x0000000200884020, },
+	{ 0x000100000002001e, 0x0000000040020415, 0x0000000200884020, },
+	{ 0x0001000000040005, 0x0000000040020414, 0x0000000200888020, },
+	{ 0x0001000000040006, 0x0000000040020414, 0x0000000200888020, },
+	{ 0x000100000004000c, 0x0000000040020414, 0x0000000280888020, },
+	{ 0x000100000004000f, 0x0000000040020415, 0x0000000280888020, },
+	{ 0x0001000000040013, 0x0000000040020415, 0x0000000200888020, },
+	{ 0x0004000000020033, 0x00000012c002045f, 0x0000000200984214, },
+	{ 0x0004000000020039, 0x00000012c002065f, 0x0000000200984214, },
+	{ 0x000400000002003a, 0x00000012c002065f, 0x0000000200984214, },
+	{ 0x0004000000040035, 0x00000012c002045f, 0x0000000200988214, },
+	{ 0x0004000000040037, 0x00000012c002045e, 0x0000000200988214, },
+	{ 0x000400000006003e, 0x00000012c002065f, 0x000000022098c214, },
+	{ 0x000500000001002e, 0x00000000000a0445, 0x0000000080800000, },
+	{ 0x0006000000040023, 0x00000012c006045f, 0x0000000200988214, },
+	{ 0x0008000000020027, 0x0000000fa8738e3f, 0x00000002108c4658, },
+	{ 0x000a00000002001a, 0x0000000fbcf38ebf, 0x0000000210984878, },
+	{ 0x000a000000040019, 0x0000000fbcf38ebf, 0x0000000320988878, },
+	{ 0x000c000000010014, 0x0000000000080005, 0x0000000000800000, },
+	{ 0x000c000000010030, 0x0000000000080005, 0x0000000000800000, },
+	{ 0x000f000000010040, 0x00000000000a0645, 0x0000000180840000, },
+	{ 0x001600000015000b, 0x00000000130a7605, 0x0000000000000000, },
+	{ 0x0016000000150010, 0x00000000130a7605, 0x0000000000040000, },
+	{ 0x0016000000160016, 0x00000000010a7605, 0x0000000080000000, },
+	{ 0x0016000000160017, 0x00000000110a7605, 0x0000000080000000, },
+	{ 0x0016000000160019, 0x00000000110a7605, 0x0000000080040000, },
+	{ 0x001600000016001b, 0x00000000110a7605, 0x0000000080000000, },
+	{ 0x001600000016001d, 0x00000000110a7605, 0x0000000080040000, },
+	{ 0x0016000000360018, 0x00000000010a7605, 0x0000000180080000, },
+	{ 0x0016000000360019, 0x00000000110a7605, 0x0000000180080000, },
+	{ 0x001600000036001e, 0x00000000110a7605, 0x00000001800c0000, },
+	{ 0x0016000000360148, 0x00000000110a7605, 0x00000001800c0000, },
+	{ 0x001600000036014a, 0x00000000110a7605, 0x00000001800c0000, },
+	{ 0x0016000000d00138, 0x00000000110a7605, 0x00000001800c4000, },
+	{ 0x0016000000d0013c, 0x00000000110a7605, 0x00000001801c4000, },
+};
+
+IMG_UINT64    gaErnsBrns[][2]=
+{
+	{ 0x0001002100020005, 0x000000000100044c, },
+	{ 0x0001002700040013, 0x0000000001000449, },
+	{ 0x0001003000020000, 0x0000000001000449, },
+	{ 0x000100480004000c, 0x0000000001000401, },
+	{ 0x0001004b00020014, 0x0000000001000441, },
+	{ 0x0001004b0002001e, 0x0000000001000441, },
+	{ 0x0001004c00040006, 0x0000000001000489, },
+	{ 0x000100510004000f, 0x0000000001000449, },
+	{ 0x0001005200040005, 0x0000000001000401, },
+	{ 0x0004001d00020033, 0x0000000205040121, },
+	{ 0x0004001f00040037, 0x0000000205040121, },
+	{ 0x0004002800020033, 0x0000000205040121, },
+	{ 0x0004002900020039, 0x0000000205040121, },
+	{ 0x0004002a00040035, 0x0000000205040121, },
+	{ 0x0004002b0006003e, 0x0000000205040121, },
+	{ 0x0004002d0002003a, 0x0000000205000121, },
+	{ 0x0004002e0006003e, 0x0000000204040121, },
+	{ 0x000500090001002e, 0x0000000000000a09, },
+	{ 0x0005000b0001002e, 0x0000000000000a41, },
+	{ 0x0006002200040023, 0x0000000205000121, },
+	{ 0x0008002f00020027, 0x000000008040e121, },
+	{ 0x0008003000020027, 0x000000008040e121, },
+	{ 0x000a001600040019, 0x000000008002e121, },
+	{ 0x000a001e0002001a, 0x000000008002e121, },
+	{ 0x000a002000040019, 0x000000008002e121, },
+	{ 0x000a002100040019, 0x000000008002e121, },
+	{ 0x000c000400010030, 0x0000000000000a09, },
+	{ 0x000c000500010014, 0x0000000000000a01, },
+	{ 0x000f000500010040, 0x0000000000000a01, },
+	{ 0x0016001200160016, 0x0000000152000b01, },
+	{ 0x0016001a00360018, 0x000000015a000b01, },
+	{ 0x0016001c00160017, 0x000000015a000b01, },
+	{ 0x0016001d0016001b, 0x000000015a000b01, },
+	{ 0x0016001e00360019, 0x000000015a000b01, },
+	{ 0x0016002000360148, 0x0000000152000b21, },
+	{ 0x001600210015000b, 0x000000015a000b01, },
+	{ 0x001600230016001b, 0x000000015a000b01, },
+	{ 0x001600280036001e, 0x000000015a000b01, },
+	{ 0x001600290036014a, 0x0000000152000b21, },
+	{ 0x0016002c00160019, 0x000000015a000b01, },
+	{ 0x0016002d0016001d, 0x000000015a000b01, },
+	{ 0x0016002e0036014a, 0x0000000152000b21, },
+	{ 0x0016002f00d00138, 0x0000000142000121, },
+	{ 0x001600300036001e, 0x000000015a000b01, },
+	{ 0x0016003100150010, 0x000000015a000101, },
+	{ 0x001600320016001d, 0x000000015a000b01, },
+	{ 0x001600370036001e, 0x000000011a000b01, },
+	{ 0x001600390036001e, 0x000000013a000b01, },
+	{ 0x0016003a00160019, 0x000000012a000b01, },
+	{ 0x0016003b0036001e, 0x0000000008000101, },
+	{ 0x0016003b0036001e, 0x000000012a000b01, },
+	{ 0x0016003e00150010, 0x000000012a000101, },
+	{ 0x0016003e00150010, 0x0000000028000101, },
+	{ 0x0016003f0036014a, 0x0000000122000b21, },
+	{ 0x0016003f0036014a, 0x0000000022000b21, },
+	{ 0x001600430036001e, 0x000000013a000b01, },
+	{ 0x001600440036001e, 0x000000012a000b01, },
+	{ 0x0016004500160019, 0x000000012a000b01, },
+	{ 0x0016004600d0013c, 0x0000000122000121, },
+};
+
+
+#endif /*_RGX_BVNC_TABLE_KM_H_ */
+
+
+
diff --git a/drivers/staging/imgtec/rogue/hwdefs/km/rgx_cr_defs_km.h b/drivers/staging/imgtec/rogue/hwdefs/km/rgx_cr_defs_km.h
index bab7c02..31814f8 100644
--- a/drivers/staging/imgtec/rogue/hwdefs/km/rgx_cr_defs_km.h
+++ b/drivers/staging/imgtec/rogue/hwdefs/km/rgx_cr_defs_km.h
@@ -42,8 +42,6 @@
 /*               ****   Autogenerated C -- do not edit    ****               */
 
 /*
- * Generated by regconv version MAIN@3328745
- *   from files:
  */
 
 #if !defined(__IMG_EXPLICIT_INCLUDE_HWDEFS)
@@ -55,6 +53,18 @@
 
 #include "img_types.h"
 
+
+#define RGX_CR_DEFS_KM_REVISION 1
+
+/*
+    Register RGX_CR_PBE_INDIRECT
+*/
+#define RGX_CR_PBE_INDIRECT                               (0x83E0U)
+#define RGX_CR_PBE_INDIRECT_MASKFULL                      (IMG_UINT64_C(0x000000000000000F))
+#define RGX_CR_PBE_INDIRECT_ADDRESS_SHIFT                 (0U)
+#define RGX_CR_PBE_INDIRECT_ADDRESS_CLRMSK                (0XFFFFFFF0U)
+
+
 /*
     Register RGX_CR_PBE_PERF_INDIRECT
 */
@@ -73,7 +83,6 @@
 #define RGX_CR_TPU_PERF_INDIRECT_ADDRESS_CLRMSK           (0XFFFFFFF8U)
 
 
-#if defined(RGX_FEATURE_CLUSTER_GROUPING)
 /*
     Register RGX_CR_RASTERISATION_PERF_INDIRECT
 */
@@ -83,8 +92,6 @@
 #define RGX_CR_RASTERISATION_PERF_INDIRECT_ADDRESS_CLRMSK (0XFFFFFFF0U)
 
 
-#endif /* RGX_FEATURE_CLUSTER_GROUPING */
-
 /*
     Register RGX_CR_TPU_MCU_L0_PERF_INDIRECT
 */
@@ -104,6 +111,15 @@
 
 
 /*
+    Register RGX_CR_BLACKPEARL_INDIRECT
+*/
+#define RGX_CR_BLACKPEARL_INDIRECT                        (0x8388U)
+#define RGX_CR_BLACKPEARL_INDIRECT_MASKFULL               (IMG_UINT64_C(0x0000000000000003))
+#define RGX_CR_BLACKPEARL_INDIRECT_ADDRESS_SHIFT          (0U)
+#define RGX_CR_BLACKPEARL_INDIRECT_ADDRESS_CLRMSK         (0XFFFFFFFCU)
+
+
+/*
     Register RGX_CR_BLACKPEARL_PERF_INDIRECT
 */
 #define RGX_CR_BLACKPEARL_PERF_INDIRECT                   (0x83F8U)
@@ -121,7 +137,6 @@
 #define RGX_CR_TEXAS3_PERF_INDIRECT_ADDRESS_CLRMSK        (0XFFFFFFF8U)
 
 
-#if defined(RGX_FEATURE_CLUSTER_GROUPING)
 /*
     Register RGX_CR_TEXAS_PERF_INDIRECT
 */
@@ -131,712 +146,284 @@
 #define RGX_CR_TEXAS_PERF_INDIRECT_ADDRESS_CLRMSK         (0XFFFFFFFCU)
 
 
-#endif /* RGX_FEATURE_CLUSTER_GROUPING */
+/*
+    Register RGX_CR_BX_TU_PERF_INDIRECT
+*/
+#define RGX_CR_BX_TU_PERF_INDIRECT                        (0xC900U)
+#define RGX_CR_BX_TU_PERF_INDIRECT_MASKFULL               (IMG_UINT64_C(0x0000000000000003))
+#define RGX_CR_BX_TU_PERF_INDIRECT_ADDRESS_SHIFT          (0U)
+#define RGX_CR_BX_TU_PERF_INDIRECT_ADDRESS_CLRMSK         (0XFFFFFFFCU)
 
-#if defined(RGX_FEATURE_PBE2_IN_XE)
+
 /*
     Register RGX_CR_CLK_CTRL
 */
 #define RGX_CR_CLK_CTRL                                   (0x0000U)
+#define RGX_CR_CLK_CTRL__PBE2_XE__MASKFULL                (IMG_UINT64_C(0xFFFFFF003F3FFFFF))
+#define RGX_CR_CLK_CTRL__S7_TOP__MASKFULL                 (IMG_UINT64_C(0xCFCF03000F3F3F0F))
 #define RGX_CR_CLK_CTRL_MASKFULL                          (IMG_UINT64_C(0xFFFFFF003F3FFFFF))
-#if defined(RGX_FEATURE_CLUSTER_GROUPING)
 #define RGX_CR_CLK_CTRL_BIF_TEXAS_SHIFT                   (62U)
 #define RGX_CR_CLK_CTRL_BIF_TEXAS_CLRMSK                  (IMG_UINT64_C(0X3FFFFFFFFFFFFFFF))
-#define RGX_CR_CLK_CTRL_BIF_TEXAS_OFF                     (IMG_UINT64_C(0000000000000000))
-#define RGX_CR_CLK_CTRL_BIF_TEXAS_ON                      (IMG_UINT64_C(0x4000000000000000))
-#define RGX_CR_CLK_CTRL_BIF_TEXAS_AUTO                    (IMG_UINT64_C(0x8000000000000000))
+#define RGX_CR_CLK_CTRL_BIF_TEXAS_OFF                     (IMG_UINT64_C(0000000000000000))  
+#define RGX_CR_CLK_CTRL_BIF_TEXAS_ON                      (IMG_UINT64_C(0x4000000000000000))  
+#define RGX_CR_CLK_CTRL_BIF_TEXAS_AUTO                    (IMG_UINT64_C(0x8000000000000000))  
 #define RGX_CR_CLK_CTRL_IPP_SHIFT                         (60U)
 #define RGX_CR_CLK_CTRL_IPP_CLRMSK                        (IMG_UINT64_C(0XCFFFFFFFFFFFFFFF))
-#define RGX_CR_CLK_CTRL_IPP_OFF                           (IMG_UINT64_C(0000000000000000))
-#define RGX_CR_CLK_CTRL_IPP_ON                            (IMG_UINT64_C(0x1000000000000000))
-#define RGX_CR_CLK_CTRL_IPP_AUTO                          (IMG_UINT64_C(0x2000000000000000))
-#endif /* RGX_FEATURE_CLUSTER_GROUPING */
-
+#define RGX_CR_CLK_CTRL_IPP_OFF                           (IMG_UINT64_C(0000000000000000))  
+#define RGX_CR_CLK_CTRL_IPP_ON                            (IMG_UINT64_C(0x1000000000000000))  
+#define RGX_CR_CLK_CTRL_IPP_AUTO                          (IMG_UINT64_C(0x2000000000000000))  
 #define RGX_CR_CLK_CTRL_FBC_SHIFT                         (58U)
 #define RGX_CR_CLK_CTRL_FBC_CLRMSK                        (IMG_UINT64_C(0XF3FFFFFFFFFFFFFF))
-#define RGX_CR_CLK_CTRL_FBC_OFF                           (IMG_UINT64_C(0000000000000000))
-#define RGX_CR_CLK_CTRL_FBC_ON                            (IMG_UINT64_C(0x0400000000000000))
-#define RGX_CR_CLK_CTRL_FBC_AUTO                          (IMG_UINT64_C(0x0800000000000000))
+#define RGX_CR_CLK_CTRL_FBC_OFF                           (IMG_UINT64_C(0000000000000000))  
+#define RGX_CR_CLK_CTRL_FBC_ON                            (IMG_UINT64_C(0x0400000000000000))  
+#define RGX_CR_CLK_CTRL_FBC_AUTO                          (IMG_UINT64_C(0x0800000000000000))  
 #define RGX_CR_CLK_CTRL_FBDC_SHIFT                        (56U)
 #define RGX_CR_CLK_CTRL_FBDC_CLRMSK                       (IMG_UINT64_C(0XFCFFFFFFFFFFFFFF))
-#define RGX_CR_CLK_CTRL_FBDC_OFF                          (IMG_UINT64_C(0000000000000000))
-#define RGX_CR_CLK_CTRL_FBDC_ON                           (IMG_UINT64_C(0x0100000000000000))
-#define RGX_CR_CLK_CTRL_FBDC_AUTO                         (IMG_UINT64_C(0x0200000000000000))
+#define RGX_CR_CLK_CTRL_FBDC_OFF                          (IMG_UINT64_C(0000000000000000))  
+#define RGX_CR_CLK_CTRL_FBDC_ON                           (IMG_UINT64_C(0x0100000000000000))  
+#define RGX_CR_CLK_CTRL_FBDC_AUTO                         (IMG_UINT64_C(0x0200000000000000))  
 #define RGX_CR_CLK_CTRL_FB_TLCACHE_SHIFT                  (54U)
 #define RGX_CR_CLK_CTRL_FB_TLCACHE_CLRMSK                 (IMG_UINT64_C(0XFF3FFFFFFFFFFFFF))
-#define RGX_CR_CLK_CTRL_FB_TLCACHE_OFF                    (IMG_UINT64_C(0000000000000000))
-#define RGX_CR_CLK_CTRL_FB_TLCACHE_ON                     (IMG_UINT64_C(0x0040000000000000))
-#define RGX_CR_CLK_CTRL_FB_TLCACHE_AUTO                   (IMG_UINT64_C(0x0080000000000000))
+#define RGX_CR_CLK_CTRL_FB_TLCACHE_OFF                    (IMG_UINT64_C(0000000000000000))  
+#define RGX_CR_CLK_CTRL_FB_TLCACHE_ON                     (IMG_UINT64_C(0x0040000000000000))  
+#define RGX_CR_CLK_CTRL_FB_TLCACHE_AUTO                   (IMG_UINT64_C(0x0080000000000000))  
 #define RGX_CR_CLK_CTRL_USCS_SHIFT                        (52U)
 #define RGX_CR_CLK_CTRL_USCS_CLRMSK                       (IMG_UINT64_C(0XFFCFFFFFFFFFFFFF))
-#define RGX_CR_CLK_CTRL_USCS_OFF                          (IMG_UINT64_C(0000000000000000))
-#define RGX_CR_CLK_CTRL_USCS_ON                           (IMG_UINT64_C(0x0010000000000000))
-#define RGX_CR_CLK_CTRL_USCS_AUTO                         (IMG_UINT64_C(0x0020000000000000))
+#define RGX_CR_CLK_CTRL_USCS_OFF                          (IMG_UINT64_C(0000000000000000))  
+#define RGX_CR_CLK_CTRL_USCS_ON                           (IMG_UINT64_C(0x0010000000000000))  
+#define RGX_CR_CLK_CTRL_USCS_AUTO                         (IMG_UINT64_C(0x0020000000000000))  
 #define RGX_CR_CLK_CTRL_PBE_SHIFT                         (50U)
 #define RGX_CR_CLK_CTRL_PBE_CLRMSK                        (IMG_UINT64_C(0XFFF3FFFFFFFFFFFF))
-#define RGX_CR_CLK_CTRL_PBE_OFF                           (IMG_UINT64_C(0000000000000000))
-#define RGX_CR_CLK_CTRL_PBE_ON                            (IMG_UINT64_C(0x0004000000000000))
-#define RGX_CR_CLK_CTRL_PBE_AUTO                          (IMG_UINT64_C(0x0008000000000000))
+#define RGX_CR_CLK_CTRL_PBE_OFF                           (IMG_UINT64_C(0000000000000000))  
+#define RGX_CR_CLK_CTRL_PBE_ON                            (IMG_UINT64_C(0x0004000000000000))  
+#define RGX_CR_CLK_CTRL_PBE_AUTO                          (IMG_UINT64_C(0x0008000000000000))  
 #define RGX_CR_CLK_CTRL_MCU_L1_SHIFT                      (48U)
 #define RGX_CR_CLK_CTRL_MCU_L1_CLRMSK                     (IMG_UINT64_C(0XFFFCFFFFFFFFFFFF))
-#define RGX_CR_CLK_CTRL_MCU_L1_OFF                        (IMG_UINT64_C(0000000000000000))
-#define RGX_CR_CLK_CTRL_MCU_L1_ON                         (IMG_UINT64_C(0x0001000000000000))
-#define RGX_CR_CLK_CTRL_MCU_L1_AUTO                       (IMG_UINT64_C(0x0002000000000000))
+#define RGX_CR_CLK_CTRL_MCU_L1_OFF                        (IMG_UINT64_C(0000000000000000))  
+#define RGX_CR_CLK_CTRL_MCU_L1_ON                         (IMG_UINT64_C(0x0001000000000000))  
+#define RGX_CR_CLK_CTRL_MCU_L1_AUTO                       (IMG_UINT64_C(0x0002000000000000))  
 #define RGX_CR_CLK_CTRL_CDM_SHIFT                         (46U)
 #define RGX_CR_CLK_CTRL_CDM_CLRMSK                        (IMG_UINT64_C(0XFFFF3FFFFFFFFFFF))
-#define RGX_CR_CLK_CTRL_CDM_OFF                           (IMG_UINT64_C(0000000000000000))
-#define RGX_CR_CLK_CTRL_CDM_ON                            (IMG_UINT64_C(0x0000400000000000))
-#define RGX_CR_CLK_CTRL_CDM_AUTO                          (IMG_UINT64_C(0x0000800000000000))
+#define RGX_CR_CLK_CTRL_CDM_OFF                           (IMG_UINT64_C(0000000000000000))  
+#define RGX_CR_CLK_CTRL_CDM_ON                            (IMG_UINT64_C(0x0000400000000000))  
+#define RGX_CR_CLK_CTRL_CDM_AUTO                          (IMG_UINT64_C(0x0000800000000000))  
 #define RGX_CR_CLK_CTRL_SIDEKICK_SHIFT                    (44U)
 #define RGX_CR_CLK_CTRL_SIDEKICK_CLRMSK                   (IMG_UINT64_C(0XFFFFCFFFFFFFFFFF))
-#define RGX_CR_CLK_CTRL_SIDEKICK_OFF                      (IMG_UINT64_C(0000000000000000))
-#define RGX_CR_CLK_CTRL_SIDEKICK_ON                       (IMG_UINT64_C(0x0000100000000000))
-#define RGX_CR_CLK_CTRL_SIDEKICK_AUTO                     (IMG_UINT64_C(0x0000200000000000))
+#define RGX_CR_CLK_CTRL_SIDEKICK_OFF                      (IMG_UINT64_C(0000000000000000))  
+#define RGX_CR_CLK_CTRL_SIDEKICK_ON                       (IMG_UINT64_C(0x0000100000000000))  
+#define RGX_CR_CLK_CTRL_SIDEKICK_AUTO                     (IMG_UINT64_C(0x0000200000000000))  
 #define RGX_CR_CLK_CTRL_BIF_SIDEKICK_SHIFT                (42U)
 #define RGX_CR_CLK_CTRL_BIF_SIDEKICK_CLRMSK               (IMG_UINT64_C(0XFFFFF3FFFFFFFFFF))
-#define RGX_CR_CLK_CTRL_BIF_SIDEKICK_OFF                  (IMG_UINT64_C(0000000000000000))
-#define RGX_CR_CLK_CTRL_BIF_SIDEKICK_ON                   (IMG_UINT64_C(0x0000040000000000))
-#define RGX_CR_CLK_CTRL_BIF_SIDEKICK_AUTO                 (IMG_UINT64_C(0x0000080000000000))
+#define RGX_CR_CLK_CTRL_BIF_SIDEKICK_OFF                  (IMG_UINT64_C(0000000000000000))  
+#define RGX_CR_CLK_CTRL_BIF_SIDEKICK_ON                   (IMG_UINT64_C(0x0000040000000000))  
+#define RGX_CR_CLK_CTRL_BIF_SIDEKICK_AUTO                 (IMG_UINT64_C(0x0000080000000000))  
 #define RGX_CR_CLK_CTRL_BIF_SHIFT                         (40U)
 #define RGX_CR_CLK_CTRL_BIF_CLRMSK                        (IMG_UINT64_C(0XFFFFFCFFFFFFFFFF))
-#define RGX_CR_CLK_CTRL_BIF_OFF                           (IMG_UINT64_C(0000000000000000))
-#define RGX_CR_CLK_CTRL_BIF_ON                            (IMG_UINT64_C(0x0000010000000000))
-#define RGX_CR_CLK_CTRL_BIF_AUTO                          (IMG_UINT64_C(0x0000020000000000))
+#define RGX_CR_CLK_CTRL_BIF_OFF                           (IMG_UINT64_C(0000000000000000))  
+#define RGX_CR_CLK_CTRL_BIF_ON                            (IMG_UINT64_C(0x0000010000000000))  
+#define RGX_CR_CLK_CTRL_BIF_AUTO                          (IMG_UINT64_C(0x0000020000000000))  
 #define RGX_CR_CLK_CTRL_TPU_MCU_DEMUX_SHIFT               (28U)
 #define RGX_CR_CLK_CTRL_TPU_MCU_DEMUX_CLRMSK              (IMG_UINT64_C(0XFFFFFFFFCFFFFFFF))
-#define RGX_CR_CLK_CTRL_TPU_MCU_DEMUX_OFF                 (IMG_UINT64_C(0000000000000000))
-#define RGX_CR_CLK_CTRL_TPU_MCU_DEMUX_ON                  (IMG_UINT64_C(0x0000000010000000))
-#define RGX_CR_CLK_CTRL_TPU_MCU_DEMUX_AUTO                (IMG_UINT64_C(0x0000000020000000))
+#define RGX_CR_CLK_CTRL_TPU_MCU_DEMUX_OFF                 (IMG_UINT64_C(0000000000000000))  
+#define RGX_CR_CLK_CTRL_TPU_MCU_DEMUX_ON                  (IMG_UINT64_C(0x0000000010000000))  
+#define RGX_CR_CLK_CTRL_TPU_MCU_DEMUX_AUTO                (IMG_UINT64_C(0x0000000020000000))  
 #define RGX_CR_CLK_CTRL_MCU_L0_SHIFT                      (26U)
 #define RGX_CR_CLK_CTRL_MCU_L0_CLRMSK                     (IMG_UINT64_C(0XFFFFFFFFF3FFFFFF))
-#define RGX_CR_CLK_CTRL_MCU_L0_OFF                        (IMG_UINT64_C(0000000000000000))
-#define RGX_CR_CLK_CTRL_MCU_L0_ON                         (IMG_UINT64_C(0x0000000004000000))
-#define RGX_CR_CLK_CTRL_MCU_L0_AUTO                       (IMG_UINT64_C(0x0000000008000000))
+#define RGX_CR_CLK_CTRL_MCU_L0_OFF                        (IMG_UINT64_C(0000000000000000))  
+#define RGX_CR_CLK_CTRL_MCU_L0_ON                         (IMG_UINT64_C(0x0000000004000000))  
+#define RGX_CR_CLK_CTRL_MCU_L0_AUTO                       (IMG_UINT64_C(0x0000000008000000))  
 #define RGX_CR_CLK_CTRL_TPU_SHIFT                         (24U)
 #define RGX_CR_CLK_CTRL_TPU_CLRMSK                        (IMG_UINT64_C(0XFFFFFFFFFCFFFFFF))
-#define RGX_CR_CLK_CTRL_TPU_OFF                           (IMG_UINT64_C(0000000000000000))
-#define RGX_CR_CLK_CTRL_TPU_ON                            (IMG_UINT64_C(0x0000000001000000))
-#define RGX_CR_CLK_CTRL_TPU_AUTO                          (IMG_UINT64_C(0x0000000002000000))
+#define RGX_CR_CLK_CTRL_TPU_OFF                           (IMG_UINT64_C(0000000000000000))  
+#define RGX_CR_CLK_CTRL_TPU_ON                            (IMG_UINT64_C(0x0000000001000000))  
+#define RGX_CR_CLK_CTRL_TPU_AUTO                          (IMG_UINT64_C(0x0000000002000000))  
 #define RGX_CR_CLK_CTRL_USC_SHIFT                         (20U)
 #define RGX_CR_CLK_CTRL_USC_CLRMSK                        (IMG_UINT64_C(0XFFFFFFFFFFCFFFFF))
-#define RGX_CR_CLK_CTRL_USC_OFF                           (IMG_UINT64_C(0000000000000000))
-#define RGX_CR_CLK_CTRL_USC_ON                            (IMG_UINT64_C(0x0000000000100000))
-#define RGX_CR_CLK_CTRL_USC_AUTO                          (IMG_UINT64_C(0x0000000000200000))
+#define RGX_CR_CLK_CTRL_USC_OFF                           (IMG_UINT64_C(0000000000000000))  
+#define RGX_CR_CLK_CTRL_USC_ON                            (IMG_UINT64_C(0x0000000000100000))  
+#define RGX_CR_CLK_CTRL_USC_AUTO                          (IMG_UINT64_C(0x0000000000200000))  
 #define RGX_CR_CLK_CTRL_TLA_SHIFT                         (18U)
 #define RGX_CR_CLK_CTRL_TLA_CLRMSK                        (IMG_UINT64_C(0XFFFFFFFFFFF3FFFF))
-#define RGX_CR_CLK_CTRL_TLA_OFF                           (IMG_UINT64_C(0000000000000000))
-#define RGX_CR_CLK_CTRL_TLA_ON                            (IMG_UINT64_C(0x0000000000040000))
-#define RGX_CR_CLK_CTRL_TLA_AUTO                          (IMG_UINT64_C(0x0000000000080000))
+#define RGX_CR_CLK_CTRL_TLA_OFF                           (IMG_UINT64_C(0000000000000000))  
+#define RGX_CR_CLK_CTRL_TLA_ON                            (IMG_UINT64_C(0x0000000000040000))  
+#define RGX_CR_CLK_CTRL_TLA_AUTO                          (IMG_UINT64_C(0x0000000000080000))  
 #define RGX_CR_CLK_CTRL_SLC_SHIFT                         (16U)
 #define RGX_CR_CLK_CTRL_SLC_CLRMSK                        (IMG_UINT64_C(0XFFFFFFFFFFFCFFFF))
-#define RGX_CR_CLK_CTRL_SLC_OFF                           (IMG_UINT64_C(0000000000000000))
-#define RGX_CR_CLK_CTRL_SLC_ON                            (IMG_UINT64_C(0x0000000000010000))
-#define RGX_CR_CLK_CTRL_SLC_AUTO                          (IMG_UINT64_C(0x0000000000020000))
+#define RGX_CR_CLK_CTRL_SLC_OFF                           (IMG_UINT64_C(0000000000000000))  
+#define RGX_CR_CLK_CTRL_SLC_ON                            (IMG_UINT64_C(0x0000000000010000))  
+#define RGX_CR_CLK_CTRL_SLC_AUTO                          (IMG_UINT64_C(0x0000000000020000))  
 #define RGX_CR_CLK_CTRL_UVS_SHIFT                         (14U)
 #define RGX_CR_CLK_CTRL_UVS_CLRMSK                        (IMG_UINT64_C(0XFFFFFFFFFFFF3FFF))
-#define RGX_CR_CLK_CTRL_UVS_OFF                           (IMG_UINT64_C(0000000000000000))
-#define RGX_CR_CLK_CTRL_UVS_ON                            (IMG_UINT64_C(0x0000000000004000))
-#define RGX_CR_CLK_CTRL_UVS_AUTO                          (IMG_UINT64_C(0x0000000000008000))
+#define RGX_CR_CLK_CTRL_UVS_OFF                           (IMG_UINT64_C(0000000000000000))  
+#define RGX_CR_CLK_CTRL_UVS_ON                            (IMG_UINT64_C(0x0000000000004000))  
+#define RGX_CR_CLK_CTRL_UVS_AUTO                          (IMG_UINT64_C(0x0000000000008000))  
 #define RGX_CR_CLK_CTRL_PDS_SHIFT                         (12U)
 #define RGX_CR_CLK_CTRL_PDS_CLRMSK                        (IMG_UINT64_C(0XFFFFFFFFFFFFCFFF))
-#define RGX_CR_CLK_CTRL_PDS_OFF                           (IMG_UINT64_C(0000000000000000))
-#define RGX_CR_CLK_CTRL_PDS_ON                            (IMG_UINT64_C(0x0000000000001000))
-#define RGX_CR_CLK_CTRL_PDS_AUTO                          (IMG_UINT64_C(0x0000000000002000))
+#define RGX_CR_CLK_CTRL_PDS_OFF                           (IMG_UINT64_C(0000000000000000))  
+#define RGX_CR_CLK_CTRL_PDS_ON                            (IMG_UINT64_C(0x0000000000001000))  
+#define RGX_CR_CLK_CTRL_PDS_AUTO                          (IMG_UINT64_C(0x0000000000002000))  
 #define RGX_CR_CLK_CTRL_VDM_SHIFT                         (10U)
 #define RGX_CR_CLK_CTRL_VDM_CLRMSK                        (IMG_UINT64_C(0XFFFFFFFFFFFFF3FF))
-#define RGX_CR_CLK_CTRL_VDM_OFF                           (IMG_UINT64_C(0000000000000000))
-#define RGX_CR_CLK_CTRL_VDM_ON                            (IMG_UINT64_C(0x0000000000000400))
-#define RGX_CR_CLK_CTRL_VDM_AUTO                          (IMG_UINT64_C(0x0000000000000800))
+#define RGX_CR_CLK_CTRL_VDM_OFF                           (IMG_UINT64_C(0000000000000000))  
+#define RGX_CR_CLK_CTRL_VDM_ON                            (IMG_UINT64_C(0x0000000000000400))  
+#define RGX_CR_CLK_CTRL_VDM_AUTO                          (IMG_UINT64_C(0x0000000000000800))  
 #define RGX_CR_CLK_CTRL_PM_SHIFT                          (8U)
 #define RGX_CR_CLK_CTRL_PM_CLRMSK                         (IMG_UINT64_C(0XFFFFFFFFFFFFFCFF))
-#define RGX_CR_CLK_CTRL_PM_OFF                            (IMG_UINT64_C(0000000000000000))
-#define RGX_CR_CLK_CTRL_PM_ON                             (IMG_UINT64_C(0x0000000000000100))
-#define RGX_CR_CLK_CTRL_PM_AUTO                           (IMG_UINT64_C(0x0000000000000200))
+#define RGX_CR_CLK_CTRL_PM_OFF                            (IMG_UINT64_C(0000000000000000))  
+#define RGX_CR_CLK_CTRL_PM_ON                             (IMG_UINT64_C(0x0000000000000100))  
+#define RGX_CR_CLK_CTRL_PM_AUTO                           (IMG_UINT64_C(0x0000000000000200))  
 #define RGX_CR_CLK_CTRL_GPP_SHIFT                         (6U)
 #define RGX_CR_CLK_CTRL_GPP_CLRMSK                        (IMG_UINT64_C(0XFFFFFFFFFFFFFF3F))
-#define RGX_CR_CLK_CTRL_GPP_OFF                           (IMG_UINT64_C(0000000000000000))
-#define RGX_CR_CLK_CTRL_GPP_ON                            (IMG_UINT64_C(0x0000000000000040))
-#define RGX_CR_CLK_CTRL_GPP_AUTO                          (IMG_UINT64_C(0x0000000000000080))
+#define RGX_CR_CLK_CTRL_GPP_OFF                           (IMG_UINT64_C(0000000000000000))  
+#define RGX_CR_CLK_CTRL_GPP_ON                            (IMG_UINT64_C(0x0000000000000040))  
+#define RGX_CR_CLK_CTRL_GPP_AUTO                          (IMG_UINT64_C(0x0000000000000080))  
 #define RGX_CR_CLK_CTRL_TE_SHIFT                          (4U)
 #define RGX_CR_CLK_CTRL_TE_CLRMSK                         (IMG_UINT64_C(0XFFFFFFFFFFFFFFCF))
-#define RGX_CR_CLK_CTRL_TE_OFF                            (IMG_UINT64_C(0000000000000000))
-#define RGX_CR_CLK_CTRL_TE_ON                             (IMG_UINT64_C(0x0000000000000010))
-#define RGX_CR_CLK_CTRL_TE_AUTO                           (IMG_UINT64_C(0x0000000000000020))
+#define RGX_CR_CLK_CTRL_TE_OFF                            (IMG_UINT64_C(0000000000000000))  
+#define RGX_CR_CLK_CTRL_TE_ON                             (IMG_UINT64_C(0x0000000000000010))  
+#define RGX_CR_CLK_CTRL_TE_AUTO                           (IMG_UINT64_C(0x0000000000000020))  
 #define RGX_CR_CLK_CTRL_TSP_SHIFT                         (2U)
 #define RGX_CR_CLK_CTRL_TSP_CLRMSK                        (IMG_UINT64_C(0XFFFFFFFFFFFFFFF3))
-#define RGX_CR_CLK_CTRL_TSP_OFF                           (IMG_UINT64_C(0000000000000000))
-#define RGX_CR_CLK_CTRL_TSP_ON                            (IMG_UINT64_C(0x0000000000000004))
-#define RGX_CR_CLK_CTRL_TSP_AUTO                          (IMG_UINT64_C(0x0000000000000008))
+#define RGX_CR_CLK_CTRL_TSP_OFF                           (IMG_UINT64_C(0000000000000000))  
+#define RGX_CR_CLK_CTRL_TSP_ON                            (IMG_UINT64_C(0x0000000000000004))  
+#define RGX_CR_CLK_CTRL_TSP_AUTO                          (IMG_UINT64_C(0x0000000000000008))  
 #define RGX_CR_CLK_CTRL_ISP_SHIFT                         (0U)
 #define RGX_CR_CLK_CTRL_ISP_CLRMSK                        (IMG_UINT64_C(0XFFFFFFFFFFFFFFFC))
-#define RGX_CR_CLK_CTRL_ISP_OFF                           (IMG_UINT64_C(0000000000000000))
-#define RGX_CR_CLK_CTRL_ISP_ON                            (IMG_UINT64_C(0x0000000000000001))
-#define RGX_CR_CLK_CTRL_ISP_AUTO                          (IMG_UINT64_C(0x0000000000000002))
-#endif /* RGX_FEATURE_PBE2_IN_XE */ 
+#define RGX_CR_CLK_CTRL_ISP_OFF                           (IMG_UINT64_C(0000000000000000))  
+#define RGX_CR_CLK_CTRL_ISP_ON                            (IMG_UINT64_C(0x0000000000000001))  
+#define RGX_CR_CLK_CTRL_ISP_AUTO                          (IMG_UINT64_C(0x0000000000000002))  
 
 
-#if defined(RGX_FEATURE_S7_TOP_INFRASTRUCTURE)
-/*
-    Register RGX_CR_CLK_CTRL
-*/
-#define RGX_CR_CLK_CTRL                                   (0x0000U)
-#define RGX_CR_CLK_CTRL_MASKFULL                          (IMG_UINT64_C(0xCFCF03000F3F3F0F))
-#if defined(RGX_FEATURE_CLUSTER_GROUPING)
-#define RGX_CR_CLK_CTRL_BIF_TEXAS_SHIFT                   (62U)
-#define RGX_CR_CLK_CTRL_BIF_TEXAS_CLRMSK                  (IMG_UINT64_C(0X3FFFFFFFFFFFFFFF))
-#define RGX_CR_CLK_CTRL_BIF_TEXAS_OFF                     (IMG_UINT64_C(0000000000000000))
-#define RGX_CR_CLK_CTRL_BIF_TEXAS_ON                      (IMG_UINT64_C(0x4000000000000000))
-#define RGX_CR_CLK_CTRL_BIF_TEXAS_AUTO                    (IMG_UINT64_C(0x8000000000000000))
-#endif /* RGX_FEATURE_CLUSTER_GROUPING */
-
-#define RGX_CR_CLK_CTRL_FBC_SHIFT                         (58U)
-#define RGX_CR_CLK_CTRL_FBC_CLRMSK                        (IMG_UINT64_C(0XF3FFFFFFFFFFFFFF))
-#define RGX_CR_CLK_CTRL_FBC_OFF                           (IMG_UINT64_C(0000000000000000))
-#define RGX_CR_CLK_CTRL_FBC_ON                            (IMG_UINT64_C(0x0400000000000000))
-#define RGX_CR_CLK_CTRL_FBC_AUTO                          (IMG_UINT64_C(0x0800000000000000))
-#define RGX_CR_CLK_CTRL_FBDC_SHIFT                        (56U)
-#define RGX_CR_CLK_CTRL_FBDC_CLRMSK                       (IMG_UINT64_C(0XFCFFFFFFFFFFFFFF))
-#define RGX_CR_CLK_CTRL_FBDC_OFF                          (IMG_UINT64_C(0000000000000000))
-#define RGX_CR_CLK_CTRL_FBDC_ON                           (IMG_UINT64_C(0x0100000000000000))
-#define RGX_CR_CLK_CTRL_FBDC_AUTO                         (IMG_UINT64_C(0x0200000000000000))
-#define RGX_CR_CLK_CTRL_FB_TLCACHE_SHIFT                  (54U)
-#define RGX_CR_CLK_CTRL_FB_TLCACHE_CLRMSK                 (IMG_UINT64_C(0XFF3FFFFFFFFFFFFF))
-#define RGX_CR_CLK_CTRL_FB_TLCACHE_OFF                    (IMG_UINT64_C(0000000000000000))
-#define RGX_CR_CLK_CTRL_FB_TLCACHE_ON                     (IMG_UINT64_C(0x0040000000000000))
-#define RGX_CR_CLK_CTRL_FB_TLCACHE_AUTO                   (IMG_UINT64_C(0x0080000000000000))
-#define RGX_CR_CLK_CTRL_PBE_SHIFT                         (50U)
-#define RGX_CR_CLK_CTRL_PBE_CLRMSK                        (IMG_UINT64_C(0XFFF3FFFFFFFFFFFF))
-#define RGX_CR_CLK_CTRL_PBE_OFF                           (IMG_UINT64_C(0000000000000000))
-#define RGX_CR_CLK_CTRL_PBE_ON                            (IMG_UINT64_C(0x0004000000000000))
-#define RGX_CR_CLK_CTRL_PBE_AUTO                          (IMG_UINT64_C(0x0008000000000000))
-#define RGX_CR_CLK_CTRL_MCU_L1_SHIFT                      (48U)
-#define RGX_CR_CLK_CTRL_MCU_L1_CLRMSK                     (IMG_UINT64_C(0XFFFCFFFFFFFFFFFF))
-#define RGX_CR_CLK_CTRL_MCU_L1_OFF                        (IMG_UINT64_C(0000000000000000))
-#define RGX_CR_CLK_CTRL_MCU_L1_ON                         (IMG_UINT64_C(0x0001000000000000))
-#define RGX_CR_CLK_CTRL_MCU_L1_AUTO                       (IMG_UINT64_C(0x0002000000000000))
-#define RGX_CR_CLK_CTRL_BIF_SHIFT                         (40U)
-#define RGX_CR_CLK_CTRL_BIF_CLRMSK                        (IMG_UINT64_C(0XFFFFFCFFFFFFFFFF))
-#define RGX_CR_CLK_CTRL_BIF_OFF                           (IMG_UINT64_C(0000000000000000))
-#define RGX_CR_CLK_CTRL_BIF_ON                            (IMG_UINT64_C(0x0000010000000000))
-#define RGX_CR_CLK_CTRL_BIF_AUTO                          (IMG_UINT64_C(0x0000020000000000))
-#define RGX_CR_CLK_CTRL_MCU_L0_SHIFT                      (26U)
-#define RGX_CR_CLK_CTRL_MCU_L0_CLRMSK                     (IMG_UINT64_C(0XFFFFFFFFF3FFFFFF))
-#define RGX_CR_CLK_CTRL_MCU_L0_OFF                        (IMG_UINT64_C(0000000000000000))
-#define RGX_CR_CLK_CTRL_MCU_L0_ON                         (IMG_UINT64_C(0x0000000004000000))
-#define RGX_CR_CLK_CTRL_MCU_L0_AUTO                       (IMG_UINT64_C(0x0000000008000000))
-#define RGX_CR_CLK_CTRL_TPU_SHIFT                         (24U)
-#define RGX_CR_CLK_CTRL_TPU_CLRMSK                        (IMG_UINT64_C(0XFFFFFFFFFCFFFFFF))
-#define RGX_CR_CLK_CTRL_TPU_OFF                           (IMG_UINT64_C(0000000000000000))
-#define RGX_CR_CLK_CTRL_TPU_ON                            (IMG_UINT64_C(0x0000000001000000))
-#define RGX_CR_CLK_CTRL_TPU_AUTO                          (IMG_UINT64_C(0x0000000002000000))
-#define RGX_CR_CLK_CTRL_USC_SHIFT                         (20U)
-#define RGX_CR_CLK_CTRL_USC_CLRMSK                        (IMG_UINT64_C(0XFFFFFFFFFFCFFFFF))
-#define RGX_CR_CLK_CTRL_USC_OFF                           (IMG_UINT64_C(0000000000000000))
-#define RGX_CR_CLK_CTRL_USC_ON                            (IMG_UINT64_C(0x0000000000100000))
-#define RGX_CR_CLK_CTRL_USC_AUTO                          (IMG_UINT64_C(0x0000000000200000))
-#define RGX_CR_CLK_CTRL_TLA_SHIFT                         (18U)
-#define RGX_CR_CLK_CTRL_TLA_CLRMSK                        (IMG_UINT64_C(0XFFFFFFFFFFF3FFFF))
-#define RGX_CR_CLK_CTRL_TLA_OFF                           (IMG_UINT64_C(0000000000000000))
-#define RGX_CR_CLK_CTRL_TLA_ON                            (IMG_UINT64_C(0x0000000000040000))
-#define RGX_CR_CLK_CTRL_TLA_AUTO                          (IMG_UINT64_C(0x0000000000080000))
-#define RGX_CR_CLK_CTRL_SLC_SHIFT                         (16U)
-#define RGX_CR_CLK_CTRL_SLC_CLRMSK                        (IMG_UINT64_C(0XFFFFFFFFFFFCFFFF))
-#define RGX_CR_CLK_CTRL_SLC_OFF                           (IMG_UINT64_C(0000000000000000))
-#define RGX_CR_CLK_CTRL_SLC_ON                            (IMG_UINT64_C(0x0000000000010000))
-#define RGX_CR_CLK_CTRL_SLC_AUTO                          (IMG_UINT64_C(0x0000000000020000))
-#define RGX_CR_CLK_CTRL_PDS_SHIFT                         (12U)
-#define RGX_CR_CLK_CTRL_PDS_CLRMSK                        (IMG_UINT64_C(0XFFFFFFFFFFFFCFFF))
-#define RGX_CR_CLK_CTRL_PDS_OFF                           (IMG_UINT64_C(0000000000000000))
-#define RGX_CR_CLK_CTRL_PDS_ON                            (IMG_UINT64_C(0x0000000000001000))
-#define RGX_CR_CLK_CTRL_PDS_AUTO                          (IMG_UINT64_C(0x0000000000002000))
-#define RGX_CR_CLK_CTRL_VDM_SHIFT                         (10U)
-#define RGX_CR_CLK_CTRL_VDM_CLRMSK                        (IMG_UINT64_C(0XFFFFFFFFFFFFF3FF))
-#define RGX_CR_CLK_CTRL_VDM_OFF                           (IMG_UINT64_C(0000000000000000))
-#define RGX_CR_CLK_CTRL_VDM_ON                            (IMG_UINT64_C(0x0000000000000400))
-#define RGX_CR_CLK_CTRL_VDM_AUTO                          (IMG_UINT64_C(0x0000000000000800))
-#define RGX_CR_CLK_CTRL_PM_SHIFT                          (8U)
-#define RGX_CR_CLK_CTRL_PM_CLRMSK                         (IMG_UINT64_C(0XFFFFFFFFFFFFFCFF))
-#define RGX_CR_CLK_CTRL_PM_OFF                            (IMG_UINT64_C(0000000000000000))
-#define RGX_CR_CLK_CTRL_PM_ON                             (IMG_UINT64_C(0x0000000000000100))
-#define RGX_CR_CLK_CTRL_PM_AUTO                           (IMG_UINT64_C(0x0000000000000200))
-#define RGX_CR_CLK_CTRL_TSP_SHIFT                         (2U)
-#define RGX_CR_CLK_CTRL_TSP_CLRMSK                        (IMG_UINT64_C(0XFFFFFFFFFFFFFFF3))
-#define RGX_CR_CLK_CTRL_TSP_OFF                           (IMG_UINT64_C(0000000000000000))
-#define RGX_CR_CLK_CTRL_TSP_ON                            (IMG_UINT64_C(0x0000000000000004))
-#define RGX_CR_CLK_CTRL_TSP_AUTO                          (IMG_UINT64_C(0x0000000000000008))
-#define RGX_CR_CLK_CTRL_ISP_SHIFT                         (0U)
-#define RGX_CR_CLK_CTRL_ISP_CLRMSK                        (IMG_UINT64_C(0XFFFFFFFFFFFFFFFC))
-#define RGX_CR_CLK_CTRL_ISP_OFF                           (IMG_UINT64_C(0000000000000000))
-#define RGX_CR_CLK_CTRL_ISP_ON                            (IMG_UINT64_C(0x0000000000000001))
-#define RGX_CR_CLK_CTRL_ISP_AUTO                          (IMG_UINT64_C(0x0000000000000002))
-#endif /* RGX_FEATURE_S7_TOP_INFRASTRUCTURE */ 
-
-
-#if !defined(RGX_FEATURE_PBE2_IN_XE) && !defined(RGX_FEATURE_S7_TOP_INFRASTRUCTURE)
-/*
-    Register RGX_CR_CLK_CTRL
-*/
-#define RGX_CR_CLK_CTRL                                   (0x0000U)
-#define RGX_CR_CLK_CTRL_MASKFULL                          (IMG_UINT64_C(0xFFFFFF003F3FFFFF))
-#if defined(RGX_FEATURE_CLUSTER_GROUPING)
-#define RGX_CR_CLK_CTRL_BIF_TEXAS_SHIFT                   (62U)
-#define RGX_CR_CLK_CTRL_BIF_TEXAS_CLRMSK                  (IMG_UINT64_C(0X3FFFFFFFFFFFFFFF))
-#define RGX_CR_CLK_CTRL_BIF_TEXAS_OFF                     (IMG_UINT64_C(0000000000000000))
-#define RGX_CR_CLK_CTRL_BIF_TEXAS_ON                      (IMG_UINT64_C(0x4000000000000000))
-#define RGX_CR_CLK_CTRL_BIF_TEXAS_AUTO                    (IMG_UINT64_C(0x8000000000000000))
-#define RGX_CR_CLK_CTRL_IPP_SHIFT                         (60U)
-#define RGX_CR_CLK_CTRL_IPP_CLRMSK                        (IMG_UINT64_C(0XCFFFFFFFFFFFFFFF))
-#define RGX_CR_CLK_CTRL_IPP_OFF                           (IMG_UINT64_C(0000000000000000))
-#define RGX_CR_CLK_CTRL_IPP_ON                            (IMG_UINT64_C(0x1000000000000000))
-#define RGX_CR_CLK_CTRL_IPP_AUTO                          (IMG_UINT64_C(0x2000000000000000))
-#endif /* RGX_FEATURE_CLUSTER_GROUPING */
-
-#define RGX_CR_CLK_CTRL_FBC_SHIFT                         (58U)
-#define RGX_CR_CLK_CTRL_FBC_CLRMSK                        (IMG_UINT64_C(0XF3FFFFFFFFFFFFFF))
-#define RGX_CR_CLK_CTRL_FBC_OFF                           (IMG_UINT64_C(0000000000000000))
-#define RGX_CR_CLK_CTRL_FBC_ON                            (IMG_UINT64_C(0x0400000000000000))
-#define RGX_CR_CLK_CTRL_FBC_AUTO                          (IMG_UINT64_C(0x0800000000000000))
-#define RGX_CR_CLK_CTRL_FBDC_SHIFT                        (56U)
-#define RGX_CR_CLK_CTRL_FBDC_CLRMSK                       (IMG_UINT64_C(0XFCFFFFFFFFFFFFFF))
-#define RGX_CR_CLK_CTRL_FBDC_OFF                          (IMG_UINT64_C(0000000000000000))
-#define RGX_CR_CLK_CTRL_FBDC_ON                           (IMG_UINT64_C(0x0100000000000000))
-#define RGX_CR_CLK_CTRL_FBDC_AUTO                         (IMG_UINT64_C(0x0200000000000000))
-#define RGX_CR_CLK_CTRL_FB_TLCACHE_SHIFT                  (54U)
-#define RGX_CR_CLK_CTRL_FB_TLCACHE_CLRMSK                 (IMG_UINT64_C(0XFF3FFFFFFFFFFFFF))
-#define RGX_CR_CLK_CTRL_FB_TLCACHE_OFF                    (IMG_UINT64_C(0000000000000000))
-#define RGX_CR_CLK_CTRL_FB_TLCACHE_ON                     (IMG_UINT64_C(0x0040000000000000))
-#define RGX_CR_CLK_CTRL_FB_TLCACHE_AUTO                   (IMG_UINT64_C(0x0080000000000000))
-#define RGX_CR_CLK_CTRL_USCS_SHIFT                        (52U)
-#define RGX_CR_CLK_CTRL_USCS_CLRMSK                       (IMG_UINT64_C(0XFFCFFFFFFFFFFFFF))
-#define RGX_CR_CLK_CTRL_USCS_OFF                          (IMG_UINT64_C(0000000000000000))
-#define RGX_CR_CLK_CTRL_USCS_ON                           (IMG_UINT64_C(0x0010000000000000))
-#define RGX_CR_CLK_CTRL_USCS_AUTO                         (IMG_UINT64_C(0x0020000000000000))
-#define RGX_CR_CLK_CTRL_PBE_SHIFT                         (50U)
-#define RGX_CR_CLK_CTRL_PBE_CLRMSK                        (IMG_UINT64_C(0XFFF3FFFFFFFFFFFF))
-#define RGX_CR_CLK_CTRL_PBE_OFF                           (IMG_UINT64_C(0000000000000000))
-#define RGX_CR_CLK_CTRL_PBE_ON                            (IMG_UINT64_C(0x0004000000000000))
-#define RGX_CR_CLK_CTRL_PBE_AUTO                          (IMG_UINT64_C(0x0008000000000000))
-#define RGX_CR_CLK_CTRL_MCU_L1_SHIFT                      (48U)
-#define RGX_CR_CLK_CTRL_MCU_L1_CLRMSK                     (IMG_UINT64_C(0XFFFCFFFFFFFFFFFF))
-#define RGX_CR_CLK_CTRL_MCU_L1_OFF                        (IMG_UINT64_C(0000000000000000))
-#define RGX_CR_CLK_CTRL_MCU_L1_ON                         (IMG_UINT64_C(0x0001000000000000))
-#define RGX_CR_CLK_CTRL_MCU_L1_AUTO                       (IMG_UINT64_C(0x0002000000000000))
-#if defined(RGX_FEATURE_COMPUTE)
-#define RGX_CR_CLK_CTRL_CDM_SHIFT                         (46U)
-#define RGX_CR_CLK_CTRL_CDM_CLRMSK                        (IMG_UINT64_C(0XFFFF3FFFFFFFFFFF))
-#define RGX_CR_CLK_CTRL_CDM_OFF                           (IMG_UINT64_C(0000000000000000))
-#define RGX_CR_CLK_CTRL_CDM_ON                            (IMG_UINT64_C(0x0000400000000000))
-#define RGX_CR_CLK_CTRL_CDM_AUTO                          (IMG_UINT64_C(0x0000800000000000))
-#endif /* RGX_FEATURE_COMPUTE */
-
-#define RGX_CR_CLK_CTRL_SIDEKICK_SHIFT                    (44U)
-#define RGX_CR_CLK_CTRL_SIDEKICK_CLRMSK                   (IMG_UINT64_C(0XFFFFCFFFFFFFFFFF))
-#define RGX_CR_CLK_CTRL_SIDEKICK_OFF                      (IMG_UINT64_C(0000000000000000))
-#define RGX_CR_CLK_CTRL_SIDEKICK_ON                       (IMG_UINT64_C(0x0000100000000000))
-#define RGX_CR_CLK_CTRL_SIDEKICK_AUTO                     (IMG_UINT64_C(0x0000200000000000))
-#define RGX_CR_CLK_CTRL_BIF_SIDEKICK_SHIFT                (42U)
-#define RGX_CR_CLK_CTRL_BIF_SIDEKICK_CLRMSK               (IMG_UINT64_C(0XFFFFF3FFFFFFFFFF))
-#define RGX_CR_CLK_CTRL_BIF_SIDEKICK_OFF                  (IMG_UINT64_C(0000000000000000))
-#define RGX_CR_CLK_CTRL_BIF_SIDEKICK_ON                   (IMG_UINT64_C(0x0000040000000000))
-#define RGX_CR_CLK_CTRL_BIF_SIDEKICK_AUTO                 (IMG_UINT64_C(0x0000080000000000))
-#define RGX_CR_CLK_CTRL_BIF_SHIFT                         (40U)
-#define RGX_CR_CLK_CTRL_BIF_CLRMSK                        (IMG_UINT64_C(0XFFFFFCFFFFFFFFFF))
-#define RGX_CR_CLK_CTRL_BIF_OFF                           (IMG_UINT64_C(0000000000000000))
-#define RGX_CR_CLK_CTRL_BIF_ON                            (IMG_UINT64_C(0x0000010000000000))
-#define RGX_CR_CLK_CTRL_BIF_AUTO                          (IMG_UINT64_C(0x0000020000000000))
-#define RGX_CR_CLK_CTRL_TPU_MCU_DEMUX_SHIFT               (28U)
-#define RGX_CR_CLK_CTRL_TPU_MCU_DEMUX_CLRMSK              (IMG_UINT64_C(0XFFFFFFFFCFFFFFFF))
-#define RGX_CR_CLK_CTRL_TPU_MCU_DEMUX_OFF                 (IMG_UINT64_C(0000000000000000))
-#define RGX_CR_CLK_CTRL_TPU_MCU_DEMUX_ON                  (IMG_UINT64_C(0x0000000010000000))
-#define RGX_CR_CLK_CTRL_TPU_MCU_DEMUX_AUTO                (IMG_UINT64_C(0x0000000020000000))
-#define RGX_CR_CLK_CTRL_MCU_L0_SHIFT                      (26U)
-#define RGX_CR_CLK_CTRL_MCU_L0_CLRMSK                     (IMG_UINT64_C(0XFFFFFFFFF3FFFFFF))
-#define RGX_CR_CLK_CTRL_MCU_L0_OFF                        (IMG_UINT64_C(0000000000000000))
-#define RGX_CR_CLK_CTRL_MCU_L0_ON                         (IMG_UINT64_C(0x0000000004000000))
-#define RGX_CR_CLK_CTRL_MCU_L0_AUTO                       (IMG_UINT64_C(0x0000000008000000))
-#define RGX_CR_CLK_CTRL_TPU_SHIFT                         (24U)
-#define RGX_CR_CLK_CTRL_TPU_CLRMSK                        (IMG_UINT64_C(0XFFFFFFFFFCFFFFFF))
-#define RGX_CR_CLK_CTRL_TPU_OFF                           (IMG_UINT64_C(0000000000000000))
-#define RGX_CR_CLK_CTRL_TPU_ON                            (IMG_UINT64_C(0x0000000001000000))
-#define RGX_CR_CLK_CTRL_TPU_AUTO                          (IMG_UINT64_C(0x0000000002000000))
-#define RGX_CR_CLK_CTRL_USC_SHIFT                         (20U)
-#define RGX_CR_CLK_CTRL_USC_CLRMSK                        (IMG_UINT64_C(0XFFFFFFFFFFCFFFFF))
-#define RGX_CR_CLK_CTRL_USC_OFF                           (IMG_UINT64_C(0000000000000000))
-#define RGX_CR_CLK_CTRL_USC_ON                            (IMG_UINT64_C(0x0000000000100000))
-#define RGX_CR_CLK_CTRL_USC_AUTO                          (IMG_UINT64_C(0x0000000000200000))
-#define RGX_CR_CLK_CTRL_TLA_SHIFT                         (18U)
-#define RGX_CR_CLK_CTRL_TLA_CLRMSK                        (IMG_UINT64_C(0XFFFFFFFFFFF3FFFF))
-#define RGX_CR_CLK_CTRL_TLA_OFF                           (IMG_UINT64_C(0000000000000000))
-#define RGX_CR_CLK_CTRL_TLA_ON                            (IMG_UINT64_C(0x0000000000040000))
-#define RGX_CR_CLK_CTRL_TLA_AUTO                          (IMG_UINT64_C(0x0000000000080000))
-#define RGX_CR_CLK_CTRL_SLC_SHIFT                         (16U)
-#define RGX_CR_CLK_CTRL_SLC_CLRMSK                        (IMG_UINT64_C(0XFFFFFFFFFFFCFFFF))
-#define RGX_CR_CLK_CTRL_SLC_OFF                           (IMG_UINT64_C(0000000000000000))
-#define RGX_CR_CLK_CTRL_SLC_ON                            (IMG_UINT64_C(0x0000000000010000))
-#define RGX_CR_CLK_CTRL_SLC_AUTO                          (IMG_UINT64_C(0x0000000000020000))
-#define RGX_CR_CLK_CTRL_UVS_SHIFT                         (14U)
-#define RGX_CR_CLK_CTRL_UVS_CLRMSK                        (IMG_UINT64_C(0XFFFFFFFFFFFF3FFF))
-#define RGX_CR_CLK_CTRL_UVS_OFF                           (IMG_UINT64_C(0000000000000000))
-#define RGX_CR_CLK_CTRL_UVS_ON                            (IMG_UINT64_C(0x0000000000004000))
-#define RGX_CR_CLK_CTRL_UVS_AUTO                          (IMG_UINT64_C(0x0000000000008000))
-#define RGX_CR_CLK_CTRL_PDS_SHIFT                         (12U)
-#define RGX_CR_CLK_CTRL_PDS_CLRMSK                        (IMG_UINT64_C(0XFFFFFFFFFFFFCFFF))
-#define RGX_CR_CLK_CTRL_PDS_OFF                           (IMG_UINT64_C(0000000000000000))
-#define RGX_CR_CLK_CTRL_PDS_ON                            (IMG_UINT64_C(0x0000000000001000))
-#define RGX_CR_CLK_CTRL_PDS_AUTO                          (IMG_UINT64_C(0x0000000000002000))
-#define RGX_CR_CLK_CTRL_VDM_SHIFT                         (10U)
-#define RGX_CR_CLK_CTRL_VDM_CLRMSK                        (IMG_UINT64_C(0XFFFFFFFFFFFFF3FF))
-#define RGX_CR_CLK_CTRL_VDM_OFF                           (IMG_UINT64_C(0000000000000000))
-#define RGX_CR_CLK_CTRL_VDM_ON                            (IMG_UINT64_C(0x0000000000000400))
-#define RGX_CR_CLK_CTRL_VDM_AUTO                          (IMG_UINT64_C(0x0000000000000800))
-#define RGX_CR_CLK_CTRL_PM_SHIFT                          (8U)
-#define RGX_CR_CLK_CTRL_PM_CLRMSK                         (IMG_UINT64_C(0XFFFFFFFFFFFFFCFF))
-#define RGX_CR_CLK_CTRL_PM_OFF                            (IMG_UINT64_C(0000000000000000))
-#define RGX_CR_CLK_CTRL_PM_ON                             (IMG_UINT64_C(0x0000000000000100))
-#define RGX_CR_CLK_CTRL_PM_AUTO                           (IMG_UINT64_C(0x0000000000000200))
-#define RGX_CR_CLK_CTRL_GPP_SHIFT                         (6U)
-#define RGX_CR_CLK_CTRL_GPP_CLRMSK                        (IMG_UINT64_C(0XFFFFFFFFFFFFFF3F))
-#define RGX_CR_CLK_CTRL_GPP_OFF                           (IMG_UINT64_C(0000000000000000))
-#define RGX_CR_CLK_CTRL_GPP_ON                            (IMG_UINT64_C(0x0000000000000040))
-#define RGX_CR_CLK_CTRL_GPP_AUTO                          (IMG_UINT64_C(0x0000000000000080))
-#define RGX_CR_CLK_CTRL_TE_SHIFT                          (4U)
-#define RGX_CR_CLK_CTRL_TE_CLRMSK                         (IMG_UINT64_C(0XFFFFFFFFFFFFFFCF))
-#define RGX_CR_CLK_CTRL_TE_OFF                            (IMG_UINT64_C(0000000000000000))
-#define RGX_CR_CLK_CTRL_TE_ON                             (IMG_UINT64_C(0x0000000000000010))
-#define RGX_CR_CLK_CTRL_TE_AUTO                           (IMG_UINT64_C(0x0000000000000020))
-#define RGX_CR_CLK_CTRL_TSP_SHIFT                         (2U)
-#define RGX_CR_CLK_CTRL_TSP_CLRMSK                        (IMG_UINT64_C(0XFFFFFFFFFFFFFFF3))
-#define RGX_CR_CLK_CTRL_TSP_OFF                           (IMG_UINT64_C(0000000000000000))
-#define RGX_CR_CLK_CTRL_TSP_ON                            (IMG_UINT64_C(0x0000000000000004))
-#define RGX_CR_CLK_CTRL_TSP_AUTO                          (IMG_UINT64_C(0x0000000000000008))
-#define RGX_CR_CLK_CTRL_ISP_SHIFT                         (0U)
-#define RGX_CR_CLK_CTRL_ISP_CLRMSK                        (IMG_UINT64_C(0XFFFFFFFFFFFFFFFC))
-#define RGX_CR_CLK_CTRL_ISP_OFF                           (IMG_UINT64_C(0000000000000000))
-#define RGX_CR_CLK_CTRL_ISP_ON                            (IMG_UINT64_C(0x0000000000000001))
-#define RGX_CR_CLK_CTRL_ISP_AUTO                          (IMG_UINT64_C(0x0000000000000002))
-#endif /* !defined(RGX_FEATURE_PBE2_IN_XE) && !defined(RGX_FEATURE_S7_TOP_INFRASTRUCTURE) */
-
-
-#if defined(RGX_FEATURE_PBE2_IN_XE)
 /*
     Register RGX_CR_CLK_STATUS
 */
 #define RGX_CR_CLK_STATUS                                 (0x0008U)
+#define RGX_CR_CLK_STATUS__PBE2_XE__MASKFULL              (IMG_UINT64_C(0x00000001FFF077FF))
+#define RGX_CR_CLK_STATUS__S7_TOP__MASKFULL               (IMG_UINT64_C(0x00000001B3101773))
 #define RGX_CR_CLK_STATUS_MASKFULL                        (IMG_UINT64_C(0x00000001FFF077FF))
 #define RGX_CR_CLK_STATUS_MCU_FBTC_SHIFT                  (32U)
 #define RGX_CR_CLK_STATUS_MCU_FBTC_CLRMSK                 (IMG_UINT64_C(0XFFFFFFFEFFFFFFFF))
-#define RGX_CR_CLK_STATUS_MCU_FBTC_GATED                  (IMG_UINT64_C(0000000000000000))
-#define RGX_CR_CLK_STATUS_MCU_FBTC_RUNNING                (IMG_UINT64_C(0x0000000100000000))
-#if defined(RGX_FEATURE_CLUSTER_GROUPING)
+#define RGX_CR_CLK_STATUS_MCU_FBTC_GATED                  (IMG_UINT64_C(0000000000000000))  
+#define RGX_CR_CLK_STATUS_MCU_FBTC_RUNNING                (IMG_UINT64_C(0x0000000100000000))  
 #define RGX_CR_CLK_STATUS_BIF_TEXAS_SHIFT                 (31U)
 #define RGX_CR_CLK_STATUS_BIF_TEXAS_CLRMSK                (IMG_UINT64_C(0XFFFFFFFF7FFFFFFF))
-#define RGX_CR_CLK_STATUS_BIF_TEXAS_GATED                 (IMG_UINT64_C(0000000000000000))
-#define RGX_CR_CLK_STATUS_BIF_TEXAS_RUNNING               (IMG_UINT64_C(0x0000000080000000))
+#define RGX_CR_CLK_STATUS_BIF_TEXAS_GATED                 (IMG_UINT64_C(0000000000000000))  
+#define RGX_CR_CLK_STATUS_BIF_TEXAS_RUNNING               (IMG_UINT64_C(0x0000000080000000))  
 #define RGX_CR_CLK_STATUS_IPP_SHIFT                       (30U)
 #define RGX_CR_CLK_STATUS_IPP_CLRMSK                      (IMG_UINT64_C(0XFFFFFFFFBFFFFFFF))
-#define RGX_CR_CLK_STATUS_IPP_GATED                       (IMG_UINT64_C(0000000000000000))
-#define RGX_CR_CLK_STATUS_IPP_RUNNING                     (IMG_UINT64_C(0x0000000040000000))
-#endif /* RGX_FEATURE_CLUSTER_GROUPING */
-
+#define RGX_CR_CLK_STATUS_IPP_GATED                       (IMG_UINT64_C(0000000000000000))  
+#define RGX_CR_CLK_STATUS_IPP_RUNNING                     (IMG_UINT64_C(0x0000000040000000))  
 #define RGX_CR_CLK_STATUS_FBC_SHIFT                       (29U)
 #define RGX_CR_CLK_STATUS_FBC_CLRMSK                      (IMG_UINT64_C(0XFFFFFFFFDFFFFFFF))
-#define RGX_CR_CLK_STATUS_FBC_GATED                       (IMG_UINT64_C(0000000000000000))
-#define RGX_CR_CLK_STATUS_FBC_RUNNING                     (IMG_UINT64_C(0x0000000020000000))
+#define RGX_CR_CLK_STATUS_FBC_GATED                       (IMG_UINT64_C(0000000000000000))  
+#define RGX_CR_CLK_STATUS_FBC_RUNNING                     (IMG_UINT64_C(0x0000000020000000))  
 #define RGX_CR_CLK_STATUS_FBDC_SHIFT                      (28U)
 #define RGX_CR_CLK_STATUS_FBDC_CLRMSK                     (IMG_UINT64_C(0XFFFFFFFFEFFFFFFF))
-#define RGX_CR_CLK_STATUS_FBDC_GATED                      (IMG_UINT64_C(0000000000000000))
-#define RGX_CR_CLK_STATUS_FBDC_RUNNING                    (IMG_UINT64_C(0x0000000010000000))
+#define RGX_CR_CLK_STATUS_FBDC_GATED                      (IMG_UINT64_C(0000000000000000))  
+#define RGX_CR_CLK_STATUS_FBDC_RUNNING                    (IMG_UINT64_C(0x0000000010000000))  
 #define RGX_CR_CLK_STATUS_FB_TLCACHE_SHIFT                (27U)
 #define RGX_CR_CLK_STATUS_FB_TLCACHE_CLRMSK               (IMG_UINT64_C(0XFFFFFFFFF7FFFFFF))
-#define RGX_CR_CLK_STATUS_FB_TLCACHE_GATED                (IMG_UINT64_C(0000000000000000))
-#define RGX_CR_CLK_STATUS_FB_TLCACHE_RUNNING              (IMG_UINT64_C(0x0000000008000000))
+#define RGX_CR_CLK_STATUS_FB_TLCACHE_GATED                (IMG_UINT64_C(0000000000000000))  
+#define RGX_CR_CLK_STATUS_FB_TLCACHE_RUNNING              (IMG_UINT64_C(0x0000000008000000))  
 #define RGX_CR_CLK_STATUS_USCS_SHIFT                      (26U)
 #define RGX_CR_CLK_STATUS_USCS_CLRMSK                     (IMG_UINT64_C(0XFFFFFFFFFBFFFFFF))
-#define RGX_CR_CLK_STATUS_USCS_GATED                      (IMG_UINT64_C(0000000000000000))
-#define RGX_CR_CLK_STATUS_USCS_RUNNING                    (IMG_UINT64_C(0x0000000004000000))
+#define RGX_CR_CLK_STATUS_USCS_GATED                      (IMG_UINT64_C(0000000000000000))  
+#define RGX_CR_CLK_STATUS_USCS_RUNNING                    (IMG_UINT64_C(0x0000000004000000))  
 #define RGX_CR_CLK_STATUS_PBE_SHIFT                       (25U)
 #define RGX_CR_CLK_STATUS_PBE_CLRMSK                      (IMG_UINT64_C(0XFFFFFFFFFDFFFFFF))
-#define RGX_CR_CLK_STATUS_PBE_GATED                       (IMG_UINT64_C(0000000000000000))
-#define RGX_CR_CLK_STATUS_PBE_RUNNING                     (IMG_UINT64_C(0x0000000002000000))
+#define RGX_CR_CLK_STATUS_PBE_GATED                       (IMG_UINT64_C(0000000000000000))  
+#define RGX_CR_CLK_STATUS_PBE_RUNNING                     (IMG_UINT64_C(0x0000000002000000))  
 #define RGX_CR_CLK_STATUS_MCU_L1_SHIFT                    (24U)
 #define RGX_CR_CLK_STATUS_MCU_L1_CLRMSK                   (IMG_UINT64_C(0XFFFFFFFFFEFFFFFF))
-#define RGX_CR_CLK_STATUS_MCU_L1_GATED                    (IMG_UINT64_C(0000000000000000))
-#define RGX_CR_CLK_STATUS_MCU_L1_RUNNING                  (IMG_UINT64_C(0x0000000001000000))
-#if defined(RGX_FEATURE_COMPUTE)
+#define RGX_CR_CLK_STATUS_MCU_L1_GATED                    (IMG_UINT64_C(0000000000000000))  
+#define RGX_CR_CLK_STATUS_MCU_L1_RUNNING                  (IMG_UINT64_C(0x0000000001000000))  
 #define RGX_CR_CLK_STATUS_CDM_SHIFT                       (23U)
 #define RGX_CR_CLK_STATUS_CDM_CLRMSK                      (IMG_UINT64_C(0XFFFFFFFFFF7FFFFF))
-#define RGX_CR_CLK_STATUS_CDM_GATED                       (IMG_UINT64_C(0000000000000000))
-#define RGX_CR_CLK_STATUS_CDM_RUNNING                     (IMG_UINT64_C(0x0000000000800000))
-#endif /* RGX_FEATURE_COMPUTE */
-
+#define RGX_CR_CLK_STATUS_CDM_GATED                       (IMG_UINT64_C(0000000000000000))  
+#define RGX_CR_CLK_STATUS_CDM_RUNNING                     (IMG_UINT64_C(0x0000000000800000))  
 #define RGX_CR_CLK_STATUS_SIDEKICK_SHIFT                  (22U)
 #define RGX_CR_CLK_STATUS_SIDEKICK_CLRMSK                 (IMG_UINT64_C(0XFFFFFFFFFFBFFFFF))
-#define RGX_CR_CLK_STATUS_SIDEKICK_GATED                  (IMG_UINT64_C(0000000000000000))
-#define RGX_CR_CLK_STATUS_SIDEKICK_RUNNING                (IMG_UINT64_C(0x0000000000400000))
+#define RGX_CR_CLK_STATUS_SIDEKICK_GATED                  (IMG_UINT64_C(0000000000000000))  
+#define RGX_CR_CLK_STATUS_SIDEKICK_RUNNING                (IMG_UINT64_C(0x0000000000400000))  
 #define RGX_CR_CLK_STATUS_BIF_SIDEKICK_SHIFT              (21U)
 #define RGX_CR_CLK_STATUS_BIF_SIDEKICK_CLRMSK             (IMG_UINT64_C(0XFFFFFFFFFFDFFFFF))
-#define RGX_CR_CLK_STATUS_BIF_SIDEKICK_GATED              (IMG_UINT64_C(0000000000000000))
-#define RGX_CR_CLK_STATUS_BIF_SIDEKICK_RUNNING            (IMG_UINT64_C(0x0000000000200000))
+#define RGX_CR_CLK_STATUS_BIF_SIDEKICK_GATED              (IMG_UINT64_C(0000000000000000))  
+#define RGX_CR_CLK_STATUS_BIF_SIDEKICK_RUNNING            (IMG_UINT64_C(0x0000000000200000))  
 #define RGX_CR_CLK_STATUS_BIF_SHIFT                       (20U)
 #define RGX_CR_CLK_STATUS_BIF_CLRMSK                      (IMG_UINT64_C(0XFFFFFFFFFFEFFFFF))
-#define RGX_CR_CLK_STATUS_BIF_GATED                       (IMG_UINT64_C(0000000000000000))
-#define RGX_CR_CLK_STATUS_BIF_RUNNING                     (IMG_UINT64_C(0x0000000000100000))
+#define RGX_CR_CLK_STATUS_BIF_GATED                       (IMG_UINT64_C(0000000000000000))  
+#define RGX_CR_CLK_STATUS_BIF_RUNNING                     (IMG_UINT64_C(0x0000000000100000))  
 #define RGX_CR_CLK_STATUS_TPU_MCU_DEMUX_SHIFT             (14U)
 #define RGX_CR_CLK_STATUS_TPU_MCU_DEMUX_CLRMSK            (IMG_UINT64_C(0XFFFFFFFFFFFFBFFF))
-#define RGX_CR_CLK_STATUS_TPU_MCU_DEMUX_GATED             (IMG_UINT64_C(0000000000000000))
-#define RGX_CR_CLK_STATUS_TPU_MCU_DEMUX_RUNNING           (IMG_UINT64_C(0x0000000000004000))
+#define RGX_CR_CLK_STATUS_TPU_MCU_DEMUX_GATED             (IMG_UINT64_C(0000000000000000))  
+#define RGX_CR_CLK_STATUS_TPU_MCU_DEMUX_RUNNING           (IMG_UINT64_C(0x0000000000004000))  
 #define RGX_CR_CLK_STATUS_MCU_L0_SHIFT                    (13U)
 #define RGX_CR_CLK_STATUS_MCU_L0_CLRMSK                   (IMG_UINT64_C(0XFFFFFFFFFFFFDFFF))
-#define RGX_CR_CLK_STATUS_MCU_L0_GATED                    (IMG_UINT64_C(0000000000000000))
-#define RGX_CR_CLK_STATUS_MCU_L0_RUNNING                  (IMG_UINT64_C(0x0000000000002000))
+#define RGX_CR_CLK_STATUS_MCU_L0_GATED                    (IMG_UINT64_C(0000000000000000))  
+#define RGX_CR_CLK_STATUS_MCU_L0_RUNNING                  (IMG_UINT64_C(0x0000000000002000))  
 #define RGX_CR_CLK_STATUS_TPU_SHIFT                       (12U)
 #define RGX_CR_CLK_STATUS_TPU_CLRMSK                      (IMG_UINT64_C(0XFFFFFFFFFFFFEFFF))
-#define RGX_CR_CLK_STATUS_TPU_GATED                       (IMG_UINT64_C(0000000000000000))
-#define RGX_CR_CLK_STATUS_TPU_RUNNING                     (IMG_UINT64_C(0x0000000000001000))
+#define RGX_CR_CLK_STATUS_TPU_GATED                       (IMG_UINT64_C(0000000000000000))  
+#define RGX_CR_CLK_STATUS_TPU_RUNNING                     (IMG_UINT64_C(0x0000000000001000))  
 #define RGX_CR_CLK_STATUS_USC_SHIFT                       (10U)
 #define RGX_CR_CLK_STATUS_USC_CLRMSK                      (IMG_UINT64_C(0XFFFFFFFFFFFFFBFF))
-#define RGX_CR_CLK_STATUS_USC_GATED                       (IMG_UINT64_C(0000000000000000))
-#define RGX_CR_CLK_STATUS_USC_RUNNING                     (IMG_UINT64_C(0x0000000000000400))
+#define RGX_CR_CLK_STATUS_USC_GATED                       (IMG_UINT64_C(0000000000000000))  
+#define RGX_CR_CLK_STATUS_USC_RUNNING                     (IMG_UINT64_C(0x0000000000000400))  
 #define RGX_CR_CLK_STATUS_TLA_SHIFT                       (9U)
 #define RGX_CR_CLK_STATUS_TLA_CLRMSK                      (IMG_UINT64_C(0XFFFFFFFFFFFFFDFF))
-#define RGX_CR_CLK_STATUS_TLA_GATED                       (IMG_UINT64_C(0000000000000000))
-#define RGX_CR_CLK_STATUS_TLA_RUNNING                     (IMG_UINT64_C(0x0000000000000200))
+#define RGX_CR_CLK_STATUS_TLA_GATED                       (IMG_UINT64_C(0000000000000000))  
+#define RGX_CR_CLK_STATUS_TLA_RUNNING                     (IMG_UINT64_C(0x0000000000000200))  
 #define RGX_CR_CLK_STATUS_SLC_SHIFT                       (8U)
 #define RGX_CR_CLK_STATUS_SLC_CLRMSK                      (IMG_UINT64_C(0XFFFFFFFFFFFFFEFF))
-#define RGX_CR_CLK_STATUS_SLC_GATED                       (IMG_UINT64_C(0000000000000000))
-#define RGX_CR_CLK_STATUS_SLC_RUNNING                     (IMG_UINT64_C(0x0000000000000100))
+#define RGX_CR_CLK_STATUS_SLC_GATED                       (IMG_UINT64_C(0000000000000000))  
+#define RGX_CR_CLK_STATUS_SLC_RUNNING                     (IMG_UINT64_C(0x0000000000000100))  
 #define RGX_CR_CLK_STATUS_UVS_SHIFT                       (7U)
 #define RGX_CR_CLK_STATUS_UVS_CLRMSK                      (IMG_UINT64_C(0XFFFFFFFFFFFFFF7F))
-#define RGX_CR_CLK_STATUS_UVS_GATED                       (IMG_UINT64_C(0000000000000000))
-#define RGX_CR_CLK_STATUS_UVS_RUNNING                     (IMG_UINT64_C(0x0000000000000080))
+#define RGX_CR_CLK_STATUS_UVS_GATED                       (IMG_UINT64_C(0000000000000000))  
+#define RGX_CR_CLK_STATUS_UVS_RUNNING                     (IMG_UINT64_C(0x0000000000000080))  
 #define RGX_CR_CLK_STATUS_PDS_SHIFT                       (6U)
 #define RGX_CR_CLK_STATUS_PDS_CLRMSK                      (IMG_UINT64_C(0XFFFFFFFFFFFFFFBF))
-#define RGX_CR_CLK_STATUS_PDS_GATED                       (IMG_UINT64_C(0000000000000000))
-#define RGX_CR_CLK_STATUS_PDS_RUNNING                     (IMG_UINT64_C(0x0000000000000040))
+#define RGX_CR_CLK_STATUS_PDS_GATED                       (IMG_UINT64_C(0000000000000000))  
+#define RGX_CR_CLK_STATUS_PDS_RUNNING                     (IMG_UINT64_C(0x0000000000000040))  
 #define RGX_CR_CLK_STATUS_VDM_SHIFT                       (5U)
 #define RGX_CR_CLK_STATUS_VDM_CLRMSK                      (IMG_UINT64_C(0XFFFFFFFFFFFFFFDF))
-#define RGX_CR_CLK_STATUS_VDM_GATED                       (IMG_UINT64_C(0000000000000000))
-#define RGX_CR_CLK_STATUS_VDM_RUNNING                     (IMG_UINT64_C(0x0000000000000020))
+#define RGX_CR_CLK_STATUS_VDM_GATED                       (IMG_UINT64_C(0000000000000000))  
+#define RGX_CR_CLK_STATUS_VDM_RUNNING                     (IMG_UINT64_C(0x0000000000000020))  
 #define RGX_CR_CLK_STATUS_PM_SHIFT                        (4U)
 #define RGX_CR_CLK_STATUS_PM_CLRMSK                       (IMG_UINT64_C(0XFFFFFFFFFFFFFFEF))
-#define RGX_CR_CLK_STATUS_PM_GATED                        (IMG_UINT64_C(0000000000000000))
-#define RGX_CR_CLK_STATUS_PM_RUNNING                      (IMG_UINT64_C(0x0000000000000010))
+#define RGX_CR_CLK_STATUS_PM_GATED                        (IMG_UINT64_C(0000000000000000))  
+#define RGX_CR_CLK_STATUS_PM_RUNNING                      (IMG_UINT64_C(0x0000000000000010))  
 #define RGX_CR_CLK_STATUS_GPP_SHIFT                       (3U)
 #define RGX_CR_CLK_STATUS_GPP_CLRMSK                      (IMG_UINT64_C(0XFFFFFFFFFFFFFFF7))
-#define RGX_CR_CLK_STATUS_GPP_GATED                       (IMG_UINT64_C(0000000000000000))
-#define RGX_CR_CLK_STATUS_GPP_RUNNING                     (IMG_UINT64_C(0x0000000000000008))
+#define RGX_CR_CLK_STATUS_GPP_GATED                       (IMG_UINT64_C(0000000000000000))  
+#define RGX_CR_CLK_STATUS_GPP_RUNNING                     (IMG_UINT64_C(0x0000000000000008))  
 #define RGX_CR_CLK_STATUS_TE_SHIFT                        (2U)
 #define RGX_CR_CLK_STATUS_TE_CLRMSK                       (IMG_UINT64_C(0XFFFFFFFFFFFFFFFB))
-#define RGX_CR_CLK_STATUS_TE_GATED                        (IMG_UINT64_C(0000000000000000))
-#define RGX_CR_CLK_STATUS_TE_RUNNING                      (IMG_UINT64_C(0x0000000000000004))
+#define RGX_CR_CLK_STATUS_TE_GATED                        (IMG_UINT64_C(0000000000000000))  
+#define RGX_CR_CLK_STATUS_TE_RUNNING                      (IMG_UINT64_C(0x0000000000000004))  
 #define RGX_CR_CLK_STATUS_TSP_SHIFT                       (1U)
 #define RGX_CR_CLK_STATUS_TSP_CLRMSK                      (IMG_UINT64_C(0XFFFFFFFFFFFFFFFD))
-#define RGX_CR_CLK_STATUS_TSP_GATED                       (IMG_UINT64_C(0000000000000000))
-#define RGX_CR_CLK_STATUS_TSP_RUNNING                     (IMG_UINT64_C(0x0000000000000002))
+#define RGX_CR_CLK_STATUS_TSP_GATED                       (IMG_UINT64_C(0000000000000000))  
+#define RGX_CR_CLK_STATUS_TSP_RUNNING                     (IMG_UINT64_C(0x0000000000000002))  
 #define RGX_CR_CLK_STATUS_ISP_SHIFT                       (0U)
 #define RGX_CR_CLK_STATUS_ISP_CLRMSK                      (IMG_UINT64_C(0XFFFFFFFFFFFFFFFE))
-#define RGX_CR_CLK_STATUS_ISP_GATED                       (IMG_UINT64_C(0000000000000000))
-#define RGX_CR_CLK_STATUS_ISP_RUNNING                     (IMG_UINT64_C(0x0000000000000001))
-#endif /* RGX_FEATURE_PBE2_IN_XE */ 
+#define RGX_CR_CLK_STATUS_ISP_GATED                       (IMG_UINT64_C(0000000000000000))  
+#define RGX_CR_CLK_STATUS_ISP_RUNNING                     (IMG_UINT64_C(0x0000000000000001))  
 
 
-#if defined(RGX_FEATURE_S7_TOP_INFRASTRUCTURE)
 /*
-    Register RGX_CR_CLK_STATUS
+    Register RGX_CR_CORE_ID
 */
-#define RGX_CR_CLK_STATUS                                 (0x0008U)
-#define RGX_CR_CLK_STATUS_MASKFULL                        (IMG_UINT64_C(0x00000001B3101773))
-#define RGX_CR_CLK_STATUS_MCU_FBTC_SHIFT                  (32U)
-#define RGX_CR_CLK_STATUS_MCU_FBTC_CLRMSK                 (IMG_UINT64_C(0XFFFFFFFEFFFFFFFF))
-#define RGX_CR_CLK_STATUS_MCU_FBTC_GATED                  (IMG_UINT64_C(0000000000000000))
-#define RGX_CR_CLK_STATUS_MCU_FBTC_RUNNING                (IMG_UINT64_C(0x0000000100000000))
-#if defined(RGX_FEATURE_CLUSTER_GROUPING)
-#define RGX_CR_CLK_STATUS_BIF_TEXAS_SHIFT                 (31U)
-#define RGX_CR_CLK_STATUS_BIF_TEXAS_CLRMSK                (IMG_UINT64_C(0XFFFFFFFF7FFFFFFF))
-#define RGX_CR_CLK_STATUS_BIF_TEXAS_GATED                 (IMG_UINT64_C(0000000000000000))
-#define RGX_CR_CLK_STATUS_BIF_TEXAS_RUNNING               (IMG_UINT64_C(0x0000000080000000))
-#endif /* RGX_FEATURE_CLUSTER_GROUPING */
-
-#define RGX_CR_CLK_STATUS_FBC_SHIFT                       (29U)
-#define RGX_CR_CLK_STATUS_FBC_CLRMSK                      (IMG_UINT64_C(0XFFFFFFFFDFFFFFFF))
-#define RGX_CR_CLK_STATUS_FBC_GATED                       (IMG_UINT64_C(0000000000000000))
-#define RGX_CR_CLK_STATUS_FBC_RUNNING                     (IMG_UINT64_C(0x0000000020000000))
-#define RGX_CR_CLK_STATUS_FBDC_SHIFT                      (28U)
-#define RGX_CR_CLK_STATUS_FBDC_CLRMSK                     (IMG_UINT64_C(0XFFFFFFFFEFFFFFFF))
-#define RGX_CR_CLK_STATUS_FBDC_GATED                      (IMG_UINT64_C(0000000000000000))
-#define RGX_CR_CLK_STATUS_FBDC_RUNNING                    (IMG_UINT64_C(0x0000000010000000))
-#define RGX_CR_CLK_STATUS_PBE_SHIFT                       (25U)
-#define RGX_CR_CLK_STATUS_PBE_CLRMSK                      (IMG_UINT64_C(0XFFFFFFFFFDFFFFFF))
-#define RGX_CR_CLK_STATUS_PBE_GATED                       (IMG_UINT64_C(0000000000000000))
-#define RGX_CR_CLK_STATUS_PBE_RUNNING                     (IMG_UINT64_C(0x0000000002000000))
-#define RGX_CR_CLK_STATUS_MCU_L1_SHIFT                    (24U)
-#define RGX_CR_CLK_STATUS_MCU_L1_CLRMSK                   (IMG_UINT64_C(0XFFFFFFFFFEFFFFFF))
-#define RGX_CR_CLK_STATUS_MCU_L1_GATED                    (IMG_UINT64_C(0000000000000000))
-#define RGX_CR_CLK_STATUS_MCU_L1_RUNNING                  (IMG_UINT64_C(0x0000000001000000))
-#define RGX_CR_CLK_STATUS_BIF_SHIFT                       (20U)
-#define RGX_CR_CLK_STATUS_BIF_CLRMSK                      (IMG_UINT64_C(0XFFFFFFFFFFEFFFFF))
-#define RGX_CR_CLK_STATUS_BIF_GATED                       (IMG_UINT64_C(0000000000000000))
-#define RGX_CR_CLK_STATUS_BIF_RUNNING                     (IMG_UINT64_C(0x0000000000100000))
-#define RGX_CR_CLK_STATUS_TPU_SHIFT                       (12U)
-#define RGX_CR_CLK_STATUS_TPU_CLRMSK                      (IMG_UINT64_C(0XFFFFFFFFFFFFEFFF))
-#define RGX_CR_CLK_STATUS_TPU_GATED                       (IMG_UINT64_C(0000000000000000))
-#define RGX_CR_CLK_STATUS_TPU_RUNNING                     (IMG_UINT64_C(0x0000000000001000))
-#define RGX_CR_CLK_STATUS_USC_SHIFT                       (10U)
-#define RGX_CR_CLK_STATUS_USC_CLRMSK                      (IMG_UINT64_C(0XFFFFFFFFFFFFFBFF))
-#define RGX_CR_CLK_STATUS_USC_GATED                       (IMG_UINT64_C(0000000000000000))
-#define RGX_CR_CLK_STATUS_USC_RUNNING                     (IMG_UINT64_C(0x0000000000000400))
-#define RGX_CR_CLK_STATUS_TLA_SHIFT                       (9U)
-#define RGX_CR_CLK_STATUS_TLA_CLRMSK                      (IMG_UINT64_C(0XFFFFFFFFFFFFFDFF))
-#define RGX_CR_CLK_STATUS_TLA_GATED                       (IMG_UINT64_C(0000000000000000))
-#define RGX_CR_CLK_STATUS_TLA_RUNNING                     (IMG_UINT64_C(0x0000000000000200))
-#define RGX_CR_CLK_STATUS_SLC_SHIFT                       (8U)
-#define RGX_CR_CLK_STATUS_SLC_CLRMSK                      (IMG_UINT64_C(0XFFFFFFFFFFFFFEFF))
-#define RGX_CR_CLK_STATUS_SLC_GATED                       (IMG_UINT64_C(0000000000000000))
-#define RGX_CR_CLK_STATUS_SLC_RUNNING                     (IMG_UINT64_C(0x0000000000000100))
-#define RGX_CR_CLK_STATUS_PDS_SHIFT                       (6U)
-#define RGX_CR_CLK_STATUS_PDS_CLRMSK                      (IMG_UINT64_C(0XFFFFFFFFFFFFFFBF))
-#define RGX_CR_CLK_STATUS_PDS_GATED                       (IMG_UINT64_C(0000000000000000))
-#define RGX_CR_CLK_STATUS_PDS_RUNNING                     (IMG_UINT64_C(0x0000000000000040))
-#define RGX_CR_CLK_STATUS_VDM_SHIFT                       (5U)
-#define RGX_CR_CLK_STATUS_VDM_CLRMSK                      (IMG_UINT64_C(0XFFFFFFFFFFFFFFDF))
-#define RGX_CR_CLK_STATUS_VDM_GATED                       (IMG_UINT64_C(0000000000000000))
-#define RGX_CR_CLK_STATUS_VDM_RUNNING                     (IMG_UINT64_C(0x0000000000000020))
-#define RGX_CR_CLK_STATUS_PM_SHIFT                        (4U)
-#define RGX_CR_CLK_STATUS_PM_CLRMSK                       (IMG_UINT64_C(0XFFFFFFFFFFFFFFEF))
-#define RGX_CR_CLK_STATUS_PM_GATED                        (IMG_UINT64_C(0000000000000000))
-#define RGX_CR_CLK_STATUS_PM_RUNNING                      (IMG_UINT64_C(0x0000000000000010))
-#define RGX_CR_CLK_STATUS_TSP_SHIFT                       (1U)
-#define RGX_CR_CLK_STATUS_TSP_CLRMSK                      (IMG_UINT64_C(0XFFFFFFFFFFFFFFFD))
-#define RGX_CR_CLK_STATUS_TSP_GATED                       (IMG_UINT64_C(0000000000000000))
-#define RGX_CR_CLK_STATUS_TSP_RUNNING                     (IMG_UINT64_C(0x0000000000000002))
-#define RGX_CR_CLK_STATUS_ISP_SHIFT                       (0U)
-#define RGX_CR_CLK_STATUS_ISP_CLRMSK                      (IMG_UINT64_C(0XFFFFFFFFFFFFFFFE))
-#define RGX_CR_CLK_STATUS_ISP_GATED                       (IMG_UINT64_C(0000000000000000))
-#define RGX_CR_CLK_STATUS_ISP_RUNNING                     (IMG_UINT64_C(0x0000000000000001))
-#endif /* RGX_FEATURE_S7_TOP_INFRASTRUCTURE */ 
-
-
-#if !defined(RGX_FEATURE_PBE2_IN_XE) && !defined(RGX_FEATURE_S7_TOP_INFRASTRUCTURE)
-/*
-    Register RGX_CR_CLK_STATUS
-*/
-#define RGX_CR_CLK_STATUS                                 (0x0008U)
-#define RGX_CR_CLK_STATUS_MASKFULL                        (IMG_UINT64_C(0x00000001FFF077FF))
-#define RGX_CR_CLK_STATUS_MCU_FBTC_SHIFT                  (32U)
-#define RGX_CR_CLK_STATUS_MCU_FBTC_CLRMSK                 (IMG_UINT64_C(0XFFFFFFFEFFFFFFFF))
-#define RGX_CR_CLK_STATUS_MCU_FBTC_GATED                  (IMG_UINT64_C(0000000000000000))
-#define RGX_CR_CLK_STATUS_MCU_FBTC_RUNNING                (IMG_UINT64_C(0x0000000100000000))
-#if defined(RGX_FEATURE_CLUSTER_GROUPING)
-#define RGX_CR_CLK_STATUS_BIF_TEXAS_SHIFT                 (31U)
-#define RGX_CR_CLK_STATUS_BIF_TEXAS_CLRMSK                (IMG_UINT64_C(0XFFFFFFFF7FFFFFFF))
-#define RGX_CR_CLK_STATUS_BIF_TEXAS_GATED                 (IMG_UINT64_C(0000000000000000))
-#define RGX_CR_CLK_STATUS_BIF_TEXAS_RUNNING               (IMG_UINT64_C(0x0000000080000000))
-#define RGX_CR_CLK_STATUS_IPP_SHIFT                       (30U)
-#define RGX_CR_CLK_STATUS_IPP_CLRMSK                      (IMG_UINT64_C(0XFFFFFFFFBFFFFFFF))
-#define RGX_CR_CLK_STATUS_IPP_GATED                       (IMG_UINT64_C(0000000000000000))
-#define RGX_CR_CLK_STATUS_IPP_RUNNING                     (IMG_UINT64_C(0x0000000040000000))
-#endif /* RGX_FEATURE_CLUSTER_GROUPING */
-
-#define RGX_CR_CLK_STATUS_FBC_SHIFT                       (29U)
-#define RGX_CR_CLK_STATUS_FBC_CLRMSK                      (IMG_UINT64_C(0XFFFFFFFFDFFFFFFF))
-#define RGX_CR_CLK_STATUS_FBC_GATED                       (IMG_UINT64_C(0000000000000000))
-#define RGX_CR_CLK_STATUS_FBC_RUNNING                     (IMG_UINT64_C(0x0000000020000000))
-#define RGX_CR_CLK_STATUS_FBDC_SHIFT                      (28U)
-#define RGX_CR_CLK_STATUS_FBDC_CLRMSK                     (IMG_UINT64_C(0XFFFFFFFFEFFFFFFF))
-#define RGX_CR_CLK_STATUS_FBDC_GATED                      (IMG_UINT64_C(0000000000000000))
-#define RGX_CR_CLK_STATUS_FBDC_RUNNING                    (IMG_UINT64_C(0x0000000010000000))
-#define RGX_CR_CLK_STATUS_FB_TLCACHE_SHIFT                (27U)
-#define RGX_CR_CLK_STATUS_FB_TLCACHE_CLRMSK               (IMG_UINT64_C(0XFFFFFFFFF7FFFFFF))
-#define RGX_CR_CLK_STATUS_FB_TLCACHE_GATED                (IMG_UINT64_C(0000000000000000))
-#define RGX_CR_CLK_STATUS_FB_TLCACHE_RUNNING              (IMG_UINT64_C(0x0000000008000000))
-#define RGX_CR_CLK_STATUS_USCS_SHIFT                      (26U)
-#define RGX_CR_CLK_STATUS_USCS_CLRMSK                     (IMG_UINT64_C(0XFFFFFFFFFBFFFFFF))
-#define RGX_CR_CLK_STATUS_USCS_GATED                      (IMG_UINT64_C(0000000000000000))
-#define RGX_CR_CLK_STATUS_USCS_RUNNING                    (IMG_UINT64_C(0x0000000004000000))
-#define RGX_CR_CLK_STATUS_PBE_SHIFT                       (25U)
-#define RGX_CR_CLK_STATUS_PBE_CLRMSK                      (IMG_UINT64_C(0XFFFFFFFFFDFFFFFF))
-#define RGX_CR_CLK_STATUS_PBE_GATED                       (IMG_UINT64_C(0000000000000000))
-#define RGX_CR_CLK_STATUS_PBE_RUNNING                     (IMG_UINT64_C(0x0000000002000000))
-#define RGX_CR_CLK_STATUS_MCU_L1_SHIFT                    (24U)
-#define RGX_CR_CLK_STATUS_MCU_L1_CLRMSK                   (IMG_UINT64_C(0XFFFFFFFFFEFFFFFF))
-#define RGX_CR_CLK_STATUS_MCU_L1_GATED                    (IMG_UINT64_C(0000000000000000))
-#define RGX_CR_CLK_STATUS_MCU_L1_RUNNING                  (IMG_UINT64_C(0x0000000001000000))
-#if defined(RGX_FEATURE_COMPUTE)
-#define RGX_CR_CLK_STATUS_CDM_SHIFT                       (23U)
-#define RGX_CR_CLK_STATUS_CDM_CLRMSK                      (IMG_UINT64_C(0XFFFFFFFFFF7FFFFF))
-#define RGX_CR_CLK_STATUS_CDM_GATED                       (IMG_UINT64_C(0000000000000000))
-#define RGX_CR_CLK_STATUS_CDM_RUNNING                     (IMG_UINT64_C(0x0000000000800000))
-#endif /* RGX_FEATURE_COMPUTE */
-
-#define RGX_CR_CLK_STATUS_SIDEKICK_SHIFT                  (22U)
-#define RGX_CR_CLK_STATUS_SIDEKICK_CLRMSK                 (IMG_UINT64_C(0XFFFFFFFFFFBFFFFF))
-#define RGX_CR_CLK_STATUS_SIDEKICK_GATED                  (IMG_UINT64_C(0000000000000000))
-#define RGX_CR_CLK_STATUS_SIDEKICK_RUNNING                (IMG_UINT64_C(0x0000000000400000))
-#define RGX_CR_CLK_STATUS_BIF_SIDEKICK_SHIFT              (21U)
-#define RGX_CR_CLK_STATUS_BIF_SIDEKICK_CLRMSK             (IMG_UINT64_C(0XFFFFFFFFFFDFFFFF))
-#define RGX_CR_CLK_STATUS_BIF_SIDEKICK_GATED              (IMG_UINT64_C(0000000000000000))
-#define RGX_CR_CLK_STATUS_BIF_SIDEKICK_RUNNING            (IMG_UINT64_C(0x0000000000200000))
-#define RGX_CR_CLK_STATUS_BIF_SHIFT                       (20U)
-#define RGX_CR_CLK_STATUS_BIF_CLRMSK                      (IMG_UINT64_C(0XFFFFFFFFFFEFFFFF))
-#define RGX_CR_CLK_STATUS_BIF_GATED                       (IMG_UINT64_C(0000000000000000))
-#define RGX_CR_CLK_STATUS_BIF_RUNNING                     (IMG_UINT64_C(0x0000000000100000))
-#define RGX_CR_CLK_STATUS_TPU_MCU_DEMUX_SHIFT             (14U)
-#define RGX_CR_CLK_STATUS_TPU_MCU_DEMUX_CLRMSK            (IMG_UINT64_C(0XFFFFFFFFFFFFBFFF))
-#define RGX_CR_CLK_STATUS_TPU_MCU_DEMUX_GATED             (IMG_UINT64_C(0000000000000000))
-#define RGX_CR_CLK_STATUS_TPU_MCU_DEMUX_RUNNING           (IMG_UINT64_C(0x0000000000004000))
-#define RGX_CR_CLK_STATUS_MCU_L0_SHIFT                    (13U)
-#define RGX_CR_CLK_STATUS_MCU_L0_CLRMSK                   (IMG_UINT64_C(0XFFFFFFFFFFFFDFFF))
-#define RGX_CR_CLK_STATUS_MCU_L0_GATED                    (IMG_UINT64_C(0000000000000000))
-#define RGX_CR_CLK_STATUS_MCU_L0_RUNNING                  (IMG_UINT64_C(0x0000000000002000))
-#define RGX_CR_CLK_STATUS_TPU_SHIFT                       (12U)
-#define RGX_CR_CLK_STATUS_TPU_CLRMSK                      (IMG_UINT64_C(0XFFFFFFFFFFFFEFFF))
-#define RGX_CR_CLK_STATUS_TPU_GATED                       (IMG_UINT64_C(0000000000000000))
-#define RGX_CR_CLK_STATUS_TPU_RUNNING                     (IMG_UINT64_C(0x0000000000001000))
-#define RGX_CR_CLK_STATUS_USC_SHIFT                       (10U)
-#define RGX_CR_CLK_STATUS_USC_CLRMSK                      (IMG_UINT64_C(0XFFFFFFFFFFFFFBFF))
-#define RGX_CR_CLK_STATUS_USC_GATED                       (IMG_UINT64_C(0000000000000000))
-#define RGX_CR_CLK_STATUS_USC_RUNNING                     (IMG_UINT64_C(0x0000000000000400))
-#define RGX_CR_CLK_STATUS_TLA_SHIFT                       (9U)
-#define RGX_CR_CLK_STATUS_TLA_CLRMSK                      (IMG_UINT64_C(0XFFFFFFFFFFFFFDFF))
-#define RGX_CR_CLK_STATUS_TLA_GATED                       (IMG_UINT64_C(0000000000000000))
-#define RGX_CR_CLK_STATUS_TLA_RUNNING                     (IMG_UINT64_C(0x0000000000000200))
-#define RGX_CR_CLK_STATUS_SLC_SHIFT                       (8U)
-#define RGX_CR_CLK_STATUS_SLC_CLRMSK                      (IMG_UINT64_C(0XFFFFFFFFFFFFFEFF))
-#define RGX_CR_CLK_STATUS_SLC_GATED                       (IMG_UINT64_C(0000000000000000))
-#define RGX_CR_CLK_STATUS_SLC_RUNNING                     (IMG_UINT64_C(0x0000000000000100))
-#define RGX_CR_CLK_STATUS_UVS_SHIFT                       (7U)
-#define RGX_CR_CLK_STATUS_UVS_CLRMSK                      (IMG_UINT64_C(0XFFFFFFFFFFFFFF7F))
-#define RGX_CR_CLK_STATUS_UVS_GATED                       (IMG_UINT64_C(0000000000000000))
-#define RGX_CR_CLK_STATUS_UVS_RUNNING                     (IMG_UINT64_C(0x0000000000000080))
-#define RGX_CR_CLK_STATUS_PDS_SHIFT                       (6U)
-#define RGX_CR_CLK_STATUS_PDS_CLRMSK                      (IMG_UINT64_C(0XFFFFFFFFFFFFFFBF))
-#define RGX_CR_CLK_STATUS_PDS_GATED                       (IMG_UINT64_C(0000000000000000))
-#define RGX_CR_CLK_STATUS_PDS_RUNNING                     (IMG_UINT64_C(0x0000000000000040))
-#define RGX_CR_CLK_STATUS_VDM_SHIFT                       (5U)
-#define RGX_CR_CLK_STATUS_VDM_CLRMSK                      (IMG_UINT64_C(0XFFFFFFFFFFFFFFDF))
-#define RGX_CR_CLK_STATUS_VDM_GATED                       (IMG_UINT64_C(0000000000000000))
-#define RGX_CR_CLK_STATUS_VDM_RUNNING                     (IMG_UINT64_C(0x0000000000000020))
-#define RGX_CR_CLK_STATUS_PM_SHIFT                        (4U)
-#define RGX_CR_CLK_STATUS_PM_CLRMSK                       (IMG_UINT64_C(0XFFFFFFFFFFFFFFEF))
-#define RGX_CR_CLK_STATUS_PM_GATED                        (IMG_UINT64_C(0000000000000000))
-#define RGX_CR_CLK_STATUS_PM_RUNNING                      (IMG_UINT64_C(0x0000000000000010))
-#define RGX_CR_CLK_STATUS_GPP_SHIFT                       (3U)
-#define RGX_CR_CLK_STATUS_GPP_CLRMSK                      (IMG_UINT64_C(0XFFFFFFFFFFFFFFF7))
-#define RGX_CR_CLK_STATUS_GPP_GATED                       (IMG_UINT64_C(0000000000000000))
-#define RGX_CR_CLK_STATUS_GPP_RUNNING                     (IMG_UINT64_C(0x0000000000000008))
-#define RGX_CR_CLK_STATUS_TE_SHIFT                        (2U)
-#define RGX_CR_CLK_STATUS_TE_CLRMSK                       (IMG_UINT64_C(0XFFFFFFFFFFFFFFFB))
-#define RGX_CR_CLK_STATUS_TE_GATED                        (IMG_UINT64_C(0000000000000000))
-#define RGX_CR_CLK_STATUS_TE_RUNNING                      (IMG_UINT64_C(0x0000000000000004))
-#define RGX_CR_CLK_STATUS_TSP_SHIFT                       (1U)
-#define RGX_CR_CLK_STATUS_TSP_CLRMSK                      (IMG_UINT64_C(0XFFFFFFFFFFFFFFFD))
-#define RGX_CR_CLK_STATUS_TSP_GATED                       (IMG_UINT64_C(0000000000000000))
-#define RGX_CR_CLK_STATUS_TSP_RUNNING                     (IMG_UINT64_C(0x0000000000000002))
-#define RGX_CR_CLK_STATUS_ISP_SHIFT                       (0U)
-#define RGX_CR_CLK_STATUS_ISP_CLRMSK                      (IMG_UINT64_C(0XFFFFFFFFFFFFFFFE))
-#define RGX_CR_CLK_STATUS_ISP_GATED                       (IMG_UINT64_C(0000000000000000))
-#define RGX_CR_CLK_STATUS_ISP_RUNNING                     (IMG_UINT64_C(0x0000000000000001))
-#endif /* !defined(RGX_FEATURE_PBE2_IN_XE) && !defined(RGX_FEATURE_S7_TOP_INFRASTRUCTURE) */
+#define RGX_CR_CORE_ID__PBVNC                             (0x0020U)
+#define RGX_CR_CORE_ID__PBVNC__MASKFULL                   (IMG_UINT64_C(0xFFFFFFFFFFFFFFFF))
+#define RGX_CR_CORE_ID__PBVNC__BRANCH_ID_SHIFT            (48U)
+#define RGX_CR_CORE_ID__PBVNC__BRANCH_ID_CLRMSK           (IMG_UINT64_C(0X0000FFFFFFFFFFFF))
+#define RGX_CR_CORE_ID__PBVNC__VERSION_ID_SHIFT           (32U)
+#define RGX_CR_CORE_ID__PBVNC__VERSION_ID_CLRMSK          (IMG_UINT64_C(0XFFFF0000FFFFFFFF))
+#define RGX_CR_CORE_ID__PBVNC__NUMBER_OF_SCALABLE_UNITS_SHIFT (16U)
+#define RGX_CR_CORE_ID__PBVNC__NUMBER_OF_SCALABLE_UNITS_CLRMSK (IMG_UINT64_C(0XFFFFFFFF0000FFFF))
+#define RGX_CR_CORE_ID__PBVNC__CONFIG_ID_SHIFT            (0U)
+#define RGX_CR_CORE_ID__PBVNC__CONFIG_ID_CLRMSK           (IMG_UINT64_C(0XFFFFFFFFFFFF0000))
 
 
 /*
@@ -897,64 +484,61 @@
 */
 #define RGX_CR_CLK_XTPLUS_CTRL                            (0x0080U)
 #define RGX_CR_CLK_XTPLUS_CTRL_MASKFULL                   (IMG_UINT64_C(0x0000003FFFFF0000))
-#if defined(RGX_FEATURE_FASTRENDER_DM)
 #define RGX_CR_CLK_XTPLUS_CTRL_TDM_SHIFT                  (36U)
 #define RGX_CR_CLK_XTPLUS_CTRL_TDM_CLRMSK                 (IMG_UINT64_C(0XFFFFFFCFFFFFFFFF))
-#define RGX_CR_CLK_XTPLUS_CTRL_TDM_OFF                    (IMG_UINT64_C(0000000000000000))
-#define RGX_CR_CLK_XTPLUS_CTRL_TDM_ON                     (IMG_UINT64_C(0x0000001000000000))
-#define RGX_CR_CLK_XTPLUS_CTRL_TDM_AUTO                   (IMG_UINT64_C(0x0000002000000000))
-#endif /* RGX_FEATURE_FASTRENDER_DM */
-
+#define RGX_CR_CLK_XTPLUS_CTRL_TDM_OFF                    (IMG_UINT64_C(0000000000000000))  
+#define RGX_CR_CLK_XTPLUS_CTRL_TDM_ON                     (IMG_UINT64_C(0x0000001000000000))  
+#define RGX_CR_CLK_XTPLUS_CTRL_TDM_AUTO                   (IMG_UINT64_C(0x0000002000000000))  
 #define RGX_CR_CLK_XTPLUS_CTRL_ASTC_SHIFT                 (34U)
 #define RGX_CR_CLK_XTPLUS_CTRL_ASTC_CLRMSK                (IMG_UINT64_C(0XFFFFFFF3FFFFFFFF))
-#define RGX_CR_CLK_XTPLUS_CTRL_ASTC_OFF                   (IMG_UINT64_C(0000000000000000))
-#define RGX_CR_CLK_XTPLUS_CTRL_ASTC_ON                    (IMG_UINT64_C(0x0000000400000000))
-#define RGX_CR_CLK_XTPLUS_CTRL_ASTC_AUTO                  (IMG_UINT64_C(0x0000000800000000))
+#define RGX_CR_CLK_XTPLUS_CTRL_ASTC_OFF                   (IMG_UINT64_C(0000000000000000))  
+#define RGX_CR_CLK_XTPLUS_CTRL_ASTC_ON                    (IMG_UINT64_C(0x0000000400000000))  
+#define RGX_CR_CLK_XTPLUS_CTRL_ASTC_AUTO                  (IMG_UINT64_C(0x0000000800000000))  
 #define RGX_CR_CLK_XTPLUS_CTRL_IPF_SHIFT                  (32U)
 #define RGX_CR_CLK_XTPLUS_CTRL_IPF_CLRMSK                 (IMG_UINT64_C(0XFFFFFFFCFFFFFFFF))
-#define RGX_CR_CLK_XTPLUS_CTRL_IPF_OFF                    (IMG_UINT64_C(0000000000000000))
-#define RGX_CR_CLK_XTPLUS_CTRL_IPF_ON                     (IMG_UINT64_C(0x0000000100000000))
-#define RGX_CR_CLK_XTPLUS_CTRL_IPF_AUTO                   (IMG_UINT64_C(0x0000000200000000))
+#define RGX_CR_CLK_XTPLUS_CTRL_IPF_OFF                    (IMG_UINT64_C(0000000000000000))  
+#define RGX_CR_CLK_XTPLUS_CTRL_IPF_ON                     (IMG_UINT64_C(0x0000000100000000))  
+#define RGX_CR_CLK_XTPLUS_CTRL_IPF_AUTO                   (IMG_UINT64_C(0x0000000200000000))  
 #define RGX_CR_CLK_XTPLUS_CTRL_COMPUTE_SHIFT              (30U)
 #define RGX_CR_CLK_XTPLUS_CTRL_COMPUTE_CLRMSK             (IMG_UINT64_C(0XFFFFFFFF3FFFFFFF))
-#define RGX_CR_CLK_XTPLUS_CTRL_COMPUTE_OFF                (IMG_UINT64_C(0000000000000000))
-#define RGX_CR_CLK_XTPLUS_CTRL_COMPUTE_ON                 (IMG_UINT64_C(0x0000000040000000))
-#define RGX_CR_CLK_XTPLUS_CTRL_COMPUTE_AUTO               (IMG_UINT64_C(0x0000000080000000))
+#define RGX_CR_CLK_XTPLUS_CTRL_COMPUTE_OFF                (IMG_UINT64_C(0000000000000000))  
+#define RGX_CR_CLK_XTPLUS_CTRL_COMPUTE_ON                 (IMG_UINT64_C(0x0000000040000000))  
+#define RGX_CR_CLK_XTPLUS_CTRL_COMPUTE_AUTO               (IMG_UINT64_C(0x0000000080000000))  
 #define RGX_CR_CLK_XTPLUS_CTRL_PIXEL_SHIFT                (28U)
 #define RGX_CR_CLK_XTPLUS_CTRL_PIXEL_CLRMSK               (IMG_UINT64_C(0XFFFFFFFFCFFFFFFF))
-#define RGX_CR_CLK_XTPLUS_CTRL_PIXEL_OFF                  (IMG_UINT64_C(0000000000000000))
-#define RGX_CR_CLK_XTPLUS_CTRL_PIXEL_ON                   (IMG_UINT64_C(0x0000000010000000))
-#define RGX_CR_CLK_XTPLUS_CTRL_PIXEL_AUTO                 (IMG_UINT64_C(0x0000000020000000))
+#define RGX_CR_CLK_XTPLUS_CTRL_PIXEL_OFF                  (IMG_UINT64_C(0000000000000000))  
+#define RGX_CR_CLK_XTPLUS_CTRL_PIXEL_ON                   (IMG_UINT64_C(0x0000000010000000))  
+#define RGX_CR_CLK_XTPLUS_CTRL_PIXEL_AUTO                 (IMG_UINT64_C(0x0000000020000000))  
 #define RGX_CR_CLK_XTPLUS_CTRL_VERTEX_SHIFT               (26U)
 #define RGX_CR_CLK_XTPLUS_CTRL_VERTEX_CLRMSK              (IMG_UINT64_C(0XFFFFFFFFF3FFFFFF))
-#define RGX_CR_CLK_XTPLUS_CTRL_VERTEX_OFF                 (IMG_UINT64_C(0000000000000000))
-#define RGX_CR_CLK_XTPLUS_CTRL_VERTEX_ON                  (IMG_UINT64_C(0x0000000004000000))
-#define RGX_CR_CLK_XTPLUS_CTRL_VERTEX_AUTO                (IMG_UINT64_C(0x0000000008000000))
+#define RGX_CR_CLK_XTPLUS_CTRL_VERTEX_OFF                 (IMG_UINT64_C(0000000000000000))  
+#define RGX_CR_CLK_XTPLUS_CTRL_VERTEX_ON                  (IMG_UINT64_C(0x0000000004000000))  
+#define RGX_CR_CLK_XTPLUS_CTRL_VERTEX_AUTO                (IMG_UINT64_C(0x0000000008000000))  
 #define RGX_CR_CLK_XTPLUS_CTRL_USCPS_SHIFT                (24U)
 #define RGX_CR_CLK_XTPLUS_CTRL_USCPS_CLRMSK               (IMG_UINT64_C(0XFFFFFFFFFCFFFFFF))
-#define RGX_CR_CLK_XTPLUS_CTRL_USCPS_OFF                  (IMG_UINT64_C(0000000000000000))
-#define RGX_CR_CLK_XTPLUS_CTRL_USCPS_ON                   (IMG_UINT64_C(0x0000000001000000))
-#define RGX_CR_CLK_XTPLUS_CTRL_USCPS_AUTO                 (IMG_UINT64_C(0x0000000002000000))
+#define RGX_CR_CLK_XTPLUS_CTRL_USCPS_OFF                  (IMG_UINT64_C(0000000000000000))  
+#define RGX_CR_CLK_XTPLUS_CTRL_USCPS_ON                   (IMG_UINT64_C(0x0000000001000000))  
+#define RGX_CR_CLK_XTPLUS_CTRL_USCPS_AUTO                 (IMG_UINT64_C(0x0000000002000000))  
 #define RGX_CR_CLK_XTPLUS_CTRL_PDS_SHARED_SHIFT           (22U)
 #define RGX_CR_CLK_XTPLUS_CTRL_PDS_SHARED_CLRMSK          (IMG_UINT64_C(0XFFFFFFFFFF3FFFFF))
-#define RGX_CR_CLK_XTPLUS_CTRL_PDS_SHARED_OFF             (IMG_UINT64_C(0000000000000000))
-#define RGX_CR_CLK_XTPLUS_CTRL_PDS_SHARED_ON              (IMG_UINT64_C(0x0000000000400000))
-#define RGX_CR_CLK_XTPLUS_CTRL_PDS_SHARED_AUTO            (IMG_UINT64_C(0x0000000000800000))
+#define RGX_CR_CLK_XTPLUS_CTRL_PDS_SHARED_OFF             (IMG_UINT64_C(0000000000000000))  
+#define RGX_CR_CLK_XTPLUS_CTRL_PDS_SHARED_ON              (IMG_UINT64_C(0x0000000000400000))  
+#define RGX_CR_CLK_XTPLUS_CTRL_PDS_SHARED_AUTO            (IMG_UINT64_C(0x0000000000800000))  
 #define RGX_CR_CLK_XTPLUS_CTRL_BIF_BLACKPEARL_SHIFT       (20U)
 #define RGX_CR_CLK_XTPLUS_CTRL_BIF_BLACKPEARL_CLRMSK      (IMG_UINT64_C(0XFFFFFFFFFFCFFFFF))
-#define RGX_CR_CLK_XTPLUS_CTRL_BIF_BLACKPEARL_OFF         (IMG_UINT64_C(0000000000000000))
-#define RGX_CR_CLK_XTPLUS_CTRL_BIF_BLACKPEARL_ON          (IMG_UINT64_C(0x0000000000100000))
-#define RGX_CR_CLK_XTPLUS_CTRL_BIF_BLACKPEARL_AUTO        (IMG_UINT64_C(0x0000000000200000))
+#define RGX_CR_CLK_XTPLUS_CTRL_BIF_BLACKPEARL_OFF         (IMG_UINT64_C(0000000000000000))  
+#define RGX_CR_CLK_XTPLUS_CTRL_BIF_BLACKPEARL_ON          (IMG_UINT64_C(0x0000000000100000))  
+#define RGX_CR_CLK_XTPLUS_CTRL_BIF_BLACKPEARL_AUTO        (IMG_UINT64_C(0x0000000000200000))  
 #define RGX_CR_CLK_XTPLUS_CTRL_USC_SHARED_SHIFT           (18U)
 #define RGX_CR_CLK_XTPLUS_CTRL_USC_SHARED_CLRMSK          (IMG_UINT64_C(0XFFFFFFFFFFF3FFFF))
-#define RGX_CR_CLK_XTPLUS_CTRL_USC_SHARED_OFF             (IMG_UINT64_C(0000000000000000))
-#define RGX_CR_CLK_XTPLUS_CTRL_USC_SHARED_ON              (IMG_UINT64_C(0x0000000000040000))
-#define RGX_CR_CLK_XTPLUS_CTRL_USC_SHARED_AUTO            (IMG_UINT64_C(0x0000000000080000))
+#define RGX_CR_CLK_XTPLUS_CTRL_USC_SHARED_OFF             (IMG_UINT64_C(0000000000000000))  
+#define RGX_CR_CLK_XTPLUS_CTRL_USC_SHARED_ON              (IMG_UINT64_C(0x0000000000040000))  
+#define RGX_CR_CLK_XTPLUS_CTRL_USC_SHARED_AUTO            (IMG_UINT64_C(0x0000000000080000))  
 #define RGX_CR_CLK_XTPLUS_CTRL_GEOMETRY_SHIFT             (16U)
 #define RGX_CR_CLK_XTPLUS_CTRL_GEOMETRY_CLRMSK            (IMG_UINT64_C(0XFFFFFFFFFFFCFFFF))
-#define RGX_CR_CLK_XTPLUS_CTRL_GEOMETRY_OFF               (IMG_UINT64_C(0000000000000000))
-#define RGX_CR_CLK_XTPLUS_CTRL_GEOMETRY_ON                (IMG_UINT64_C(0x0000000000010000))
-#define RGX_CR_CLK_XTPLUS_CTRL_GEOMETRY_AUTO              (IMG_UINT64_C(0x0000000000020000))
+#define RGX_CR_CLK_XTPLUS_CTRL_GEOMETRY_OFF               (IMG_UINT64_C(0000000000000000))  
+#define RGX_CR_CLK_XTPLUS_CTRL_GEOMETRY_ON                (IMG_UINT64_C(0x0000000000010000))  
+#define RGX_CR_CLK_XTPLUS_CTRL_GEOMETRY_AUTO              (IMG_UINT64_C(0x0000000000020000))  
 
 
 /*
@@ -962,254 +546,82 @@
 */
 #define RGX_CR_CLK_XTPLUS_STATUS                          (0x0088U)
 #define RGX_CR_CLK_XTPLUS_STATUS_MASKFULL                 (IMG_UINT64_C(0x00000000000007FF))
-#if defined(RGX_FEATURE_FASTRENDER_DM)
 #define RGX_CR_CLK_XTPLUS_STATUS_TDM_SHIFT                (10U)
 #define RGX_CR_CLK_XTPLUS_STATUS_TDM_CLRMSK               (IMG_UINT64_C(0XFFFFFFFFFFFFFBFF))
-#define RGX_CR_CLK_XTPLUS_STATUS_TDM_GATED                (IMG_UINT64_C(0000000000000000))
-#define RGX_CR_CLK_XTPLUS_STATUS_TDM_RUNNING              (IMG_UINT64_C(0x0000000000000400))
-#endif /* RGX_FEATURE_FASTRENDER_DM */
-
+#define RGX_CR_CLK_XTPLUS_STATUS_TDM_GATED                (IMG_UINT64_C(0000000000000000))  
+#define RGX_CR_CLK_XTPLUS_STATUS_TDM_RUNNING              (IMG_UINT64_C(0x0000000000000400))  
 #define RGX_CR_CLK_XTPLUS_STATUS_IPF_SHIFT                (9U)
 #define RGX_CR_CLK_XTPLUS_STATUS_IPF_CLRMSK               (IMG_UINT64_C(0XFFFFFFFFFFFFFDFF))
-#define RGX_CR_CLK_XTPLUS_STATUS_IPF_GATED                (IMG_UINT64_C(0000000000000000))
-#define RGX_CR_CLK_XTPLUS_STATUS_IPF_RUNNING              (IMG_UINT64_C(0x0000000000000200))
+#define RGX_CR_CLK_XTPLUS_STATUS_IPF_GATED                (IMG_UINT64_C(0000000000000000))  
+#define RGX_CR_CLK_XTPLUS_STATUS_IPF_RUNNING              (IMG_UINT64_C(0x0000000000000200))  
 #define RGX_CR_CLK_XTPLUS_STATUS_COMPUTE_SHIFT            (8U)
 #define RGX_CR_CLK_XTPLUS_STATUS_COMPUTE_CLRMSK           (IMG_UINT64_C(0XFFFFFFFFFFFFFEFF))
-#define RGX_CR_CLK_XTPLUS_STATUS_COMPUTE_GATED            (IMG_UINT64_C(0000000000000000))
-#define RGX_CR_CLK_XTPLUS_STATUS_COMPUTE_RUNNING          (IMG_UINT64_C(0x0000000000000100))
+#define RGX_CR_CLK_XTPLUS_STATUS_COMPUTE_GATED            (IMG_UINT64_C(0000000000000000))  
+#define RGX_CR_CLK_XTPLUS_STATUS_COMPUTE_RUNNING          (IMG_UINT64_C(0x0000000000000100))  
 #define RGX_CR_CLK_XTPLUS_STATUS_ASTC_SHIFT               (7U)
 #define RGX_CR_CLK_XTPLUS_STATUS_ASTC_CLRMSK              (IMG_UINT64_C(0XFFFFFFFFFFFFFF7F))
-#define RGX_CR_CLK_XTPLUS_STATUS_ASTC_GATED               (IMG_UINT64_C(0000000000000000))
-#define RGX_CR_CLK_XTPLUS_STATUS_ASTC_RUNNING             (IMG_UINT64_C(0x0000000000000080))
+#define RGX_CR_CLK_XTPLUS_STATUS_ASTC_GATED               (IMG_UINT64_C(0000000000000000))  
+#define RGX_CR_CLK_XTPLUS_STATUS_ASTC_RUNNING             (IMG_UINT64_C(0x0000000000000080))  
 #define RGX_CR_CLK_XTPLUS_STATUS_PIXEL_SHIFT              (6U)
 #define RGX_CR_CLK_XTPLUS_STATUS_PIXEL_CLRMSK             (IMG_UINT64_C(0XFFFFFFFFFFFFFFBF))
-#define RGX_CR_CLK_XTPLUS_STATUS_PIXEL_GATED              (IMG_UINT64_C(0000000000000000))
-#define RGX_CR_CLK_XTPLUS_STATUS_PIXEL_RUNNING            (IMG_UINT64_C(0x0000000000000040))
+#define RGX_CR_CLK_XTPLUS_STATUS_PIXEL_GATED              (IMG_UINT64_C(0000000000000000))  
+#define RGX_CR_CLK_XTPLUS_STATUS_PIXEL_RUNNING            (IMG_UINT64_C(0x0000000000000040))  
 #define RGX_CR_CLK_XTPLUS_STATUS_VERTEX_SHIFT             (5U)
 #define RGX_CR_CLK_XTPLUS_STATUS_VERTEX_CLRMSK            (IMG_UINT64_C(0XFFFFFFFFFFFFFFDF))
-#define RGX_CR_CLK_XTPLUS_STATUS_VERTEX_GATED             (IMG_UINT64_C(0000000000000000))
-#define RGX_CR_CLK_XTPLUS_STATUS_VERTEX_RUNNING           (IMG_UINT64_C(0x0000000000000020))
+#define RGX_CR_CLK_XTPLUS_STATUS_VERTEX_GATED             (IMG_UINT64_C(0000000000000000))  
+#define RGX_CR_CLK_XTPLUS_STATUS_VERTEX_RUNNING           (IMG_UINT64_C(0x0000000000000020))  
 #define RGX_CR_CLK_XTPLUS_STATUS_USCPS_SHIFT              (4U)
 #define RGX_CR_CLK_XTPLUS_STATUS_USCPS_CLRMSK             (IMG_UINT64_C(0XFFFFFFFFFFFFFFEF))
-#define RGX_CR_CLK_XTPLUS_STATUS_USCPS_GATED              (IMG_UINT64_C(0000000000000000))
-#define RGX_CR_CLK_XTPLUS_STATUS_USCPS_RUNNING            (IMG_UINT64_C(0x0000000000000010))
+#define RGX_CR_CLK_XTPLUS_STATUS_USCPS_GATED              (IMG_UINT64_C(0000000000000000))  
+#define RGX_CR_CLK_XTPLUS_STATUS_USCPS_RUNNING            (IMG_UINT64_C(0x0000000000000010))  
 #define RGX_CR_CLK_XTPLUS_STATUS_PDS_SHARED_SHIFT         (3U)
 #define RGX_CR_CLK_XTPLUS_STATUS_PDS_SHARED_CLRMSK        (IMG_UINT64_C(0XFFFFFFFFFFFFFFF7))
-#define RGX_CR_CLK_XTPLUS_STATUS_PDS_SHARED_GATED         (IMG_UINT64_C(0000000000000000))
-#define RGX_CR_CLK_XTPLUS_STATUS_PDS_SHARED_RUNNING       (IMG_UINT64_C(0x0000000000000008))
+#define RGX_CR_CLK_XTPLUS_STATUS_PDS_SHARED_GATED         (IMG_UINT64_C(0000000000000000))  
+#define RGX_CR_CLK_XTPLUS_STATUS_PDS_SHARED_RUNNING       (IMG_UINT64_C(0x0000000000000008))  
 #define RGX_CR_CLK_XTPLUS_STATUS_BIF_BLACKPEARL_SHIFT     (2U)
 #define RGX_CR_CLK_XTPLUS_STATUS_BIF_BLACKPEARL_CLRMSK    (IMG_UINT64_C(0XFFFFFFFFFFFFFFFB))
-#define RGX_CR_CLK_XTPLUS_STATUS_BIF_BLACKPEARL_GATED     (IMG_UINT64_C(0000000000000000))
-#define RGX_CR_CLK_XTPLUS_STATUS_BIF_BLACKPEARL_RUNNING   (IMG_UINT64_C(0x0000000000000004))
+#define RGX_CR_CLK_XTPLUS_STATUS_BIF_BLACKPEARL_GATED     (IMG_UINT64_C(0000000000000000))  
+#define RGX_CR_CLK_XTPLUS_STATUS_BIF_BLACKPEARL_RUNNING   (IMG_UINT64_C(0x0000000000000004))  
 #define RGX_CR_CLK_XTPLUS_STATUS_USC_SHARED_SHIFT         (1U)
 #define RGX_CR_CLK_XTPLUS_STATUS_USC_SHARED_CLRMSK        (IMG_UINT64_C(0XFFFFFFFFFFFFFFFD))
-#define RGX_CR_CLK_XTPLUS_STATUS_USC_SHARED_GATED         (IMG_UINT64_C(0000000000000000))
-#define RGX_CR_CLK_XTPLUS_STATUS_USC_SHARED_RUNNING       (IMG_UINT64_C(0x0000000000000002))
+#define RGX_CR_CLK_XTPLUS_STATUS_USC_SHARED_GATED         (IMG_UINT64_C(0000000000000000))  
+#define RGX_CR_CLK_XTPLUS_STATUS_USC_SHARED_RUNNING       (IMG_UINT64_C(0x0000000000000002))  
 #define RGX_CR_CLK_XTPLUS_STATUS_GEOMETRY_SHIFT           (0U)
 #define RGX_CR_CLK_XTPLUS_STATUS_GEOMETRY_CLRMSK          (IMG_UINT64_C(0XFFFFFFFFFFFFFFFE))
-#define RGX_CR_CLK_XTPLUS_STATUS_GEOMETRY_GATED           (IMG_UINT64_C(0000000000000000))
-#define RGX_CR_CLK_XTPLUS_STATUS_GEOMETRY_RUNNING         (IMG_UINT64_C(0x0000000000000001))
+#define RGX_CR_CLK_XTPLUS_STATUS_GEOMETRY_GATED           (IMG_UINT64_C(0000000000000000))  
+#define RGX_CR_CLK_XTPLUS_STATUS_GEOMETRY_RUNNING         (IMG_UINT64_C(0x0000000000000001))  
 
 
-#if defined(RGX_FEATURE_PBE2_IN_XE)
 /*
     Register RGX_CR_SOFT_RESET
 */
 #define RGX_CR_SOFT_RESET                                 (0x0100U)
-#define RGX_CR_SOFT_RESET_MASKFULL                        (IMG_UINT64_C(0xFFE7FFFFFFFFFC1D))
-#if defined(RGX_FEATURE_CLUSTER_GROUPING)
-#define RGX_CR_SOFT_RESET_PHANTOM3_CORE_SHIFT             (63U)
-#define RGX_CR_SOFT_RESET_PHANTOM3_CORE_CLRMSK            (IMG_UINT64_C(0X7FFFFFFFFFFFFFFF))
-#define RGX_CR_SOFT_RESET_PHANTOM3_CORE_EN                (IMG_UINT64_C(0X8000000000000000))
-#define RGX_CR_SOFT_RESET_PHANTOM2_CORE_SHIFT             (62U)
-#define RGX_CR_SOFT_RESET_PHANTOM2_CORE_CLRMSK            (IMG_UINT64_C(0XBFFFFFFFFFFFFFFF))
-#define RGX_CR_SOFT_RESET_PHANTOM2_CORE_EN                (IMG_UINT64_C(0X4000000000000000))
-#define RGX_CR_SOFT_RESET_BERNADO2_CORE_SHIFT             (61U)
-#define RGX_CR_SOFT_RESET_BERNADO2_CORE_CLRMSK            (IMG_UINT64_C(0XDFFFFFFFFFFFFFFF))
-#define RGX_CR_SOFT_RESET_BERNADO2_CORE_EN                (IMG_UINT64_C(0X2000000000000000))
-#endif /* RGX_FEATURE_CLUSTER_GROUPING */
-
-#define RGX_CR_SOFT_RESET_JONES_CORE_SHIFT                (60U)
-#define RGX_CR_SOFT_RESET_JONES_CORE_CLRMSK               (IMG_UINT64_C(0XEFFFFFFFFFFFFFFF))
-#define RGX_CR_SOFT_RESET_JONES_CORE_EN                   (IMG_UINT64_C(0X1000000000000000))
-#define RGX_CR_SOFT_RESET_TILING_CORE_SHIFT               (59U)
-#define RGX_CR_SOFT_RESET_TILING_CORE_CLRMSK              (IMG_UINT64_C(0XF7FFFFFFFFFFFFFF))
-#define RGX_CR_SOFT_RESET_TILING_CORE_EN                  (IMG_UINT64_C(0X0800000000000000))
-#define RGX_CR_SOFT_RESET_TE3_SHIFT                       (58U)
-#define RGX_CR_SOFT_RESET_TE3_CLRMSK                      (IMG_UINT64_C(0XFBFFFFFFFFFFFFFF))
-#define RGX_CR_SOFT_RESET_TE3_EN                          (IMG_UINT64_C(0X0400000000000000))
-#define RGX_CR_SOFT_RESET_VCE_SHIFT                       (57U)
-#define RGX_CR_SOFT_RESET_VCE_CLRMSK                      (IMG_UINT64_C(0XFDFFFFFFFFFFFFFF))
-#define RGX_CR_SOFT_RESET_VCE_EN                          (IMG_UINT64_C(0X0200000000000000))
-#define RGX_CR_SOFT_RESET_VBS_SHIFT                       (56U)
-#define RGX_CR_SOFT_RESET_VBS_CLRMSK                      (IMG_UINT64_C(0XFEFFFFFFFFFFFFFF))
-#define RGX_CR_SOFT_RESET_VBS_EN                          (IMG_UINT64_C(0X0100000000000000))
-#if defined(RGX_FEATURE_RAY_TRACING)
-#define RGX_CR_SOFT_RESET_DPX1_CORE_SHIFT                 (55U)
-#define RGX_CR_SOFT_RESET_DPX1_CORE_CLRMSK                (IMG_UINT64_C(0XFF7FFFFFFFFFFFFF))
-#define RGX_CR_SOFT_RESET_DPX1_CORE_EN                    (IMG_UINT64_C(0X0080000000000000))
-#define RGX_CR_SOFT_RESET_DPX0_CORE_SHIFT                 (54U)
-#define RGX_CR_SOFT_RESET_DPX0_CORE_CLRMSK                (IMG_UINT64_C(0XFFBFFFFFFFFFFFFF))
-#define RGX_CR_SOFT_RESET_DPX0_CORE_EN                    (IMG_UINT64_C(0X0040000000000000))
-#define RGX_CR_SOFT_RESET_FBA_SHIFT                       (53U)
-#define RGX_CR_SOFT_RESET_FBA_CLRMSK                      (IMG_UINT64_C(0XFFDFFFFFFFFFFFFF))
-#define RGX_CR_SOFT_RESET_FBA_EN                          (IMG_UINT64_C(0X0020000000000000))
-#define RGX_CR_SOFT_RESET_SH_SHIFT                        (50U)
-#define RGX_CR_SOFT_RESET_SH_CLRMSK                       (IMG_UINT64_C(0XFFFBFFFFFFFFFFFF))
-#define RGX_CR_SOFT_RESET_SH_EN                           (IMG_UINT64_C(0X0004000000000000))
-#define RGX_CR_SOFT_RESET_VRDM_SHIFT                      (49U)
-#define RGX_CR_SOFT_RESET_VRDM_CLRMSK                     (IMG_UINT64_C(0XFFFDFFFFFFFFFFFF))
-#define RGX_CR_SOFT_RESET_VRDM_EN                         (IMG_UINT64_C(0X0002000000000000))
-#endif /* RGX_FEATURE_RAY_TRACING */
-
-#define RGX_CR_SOFT_RESET_MCU_FBTC_SHIFT                  (48U)
-#define RGX_CR_SOFT_RESET_MCU_FBTC_CLRMSK                 (IMG_UINT64_C(0XFFFEFFFFFFFFFFFF))
-#define RGX_CR_SOFT_RESET_MCU_FBTC_EN                     (IMG_UINT64_C(0X0001000000000000))
-#if defined(RGX_FEATURE_CLUSTER_GROUPING)
-#define RGX_CR_SOFT_RESET_PHANTOM1_CORE_SHIFT             (47U)
-#define RGX_CR_SOFT_RESET_PHANTOM1_CORE_CLRMSK            (IMG_UINT64_C(0XFFFF7FFFFFFFFFFF))
-#define RGX_CR_SOFT_RESET_PHANTOM1_CORE_EN                (IMG_UINT64_C(0X0000800000000000))
-#define RGX_CR_SOFT_RESET_PHANTOM0_CORE_SHIFT             (46U)
-#define RGX_CR_SOFT_RESET_PHANTOM0_CORE_CLRMSK            (IMG_UINT64_C(0XFFFFBFFFFFFFFFFF))
-#define RGX_CR_SOFT_RESET_PHANTOM0_CORE_EN                (IMG_UINT64_C(0X0000400000000000))
-#define RGX_CR_SOFT_RESET_BERNADO1_CORE_SHIFT             (45U)
-#define RGX_CR_SOFT_RESET_BERNADO1_CORE_CLRMSK            (IMG_UINT64_C(0XFFFFDFFFFFFFFFFF))
-#define RGX_CR_SOFT_RESET_BERNADO1_CORE_EN                (IMG_UINT64_C(0X0000200000000000))
-#define RGX_CR_SOFT_RESET_BERNADO0_CORE_SHIFT             (44U)
-#define RGX_CR_SOFT_RESET_BERNADO0_CORE_CLRMSK            (IMG_UINT64_C(0XFFFFEFFFFFFFFFFF))
-#define RGX_CR_SOFT_RESET_BERNADO0_CORE_EN                (IMG_UINT64_C(0X0000100000000000))
-#define RGX_CR_SOFT_RESET_IPP_SHIFT                       (43U)
-#define RGX_CR_SOFT_RESET_IPP_CLRMSK                      (IMG_UINT64_C(0XFFFFF7FFFFFFFFFF))
-#define RGX_CR_SOFT_RESET_IPP_EN                          (IMG_UINT64_C(0X0000080000000000))
-#define RGX_CR_SOFT_RESET_BIF_TEXAS_SHIFT                 (42U)
-#define RGX_CR_SOFT_RESET_BIF_TEXAS_CLRMSK                (IMG_UINT64_C(0XFFFFFBFFFFFFFFFF))
-#define RGX_CR_SOFT_RESET_BIF_TEXAS_EN                    (IMG_UINT64_C(0X0000040000000000))
-#define RGX_CR_SOFT_RESET_TORNADO_CORE_SHIFT              (41U)
-#define RGX_CR_SOFT_RESET_TORNADO_CORE_CLRMSK             (IMG_UINT64_C(0XFFFFFDFFFFFFFFFF))
-#define RGX_CR_SOFT_RESET_TORNADO_CORE_EN                 (IMG_UINT64_C(0X0000020000000000))
-#endif /* RGX_FEATURE_CLUSTER_GROUPING */
-
-#define RGX_CR_SOFT_RESET_DUST_H_CORE_SHIFT               (40U)
-#define RGX_CR_SOFT_RESET_DUST_H_CORE_CLRMSK              (IMG_UINT64_C(0XFFFFFEFFFFFFFFFF))
-#define RGX_CR_SOFT_RESET_DUST_H_CORE_EN                  (IMG_UINT64_C(0X0000010000000000))
-#define RGX_CR_SOFT_RESET_DUST_G_CORE_SHIFT               (39U)
-#define RGX_CR_SOFT_RESET_DUST_G_CORE_CLRMSK              (IMG_UINT64_C(0XFFFFFF7FFFFFFFFF))
-#define RGX_CR_SOFT_RESET_DUST_G_CORE_EN                  (IMG_UINT64_C(0X0000008000000000))
-#define RGX_CR_SOFT_RESET_DUST_F_CORE_SHIFT               (38U)
-#define RGX_CR_SOFT_RESET_DUST_F_CORE_CLRMSK              (IMG_UINT64_C(0XFFFFFFBFFFFFFFFF))
-#define RGX_CR_SOFT_RESET_DUST_F_CORE_EN                  (IMG_UINT64_C(0X0000004000000000))
-#define RGX_CR_SOFT_RESET_DUST_E_CORE_SHIFT               (37U)
-#define RGX_CR_SOFT_RESET_DUST_E_CORE_CLRMSK              (IMG_UINT64_C(0XFFFFFFDFFFFFFFFF))
-#define RGX_CR_SOFT_RESET_DUST_E_CORE_EN                  (IMG_UINT64_C(0X0000002000000000))
-#define RGX_CR_SOFT_RESET_DUST_D_CORE_SHIFT               (36U)
-#define RGX_CR_SOFT_RESET_DUST_D_CORE_CLRMSK              (IMG_UINT64_C(0XFFFFFFEFFFFFFFFF))
-#define RGX_CR_SOFT_RESET_DUST_D_CORE_EN                  (IMG_UINT64_C(0X0000001000000000))
-#define RGX_CR_SOFT_RESET_DUST_C_CORE_SHIFT               (35U)
-#define RGX_CR_SOFT_RESET_DUST_C_CORE_CLRMSK              (IMG_UINT64_C(0XFFFFFFF7FFFFFFFF))
-#define RGX_CR_SOFT_RESET_DUST_C_CORE_EN                  (IMG_UINT64_C(0X0000000800000000))
-#define RGX_CR_SOFT_RESET_MMU_SHIFT                       (34U)
-#define RGX_CR_SOFT_RESET_MMU_CLRMSK                      (IMG_UINT64_C(0XFFFFFFFBFFFFFFFF))
-#define RGX_CR_SOFT_RESET_MMU_EN                          (IMG_UINT64_C(0X0000000400000000))
-#define RGX_CR_SOFT_RESET_BIF1_SHIFT                      (33U)
-#define RGX_CR_SOFT_RESET_BIF1_CLRMSK                     (IMG_UINT64_C(0XFFFFFFFDFFFFFFFF))
-#define RGX_CR_SOFT_RESET_BIF1_EN                         (IMG_UINT64_C(0X0000000200000000))
-#define RGX_CR_SOFT_RESET_GARTEN_SHIFT                    (32U)
-#define RGX_CR_SOFT_RESET_GARTEN_CLRMSK                   (IMG_UINT64_C(0XFFFFFFFEFFFFFFFF))
-#define RGX_CR_SOFT_RESET_GARTEN_EN                       (IMG_UINT64_C(0X0000000100000000))
-#define RGX_CR_SOFT_RESET_RASCAL_CORE_SHIFT               (31U)
-#define RGX_CR_SOFT_RESET_RASCAL_CORE_CLRMSK              (IMG_UINT64_C(0XFFFFFFFF7FFFFFFF))
-#define RGX_CR_SOFT_RESET_RASCAL_CORE_EN                  (IMG_UINT64_C(0X0000000080000000))
-#define RGX_CR_SOFT_RESET_DUST_B_CORE_SHIFT               (30U)
-#define RGX_CR_SOFT_RESET_DUST_B_CORE_CLRMSK              (IMG_UINT64_C(0XFFFFFFFFBFFFFFFF))
-#define RGX_CR_SOFT_RESET_DUST_B_CORE_EN                  (IMG_UINT64_C(0X0000000040000000))
-#define RGX_CR_SOFT_RESET_DUST_A_CORE_SHIFT               (29U)
-#define RGX_CR_SOFT_RESET_DUST_A_CORE_CLRMSK              (IMG_UINT64_C(0XFFFFFFFFDFFFFFFF))
-#define RGX_CR_SOFT_RESET_DUST_A_CORE_EN                  (IMG_UINT64_C(0X0000000020000000))
-#define RGX_CR_SOFT_RESET_FB_TLCACHE_SHIFT                (28U)
-#define RGX_CR_SOFT_RESET_FB_TLCACHE_CLRMSK               (IMG_UINT64_C(0XFFFFFFFFEFFFFFFF))
-#define RGX_CR_SOFT_RESET_FB_TLCACHE_EN                   (IMG_UINT64_C(0X0000000010000000))
-#define RGX_CR_SOFT_RESET_SLC_SHIFT                       (27U)
-#define RGX_CR_SOFT_RESET_SLC_CLRMSK                      (IMG_UINT64_C(0XFFFFFFFFF7FFFFFF))
-#define RGX_CR_SOFT_RESET_SLC_EN                          (IMG_UINT64_C(0X0000000008000000))
-#define RGX_CR_SOFT_RESET_TLA_SHIFT                       (26U)
-#define RGX_CR_SOFT_RESET_TLA_CLRMSK                      (IMG_UINT64_C(0XFFFFFFFFFBFFFFFF))
-#define RGX_CR_SOFT_RESET_TLA_EN                          (IMG_UINT64_C(0X0000000004000000))
-#define RGX_CR_SOFT_RESET_UVS_SHIFT                       (25U)
-#define RGX_CR_SOFT_RESET_UVS_CLRMSK                      (IMG_UINT64_C(0XFFFFFFFFFDFFFFFF))
-#define RGX_CR_SOFT_RESET_UVS_EN                          (IMG_UINT64_C(0X0000000002000000))
-#define RGX_CR_SOFT_RESET_TE_SHIFT                        (24U)
-#define RGX_CR_SOFT_RESET_TE_CLRMSK                       (IMG_UINT64_C(0XFFFFFFFFFEFFFFFF))
-#define RGX_CR_SOFT_RESET_TE_EN                           (IMG_UINT64_C(0X0000000001000000))
-#define RGX_CR_SOFT_RESET_GPP_SHIFT                       (23U)
-#define RGX_CR_SOFT_RESET_GPP_CLRMSK                      (IMG_UINT64_C(0XFFFFFFFFFF7FFFFF))
-#define RGX_CR_SOFT_RESET_GPP_EN                          (IMG_UINT64_C(0X0000000000800000))
-#define RGX_CR_SOFT_RESET_FBDC_SHIFT                      (22U)
-#define RGX_CR_SOFT_RESET_FBDC_CLRMSK                     (IMG_UINT64_C(0XFFFFFFFFFFBFFFFF))
-#define RGX_CR_SOFT_RESET_FBDC_EN                         (IMG_UINT64_C(0X0000000000400000))
-#define RGX_CR_SOFT_RESET_FBC_SHIFT                       (21U)
-#define RGX_CR_SOFT_RESET_FBC_CLRMSK                      (IMG_UINT64_C(0XFFFFFFFFFFDFFFFF))
-#define RGX_CR_SOFT_RESET_FBC_EN                          (IMG_UINT64_C(0X0000000000200000))
-#define RGX_CR_SOFT_RESET_PM_SHIFT                        (20U)
-#define RGX_CR_SOFT_RESET_PM_CLRMSK                       (IMG_UINT64_C(0XFFFFFFFFFFEFFFFF))
-#define RGX_CR_SOFT_RESET_PM_EN                           (IMG_UINT64_C(0X0000000000100000))
-#define RGX_CR_SOFT_RESET_PBE_SHIFT                       (19U)
-#define RGX_CR_SOFT_RESET_PBE_CLRMSK                      (IMG_UINT64_C(0XFFFFFFFFFFF7FFFF))
-#define RGX_CR_SOFT_RESET_PBE_EN                          (IMG_UINT64_C(0X0000000000080000))
-#define RGX_CR_SOFT_RESET_USC_SHARED_SHIFT                (18U)
-#define RGX_CR_SOFT_RESET_USC_SHARED_CLRMSK               (IMG_UINT64_C(0XFFFFFFFFFFFBFFFF))
-#define RGX_CR_SOFT_RESET_USC_SHARED_EN                   (IMG_UINT64_C(0X0000000000040000))
-#define RGX_CR_SOFT_RESET_MCU_L1_SHIFT                    (17U)
-#define RGX_CR_SOFT_RESET_MCU_L1_CLRMSK                   (IMG_UINT64_C(0XFFFFFFFFFFFDFFFF))
-#define RGX_CR_SOFT_RESET_MCU_L1_EN                       (IMG_UINT64_C(0X0000000000020000))
-#define RGX_CR_SOFT_RESET_BIF_SHIFT                       (16U)
-#define RGX_CR_SOFT_RESET_BIF_CLRMSK                      (IMG_UINT64_C(0XFFFFFFFFFFFEFFFF))
-#define RGX_CR_SOFT_RESET_BIF_EN                          (IMG_UINT64_C(0X0000000000010000))
-#if defined(RGX_FEATURE_COMPUTE)
-#define RGX_CR_SOFT_RESET_CDM_SHIFT                       (15U)
-#define RGX_CR_SOFT_RESET_CDM_CLRMSK                      (IMG_UINT64_C(0XFFFFFFFFFFFF7FFF))
-#define RGX_CR_SOFT_RESET_CDM_EN                          (IMG_UINT64_C(0X0000000000008000))
-#endif /* RGX_FEATURE_COMPUTE */
-
-#define RGX_CR_SOFT_RESET_VDM_SHIFT                       (14U)
-#define RGX_CR_SOFT_RESET_VDM_CLRMSK                      (IMG_UINT64_C(0XFFFFFFFFFFFFBFFF))
-#define RGX_CR_SOFT_RESET_VDM_EN                          (IMG_UINT64_C(0X0000000000004000))
-#if defined(RGX_FEATURE_TESSELLATION)
-#define RGX_CR_SOFT_RESET_TESS_SHIFT                      (13U)
-#define RGX_CR_SOFT_RESET_TESS_CLRMSK                     (IMG_UINT64_C(0XFFFFFFFFFFFFDFFF))
-#define RGX_CR_SOFT_RESET_TESS_EN                         (IMG_UINT64_C(0X0000000000002000))
-#endif /* RGX_FEATURE_TESSELLATION */
-
-#define RGX_CR_SOFT_RESET_PDS_SHIFT                       (12U)
-#define RGX_CR_SOFT_RESET_PDS_CLRMSK                      (IMG_UINT64_C(0XFFFFFFFFFFFFEFFF))
-#define RGX_CR_SOFT_RESET_PDS_EN                          (IMG_UINT64_C(0X0000000000001000))
-#define RGX_CR_SOFT_RESET_ISP_SHIFT                       (11U)
-#define RGX_CR_SOFT_RESET_ISP_CLRMSK                      (IMG_UINT64_C(0XFFFFFFFFFFFFF7FF))
-#define RGX_CR_SOFT_RESET_ISP_EN                          (IMG_UINT64_C(0X0000000000000800))
-#define RGX_CR_SOFT_RESET_TSP_SHIFT                       (10U)
-#define RGX_CR_SOFT_RESET_TSP_CLRMSK                      (IMG_UINT64_C(0XFFFFFFFFFFFFFBFF))
-#define RGX_CR_SOFT_RESET_TSP_EN                          (IMG_UINT64_C(0X0000000000000400))
-#define RGX_CR_SOFT_RESET_TPU_MCU_DEMUX_SHIFT             (4U)
-#define RGX_CR_SOFT_RESET_TPU_MCU_DEMUX_CLRMSK            (IMG_UINT64_C(0XFFFFFFFFFFFFFFEF))
-#define RGX_CR_SOFT_RESET_TPU_MCU_DEMUX_EN                (IMG_UINT64_C(0X0000000000000010))
-#define RGX_CR_SOFT_RESET_MCU_L0_SHIFT                    (3U)
-#define RGX_CR_SOFT_RESET_MCU_L0_CLRMSK                   (IMG_UINT64_C(0XFFFFFFFFFFFFFFF7))
-#define RGX_CR_SOFT_RESET_MCU_L0_EN                       (IMG_UINT64_C(0X0000000000000008))
-#define RGX_CR_SOFT_RESET_TPU_SHIFT                       (2U)
-#define RGX_CR_SOFT_RESET_TPU_CLRMSK                      (IMG_UINT64_C(0XFFFFFFFFFFFFFFFB))
-#define RGX_CR_SOFT_RESET_TPU_EN                          (IMG_UINT64_C(0X0000000000000004))
-#define RGX_CR_SOFT_RESET_USC_SHIFT                       (0U)
-#define RGX_CR_SOFT_RESET_USC_CLRMSK                      (IMG_UINT64_C(0XFFFFFFFFFFFFFFFE))
-#define RGX_CR_SOFT_RESET_USC_EN                          (IMG_UINT64_C(0X0000000000000001))
-#endif /* RGX_FEATURE_PBE2_IN_XE */ 
-
-
-#if !defined(RGX_FEATURE_PBE2_IN_XE)
-/*
-    Register RGX_CR_SOFT_RESET
-*/
-#define RGX_CR_SOFT_RESET                                 (0x0100U)
+#define RGX_CR_SOFT_RESET__PBE2_XE__MASKFULL              (IMG_UINT64_C(0xFFE7FFFFFFFFFC1D))
 #define RGX_CR_SOFT_RESET_MASKFULL                        (IMG_UINT64_C(0x00E7FFFFFFFFFC1D))
-#if defined(RGX_FEATURE_RAY_TRACING)
+#define RGX_CR_SOFT_RESET__PBE2_XE__PHANTOM3_CORE_SHIFT   (63U)
+#define RGX_CR_SOFT_RESET__PBE2_XE__PHANTOM3_CORE_CLRMSK  (IMG_UINT64_C(0X7FFFFFFFFFFFFFFF))
+#define RGX_CR_SOFT_RESET__PBE2_XE__PHANTOM3_CORE_EN      (IMG_UINT64_C(0X8000000000000000))
+#define RGX_CR_SOFT_RESET__PBE2_XE__PHANTOM2_CORE_SHIFT   (62U)
+#define RGX_CR_SOFT_RESET__PBE2_XE__PHANTOM2_CORE_CLRMSK  (IMG_UINT64_C(0XBFFFFFFFFFFFFFFF))
+#define RGX_CR_SOFT_RESET__PBE2_XE__PHANTOM2_CORE_EN      (IMG_UINT64_C(0X4000000000000000))
+#define RGX_CR_SOFT_RESET__PBE2_XE__BERNADO2_CORE_SHIFT   (61U)
+#define RGX_CR_SOFT_RESET__PBE2_XE__BERNADO2_CORE_CLRMSK  (IMG_UINT64_C(0XDFFFFFFFFFFFFFFF))
+#define RGX_CR_SOFT_RESET__PBE2_XE__BERNADO2_CORE_EN      (IMG_UINT64_C(0X2000000000000000))
+#define RGX_CR_SOFT_RESET__PBE2_XE__JONES_CORE_SHIFT      (60U)
+#define RGX_CR_SOFT_RESET__PBE2_XE__JONES_CORE_CLRMSK     (IMG_UINT64_C(0XEFFFFFFFFFFFFFFF))
+#define RGX_CR_SOFT_RESET__PBE2_XE__JONES_CORE_EN         (IMG_UINT64_C(0X1000000000000000))
+#define RGX_CR_SOFT_RESET__PBE2_XE__TILING_CORE_SHIFT     (59U)
+#define RGX_CR_SOFT_RESET__PBE2_XE__TILING_CORE_CLRMSK    (IMG_UINT64_C(0XF7FFFFFFFFFFFFFF))
+#define RGX_CR_SOFT_RESET__PBE2_XE__TILING_CORE_EN        (IMG_UINT64_C(0X0800000000000000))
+#define RGX_CR_SOFT_RESET__PBE2_XE__TE3_SHIFT             (58U)
+#define RGX_CR_SOFT_RESET__PBE2_XE__TE3_CLRMSK            (IMG_UINT64_C(0XFBFFFFFFFFFFFFFF))
+#define RGX_CR_SOFT_RESET__PBE2_XE__TE3_EN                (IMG_UINT64_C(0X0400000000000000))
+#define RGX_CR_SOFT_RESET__PBE2_XE__VCE_SHIFT             (57U)
+#define RGX_CR_SOFT_RESET__PBE2_XE__VCE_CLRMSK            (IMG_UINT64_C(0XFDFFFFFFFFFFFFFF))
+#define RGX_CR_SOFT_RESET__PBE2_XE__VCE_EN                (IMG_UINT64_C(0X0200000000000000))
+#define RGX_CR_SOFT_RESET__PBE2_XE__VBS_SHIFT             (56U)
+#define RGX_CR_SOFT_RESET__PBE2_XE__VBS_CLRMSK            (IMG_UINT64_C(0XFEFFFFFFFFFFFFFF))
+#define RGX_CR_SOFT_RESET__PBE2_XE__VBS_EN                (IMG_UINT64_C(0X0100000000000000))
 #define RGX_CR_SOFT_RESET_DPX1_CORE_SHIFT                 (55U)
 #define RGX_CR_SOFT_RESET_DPX1_CORE_CLRMSK                (IMG_UINT64_C(0XFF7FFFFFFFFFFFFF))
 #define RGX_CR_SOFT_RESET_DPX1_CORE_EN                    (IMG_UINT64_C(0X0080000000000000))
@@ -1225,12 +637,9 @@
 #define RGX_CR_SOFT_RESET_VRDM_SHIFT                      (49U)
 #define RGX_CR_SOFT_RESET_VRDM_CLRMSK                     (IMG_UINT64_C(0XFFFDFFFFFFFFFFFF))
 #define RGX_CR_SOFT_RESET_VRDM_EN                         (IMG_UINT64_C(0X0002000000000000))
-#endif /* RGX_FEATURE_RAY_TRACING */
-
 #define RGX_CR_SOFT_RESET_MCU_FBTC_SHIFT                  (48U)
 #define RGX_CR_SOFT_RESET_MCU_FBTC_CLRMSK                 (IMG_UINT64_C(0XFFFEFFFFFFFFFFFF))
 #define RGX_CR_SOFT_RESET_MCU_FBTC_EN                     (IMG_UINT64_C(0X0001000000000000))
-#if defined(RGX_FEATURE_CLUSTER_GROUPING)
 #define RGX_CR_SOFT_RESET_PHANTOM1_CORE_SHIFT             (47U)
 #define RGX_CR_SOFT_RESET_PHANTOM1_CORE_CLRMSK            (IMG_UINT64_C(0XFFFF7FFFFFFFFFFF))
 #define RGX_CR_SOFT_RESET_PHANTOM1_CORE_EN                (IMG_UINT64_C(0X0000800000000000))
@@ -1252,8 +661,6 @@
 #define RGX_CR_SOFT_RESET_TORNADO_CORE_SHIFT              (41U)
 #define RGX_CR_SOFT_RESET_TORNADO_CORE_CLRMSK             (IMG_UINT64_C(0XFFFFFDFFFFFFFFFF))
 #define RGX_CR_SOFT_RESET_TORNADO_CORE_EN                 (IMG_UINT64_C(0X0000020000000000))
-#endif /* RGX_FEATURE_CLUSTER_GROUPING */
-
 #define RGX_CR_SOFT_RESET_DUST_H_CORE_SHIFT               (40U)
 #define RGX_CR_SOFT_RESET_DUST_H_CORE_CLRMSK              (IMG_UINT64_C(0XFFFFFEFFFFFFFFFF))
 #define RGX_CR_SOFT_RESET_DUST_H_CORE_EN                  (IMG_UINT64_C(0X0000010000000000))
@@ -1329,21 +736,15 @@
 #define RGX_CR_SOFT_RESET_BIF_SHIFT                       (16U)
 #define RGX_CR_SOFT_RESET_BIF_CLRMSK                      (IMG_UINT64_C(0XFFFFFFFFFFFEFFFF))
 #define RGX_CR_SOFT_RESET_BIF_EN                          (IMG_UINT64_C(0X0000000000010000))
-#if defined(RGX_FEATURE_COMPUTE)
 #define RGX_CR_SOFT_RESET_CDM_SHIFT                       (15U)
 #define RGX_CR_SOFT_RESET_CDM_CLRMSK                      (IMG_UINT64_C(0XFFFFFFFFFFFF7FFF))
 #define RGX_CR_SOFT_RESET_CDM_EN                          (IMG_UINT64_C(0X0000000000008000))
-#endif /* RGX_FEATURE_COMPUTE */
-
 #define RGX_CR_SOFT_RESET_VDM_SHIFT                       (14U)
 #define RGX_CR_SOFT_RESET_VDM_CLRMSK                      (IMG_UINT64_C(0XFFFFFFFFFFFFBFFF))
 #define RGX_CR_SOFT_RESET_VDM_EN                          (IMG_UINT64_C(0X0000000000004000))
-#if defined(RGX_FEATURE_TESSELLATION)
 #define RGX_CR_SOFT_RESET_TESS_SHIFT                      (13U)
 #define RGX_CR_SOFT_RESET_TESS_CLRMSK                     (IMG_UINT64_C(0XFFFFFFFFFFFFDFFF))
 #define RGX_CR_SOFT_RESET_TESS_EN                         (IMG_UINT64_C(0X0000000000002000))
-#endif /* RGX_FEATURE_TESSELLATION */
-
 #define RGX_CR_SOFT_RESET_PDS_SHIFT                       (12U)
 #define RGX_CR_SOFT_RESET_PDS_CLRMSK                      (IMG_UINT64_C(0XFFFFFFFFFFFFEFFF))
 #define RGX_CR_SOFT_RESET_PDS_EN                          (IMG_UINT64_C(0X0000000000001000))
@@ -1365,15 +766,15 @@
 #define RGX_CR_SOFT_RESET_USC_SHIFT                       (0U)
 #define RGX_CR_SOFT_RESET_USC_CLRMSK                      (IMG_UINT64_C(0XFFFFFFFFFFFFFFFE))
 #define RGX_CR_SOFT_RESET_USC_EN                          (IMG_UINT64_C(0X0000000000000001))
-#endif /* !defined(RGX_FEATURE_PBE2_IN_XE) */
 
 
-#if defined(RGX_FEATURE_S7_TOP_INFRASTRUCTURE)
 /*
     Register RGX_CR_SOFT_RESET2
 */
 #define RGX_CR_SOFT_RESET2                                (0x0108U)
-#define RGX_CR_SOFT_RESET2_MASKFULL                       (IMG_UINT64_C(0x0000000000000FFF))
+#define RGX_CR_SOFT_RESET2_MASKFULL                       (IMG_UINT64_C(0x00000000001FFFFF))
+#define RGX_CR_SOFT_RESET2_SPFILTER_SHIFT                 (12U)
+#define RGX_CR_SOFT_RESET2_SPFILTER_CLRMSK                (0XFFE00FFFU)
 #define RGX_CR_SOFT_RESET2_TDM_SHIFT                      (11U)
 #define RGX_CR_SOFT_RESET2_TDM_CLRMSK                     (0XFFFFF7FFU)
 #define RGX_CR_SOFT_RESET2_TDM_EN                         (0X00000800U)
@@ -1404,122 +805,29 @@
 #define RGX_CR_SOFT_RESET2_PIXEL_SHIFT                    (2U)
 #define RGX_CR_SOFT_RESET2_PIXEL_CLRMSK                   (0XFFFFFFFBU)
 #define RGX_CR_SOFT_RESET2_PIXEL_EN                       (0X00000004U)
-#if defined(RGX_FEATURE_COMPUTE)
 #define RGX_CR_SOFT_RESET2_CDM_SHIFT                      (1U)
 #define RGX_CR_SOFT_RESET2_CDM_CLRMSK                     (0XFFFFFFFDU)
 #define RGX_CR_SOFT_RESET2_CDM_EN                         (0X00000002U)
-#endif /* RGX_FEATURE_COMPUTE */
-
 #define RGX_CR_SOFT_RESET2_VERTEX_SHIFT                   (0U)
 #define RGX_CR_SOFT_RESET2_VERTEX_CLRMSK                  (0XFFFFFFFEU)
 #define RGX_CR_SOFT_RESET2_VERTEX_EN                      (0X00000001U)
 
 
-#endif /* RGX_FEATURE_S7_TOP_INFRASTRUCTURE */
-
-#if defined(RGX_FEATURE_SIGNAL_SNOOPING)
 /*
     Register RGX_CR_EVENT_STATUS
 */
 #define RGX_CR_EVENT_STATUS                               (0x0130U)
-#define RGX_CR_EVENT_STATUS_MASKFULL                      (IMG_UINT64_C(0x00000000E007FFFF))
-#if defined(RGX_FEATURE_FASTRENDER_DM)
-#define RGX_CR_EVENT_STATUS_TDM_FENCE_FINISHED_SHIFT      (31U)
-#define RGX_CR_EVENT_STATUS_TDM_FENCE_FINISHED_CLRMSK     (0X7FFFFFFFU)
-#define RGX_CR_EVENT_STATUS_TDM_FENCE_FINISHED_EN         (0X80000000U)
-#define RGX_CR_EVENT_STATUS_TDM_BUFFER_STALL_SHIFT        (30U)
-#define RGX_CR_EVENT_STATUS_TDM_BUFFER_STALL_CLRMSK       (0XBFFFFFFFU)
-#define RGX_CR_EVENT_STATUS_TDM_BUFFER_STALL_EN           (0X40000000U)
-#endif /* RGX_FEATURE_FASTRENDER_DM */
-
-#define RGX_CR_EVENT_STATUS_COMPUTE_SIGNAL_FAILURE_SHIFT  (29U)
-#define RGX_CR_EVENT_STATUS_COMPUTE_SIGNAL_FAILURE_CLRMSK (0XDFFFFFFFU)
-#define RGX_CR_EVENT_STATUS_COMPUTE_SIGNAL_FAILURE_EN     (0X20000000U)
-#if defined(RGX_FEATURE_FASTRENDER_DM)
-#define RGX_CR_EVENT_STATUS_TDM_CONTEXT_STORE_FINISHED_SHIFT (18U)
-#define RGX_CR_EVENT_STATUS_TDM_CONTEXT_STORE_FINISHED_CLRMSK (0XFFFBFFFFU)
-#define RGX_CR_EVENT_STATUS_TDM_CONTEXT_STORE_FINISHED_EN (0X00040000U)
-#endif /* RGX_FEATURE_FASTRENDER_DM */
-
-#define RGX_CR_EVENT_STATUS_SPFILTER_SIGNAL_UPDATE_SHIFT  (17U)
-#define RGX_CR_EVENT_STATUS_SPFILTER_SIGNAL_UPDATE_CLRMSK (0XFFFDFFFFU)
-#define RGX_CR_EVENT_STATUS_SPFILTER_SIGNAL_UPDATE_EN     (0X00020000U)
-#define RGX_CR_EVENT_STATUS_COMPUTE_BUFFER_STALL_SHIFT    (16U)
-#define RGX_CR_EVENT_STATUS_COMPUTE_BUFFER_STALL_CLRMSK   (0XFFFEFFFFU)
-#define RGX_CR_EVENT_STATUS_COMPUTE_BUFFER_STALL_EN       (0X00010000U)
-#define RGX_CR_EVENT_STATUS_USC_TRIGGER_SHIFT             (15U)
-#define RGX_CR_EVENT_STATUS_USC_TRIGGER_CLRMSK            (0XFFFF7FFFU)
-#define RGX_CR_EVENT_STATUS_USC_TRIGGER_EN                (0X00008000U)
-#define RGX_CR_EVENT_STATUS_ZLS_FINISHED_SHIFT            (14U)
-#define RGX_CR_EVENT_STATUS_ZLS_FINISHED_CLRMSK           (0XFFFFBFFFU)
-#define RGX_CR_EVENT_STATUS_ZLS_FINISHED_EN               (0X00004000U)
-#define RGX_CR_EVENT_STATUS_GPIO_ACK_SHIFT                (13U)
-#define RGX_CR_EVENT_STATUS_GPIO_ACK_CLRMSK               (0XFFFFDFFFU)
-#define RGX_CR_EVENT_STATUS_GPIO_ACK_EN                   (0X00002000U)
-#define RGX_CR_EVENT_STATUS_GPIO_REQ_SHIFT                (12U)
-#define RGX_CR_EVENT_STATUS_GPIO_REQ_CLRMSK               (0XFFFFEFFFU)
-#define RGX_CR_EVENT_STATUS_GPIO_REQ_EN                   (0X00001000U)
-#define RGX_CR_EVENT_STATUS_POWER_ABORT_SHIFT             (11U)
-#define RGX_CR_EVENT_STATUS_POWER_ABORT_CLRMSK            (0XFFFFF7FFU)
-#define RGX_CR_EVENT_STATUS_POWER_ABORT_EN                (0X00000800U)
-#define RGX_CR_EVENT_STATUS_POWER_COMPLETE_SHIFT          (10U)
-#define RGX_CR_EVENT_STATUS_POWER_COMPLETE_CLRMSK         (0XFFFFFBFFU)
-#define RGX_CR_EVENT_STATUS_POWER_COMPLETE_EN             (0X00000400U)
-#define RGX_CR_EVENT_STATUS_MMU_PAGE_FAULT_SHIFT          (9U)
-#define RGX_CR_EVENT_STATUS_MMU_PAGE_FAULT_CLRMSK         (0XFFFFFDFFU)
-#define RGX_CR_EVENT_STATUS_MMU_PAGE_FAULT_EN             (0X00000200U)
-#define RGX_CR_EVENT_STATUS_PM_3D_MEM_FREE_SHIFT          (8U)
-#define RGX_CR_EVENT_STATUS_PM_3D_MEM_FREE_CLRMSK         (0XFFFFFEFFU)
-#define RGX_CR_EVENT_STATUS_PM_3D_MEM_FREE_EN             (0X00000100U)
-#define RGX_CR_EVENT_STATUS_PM_OUT_OF_MEMORY_SHIFT        (7U)
-#define RGX_CR_EVENT_STATUS_PM_OUT_OF_MEMORY_CLRMSK       (0XFFFFFF7FU)
-#define RGX_CR_EVENT_STATUS_PM_OUT_OF_MEMORY_EN           (0X00000080U)
-#define RGX_CR_EVENT_STATUS_TA_TERMINATE_SHIFT            (6U)
-#define RGX_CR_EVENT_STATUS_TA_TERMINATE_CLRMSK           (0XFFFFFFBFU)
-#define RGX_CR_EVENT_STATUS_TA_TERMINATE_EN               (0X00000040U)
-#define RGX_CR_EVENT_STATUS_TA_FINISHED_SHIFT             (5U)
-#define RGX_CR_EVENT_STATUS_TA_FINISHED_CLRMSK            (0XFFFFFFDFU)
-#define RGX_CR_EVENT_STATUS_TA_FINISHED_EN                (0X00000020U)
-#define RGX_CR_EVENT_STATUS_ISP_END_MACROTILE_SHIFT       (4U)
-#define RGX_CR_EVENT_STATUS_ISP_END_MACROTILE_CLRMSK      (0XFFFFFFEFU)
-#define RGX_CR_EVENT_STATUS_ISP_END_MACROTILE_EN          (0X00000010U)
-#define RGX_CR_EVENT_STATUS_PIXELBE_END_RENDER_SHIFT      (3U)
-#define RGX_CR_EVENT_STATUS_PIXELBE_END_RENDER_CLRMSK     (0XFFFFFFF7U)
-#define RGX_CR_EVENT_STATUS_PIXELBE_END_RENDER_EN         (0X00000008U)
-#if defined(RGX_FEATURE_COMPUTE)
-#define RGX_CR_EVENT_STATUS_COMPUTE_FINISHED_SHIFT        (2U)
-#define RGX_CR_EVENT_STATUS_COMPUTE_FINISHED_CLRMSK       (0XFFFFFFFBU)
-#define RGX_CR_EVENT_STATUS_COMPUTE_FINISHED_EN           (0X00000004U)
-#define RGX_CR_EVENT_STATUS_KERNEL_FINISHED_SHIFT         (1U)
-#define RGX_CR_EVENT_STATUS_KERNEL_FINISHED_CLRMSK        (0XFFFFFFFDU)
-#define RGX_CR_EVENT_STATUS_KERNEL_FINISHED_EN            (0X00000002U)
-#endif /* RGX_FEATURE_COMPUTE */
-
-#define RGX_CR_EVENT_STATUS_TLA_COMPLETE_SHIFT            (0U)
-#define RGX_CR_EVENT_STATUS_TLA_COMPLETE_CLRMSK           (0XFFFFFFFEU)
-#define RGX_CR_EVENT_STATUS_TLA_COMPLETE_EN               (0X00000001U)
-#endif /* RGX_FEATURE_SIGNAL_SNOOPING */ 
-
-
-#if !defined(RGX_FEATURE_SIGNAL_SNOOPING)
-/*
-    Register RGX_CR_EVENT_STATUS
-*/
-#define RGX_CR_EVENT_STATUS                               (0x0130U)
+#define RGX_CR_EVENT_STATUS__SIGNALS__MASKFULL            (IMG_UINT64_C(0x00000000E007FFFF))
 #define RGX_CR_EVENT_STATUS_MASKFULL                      (IMG_UINT64_C(0x00000000FFFFFFFF))
-#if defined(RGX_FEATURE_FASTRENDER_DM)
 #define RGX_CR_EVENT_STATUS_TDM_FENCE_FINISHED_SHIFT      (31U)
 #define RGX_CR_EVENT_STATUS_TDM_FENCE_FINISHED_CLRMSK     (0X7FFFFFFFU)
 #define RGX_CR_EVENT_STATUS_TDM_FENCE_FINISHED_EN         (0X80000000U)
 #define RGX_CR_EVENT_STATUS_TDM_BUFFER_STALL_SHIFT        (30U)
 #define RGX_CR_EVENT_STATUS_TDM_BUFFER_STALL_CLRMSK       (0XBFFFFFFFU)
 #define RGX_CR_EVENT_STATUS_TDM_BUFFER_STALL_EN           (0X40000000U)
-#endif /* RGX_FEATURE_FASTRENDER_DM */
-
 #define RGX_CR_EVENT_STATUS_COMPUTE_SIGNAL_FAILURE_SHIFT  (29U)
 #define RGX_CR_EVENT_STATUS_COMPUTE_SIGNAL_FAILURE_CLRMSK (0XDFFFFFFFU)
 #define RGX_CR_EVENT_STATUS_COMPUTE_SIGNAL_FAILURE_EN     (0X20000000U)
-#if defined(RGX_FEATURE_RAY_TRACING)
 #define RGX_CR_EVENT_STATUS_DPX_OUT_OF_MEMORY_SHIFT       (28U)
 #define RGX_CR_EVENT_STATUS_DPX_OUT_OF_MEMORY_CLRMSK      (0XEFFFFFFFU)
 #define RGX_CR_EVENT_STATUS_DPX_OUT_OF_MEMORY_EN          (0X10000000U)
@@ -1553,11 +861,15 @@
 #define RGX_CR_EVENT_STATUS_RDM_FC0_FINISHED_SHIFT        (18U)
 #define RGX_CR_EVENT_STATUS_RDM_FC0_FINISHED_CLRMSK       (0XFFFBFFFFU)
 #define RGX_CR_EVENT_STATUS_RDM_FC0_FINISHED_EN           (0X00040000U)
+#define RGX_CR_EVENT_STATUS__SIGNALS__TDM_CONTEXT_STORE_FINISHED_SHIFT (18U)
+#define RGX_CR_EVENT_STATUS__SIGNALS__TDM_CONTEXT_STORE_FINISHED_CLRMSK (0XFFFBFFFFU)
+#define RGX_CR_EVENT_STATUS__SIGNALS__TDM_CONTEXT_STORE_FINISHED_EN (0X00040000U)
 #define RGX_CR_EVENT_STATUS_SHG_FINISHED_SHIFT            (17U)
 #define RGX_CR_EVENT_STATUS_SHG_FINISHED_CLRMSK           (0XFFFDFFFFU)
 #define RGX_CR_EVENT_STATUS_SHG_FINISHED_EN               (0X00020000U)
-#endif /* RGX_FEATURE_RAY_TRACING */
-
+#define RGX_CR_EVENT_STATUS__SIGNALS__SPFILTER_SIGNAL_UPDATE_SHIFT (17U)
+#define RGX_CR_EVENT_STATUS__SIGNALS__SPFILTER_SIGNAL_UPDATE_CLRMSK (0XFFFDFFFFU)
+#define RGX_CR_EVENT_STATUS__SIGNALS__SPFILTER_SIGNAL_UPDATE_EN (0X00020000U)
 #define RGX_CR_EVENT_STATUS_COMPUTE_BUFFER_STALL_SHIFT    (16U)
 #define RGX_CR_EVENT_STATUS_COMPUTE_BUFFER_STALL_CLRMSK   (0XFFFEFFFFU)
 #define RGX_CR_EVENT_STATUS_COMPUTE_BUFFER_STALL_EN       (0X00010000U)
@@ -1600,19 +912,15 @@
 #define RGX_CR_EVENT_STATUS_PIXELBE_END_RENDER_SHIFT      (3U)
 #define RGX_CR_EVENT_STATUS_PIXELBE_END_RENDER_CLRMSK     (0XFFFFFFF7U)
 #define RGX_CR_EVENT_STATUS_PIXELBE_END_RENDER_EN         (0X00000008U)
-#if defined(RGX_FEATURE_COMPUTE)
 #define RGX_CR_EVENT_STATUS_COMPUTE_FINISHED_SHIFT        (2U)
 #define RGX_CR_EVENT_STATUS_COMPUTE_FINISHED_CLRMSK       (0XFFFFFFFBU)
 #define RGX_CR_EVENT_STATUS_COMPUTE_FINISHED_EN           (0X00000004U)
 #define RGX_CR_EVENT_STATUS_KERNEL_FINISHED_SHIFT         (1U)
 #define RGX_CR_EVENT_STATUS_KERNEL_FINISHED_CLRMSK        (0XFFFFFFFDU)
 #define RGX_CR_EVENT_STATUS_KERNEL_FINISHED_EN            (0X00000002U)
-#endif /* RGX_FEATURE_COMPUTE */
-
 #define RGX_CR_EVENT_STATUS_TLA_COMPLETE_SHIFT            (0U)
 #define RGX_CR_EVENT_STATUS_TLA_COMPLETE_CLRMSK           (0XFFFFFFFEU)
 #define RGX_CR_EVENT_STATUS_TLA_COMPLETE_EN               (0X00000001U)
-#endif /* !defined(RGX_FEATURE_SIGNAL_SNOOPING) */
 
 
 /*
@@ -1786,68 +1094,53 @@
 #define RGX_CR_CDM_CONTEXT_PDS0_CODE_ADDR_ALIGNSIZE       (16U)
 
 
-#if defined(RGX_FEATURE_PDS_TEMPSIZE8)
 /*
     Register RGX_CR_CDM_CONTEXT_PDS1
 */
 #define RGX_CR_CDM_CONTEXT_PDS1                           (0x04B0U)
-#define RGX_CR_CDM_CONTEXT_PDS1_MASKFULL                  (IMG_UINT64_C(0x000000007FFFFFFF))
-#define RGX_CR_CDM_CONTEXT_PDS1_PDS_SEQ_DEP_SHIFT         (30U)
-#define RGX_CR_CDM_CONTEXT_PDS1_PDS_SEQ_DEP_CLRMSK        (0XBFFFFFFFU)
-#define RGX_CR_CDM_CONTEXT_PDS1_PDS_SEQ_DEP_EN            (0X40000000U)
-#define RGX_CR_CDM_CONTEXT_PDS1_USC_SEQ_DEP_SHIFT         (29U)
-#define RGX_CR_CDM_CONTEXT_PDS1_USC_SEQ_DEP_CLRMSK        (0XDFFFFFFFU)
-#define RGX_CR_CDM_CONTEXT_PDS1_USC_SEQ_DEP_EN            (0X20000000U)
-#define RGX_CR_CDM_CONTEXT_PDS1_TARGET_SHIFT              (28U)
-#define RGX_CR_CDM_CONTEXT_PDS1_TARGET_CLRMSK             (0XEFFFFFFFU)
-#define RGX_CR_CDM_CONTEXT_PDS1_TARGET_EN                 (0X10000000U)
-#define RGX_CR_CDM_CONTEXT_PDS1_UNIFIED_SIZE_SHIFT        (22U)
-#define RGX_CR_CDM_CONTEXT_PDS1_UNIFIED_SIZE_CLRMSK       (0XF03FFFFFU)
-#define RGX_CR_CDM_CONTEXT_PDS1_COMMON_SHARED_SHIFT       (21U)
-#define RGX_CR_CDM_CONTEXT_PDS1_COMMON_SHARED_CLRMSK      (0XFFDFFFFFU)
-#define RGX_CR_CDM_CONTEXT_PDS1_COMMON_SHARED_EN          (0X00200000U)
-#define RGX_CR_CDM_CONTEXT_PDS1_COMMON_SIZE_SHIFT         (12U)
-#define RGX_CR_CDM_CONTEXT_PDS1_COMMON_SIZE_CLRMSK        (0XFFE00FFFU)
-#define RGX_CR_CDM_CONTEXT_PDS1_TEMP_SIZE_SHIFT           (7U)
-#define RGX_CR_CDM_CONTEXT_PDS1_TEMP_SIZE_CLRMSK          (0XFFFFF07FU)
-#define RGX_CR_CDM_CONTEXT_PDS1_DATA_SIZE_SHIFT           (1U)
-#define RGX_CR_CDM_CONTEXT_PDS1_DATA_SIZE_CLRMSK          (0XFFFFFF81U)
-#define RGX_CR_CDM_CONTEXT_PDS1_FENCE_SHIFT               (0U)
-#define RGX_CR_CDM_CONTEXT_PDS1_FENCE_CLRMSK              (0XFFFFFFFEU)
-#define RGX_CR_CDM_CONTEXT_PDS1_FENCE_EN                  (0X00000001U)
-#endif /* RGX_FEATURE_PDS_TEMPSIZE8 */ 
-
-
-#if !defined(RGX_FEATURE_PDS_TEMPSIZE8)
-/*
-    Register RGX_CR_CDM_CONTEXT_PDS1
-*/
-#define RGX_CR_CDM_CONTEXT_PDS1                           (0x04B0U)
+#define RGX_CR_CDM_CONTEXT_PDS1__TEMPSIZE8__MASKFULL      (IMG_UINT64_C(0x000000007FFFFFFF))
 #define RGX_CR_CDM_CONTEXT_PDS1_MASKFULL                  (IMG_UINT64_C(0x000000003FFFFFFF))
+#define RGX_CR_CDM_CONTEXT_PDS1__TEMPSIZE8__PDS_SEQ_DEP_SHIFT (30U)
+#define RGX_CR_CDM_CONTEXT_PDS1__TEMPSIZE8__PDS_SEQ_DEP_CLRMSK (0XBFFFFFFFU)
+#define RGX_CR_CDM_CONTEXT_PDS1__TEMPSIZE8__PDS_SEQ_DEP_EN (0X40000000U)
 #define RGX_CR_CDM_CONTEXT_PDS1_PDS_SEQ_DEP_SHIFT         (29U)
 #define RGX_CR_CDM_CONTEXT_PDS1_PDS_SEQ_DEP_CLRMSK        (0XDFFFFFFFU)
 #define RGX_CR_CDM_CONTEXT_PDS1_PDS_SEQ_DEP_EN            (0X20000000U)
+#define RGX_CR_CDM_CONTEXT_PDS1__TEMPSIZE8__USC_SEQ_DEP_SHIFT (29U)
+#define RGX_CR_CDM_CONTEXT_PDS1__TEMPSIZE8__USC_SEQ_DEP_CLRMSK (0XDFFFFFFFU)
+#define RGX_CR_CDM_CONTEXT_PDS1__TEMPSIZE8__USC_SEQ_DEP_EN (0X20000000U)
 #define RGX_CR_CDM_CONTEXT_PDS1_USC_SEQ_DEP_SHIFT         (28U)
 #define RGX_CR_CDM_CONTEXT_PDS1_USC_SEQ_DEP_CLRMSK        (0XEFFFFFFFU)
 #define RGX_CR_CDM_CONTEXT_PDS1_USC_SEQ_DEP_EN            (0X10000000U)
+#define RGX_CR_CDM_CONTEXT_PDS1__TEMPSIZE8__TARGET_SHIFT  (28U)
+#define RGX_CR_CDM_CONTEXT_PDS1__TEMPSIZE8__TARGET_CLRMSK (0XEFFFFFFFU)
+#define RGX_CR_CDM_CONTEXT_PDS1__TEMPSIZE8__TARGET_EN     (0X10000000U)
 #define RGX_CR_CDM_CONTEXT_PDS1_TARGET_SHIFT              (27U)
 #define RGX_CR_CDM_CONTEXT_PDS1_TARGET_CLRMSK             (0XF7FFFFFFU)
 #define RGX_CR_CDM_CONTEXT_PDS1_TARGET_EN                 (0X08000000U)
+#define RGX_CR_CDM_CONTEXT_PDS1__TEMPSIZE8__UNIFIED_SIZE_SHIFT (22U)
+#define RGX_CR_CDM_CONTEXT_PDS1__TEMPSIZE8__UNIFIED_SIZE_CLRMSK (0XF03FFFFFU)
 #define RGX_CR_CDM_CONTEXT_PDS1_UNIFIED_SIZE_SHIFT        (21U)
 #define RGX_CR_CDM_CONTEXT_PDS1_UNIFIED_SIZE_CLRMSK       (0XF81FFFFFU)
+#define RGX_CR_CDM_CONTEXT_PDS1__TEMPSIZE8__COMMON_SHARED_SHIFT (21U)
+#define RGX_CR_CDM_CONTEXT_PDS1__TEMPSIZE8__COMMON_SHARED_CLRMSK (0XFFDFFFFFU)
+#define RGX_CR_CDM_CONTEXT_PDS1__TEMPSIZE8__COMMON_SHARED_EN (0X00200000U)
 #define RGX_CR_CDM_CONTEXT_PDS1_COMMON_SHARED_SHIFT       (20U)
 #define RGX_CR_CDM_CONTEXT_PDS1_COMMON_SHARED_CLRMSK      (0XFFEFFFFFU)
 #define RGX_CR_CDM_CONTEXT_PDS1_COMMON_SHARED_EN          (0X00100000U)
+#define RGX_CR_CDM_CONTEXT_PDS1__TEMPSIZE8__COMMON_SIZE_SHIFT (12U)
+#define RGX_CR_CDM_CONTEXT_PDS1__TEMPSIZE8__COMMON_SIZE_CLRMSK (0XFFE00FFFU)
 #define RGX_CR_CDM_CONTEXT_PDS1_COMMON_SIZE_SHIFT         (11U)
 #define RGX_CR_CDM_CONTEXT_PDS1_COMMON_SIZE_CLRMSK        (0XFFF007FFU)
 #define RGX_CR_CDM_CONTEXT_PDS1_TEMP_SIZE_SHIFT           (7U)
 #define RGX_CR_CDM_CONTEXT_PDS1_TEMP_SIZE_CLRMSK          (0XFFFFF87FU)
+#define RGX_CR_CDM_CONTEXT_PDS1__TEMPSIZE8__TEMP_SIZE_SHIFT (7U)
+#define RGX_CR_CDM_CONTEXT_PDS1__TEMPSIZE8__TEMP_SIZE_CLRMSK (0XFFFFF07FU)
 #define RGX_CR_CDM_CONTEXT_PDS1_DATA_SIZE_SHIFT           (1U)
 #define RGX_CR_CDM_CONTEXT_PDS1_DATA_SIZE_CLRMSK          (0XFFFFFF81U)
 #define RGX_CR_CDM_CONTEXT_PDS1_FENCE_SHIFT               (0U)
 #define RGX_CR_CDM_CONTEXT_PDS1_FENCE_CLRMSK              (0XFFFFFFFEU)
 #define RGX_CR_CDM_CONTEXT_PDS1_FENCE_EN                  (0X00000001U)
-#endif /* !defined(RGX_FEATURE_PDS_TEMPSIZE8) */
 
 
 /*
@@ -1865,68 +1158,53 @@
 #define RGX_CR_CDM_TERMINATE_PDS_CODE_ADDR_ALIGNSIZE      (16U)
 
 
-#if defined(RGX_FEATURE_PDS_TEMPSIZE8)
 /*
     Register RGX_CR_CDM_TERMINATE_PDS1
 */
 #define RGX_CR_CDM_TERMINATE_PDS1                         (0x04C0U)
-#define RGX_CR_CDM_TERMINATE_PDS1_MASKFULL                (IMG_UINT64_C(0x000000007FFFFFFF))
-#define RGX_CR_CDM_TERMINATE_PDS1_PDS_SEQ_DEP_SHIFT       (30U)
-#define RGX_CR_CDM_TERMINATE_PDS1_PDS_SEQ_DEP_CLRMSK      (0XBFFFFFFFU)
-#define RGX_CR_CDM_TERMINATE_PDS1_PDS_SEQ_DEP_EN          (0X40000000U)
-#define RGX_CR_CDM_TERMINATE_PDS1_USC_SEQ_DEP_SHIFT       (29U)
-#define RGX_CR_CDM_TERMINATE_PDS1_USC_SEQ_DEP_CLRMSK      (0XDFFFFFFFU)
-#define RGX_CR_CDM_TERMINATE_PDS1_USC_SEQ_DEP_EN          (0X20000000U)
-#define RGX_CR_CDM_TERMINATE_PDS1_TARGET_SHIFT            (28U)
-#define RGX_CR_CDM_TERMINATE_PDS1_TARGET_CLRMSK           (0XEFFFFFFFU)
-#define RGX_CR_CDM_TERMINATE_PDS1_TARGET_EN               (0X10000000U)
-#define RGX_CR_CDM_TERMINATE_PDS1_UNIFIED_SIZE_SHIFT      (22U)
-#define RGX_CR_CDM_TERMINATE_PDS1_UNIFIED_SIZE_CLRMSK     (0XF03FFFFFU)
-#define RGX_CR_CDM_TERMINATE_PDS1_COMMON_SHARED_SHIFT     (21U)
-#define RGX_CR_CDM_TERMINATE_PDS1_COMMON_SHARED_CLRMSK    (0XFFDFFFFFU)
-#define RGX_CR_CDM_TERMINATE_PDS1_COMMON_SHARED_EN        (0X00200000U)
-#define RGX_CR_CDM_TERMINATE_PDS1_COMMON_SIZE_SHIFT       (12U)
-#define RGX_CR_CDM_TERMINATE_PDS1_COMMON_SIZE_CLRMSK      (0XFFE00FFFU)
-#define RGX_CR_CDM_TERMINATE_PDS1_TEMP_SIZE_SHIFT         (7U)
-#define RGX_CR_CDM_TERMINATE_PDS1_TEMP_SIZE_CLRMSK        (0XFFFFF07FU)
-#define RGX_CR_CDM_TERMINATE_PDS1_DATA_SIZE_SHIFT         (1U)
-#define RGX_CR_CDM_TERMINATE_PDS1_DATA_SIZE_CLRMSK        (0XFFFFFF81U)
-#define RGX_CR_CDM_TERMINATE_PDS1_FENCE_SHIFT             (0U)
-#define RGX_CR_CDM_TERMINATE_PDS1_FENCE_CLRMSK            (0XFFFFFFFEU)
-#define RGX_CR_CDM_TERMINATE_PDS1_FENCE_EN                (0X00000001U)
-#endif /* RGX_FEATURE_PDS_TEMPSIZE8 */ 
-
-
-#if !defined(RGX_FEATURE_PDS_TEMPSIZE8)
-/*
-    Register RGX_CR_CDM_TERMINATE_PDS1
-*/
-#define RGX_CR_CDM_TERMINATE_PDS1                         (0x04C0U)
+#define RGX_CR_CDM_TERMINATE_PDS1__TEMPSIZE8__MASKFULL    (IMG_UINT64_C(0x000000007FFFFFFF))
 #define RGX_CR_CDM_TERMINATE_PDS1_MASKFULL                (IMG_UINT64_C(0x000000003FFFFFFF))
+#define RGX_CR_CDM_TERMINATE_PDS1__TEMPSIZE8__PDS_SEQ_DEP_SHIFT (30U)
+#define RGX_CR_CDM_TERMINATE_PDS1__TEMPSIZE8__PDS_SEQ_DEP_CLRMSK (0XBFFFFFFFU)
+#define RGX_CR_CDM_TERMINATE_PDS1__TEMPSIZE8__PDS_SEQ_DEP_EN (0X40000000U)
 #define RGX_CR_CDM_TERMINATE_PDS1_PDS_SEQ_DEP_SHIFT       (29U)
 #define RGX_CR_CDM_TERMINATE_PDS1_PDS_SEQ_DEP_CLRMSK      (0XDFFFFFFFU)
 #define RGX_CR_CDM_TERMINATE_PDS1_PDS_SEQ_DEP_EN          (0X20000000U)
+#define RGX_CR_CDM_TERMINATE_PDS1__TEMPSIZE8__USC_SEQ_DEP_SHIFT (29U)
+#define RGX_CR_CDM_TERMINATE_PDS1__TEMPSIZE8__USC_SEQ_DEP_CLRMSK (0XDFFFFFFFU)
+#define RGX_CR_CDM_TERMINATE_PDS1__TEMPSIZE8__USC_SEQ_DEP_EN (0X20000000U)
 #define RGX_CR_CDM_TERMINATE_PDS1_USC_SEQ_DEP_SHIFT       (28U)
 #define RGX_CR_CDM_TERMINATE_PDS1_USC_SEQ_DEP_CLRMSK      (0XEFFFFFFFU)
 #define RGX_CR_CDM_TERMINATE_PDS1_USC_SEQ_DEP_EN          (0X10000000U)
+#define RGX_CR_CDM_TERMINATE_PDS1__TEMPSIZE8__TARGET_SHIFT (28U)
+#define RGX_CR_CDM_TERMINATE_PDS1__TEMPSIZE8__TARGET_CLRMSK (0XEFFFFFFFU)
+#define RGX_CR_CDM_TERMINATE_PDS1__TEMPSIZE8__TARGET_EN   (0X10000000U)
 #define RGX_CR_CDM_TERMINATE_PDS1_TARGET_SHIFT            (27U)
 #define RGX_CR_CDM_TERMINATE_PDS1_TARGET_CLRMSK           (0XF7FFFFFFU)
 #define RGX_CR_CDM_TERMINATE_PDS1_TARGET_EN               (0X08000000U)
+#define RGX_CR_CDM_TERMINATE_PDS1__TEMPSIZE8__UNIFIED_SIZE_SHIFT (22U)
+#define RGX_CR_CDM_TERMINATE_PDS1__TEMPSIZE8__UNIFIED_SIZE_CLRMSK (0XF03FFFFFU)
 #define RGX_CR_CDM_TERMINATE_PDS1_UNIFIED_SIZE_SHIFT      (21U)
 #define RGX_CR_CDM_TERMINATE_PDS1_UNIFIED_SIZE_CLRMSK     (0XF81FFFFFU)
+#define RGX_CR_CDM_TERMINATE_PDS1__TEMPSIZE8__COMMON_SHARED_SHIFT (21U)
+#define RGX_CR_CDM_TERMINATE_PDS1__TEMPSIZE8__COMMON_SHARED_CLRMSK (0XFFDFFFFFU)
+#define RGX_CR_CDM_TERMINATE_PDS1__TEMPSIZE8__COMMON_SHARED_EN (0X00200000U)
 #define RGX_CR_CDM_TERMINATE_PDS1_COMMON_SHARED_SHIFT     (20U)
 #define RGX_CR_CDM_TERMINATE_PDS1_COMMON_SHARED_CLRMSK    (0XFFEFFFFFU)
 #define RGX_CR_CDM_TERMINATE_PDS1_COMMON_SHARED_EN        (0X00100000U)
+#define RGX_CR_CDM_TERMINATE_PDS1__TEMPSIZE8__COMMON_SIZE_SHIFT (12U)
+#define RGX_CR_CDM_TERMINATE_PDS1__TEMPSIZE8__COMMON_SIZE_CLRMSK (0XFFE00FFFU)
 #define RGX_CR_CDM_TERMINATE_PDS1_COMMON_SIZE_SHIFT       (11U)
 #define RGX_CR_CDM_TERMINATE_PDS1_COMMON_SIZE_CLRMSK      (0XFFF007FFU)
 #define RGX_CR_CDM_TERMINATE_PDS1_TEMP_SIZE_SHIFT         (7U)
 #define RGX_CR_CDM_TERMINATE_PDS1_TEMP_SIZE_CLRMSK        (0XFFFFF87FU)
+#define RGX_CR_CDM_TERMINATE_PDS1__TEMPSIZE8__TEMP_SIZE_SHIFT (7U)
+#define RGX_CR_CDM_TERMINATE_PDS1__TEMPSIZE8__TEMP_SIZE_CLRMSK (0XFFFFF07FU)
 #define RGX_CR_CDM_TERMINATE_PDS1_DATA_SIZE_SHIFT         (1U)
 #define RGX_CR_CDM_TERMINATE_PDS1_DATA_SIZE_CLRMSK        (0XFFFFFF81U)
 #define RGX_CR_CDM_TERMINATE_PDS1_FENCE_SHIFT             (0U)
 #define RGX_CR_CDM_TERMINATE_PDS1_FENCE_CLRMSK            (0XFFFFFFFEU)
 #define RGX_CR_CDM_TERMINATE_PDS1_FENCE_EN                (0X00000001U)
-#endif /* !defined(RGX_FEATURE_PDS_TEMPSIZE8) */
 
 
 /*
@@ -1944,79 +1222,72 @@
 #define RGX_CR_CDM_CONTEXT_LOAD_PDS0_CODE_ADDR_ALIGNSIZE  (16U)
 
 
-#if defined(RGX_FEATURE_PDS_TEMPSIZE8)
 /*
     Register RGX_CR_CDM_CONTEXT_LOAD_PDS1
 */
 #define RGX_CR_CDM_CONTEXT_LOAD_PDS1                      (0x04E0U)
-#define RGX_CR_CDM_CONTEXT_LOAD_PDS1_MASKFULL             (IMG_UINT64_C(0x000000007FFFFFFF))
-#define RGX_CR_CDM_CONTEXT_LOAD_PDS1_PDS_SEQ_DEP_SHIFT    (30U)
-#define RGX_CR_CDM_CONTEXT_LOAD_PDS1_PDS_SEQ_DEP_CLRMSK   (0XBFFFFFFFU)
-#define RGX_CR_CDM_CONTEXT_LOAD_PDS1_PDS_SEQ_DEP_EN       (0X40000000U)
-#define RGX_CR_CDM_CONTEXT_LOAD_PDS1_USC_SEQ_DEP_SHIFT    (29U)
-#define RGX_CR_CDM_CONTEXT_LOAD_PDS1_USC_SEQ_DEP_CLRMSK   (0XDFFFFFFFU)
-#define RGX_CR_CDM_CONTEXT_LOAD_PDS1_USC_SEQ_DEP_EN       (0X20000000U)
-#define RGX_CR_CDM_CONTEXT_LOAD_PDS1_TARGET_SHIFT         (28U)
-#define RGX_CR_CDM_CONTEXT_LOAD_PDS1_TARGET_CLRMSK        (0XEFFFFFFFU)
-#define RGX_CR_CDM_CONTEXT_LOAD_PDS1_TARGET_EN            (0X10000000U)
-#define RGX_CR_CDM_CONTEXT_LOAD_PDS1_UNIFIED_SIZE_SHIFT   (22U)
-#define RGX_CR_CDM_CONTEXT_LOAD_PDS1_UNIFIED_SIZE_CLRMSK  (0XF03FFFFFU)
-#define RGX_CR_CDM_CONTEXT_LOAD_PDS1_COMMON_SHARED_SHIFT  (21U)
-#define RGX_CR_CDM_CONTEXT_LOAD_PDS1_COMMON_SHARED_CLRMSK (0XFFDFFFFFU)
-#define RGX_CR_CDM_CONTEXT_LOAD_PDS1_COMMON_SHARED_EN     (0X00200000U)
-#define RGX_CR_CDM_CONTEXT_LOAD_PDS1_COMMON_SIZE_SHIFT    (12U)
-#define RGX_CR_CDM_CONTEXT_LOAD_PDS1_COMMON_SIZE_CLRMSK   (0XFFE00FFFU)
-#define RGX_CR_CDM_CONTEXT_LOAD_PDS1_TEMP_SIZE_SHIFT      (7U)
-#define RGX_CR_CDM_CONTEXT_LOAD_PDS1_TEMP_SIZE_CLRMSK     (0XFFFFF07FU)
-#define RGX_CR_CDM_CONTEXT_LOAD_PDS1_DATA_SIZE_SHIFT      (1U)
-#define RGX_CR_CDM_CONTEXT_LOAD_PDS1_DATA_SIZE_CLRMSK     (0XFFFFFF81U)
-#define RGX_CR_CDM_CONTEXT_LOAD_PDS1_FENCE_SHIFT          (0U)
-#define RGX_CR_CDM_CONTEXT_LOAD_PDS1_FENCE_CLRMSK         (0XFFFFFFFEU)
-#define RGX_CR_CDM_CONTEXT_LOAD_PDS1_FENCE_EN             (0X00000001U)
-#endif /* RGX_FEATURE_PDS_TEMPSIZE8 */ 
-
-
-#if !defined(RGX_FEATURE_PDS_TEMPSIZE8)
-/*
-    Register RGX_CR_CDM_CONTEXT_LOAD_PDS1
-*/
-#define RGX_CR_CDM_CONTEXT_LOAD_PDS1                      (0x04E0U)
+#define RGX_CR_CDM_CONTEXT_LOAD_PDS1__TEMPSIZE8__MASKFULL (IMG_UINT64_C(0x000000007FFFFFFF))
 #define RGX_CR_CDM_CONTEXT_LOAD_PDS1_MASKFULL             (IMG_UINT64_C(0x000000003FFFFFFF))
+#define RGX_CR_CDM_CONTEXT_LOAD_PDS1__TEMPSIZE8__PDS_SEQ_DEP_SHIFT (30U)
+#define RGX_CR_CDM_CONTEXT_LOAD_PDS1__TEMPSIZE8__PDS_SEQ_DEP_CLRMSK (0XBFFFFFFFU)
+#define RGX_CR_CDM_CONTEXT_LOAD_PDS1__TEMPSIZE8__PDS_SEQ_DEP_EN (0X40000000U)
 #define RGX_CR_CDM_CONTEXT_LOAD_PDS1_PDS_SEQ_DEP_SHIFT    (29U)
 #define RGX_CR_CDM_CONTEXT_LOAD_PDS1_PDS_SEQ_DEP_CLRMSK   (0XDFFFFFFFU)
 #define RGX_CR_CDM_CONTEXT_LOAD_PDS1_PDS_SEQ_DEP_EN       (0X20000000U)
+#define RGX_CR_CDM_CONTEXT_LOAD_PDS1__TEMPSIZE8__USC_SEQ_DEP_SHIFT (29U)
+#define RGX_CR_CDM_CONTEXT_LOAD_PDS1__TEMPSIZE8__USC_SEQ_DEP_CLRMSK (0XDFFFFFFFU)
+#define RGX_CR_CDM_CONTEXT_LOAD_PDS1__TEMPSIZE8__USC_SEQ_DEP_EN (0X20000000U)
 #define RGX_CR_CDM_CONTEXT_LOAD_PDS1_USC_SEQ_DEP_SHIFT    (28U)
 #define RGX_CR_CDM_CONTEXT_LOAD_PDS1_USC_SEQ_DEP_CLRMSK   (0XEFFFFFFFU)
 #define RGX_CR_CDM_CONTEXT_LOAD_PDS1_USC_SEQ_DEP_EN       (0X10000000U)
+#define RGX_CR_CDM_CONTEXT_LOAD_PDS1__TEMPSIZE8__TARGET_SHIFT (28U)
+#define RGX_CR_CDM_CONTEXT_LOAD_PDS1__TEMPSIZE8__TARGET_CLRMSK (0XEFFFFFFFU)
+#define RGX_CR_CDM_CONTEXT_LOAD_PDS1__TEMPSIZE8__TARGET_EN (0X10000000U)
 #define RGX_CR_CDM_CONTEXT_LOAD_PDS1_TARGET_SHIFT         (27U)
 #define RGX_CR_CDM_CONTEXT_LOAD_PDS1_TARGET_CLRMSK        (0XF7FFFFFFU)
 #define RGX_CR_CDM_CONTEXT_LOAD_PDS1_TARGET_EN            (0X08000000U)
+#define RGX_CR_CDM_CONTEXT_LOAD_PDS1__TEMPSIZE8__UNIFIED_SIZE_SHIFT (22U)
+#define RGX_CR_CDM_CONTEXT_LOAD_PDS1__TEMPSIZE8__UNIFIED_SIZE_CLRMSK (0XF03FFFFFU)
 #define RGX_CR_CDM_CONTEXT_LOAD_PDS1_UNIFIED_SIZE_SHIFT   (21U)
 #define RGX_CR_CDM_CONTEXT_LOAD_PDS1_UNIFIED_SIZE_CLRMSK  (0XF81FFFFFU)
+#define RGX_CR_CDM_CONTEXT_LOAD_PDS1__TEMPSIZE8__COMMON_SHARED_SHIFT (21U)
+#define RGX_CR_CDM_CONTEXT_LOAD_PDS1__TEMPSIZE8__COMMON_SHARED_CLRMSK (0XFFDFFFFFU)
+#define RGX_CR_CDM_CONTEXT_LOAD_PDS1__TEMPSIZE8__COMMON_SHARED_EN (0X00200000U)
 #define RGX_CR_CDM_CONTEXT_LOAD_PDS1_COMMON_SHARED_SHIFT  (20U)
 #define RGX_CR_CDM_CONTEXT_LOAD_PDS1_COMMON_SHARED_CLRMSK (0XFFEFFFFFU)
 #define RGX_CR_CDM_CONTEXT_LOAD_PDS1_COMMON_SHARED_EN     (0X00100000U)
+#define RGX_CR_CDM_CONTEXT_LOAD_PDS1__TEMPSIZE8__COMMON_SIZE_SHIFT (12U)
+#define RGX_CR_CDM_CONTEXT_LOAD_PDS1__TEMPSIZE8__COMMON_SIZE_CLRMSK (0XFFE00FFFU)
 #define RGX_CR_CDM_CONTEXT_LOAD_PDS1_COMMON_SIZE_SHIFT    (11U)
 #define RGX_CR_CDM_CONTEXT_LOAD_PDS1_COMMON_SIZE_CLRMSK   (0XFFF007FFU)
 #define RGX_CR_CDM_CONTEXT_LOAD_PDS1_TEMP_SIZE_SHIFT      (7U)
 #define RGX_CR_CDM_CONTEXT_LOAD_PDS1_TEMP_SIZE_CLRMSK     (0XFFFFF87FU)
+#define RGX_CR_CDM_CONTEXT_LOAD_PDS1__TEMPSIZE8__TEMP_SIZE_SHIFT (7U)
+#define RGX_CR_CDM_CONTEXT_LOAD_PDS1__TEMPSIZE8__TEMP_SIZE_CLRMSK (0XFFFFF07FU)
 #define RGX_CR_CDM_CONTEXT_LOAD_PDS1_DATA_SIZE_SHIFT      (1U)
 #define RGX_CR_CDM_CONTEXT_LOAD_PDS1_DATA_SIZE_CLRMSK     (0XFFFFFF81U)
 #define RGX_CR_CDM_CONTEXT_LOAD_PDS1_FENCE_SHIFT          (0U)
 #define RGX_CR_CDM_CONTEXT_LOAD_PDS1_FENCE_CLRMSK         (0XFFFFFFFEU)
 #define RGX_CR_CDM_CONTEXT_LOAD_PDS1_FENCE_EN             (0X00000001U)
-#endif /* !defined(RGX_FEATURE_PDS_TEMPSIZE8) */
 
 
 /*
     Register RGX_CR_MIPS_WRAPPER_CONFIG
 */
 #define RGX_CR_MIPS_WRAPPER_CONFIG                        (0x0810U)
-#define RGX_CR_MIPS_WRAPPER_CONFIG_MASKFULL               (IMG_UINT64_C(0x000000000001FFFF))
+#define RGX_CR_MIPS_WRAPPER_CONFIG_MASKFULL               (IMG_UINT64_C(0x000000010F01FFFF))
+#define RGX_CR_MIPS_WRAPPER_CONFIG_L2_CACHE_OFF_SHIFT     (32U)
+#define RGX_CR_MIPS_WRAPPER_CONFIG_L2_CACHE_OFF_CLRMSK    (IMG_UINT64_C(0XFFFFFFFEFFFFFFFF))
+#define RGX_CR_MIPS_WRAPPER_CONFIG_L2_CACHE_OFF_EN        (IMG_UINT64_C(0X0000000100000000))
+#define RGX_CR_MIPS_WRAPPER_CONFIG_OS_ID_SHIFT            (25U)
+#define RGX_CR_MIPS_WRAPPER_CONFIG_OS_ID_CLRMSK           (IMG_UINT64_C(0XFFFFFFFFF1FFFFFF))
+#define RGX_CR_MIPS_WRAPPER_CONFIG_TRUSTED_SHIFT          (24U)
+#define RGX_CR_MIPS_WRAPPER_CONFIG_TRUSTED_CLRMSK         (IMG_UINT64_C(0XFFFFFFFFFEFFFFFF))
+#define RGX_CR_MIPS_WRAPPER_CONFIG_TRUSTED_EN             (IMG_UINT64_C(0X0000000001000000))
 #define RGX_CR_MIPS_WRAPPER_CONFIG_BOOT_ISA_MODE_SHIFT    (16U)
 #define RGX_CR_MIPS_WRAPPER_CONFIG_BOOT_ISA_MODE_CLRMSK   (IMG_UINT64_C(0XFFFFFFFFFFFEFFFF))
-#define RGX_CR_MIPS_WRAPPER_CONFIG_BOOT_ISA_MODE_MIPS32   (IMG_UINT64_C(0000000000000000))
-#define RGX_CR_MIPS_WRAPPER_CONFIG_BOOT_ISA_MODE_MICROMIPS (IMG_UINT64_C(0x0000000000010000))
+#define RGX_CR_MIPS_WRAPPER_CONFIG_BOOT_ISA_MODE_MIPS32   (IMG_UINT64_C(0000000000000000))  
+#define RGX_CR_MIPS_WRAPPER_CONFIG_BOOT_ISA_MODE_MICROMIPS (IMG_UINT64_C(0x0000000000010000))  
 #define RGX_CR_MIPS_WRAPPER_CONFIG_REGBANK_BASE_ADDR_SHIFT (0U)
 #define RGX_CR_MIPS_WRAPPER_CONFIG_REGBANK_BASE_ADDR_CLRMSK (IMG_UINT64_C(0XFFFFFFFFFFFF0000))
 
@@ -2037,9 +1308,14 @@
     Register RGX_CR_MIPS_ADDR_REMAP1_CONFIG2
 */
 #define RGX_CR_MIPS_ADDR_REMAP1_CONFIG2                   (0x0820U)
-#define RGX_CR_MIPS_ADDR_REMAP1_CONFIG2_MASKFULL          (IMG_UINT64_C(0x00000000FFFFF01F))
+#define RGX_CR_MIPS_ADDR_REMAP1_CONFIG2_MASKFULL          (IMG_UINT64_C(0x00000000FFFFF1FF))
 #define RGX_CR_MIPS_ADDR_REMAP1_CONFIG2_ADDR_OUT_SHIFT    (12U)
 #define RGX_CR_MIPS_ADDR_REMAP1_CONFIG2_ADDR_OUT_CLRMSK   (IMG_UINT64_C(0XFFFFFFFF00000FFF))
+#define RGX_CR_MIPS_ADDR_REMAP1_CONFIG2_OS_ID_SHIFT       (6U)
+#define RGX_CR_MIPS_ADDR_REMAP1_CONFIG2_OS_ID_CLRMSK      (IMG_UINT64_C(0XFFFFFFFFFFFFFE3F))
+#define RGX_CR_MIPS_ADDR_REMAP1_CONFIG2_TRUSTED_SHIFT     (5U)
+#define RGX_CR_MIPS_ADDR_REMAP1_CONFIG2_TRUSTED_CLRMSK    (IMG_UINT64_C(0XFFFFFFFFFFFFFFDF))
+#define RGX_CR_MIPS_ADDR_REMAP1_CONFIG2_TRUSTED_EN        (IMG_UINT64_C(0X0000000000000020))
 #define RGX_CR_MIPS_ADDR_REMAP1_CONFIG2_REGION_SIZE_POW2_SHIFT (0U)
 #define RGX_CR_MIPS_ADDR_REMAP1_CONFIG2_REGION_SIZE_POW2_CLRMSK (IMG_UINT64_C(0XFFFFFFFFFFFFFFE0))
 
@@ -2060,9 +1336,14 @@
     Register RGX_CR_MIPS_ADDR_REMAP2_CONFIG2
 */
 #define RGX_CR_MIPS_ADDR_REMAP2_CONFIG2                   (0x0830U)
-#define RGX_CR_MIPS_ADDR_REMAP2_CONFIG2_MASKFULL          (IMG_UINT64_C(0x00000000FFFFF01F))
+#define RGX_CR_MIPS_ADDR_REMAP2_CONFIG2_MASKFULL          (IMG_UINT64_C(0x00000000FFFFF1FF))
 #define RGX_CR_MIPS_ADDR_REMAP2_CONFIG2_ADDR_OUT_SHIFT    (12U)
 #define RGX_CR_MIPS_ADDR_REMAP2_CONFIG2_ADDR_OUT_CLRMSK   (IMG_UINT64_C(0XFFFFFFFF00000FFF))
+#define RGX_CR_MIPS_ADDR_REMAP2_CONFIG2_OS_ID_SHIFT       (6U)
+#define RGX_CR_MIPS_ADDR_REMAP2_CONFIG2_OS_ID_CLRMSK      (IMG_UINT64_C(0XFFFFFFFFFFFFFE3F))
+#define RGX_CR_MIPS_ADDR_REMAP2_CONFIG2_TRUSTED_SHIFT     (5U)
+#define RGX_CR_MIPS_ADDR_REMAP2_CONFIG2_TRUSTED_CLRMSK    (IMG_UINT64_C(0XFFFFFFFFFFFFFFDF))
+#define RGX_CR_MIPS_ADDR_REMAP2_CONFIG2_TRUSTED_EN        (IMG_UINT64_C(0X0000000000000020))
 #define RGX_CR_MIPS_ADDR_REMAP2_CONFIG2_REGION_SIZE_POW2_SHIFT (0U)
 #define RGX_CR_MIPS_ADDR_REMAP2_CONFIG2_REGION_SIZE_POW2_CLRMSK (IMG_UINT64_C(0XFFFFFFFFFFFFFFE0))
 
@@ -2083,14 +1364,75 @@
     Register RGX_CR_MIPS_ADDR_REMAP3_CONFIG2
 */
 #define RGX_CR_MIPS_ADDR_REMAP3_CONFIG2                   (0x0840U)
-#define RGX_CR_MIPS_ADDR_REMAP3_CONFIG2_MASKFULL          (IMG_UINT64_C(0x00000000FFFFF01F))
+#define RGX_CR_MIPS_ADDR_REMAP3_CONFIG2_MASKFULL          (IMG_UINT64_C(0x00000000FFFFF1FF))
 #define RGX_CR_MIPS_ADDR_REMAP3_CONFIG2_ADDR_OUT_SHIFT    (12U)
 #define RGX_CR_MIPS_ADDR_REMAP3_CONFIG2_ADDR_OUT_CLRMSK   (IMG_UINT64_C(0XFFFFFFFF00000FFF))
+#define RGX_CR_MIPS_ADDR_REMAP3_CONFIG2_OS_ID_SHIFT       (6U)
+#define RGX_CR_MIPS_ADDR_REMAP3_CONFIG2_OS_ID_CLRMSK      (IMG_UINT64_C(0XFFFFFFFFFFFFFE3F))
+#define RGX_CR_MIPS_ADDR_REMAP3_CONFIG2_TRUSTED_SHIFT     (5U)
+#define RGX_CR_MIPS_ADDR_REMAP3_CONFIG2_TRUSTED_CLRMSK    (IMG_UINT64_C(0XFFFFFFFFFFFFFFDF))
+#define RGX_CR_MIPS_ADDR_REMAP3_CONFIG2_TRUSTED_EN        (IMG_UINT64_C(0X0000000000000020))
 #define RGX_CR_MIPS_ADDR_REMAP3_CONFIG2_REGION_SIZE_POW2_SHIFT (0U)
 #define RGX_CR_MIPS_ADDR_REMAP3_CONFIG2_REGION_SIZE_POW2_CLRMSK (IMG_UINT64_C(0XFFFFFFFFFFFFFFE0))
 
 
 /*
+    Register RGX_CR_MIPS_ADDR_REMAP4_CONFIG1
+*/
+#define RGX_CR_MIPS_ADDR_REMAP4_CONFIG1                   (0x0848U)
+#define RGX_CR_MIPS_ADDR_REMAP4_CONFIG1_MASKFULL          (IMG_UINT64_C(0x00000000FFFFF001))
+#define RGX_CR_MIPS_ADDR_REMAP4_CONFIG1_BASE_ADDR_IN_SHIFT (12U)
+#define RGX_CR_MIPS_ADDR_REMAP4_CONFIG1_BASE_ADDR_IN_CLRMSK (IMG_UINT64_C(0XFFFFFFFF00000FFF))
+#define RGX_CR_MIPS_ADDR_REMAP4_CONFIG1_MODE_ENABLE_SHIFT (0U)
+#define RGX_CR_MIPS_ADDR_REMAP4_CONFIG1_MODE_ENABLE_CLRMSK (IMG_UINT64_C(0XFFFFFFFFFFFFFFFE))
+#define RGX_CR_MIPS_ADDR_REMAP4_CONFIG1_MODE_ENABLE_EN    (IMG_UINT64_C(0X0000000000000001))
+
+
+/*
+    Register RGX_CR_MIPS_ADDR_REMAP4_CONFIG2
+*/
+#define RGX_CR_MIPS_ADDR_REMAP4_CONFIG2                   (0x0850U)
+#define RGX_CR_MIPS_ADDR_REMAP4_CONFIG2_MASKFULL          (IMG_UINT64_C(0x00000000FFFFF1FF))
+#define RGX_CR_MIPS_ADDR_REMAP4_CONFIG2_ADDR_OUT_SHIFT    (12U)
+#define RGX_CR_MIPS_ADDR_REMAP4_CONFIG2_ADDR_OUT_CLRMSK   (IMG_UINT64_C(0XFFFFFFFF00000FFF))
+#define RGX_CR_MIPS_ADDR_REMAP4_CONFIG2_OS_ID_SHIFT       (6U)
+#define RGX_CR_MIPS_ADDR_REMAP4_CONFIG2_OS_ID_CLRMSK      (IMG_UINT64_C(0XFFFFFFFFFFFFFE3F))
+#define RGX_CR_MIPS_ADDR_REMAP4_CONFIG2_TRUSTED_SHIFT     (5U)
+#define RGX_CR_MIPS_ADDR_REMAP4_CONFIG2_TRUSTED_CLRMSK    (IMG_UINT64_C(0XFFFFFFFFFFFFFFDF))
+#define RGX_CR_MIPS_ADDR_REMAP4_CONFIG2_TRUSTED_EN        (IMG_UINT64_C(0X0000000000000020))
+#define RGX_CR_MIPS_ADDR_REMAP4_CONFIG2_REGION_SIZE_POW2_SHIFT (0U)
+#define RGX_CR_MIPS_ADDR_REMAP4_CONFIG2_REGION_SIZE_POW2_CLRMSK (IMG_UINT64_C(0XFFFFFFFFFFFFFFE0))
+
+
+/*
+    Register RGX_CR_MIPS_ADDR_REMAP5_CONFIG1
+*/
+#define RGX_CR_MIPS_ADDR_REMAP5_CONFIG1                   (0x0858U)
+#define RGX_CR_MIPS_ADDR_REMAP5_CONFIG1_MASKFULL          (IMG_UINT64_C(0x00000000FFFFF001))
+#define RGX_CR_MIPS_ADDR_REMAP5_CONFIG1_BASE_ADDR_IN_SHIFT (12U)
+#define RGX_CR_MIPS_ADDR_REMAP5_CONFIG1_BASE_ADDR_IN_CLRMSK (IMG_UINT64_C(0XFFFFFFFF00000FFF))
+#define RGX_CR_MIPS_ADDR_REMAP5_CONFIG1_MODE_ENABLE_SHIFT (0U)
+#define RGX_CR_MIPS_ADDR_REMAP5_CONFIG1_MODE_ENABLE_CLRMSK (IMG_UINT64_C(0XFFFFFFFFFFFFFFFE))
+#define RGX_CR_MIPS_ADDR_REMAP5_CONFIG1_MODE_ENABLE_EN    (IMG_UINT64_C(0X0000000000000001))
+
+
+/*
+    Register RGX_CR_MIPS_ADDR_REMAP5_CONFIG2
+*/
+#define RGX_CR_MIPS_ADDR_REMAP5_CONFIG2                   (0x0860U)
+#define RGX_CR_MIPS_ADDR_REMAP5_CONFIG2_MASKFULL          (IMG_UINT64_C(0x00000000FFFFF1FF))
+#define RGX_CR_MIPS_ADDR_REMAP5_CONFIG2_ADDR_OUT_SHIFT    (12U)
+#define RGX_CR_MIPS_ADDR_REMAP5_CONFIG2_ADDR_OUT_CLRMSK   (IMG_UINT64_C(0XFFFFFFFF00000FFF))
+#define RGX_CR_MIPS_ADDR_REMAP5_CONFIG2_OS_ID_SHIFT       (6U)
+#define RGX_CR_MIPS_ADDR_REMAP5_CONFIG2_OS_ID_CLRMSK      (IMG_UINT64_C(0XFFFFFFFFFFFFFE3F))
+#define RGX_CR_MIPS_ADDR_REMAP5_CONFIG2_TRUSTED_SHIFT     (5U)
+#define RGX_CR_MIPS_ADDR_REMAP5_CONFIG2_TRUSTED_CLRMSK    (IMG_UINT64_C(0XFFFFFFFFFFFFFFDF))
+#define RGX_CR_MIPS_ADDR_REMAP5_CONFIG2_TRUSTED_EN        (IMG_UINT64_C(0X0000000000000020))
+#define RGX_CR_MIPS_ADDR_REMAP5_CONFIG2_REGION_SIZE_POW2_SHIFT (0U)
+#define RGX_CR_MIPS_ADDR_REMAP5_CONFIG2_REGION_SIZE_POW2_CLRMSK (IMG_UINT64_C(0XFFFFFFFFFFFFFFE0))
+
+
+/*
     Register RGX_CR_MIPS_WRAPPER_IRQ_ENABLE
 */
 #define RGX_CR_MIPS_WRAPPER_IRQ_ENABLE                    (0x08A0U)
@@ -2699,45 +2041,29 @@
 #define RGX_CR_MTS_INTCTX_THREAD1_DM_ASSOC_DM_ASSOC_CLRMSK (0XFFFF0000U)
 
 
-#if defined(RGX_FEATURE_S7_TOP_INFRASTRUCTURE)
 /*
     Register RGX_CR_MTS_GARTEN_WRAPPER_CONFIG
 */
 #define RGX_CR_MTS_GARTEN_WRAPPER_CONFIG                  (0x0B50U)
-#define RGX_CR_MTS_GARTEN_WRAPPER_CONFIG_MASKFULL         (IMG_UINT64_C(0x000FF0FFFFFFF701))
-#define RGX_CR_MTS_GARTEN_WRAPPER_CONFIG_FENCE_PC_BASE_SHIFT (44U)
-#define RGX_CR_MTS_GARTEN_WRAPPER_CONFIG_FENCE_PC_BASE_CLRMSK (IMG_UINT64_C(0XFFF00FFFFFFFFFFF))
-#define RGX_CR_MTS_GARTEN_WRAPPER_CONFIG_FENCE_ADDR_SHIFT (12U)
-#define RGX_CR_MTS_GARTEN_WRAPPER_CONFIG_FENCE_ADDR_CLRMSK (IMG_UINT64_C(0XFFFFFF0000000FFF))
-#define RGX_CR_MTS_GARTEN_WRAPPER_CONFIG_FENCE_PERSISTENCE_SHIFT (9U)
-#define RGX_CR_MTS_GARTEN_WRAPPER_CONFIG_FENCE_PERSISTENCE_CLRMSK (IMG_UINT64_C(0XFFFFFFFFFFFFF9FF))
-#define RGX_CR_MTS_GARTEN_WRAPPER_CONFIG_FENCE_SLC_COHERENT_SHIFT (8U)
-#define RGX_CR_MTS_GARTEN_WRAPPER_CONFIG_FENCE_SLC_COHERENT_CLRMSK (IMG_UINT64_C(0XFFFFFFFFFFFFFEFF))
-#define RGX_CR_MTS_GARTEN_WRAPPER_CONFIG_FENCE_SLC_COHERENT_EN (IMG_UINT64_C(0X0000000000000100))
-#define RGX_CR_MTS_GARTEN_WRAPPER_CONFIG_IDLE_CTRL_SHIFT  (0U)
-#define RGX_CR_MTS_GARTEN_WRAPPER_CONFIG_IDLE_CTRL_CLRMSK (IMG_UINT64_C(0XFFFFFFFFFFFFFFFE))
-#define RGX_CR_MTS_GARTEN_WRAPPER_CONFIG_IDLE_CTRL_META   (IMG_UINT64_C(0000000000000000))
-#define RGX_CR_MTS_GARTEN_WRAPPER_CONFIG_IDLE_CTRL_MTS    (IMG_UINT64_C(0x0000000000000001))
-#endif /* RGX_FEATURE_S7_TOP_INFRASTRUCTURE */ 
-
-
-#if !defined(RGX_FEATURE_S7_TOP_INFRASTRUCTURE)
-/*
-    Register RGX_CR_MTS_GARTEN_WRAPPER_CONFIG
-*/
-#define RGX_CR_MTS_GARTEN_WRAPPER_CONFIG                  (0x0B50U)
+#define RGX_CR_MTS_GARTEN_WRAPPER_CONFIG__S7_TOP__MASKFULL (IMG_UINT64_C(0x000FF0FFFFFFF701))
 #define RGX_CR_MTS_GARTEN_WRAPPER_CONFIG_MASKFULL         (IMG_UINT64_C(0x0000FFFFFFFFF001))
 #define RGX_CR_MTS_GARTEN_WRAPPER_CONFIG_FENCE_PC_BASE_SHIFT (44U)
 #define RGX_CR_MTS_GARTEN_WRAPPER_CONFIG_FENCE_PC_BASE_CLRMSK (IMG_UINT64_C(0XFFFF0FFFFFFFFFFF))
+#define RGX_CR_MTS_GARTEN_WRAPPER_CONFIG__S7_TOP__FENCE_PC_BASE_SHIFT (44U)
+#define RGX_CR_MTS_GARTEN_WRAPPER_CONFIG__S7_TOP__FENCE_PC_BASE_CLRMSK (IMG_UINT64_C(0XFFF00FFFFFFFFFFF))
 #define RGX_CR_MTS_GARTEN_WRAPPER_CONFIG_FENCE_DM_SHIFT   (40U)
 #define RGX_CR_MTS_GARTEN_WRAPPER_CONFIG_FENCE_DM_CLRMSK  (IMG_UINT64_C(0XFFFFF0FFFFFFFFFF))
 #define RGX_CR_MTS_GARTEN_WRAPPER_CONFIG_FENCE_ADDR_SHIFT (12U)
 #define RGX_CR_MTS_GARTEN_WRAPPER_CONFIG_FENCE_ADDR_CLRMSK (IMG_UINT64_C(0XFFFFFF0000000FFF))
+#define RGX_CR_MTS_GARTEN_WRAPPER_CONFIG__S7_TOP__FENCE_PERSISTENCE_SHIFT (9U)
+#define RGX_CR_MTS_GARTEN_WRAPPER_CONFIG__S7_TOP__FENCE_PERSISTENCE_CLRMSK (IMG_UINT64_C(0XFFFFFFFFFFFFF9FF))
+#define RGX_CR_MTS_GARTEN_WRAPPER_CONFIG__S7_TOP__FENCE_SLC_COHERENT_SHIFT (8U)
+#define RGX_CR_MTS_GARTEN_WRAPPER_CONFIG__S7_TOP__FENCE_SLC_COHERENT_CLRMSK (IMG_UINT64_C(0XFFFFFFFFFFFFFEFF))
+#define RGX_CR_MTS_GARTEN_WRAPPER_CONFIG__S7_TOP__FENCE_SLC_COHERENT_EN (IMG_UINT64_C(0X0000000000000100))
 #define RGX_CR_MTS_GARTEN_WRAPPER_CONFIG_IDLE_CTRL_SHIFT  (0U)
 #define RGX_CR_MTS_GARTEN_WRAPPER_CONFIG_IDLE_CTRL_CLRMSK (IMG_UINT64_C(0XFFFFFFFFFFFFFFFE))
-#define RGX_CR_MTS_GARTEN_WRAPPER_CONFIG_IDLE_CTRL_META   (IMG_UINT64_C(0000000000000000))
-#define RGX_CR_MTS_GARTEN_WRAPPER_CONFIG_IDLE_CTRL_MTS    (IMG_UINT64_C(0x0000000000000001))
-#endif /* !defined(RGX_FEATURE_S7_TOP_INFRASTRUCTURE) */
+#define RGX_CR_MTS_GARTEN_WRAPPER_CONFIG_IDLE_CTRL_META   (IMG_UINT64_C(0000000000000000))  
+#define RGX_CR_MTS_GARTEN_WRAPPER_CONFIG_IDLE_CTRL_MTS    (IMG_UINT64_C(0x0000000000000001))  
 
 
 /*
@@ -2775,13 +2101,10 @@
 */
 #define RGX_CR_MTS_BGCTX_COUNTED_SCHEDULE                 (0x0BA8U)
 #define RGX_CR_MTS_BGCTX_COUNTED_SCHEDULE_MASKFULL        (IMG_UINT64_C(0xFFFFFFFFFFFFFFFF))
-#if defined(RGX_FEATURE_RAY_TRACING)
 #define RGX_CR_MTS_BGCTX_COUNTED_SCHEDULE_DM7_SHIFT       (56U)
 #define RGX_CR_MTS_BGCTX_COUNTED_SCHEDULE_DM7_CLRMSK      (IMG_UINT64_C(0X00FFFFFFFFFFFFFF))
 #define RGX_CR_MTS_BGCTX_COUNTED_SCHEDULE_DM6_SHIFT       (48U)
 #define RGX_CR_MTS_BGCTX_COUNTED_SCHEDULE_DM6_CLRMSK      (IMG_UINT64_C(0XFF00FFFFFFFFFFFF))
-#endif /* RGX_FEATURE_RAY_TRACING */
-
 #define RGX_CR_MTS_BGCTX_COUNTED_SCHEDULE_DM5_SHIFT       (40U)
 #define RGX_CR_MTS_BGCTX_COUNTED_SCHEDULE_DM5_CLRMSK      (IMG_UINT64_C(0XFFFF00FFFFFFFFFF))
 #define RGX_CR_MTS_BGCTX_COUNTED_SCHEDULE_DM4_SHIFT       (32U)
@@ -2825,6 +2148,15 @@
 #define RGX_CR_GARTEN_SLC_FORCE_COHERENCY_EN              (0X00000001U)
 
 
+/*
+    Register RGX_CR_PPP
+*/
+#define RGX_CR_PPP                                        (0x0CD0U)
+#define RGX_CR_PPP_MASKFULL                               (IMG_UINT64_C(0x00000000FFFFFFFF))
+#define RGX_CR_PPP_CHECKSUM_SHIFT                         (0U)
+#define RGX_CR_PPP_CHECKSUM_CLRMSK                        (00000000U)
+
+
 #define RGX_CR_ISP_RENDER_DIR_TYPE_MASK                   (0x00000003U)
 /*
  Top-left to bottom-right */
@@ -2911,14 +2243,19 @@
 #define RGX_CR_ISP_CTL_PIPE_ENABLE_PIPE_ONE               (00000000U)
 #define RGX_CR_ISP_CTL_PIPE_ENABLE_PIPE_TWO               (0X00001000U)
 #define RGX_CR_ISP_CTL_PIPE_ENABLE_PIPE_THREE             (0X00002000U)
-#if defined(RGX_FEATURE_CLUSTER_GROUPING)
 #define RGX_CR_ISP_CTL_PIPE_ENABLE_PIPE_FOUR              (0X00003000U)
 #define RGX_CR_ISP_CTL_PIPE_ENABLE_PIPE_FIVE              (0X00004000U)
 #define RGX_CR_ISP_CTL_PIPE_ENABLE_PIPE_SIX               (0X00005000U)
 #define RGX_CR_ISP_CTL_PIPE_ENABLE_PIPE_SEVEN             (0X00006000U)
 #define RGX_CR_ISP_CTL_PIPE_ENABLE_PIPE_EIGHT             (0X00007000U)
-#endif /* RGX_FEATURE_CLUSTER_GROUPING */
-
+#define RGX_CR_ISP_CTL_PIPE_ENABLE_PIPE_NINE              (0X00008000U)
+#define RGX_CR_ISP_CTL_PIPE_ENABLE_PIPE_TEN               (0X00009000U)
+#define RGX_CR_ISP_CTL_PIPE_ENABLE_PIPE_ELEVEN            (0X0000A000U)
+#define RGX_CR_ISP_CTL_PIPE_ENABLE_PIPE_TWELVE            (0X0000B000U)
+#define RGX_CR_ISP_CTL_PIPE_ENABLE_PIPE_THIRTEEN          (0X0000C000U)
+#define RGX_CR_ISP_CTL_PIPE_ENABLE_PIPE_FOURTEEN          (0X0000D000U)
+#define RGX_CR_ISP_CTL_PIPE_ENABLE_PIPE_FIFTEEN           (0X0000E000U)
+#define RGX_CR_ISP_CTL_PIPE_ENABLE_PIPE_SIXTEEN           (0X0000F000U)
 #define RGX_CR_ISP_CTL_VALID_ID_SHIFT                     (4U)
 #define RGX_CR_ISP_CTL_VALID_ID_CLRMSK                    (0XFFFFFC0FU)
 #define RGX_CR_ISP_CTL_UPASS_START_SHIFT                  (0U)
@@ -2926,105 +2263,6 @@
 
 
 /*
-    Register RGX_CR_ISP_STORE0
-*/
-#define RGX_CR_ISP_STORE0                                 (0x1008U)
-#define RGX_CR_ISP_STORE0_MASKFULL                        (IMG_UINT64_C(0x000000007F3FF3FF))
-#define RGX_CR_ISP_STORE0_ACTIVE_SHIFT                    (30U)
-#define RGX_CR_ISP_STORE0_ACTIVE_CLRMSK                   (0XBFFFFFFFU)
-#define RGX_CR_ISP_STORE0_ACTIVE_EN                       (0X40000000U)
-#define RGX_CR_ISP_STORE0_EOR_SHIFT                       (29U)
-#define RGX_CR_ISP_STORE0_EOR_CLRMSK                      (0XDFFFFFFFU)
-#define RGX_CR_ISP_STORE0_EOR_EN                          (0X20000000U)
-#define RGX_CR_ISP_STORE0_TILE_LAST_SHIFT                 (28U)
-#define RGX_CR_ISP_STORE0_TILE_LAST_CLRMSK                (0XEFFFFFFFU)
-#define RGX_CR_ISP_STORE0_TILE_LAST_EN                    (0X10000000U)
-#define RGX_CR_ISP_STORE0_MT_SHIFT                        (24U)
-#define RGX_CR_ISP_STORE0_MT_CLRMSK                       (0XF0FFFFFFU)
-#define RGX_CR_ISP_STORE0_TILE_X_SHIFT                    (12U)
-#define RGX_CR_ISP_STORE0_TILE_X_CLRMSK                   (0XFFC00FFFU)
-#define RGX_CR_ISP_STORE0_TILE_Y_SHIFT                    (0U)
-#define RGX_CR_ISP_STORE0_TILE_Y_CLRMSK                   (0XFFFFFC00U)
-
-
-/*
-    Register RGX_CR_ISP_STORE1
-*/
-#define RGX_CR_ISP_STORE1                                 (0x1010U)
-#define RGX_CR_ISP_STORE1_MASKFULL                        (IMG_UINT64_C(0x000000007F3FF3FF))
-#define RGX_CR_ISP_STORE1_ACTIVE_SHIFT                    (30U)
-#define RGX_CR_ISP_STORE1_ACTIVE_CLRMSK                   (0XBFFFFFFFU)
-#define RGX_CR_ISP_STORE1_ACTIVE_EN                       (0X40000000U)
-#define RGX_CR_ISP_STORE1_EOR_SHIFT                       (29U)
-#define RGX_CR_ISP_STORE1_EOR_CLRMSK                      (0XDFFFFFFFU)
-#define RGX_CR_ISP_STORE1_EOR_EN                          (0X20000000U)
-#define RGX_CR_ISP_STORE1_TILE_LAST_SHIFT                 (28U)
-#define RGX_CR_ISP_STORE1_TILE_LAST_CLRMSK                (0XEFFFFFFFU)
-#define RGX_CR_ISP_STORE1_TILE_LAST_EN                    (0X10000000U)
-#define RGX_CR_ISP_STORE1_MT_SHIFT                        (24U)
-#define RGX_CR_ISP_STORE1_MT_CLRMSK                       (0XF0FFFFFFU)
-#define RGX_CR_ISP_STORE1_TILE_X_SHIFT                    (12U)
-#define RGX_CR_ISP_STORE1_TILE_X_CLRMSK                   (0XFFC00FFFU)
-#define RGX_CR_ISP_STORE1_TILE_Y_SHIFT                    (0U)
-#define RGX_CR_ISP_STORE1_TILE_Y_CLRMSK                   (0XFFFFFC00U)
-
-
-/*
-    Register RGX_CR_ISP_STORE2
-*/
-#define RGX_CR_ISP_STORE2                                 (0x1018U)
-#define RGX_CR_ISP_STORE2_MASKFULL                        (IMG_UINT64_C(0x000000007F3FF3FF))
-#define RGX_CR_ISP_STORE2_ACTIVE_SHIFT                    (30U)
-#define RGX_CR_ISP_STORE2_ACTIVE_CLRMSK                   (0XBFFFFFFFU)
-#define RGX_CR_ISP_STORE2_ACTIVE_EN                       (0X40000000U)
-#define RGX_CR_ISP_STORE2_EOR_SHIFT                       (29U)
-#define RGX_CR_ISP_STORE2_EOR_CLRMSK                      (0XDFFFFFFFU)
-#define RGX_CR_ISP_STORE2_EOR_EN                          (0X20000000U)
-#define RGX_CR_ISP_STORE2_TILE_LAST_SHIFT                 (28U)
-#define RGX_CR_ISP_STORE2_TILE_LAST_CLRMSK                (0XEFFFFFFFU)
-#define RGX_CR_ISP_STORE2_TILE_LAST_EN                    (0X10000000U)
-#define RGX_CR_ISP_STORE2_MT_SHIFT                        (24U)
-#define RGX_CR_ISP_STORE2_MT_CLRMSK                       (0XF0FFFFFFU)
-#define RGX_CR_ISP_STORE2_TILE_X_SHIFT                    (12U)
-#define RGX_CR_ISP_STORE2_TILE_X_CLRMSK                   (0XFFC00FFFU)
-#define RGX_CR_ISP_STORE2_TILE_Y_SHIFT                    (0U)
-#define RGX_CR_ISP_STORE2_TILE_Y_CLRMSK                   (0XFFFFFC00U)
-
-
-/*
-    Register RGX_CR_ISP_RESUME0
-*/
-#define RGX_CR_ISP_RESUME0                                (0x1020U)
-#define RGX_CR_ISP_RESUME0_MASKFULL                       (IMG_UINT64_C(0x00000000003FF3FF))
-#define RGX_CR_ISP_RESUME0_TILE_X_SHIFT                   (12U)
-#define RGX_CR_ISP_RESUME0_TILE_X_CLRMSK                  (0XFFC00FFFU)
-#define RGX_CR_ISP_RESUME0_TILE_Y_SHIFT                   (0U)
-#define RGX_CR_ISP_RESUME0_TILE_Y_CLRMSK                  (0XFFFFFC00U)
-
-
-/*
-    Register RGX_CR_ISP_RESUME1
-*/
-#define RGX_CR_ISP_RESUME1                                (0x1028U)
-#define RGX_CR_ISP_RESUME1_MASKFULL                       (IMG_UINT64_C(0x00000000003FF3FF))
-#define RGX_CR_ISP_RESUME1_TILE_X_SHIFT                   (12U)
-#define RGX_CR_ISP_RESUME1_TILE_X_CLRMSK                  (0XFFC00FFFU)
-#define RGX_CR_ISP_RESUME1_TILE_Y_SHIFT                   (0U)
-#define RGX_CR_ISP_RESUME1_TILE_Y_CLRMSK                  (0XFFFFFC00U)
-
-
-/*
-    Register RGX_CR_ISP_RESUME2
-*/
-#define RGX_CR_ISP_RESUME2                                (0x1030U)
-#define RGX_CR_ISP_RESUME2_MASKFULL                       (IMG_UINT64_C(0x00000000003FF3FF))
-#define RGX_CR_ISP_RESUME2_TILE_X_SHIFT                   (12U)
-#define RGX_CR_ISP_RESUME2_TILE_X_CLRMSK                  (0XFFC00FFFU)
-#define RGX_CR_ISP_RESUME2_TILE_Y_SHIFT                   (0U)
-#define RGX_CR_ISP_RESUME2_TILE_Y_CLRMSK                  (0XFFFFFC00U)
-
-
-/*
     Register RGX_CR_ISP_STATUS
 */
 #define RGX_CR_ISP_STATUS                                 (0x1038U)
@@ -3040,174 +2278,6 @@
 #define RGX_CR_ISP_STATUS_EOR_EN                          (0X00000001U)
 
 
-#if defined(RGX_FEATURE_CLUSTER_GROUPING)
-/*
-    Register RGX_CR_ISP_STORE3
-*/
-#define RGX_CR_ISP_STORE3                                 (0x1060U)
-#define RGX_CR_ISP_STORE3_MASKFULL                        (IMG_UINT64_C(0x000000007F3FF3FF))
-#define RGX_CR_ISP_STORE3_ACTIVE_SHIFT                    (30U)
-#define RGX_CR_ISP_STORE3_ACTIVE_CLRMSK                   (0XBFFFFFFFU)
-#define RGX_CR_ISP_STORE3_ACTIVE_EN                       (0X40000000U)
-#define RGX_CR_ISP_STORE3_EOR_SHIFT                       (29U)
-#define RGX_CR_ISP_STORE3_EOR_CLRMSK                      (0XDFFFFFFFU)
-#define RGX_CR_ISP_STORE3_EOR_EN                          (0X20000000U)
-#define RGX_CR_ISP_STORE3_TILE_LAST_SHIFT                 (28U)
-#define RGX_CR_ISP_STORE3_TILE_LAST_CLRMSK                (0XEFFFFFFFU)
-#define RGX_CR_ISP_STORE3_TILE_LAST_EN                    (0X10000000U)
-#define RGX_CR_ISP_STORE3_MT_SHIFT                        (24U)
-#define RGX_CR_ISP_STORE3_MT_CLRMSK                       (0XF0FFFFFFU)
-#define RGX_CR_ISP_STORE3_TILE_X_SHIFT                    (12U)
-#define RGX_CR_ISP_STORE3_TILE_X_CLRMSK                   (0XFFC00FFFU)
-#define RGX_CR_ISP_STORE3_TILE_Y_SHIFT                    (0U)
-#define RGX_CR_ISP_STORE3_TILE_Y_CLRMSK                   (0XFFFFFC00U)
-
-
-/*
-    Register RGX_CR_ISP_STORE4
-*/
-#define RGX_CR_ISP_STORE4                                 (0x1068U)
-#define RGX_CR_ISP_STORE4_MASKFULL                        (IMG_UINT64_C(0x000000007F3FF3FF))
-#define RGX_CR_ISP_STORE4_ACTIVE_SHIFT                    (30U)
-#define RGX_CR_ISP_STORE4_ACTIVE_CLRMSK                   (0XBFFFFFFFU)
-#define RGX_CR_ISP_STORE4_ACTIVE_EN                       (0X40000000U)
-#define RGX_CR_ISP_STORE4_EOR_SHIFT                       (29U)
-#define RGX_CR_ISP_STORE4_EOR_CLRMSK                      (0XDFFFFFFFU)
-#define RGX_CR_ISP_STORE4_EOR_EN                          (0X20000000U)
-#define RGX_CR_ISP_STORE4_TILE_LAST_SHIFT                 (28U)
-#define RGX_CR_ISP_STORE4_TILE_LAST_CLRMSK                (0XEFFFFFFFU)
-#define RGX_CR_ISP_STORE4_TILE_LAST_EN                    (0X10000000U)
-#define RGX_CR_ISP_STORE4_MT_SHIFT                        (24U)
-#define RGX_CR_ISP_STORE4_MT_CLRMSK                       (0XF0FFFFFFU)
-#define RGX_CR_ISP_STORE4_TILE_X_SHIFT                    (12U)
-#define RGX_CR_ISP_STORE4_TILE_X_CLRMSK                   (0XFFC00FFFU)
-#define RGX_CR_ISP_STORE4_TILE_Y_SHIFT                    (0U)
-#define RGX_CR_ISP_STORE4_TILE_Y_CLRMSK                   (0XFFFFFC00U)
-
-
-/*
-    Register RGX_CR_ISP_STORE5
-*/
-#define RGX_CR_ISP_STORE5                                 (0x1070U)
-#define RGX_CR_ISP_STORE5_MASKFULL                        (IMG_UINT64_C(0x000000007F3FF3FF))
-#define RGX_CR_ISP_STORE5_ACTIVE_SHIFT                    (30U)
-#define RGX_CR_ISP_STORE5_ACTIVE_CLRMSK                   (0XBFFFFFFFU)
-#define RGX_CR_ISP_STORE5_ACTIVE_EN                       (0X40000000U)
-#define RGX_CR_ISP_STORE5_EOR_SHIFT                       (29U)
-#define RGX_CR_ISP_STORE5_EOR_CLRMSK                      (0XDFFFFFFFU)
-#define RGX_CR_ISP_STORE5_EOR_EN                          (0X20000000U)
-#define RGX_CR_ISP_STORE5_TILE_LAST_SHIFT                 (28U)
-#define RGX_CR_ISP_STORE5_TILE_LAST_CLRMSK                (0XEFFFFFFFU)
-#define RGX_CR_ISP_STORE5_TILE_LAST_EN                    (0X10000000U)
-#define RGX_CR_ISP_STORE5_MT_SHIFT                        (24U)
-#define RGX_CR_ISP_STORE5_MT_CLRMSK                       (0XF0FFFFFFU)
-#define RGX_CR_ISP_STORE5_TILE_X_SHIFT                    (12U)
-#define RGX_CR_ISP_STORE5_TILE_X_CLRMSK                   (0XFFC00FFFU)
-#define RGX_CR_ISP_STORE5_TILE_Y_SHIFT                    (0U)
-#define RGX_CR_ISP_STORE5_TILE_Y_CLRMSK                   (0XFFFFFC00U)
-
-
-/*
-    Register RGX_CR_ISP_RESUME3
-*/
-#define RGX_CR_ISP_RESUME3                                (0x1078U)
-#define RGX_CR_ISP_RESUME3_MASKFULL                       (IMG_UINT64_C(0x00000000003FF3FF))
-#define RGX_CR_ISP_RESUME3_TILE_X_SHIFT                   (12U)
-#define RGX_CR_ISP_RESUME3_TILE_X_CLRMSK                  (0XFFC00FFFU)
-#define RGX_CR_ISP_RESUME3_TILE_Y_SHIFT                   (0U)
-#define RGX_CR_ISP_RESUME3_TILE_Y_CLRMSK                  (0XFFFFFC00U)
-
-
-/*
-    Register RGX_CR_ISP_RESUME4
-*/
-#define RGX_CR_ISP_RESUME4                                (0x1080U)
-#define RGX_CR_ISP_RESUME4_MASKFULL                       (IMG_UINT64_C(0x00000000003FF3FF))
-#define RGX_CR_ISP_RESUME4_TILE_X_SHIFT                   (12U)
-#define RGX_CR_ISP_RESUME4_TILE_X_CLRMSK                  (0XFFC00FFFU)
-#define RGX_CR_ISP_RESUME4_TILE_Y_SHIFT                   (0U)
-#define RGX_CR_ISP_RESUME4_TILE_Y_CLRMSK                  (0XFFFFFC00U)
-
-
-/*
-    Register RGX_CR_ISP_RESUME5
-*/
-#define RGX_CR_ISP_RESUME5                                (0x1088U)
-#define RGX_CR_ISP_RESUME5_MASKFULL                       (IMG_UINT64_C(0x00000000003FF3FF))
-#define RGX_CR_ISP_RESUME5_TILE_X_SHIFT                   (12U)
-#define RGX_CR_ISP_RESUME5_TILE_X_CLRMSK                  (0XFFC00FFFU)
-#define RGX_CR_ISP_RESUME5_TILE_Y_SHIFT                   (0U)
-#define RGX_CR_ISP_RESUME5_TILE_Y_CLRMSK                  (0XFFFFFC00U)
-
-
-/*
-    Register RGX_CR_ISP_STORE6
-*/
-#define RGX_CR_ISP_STORE6                                 (0x10A0U)
-#define RGX_CR_ISP_STORE6_MASKFULL                        (IMG_UINT64_C(0x000000007F3FF3FF))
-#define RGX_CR_ISP_STORE6_ACTIVE_SHIFT                    (30U)
-#define RGX_CR_ISP_STORE6_ACTIVE_CLRMSK                   (0XBFFFFFFFU)
-#define RGX_CR_ISP_STORE6_ACTIVE_EN                       (0X40000000U)
-#define RGX_CR_ISP_STORE6_EOR_SHIFT                       (29U)
-#define RGX_CR_ISP_STORE6_EOR_CLRMSK                      (0XDFFFFFFFU)
-#define RGX_CR_ISP_STORE6_EOR_EN                          (0X20000000U)
-#define RGX_CR_ISP_STORE6_TILE_LAST_SHIFT                 (28U)
-#define RGX_CR_ISP_STORE6_TILE_LAST_CLRMSK                (0XEFFFFFFFU)
-#define RGX_CR_ISP_STORE6_TILE_LAST_EN                    (0X10000000U)
-#define RGX_CR_ISP_STORE6_MT_SHIFT                        (24U)
-#define RGX_CR_ISP_STORE6_MT_CLRMSK                       (0XF0FFFFFFU)
-#define RGX_CR_ISP_STORE6_TILE_X_SHIFT                    (12U)
-#define RGX_CR_ISP_STORE6_TILE_X_CLRMSK                   (0XFFC00FFFU)
-#define RGX_CR_ISP_STORE6_TILE_Y_SHIFT                    (0U)
-#define RGX_CR_ISP_STORE6_TILE_Y_CLRMSK                   (0XFFFFFC00U)
-
-
-/*
-    Register RGX_CR_ISP_STORE7
-*/
-#define RGX_CR_ISP_STORE7                                 (0x10A8U)
-#define RGX_CR_ISP_STORE7_MASKFULL                        (IMG_UINT64_C(0x000000007F3FF3FF))
-#define RGX_CR_ISP_STORE7_ACTIVE_SHIFT                    (30U)
-#define RGX_CR_ISP_STORE7_ACTIVE_CLRMSK                   (0XBFFFFFFFU)
-#define RGX_CR_ISP_STORE7_ACTIVE_EN                       (0X40000000U)
-#define RGX_CR_ISP_STORE7_EOR_SHIFT                       (29U)
-#define RGX_CR_ISP_STORE7_EOR_CLRMSK                      (0XDFFFFFFFU)
-#define RGX_CR_ISP_STORE7_EOR_EN                          (0X20000000U)
-#define RGX_CR_ISP_STORE7_TILE_LAST_SHIFT                 (28U)
-#define RGX_CR_ISP_STORE7_TILE_LAST_CLRMSK                (0XEFFFFFFFU)
-#define RGX_CR_ISP_STORE7_TILE_LAST_EN                    (0X10000000U)
-#define RGX_CR_ISP_STORE7_MT_SHIFT                        (24U)
-#define RGX_CR_ISP_STORE7_MT_CLRMSK                       (0XF0FFFFFFU)
-#define RGX_CR_ISP_STORE7_TILE_X_SHIFT                    (12U)
-#define RGX_CR_ISP_STORE7_TILE_X_CLRMSK                   (0XFFC00FFFU)
-#define RGX_CR_ISP_STORE7_TILE_Y_SHIFT                    (0U)
-#define RGX_CR_ISP_STORE7_TILE_Y_CLRMSK                   (0XFFFFFC00U)
-
-
-/*
-    Register RGX_CR_ISP_RESUME6
-*/
-#define RGX_CR_ISP_RESUME6                                (0x10B0U)
-#define RGX_CR_ISP_RESUME6_MASKFULL                       (IMG_UINT64_C(0x00000000003FF3FF))
-#define RGX_CR_ISP_RESUME6_TILE_X_SHIFT                   (12U)
-#define RGX_CR_ISP_RESUME6_TILE_X_CLRMSK                  (0XFFC00FFFU)
-#define RGX_CR_ISP_RESUME6_TILE_Y_SHIFT                   (0U)
-#define RGX_CR_ISP_RESUME6_TILE_Y_CLRMSK                  (0XFFFFFC00U)
-
-
-/*
-    Register RGX_CR_ISP_RESUME7
-*/
-#define RGX_CR_ISP_RESUME7                                (0x10B8U)
-#define RGX_CR_ISP_RESUME7_MASKFULL                       (IMG_UINT64_C(0x00000000003FF3FF))
-#define RGX_CR_ISP_RESUME7_TILE_X_SHIFT                   (12U)
-#define RGX_CR_ISP_RESUME7_TILE_X_CLRMSK                  (0XFFC00FFFU)
-#define RGX_CR_ISP_RESUME7_TILE_Y_SHIFT                   (0U)
-#define RGX_CR_ISP_RESUME7_TILE_Y_CLRMSK                  (0XFFFFFC00U)
-
-
-#endif /* RGX_FEATURE_CLUSTER_GROUPING */
-
 /*
     Register group: RGX_CR_ISP_XTP_RESUME, with 64 repeats
 */
@@ -3346,22 +2416,16 @@
 */
 #define RGX_CR_BIF_CAT_BASE_INDEX                         (0x1240U)
 #define RGX_CR_BIF_CAT_BASE_INDEX_MASKFULL                (IMG_UINT64_C(0x0007070707070707))
-#if defined(RGX_FEATURE_RAY_TRACING)
 #define RGX_CR_BIF_CAT_BASE_INDEX_RVTX_SHIFT              (48U)
 #define RGX_CR_BIF_CAT_BASE_INDEX_RVTX_CLRMSK             (IMG_UINT64_C(0XFFF8FFFFFFFFFFFF))
 #define RGX_CR_BIF_CAT_BASE_INDEX_RAY_SHIFT               (40U)
 #define RGX_CR_BIF_CAT_BASE_INDEX_RAY_CLRMSK              (IMG_UINT64_C(0XFFFFF8FFFFFFFFFF))
-#endif /* RGX_FEATURE_RAY_TRACING */
-
 #define RGX_CR_BIF_CAT_BASE_INDEX_HOST_SHIFT              (32U)
 #define RGX_CR_BIF_CAT_BASE_INDEX_HOST_CLRMSK             (IMG_UINT64_C(0XFFFFFFF8FFFFFFFF))
 #define RGX_CR_BIF_CAT_BASE_INDEX_TLA_SHIFT               (24U)
 #define RGX_CR_BIF_CAT_BASE_INDEX_TLA_CLRMSK              (IMG_UINT64_C(0XFFFFFFFFF8FFFFFF))
-#if defined(RGX_FEATURE_COMPUTE)
 #define RGX_CR_BIF_CAT_BASE_INDEX_CDM_SHIFT               (16U)
 #define RGX_CR_BIF_CAT_BASE_INDEX_CDM_CLRMSK              (IMG_UINT64_C(0XFFFFFFFFFFF8FFFF))
-#endif /* RGX_FEATURE_COMPUTE */
-
 #define RGX_CR_BIF_CAT_BASE_INDEX_PIXEL_SHIFT             (8U)
 #define RGX_CR_BIF_CAT_BASE_INDEX_PIXEL_CLRMSK            (IMG_UINT64_C(0XFFFFFFFFFFFFF8FF))
 #define RGX_CR_BIF_CAT_BASE_INDEX_TA_SHIFT                (0U)
@@ -3767,17 +2831,11 @@
 #define RGX_CR_MCU_FENCE_MASKFULL                         (IMG_UINT64_C(0x000007FFFFFFFFE0))
 #define RGX_CR_MCU_FENCE_DM_SHIFT                         (40U)
 #define RGX_CR_MCU_FENCE_DM_CLRMSK                        (IMG_UINT64_C(0XFFFFF8FFFFFFFFFF))
-#define RGX_CR_MCU_FENCE_DM_VERTEX                        (IMG_UINT64_C(0000000000000000))
-#define RGX_CR_MCU_FENCE_DM_PIXEL                         (IMG_UINT64_C(0x0000010000000000))
-#if defined(RGX_FEATURE_COMPUTE)
-#define RGX_CR_MCU_FENCE_DM_COMPUTE                       (IMG_UINT64_C(0x0000020000000000))
-#endif /* RGX_FEATURE_COMPUTE */
-
-#if defined(RGX_FEATURE_RAY_TRACING)
-#define RGX_CR_MCU_FENCE_DM_RAY_VERTEX                    (IMG_UINT64_C(0x0000030000000000))
-#define RGX_CR_MCU_FENCE_DM_RAY                           (IMG_UINT64_C(0x0000040000000000))
-#endif /* RGX_FEATURE_RAY_TRACING */
-
+#define RGX_CR_MCU_FENCE_DM_VERTEX                        (IMG_UINT64_C(0000000000000000))  
+#define RGX_CR_MCU_FENCE_DM_PIXEL                         (IMG_UINT64_C(0x0000010000000000))  
+#define RGX_CR_MCU_FENCE_DM_COMPUTE                       (IMG_UINT64_C(0x0000020000000000))  
+#define RGX_CR_MCU_FENCE_DM_RAY_VERTEX                    (IMG_UINT64_C(0x0000030000000000))  
+#define RGX_CR_MCU_FENCE_DM_RAY                           (IMG_UINT64_C(0x0000040000000000))  
 #define RGX_CR_MCU_FENCE_ADDR_SHIFT                       (5U)
 #define RGX_CR_MCU_FENCE_ADDR_CLRMSK                      (IMG_UINT64_C(0XFFFFFF000000001F))
 #define RGX_CR_MCU_FENCE_ADDR_ALIGNSHIFT                  (5U)
@@ -3785,26 +2843,51 @@
 
 
 /*
+    Register RGX_CR_SPFILTER_SIGNAL_DESCR
+*/
+#define RGX_CR_SPFILTER_SIGNAL_DESCR                      (0x2700U)
+#define RGX_CR_SPFILTER_SIGNAL_DESCR_MASKFULL             (IMG_UINT64_C(0x000000000000FFFF))
+#define RGX_CR_SPFILTER_SIGNAL_DESCR_SIZE_SHIFT           (0U)
+#define RGX_CR_SPFILTER_SIGNAL_DESCR_SIZE_CLRMSK          (0XFFFF0000U)
+#define RGX_CR_SPFILTER_SIGNAL_DESCR_SIZE_ALIGNSHIFT      (4U)
+#define RGX_CR_SPFILTER_SIGNAL_DESCR_SIZE_ALIGNSIZE       (16U)
+
+
+/*
+    Register RGX_CR_SPFILTER_SIGNAL_DESCR_MIN
+*/
+#define RGX_CR_SPFILTER_SIGNAL_DESCR_MIN                  (0x2708U)
+#define RGX_CR_SPFILTER_SIGNAL_DESCR_MIN_MASKFULL         (IMG_UINT64_C(0x000000FFFFFFFFF0))
+#define RGX_CR_SPFILTER_SIGNAL_DESCR_MIN_ADDR_SHIFT       (4U)
+#define RGX_CR_SPFILTER_SIGNAL_DESCR_MIN_ADDR_CLRMSK      (IMG_UINT64_C(0XFFFFFF000000000F))
+#define RGX_CR_SPFILTER_SIGNAL_DESCR_MIN_ADDR_ALIGNSHIFT  (4U)
+#define RGX_CR_SPFILTER_SIGNAL_DESCR_MIN_ADDR_ALIGNSIZE   (16U)
+
+
+/*
     Register RGX_CR_SLC_CTRL_MISC
 */
 #define RGX_CR_SLC_CTRL_MISC                              (0x3800U)
-#define RGX_CR_SLC_CTRL_MISC_MASKFULL                     (IMG_UINT64_C(0xFFFFFFFF00FF0105))
+#define RGX_CR_SLC_CTRL_MISC_MASKFULL                     (IMG_UINT64_C(0xFFFFFFFF00FF0107))
 #define RGX_CR_SLC_CTRL_MISC_SCRAMBLE_BITS_SHIFT          (32U)
 #define RGX_CR_SLC_CTRL_MISC_SCRAMBLE_BITS_CLRMSK         (IMG_UINT64_C(0X00000000FFFFFFFF))
 #define RGX_CR_SLC_CTRL_MISC_ADDR_DECODE_MODE_SHIFT       (16U)
 #define RGX_CR_SLC_CTRL_MISC_ADDR_DECODE_MODE_CLRMSK      (IMG_UINT64_C(0XFFFFFFFFFF00FFFF))
-#define RGX_CR_SLC_CTRL_MISC_ADDR_DECODE_MODE_INTERLEAVED_64_BYTE (IMG_UINT64_C(0000000000000000))
-#define RGX_CR_SLC_CTRL_MISC_ADDR_DECODE_MODE_INTERLEAVED_128_BYTE (IMG_UINT64_C(0x0000000000010000))
-#define RGX_CR_SLC_CTRL_MISC_ADDR_DECODE_MODE_SIMPLE_HASH1 (IMG_UINT64_C(0x0000000000100000))
-#define RGX_CR_SLC_CTRL_MISC_ADDR_DECODE_MODE_SIMPLE_HASH2 (IMG_UINT64_C(0x0000000000110000))
-#define RGX_CR_SLC_CTRL_MISC_ADDR_DECODE_MODE_PVR_HASH1   (IMG_UINT64_C(0x0000000000200000))
-#define RGX_CR_SLC_CTRL_MISC_ADDR_DECODE_MODE_PVR_HASH2_SCRAMBLE (IMG_UINT64_C(0x0000000000210000))
+#define RGX_CR_SLC_CTRL_MISC_ADDR_DECODE_MODE_INTERLEAVED_64_BYTE (IMG_UINT64_C(0000000000000000))  
+#define RGX_CR_SLC_CTRL_MISC_ADDR_DECODE_MODE_INTERLEAVED_128_BYTE (IMG_UINT64_C(0x0000000000010000))  
+#define RGX_CR_SLC_CTRL_MISC_ADDR_DECODE_MODE_SIMPLE_HASH1 (IMG_UINT64_C(0x0000000000100000))  
+#define RGX_CR_SLC_CTRL_MISC_ADDR_DECODE_MODE_SIMPLE_HASH2 (IMG_UINT64_C(0x0000000000110000))  
+#define RGX_CR_SLC_CTRL_MISC_ADDR_DECODE_MODE_PVR_HASH1   (IMG_UINT64_C(0x0000000000200000))  
+#define RGX_CR_SLC_CTRL_MISC_ADDR_DECODE_MODE_PVR_HASH2_SCRAMBLE (IMG_UINT64_C(0x0000000000210000))  
 #define RGX_CR_SLC_CTRL_MISC_PAUSE_SHIFT                  (8U)
 #define RGX_CR_SLC_CTRL_MISC_PAUSE_CLRMSK                 (IMG_UINT64_C(0XFFFFFFFFFFFFFEFF))
 #define RGX_CR_SLC_CTRL_MISC_PAUSE_EN                     (IMG_UINT64_C(0X0000000000000100))
 #define RGX_CR_SLC_CTRL_MISC_ENABLE_LINE_USE_LIMIT_SHIFT  (2U)
 #define RGX_CR_SLC_CTRL_MISC_ENABLE_LINE_USE_LIMIT_CLRMSK (IMG_UINT64_C(0XFFFFFFFFFFFFFFFB))
 #define RGX_CR_SLC_CTRL_MISC_ENABLE_LINE_USE_LIMIT_EN     (IMG_UINT64_C(0X0000000000000004))
+#define RGX_CR_SLC_CTRL_MISC_ENABLE_PSG_HAZARD_CHECK_SHIFT (1U)
+#define RGX_CR_SLC_CTRL_MISC_ENABLE_PSG_HAZARD_CHECK_CLRMSK (IMG_UINT64_C(0XFFFFFFFFFFFFFFFD))
+#define RGX_CR_SLC_CTRL_MISC_ENABLE_PSG_HAZARD_CHECK_EN   (IMG_UINT64_C(0X0000000000000002))
 #define RGX_CR_SLC_CTRL_MISC_BYPASS_BURST_COMBINER_SHIFT  (0U)
 #define RGX_CR_SLC_CTRL_MISC_BYPASS_BURST_COMBINER_CLRMSK (IMG_UINT64_C(0XFFFFFFFFFFFFFFFE))
 #define RGX_CR_SLC_CTRL_MISC_BYPASS_BURST_COMBINER_EN     (IMG_UINT64_C(0X0000000000000001))
@@ -3818,15 +2901,12 @@
 #define RGX_CR_SLC_CTRL_FLUSH_INVAL_LAZY_SHIFT            (31U)
 #define RGX_CR_SLC_CTRL_FLUSH_INVAL_LAZY_CLRMSK           (0X7FFFFFFFU)
 #define RGX_CR_SLC_CTRL_FLUSH_INVAL_LAZY_EN               (0X80000000U)
-#if defined(RGX_FEATURE_RAY_TRACING)
 #define RGX_CR_SLC_CTRL_FLUSH_INVAL_DM_RAY_VERTEX_SHIFT   (10U)
 #define RGX_CR_SLC_CTRL_FLUSH_INVAL_DM_RAY_VERTEX_CLRMSK  (0XFFFFFBFFU)
 #define RGX_CR_SLC_CTRL_FLUSH_INVAL_DM_RAY_VERTEX_EN      (0X00000400U)
 #define RGX_CR_SLC_CTRL_FLUSH_INVAL_DM_RAY_SHIFT          (9U)
 #define RGX_CR_SLC_CTRL_FLUSH_INVAL_DM_RAY_CLRMSK         (0XFFFFFDFFU)
 #define RGX_CR_SLC_CTRL_FLUSH_INVAL_DM_RAY_EN             (0X00000200U)
-#endif /* RGX_FEATURE_RAY_TRACING */
-
 #define RGX_CR_SLC_CTRL_FLUSH_INVAL_DM_FRC_SHIFT          (8U)
 #define RGX_CR_SLC_CTRL_FLUSH_INVAL_DM_FRC_CLRMSK         (0XFFFFFEFFU)
 #define RGX_CR_SLC_CTRL_FLUSH_INVAL_DM_FRC_EN             (0X00000100U)
@@ -3842,12 +2922,9 @@
 #define RGX_CR_SLC_CTRL_FLUSH_INVAL_DM_MMU_SHIFT          (4U)
 #define RGX_CR_SLC_CTRL_FLUSH_INVAL_DM_MMU_CLRMSK         (0XFFFFFFEFU)
 #define RGX_CR_SLC_CTRL_FLUSH_INVAL_DM_MMU_EN             (0X00000010U)
-#if defined(RGX_FEATURE_COMPUTE)
 #define RGX_CR_SLC_CTRL_FLUSH_INVAL_DM_COMPUTE_SHIFT      (3U)
 #define RGX_CR_SLC_CTRL_FLUSH_INVAL_DM_COMPUTE_CLRMSK     (0XFFFFFFF7U)
 #define RGX_CR_SLC_CTRL_FLUSH_INVAL_DM_COMPUTE_EN         (0X00000008U)
-#endif /* RGX_FEATURE_COMPUTE */
-
 #define RGX_CR_SLC_CTRL_FLUSH_INVAL_DM_PIXEL_SHIFT        (2U)
 #define RGX_CR_SLC_CTRL_FLUSH_INVAL_DM_PIXEL_CLRMSK       (0XFFFFFFFBU)
 #define RGX_CR_SLC_CTRL_FLUSH_INVAL_DM_PIXEL_EN           (0X00000004U)
@@ -3880,15 +2957,12 @@
 */
 #define RGX_CR_SLC_CTRL_BYPASS                            (0x3828U)
 #define RGX_CR_SLC_CTRL_BYPASS_MASKFULL                   (IMG_UINT64_C(0x000000000FFFFFFF))
-#if defined(RGX_FEATURE_RAY_TRACING)
 #define RGX_CR_SLC_CTRL_BYPASS_DM_RAY_VERTEX_SHIFT        (27U)
 #define RGX_CR_SLC_CTRL_BYPASS_DM_RAY_VERTEX_CLRMSK       (0XF7FFFFFFU)
 #define RGX_CR_SLC_CTRL_BYPASS_DM_RAY_VERTEX_EN           (0X08000000U)
 #define RGX_CR_SLC_CTRL_BYPASS_DM_RAY_SHIFT               (26U)
 #define RGX_CR_SLC_CTRL_BYPASS_DM_RAY_CLRMSK              (0XFBFFFFFFU)
 #define RGX_CR_SLC_CTRL_BYPASS_DM_RAY_EN                  (0X04000000U)
-#endif /* RGX_FEATURE_RAY_TRACING */
-
 #define RGX_CR_SLC_CTRL_BYPASS_REQ_IPF_CPF_SHIFT          (25U)
 #define RGX_CR_SLC_CTRL_BYPASS_REQ_IPF_CPF_CLRMSK         (0XFDFFFFFFU)
 #define RGX_CR_SLC_CTRL_BYPASS_REQ_IPF_CPF_EN             (0X02000000U)
@@ -3955,12 +3029,9 @@
 #define RGX_CR_SLC_CTRL_BYPASS_DM_MMU_SHIFT               (4U)
 #define RGX_CR_SLC_CTRL_BYPASS_DM_MMU_CLRMSK              (0XFFFFFFEFU)
 #define RGX_CR_SLC_CTRL_BYPASS_DM_MMU_EN                  (0X00000010U)
-#if defined(RGX_FEATURE_COMPUTE)
 #define RGX_CR_SLC_CTRL_BYPASS_DM_COMPUTE_SHIFT           (3U)
 #define RGX_CR_SLC_CTRL_BYPASS_DM_COMPUTE_CLRMSK          (0XFFFFFFF7U)
 #define RGX_CR_SLC_CTRL_BYPASS_DM_COMPUTE_EN              (0X00000008U)
-#endif /* RGX_FEATURE_COMPUTE */
-
 #define RGX_CR_SLC_CTRL_BYPASS_DM_PIXEL_SHIFT             (2U)
 #define RGX_CR_SLC_CTRL_BYPASS_DM_PIXEL_CLRMSK            (0XFFFFFFFBU)
 #define RGX_CR_SLC_CTRL_BYPASS_DM_PIXEL_EN                (0X00000004U)
@@ -4056,6 +3127,177 @@
 
 
 /*
+    Register RGX_CR_USC_UVS0_CHECKSUM
+*/
+#define RGX_CR_USC_UVS0_CHECKSUM                          (0x5000U)
+#define RGX_CR_USC_UVS0_CHECKSUM_MASKFULL                 (IMG_UINT64_C(0x00000000FFFFFFFF))
+#define RGX_CR_USC_UVS0_CHECKSUM_VALUE_SHIFT              (0U)
+#define RGX_CR_USC_UVS0_CHECKSUM_VALUE_CLRMSK             (00000000U)
+
+
+/*
+    Register RGX_CR_USC_UVS1_CHECKSUM
+*/
+#define RGX_CR_USC_UVS1_CHECKSUM                          (0x5008U)
+#define RGX_CR_USC_UVS1_CHECKSUM_MASKFULL                 (IMG_UINT64_C(0x00000000FFFFFFFF))
+#define RGX_CR_USC_UVS1_CHECKSUM_VALUE_SHIFT              (0U)
+#define RGX_CR_USC_UVS1_CHECKSUM_VALUE_CLRMSK             (00000000U)
+
+
+/*
+    Register RGX_CR_USC_UVS2_CHECKSUM
+*/
+#define RGX_CR_USC_UVS2_CHECKSUM                          (0x5010U)
+#define RGX_CR_USC_UVS2_CHECKSUM_MASKFULL                 (IMG_UINT64_C(0x00000000FFFFFFFF))
+#define RGX_CR_USC_UVS2_CHECKSUM_VALUE_SHIFT              (0U)
+#define RGX_CR_USC_UVS2_CHECKSUM_VALUE_CLRMSK             (00000000U)
+
+
+/*
+    Register RGX_CR_USC_UVS3_CHECKSUM
+*/
+#define RGX_CR_USC_UVS3_CHECKSUM                          (0x5018U)
+#define RGX_CR_USC_UVS3_CHECKSUM_MASKFULL                 (IMG_UINT64_C(0x00000000FFFFFFFF))
+#define RGX_CR_USC_UVS3_CHECKSUM_VALUE_SHIFT              (0U)
+#define RGX_CR_USC_UVS3_CHECKSUM_VALUE_CLRMSK             (00000000U)
+
+
+/*
+    Register RGX_CR_PPP_SIGNATURE
+*/
+#define RGX_CR_PPP_SIGNATURE                              (0x5020U)
+#define RGX_CR_PPP_SIGNATURE_MASKFULL                     (IMG_UINT64_C(0x00000000FFFFFFFF))
+#define RGX_CR_PPP_SIGNATURE_VALUE_SHIFT                  (0U)
+#define RGX_CR_PPP_SIGNATURE_VALUE_CLRMSK                 (00000000U)
+
+
+/*
+    Register RGX_CR_TE_SIGNATURE
+*/
+#define RGX_CR_TE_SIGNATURE                               (0x5028U)
+#define RGX_CR_TE_SIGNATURE_MASKFULL                      (IMG_UINT64_C(0x00000000FFFFFFFF))
+#define RGX_CR_TE_SIGNATURE_VALUE_SHIFT                   (0U)
+#define RGX_CR_TE_SIGNATURE_VALUE_CLRMSK                  (00000000U)
+
+
+/*
+    Register RGX_CR_TE_CHECKSUM
+*/
+#define RGX_CR_TE_CHECKSUM                                (0x5110U)
+#define RGX_CR_TE_CHECKSUM_MASKFULL                       (IMG_UINT64_C(0x00000000FFFFFFFF))
+#define RGX_CR_TE_CHECKSUM_VALUE_SHIFT                    (0U)
+#define RGX_CR_TE_CHECKSUM_VALUE_CLRMSK                   (00000000U)
+
+
+/*
+    Register RGX_CR_USC_UVB_CHECKSUM
+*/
+#define RGX_CR_USC_UVB_CHECKSUM                           (0x5118U)
+#define RGX_CR_USC_UVB_CHECKSUM_MASKFULL                  (IMG_UINT64_C(0x00000000FFFFFFFF))
+#define RGX_CR_USC_UVB_CHECKSUM_VALUE_SHIFT               (0U)
+#define RGX_CR_USC_UVB_CHECKSUM_VALUE_CLRMSK              (00000000U)
+
+
+/*
+    Register RGX_CR_VCE_CHECKSUM
+*/
+#define RGX_CR_VCE_CHECKSUM                               (0x5030U)
+#define RGX_CR_VCE_CHECKSUM_MASKFULL                      (IMG_UINT64_C(0x00000000FFFFFFFF))
+#define RGX_CR_VCE_CHECKSUM_VALUE_SHIFT                   (0U)
+#define RGX_CR_VCE_CHECKSUM_VALUE_CLRMSK                  (00000000U)
+
+
+/*
+    Register RGX_CR_ISP_PDS_CHECKSUM
+*/
+#define RGX_CR_ISP_PDS_CHECKSUM                           (0x5038U)
+#define RGX_CR_ISP_PDS_CHECKSUM_MASKFULL                  (IMG_UINT64_C(0x00000000FFFFFFFF))
+#define RGX_CR_ISP_PDS_CHECKSUM_VALUE_SHIFT               (0U)
+#define RGX_CR_ISP_PDS_CHECKSUM_VALUE_CLRMSK              (00000000U)
+
+
+/*
+    Register RGX_CR_ISP_TPF_CHECKSUM
+*/
+#define RGX_CR_ISP_TPF_CHECKSUM                           (0x5040U)
+#define RGX_CR_ISP_TPF_CHECKSUM_MASKFULL                  (IMG_UINT64_C(0x00000000FFFFFFFF))
+#define RGX_CR_ISP_TPF_CHECKSUM_VALUE_SHIFT               (0U)
+#define RGX_CR_ISP_TPF_CHECKSUM_VALUE_CLRMSK              (00000000U)
+
+
+/*
+    Register RGX_CR_TFPU_PLANE0_CHECKSUM
+*/
+#define RGX_CR_TFPU_PLANE0_CHECKSUM                       (0x5048U)
+#define RGX_CR_TFPU_PLANE0_CHECKSUM_MASKFULL              (IMG_UINT64_C(0x00000000FFFFFFFF))
+#define RGX_CR_TFPU_PLANE0_CHECKSUM_VALUE_SHIFT           (0U)
+#define RGX_CR_TFPU_PLANE0_CHECKSUM_VALUE_CLRMSK          (00000000U)
+
+
+/*
+    Register RGX_CR_TFPU_PLANE1_CHECKSUM
+*/
+#define RGX_CR_TFPU_PLANE1_CHECKSUM                       (0x5050U)
+#define RGX_CR_TFPU_PLANE1_CHECKSUM_MASKFULL              (IMG_UINT64_C(0x00000000FFFFFFFF))
+#define RGX_CR_TFPU_PLANE1_CHECKSUM_VALUE_SHIFT           (0U)
+#define RGX_CR_TFPU_PLANE1_CHECKSUM_VALUE_CLRMSK          (00000000U)
+
+
+/*
+    Register RGX_CR_PBE_CHECKSUM
+*/
+#define RGX_CR_PBE_CHECKSUM                               (0x5058U)
+#define RGX_CR_PBE_CHECKSUM_MASKFULL                      (IMG_UINT64_C(0x00000000FFFFFFFF))
+#define RGX_CR_PBE_CHECKSUM_VALUE_SHIFT                   (0U)
+#define RGX_CR_PBE_CHECKSUM_VALUE_CLRMSK                  (00000000U)
+
+
+/*
+    Register RGX_CR_PDS_DOUTM_STM_SIGNATURE
+*/
+#define RGX_CR_PDS_DOUTM_STM_SIGNATURE                    (0x5060U)
+#define RGX_CR_PDS_DOUTM_STM_SIGNATURE_MASKFULL           (IMG_UINT64_C(0x00000000FFFFFFFF))
+#define RGX_CR_PDS_DOUTM_STM_SIGNATURE_VALUE_SHIFT        (0U)
+#define RGX_CR_PDS_DOUTM_STM_SIGNATURE_VALUE_CLRMSK       (00000000U)
+
+
+/*
+    Register RGX_CR_IFPU_ISP_CHECKSUM
+*/
+#define RGX_CR_IFPU_ISP_CHECKSUM                          (0x5068U)
+#define RGX_CR_IFPU_ISP_CHECKSUM_MASKFULL                 (IMG_UINT64_C(0x00000000FFFFFFFF))
+#define RGX_CR_IFPU_ISP_CHECKSUM_VALUE_SHIFT              (0U)
+#define RGX_CR_IFPU_ISP_CHECKSUM_VALUE_CLRMSK             (00000000U)
+
+
+/*
+    Register RGX_CR_USC_UVS4_CHECKSUM
+*/
+#define RGX_CR_USC_UVS4_CHECKSUM                          (0x5100U)
+#define RGX_CR_USC_UVS4_CHECKSUM_MASKFULL                 (IMG_UINT64_C(0x00000000FFFFFFFF))
+#define RGX_CR_USC_UVS4_CHECKSUM_VALUE_SHIFT              (0U)
+#define RGX_CR_USC_UVS4_CHECKSUM_VALUE_CLRMSK             (00000000U)
+
+
+/*
+    Register RGX_CR_USC_UVS5_CHECKSUM
+*/
+#define RGX_CR_USC_UVS5_CHECKSUM                          (0x5108U)
+#define RGX_CR_USC_UVS5_CHECKSUM_MASKFULL                 (IMG_UINT64_C(0x00000000FFFFFFFF))
+#define RGX_CR_USC_UVS5_CHECKSUM_VALUE_SHIFT              (0U)
+#define RGX_CR_USC_UVS5_CHECKSUM_VALUE_CLRMSK             (00000000U)
+
+
+/*
+    Register RGX_CR_PPP_CLIP_CHECKSUM
+*/
+#define RGX_CR_PPP_CLIP_CHECKSUM                          (0x5120U)
+#define RGX_CR_PPP_CLIP_CHECKSUM_MASKFULL                 (IMG_UINT64_C(0x00000000FFFFFFFF))
+#define RGX_CR_PPP_CLIP_CHECKSUM_VALUE_SHIFT              (0U)
+#define RGX_CR_PPP_CLIP_CHECKSUM_VALUE_CLRMSK             (00000000U)
+
+
+/*
     Register RGX_CR_PERF_TA_PHASE
 */
 #define RGX_CR_PERF_TA_PHASE                              (0x6008U)
@@ -4652,7 +3894,6 @@
 #define RGX_CR_JONES_IDLE_BIF_EN                          (0X00000001U)
 
 
-#if defined(RGX_FEATURE_CLUSTER_GROUPING)
 /*
     Register RGX_CR_TORNADO_PERF
 */
@@ -4757,8 +3998,6 @@
 #define RGX_CR_TEXAS_PERF_COUNTER_0_REG_CLRMSK            (00000000U)
 
 
-#endif /* RGX_FEATURE_CLUSTER_GROUPING */
-
 /*
     Register RGX_CR_JONES_PERF
 */
@@ -4808,7 +4047,6 @@
 #define RGX_CR_JONES_PERF_COUNTER_0_REG_CLRMSK            (00000000U)
 
 
-#if defined(RGX_FEATURE_CLUSTER_GROUPING)
 /*
     Register RGX_CR_BLACKPEARL_PERF
 */
@@ -4864,8 +4102,6 @@
 #define RGX_CR_BLACKPEARL_PERF_COUNTER_0_REG_CLRMSK       (00000000U)
 
 
-#endif /* RGX_FEATURE_CLUSTER_GROUPING */
-
 /*
     Register RGX_CR_PBE_PERF
 */
@@ -5279,7 +4515,6 @@
 */
 #define RGX_CR_BIF_TRUST                                  (0xA000U)
 #define RGX_CR_BIF_TRUST_MASKFULL                         (IMG_UINT64_C(0x00000000001FFFFF))
-#if defined(RGX_FEATURE_RAY_TRACING)
 #define RGX_CR_BIF_TRUST_OTHER_RAY_VERTEX_DM_TRUSTED_SHIFT (20U)
 #define RGX_CR_BIF_TRUST_OTHER_RAY_VERTEX_DM_TRUSTED_CLRMSK (0XFFEFFFFFU)
 #define RGX_CR_BIF_TRUST_OTHER_RAY_VERTEX_DM_TRUSTED_EN   (0X00100000U)
@@ -5292,14 +4527,11 @@
 #define RGX_CR_BIF_TRUST_MCU_RAY_DM_TRUSTED_SHIFT         (17U)
 #define RGX_CR_BIF_TRUST_MCU_RAY_DM_TRUSTED_CLRMSK        (0XFFFDFFFFU)
 #define RGX_CR_BIF_TRUST_MCU_RAY_DM_TRUSTED_EN            (0X00020000U)
-#endif /* RGX_FEATURE_RAY_TRACING */
-
 #define RGX_CR_BIF_TRUST_ENABLE_SHIFT                     (16U)
 #define RGX_CR_BIF_TRUST_ENABLE_CLRMSK                    (0XFFFEFFFFU)
 #define RGX_CR_BIF_TRUST_ENABLE_EN                        (0X00010000U)
 #define RGX_CR_BIF_TRUST_DM_TRUSTED_SHIFT                 (9U)
 #define RGX_CR_BIF_TRUST_DM_TRUSTED_CLRMSK                (0XFFFF01FFU)
-#if defined(RGX_FEATURE_COMPUTE)
 #define RGX_CR_BIF_TRUST_OTHER_COMPUTE_DM_TRUSTED_SHIFT   (8U)
 #define RGX_CR_BIF_TRUST_OTHER_COMPUTE_DM_TRUSTED_CLRMSK  (0XFFFFFEFFU)
 #define RGX_CR_BIF_TRUST_OTHER_COMPUTE_DM_TRUSTED_EN      (0X00000100U)
@@ -5309,8 +4541,6 @@
 #define RGX_CR_BIF_TRUST_PBE_COMPUTE_DM_TRUSTED_SHIFT     (6U)
 #define RGX_CR_BIF_TRUST_PBE_COMPUTE_DM_TRUSTED_CLRMSK    (0XFFFFFFBFU)
 #define RGX_CR_BIF_TRUST_PBE_COMPUTE_DM_TRUSTED_EN        (0X00000040U)
-#endif /* RGX_FEATURE_COMPUTE */
-
 #define RGX_CR_BIF_TRUST_OTHER_PIXEL_DM_TRUSTED_SHIFT     (5U)
 #define RGX_CR_BIF_TRUST_OTHER_PIXEL_DM_TRUSTED_CLRMSK    (0XFFFFFFDFU)
 #define RGX_CR_BIF_TRUST_OTHER_PIXEL_DM_TRUSTED_EN        (0X00000020U)
@@ -5335,6 +4565,7 @@
     Register RGX_CR_SYS_BUS_SECURE
 */
 #define RGX_CR_SYS_BUS_SECURE                             (0xA100U)
+#define RGX_CR_SYS_BUS_SECURE__SECR__MASKFULL             (IMG_UINT64_C(0x0000000000000001))
 #define RGX_CR_SYS_BUS_SECURE_MASKFULL                    (IMG_UINT64_C(0x0000000000000001))
 #define RGX_CR_SYS_BUS_SECURE_ENABLE_SHIFT                (0U)
 #define RGX_CR_SYS_BUS_SECURE_ENABLE_CLRMSK               (0XFFFFFFFEU)
@@ -5342,53 +4573,85 @@
 
 
 /*
+    Register RGX_CR_FBA_FC0_CHECKSUM
+*/
+#define RGX_CR_FBA_FC0_CHECKSUM                           (0xD170U)
+#define RGX_CR_FBA_FC0_CHECKSUM_MASKFULL                  (IMG_UINT64_C(0x00000000FFFFFFFF))
+#define RGX_CR_FBA_FC0_CHECKSUM_VALUE_SHIFT               (0U)
+#define RGX_CR_FBA_FC0_CHECKSUM_VALUE_CLRMSK              (00000000U)
+
+
+/*
+    Register RGX_CR_FBA_FC1_CHECKSUM
+*/
+#define RGX_CR_FBA_FC1_CHECKSUM                           (0xD178U)
+#define RGX_CR_FBA_FC1_CHECKSUM_MASKFULL                  (IMG_UINT64_C(0x00000000FFFFFFFF))
+#define RGX_CR_FBA_FC1_CHECKSUM_VALUE_SHIFT               (0U)
+#define RGX_CR_FBA_FC1_CHECKSUM_VALUE_CLRMSK              (00000000U)
+
+
+/*
+    Register RGX_CR_FBA_FC2_CHECKSUM
+*/
+#define RGX_CR_FBA_FC2_CHECKSUM                           (0xD180U)
+#define RGX_CR_FBA_FC2_CHECKSUM_MASKFULL                  (IMG_UINT64_C(0x00000000FFFFFFFF))
+#define RGX_CR_FBA_FC2_CHECKSUM_VALUE_SHIFT               (0U)
+#define RGX_CR_FBA_FC2_CHECKSUM_VALUE_CLRMSK              (00000000U)
+
+
+/*
+    Register RGX_CR_FBA_FC3_CHECKSUM
+*/
+#define RGX_CR_FBA_FC3_CHECKSUM                           (0xD188U)
+#define RGX_CR_FBA_FC3_CHECKSUM_MASKFULL                  (IMG_UINT64_C(0x00000000FFFFFFFF))
+#define RGX_CR_FBA_FC3_CHECKSUM_VALUE_SHIFT               (0U)
+#define RGX_CR_FBA_FC3_CHECKSUM_VALUE_CLRMSK              (00000000U)
+
+
+/*
     Register RGX_CR_CLK_CTRL2
 */
 #define RGX_CR_CLK_CTRL2                                  (0xD200U)
 #define RGX_CR_CLK_CTRL2_MASKFULL                         (IMG_UINT64_C(0x0000000000000F33))
 #define RGX_CR_CLK_CTRL2_MCU_FBTC_SHIFT                   (10U)
 #define RGX_CR_CLK_CTRL2_MCU_FBTC_CLRMSK                  (IMG_UINT64_C(0XFFFFFFFFFFFFF3FF))
-#define RGX_CR_CLK_CTRL2_MCU_FBTC_OFF                     (IMG_UINT64_C(0000000000000000))
-#define RGX_CR_CLK_CTRL2_MCU_FBTC_ON                      (IMG_UINT64_C(0x0000000000000400))
-#define RGX_CR_CLK_CTRL2_MCU_FBTC_AUTO                    (IMG_UINT64_C(0x0000000000000800))
-#if defined(RGX_FEATURE_RAY_TRACING)
+#define RGX_CR_CLK_CTRL2_MCU_FBTC_OFF                     (IMG_UINT64_C(0000000000000000))  
+#define RGX_CR_CLK_CTRL2_MCU_FBTC_ON                      (IMG_UINT64_C(0x0000000000000400))  
+#define RGX_CR_CLK_CTRL2_MCU_FBTC_AUTO                    (IMG_UINT64_C(0x0000000000000800))  
 #define RGX_CR_CLK_CTRL2_VRDM_SHIFT                       (8U)
 #define RGX_CR_CLK_CTRL2_VRDM_CLRMSK                      (IMG_UINT64_C(0XFFFFFFFFFFFFFCFF))
-#define RGX_CR_CLK_CTRL2_VRDM_OFF                         (IMG_UINT64_C(0000000000000000))
-#define RGX_CR_CLK_CTRL2_VRDM_ON                          (IMG_UINT64_C(0x0000000000000100))
-#define RGX_CR_CLK_CTRL2_VRDM_AUTO                        (IMG_UINT64_C(0x0000000000000200))
+#define RGX_CR_CLK_CTRL2_VRDM_OFF                         (IMG_UINT64_C(0000000000000000))  
+#define RGX_CR_CLK_CTRL2_VRDM_ON                          (IMG_UINT64_C(0x0000000000000100))  
+#define RGX_CR_CLK_CTRL2_VRDM_AUTO                        (IMG_UINT64_C(0x0000000000000200))  
 #define RGX_CR_CLK_CTRL2_SH_SHIFT                         (4U)
 #define RGX_CR_CLK_CTRL2_SH_CLRMSK                        (IMG_UINT64_C(0XFFFFFFFFFFFFFFCF))
-#define RGX_CR_CLK_CTRL2_SH_OFF                           (IMG_UINT64_C(0000000000000000))
-#define RGX_CR_CLK_CTRL2_SH_ON                            (IMG_UINT64_C(0x0000000000000010))
-#define RGX_CR_CLK_CTRL2_SH_AUTO                          (IMG_UINT64_C(0x0000000000000020))
+#define RGX_CR_CLK_CTRL2_SH_OFF                           (IMG_UINT64_C(0000000000000000))  
+#define RGX_CR_CLK_CTRL2_SH_ON                            (IMG_UINT64_C(0x0000000000000010))  
+#define RGX_CR_CLK_CTRL2_SH_AUTO                          (IMG_UINT64_C(0x0000000000000020))  
 #define RGX_CR_CLK_CTRL2_FBA_SHIFT                        (0U)
 #define RGX_CR_CLK_CTRL2_FBA_CLRMSK                       (IMG_UINT64_C(0XFFFFFFFFFFFFFFFC))
-#define RGX_CR_CLK_CTRL2_FBA_OFF                          (IMG_UINT64_C(0000000000000000))
-#define RGX_CR_CLK_CTRL2_FBA_ON                           (IMG_UINT64_C(0x0000000000000001))
-#define RGX_CR_CLK_CTRL2_FBA_AUTO                         (IMG_UINT64_C(0x0000000000000002))
+#define RGX_CR_CLK_CTRL2_FBA_OFF                          (IMG_UINT64_C(0000000000000000))  
+#define RGX_CR_CLK_CTRL2_FBA_ON                           (IMG_UINT64_C(0x0000000000000001))  
+#define RGX_CR_CLK_CTRL2_FBA_AUTO                         (IMG_UINT64_C(0x0000000000000002))  
 
 
-#endif /* RGX_FEATURE_RAY_TRACING */
-
 /*
     Register RGX_CR_CLK_STATUS2
 */
 #define RGX_CR_CLK_STATUS2                                (0xD208U)
 #define RGX_CR_CLK_STATUS2_MASKFULL                       (IMG_UINT64_C(0x0000000000000015))
-#if defined(RGX_FEATURE_RAY_TRACING)
 #define RGX_CR_CLK_STATUS2_VRDM_SHIFT                     (4U)
 #define RGX_CR_CLK_STATUS2_VRDM_CLRMSK                    (IMG_UINT64_C(0XFFFFFFFFFFFFFFEF))
-#define RGX_CR_CLK_STATUS2_VRDM_GATED                     (IMG_UINT64_C(0000000000000000))
-#define RGX_CR_CLK_STATUS2_VRDM_RUNNING                   (IMG_UINT64_C(0x0000000000000010))
+#define RGX_CR_CLK_STATUS2_VRDM_GATED                     (IMG_UINT64_C(0000000000000000))  
+#define RGX_CR_CLK_STATUS2_VRDM_RUNNING                   (IMG_UINT64_C(0x0000000000000010))  
 #define RGX_CR_CLK_STATUS2_SH_SHIFT                       (2U)
 #define RGX_CR_CLK_STATUS2_SH_CLRMSK                      (IMG_UINT64_C(0XFFFFFFFFFFFFFFFB))
-#define RGX_CR_CLK_STATUS2_SH_GATED                       (IMG_UINT64_C(0000000000000000))
-#define RGX_CR_CLK_STATUS2_SH_RUNNING                     (IMG_UINT64_C(0x0000000000000004))
+#define RGX_CR_CLK_STATUS2_SH_GATED                       (IMG_UINT64_C(0000000000000000))  
+#define RGX_CR_CLK_STATUS2_SH_RUNNING                     (IMG_UINT64_C(0x0000000000000004))  
 #define RGX_CR_CLK_STATUS2_FBA_SHIFT                      (0U)
 #define RGX_CR_CLK_STATUS2_FBA_CLRMSK                     (IMG_UINT64_C(0XFFFFFFFFFFFFFFFE))
-#define RGX_CR_CLK_STATUS2_FBA_GATED                      (IMG_UINT64_C(0000000000000000))
-#define RGX_CR_CLK_STATUS2_FBA_RUNNING                    (IMG_UINT64_C(0x0000000000000001))
+#define RGX_CR_CLK_STATUS2_FBA_GATED                      (IMG_UINT64_C(0000000000000000))  
+#define RGX_CR_CLK_STATUS2_FBA_RUNNING                    (IMG_UINT64_C(0x0000000000000001))  
 
 
 /*
@@ -5465,9 +4728,6 @@
 #define RGX_CR_RPM_SHG_FPL_WRITE_OFFSET_CLRMSK            (0XFFC00000U)
 
 
-#endif /* RGX_FEATURE_RAY_TRACING */
-
-#if defined(RGX_FEATURE_CLUSTER_GROUPING)
 /*
     Register RGX_CR_SH_PERF
 */
@@ -5517,9 +4777,60 @@
 #define RGX_CR_SH_PERF_COUNTER_0_REG_CLRMSK               (00000000U)
 
 
-#endif /* RGX_FEATURE_CLUSTER_GROUPING */
+/*
+    Register RGX_CR_SHF_SHG_CHECKSUM
+*/
+#define RGX_CR_SHF_SHG_CHECKSUM                           (0xD1C0U)
+#define RGX_CR_SHF_SHG_CHECKSUM_MASKFULL                  (IMG_UINT64_C(0x00000000FFFFFFFF))
+#define RGX_CR_SHF_SHG_CHECKSUM_VALUE_SHIFT               (0U)
+#define RGX_CR_SHF_SHG_CHECKSUM_VALUE_CLRMSK              (00000000U)
 
-#if defined(RGX_FEATURE_RAY_TRACING)
+
+/*
+    Register RGX_CR_SHF_VERTEX_BIF_CHECKSUM
+*/
+#define RGX_CR_SHF_VERTEX_BIF_CHECKSUM                    (0xD1C8U)
+#define RGX_CR_SHF_VERTEX_BIF_CHECKSUM_MASKFULL           (IMG_UINT64_C(0x00000000FFFFFFFF))
+#define RGX_CR_SHF_VERTEX_BIF_CHECKSUM_VALUE_SHIFT        (0U)
+#define RGX_CR_SHF_VERTEX_BIF_CHECKSUM_VALUE_CLRMSK       (00000000U)
+
+
+/*
+    Register RGX_CR_SHF_VARY_BIF_CHECKSUM
+*/
+#define RGX_CR_SHF_VARY_BIF_CHECKSUM                      (0xD1D0U)
+#define RGX_CR_SHF_VARY_BIF_CHECKSUM_MASKFULL             (IMG_UINT64_C(0x00000000FFFFFFFF))
+#define RGX_CR_SHF_VARY_BIF_CHECKSUM_VALUE_SHIFT          (0U)
+#define RGX_CR_SHF_VARY_BIF_CHECKSUM_VALUE_CLRMSK         (00000000U)
+
+
+/*
+    Register RGX_CR_RPM_BIF_CHECKSUM
+*/
+#define RGX_CR_RPM_BIF_CHECKSUM                           (0xD1D8U)
+#define RGX_CR_RPM_BIF_CHECKSUM_MASKFULL                  (IMG_UINT64_C(0x00000000FFFFFFFF))
+#define RGX_CR_RPM_BIF_CHECKSUM_VALUE_SHIFT               (0U)
+#define RGX_CR_RPM_BIF_CHECKSUM_VALUE_CLRMSK              (00000000U)
+
+
+/*
+    Register RGX_CR_SHG_BIF_CHECKSUM
+*/
+#define RGX_CR_SHG_BIF_CHECKSUM                           (0xD1E0U)
+#define RGX_CR_SHG_BIF_CHECKSUM_MASKFULL                  (IMG_UINT64_C(0x00000000FFFFFFFF))
+#define RGX_CR_SHG_BIF_CHECKSUM_VALUE_SHIFT               (0U)
+#define RGX_CR_SHG_BIF_CHECKSUM_VALUE_CLRMSK              (00000000U)
+
+
+/*
+    Register RGX_CR_SHG_FE_BE_CHECKSUM
+*/
+#define RGX_CR_SHG_FE_BE_CHECKSUM                         (0xD1E8U)
+#define RGX_CR_SHG_FE_BE_CHECKSUM_MASKFULL                (IMG_UINT64_C(0x00000000FFFFFFFF))
+#define RGX_CR_SHG_FE_BE_CHECKSUM_VALUE_SHIFT             (0U)
+#define RGX_CR_SHG_FE_BE_CHECKSUM_VALUE_CLRMSK            (00000000U)
+
+
 /*
     Register DPX_CR_BF_PERF
 */
@@ -5619,6 +4930,15 @@
 
 
 /*
+    Register DPX_CR_RQ_USC_DEBUG
+*/
+#define DPX_CR_RQ_USC_DEBUG                               (0xC110U)
+#define DPX_CR_RQ_USC_DEBUG_MASKFULL                      (IMG_UINT64_C(0x00000000FFFFFFFF))
+#define DPX_CR_RQ_USC_DEBUG_CHECKSUM_SHIFT                (0U)
+#define DPX_CR_RQ_USC_DEBUG_CHECKSUM_CLRMSK               (IMG_UINT64_C(0XFFFFFFFF00000000))
+
+
+/*
     Register DPX_CR_BIF_FAULT_BANK_MMU_STATUS
 */
 #define DPX_CR_BIF_FAULT_BANK_MMU_STATUS                  (0xC5C8U)
@@ -5778,7 +5098,14 @@
 #define DPX_CR_BX_TU_PERF_COUNTER_0_REG_CLRMSK            (00000000U)
 
 
-#endif /* RGX_FEATURE_RAY_TRACING */
+/*
+    Register DPX_CR_RS_PDS_RR_CHECKSUM
+*/
+#define DPX_CR_RS_PDS_RR_CHECKSUM                         (0xC0F0U)
+#define DPX_CR_RS_PDS_RR_CHECKSUM_MASKFULL                (IMG_UINT64_C(0x00000000FFFFFFFF))
+#define DPX_CR_RS_PDS_RR_CHECKSUM_VALUE_SHIFT             (0U)
+#define DPX_CR_RS_PDS_RR_CHECKSUM_VALUE_CLRMSK            (IMG_UINT64_C(0XFFFFFFFF00000000))
+
 
 /*
     Register RGX_CR_MMU_CBASE_MAPPING_CONTEXT
@@ -5971,11 +5298,8 @@
 */
 #define RGX_CR_CONTEXT_MAPPING0                           (0xF078U)
 #define RGX_CR_CONTEXT_MAPPING0_MASKFULL                  (IMG_UINT64_C(0x00000000FFFFFFFF))
-#if defined(RGX_FEATURE_FASTRENDER_DM)
 #define RGX_CR_CONTEXT_MAPPING0_2D_SHIFT                  (24U)
 #define RGX_CR_CONTEXT_MAPPING0_2D_CLRMSK                 (0X00FFFFFFU)
-#endif /* RGX_FEATURE_FASTRENDER_DM */
-
 #define RGX_CR_CONTEXT_MAPPING0_CDM_SHIFT                 (16U)
 #define RGX_CR_CONTEXT_MAPPING0_CDM_CLRMSK                (0XFF00FFFFU)
 #define RGX_CR_CONTEXT_MAPPING0_3D_SHIFT                  (8U)
diff --git a/drivers/staging/imgtec/rogue/hwdefs/km/rgxdefs_km.h b/drivers/staging/imgtec/rogue/hwdefs/km/rgxdefs_km.h
index 788dbb0..cb61624 100644
--- a/drivers/staging/imgtec/rogue/hwdefs/km/rgxdefs_km.h
+++ b/drivers/staging/imgtec/rogue/hwdefs/km/rgxdefs_km.h
@@ -46,34 +46,77 @@
 #include RGX_BNC_CONFIG_KM_HEADER
 
 #define __IMG_EXPLICIT_INCLUDE_HWDEFS
+#if defined(__KERNEL__)
 #include "rgx_cr_defs_km.h"
+#else
+#include RGX_BVNC_CORE_HEADER
+#include RGX_BNC_CONFIG_HEADER
+#include "rgx_cr_defs.h"
+#endif
 #undef __IMG_EXPLICIT_INCLUDE_HWDEFS
 
+/* The following Macros are picked up through BVNC headers for PDUMP and
+ * no hardware operations to be compatible with old build infrastructure.
+ */
+#if defined(PDUMP) || defined(NO_HARDWARE) || !defined(SUPPORT_MULTIBVNC_RUNTIME_BVNC_ACQUISITION)
 /******************************************************************************
  * Check for valid B.X.N.C
  *****************************************************************************/
 #if !defined(RGX_BVNC_KM_B) || !defined(RGX_BVNC_KM_V) || !defined(RGX_BVNC_KM_N) || !defined(RGX_BVNC_KM_C)
 #error "Need to specify BVNC (RGX_BVNC_KM_B, RGX_BVNC_KM_V, RGX_BVNC_KM_N and RGX_BVNC_C)"
 #endif
+#endif
 
+#if defined(PDUMP) || defined(NO_HARDWARE)
 /* Check core/config compatibility */
-#if (RGX_BVNC_KM_B != RGX_BNC_KM_B) || (RGX_BVNC_KM_N != RGX_BNC_KM_N) || (RGX_BVNC_KM_C != RGX_BNC_KM_C) 
+#if (RGX_BVNC_KM_B != RGX_BNC_KM_B) || (RGX_BVNC_KM_N != RGX_BNC_KM_N) || (RGX_BVNC_KM_C != RGX_BNC_KM_C)
 #error "BVNC headers are mismatching (KM core/config)"
 #endif
 
+#endif
+
 /******************************************************************************
  * RGX Version name
  *****************************************************************************/
 #define _RGX_BVNC_ST2(S)	#S
 #define _RGX_BVNC_ST(S)		_RGX_BVNC_ST2(S)
+#if defined(PDUMP) || defined(NO_HARDWARE) || defined(PVRSRV_GPUVIRT_GUESTDRV) || !defined(SUPPORT_MULTIBVNC_RUNTIME_BVNC_ACQUISITION)
 #define RGX_BVNC_KM			_RGX_BVNC_ST(RGX_BVNC_KM_B) "." _RGX_BVNC_ST(RGX_BVNC_KM_V) "." _RGX_BVNC_ST(RGX_BVNC_KM_N) "." _RGX_BVNC_ST(RGX_BVNC_KM_C)
+#endif
 #define RGX_BVNC_KM_V_ST	_RGX_BVNC_ST(RGX_BVNC_KM_V)
 
 /******************************************************************************
  * RGX Defines
  *****************************************************************************/
 
-#if defined(RGX_FEATURE_META)
+#define			BVNC_FIELD_MASK			((1 << BVNC_FIELD_WIDTH) - 1)
+#define         C_POSITION              (0)
+#define         N_POSITION              ((C_POSITION) + (BVNC_FIELD_WIDTH))
+#define         V_POSITION              ((N_POSITION) + (BVNC_FIELD_WIDTH))
+#define         B_POSITION              ((V_POSITION) + (BVNC_FIELD_WIDTH))
+
+#define         B_POSTION_MASK          (((IMG_UINT64)(BVNC_FIELD_MASK) << (B_POSITION)))
+#define         V_POSTION_MASK          (((IMG_UINT64)(BVNC_FIELD_MASK) << (V_POSITION)))
+#define         N_POSTION_MASK          (((IMG_UINT64)(BVNC_FIELD_MASK) << (N_POSITION)))
+#define         C_POSTION_MASK          (((IMG_UINT64)(BVNC_FIELD_MASK) << (C_POSITION)))
+
+#define         GET_B(x)                (((x) & (B_POSTION_MASK)) >> (B_POSITION))
+#define         GET_V(x)                (((x) & (V_POSTION_MASK)) >> (V_POSITION))
+#define         GET_N(x)                (((x) & (N_POSTION_MASK)) >> (N_POSITION))
+#define         GET_C(x)                (((x) & (C_POSTION_MASK)) >> (C_POSITION))
+
+#define         BVNC_PACK(B,V,N,C)      ((((IMG_UINT64)B)) << (B_POSITION) | \
+                                         (((IMG_UINT64)V)) << (V_POSITION) | \
+                                         (((IMG_UINT64)N)) << (N_POSITION) | \
+                                         (((IMG_UINT64)C)) << (C_POSITION) \
+                                        )
+
+#define RGX_CR_CORE_ID_CONFIG_N_SHIFT                     (8U)
+#define RGX_CR_CORE_ID_CONFIG_C_SHIFT                     (0U)
+
+#define RGX_CR_CORE_ID_CONFIG_N_CLRMSK                    (0XFFFF00FFU)
+#define RGX_CR_CORE_ID_CONFIG_C_CLRMSK                    (0XFFFFFF00U)
+
 /* META cores (required for the RGX_FEATURE_META) */
 #define MTP218   (1)
 #define MTP219   (2)
@@ -84,30 +127,33 @@
 #define RGX_META_COREMEM_32K      (32*1024)
 #define RGX_META_COREMEM_48K      (48*1024)
 #define RGX_META_COREMEM_64K      (64*1024)
+#define RGX_META_COREMEM_128K     (128*1024)
 #define RGX_META_COREMEM_256K     (256*1024)
 
-#if !defined(SUPPORT_TRUSTED_DEVICE)
+#if !defined(__KERNEL__)
+#if (!defined(SUPPORT_TRUSTED_DEVICE) || defined(RGX_FEATURE_META_DMA)) && (RGX_FEATURE_META_COREMEM_SIZE != 0)
 #define RGX_META_COREMEM_SIZE     (RGX_FEATURE_META_COREMEM_SIZE*1024)
-#else
-#define RGX_META_COREMEM_SIZE     (0)
-#endif
-
-#if (RGX_FEATURE_META_COREMEM_SIZE != 0) && !defined(SUPPORT_TRUSTED_DEVICE)
 #define RGX_META_COREMEM          (1)
 #define RGX_META_COREMEM_CODE     (1)
 #if !defined(FIX_HW_BRN_50767)
 #define RGX_META_COREMEM_DATA     (1)
 #endif
+#else
+#undef SUPPORT_META_COREMEM
+#undef RGX_FEATURE_META_COREMEM_SIZE
+#undef RGX_FEATURE_META_DMA
+#define RGX_FEATURE_META_COREMEM_SIZE (0)
+#define RGX_META_COREMEM_SIZE         (0)
 #endif
-
-#endif  /*RGX_FEATURE_META*/
+#endif
 
 /* ISP requires valid state on all three pipes regardless of the number of
  * active pipes/tiles in flight.
  */
 #define RGX_MAX_NUM_PIPES	3
 
-#define ROGUE_CACHE_LINE_SIZE				((RGX_FEATURE_SLC_CACHE_LINE_SIZE_BITS)/8)
+#define GET_ROGUE_CACHE_LINE_SIZE(x)				((x)/8)
+
 
 #define MAX_HW_TA3DCONTEXTS	2
 
@@ -116,8 +162,6 @@
 #define RGX_CR_CLK_CTRL_ALL_ON   (IMG_UINT64_C(0x5555555555555555)&RGX_CR_CLK_CTRL_MASKFULL)
 #define RGX_CR_CLK_CTRL_ALL_AUTO (IMG_UINT64_C(0xaaaaaaaaaaaaaaaa)&RGX_CR_CLK_CTRL_MASKFULL)
 
-#define RGX_MAX_DUST		MAX(1, RGX_FEATURE_NUM_CLUSTERS/2)
-
 #define RGX_CR_SOFT_RESET_DUST_n_CORE_EN	(RGX_CR_SOFT_RESET_DUST_A_CORE_EN | \
 											 RGX_CR_SOFT_RESET_DUST_B_CORE_EN | \
 											 RGX_CR_SOFT_RESET_DUST_C_CORE_EN | \
@@ -133,7 +177,7 @@
 
 
 
-#if defined(RGX_FEATURE_S7_TOP_INFRASTRUCTURE)
+
 /* SOFT_RESET steps as defined in the TRM */
 #define RGX_S7_SOFT_RESET_DUSTS (RGX_CR_SOFT_RESET_DUST_n_CORE_EN)
 
@@ -150,7 +194,7 @@
                             RGX_CR_SOFT_RESET2_PIXEL_EN | \
 							RGX_CR_SOFT_RESET2_CDM_EN | \
 							RGX_CR_SOFT_RESET2_VERTEX_EN)
-#endif
+
 
 
 #define RGX_BIF_PM_PHYSICAL_PAGE_ALIGNSHIFT		(12)
@@ -167,17 +211,51 @@
 #define RGX_REQ_NUM_BERNADOS(CLUSTERS) ((CLUSTERS + 3) / 4)
 #define RGX_REQ_NUM_BLACKPEARLS(CLUSTERS) ((CLUSTERS + 3) / 4)
 
+#if  defined(SUPPORT_KERNEL_SRVINIT) && defined(__KERNEL__)
+	#define RGX_GET_NUM_PHANTOMS(x)	 (RGX_REQ_NUM_PHANTOMS(x))
 #if defined(RGX_FEATURE_CLUSTER_GROUPING)
-#define RGX_NUM_PHANTOMS (RGX_REQ_NUM_PHANTOMS(RGX_FEATURE_NUM_CLUSTERS))
+	#define RGX_NUM_PHANTOMS (RGX_REQ_NUM_PHANTOMS(RGX_FEATURE_NUM_CLUSTERS))
 #else
-#define RGX_NUM_PHANTOMS (1)
+	#define RGX_NUM_PHANTOMS (1)
+#endif
+#else
+	#if defined(RGX_FEATURE_CLUSTER_GROUPING)
+	#define RGX_NUM_PHANTOMS (RGX_REQ_NUM_PHANTOMS(RGX_FEATURE_NUM_CLUSTERS))
+	#else
+	#define RGX_NUM_PHANTOMS (1)
+	#endif
+	#define RGX_GET_NUM_PHANTOMS(x)	 (RGX_REQ_NUM_PHANTOMS(RGX_FEATURE_NUM_CLUSTERS))
 #endif
 
-/* Temporary until RGX_FEATURE_CDM_CONTROL_STREAM_FORMAT is defined for all cores. */
+
+/* RGX_FEATURE_CDM_CONTROL_STREAM_FORMAT is not defined for format 1 cores (so define it now). */
 #if !defined(RGX_FEATURE_CDM_CONTROL_STREAM_FORMAT)
 #define RGX_FEATURE_CDM_CONTROL_STREAM_FORMAT (1)
 #endif
 
+/* META second thread feature depending on META variants and available CoreMem*/
+#if defined(RGX_FEATURE_META) && (RGX_FEATURE_META == MTP218 || RGX_FEATURE_META == MTP219) && defined(RGX_FEATURE_S7_TOP_INFRASTRUCTURE) && (RGX_FEATURE_META_COREMEM_SIZE == 256)
+#define RGXFW_META_SUPPORT_2ND_THREAD
+#endif
+
+/*
+   Start at 903GiB. Size of 32MB per OSID (see rgxheapconfig.h)
+   NOTE:
+		The firmware heap base and size is defined here to
+		simplify #include dependencies, see rgxheapconfig.h
+		for the full RGX virtual address space layout.
+*/
+#define RGX_FIRMWARE_HEAP_BASE			IMG_UINT64_C(0xE1C0000000)
+#define RGX_FIRMWARE_HEAP_SIZE			(1<<RGX_FW_HEAP_SHIFT)
+#define RGX_FIRMWARE_HEAP_SHIFT			RGX_FW_HEAP_SHIFT
+
+/* Default number of OSIDs is 1 unless GPU Virtualization is supported and enabled */
+#if defined(SUPPORT_PVRSRV_GPUVIRT) && !defined(PVRSRV_GPUVIRT_GUESTDRV) && (PVRSRV_GPUVIRT_NUM_OSID +1> 1)
+#define RGXFW_NUM_OS PVRSRV_GPUVIRT_NUM_OSID
+#else
+#define RGXFW_NUM_OS 1
+#endif
+
 /******************************************************************************
  * WA HWBRNs
  *****************************************************************************/
@@ -188,15 +266,30 @@
 #undef RGX_CR_SOFT_RESET_SLC_SHIFT
 
 /* Remove the SOFT_RESET_SLC_EN bit from SOFT_RESET_MASKFULL */
-#undef RGX_CR_SOFT_RESET_MASKFULL 
+#undef RGX_CR_SOFT_RESET_MASKFULL
 #define RGX_CR_SOFT_RESET_MASKFULL IMG_UINT64_C(0x000001FFF7FFFC1D)
 
 #endif /* FIX_HW_BRN_36492 */
 
+
+#if defined(RGX_CR_JONES_IDLE_MASKFULL)
+/* Workaround for HW BRN 57289 */
+#if (RGX_CR_JONES_IDLE_MASKFULL != 0x0000000000007FFF)
+#error This WA must be updated if RGX_CR_JONES_IDLE is expanded!!!
+#endif
+#undef RGX_CR_JONES_IDLE_MASKFULL
+#undef RGX_CR_JONES_IDLE_TDM_SHIFT
+#undef RGX_CR_JONES_IDLE_TDM_CLRMSK
+#undef RGX_CR_JONES_IDLE_TDM_EN
+#define RGX_CR_JONES_IDLE_MASKFULL                        (IMG_UINT64_C(0x0000000000003FFF))
+#endif
+
+
 #define DPX_MAX_RAY_CONTEXTS 4 /* FIXME should this be in dpx file? */
 #define DPX_MAX_FBA_AP 16
 #define DPX_MAX_FBA_FILTER_WIDTH 24
 
+#if !defined(__KERNEL__)
 #if !defined(RGX_FEATURE_SLC_SIZE_IN_BYTES)
 #if defined(RGX_FEATURE_SLC_SIZE_IN_KILOBYTES)
 #define RGX_FEATURE_SLC_SIZE_IN_BYTES (RGX_FEATURE_SLC_SIZE_IN_KILOBYTES * 1024)
@@ -204,5 +297,7 @@
 #define RGX_FEATURE_SLC_SIZE_IN_BYTES (0)
 #endif
 #endif
+#endif
+
 
 #endif /* _RGXDEFS_KM_H_ */
diff --git a/drivers/staging/imgtec/rogue/hwdefs/km/rgxmmudefs_km.h b/drivers/staging/imgtec/rogue/hwdefs/km/rgxmmudefs_km.h
index 7419db5..fca692d 100644
--- a/drivers/staging/imgtec/rogue/hwdefs/km/rgxmmudefs_km.h
+++ b/drivers/staging/imgtec/rogue/hwdefs/km/rgxmmudefs_km.h
@@ -42,7 +42,7 @@
 /*               ****   Autogenerated C -- do not edit    ****               */
 
 /*
- * Generated by regconv version MAIN@2782796
+ * Generated by regconv version MAIN@3328745
  *   from files:
  *      rogue_bif.def 
  *      rogue_bif.def 
diff --git a/drivers/staging/imgtec/rogue/img_3dtypes.h b/drivers/staging/imgtec/rogue/img_3dtypes.h
index d082c78..c940ff3 100644
--- a/drivers/staging/imgtec/rogue/img_3dtypes.h
+++ b/drivers/staging/imgtec/rogue/img_3dtypes.h
@@ -44,6 +44,8 @@
 #ifndef __IMG_3DTYPES_H__
 #define __IMG_3DTYPES_H__
 
+#include <powervr/buffer_attribs.h>
+
 /**
  * Comparison functions
  * This comparison function is defined as:
@@ -85,19 +87,6 @@
 } IMG_STENCILOP;
 
 /**
- * Memory layout enumeration.
- * Defines how pixels are laid out within a surface.
- */
-typedef enum _IMG_MEMLAYOUT_
-{
-	IMG_MEMLAYOUT_STRIDED,			/**< Resource is strided, one row at a time */
-    IMG_MEMLAYOUT_TWIDDLED,			/**< Resource is 2D twiddled, classic style */
-    IMG_MEMLAYOUT_3DTWIDDLED,       /**< Resource is 3D twiddled, classic style */
-	IMG_MEMLAYOUT_TILED,			/**< Resource is tiled, tiling config specified elsewhere. */
-	IMG_MEMLAYOUT_PAGETILED,		/**< Resource is pagetiled */
-} IMG_MEMLAYOUT;
-
-/**
  * Alpha blending allows colours and textures on one surface
  * to be blended with transparency onto another surface.
  * These definitions apply to both source and destination blending
@@ -217,19 +206,24 @@
 	IMG_CULLMODE_BACKFACING,	/**< Back facing triangles */
 } IMG_CULLMODE;
 
-/**
- * Rotation clockwise
- */
-typedef enum _IMG_ROTATION_
-{
-	IMG_ROTATION_0DEG = 0,
-	IMG_ROTATION_90DEG = 1,
-	IMG_ROTATION_180DEG = 2,
-	IMG_ROTATION_270DEG = 3,
-	IMG_ROTATION_FLIP_Y = 4,
 
-	IMG_ROTATION_BAD = 255,
-} IMG_ROTATION;
+/*! ************************************************************************//**
+@brief          Specifies the MSAA resolve operation.
+*/ /**************************************************************************/
+typedef enum _IMG_RESOLVE_OP_
+{
+	IMG_RESOLVE_BLEND   = 0,          /*!< box filter on the samples */
+	IMG_RESOLVE_MIN     = 1,          /*!< minimum of the samples */
+	IMG_RESOLVE_MAX     = 2,          /*!< maximum of the samples */
+	IMG_RESOLVE_SAMPLE0 = 3,          /*!< choose sample 0 */
+	IMG_RESOLVE_SAMPLE1 = 4,          /*!< choose sample 1 */
+	IMG_RESOLVE_SAMPLE2 = 5,          /*!< choose sample 2 */
+	IMG_RESOLVE_SAMPLE3 = 6,          /*!< choose sample 3 */
+	IMG_RESOLVE_SAMPLE4 = 7,          /*!< choose sample 4 */
+	IMG_RESOLVE_SAMPLE5 = 8,          /*!< choose sample 5 */
+	IMG_RESOLVE_SAMPLE6 = 9,          /*!< choose sample 6 */
+	IMG_RESOLVE_SAMPLE7 = 10,         /*!< choose sample 7 */
+} IMG_RESOLVE_OP;
 
 
 #endif /* __IMG_3DTYPES_H__ */
diff --git a/drivers/staging/imgtec/rogue/img_defs.h b/drivers/staging/imgtec/rogue/img_defs.h
index 155f0c3..398c2f6 100644
--- a/drivers/staging/imgtec/rogue/img_defs.h
+++ b/drivers/staging/imgtec/rogue/img_defs.h
@@ -52,6 +52,12 @@
 #if defined (NO_INLINE_FUNCS)
 	#define	INLINE
 	#define	FORCE_INLINE
+#elif defined(INTEGRITY_OS)
+	#ifndef INLINE
+	#define	INLINE
+	#endif
+	#define	FORCE_INLINE			static
+	#define INLINE_IS_PRAGMA
 #else
 #if defined (__cplusplus)
 	#define INLINE					inline
@@ -76,6 +82,13 @@
 		__GNUC__ > (major) ||									\
 		(__GNUC__ == (major) && __GNUC_MINOR__ >= (minor))))
 
+/* Ensure Clang's __has_extension macro is defined for all compilers so we
+ * can use it safely in preprocessor conditionals.
+ */
+#if !defined(__has_extension)
+#define __has_extension(e) 0
+#endif
+
 /* Use this in any file, or use attributes under GCC - see below */
 #ifndef PVR_UNREFERENCED_PARAMETER
 #define	PVR_UNREFERENCED_PARAMETER(param) ((void)(param))
@@ -98,12 +111,20 @@
 #if !defined(static_assert) && !defined(_MSC_VER) && \
 		(!defined(__cplusplus) || __cplusplus < 201103L)
 	/* static_assert isn't already available */
-	#if GCC_VERSION_AT_LEAST(4, 6) && !defined(__cplusplus)
+	#if !defined(__cplusplus) && (GCC_VERSION_AT_LEAST(4, 6) || \
+								  (defined(__clang__) && __has_extension(c_static_assert)))
 		#define static_assert _Static_assert
 	#else
 		#define static_assert(expr, message) \
 			extern int _static_assert_failed[2*!!(expr) - 1] __attribute__((unused))
 	#endif
+#else
+#if defined(CONFIG_L4)
+	/* Defined but not compatible with DDK usage
+	   so undefine & ignore */
+	#undef static_assert
+	#define static_assert(expr, message)
+#endif
 #endif
 
 /*! Macro to calculate the n-byte aligned value from that supplied rounding up.
@@ -114,26 +135,6 @@
  */
 #define PVR_ALIGN(_x, _n)   (((_x)+((_n)-1)) & ~((_n)-1))
 
-
-/* The best way to supress unused parameter warnings using GCC is to use a
- * variable attribute.  Place the unref__ between the type and name of an
- * unused parameter in a function parameter list, eg `int unref__ var'. This
- * should only be used in GCC build environments, for example, in files that
- * compile only on Linux. Other files should use UNREFERENCED_PARAMETER */
-#ifdef __GNUC__
-#define unref__ __attribute__ ((unused))
-#else
-#define unref__
-#endif
-
-#if __GNUC__ >= 3
-# define IMG_LIKELY(x) __builtin_expect (!!(x), 1)
-# define IMG_UNLIKELY(x) __builtin_expect (!!(x), 0)
-#else
-# define IMG_LIKELY(x) (x)
-# define IMG_UNLIKELY(x) (x)
-#endif
-
 #if defined(_WIN32)
 
 #if defined(WINDOWS_WDF)
@@ -189,12 +190,6 @@
 			_CRTIMP void __cdecl abort(void);
 		#endif
 	#endif
-	#if defined(EXIT_ON_ABORT)
-		#define IMG_ABORT()	exit(1);
-	#else
-		#define IMG_ABORT()	abort();
-	#endif
-//	#define IMG_ABORT()	img_abort()
 #endif /* UNDER_WDDM */
 #else
 	#if defined(LINUX) || defined(__METAG) || defined(__QNXNTO__)
@@ -210,6 +205,21 @@
 		#define IMG_IMPORT
 		#define IMG_RESTRICT	__restrict__
 
+	#elif defined(INTEGRITY_OS)
+		#define IMG_CALLCONV
+		#define IMG_INTERNAL
+		#define IMG_EXPORT
+		#define IMG_RESTRICT
+		#define C_CALLCONV
+		#define __cdecl
+		/* IMG_IMPORT is defined as IMG_EXPORT so that headers and implementations match.
+		 * Some compilers require the header to be declared IMPORT, while the implementation is declared EXPORT 
+		 */
+		#define	IMG_IMPORT	IMG_EXPORT 
+		#ifndef USE_CODE
+		#define IMG_ABORT()	printf("IMG_ABORT was called.\n")
+
+		#endif
 	#else
 		#error("define an OS")
 	#endif
@@ -224,30 +234,97 @@
 	#endif
 #endif
 
-#if defined(__GNUC__)
-#define IMG_FORMAT_PRINTF(x,y)		__attribute__((format(printf,x,y)))
-#else
-#define IMG_FORMAT_PRINTF(x,y)
-#endif
+/* The best way to suppress unused parameter warnings using GCC is to use a
+ * variable attribute.  Place the __maybe_unused between the type and name of an
+ * unused parameter in a function parameter list, eg `int __maybe_unused var'. This
+ * should only be used in GCC build environments, for example, in files that
+ * compile only on Linux. Other files should use PVR_UNREFERENCED_PARAMETER */
 
-#if defined(__GNUC__)
-#define IMG_WARN_UNUSED_RESULT		__attribute__((warn_unused_result))
-#else
-#define IMG_WARN_UNUSED_RESULT
-#endif
+/* Kernel macros for compiler attributes */
+/* Note: param positions start at 1 */
+#if defined(LINUX) && defined(__KERNEL__)
+	#include <linux/compiler.h>
+#elif defined(__GNUC__) || defined(HAS_GNUC_ATTRIBUTES)
+	#define __must_check       __attribute__((warn_unused_result))
+	#define __maybe_unused     __attribute__((unused))
+	#define __malloc           __attribute__((malloc))
 
-#if defined(_MSC_VER) || defined(CC_ARM)
-	#define IMG_NORETURN __declspec(noreturn)
-#else
-	#if defined(__GNUC__)
-		#define IMG_NORETURN __attribute__((noreturn))
-	#else
-		#define IMG_NORETURN
+	/* Bionic's <sys/cdefs.h> might have defined these already */
+	#if !defined(__packed)
+		#define __packed           __attribute__((packed))
 	#endif
+	#if !defined(__aligned)
+		#define __aligned(n)       __attribute__((aligned(n)))
+	#endif
+
+	/* That one compiler that supports attributes but doesn't support
+	 * the printf attribute... */
+	#if defined(__GNUC__)
+		#define __printf(fmt, va)  __attribute__((format(printf, fmt, va)))
+	#else
+		#define __printf(fmt, va)
+	#endif /* defined(__GNUC__) */
+
+#else
+	/* Silently ignore those attributes */
+	#define __printf(fmt, va)
+	#define __packed
+	#define __aligned(n)
+	#define __must_check
+	#define __maybe_unused
+	#define __malloc
 #endif
 
+
+/* Other attributes, following the same style */
+#if defined(__GNUC__) || defined(HAS_GNUC_ATTRIBUTES)
+	#define __param_nonnull(...)  __attribute__((nonnull(__VA_ARGS__)))
+	#define __returns_nonnull     __attribute__((returns_nonnull))
+#else
+	#define __param_nonnull(...)
+	#define __returns_nonnull
+#endif
+
+
+/* GCC builtins */
+#if defined(LINUX) && defined(__KERNEL__)
+	#include <linux/compiler.h>
+#elif defined(__GNUC__)
+	#define likely(x)   __builtin_expect(!!(x), 1)
+	#define unlikely(x) __builtin_expect(!!(x), 0)
+
+	/* Compiler memory barrier to prevent reordering */
+	#define barrier() __asm__ __volatile__("": : :"memory")
+#else
+	#define barrier() do { static_assert(0, "barrier() isn't supported by your compiler"); } while(0)
+#endif
+
+/* That one OS that defines one but not the other... */
+#ifndef likely
+	#define likely(x)   (x)
+#endif
+#ifndef unlikely
+	#define unlikely(x) (x)
+#endif
+
+
+#if defined(__noreturn)
+	/* Already defined by the Kernel */
+#elif defined(_MSC_VER) || defined(CC_ARM)
+	#define __noreturn __declspec(noreturn)
+#elif defined(__GNUC__) || defined(HAS_GNUC_ATTRIBUTES)
+	#define __noreturn __attribute__((noreturn))
+#else
+	#define __noreturn
+#endif
+
+#ifndef MAX
 #define MAX(a,b) 					(((a) > (b)) ? (a) : (b))
+#endif
+
+#ifndef MIN
 #define MIN(a,b) 					(((a) < (b)) ? (a) : (b))
+#endif
 
 /* Get a structures address from the address of a member */
 #define IMG_CONTAINER_OF(ptr, type, member) \
@@ -272,21 +349,61 @@
 	void operator=(const C&)
 #endif
 
-#if defined(SUPPORT_PVR_VALGRIND)
-	#if !defined(__METAG)
-		#include "/usr/include/valgrind/memcheck.h"
+#if defined(SUPPORT_PVR_VALGRIND) && !defined(__METAG)
+	#include "/usr/include/valgrind/memcheck.h"
 
-		#define VALGRIND_HEADER_PRESENT
-
-		#define VG_MARK_INITIALIZED(pvData,ui32Size)  VALGRIND_MAKE_MEM_DEFINED(pvData,ui32Size)
-	#else
-		#define VG_MARK_INITIALIZED(pvData,ui32Size) do { } while(0)
-	#endif
+	#define VG_MARK_INITIALIZED(pvData,ui32Size)  VALGRIND_MAKE_MEM_DEFINED(pvData,ui32Size)
+	#define VG_MARK_NOACCESS(pvData,ui32Size) VALGRIND_MAKE_MEM_NOACCESS(pvData,ui32Size)
+	#define VG_MARK_ACCESS(pvData,ui32Size) VALGRIND_MAKE_MEM_UNDEFINED(pvData,ui32Size)
 #else
+	#if defined(_MSC_VER)
+	#	define PVR_MSC_SUPPRESS_4127 __pragma(warning(suppress:4127))
+	#else
+	#	define PVR_MSC_SUPPRESS_4127
+	#endif
 
-	#define VG_MARK_INITIALIZED(pvData,ui32Size) do { } while(0)
+	#define VG_MARK_INITIALIZED(pvData,ui32Size) PVR_MSC_SUPPRESS_4127 do { } while(0)
+	#define VG_MARK_NOACCESS(pvData,ui32Size) PVR_MSC_SUPPRESS_4127 do { } while(0)
+	#define VG_MARK_ACCESS(pvData,ui32Size) PVR_MSC_SUPPRESS_4127 do { } while(0)
 #endif
 
+#define _STRINGIFY(x) # x
+#define IMG_STRINGIFY(x) _STRINGIFY(x)
+
+#if defined(INTEGRITY_OS)
+	/* Definitions not present in INTEGRITY. */
+	#define PATH_MAX	200
+#endif
+
+#if defined (__clang__) || defined (__GNUC__)
+	/* __SIZEOF_POINTER__ is defined already by these compilers */
+#elif defined (INTEGRITY_OS)
+	#if defined (__Ptr_Is_64)
+		#define __SIZEOF_POINTER__ 8
+	#else
+		#define __SIZEOF_POINTER__ 4
+	#endif
+#elif defined(_WIN32)
+	#define __SIZEOF_POINTER__ sizeof(char *)
+#else
+	#warning Unknown OS - using default method to determine whether CPU arch is 64-bit.
+	#define __SIZEOF_POINTER__ sizeof(char *)
+#endif
+
+/* RDI8567: clang/llvm load/store optimisations cause issues with device
+ * memory allocations. Some pointers are made 'volatile' to prevent
+ * this optimisations being applied to writes through that particular pointer.
+ */
+#if defined(__clang__) && defined(__aarch64__)
+#define NOLDSTOPT volatile
+/* after applying 'volatile' to a pointer, we may need to cast it to 'void *'
+ * to keep it compatible with its existing uses
+ */
+#define NOLDSTOPT_VOID (void *)
+#else
+#define NOLDSTOPT
+#define NOLDSTOPT_VOID
+#endif
 
 #endif /* #if !defined (__IMG_DEFS_H__) */
 /*****************************************************************************
diff --git a/drivers/staging/imgtec/rogue/img_types.h b/drivers/staging/imgtec/rogue/img_types.h
index ddb02f2..06fbff1 100644
--- a/drivers/staging/imgtec/rogue/img_types.h
+++ b/drivers/staging/imgtec/rogue/img_types.h
@@ -64,8 +64,9 @@
 #if defined(_MSC_VER)
 	#include "msvc_types.h"
 #elif defined(LINUX) && defined(__KERNEL__)
+	#include <linux/types.h>
 	#include "kernel_types.h"
-#elif defined(LINUX) || defined(__METAG) || defined(__QNXNTO__)
+#elif defined(LINUX) || defined(__METAG) || defined(__QNXNTO__) || defined(INTEGRITY_OS)
 	#include <stddef.h>			/* NULL */
 	#include <inttypes.h>		/* intX_t/uintX_t, format specifiers */
 	#include <limits.h>			/* INT_MIN, etc */
@@ -126,9 +127,8 @@
 	IMG_FORCE_ALIGN = 0x7FFFFFFF
 } IMG_BOOL, *IMG_PBOOL;
 
-#if !defined(LINUX)
+#if defined(UNDER_WDDM) || defined(WINDOWS_WDF)
 typedef void            IMG_VOID, *IMG_PVOID;
-typedef IMG_VOID const* IMG_PCVOID;
 
 typedef uintptr_t		IMG_UINTPTR_T;
 typedef size_t			IMG_SIZE_T;
@@ -137,11 +137,6 @@
 #define IMG_NULL		NULL
 
 typedef IMG_CHAR const* IMG_PCCHAR;
-typedef IMG_UINT16 const* IMG_PCUINT16;
-typedef IMG_INT16 const* IMG_PCINT16;
-typedef IMG_UINT32 const* IMG_PCUINT32;
-typedef IMG_INT32 const* IMG_PCINT32;
-typedef IMG_BOOL const* IMG_PCBOOL;
 #endif
 
 #if defined(_MSC_VER)
@@ -213,21 +208,6 @@
  *
  */
 
-typedef void *IMG_CPU_VIRTADDR;
-
-/* device virtual address */
-typedef struct _IMG_DEV_VIRTADDR
-{
-	IMG_UINT64  uiAddr;
-#define IMG_CAST_TO_DEVVADDR_UINT(var)		(IMG_UINT64)(var)
-	
-} IMG_DEV_VIRTADDR;
-
-typedef IMG_UINT64 IMG_DEVMEM_SIZE_T;
-typedef IMG_UINT64 IMG_DEVMEM_ALIGN_T;
-typedef IMG_UINT64 IMG_DEVMEM_OFFSET_T;
-typedef IMG_UINT32 IMG_DEVMEM_LOG2ALIGN_T;
-
 #define IMG_DEV_VIRTADDR_FMTSPEC "0x%010" IMG_UINT64_FMTSPECX
 #define IMG_DEVMEM_SIZE_FMTSPEC "0x%010" IMG_UINT64_FMTSPECX
 #define IMG_DEVMEM_ALIGN_FMTSPEC "0x%010" IMG_UINT64_FMTSPECX
@@ -239,6 +219,9 @@
 #if defined(UNDER_WDDM) || defined(WINDOWS_WDF)
 	uintptr_t uiAddr;
 #define IMG_CAST_TO_CPUPHYADDR_UINT(var)		(uintptr_t)(var)
+#elif defined(LINUX) && defined(__KERNEL__)
+	phys_addr_t uiAddr;
+#define IMG_CAST_TO_CPUPHYADDR_UINT(var)		(phys_addr_t)(var)
 #else
 	IMG_UINT64 uiAddr;
 #define IMG_CAST_TO_CPUPHYADDR_UINT(var)		(IMG_UINT64)(var)
diff --git a/drivers/staging/imgtec/rogue/imgpixfmts_km.h b/drivers/staging/imgtec/rogue/imgpixfmts_km.h
deleted file mode 100644
index cd2df0a..0000000
--- a/drivers/staging/imgtec/rogue/imgpixfmts_km.h
+++ /dev/null
@@ -1,83 +0,0 @@
-/*************************************************************************/ /*!
-@File           imgpixfmts_km.h
-@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
-@License        Dual MIT/GPLv2
-
-The contents of this file are subject to the MIT license as set out below.
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-Alternatively, the contents of this file may be used under the terms of
-the GNU General Public License Version 2 ("GPL") in which case the provisions
-of GPL are applicable instead of those above.
-
-If you wish to allow use of your version of this file only under the terms of
-GPL, and not to allow others to use your version of this file under the terms
-of the MIT license, indicate your decision by deleting the provisions above
-and replace them with the notice and other provisions required by GPL as set
-out in the file called "GPL-COPYING" included in this distribution. If you do
-not delete the provisions above, a recipient may use your version of this file
-under the terms of either the MIT license or GPL.
-
-This License is also included in this distribution in the file called
-"MIT-COPYING".
-
-EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
-PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
-BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
-PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
-COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
-IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
-CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-*/ /**************************************************************************/
-
-/*****************************************************************************
- **
- ** WARNING: This file is autogenerated - DO NOT EDIT.
- **
- *****************************************************************************/
-
-#if !defined(_IMGPIXFMTS_KM_H_)
-#define _IMGPIXFMTS_KM_H_
-
-#include "imgyuv.h"
-
-
-typedef enum _IMG_PIXFMT_
-{
-	IMG_PIXFMT_UNKNOWN = 0,
-	IMG_PIXFMT_R8G8B8A8_UNORM = 31,
-	IMG_PIXFMT_R8G8B8X8_UNORM = 36,
-	IMG_PIXFMT_R8G8_UNORM = 61,
-	IMG_PIXFMT_R8_UNORM = 75,
-	IMG_PIXFMT_B5G6R5_UNORM = 84,
-	IMG_PIXFMT_B5G5R5A1_UNORM = 85,
-	IMG_PIXFMT_B5G5R5X1_UNORM = 86,
-	IMG_PIXFMT_B8G8R8A8_UNORM = 87,
-	IMG_PIXFMT_B8G8R8X8_UNORM = 88,
-	IMG_PIXFMT_B4G4R4A4_UNORM = 143,
-	IMG_PIXFMT_UYVY = 169,
-	IMG_PIXFMT_VYUY = 170,
-	IMG_PIXFMT_YUYV = 171,
-	IMG_PIXFMT_YVYU = 172,
-	IMG_PIXFMT_YVU420_2PLANE = 173,
-	IMG_PIXFMT_YUV420_2PLANE = 174,
-	IMG_PIXFMT_YVU420_2PLANE_MACRO_BLOCK = 175,
-	IMG_PIXFMT_YUV420_3PLANE = 176,
-	IMG_PIXFMT_YVU420_3PLANE = 177,
-	IMG_PIXFMT_V8U8Y8A8 = 182,
-	IMG_PIXFMT_YVU8_420_2PLANE_PACK8_P = 243,
-	IMG_PIXFMT_YUV8_420_2PLANE_PACK8_P = 247,
-	IMG_PIXFMT_UYVY10_422_1PLANE_PACK10_CUST1 = 250,
-	IMG_PIXFMT_R5G6B5_UNORM = 252,
-}	IMG_PIXFMT;
-
-#endif /* _IMGPIXFMTS_KM_H_ */
diff --git a/drivers/staging/imgtec/rogue/imgyuv.h b/drivers/staging/imgtec/rogue/imgyuv.h
deleted file mode 100644
index 0bc2e4d..0000000
--- a/drivers/staging/imgtec/rogue/imgyuv.h
+++ /dev/null
@@ -1,73 +0,0 @@
-/*************************************************************************/ /*!
-@File
-@Title          YUV defines
-@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
-@License        Dual MIT/GPLv2
-
-The contents of this file are subject to the MIT license as set out below.
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-Alternatively, the contents of this file may be used under the terms of
-the GNU General Public License Version 2 ("GPL") in which case the provisions
-of GPL are applicable instead of those above.
-
-If you wish to allow use of your version of this file only under the terms of
-GPL, and not to allow others to use your version of this file under the terms
-of the MIT license, indicate your decision by deleting the provisions above
-and replace them with the notice and other provisions required by GPL as set
-out in the file called "GPL-COPYING" included in this distribution. If you do
-not delete the provisions above, a recipient may use your version of this file
-under the terms of either the MIT license or GPL.
-
-This License is also included in this distribution in the file called
-"MIT-COPYING".
-
-EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
-PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
-BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
-PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
-COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
-IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
-CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-*/ /**************************************************************************/
-
-#if !defined(_IMGYUV_H_)
-#define _IMGYUV_H_
-
-typedef enum
-{
-	IMG_COLORSPACE_UNDEFINED = 0,
-	IMG_COLORSPACE_BT601_CONFORMANT_RANGE = 1,
-	IMG_COLORSPACE_BT601_FULL_RANGE = 2,
-	IMG_COLORSPACE_BT709_CONFORMANT_RANGE = 3,
-	IMG_COLORSPACE_BT709_FULL_RANGE = 4,
-	IMG_COLORSPACE_BT2020_CONFORMANT_RANGE = 5,
-	IMG_COLORSPACE_BT2020_FULL_RANGE = 6,
-	IMG_COLORSPACE_BT601_CONFORMANT_RANGE_INVERSE = 7,
-	IMG_COLORSPACE_BT601_FULL_RANGE_INVERSE = 8,
-	IMG_COLORSPACE_BT709_CONFORMANT_RANGE_INVERSE = 9,
-	IMG_COLORSPACE_BT709_FULL_RANGE_INVERSE = 10,
-	IMG_COLORSPACE_BT2020_CONFORMANT_RANGE_INVERSE = 11,
-	IMG_COLORSPACE_BT2020_FULL_RANGE_INVERSE = 12
-} IMG_YUV_COLORSPACE;
-
-typedef enum
-{
-	IMG_CHROMA_INTERP_UNDEFINED = 0,
-	IMG_CHROMA_INTERP_ZERO = 1,
-	IMG_CHROMA_INTERP_QUARTER = 2,
-	IMG_CHROMA_INTERP_HALF = 3,
-	IMG_CHROMA_INTERP_THREEQUARTERS = 4
-} IMG_YUV_CHROMA_INTERP;
-
-
-#endif /* _IMGYUV_H_ */
diff --git a/drivers/staging/imgtec/rogue/ioctl.c b/drivers/staging/imgtec/rogue/ioctl.c
index 67fe775..3ca1f93 100644
--- a/drivers/staging/imgtec/rogue/ioctl.c
+++ b/drivers/staging/imgtec/rogue/ioctl.c
@@ -133,7 +133,10 @@
 	psParams	= (PDBG_IN_FINDSTREAM)pvInBuffer;
 	phStream	= (IMG_SID *)pvOutBuffer;
 
-	*phStream = PStream2SID(ExtDBGDrivFindStream(WIDEPTR_GET_PTR(psParams->pszName, bCompat), psParams->bResetStream));
+	/* Ensure that the name will be NULL terminated */
+	psParams->pszName[DEBUG_STREAM_NAME_MAX-1] = '\0';
+
+	*phStream = PStream2SID(ExtDBGDrivFindStream(psParams->pszName, psParams->bResetStream));
 
 	return(IMG_TRUE);
 }
diff --git a/drivers/staging/imgtec/rogue/ion_sys.h b/drivers/staging/imgtec/rogue/ion_sys.h
index 9b0b32f..6eb76fa 100644
--- a/drivers/staging/imgtec/rogue/ion_sys.h
+++ b/drivers/staging/imgtec/rogue/ion_sys.h
@@ -46,7 +46,6 @@
 #define _ION_SYS_H_
 
 #include "pvrsrv_error.h"
-#include "img_types.h"
 #include PVR_ANDROID_ION_HEADER
 
 
@@ -56,19 +55,6 @@
 
 void IonDevRelease(struct ion_device *psIonDev);
 
-#if defined(LMA)
-IMG_DEV_PHYADDR IonCPUPhysToDevPhys(IMG_CPU_PHYADDR sCPUPhysAddr,
-									IMG_UINT32 ui32Offset);
-#else
-/* This is a no-op for UMA systems. */
-static inline
-IMG_DEV_PHYADDR IonCPUPhysToDevPhys(IMG_CPU_PHYADDR sCPUPhysAddr,
-									IMG_UINT32 ui32Offset)
-{
-	return (IMG_DEV_PHYADDR){ .uiAddr = sCPUPhysAddr.uiAddr + ui32Offset };
-}
-#endif
-
 void IonDeinit(void);
 
 #endif /* _ION_SYS_H_ */
diff --git a/drivers/staging/imgtec/rogue/kernel_compatibility.h b/drivers/staging/imgtec/rogue/kernel_compatibility.h
new file mode 100644
index 0000000..dc1a3aa
--- /dev/null
+++ b/drivers/staging/imgtec/rogue/kernel_compatibility.h
@@ -0,0 +1,189 @@
+/*************************************************************************/ /*!
+@File           services/server/env/linux/kernel_compatibility.h
+@Title          Kernel versions compatibility macros
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description    Per-version macros to allow code to seamlessly use older kernel
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#ifndef __KERNEL_COMPATIBILITY_H__
+#define __KERNEL_COMPATIBILITY_H__
+
+#include <linux/version.h>
+
+/*
+ * Stop supporting an old kernel? Remove the top block.
+ * New incompatible kernel?       Append a new block at the bottom.
+ *
+ * Please write you version test as `VERSION < X.Y`, and use the earliest
+ * possible version :)
+ */
+
+
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 7, 0))
+
+/* Linux 3.7 split VM_RESERVED into VM_DONTDUMP and VM_DONTEXPAND */
+#define VM_DONTDUMP VM_RESERVED
+
+#endif /* (LINUX_VERSION_CODE < KERNEL_VERSION(3, 7, 0)) */
+
+/*
+ * Note: this fix had to be written backwards because get_unused_fd_flags
+ * was already defined but not exported on kernels < 3.7
+ *
+ * When removing support for kernels < 3.7, this block should be removed
+ * and all `get_unused_fd()` should be manually replaced with
+ * `get_unused_fd_flags(0)`
+ */
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 19, 0))
+
+/* Linux 3.19 removed get_unused_fd() */
+/* get_unused_fd_flags  was introduced in 3.7 */
+#define get_unused_fd() get_unused_fd_flags(0)
+
+#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 19, 0)) */
+
+
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 12, 0))
+
+/* Linux 3.12 introduced a new shrinker API */
+#define SHRINK_STOP (~0UL)
+
+#endif /* (LINUX_VERSION_CODE < KERNEL_VERSION(3, 12, 0)) */
+
+
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 13, 0)) && defined(CONFIG_ARM)
+
+/* Linux 3.13 renamed ioremap_cached to ioremap_cache */
+#define ioremap_cache(cookie,size) ioremap_cached(cookie,size)
+
+#endif /* (LINUX_VERSION_CODE < KERNEL_VERSION(3, 13, 0)) && defined(CONFIG_ARM) */
+
+
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 17, 0))
+
+/* Linux 3.17 changed the 3rd argument from a `struct page ***pages` to
+ * `struct page **pages` */
+#define map_vm_area(area, prot, pages) map_vm_area(area, prot, &pages)
+
+#endif /* (LINUX_VERSION_CODE < KERNEL_VERSION(3, 17, 0)) */
+
+
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 19, 0))
+
+/*
+ * Linux 4.7 removed this function but its replacement was available since 3.19.
+ */
+#define drm_crtc_send_vblank_event(crtc, e) drm_send_vblank_event((crtc)->dev, drm_crtc_index(crtc), e)
+
+#endif /* (LINUX_VERSION_CODE < KERNEL_VERSION(3, 19, 0)) */
+
+
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 4, 0))
+
+/* Linux 4.4 renamed GFP_WAIT to GFP_RECLAIM */
+#define __GFP_RECLAIM __GFP_WAIT
+
+#endif /* (LINUX_VERSION_CODE < KERNEL_VERSION(4, 4, 0)) */
+
+
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 5, 0)) && !defined(CHROMIUMOS_WORKAROUNDS_KERNEL318)
+
+/* Linux 4.5 added a new printf-style parameter for debug messages */
+
+#define drm_encoder_init(dev, encoder, funcs, encoder_type, name, ...) \
+        drm_encoder_init(dev, encoder, funcs, encoder_type)
+
+#define drm_universal_plane_init(dev, plane, possible_crtcs, funcs, formats, format_count, type, name, ...) \
+        drm_universal_plane_init(dev, plane, possible_crtcs, funcs, formats, format_count, type)
+
+#define drm_crtc_init_with_planes(dev, crtc, primary, cursor, funcs, name, ...) \
+        drm_crtc_init_with_planes(dev, crtc, primary, cursor, funcs)
+
+#endif /* (LINUX_VERSION_CODE < KERNEL_VERSION(4, 5, 0)) */
+
+
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 6, 0)) && !defined(CHROMIUMOS_WORKAROUNDS_KERNEL318)
+
+/*
+ * Linux 4.6 removed the start and end arguments as it now always maps
+ * the entire DMA-BUF.
+ * Additionally, dma_buf_end_cpu_access() now returns an int error.
+ */
+#define dma_buf_begin_cpu_access(DMABUF, DIRECTION) dma_buf_begin_cpu_access(DMABUF, 0, DMABUF->size, DIRECTION)
+#define dma_buf_end_cpu_access(DMABUF, DIRECTION) ({ dma_buf_end_cpu_access(DMABUF, 0, DMABUF->size, DIRECTION); 0; })
+
+#endif /* (LINUX_VERSION_CODE < KERNEL_VERSION(4, 6, 0)) && !defined(CHROMIUMOS_WORKAROUNDS_KERNEL318) */
+
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 7, 0))
+
+/* Linux 4.7 removed the first arguments as it's never been used */
+#define drm_gem_object_lookup(filp, handle) drm_gem_object_lookup((filp)->minor->dev, filp, handle)
+
+/* Linux 4.7 replaced nla_put_u64 with nla_put_u64_64bit */
+#define nla_put_u64_64bit(skb, attrtype, value, padattr) nla_put_u64(skb, attrtype, value)
+
+#endif /* (LINUX_VERSION_CODE < KERNEL_VERSION(4, 7, 0)) */
+
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 9, 0))
+
+/* Linux 4.9 change the second argument to a drm_file pointer */
+#define drm_vma_node_is_allowed(node, file_priv) drm_vma_node_is_allowed(node, (file_priv)->filp)
+
+#endif /* (LINUX_VERSION_CODE < KERNEL_VERSION(4, 9, 0)) */
+
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 11, 0))
+static inline unsigned int refcount_read(const atomic_t *r)
+{
+	return atomic_read(r);
+}
+#define drm_mm_insert_node(mm, node, size) drm_mm_insert_node(mm, node, size, 0, DRM_MM_SEARCH_DEFAULT) 
+
+#define drm_helper_mode_fill_fb_struct(dev, fb, mode_cmd) drm_helper_mode_fill_fb_struct(fb, mode_cmd)
+#endif /* (LINUX_VERSION_CODE < KERNEL_VERSION(4, 11, 0)) */
+
+#if !defined(CHROMIUMOS_WORKAROUNDS_KERNEL318)
+#define dev_pm_opp_of_add_table of_init_opp_table
+#define dev_pm_opp_of_remove_table of_free_opp_table
+#endif
+
+
+#endif /* __KERNEL_COMPATIBILITY_H__ */
+/*****************************************************************************
+ End of file (kernel_compatibility.h)
+*****************************************************************************/
diff --git a/drivers/staging/imgtec/rogue/kerneldisplay.h b/drivers/staging/imgtec/rogue/kerneldisplay.h
index 4fd9215..d655bdc 100644
--- a/drivers/staging/imgtec/rogue/kerneldisplay.h
+++ b/drivers/staging/imgtec/rogue/kerneldisplay.h
@@ -1,8 +1,9 @@
 /*************************************************************************/ /*!
 @File
-@Title          Interface for 3rd party display class (DC) drivers
+@Title          Interface between 3rd party display controller (DC) drivers
+                and the Services server module.
+@Description    API between Services and the 3rd party DC driver and vice versa.
 @Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
-@Description    API between services and the 3rd party DC driver and vice versa
 @License        Dual MIT/GPLv2
 
 The contents of this file are subject to the MIT license as set out below.
@@ -48,34 +49,78 @@
 extern "C" {
 #endif
 
+#include <powervr/mem_types.h>
+
 #include "pvrsrv_error.h"
 #include "img_types.h"
 #include "pvrsrv_surface.h"
 #include "dc_external.h"
-#include "dc_common.h"
+
+/*!
+ ******************************************************************************
+ @mainpage Introduction and Document Scope
+This document is a function reference for the 3rd party display
+controller interface. The interface ensures that the 3rd party display driver and
+Services can exchange configurations and buffers and can inform each
+other about occurring events like render completion or vsyncs.
+
+This interface should be used and implemented if the 3rd party display driver
+is not using a native OS interface such as the Linux DRM/KMS API.
+
+To fully understand the document the reader should be aware that
+the Services driver - offering PowerVR core and platform functionality to the
+driver layers (OGLES etc.) above - is split into the "Services Client"
+user mode library and the "Services Server" kernel mode driver that communicate
+via the "Services Bridge". The terms "User-Mode" and "Client" are used as
+synonyms as well as "Kernel-Mode" and "Server".
+
+Please refer to the more comprehensive '3rd Party Display Integration Guide'
+for an architecture overview and an explanation of the data flow between a
+client process, Services and the 3rd party display driver. It also contains
+descriptions about how to make use of the client side interface that is supposed
+to be integrated in some kind of display manager like e.g. the Rogue DDK WSEGL
+window manager.
+
+The documented functions are split into different parts:
+- Callbacks that need an implementation by the 3rd party display driver and
+that are used by the Services server, some of them optional (kerneldisplay.h)
+- Functions that the Services server module exports and can be used by the
+3rd party display driver. Mainly to register/deregister a new display device
+and to query state information (kerneldisplay.h)
+- Functions that are called by the client process (a display manager e.g. WSEGL)
+to control the DC interaction (dc_client.h)
+- Commonly used structure definitions to exchange data between the modules
+(dc_external.h, pvrsrv_surface.h)
+ *****************************************************************************/
 
 /*************************************************************************/ /*!
 @Function       GetInfo
 
-@Description    Query the display controller for its information structure
+@Description    Query the display controller for its information structure.
+
+   Called by client function: #PVRSRVDCGetInfo()
+
+   Implementation of this callback is mandatory.
 
 @Input          hDeviceData             Device private data
 
 @Output         psDisplayInfo           Display info structure
-
-@Return         PVRSRV_OK if the query was successful
 */
 /*****************************************************************************/
 typedef void (*GetInfo)(IMG_HANDLE hDeviceData,
-						DC_DISPLAY_INFO *psDisplayInfo);
+                        DC_DISPLAY_INFO *psDisplayInfo);
 
 /*************************************************************************/ /*!
 @Function       PanelQueryCount
 
 @Description    Query the display controller for how many panels are
-                contented to it.
+                connected to it.
 
-@Input          hDeviceData             Device private data
+   Called by client function: #PVRSRVDCPanelQueryCount()
+
+   Implementation of this callback is mandatory.
+
+@Input          hDeviceData            Device private data
 
 @Output         pui32NumPanels         Number of panels
 
@@ -83,7 +128,7 @@
 */
 /*****************************************************************************/
 typedef PVRSRV_ERROR (*PanelQueryCount)(IMG_HANDLE hDeviceData,
-										 IMG_UINT32 *ppui32NumPanels);
+                                        IMG_UINT32 *pui32NumPanels);
 
 /*************************************************************************/ /*!
 @Function       PanelQuery
@@ -91,139 +136,162 @@
 @Description    Query the display controller for information on what panel(s)
                 are connected to it and their properties.
 
+   Called by client function: #PVRSRVDCPanelQuery()
+
+   Implementation of this callback is mandatory.
+
 @Input          hDeviceData             Device private data
 
-@Input          ui32PanelsArraySize    Size of the format and dimension
-                                        array size (i.e. number of panels
-                                        that can be returned)
+@Input          ui32PanelsArraySize     Size of the PanelInfo array
+                                        (i.e. number of panels that
+                                        can be returned)
 
-@Output         pui32NumPanels         Number of panels returned
+@Output         pui32NumPanels          Number of panels returned
 
-@Output         pasFormat               Array of formats
-
-@Output         pasDims                 Array of dimensions
+@Output         pasPanelInfo            Array of formats, allocated beforehand
 
 @Return         PVRSRV_OK if the query was successful
 */
 /*****************************************************************************/
 typedef PVRSRV_ERROR (*PanelQuery)(IMG_HANDLE hDeviceData,
-									IMG_UINT32 ui32PanelsArraySize,
-									IMG_UINT32 *pui32NumPanels,
-									PVRSRV_PANEL_INFO *pasPanelInfo);
+                                   IMG_UINT32 ui32PanelsArraySize,
+                                   IMG_UINT32 *pui32NumPanels,
+                                   PVRSRV_PANEL_INFO *pasPanelInfo);
 
 /*************************************************************************/ /*!
 @Function       FormatQuery
 
-@Description    Query the display controller to see if it supports the specified
+@Description    Query the display controller to check if it supports the specified
                 format(s).
 
+   Called by client function: #PVRSRVDCFormatQuery()
+
+   Implementation of this callback is mandatory.
+
 @Input          hDeviceData             Device private data
 
 @Input          ui32NumFormats          Number of formats to check
+                                        (i.e. length of the Format array)
 
 @Input          pasFormat               Array of formats to check
 
-@Output			pui32Supported          For each format, the number of display
+@Output         pui32Supported          For each format, the number of display
                                         pipes that support that format
 
 @Return         PVRSRV_OK if the query was successful
 */
 /*****************************************************************************/
 typedef PVRSRV_ERROR (*FormatQuery)(IMG_HANDLE hDeviceData,
-									IMG_UINT32 ui32NumFormats,
-									PVRSRV_SURFACE_FORMAT *pasFormat,
-									IMG_UINT32 *pui32Supported);
+                                    IMG_UINT32 ui32NumFormats,
+                                    PVRSRV_SURFACE_FORMAT *pasFormat,
+                                    IMG_UINT32 *pui32Supported);
 
 /*************************************************************************/ /*!
 @Function       DimQuery
 
-@Description    Query the specificed display plane for the display dimensions
+@Description    Query the specified display plane for the display dimensions
                 it supports.
 
+   Called by client function: #PVRSRVDCDimQuery()
+
+   Implementation of this callback is mandatory.
+
 @Input          hDeviceData             Device private data
 
 @Input          ui32NumDims             Number of dimensions to check
+                                        (i.e. length of the Dim array)
 
-@Input          pasDim                  Array of dimentations to check
+@Input          pasDim                  Array of dimensions to check
 
 @Output         pui32Supported          For each dimension, the number of
                                         display pipes that support that
-                                         dimension
+                                        dimension
 
 @Return         PVRSRV_OK if the query was successful
 */
 /*****************************************************************************/
 typedef PVRSRV_ERROR (*DimQuery)(IMG_HANDLE hDeviceData,
-								 IMG_UINT32 ui32NumDims,
-								 PVRSRV_SURFACE_DIMS *psDim,
-								 IMG_UINT32 *pui32Supported);
-
+                                 IMG_UINT32 ui32NumDims,
+                                 PVRSRV_SURFACE_DIMS *pasDim,
+                                 IMG_UINT32 *pui32Supported);
 
 /*************************************************************************/ /*!
 @Function       SetBlank
 
-@Description    Enable/disable blanking of the screen
+@Description    Enable/disable blanking of the screen.
 
-@Input          psConnection            Services connection
+   Called by client function: #PVRSRVDCSetBlank()
 
-@Input          hDevice                 3rd party display class device
+   Implementation of this callback is optional.
 
-@Input          bEnabled                Enable/Disable the blanking
+@Input          hDeviceData             Device private data
+
+@Input          bEnable                 Enable/Disable the blanking
 
 @Return         PVRSRV_OK on success
 */
 /*****************************************************************************/
 typedef PVRSRV_ERROR (*SetBlank)(IMG_HANDLE hDeviceData,
-								 IMG_BOOL bEnabled);
+                                 IMG_BOOL bEnable);
 
 /*************************************************************************/ /*!
 @Function       SetVSyncReporting
 
-@Description    Enable VSync reporting by trigger the global event object on
-                every vsync happened.
+@Description    Enable VSync reporting. If enabled, the 3rd party display
+                driver is expected to call PVRSRVCheckStatus() after a VSync
+                event occurred. This will signal the Services driver global 
+                event object.
 
-@Input          psConnection            Services connection
+   Called by client function: #PVRSRVDCSetVSyncReporting()
 
-@Input          hDevice                 3rd party display class device
+   Implementation of this callback is optional.
 
-@Input          bEnabled                Enable/Disable the reporting
+@Input          hDeviceData             Device private data
+
+@Input          bEnable                 Enable/Disable the reporting
 
 @Return         PVRSRV_OK on success
 */
 /*****************************************************************************/
 typedef PVRSRV_ERROR (*SetVSyncReporting)(IMG_HANDLE hDeviceData,
-										  IMG_BOOL bEnabled);
+                                          IMG_BOOL bEnable);
 
 /*************************************************************************/ /*!
-@Function       PVRSRVDCLastVSyncQuery
+@Function       LastVSyncQuery
 
 @Description    Query the time the last vsync happened.
 
-@Input          psConnection            Services connection
+   Called by client function: #PVRSRVDCLastVSyncQuery()
 
-@Input          hDevice                 3rd party display class device
+   Implementation of this callback is optional.
 
-@Output         pi64Timestamp           the requested timestamp
+@Input          hDeviceData             Device private data
+
+@Output         pi64Timestamp           The requested timestamp
+                                        of the system time in ns
 
 @Return         PVRSRV_OK if the query was successful
 */
 /*****************************************************************************/
 typedef PVRSRV_ERROR (*LastVSyncQuery)(IMG_HANDLE hDeviceData,
-									   IMG_INT64 *pi64Timestamp);
-
-typedef PVRSRV_ERROR (*BufferSystemAcquire)(IMG_HANDLE hDeviceData,
-											IMG_DEVMEM_LOG2ALIGN_T *puiLog2PageSize,
-											IMG_UINT32 *pui32PageCount,
-											IMG_UINT32 *pui32PhysHeapID,
-											IMG_UINT32 *pui32ByteStride,
-											IMG_HANDLE *phSystemBuffer);
-
-typedef	void (*BufferSystemRelease)(IMG_HANDLE hSystemBuffer);
+                                       IMG_INT64 *pi64Timestamp);
 
 /*************************************************************************/ /*!
 @Function       ContextCreate
 
 @Description    Create display context.
+                The client application and the display driver have to agree
+                as to what exactly a context represents, Services will just
+                pass it through and tie it to its own concept of a
+                display context.
+                It might contain additional locks, work-queues or other
+                important data that is necessary to drive the interaction
+                with Services. A context is usually associated with one device
+                but that is not a hard requirement.
+
+   Called by client function: #PVRSRVDCDisplayContextCreate()
+
+   Implementation of this callback is mandatory.
 
 @Input          hDeviceData             Device private data
 
@@ -233,19 +301,29 @@
 */
 /*****************************************************************************/
 typedef PVRSRV_ERROR (*ContextCreate)(IMG_HANDLE hDeviceData,
-									  IMG_HANDLE *hDisplayContext);
+                                      IMG_HANDLE *hDisplayContext);
 
 /*************************************************************************/ /*!
 @Function       ContextConfigureCheck
 
 @Description    Check to see if a configuration is valid for the display
-                controller.
+                controller. Because of runtime changes the display context
+                might not be able to work with a certain configuration anymore.
+                This function is intended to be called before ContextConfigure
+                so that the application can query details about the current
+                surface config and then do the ContextConfigure call with
+                the updated data.
+                The arrays should be z-sorted, with the farthest plane
+                first and the nearest plane last.
 
-                Note: This function is optional
+   Called by client function: #PVRSRVDCContextConfigureCheck()
+
+   Implementation of this callback is optional.
 
 @Input          hDisplayContext         Display context
 
 @Input          ui32PipeCount           Number of display pipes to configure
+                                        (length of the input arrays)
 
 @Input          pasSurfAttrib           Array of surface attributes (one for
                                         each display plane)
@@ -257,18 +335,25 @@
 */
 /*****************************************************************************/
 typedef PVRSRV_ERROR (*ContextConfigureCheck)(IMG_HANDLE hDisplayContext,
-											  IMG_UINT32 ui32PipeCount,
-											  PVRSRV_SURFACE_CONFIG_INFO *pasSurfAttrib,
-											  IMG_HANDLE *ahBuffers);
+                                              IMG_UINT32 ui32PipeCount,
+                                              PVRSRV_SURFACE_CONFIG_INFO *pasSurfAttrib,
+                                              IMG_HANDLE *ahBuffers);
 
 /*************************************************************************/ /*!
 @Function       ContextConfigure
 
-@Description    Configuration the display pipeline.
+@Description    Configure the display pipeline to display a given buffer.
+                The arrays should be z-sorted, with the farthest plane first
+                and the nearest plane last.
+
+   Called by client function: #PVRSRVDCContextConfigure(), #PVRSRVDCContextConfigureWithFDSync()
+
+   Implementation of this callback is mandatory.
 
 @Input          hDisplayContext         Display context
 
 @Input          ui32PipeCount           Number of display pipes to configure
+                                        (i.e. length of the input arrays)
 
 @Input          pasSurfAttrib           Array of surface attributes (one for
                                         each display plane)
@@ -282,22 +367,24 @@
 @Input          hConfigData             Config handle which gets passed to
                                         DisplayConfigurationRetired when this
                                         configuration is retired
-
-@Return         PVRSRV_OK if the configuration was successfully queued
 */
 /*****************************************************************************/
 typedef void (*ContextConfigure)(IMG_HANDLE hDisplayContext,
-								 IMG_UINT32 ui32PipeCount,
-								 PVRSRV_SURFACE_CONFIG_INFO *pasSurfAttrib,
-								 IMG_HANDLE *ahBuffers,
-								 IMG_UINT32 ui32DisplayPeriod,
-								 IMG_HANDLE hConfigData);
+                                 IMG_UINT32 ui32PipeCount,
+                                 PVRSRV_SURFACE_CONFIG_INFO *pasSurfAttrib,
+                                 IMG_HANDLE *ahBuffers,
+                                 IMG_UINT32 ui32DisplayPeriod,
+                                 IMG_HANDLE hConfigData);
 
 /*************************************************************************/ /*!
 @Function       ContextDestroy
 
 @Description    Destroy a display context.
 
+   Called by client function: #PVRSRVDCDisplayContextDestroy()
+
+   Implementation of this callback is mandatory.
+
 @Input          hDisplayContext         Display context to destroy
 
 @Return         None
@@ -317,16 +404,22 @@
                 still needs to be created and returned to the caller as well
                 as some information about the buffer that's required upfront.
 
+   Called by client function: #PVRSRVDCBufferAlloc()
+
+   Implementation of this callback is mandatory.
+
 @Input          hDisplayContext         Display context this buffer will be
                                         used on
 
 @Input          psSurfInfo              Attributes of the buffer
 
-@Output         puiLog2PageSize         Log2 of the pagesize of the buffer
+@Output         puiLog2PageSize         Pagesize in log2(bytes) of one page
 
 @Output         pui32PageCount          Number of pages in the buffer
 
-@Output         pui32PhysHeapID         Physcial heap ID to use
+@Output         pui32PhysHeapID         Physical heap ID to use. The physical
+                                        heap has been created in the Services
+                                        system layer.
 
 @Output         pui32ByteStride         Stride (in bytes) of allocated buffer
 
@@ -336,22 +429,30 @@
 */
 /*****************************************************************************/
 typedef PVRSRV_ERROR (*BufferAlloc)(IMG_HANDLE hDisplayContext,
-									DC_BUFFER_CREATE_INFO *psSurfInfo,
-									IMG_DEVMEM_LOG2ALIGN_T *puiLog2PageSize,
-									IMG_UINT32 *pui32PageCount,
-									IMG_UINT32 *pui32PhysHeapID,
-									IMG_UINT32 *pui32ByteStride,
-									IMG_HANDLE *phBuffer);
+                                    DC_BUFFER_CREATE_INFO *psSurfInfo,
+                                    IMG_DEVMEM_LOG2ALIGN_T *puiLog2PageSize,
+                                    IMG_UINT32 *pui32PageCount,
+                                    IMG_UINT32 *pui32PhysHeapID,
+                                    IMG_UINT32 *pui32ByteStride,
+                                    IMG_HANDLE *phBuffer);
 
 /*************************************************************************/ /*!
 @Function       BufferImport
 
-@Description    Import memory allocated from an external source to the display
-                controller. The DC checks to see if the import is compatible
-                and potentially sets up HW to map the imported buffer, although
-                this isn't require to happen until the first call to DCBufferMap
+@Description    Import memory allocated from an external source (e.g. Services)
+                to the display controller. The DC checks to see if the import
+                is compatible and potentially sets up HW to map the imported
+                buffer, although this isn't required to happen until the first
+                call to BufferMap.
 
-                Note: This is optional
+                Note: Provide this function if the controller
+                can scan out arbitrary memory, allocated for another purpose by
+                Services. To be able to use this buffer (depending on its
+                origin) the display controller probably will need a MMU.
+
+   Called by client function: #PVRSRVDCBufferImport()
+
+   Implementation of this callback is optional.
 
 @Input          hDisplayContext         Display context this buffer will be
                                         used on
@@ -368,45 +469,54 @@
 */
 /*****************************************************************************/
 typedef PVRSRV_ERROR (*BufferImport)(IMG_HANDLE hDisplayContext,
-									 IMG_UINT32 ui32NumPlanes,
-									 IMG_HANDLE **paphImport,
-									 DC_BUFFER_IMPORT_INFO *psSurfAttrib,
-									 IMG_HANDLE *phBuffer);
+                                     IMG_UINT32 ui32NumPlanes,
+                                     IMG_HANDLE **pahImport,
+                                     DC_BUFFER_IMPORT_INFO *psSurfAttrib,
+                                     IMG_HANDLE *phBuffer);
 
 /*************************************************************************/ /*!
 @Function       BufferAcquire
 
-@Description    Acquire the buffer's physcial memory pages. If the buffer doesn't
-                have any memory backing it yet then this will trigger the 3rd
+@Description    Acquire the buffer's physical memory pages. If the buffer doesn't
+                have any memory backing yet then this will trigger the 3rd
                 party driver to allocate it.
 
                 Note: The page count isn't passed back in this function as
-                services has already obtained it during BufferAlloc.
+                Services has already obtained it during BufferAlloc.
+
+   Called when Services requests buffer access for the first time. Usually part
+   of non display class functions.
+
+   Implementation of this callback is mandatory.
 
 @Input          hBuffer                 Handle to the buffer
 
 @Output         pasDevPAddr             Array of device physical page address
                                         of this buffer
 
-@Output         pvLinAddr               CPU virtual address of buffer. This is
-                                        optionial but if you have one you must
+@Output         ppvLinAddr              CPU virtual address of buffer. This is
+                                        optional but if you have one you must
                                         return it otherwise return NULL.
 
 @Return         PVRSRV_OK if the buffer was successfully acquired
 */
 /*****************************************************************************/
 typedef PVRSRV_ERROR (*BufferAcquire)(IMG_HANDLE hBuffer,
-									  IMG_DEV_PHYADDR *pasDevPAddr,
-									  void **ppvLinAddr);
+                                      IMG_DEV_PHYADDR *pasDevPAddr,
+                                      void **ppvLinAddr);
 
 /*************************************************************************/ /*!
 @Function       BufferRelease
 
-@Description    Release the buffer's physcial memory pages.
+@Description    Undo everything done by BufferAcquire.
+                Will release the buffer's physical memory pages if
+                BufferAcquire allocated them.
+
+   Called when Services finished buffer access.
+
+   Implementation of this callback is mandatory.
 
 @Input          hBuffer                 Handle to the buffer
-
-@Return         None
 */
 /*****************************************************************************/
 typedef void (*BufferRelease)(IMG_HANDLE hBuffer);
@@ -416,11 +526,13 @@
 
 @Description    Release a reference to the device buffer. If this was the last
                 reference the 3rd party driver is entitled to free the backing
-                memory.
+                memory and other related resources.
+
+   Called by client function: #PVRSRVDCBufferFree()
+
+   Implementation of this callback is mandatory.
 
 @Input          hBuffer                 Buffer handle we're releasing
-
-@Return         None
 */
 /*****************************************************************************/
 typedef void (*BufferFree)(IMG_HANDLE hBuffer);
@@ -429,8 +541,15 @@
 @Function       BufferMap
 
 @Description    Map the buffer into the display controller
+                Note: This function depends on the behaviour of
+                BufferAlloc/BufferAcquire/BufferImport/BufferSystemAcquire
+                and the controller's ability to map in memory.
+                If the controller has no MMU or the above functions already
+                map the buffer this callback does not need an implementation.
 
-                Note: This function is optional
+   Called by client function: #PVRSRVDCBufferPin()
+
+   Implementation of this callback is optional.
 
 @Input          hBuffer                 Buffer to map
 
@@ -442,96 +561,194 @@
 /*************************************************************************/ /*!
 @Function       BufferUnmap
 
-@Description    Unmap a buffer from the display controller
+@Description    Undo everything done by BufferMap.
+                Usually that means to unmap a buffer from the display controller.
 
-                Note: This function is optional
+   Called by client function: #PVRSRVDCBufferUnpin()
+
+   Implementation of this callback is optional.
 
 @Input          hBuffer                 Buffer to unmap
-
-@Return         None
 */
 /*****************************************************************************/
 typedef void (*BufferUnmap)(IMG_HANDLE hBuffer);
 
 
-/*
-	Function table for server->display
+/*************************************************************************/ /*!
+@Function       BufferSystemAcquire
+
+@Description    DEPRICATED, please use BufferAlloc
+                Acquire the system buffer from the display driver.
+                If the OS should trigger a mode change then it's not allowed to
+                free the previous buffer until Services has released it
+                via BufferSystemRelease. The system buffer has to be associated
+                to a PhysHeapID which can be one of the existing physical heaps
+                if the system buffer is compatible with it or must be a separate
+                heap created for this use.
+
+   Called by client function: #PVRSRVDCSystemBufferAcquire()
+
+   Implementation of this callback is optional.
+
+@Input          hDeviceData             Device private data
+
+@Output         puiLog2PageSize         The physical pagesize in log2(bytes)
+                                        of one page that the buffer is composed of
+
+@Output         pui32PageCount          The number of pages the buffer contains
+
+@Output         pui32PhysHeapID         The ID of the Services PhysHeap that has
+                                        been setup in the system layer
+
+@Output         pui32ByteStride         Byte stride of the buffer
+
+@Output         phSystemBuffer          Handle to the buffer object
+
+@Return         PVRSRV_OK if the query was successful
 */
+/*****************************************************************************/
+typedef PVRSRV_ERROR (*BufferSystemAcquire)(IMG_HANDLE hDeviceData,
+                                            IMG_DEVMEM_LOG2ALIGN_T *puiLog2PageSize,
+                                            IMG_UINT32 *pui32PageCount,
+                                            IMG_UINT32 *pui32PhysHeapID,
+                                            IMG_UINT32 *pui32ByteStride,
+                                            IMG_HANDLE *phSystemBuffer);
+
+/*************************************************************************/ /*!
+@Function       BufferSystemRelease
+
+@Description    DEPRICATED, please use BufferFree
+                Release a display buffer acquired with BufferSystemAcquire.
+                Services calls this after it has no use for the buffer anymore.
+                The buffer must not be destroyed before Services releases it
+                with this call.
+
+   Called by client function: #PVRSRVDCSystemBufferRelease()
+
+   Implementation of this callback is optional.
+
+@Input          hSystemBuffer          Handle to the buffer object
+*/
+/*****************************************************************************/
+typedef	void (*BufferSystemRelease)(IMG_HANDLE hSystemBuffer);
+
+#if defined(INTEGRITY_OS)
+typedef PVRSRV_ERROR (*AcquireKernelMappingData)(IMG_HANDLE hBuffer, IMG_HANDLE *phMapping, void **ppPhysAddr);
+typedef PVRSRV_ERROR (*MapMemoryObject)(IMG_HANDLE hBuffer, IMG_HANDLE *phMemObj);
+typedef PVRSRV_ERROR (*UnmapMemoryObject)(IMG_HANDLE hBuffer);
+
+#if defined(USING_HYPERVISOR)
+typedef IMG_HANDLE (*GetPmr)(IMG_HANDLE hBuffer, size_t ulOffset);
+#endif
+#endif
+
+/*!
+ * Function table for functions to be implemented by the display controller
+ * that will be called from within Services.
+ * The table will be provided to Services with the call to DCRegisterDevice.
+ */
 typedef struct _DC_DEVICE_FUNCTIONS_
 {
-	/*! Mandatory query functions */
+	/* Mandatory query functions */
 	GetInfo						pfnGetInfo;
 	PanelQueryCount				pfnPanelQueryCount;
 	PanelQuery					pfnPanelQuery;
 	FormatQuery					pfnFormatQuery;
 	DimQuery					pfnDimQuery;
 
-	/*! Optional blank/vsync function */
-	SetBlank		            pfnSetBlank;
-	SetVSyncReporting		    pfnSetVSyncReporting;
+	/* Optional blank/vsync functions */
+	SetBlank					pfnSetBlank;
+	SetVSyncReporting			pfnSetVSyncReporting;
 	LastVSyncQuery				pfnLastVSyncQuery;
 
-	/*! Mandatory configure function */
+	/* Mandatory configure functions */
 	ContextCreate				pfnContextCreate;
 	ContextDestroy				pfnContextDestroy;
 	ContextConfigure			pfnContextConfigure;
 
-	/*! Optional context function */
+	/* Optional context functions */
 	ContextConfigureCheck		pfnContextConfigureCheck;
 
-	/*! Mandatory buffer functions */
+	/* Mandatory buffer functions */
 	BufferAlloc					pfnBufferAlloc;
 	BufferAcquire				pfnBufferAcquire;
 	BufferRelease				pfnBufferRelease;
 	BufferFree					pfnBufferFree;
 
-	/*! Optional buffer functions, pfnBufferMap and pfnBufferUnmap are paired
-		functions, provide both or neither */
+	/* Optional - Provide this function if your controller can
+	 * scan out arbitrary memory, allocated for another purpose
+	 * by Services. */
 	BufferImport				pfnBufferImport;
+
+	/* Optional - Provide these functions if your controller
+	 * has an MMU and does not (or cannot) map/unmap buffers at
+	 * alloc/free time */
 	BufferMap					pfnBufferMap;
 	BufferUnmap					pfnBufferUnmap;
+
+	/* Optional - DEPRICATED */
 	BufferSystemAcquire			pfnBufferSystemAcquire;
 	BufferSystemRelease			pfnBufferSystemRelease;
+
+#if defined(INTEGRITY_OS)
+	/* The addition of these functions allow dc_server to delegate calls to
+	 * the respective functions on its PMRs towards the DC module
+	 */
+	AcquireKernelMappingData	pfnAcquireKernelMappingData;
+	MapMemoryObject             pfnMapMemoryObject;
+	UnmapMemoryObject           pfnUnmapMemoryObject;
+
+#if defined(USING_HYPERVISOR)
+	GetPmr				pfnGetPmr;
+#endif
+#endif
 } DC_DEVICE_FUNCTIONS;
 
 
 /*
-	functions exported by kernel services for use by 3rd party kernel display
-	class device driver
+ * Functions exported by kernel Services for use by 3rd party kernel display
+ * controller device driver
 */
 
 /*************************************************************************/ /*!
 @Function       DCRegisterDevice
 
-@Description    Register a display class device
+@Description    This needs to be called by the display driver before any further
+                communication with Services.
+                It registers a display controller device with Services. After this
+                registration Services is able to use the display controller
+                and will make use of the callbacks. Services will provide the
+                hDeviceData in the callbacks whenever necessary.
 
 @Input          psFuncTable             Callback function table
 
 @Input          ui32MaxConfigsInFlight  The maximum number of configs that this
-                                        display device can have in-flight.
+                                        display device can have in-flight. This
+                                        determines the number of possible calls
+                                        to ContextConfigure before Services has to
+                                        wait for DCDisplayConfigurationRetired
+                                        calls.
 
-@Input          hDeviceData             3rd party device handle, passed into
-                                        DC callbacks
+@Input          hDeviceData             Device private data passed into callbacks
 
 @Output         phSrvHandle             Services handle to pass back into
                                         UnregisterDCDevice
 
-@Return         PVRSRV_OK if the display class driver was successfully registered
+@Return         PVRSRV_OK if the display controller driver was successfully registered
 */
 /*****************************************************************************/
 PVRSRV_ERROR DCRegisterDevice(DC_DEVICE_FUNCTIONS *psFuncTable,
-							  IMG_UINT32 ui32MaxConfigsInFlight,
-							  IMG_HANDLE hDeviceData,
-							  IMG_HANDLE *phSrvHandle);
+                              IMG_UINT32 ui32MaxConfigsInFlight,
+                              IMG_HANDLE hDeviceData,
+                              IMG_HANDLE *phSrvHandle);
 
 /*************************************************************************/ /*!
 @Function       DCUnregisterDevice
 
-@Description    Unregister a display class device
+@Description    Unregister a display controller device. Undo everything done with
+                DCRegisterDevice. Services will stop using this device.
 
-@Input          hDevice                Services device handle
-
-@Return         None
+@Input          hSrvHandle              Services device handle
 */
 /*****************************************************************************/
 void DCUnregisterDevice(IMG_HANDLE hSrvHandle);
@@ -540,11 +757,9 @@
 @Function       DCDisplayConfigurationRetired
 
 @Description    Called when a configuration as been retired due to a new
-                configuration now being active.
+                configuration now being active. See #PVRSRVDCContextConfigure().
 
 @Input          hConfigData             ConfigData that is being retired
-
-@Return         None
 */
 /*****************************************************************************/
 void DCDisplayConfigurationRetired(IMG_HANDLE hConfigData);
@@ -567,40 +782,41 @@
 @Function       DCImportBufferAcquire
 
 @Description    Acquire information about a buffer that was imported with
-                BufferImport.
+                BufferImport. DCImportBufferRelease has to be called after
+                the buffer will not be used anymore.
 
 @Input          hImport                 Import buffer
 
-@Input          uiLog2PageSize          Log 2 of the DC's page size
+@Input          uiLog2PageSize          Pagesize in log2(bytes) of the buffer
 
 @Output         pui32PageCount          Size of the buffer in pages
 
-@Output         ppasDevPAddr            Array of device physcial page address
+@Output         pasDevPAddr             Array of device physical page address
                                         of this buffer
 
 @Return         PVRSRV_OK if the import buffer was successfully acquired
 */
 /*****************************************************************************/
 PVRSRV_ERROR DCImportBufferAcquire(IMG_HANDLE hImport,
-								   IMG_DEVMEM_LOG2ALIGN_T uiLog2PageSize,
-								   IMG_UINT32 *pui32PageCount,
-								   IMG_DEV_PHYADDR **ppasDevPAddr);
+                                   IMG_DEVMEM_LOG2ALIGN_T uiLog2PageSize,
+                                   IMG_UINT32 *pui32PageCount,
+                                   IMG_DEV_PHYADDR **pasDevPAddr);
 
 /*************************************************************************/ /*!
 @Function       DCImportBufferRelease
 
 @Description    Release an imported buffer.
 
-@Input          hImport                 Import handle we're releasing
+@Input          hImport                 Import handle we are releasing
 
-@Input          pasDevPAddr             Import data was returned from
+@Input          pasDevPAddr             Import data which was returned from
                                         DCImportBufferAcquire
-
-@Return         None
 */
 /*****************************************************************************/
 void DCImportBufferRelease(IMG_HANDLE hImport,
-						   IMG_DEV_PHYADDR *pasDevPAddr);
+                           IMG_DEV_PHYADDR *pasDevPAddr);
+
+
 
 #if defined (__cplusplus)
 }
diff --git a/drivers/staging/imgtec/rogue/km_apphint.c b/drivers/staging/imgtec/rogue/km_apphint.c
new file mode 100644
index 0000000..1498941
--- /dev/null
+++ b/drivers/staging/imgtec/rogue/km_apphint.c
@@ -0,0 +1,1422 @@
+/*************************************************************************/ /*!
+@File           km_apphint.c
+@Title          Apphint routines
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description    Device specific functions
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#if defined(SUPPORT_KERNEL_SRVINIT)
+
+#include "pvr_debugfs.h"
+#include "pvr_uaccess.h"
+#include <linux/moduleparam.h>
+#include <linux/workqueue.h>
+#include <linux/string.h>
+#include <stdbool.h>
+
+/* for action device access */
+#include "pvrsrv.h"
+#include "device.h"
+#include "rgxdevice.h"
+#include "rgxfwutils.h"
+#include "debugmisc_server.h"
+#include "htbserver.h"
+#include "rgxutils.h"
+#include "rgxapi_km.h"
+
+#include "img_defs.h"
+
+/* defines for default values */
+#include "rgx_fwif.h"
+#include "htbuffer_types.h"
+
+#include "pvr_notifier.h"
+
+#include "km_apphint_defs.h"
+#include "km_apphint.h"
+
+#if defined(PDUMP)
+#include <stdarg.h>
+#include "pdump_km.h"
+#endif
+
+/* Size of temporary buffers used to read and write AppHint data.
+ * Must be large enough to contain any strings read/written
+ * but no larger than 4096 with is the buffer size for the
+ * kernel_param_ops .get function.
+ * And less than 1024 to keep the stack frame size within bounds.
+ */
+#define APPHINT_BUFFER_SIZE 512
+
+#define APPHINT_DEVICES_MAX 16
+
+/*
+*******************************************************************************
+ * AppHint mnemonic data type helper tables
+******************************************************************************/
+struct apphint_lookup {
+	char *name;
+	int value;
+};
+
+static const struct apphint_lookup fwt_logtype_tbl[] = {
+	{ "trace", 2},
+	{ "tbi", 1},
+	{ "none", 0}
+};
+
+static const struct apphint_lookup fwt_loggroup_tbl[] = {
+	RGXFWIF_LOG_GROUP_NAME_VALUE_MAP
+};
+
+static const struct apphint_lookup htb_loggroup_tbl[] = {
+#define X(a, b) { #b, HTB_LOG_GROUP_FLAG(a) },
+	HTB_LOG_SFGROUPLIST
+#undef X
+};
+
+static const struct apphint_lookup htb_opmode_tbl[] = {
+	{ "droplatest", HTB_OPMODE_DROPLATEST},
+	{ "dropoldest", HTB_OPMODE_DROPOLDEST},
+	{ "block", HTB_OPMODE_BLOCK}
+};
+
+__maybe_unused
+static const struct apphint_lookup htb_logmode_tbl[] = {
+	{ "all", HTB_LOGMODE_ALLPID},
+	{ "restricted", HTB_LOGMODE_RESTRICTEDPID}
+};
+
+static const struct apphint_lookup timecorr_clk_tbl[] = {
+	{ "mono", 0 },
+	{ "mono_raw", 1 },
+	{ "sched", 2 }
+};
+
+/*
+*******************************************************************************
+ Data types
+******************************************************************************/
+union apphint_value {
+	IMG_UINT64 UINT64;
+	IMG_UINT32 UINT32;
+	IMG_BOOL BOOL;
+	IMG_CHAR *STRING;
+};
+
+struct apphint_action {
+	union {
+		PVRSRV_ERROR (*UINT64)(const PVRSRV_DEVICE_NODE *device, const void *private_data, IMG_UINT64 *value);
+		PVRSRV_ERROR (*UINT32)(const PVRSRV_DEVICE_NODE *device, const void *private_data, IMG_UINT32 *value);
+		PVRSRV_ERROR (*BOOL)(const PVRSRV_DEVICE_NODE *device, const void *private_data, IMG_BOOL *value);
+		PVRSRV_ERROR (*STRING)(const PVRSRV_DEVICE_NODE *device, const void *private_data, IMG_CHAR **value);
+	} query;
+	union {
+		PVRSRV_ERROR (*UINT64)(const PVRSRV_DEVICE_NODE *device, const void *private_data, IMG_UINT64 value);
+		PVRSRV_ERROR (*UINT32)(const PVRSRV_DEVICE_NODE *device, const void *private_data, IMG_UINT32 value);
+		PVRSRV_ERROR (*BOOL)(const PVRSRV_DEVICE_NODE *device, const void *private_data, IMG_BOOL value);
+		PVRSRV_ERROR (*STRING)(const PVRSRV_DEVICE_NODE *device, const void *private_data, IMG_CHAR *value);
+	} set;
+	const PVRSRV_DEVICE_NODE *device;
+	const void *private_data;
+	union apphint_value stored;
+	bool free;
+};
+
+struct apphint_param {
+	IMG_UINT32 id;
+	APPHINT_DATA_TYPE data_type;
+	const void *data_type_helper;
+	IMG_UINT32 helper_size;
+};
+
+struct apphint_init_data {
+	IMG_UINT32 id;			/* index into AppHint Table */
+	APPHINT_CLASS class;
+	IMG_CHAR *name;
+	union apphint_value default_value;
+};
+
+struct apphint_class_state {
+	APPHINT_CLASS class;
+	IMG_BOOL enabled;
+};
+
+struct apphint_work {
+	struct work_struct work;
+	union apphint_value new_value;
+	struct apphint_action *action;
+};
+
+/*
+*******************************************************************************
+ Initialization / configuration table data
+******************************************************************************/
+#define UINT32Bitfield UINT32
+#define UINT32List UINT32
+
+static const struct apphint_init_data init_data_buildvar[] = {
+#define X(a, b, c, d, e) \
+	{APPHINT_ID_ ## a, APPHINT_CLASS_ ## c, #a, {.b=d} },
+	APPHINT_LIST_BUILDVAR
+#undef X
+};
+
+static const struct apphint_init_data init_data_modparam[] = {
+#define X(a, b, c, d, e) \
+	{APPHINT_ID_ ## a, APPHINT_CLASS_ ## c, #a, {.b=d} },
+	APPHINT_LIST_MODPARAM
+#undef X
+};
+
+static const struct apphint_init_data init_data_debugfs[] = {
+#define X(a, b, c, d, e) \
+	{APPHINT_ID_ ## a, APPHINT_CLASS_ ## c, #a, {.b=d} },
+	APPHINT_LIST_DEBUGFS
+#undef X
+};
+
+static const struct apphint_init_data init_data_debugfs_device[] = {
+#define X(a, b, c, d, e) \
+	{APPHINT_ID_ ## a, APPHINT_CLASS_ ## c, #a, {.b=d} },
+	APPHINT_LIST_DEBUGFS_DEVICE
+#undef X
+};
+
+#undef UINT32Bitfield
+#undef UINT32List
+
+/* Don't use the kernel ARRAY_SIZE macro here because it checks
+ * __must_be_array() and we need to be able to use this safely on a NULL ptr.
+ * This will return an undefined size for a NULL ptr - so should only be
+ * used here.
+ */
+#define APPHINT_HELP_ARRAY_SIZE(a) (sizeof((a))/(sizeof((a[0]))))
+
+static const struct apphint_param param_lookup[] = {
+#define X(a, b, c, d, e) \
+	{APPHINT_ID_ ## a, APPHINT_DATA_TYPE_ ## b, e, APPHINT_HELP_ARRAY_SIZE(e) },
+	APPHINT_LIST_ALL
+#undef X
+};
+
+#undef APPHINT_HELP_ARRAY_SIZE
+
+static const struct apphint_class_state class_state[] = {
+#define X(a) {APPHINT_CLASS_ ## a, APPHINT_ENABLED_CLASS_ ## a},
+	APPHINT_CLASS_LIST
+#undef X
+};
+
+/*
+*******************************************************************************
+ Global state
+******************************************************************************/
+/* If the union apphint_value becomes such that it is not possible to read
+ * and write atomically, a mutex may be desirable to prevent a read returning
+ * a partially written state.
+ * This would require a statically initialized mutex outside of the
+ * struct apphint_state to prevent use of an uninitialized mutex when
+ * module_params are provided on the command line.
+ *     static DEFINE_MUTEX(apphint_mutex);
+ */
+static struct apphint_state
+{
+	struct workqueue_struct *workqueue;
+	PVR_DEBUGFS_DIR_DATA *debugfs_device_rootdir[APPHINT_DEVICES_MAX];
+	PVR_DEBUGFS_ENTRY_DATA *debugfs_device_entry[APPHINT_DEVICES_MAX][APPHINT_DEBUGFS_DEVICE_ID_MAX];
+	PVR_DEBUGFS_DIR_DATA *debugfs_rootdir;
+	PVR_DEBUGFS_ENTRY_DATA *debugfs_entry[APPHINT_DEBUGFS_ID_MAX];
+	PVR_DEBUGFS_DIR_DATA *buildvar_rootdir;
+	PVR_DEBUGFS_ENTRY_DATA *buildvar_entry[APPHINT_BUILDVAR_ID_MAX];
+
+	int num_devices;
+	PVRSRV_DEVICE_NODE *devices[APPHINT_DEVICES_MAX];
+	int initialized;
+
+	struct apphint_action val[APPHINT_ID_MAX + ((APPHINT_DEVICES_MAX-1)*APPHINT_DEBUGFS_DEVICE_ID_MAX)];
+
+} apphint = {
+/* statically initialise default values to ensure that any module_params
+ * provided on the command line are not overwritten by defaults.
+ */
+	.val = {
+#define UINT32Bitfield UINT32
+#define UINT32List UINT32
+#define X(a, b, c, d, e) \
+	{ {NULL}, {NULL}, NULL, NULL, {.b=d}, false },
+	APPHINT_LIST_ALL
+#undef X
+#undef UINT32Bitfield
+#undef UINT32List
+	},
+	.initialized = 0,
+	.num_devices = 0
+};
+
+#define APPHINT_DEBUGFS_DEVICE_ID_OFFSET (APPHINT_ID_MAX-APPHINT_DEBUGFS_DEVICE_ID_MAX)
+
+static inline void
+get_apphint_id_from_action_addr(const struct apphint_action * const addr,
+                                APPHINT_ID * const id)
+{
+	*id = (APPHINT_ID)(addr - apphint.val);
+	if (*id >= APPHINT_ID_MAX) {
+		*id -= APPHINT_DEBUGFS_DEVICE_ID_OFFSET;
+		*id %= APPHINT_DEBUGFS_DEVICE_ID_MAX;
+		*id += APPHINT_DEBUGFS_DEVICE_ID_OFFSET;
+	}
+}
+
+static inline void
+get_value_offset_from_device(const PVRSRV_DEVICE_NODE * const device,
+                             int * const offset)
+{
+	int i;
+	for (i = 0; device && i < APPHINT_DEVICES_MAX; i++) {
+		if (apphint.devices[i] == device)
+			break;
+	}
+	if (APPHINT_DEVICES_MAX == i) {
+		PVR_DPF((PVR_DBG_WARNING, "%s: Unregistered device", __func__));
+		i = 0;
+	}
+	*offset = i * APPHINT_DEBUGFS_DEVICE_ID_MAX;
+}
+
+/**
+ * apphint_action_worker - perform an action after an AppHint update has been
+ *                    requested by a UM process
+ *                    And update the record of the current active value
+ */
+static void apphint_action_worker(struct work_struct *work)
+{
+	struct apphint_work *work_pkt = container_of(work,
+	                                             struct apphint_work,
+	                                             work);
+	struct apphint_action *a = work_pkt->action;
+	union apphint_value value = work_pkt->new_value;
+	APPHINT_ID id;
+	PVRSRV_ERROR result = PVRSRV_OK;
+
+	get_apphint_id_from_action_addr(a, &id);
+
+	if (a->set.UINT64) {
+		switch (param_lookup[id].data_type) {
+		case APPHINT_DATA_TYPE_UINT64:
+			result = a->set.UINT64(a->device,
+			                       a->private_data,
+			                       value.UINT64);
+			break;
+
+		case APPHINT_DATA_TYPE_UINT32:
+		case APPHINT_DATA_TYPE_UINT32Bitfield:
+		case APPHINT_DATA_TYPE_UINT32List:
+			result = a->set.UINT32(a->device,
+			                       a->private_data,
+			                       value.UINT32);
+			break;
+
+		case APPHINT_DATA_TYPE_BOOL:
+			result = a->set.BOOL(a->device,
+			                     a->private_data,
+			                     value.BOOL);
+			break;
+
+		case APPHINT_DATA_TYPE_STRING:
+			result = a->set.STRING(a->device,
+								   a->private_data,
+								   value.STRING);
+			kfree(value.STRING);
+			break;
+
+		default:
+			PVR_DPF((PVR_DBG_ERROR,
+			         "%s: unrecognised data type (%d), index (%d)",
+			         __func__, param_lookup[id].data_type, id));
+		}
+
+		if (PVRSRV_OK != result) {
+			PVR_DPF((PVR_DBG_ERROR,
+			         "%s: failed (%s)",
+			         __func__, PVRSRVGetErrorStringKM(result)));
+		}
+	} else {
+		if (a->free) {
+			kfree(a->stored.STRING);
+		}
+		a->stored = value;
+		if (param_lookup[id].data_type == APPHINT_DATA_TYPE_STRING) {
+			a->free = true;
+		}
+		PVR_DPF((PVR_DBG_MESSAGE,
+		         "%s: AppHint value updated before handler is registered, ID(%d)",
+		         __func__, id));
+	}
+	kfree((void *)work_pkt);
+}
+
+static void apphint_action(union apphint_value new_value,
+                           struct apphint_action *action)
+{
+	struct apphint_work *work_pkt = kmalloc(sizeof(*work_pkt), GFP_KERNEL);
+
+	/* queue apphint update on a serialized workqueue to avoid races */
+	if (work_pkt) {
+		work_pkt->new_value = new_value;
+		work_pkt->action = action;
+		INIT_WORK(&work_pkt->work, apphint_action_worker);
+		if (0 == queue_work(apphint.workqueue, &work_pkt->work)) {
+			PVR_DPF((PVR_DBG_ERROR,
+				"%s: failed to queue apphint change request",
+				__func__));
+			goto err_exit;
+		}
+	} else {
+		PVR_DPF((PVR_DBG_ERROR,
+			"%s: failed to alloc memory for apphint change request",
+			__func__));
+			goto err_exit;
+	}
+	return;
+err_exit:
+	kfree(new_value.STRING);
+}
+
+/**
+ * apphint_read - read the different AppHint data types
+ * return -errno or the buffer size
+ */
+static int apphint_read(char *buffer, size_t count, APPHINT_ID ue,
+			 union apphint_value *value)
+{
+	APPHINT_DATA_TYPE data_type = param_lookup[ue].data_type;
+	int result = 0;
+
+	switch (data_type) {
+	case APPHINT_DATA_TYPE_UINT64:
+		if (kstrtou64(buffer, 0, &value->UINT64) < 0) {
+			PVR_DPF((PVR_DBG_ERROR,
+				"%s: Invalid UINT64 input data for id %d: %s",
+				__func__, ue, buffer));
+			result = -EINVAL;
+			goto err_exit;
+		}
+		break;
+	case APPHINT_DATA_TYPE_UINT32:
+		if (kstrtou32(buffer, 0, &value->UINT32) < 0) {
+			PVR_DPF((PVR_DBG_ERROR,
+				"%s: Invalid UINT32 input data for id %d: %s",
+				__func__, ue, buffer));
+			result = -EINVAL;
+			goto err_exit;
+		}
+		break;
+	case APPHINT_DATA_TYPE_BOOL:
+		switch (buffer[0]) {
+		case '0':
+		case 'n':
+		case 'N':
+		case 'f':
+		case 'F':
+			value->BOOL = IMG_FALSE;
+			break;
+		case '1':
+		case 'y':
+		case 'Y':
+		case 't':
+		case 'T':
+			value->BOOL = IMG_TRUE;
+			break;
+		default:
+			PVR_DPF((PVR_DBG_ERROR,
+				"%s: Invalid BOOL input data for id %d: %s",
+				__func__, ue, buffer));
+			result = -EINVAL;
+			goto err_exit;
+		}
+		break;
+	case APPHINT_DATA_TYPE_UINT32List:
+	{
+		int i;
+		struct apphint_lookup *lookup =
+			(struct apphint_lookup *)
+			param_lookup[ue].data_type_helper;
+		int size = param_lookup[ue].helper_size;
+		/* buffer may include '\n', remove it */
+		char *arg = strsep(&buffer, "\n");
+
+		if (!lookup) {
+			result = -EINVAL;
+			goto err_exit;
+		}
+
+		for (i = 0; i < size; i++) {
+			if (strcasecmp(lookup[i].name, arg) == 0) {
+				value->UINT32 = lookup[i].value;
+				break;
+			}
+		}
+		if (i == size) {
+			if (strlen(arg) == 0) {
+				PVR_DPF((PVR_DBG_ERROR,
+					"%s: No value set for AppHint",
+					__func__));
+			} else {
+				PVR_DPF((PVR_DBG_ERROR,
+					"%s: Unrecognised AppHint value (%s)",
+					__func__, arg));
+			}
+			result = -EINVAL;
+		}
+		break;
+	}
+	case APPHINT_DATA_TYPE_UINT32Bitfield:
+	{
+		int i;
+		struct apphint_lookup *lookup =
+			(struct apphint_lookup *)
+			param_lookup[ue].data_type_helper;
+		int size = param_lookup[ue].helper_size;
+		/* buffer may include '\n', remove it */
+		char *string = strsep(&buffer, "\n");
+		char *token = strsep(&string, ",");
+
+		if (!lookup) {
+			result = -EINVAL;
+			goto err_exit;
+		}
+
+		value->UINT32 = 0;
+		/* empty string is valid to clear the bitfield */
+		while (token && *token) {
+			for (i = 0; i < size; i++) {
+				if (strcasecmp(lookup[i].name, token) == 0) {
+					value->UINT32 |= lookup[i].value;
+					break;
+				}
+			}
+			if (i == size) {
+				PVR_DPF((PVR_DBG_ERROR,
+					"%s: Unrecognised AppHint value (%s)",
+					__func__, token));
+				result = -EINVAL;
+				goto err_exit;
+			}
+			token = strsep(&string, ",");
+		}
+		break;
+	}
+	case APPHINT_DATA_TYPE_STRING:
+	{
+		/* buffer may include '\n', remove it */
+		char *string = strsep(&buffer, "\n");
+		size_t len = strlen(string);
+
+		if (!len) {
+			result = -EINVAL;
+			goto err_exit;
+		}
+
+		++len;
+
+		value->STRING = kmalloc(len, GFP_KERNEL);
+		if (!value->STRING) {
+			result = -ENOMEM;
+			goto err_exit;
+		}
+
+		strlcpy(value->STRING, string, len);
+		break;
+	}
+	default:
+		result = -EINVAL;
+		goto err_exit;
+	}
+
+err_exit:
+	return (result < 0) ? result : count;
+}
+
+/**
+ * apphint_write - write the current AppHint data to a buffer
+ *
+ * Returns length written or -errno
+ */
+static int apphint_write(char *buffer, const size_t size,
+                         const struct apphint_action *a)
+{
+	const struct apphint_param *hint;
+	int result = 0;
+	APPHINT_ID id;
+	union apphint_value value;
+
+	get_apphint_id_from_action_addr(a, &id);
+	hint = &param_lookup[id];
+
+	if (a->query.UINT64) {
+		switch (hint->data_type) {
+		case APPHINT_DATA_TYPE_UINT64:
+			result = a->query.UINT64(a->device,
+			                         a->private_data,
+			                         &value.UINT64);
+			break;
+
+		case APPHINT_DATA_TYPE_UINT32:
+		case APPHINT_DATA_TYPE_UINT32Bitfield:
+		case APPHINT_DATA_TYPE_UINT32List:
+			result = a->query.UINT32(a->device,
+			                         a->private_data,
+			                         &value.UINT32);
+			break;
+
+		case APPHINT_DATA_TYPE_BOOL:
+			result = a->query.BOOL(a->device,
+			                       a->private_data,
+			                       &value.BOOL);
+			break;
+
+		case APPHINT_DATA_TYPE_STRING:
+			result = a->query.STRING(a->device,
+									 a->private_data,
+									 &value.STRING);
+			break;
+		default:
+			PVR_DPF((PVR_DBG_ERROR,
+			         "%s: unrecognised data type (%d), index (%d)",
+			         __func__, hint->data_type, id));
+		}
+
+		if (PVRSRV_OK != result) {
+			PVR_DPF((PVR_DBG_ERROR, "%s: failed (%d), index (%d)",
+			         __func__, result, id));
+		}
+	} else {
+		value = a->stored;
+	}
+
+	switch (hint->data_type) {
+	case APPHINT_DATA_TYPE_UINT64:
+		result += snprintf(buffer + result, size - result,
+				"0x%016llx",
+				value.UINT64);
+		break;
+	case APPHINT_DATA_TYPE_UINT32:
+		result += snprintf(buffer + result, size - result,
+				"0x%08x",
+				value.UINT32);
+		break;
+	case APPHINT_DATA_TYPE_BOOL:
+		result += snprintf(buffer + result, size - result,
+			"%s",
+			value.BOOL ? "Y" : "N");
+		break;
+	case APPHINT_DATA_TYPE_STRING:
+		if (value.STRING) {
+			result += snprintf(buffer + result, size - result,
+				"%s",
+				*value.STRING ? value.STRING : "(none)");
+		} else {
+			result += snprintf(buffer + result, size - result,
+			"(none)");
+		}
+		break;
+	case APPHINT_DATA_TYPE_UINT32List:
+	{
+		struct apphint_lookup *lookup =
+			(struct apphint_lookup *) hint->data_type_helper;
+		IMG_UINT32 i;
+
+		if (!lookup) {
+			result = -EINVAL;
+			goto err_exit;
+		}
+
+		for (i = 0; i < hint->helper_size; i++) {
+			if (lookup[i].value == value.UINT32) {
+				result += snprintf(buffer + result,
+						size - result,
+						"%s",
+						lookup[i].name);
+				break;
+			}
+		}
+		break;
+	}
+	case APPHINT_DATA_TYPE_UINT32Bitfield:
+	{
+		struct apphint_lookup *lookup =
+			(struct apphint_lookup *) hint->data_type_helper;
+		IMG_UINT32 i;
+
+		if (!lookup) {
+			result = -EINVAL;
+			goto err_exit;
+		}
+
+		for (i = 0; i < hint->helper_size; i++) {
+			if (lookup[i].value & value.UINT32) {
+				result += snprintf(buffer + result,
+						size - result,
+						"%s,",
+						lookup[i].name);
+			}
+		}
+		if (result) {
+			/* remove any trailing ',' */
+			--result;
+			*(buffer + result) = '\0';
+		} else {
+			result += snprintf(buffer + result,
+					size - result, "none");
+		}
+		break;
+	}
+	default:
+		PVR_DPF((PVR_DBG_ERROR,
+			 "%s: unrecognised data type (%d), index (%d)",
+			 __func__, hint->data_type, id));
+		result = -EINVAL;
+	}
+
+err_exit:
+	return result;
+}
+
+/*
+*******************************************************************************
+ Module parameters initialization - different from debugfs
+******************************************************************************/
+/**
+ * apphint_kparam_set - Handle an update of a module parameter
+ *
+ * Returns 0, or -errno.  arg is in kp->arg.
+ */
+static int apphint_kparam_set(const char *val, const struct kernel_param *kp)
+{
+	char val_copy[APPHINT_BUFFER_SIZE];
+	APPHINT_ID id;
+	union apphint_value value;
+	int result;
+
+	/* need to discard const in case of string comparison */
+	result = strlcpy(val_copy, val, APPHINT_BUFFER_SIZE);
+
+	get_apphint_id_from_action_addr(kp->arg, &id);
+	if (result < APPHINT_BUFFER_SIZE) {
+		result = apphint_read(val_copy, result, id, &value);
+		if (result >= 0) {
+			((struct apphint_action *)kp->arg)->stored = value;
+			if (param_lookup[id].data_type == APPHINT_DATA_TYPE_STRING) {
+				((struct apphint_action *)kp->arg)->free = true;
+			}
+		}
+	} else {
+		PVR_DPF((PVR_DBG_ERROR, "%s: String too long", __func__));
+	}
+	return (result > 0) ? 0 : result;
+}
+
+/**
+ * apphint_kparam_get - handle a read of a module parameter
+ *
+ * Returns length written or -errno.  Buffer is 4k (ie. be short!)
+ */
+static int apphint_kparam_get(char *buffer, const struct kernel_param *kp)
+{
+	return apphint_write(buffer, PAGE_SIZE, kp->arg);
+}
+
+__maybe_unused
+static const struct kernel_param_ops apphint_kparam_fops = {
+	.set = apphint_kparam_set,
+	.get = apphint_kparam_get,
+};
+
+/*
+ * call module_param_cb() for all AppHints listed in APPHINT_LIST_MODPARAM
+ * apphint_modparam_class_ ## resolves to apphint_modparam_enable() except for
+ * AppHint classes that have been disabled.
+ */
+
+#define apphint_modparam_enable(name, number, perm) \
+	module_param_cb(name, &apphint_kparam_fops, &apphint.val[number], perm);
+
+#define X(a, b, c, d, e) \
+	apphint_modparam_class_ ##c(a, APPHINT_ID_ ## a, (S_IRUSR|S_IRGRP|S_IROTH))
+	APPHINT_LIST_MODPARAM
+#undef X
+
+/*
+*******************************************************************************
+ Debugfs get (seq file) operations - supporting functions
+******************************************************************************/
+static void *apphint_seq_start(struct seq_file *s, loff_t *pos)
+{
+	if (*pos == 0) {
+		/* We want only one entry in the sequence, one call to show() */
+		return (void *) 1;
+	}
+
+	PVR_UNREFERENCED_PARAMETER(s);
+
+	return NULL;
+}
+
+static void apphint_seq_stop(struct seq_file *s, void *v)
+{
+	PVR_UNREFERENCED_PARAMETER(s);
+	PVR_UNREFERENCED_PARAMETER(v);
+}
+
+static void *apphint_seq_next(struct seq_file *s, void *v, loff_t *pos)
+{
+	PVR_UNREFERENCED_PARAMETER(s);
+	PVR_UNREFERENCED_PARAMETER(v);
+	PVR_UNREFERENCED_PARAMETER(pos);
+	return NULL;
+}
+
+static int apphint_seq_show(struct seq_file *s, void *v)
+{
+	IMG_CHAR km_buffer[APPHINT_BUFFER_SIZE];
+	int result;
+
+	PVR_UNREFERENCED_PARAMETER(v);
+
+	result = apphint_write(km_buffer, APPHINT_BUFFER_SIZE, s->private);
+	if (result < 0) {
+		PVR_DPF((PVR_DBG_ERROR, "%s: failure", __func__));
+	} else {
+		/* debugfs requires a trailing \n, module_params don't */
+		result += snprintf(km_buffer + result,
+				APPHINT_BUFFER_SIZE - result,
+				"\n");
+		seq_puts(s, km_buffer);
+	}
+
+	/* have to return 0 to see output */
+	return (result < 0) ? result : 0;
+}
+
+static const struct seq_operations apphint_seq_fops = {
+	.start = apphint_seq_start,
+	.stop  = apphint_seq_stop,
+	.next  = apphint_seq_next,
+	.show  = apphint_seq_show,
+};
+
+/*
+*******************************************************************************
+ Debugfs supporting functions
+******************************************************************************/
+/**
+ * apphint_set - Handle a debugfs value update
+ */
+static ssize_t apphint_set(const char __user *buffer,
+			    size_t count,
+			    loff_t position,
+			    void *data)
+{
+	APPHINT_ID id;
+	union apphint_value value;
+	struct apphint_action *action = data;
+	char km_buffer[APPHINT_BUFFER_SIZE];
+	int result = 0;
+
+	PVR_UNREFERENCED_PARAMETER(position);
+
+	if (count >= APPHINT_BUFFER_SIZE) {
+		PVR_DPF((PVR_DBG_ERROR, "%s: String too long (%zd)",
+			__func__, count));
+		result = -EINVAL;
+		goto err_exit;
+	}
+
+	if (pvr_copy_from_user(km_buffer, buffer, count)) {
+		PVR_DPF((PVR_DBG_ERROR, "%s: Copy of user data failed",
+			__func__));
+		result = -EFAULT;
+		goto err_exit;
+	}
+	km_buffer[count] = '\0';
+
+	get_apphint_id_from_action_addr(action, &id);
+	result = apphint_read(km_buffer, count, id, &value);
+	if (result >= 0)
+		apphint_action(value, action);
+
+err_exit:
+	return result;
+}
+
+/**
+ * apphint_debugfs_init - Create the specified debugfs entries
+ */
+static int apphint_debugfs_init(char *sub_dir,
+		int device_num,
+		unsigned init_data_size,
+		const struct apphint_init_data *init_data,
+		PVR_DEBUGFS_DIR_DATA *parentdir,
+		PVR_DEBUGFS_DIR_DATA **rootdir, PVR_DEBUGFS_ENTRY_DATA **entry)
+{
+	int result = 0;
+	unsigned i;
+	int device_value_offset = device_num * APPHINT_DEBUGFS_DEVICE_ID_MAX;
+
+	if (*rootdir) {
+		PVR_DPF((PVR_DBG_WARNING,
+			"AppHint DebugFS already created, skipping"));
+		result = -EEXIST;
+		goto err_exit;
+	}
+
+	result = PVRDebugFSCreateEntryDir(sub_dir, parentdir,
+					  rootdir);
+	if (result < 0) {
+		PVR_DPF((PVR_DBG_WARNING,
+			"Failed to create \"%s\" DebugFS directory.", sub_dir));
+		goto err_exit;
+	}
+
+	for (i = 0; i < init_data_size; i++) {
+		if (!class_state[init_data[i].class].enabled)
+			continue;
+
+		result = PVRDebugFSCreateEntry(init_data[i].name,
+				*rootdir,
+				&apphint_seq_fops,
+				apphint_set,
+				NULL,
+				NULL,
+				(void *) &apphint.val[init_data[i].id + device_value_offset],
+				&entry[i]);
+		if (result < 0) {
+			PVR_DPF((PVR_DBG_WARNING,
+				"Failed to create \"%s/%s\" DebugFS entry.",
+				sub_dir, init_data[i].name));
+		}
+	}
+
+err_exit:
+	return result;
+}
+
+/**
+ * apphint_debugfs_deinit- destroy the debugfs entries
+ */
+static void apphint_debugfs_deinit(unsigned num_entries,
+		PVR_DEBUGFS_DIR_DATA **rootdir, PVR_DEBUGFS_ENTRY_DATA **entry)
+{
+	unsigned i;
+
+	for (i = 0; i < num_entries; i++) {
+		if (entry[i]) {
+			PVRDebugFSRemoveEntry(&entry[i]);
+			entry[i] = NULL;
+		}
+	}
+
+	if (*rootdir) {
+		PVRDebugFSRemoveEntryDir(rootdir);
+		*rootdir = NULL;
+	}
+}
+
+/*
+*******************************************************************************
+ AppHint status dump implementation
+******************************************************************************/
+#if defined(PDUMP)
+static void apphint_pdump_values(void *flags, const IMG_CHAR *format, ...)
+{
+	char km_buffer[APPHINT_BUFFER_SIZE];
+	IMG_UINT32 ui32Flags = *(IMG_UINT32 *)flags;
+	va_list ap;
+
+	va_start(ap, format);
+	(void)vsnprintf(km_buffer, APPHINT_BUFFER_SIZE, format, ap);
+	va_end(ap);
+
+	PDumpCommentKM(km_buffer, ui32Flags);
+}
+#endif
+
+static void apphint_dump_values(char *group_name,
+			int device_num,
+			const struct apphint_init_data *group_data,
+			int group_size,
+			DUMPDEBUG_PRINTF_FUNC *pfnDumpDebugPrintf,
+			void *pvDumpDebugFile)
+{
+	int i, result;
+	int device_value_offset = device_num * APPHINT_DEBUGFS_DEVICE_ID_MAX;
+	char km_buffer[APPHINT_BUFFER_SIZE];
+
+	PVR_DUMPDEBUG_LOG("  %s", group_name);
+	for (i = 0; i < group_size; i++) {
+		result = apphint_write(km_buffer, APPHINT_BUFFER_SIZE,
+				&apphint.val[group_data[i].id + device_value_offset]);
+
+		if (result <= 0) {
+			PVR_DUMPDEBUG_LOG("    %s: <Error>",
+				group_data[i].name);
+		} else {
+			PVR_DUMPDEBUG_LOG("    %s: %s",
+				group_data[i].name, km_buffer);
+		}
+	}
+}
+
+/**
+ * Callback for debug dump
+ */
+static void apphint_dump_state(PVRSRV_DBGREQ_HANDLE hDebugRequestHandle,
+			IMG_UINT32 ui32VerbLevel,
+			DUMPDEBUG_PRINTF_FUNC *pfnDumpDebugPrintf,
+			void *pvDumpDebugFile)
+{
+	int i, result;
+	char km_buffer[APPHINT_BUFFER_SIZE];
+	PVRSRV_DEVICE_NODE *device = (PVRSRV_DEVICE_NODE *)hDebugRequestHandle;
+
+	if (DEBUG_REQUEST_VERBOSITY_HIGH == ui32VerbLevel) {
+		PVR_DUMPDEBUG_LOG("------[ AppHint Settings ]------");
+
+		apphint_dump_values("Build Vars", 0,
+			init_data_buildvar, ARRAY_SIZE(init_data_buildvar),
+			pfnDumpDebugPrintf, pvDumpDebugFile);
+
+		apphint_dump_values("Module Params", 0,
+			init_data_modparam, ARRAY_SIZE(init_data_modparam),
+			pfnDumpDebugPrintf, pvDumpDebugFile);
+
+		apphint_dump_values("Debugfs Params", 0,
+			init_data_debugfs, ARRAY_SIZE(init_data_debugfs),
+			pfnDumpDebugPrintf, pvDumpDebugFile);
+
+		for (i = 0; i < APPHINT_DEVICES_MAX; i++) {
+			if (!apphint.devices[i]
+			    || (device && device != apphint.devices[i]))
+				continue;
+
+			result = snprintf(km_buffer,
+					  APPHINT_BUFFER_SIZE,
+					  "Debugfs Params Device ID: %d",
+					  i);
+			if (0 > result)
+				continue;
+
+			apphint_dump_values(km_buffer, i,
+					    init_data_debugfs_device,
+					    ARRAY_SIZE(init_data_debugfs_device),
+					    pfnDumpDebugPrintf,
+					    pvDumpDebugFile);
+		}
+	}
+}
+
+/*
+*******************************************************************************
+ Public interface
+******************************************************************************/
+int pvr_apphint_init(void)
+{
+	int result, i;
+
+	if (apphint.initialized) {
+		result = -EEXIST;
+		goto err_out;
+	}
+
+	for (i = 0; i < APPHINT_DEVICES_MAX; i++)
+		apphint.devices[i] = NULL;
+
+	/* create workqueue with strict execution ordering to ensure no
+	 * race conditions when setting/updating apphints from different
+	 * contexts
+	 */
+	apphint.workqueue = alloc_workqueue("apphint_workqueue", WQ_UNBOUND, 1);
+	if (!apphint.workqueue) {
+		result = -ENOMEM;
+		goto err_out;
+	}
+
+	result = apphint_debugfs_init("apphint", 0,
+		ARRAY_SIZE(init_data_debugfs), init_data_debugfs,
+		NULL,
+		&apphint.debugfs_rootdir, apphint.debugfs_entry);
+	if (0 != result)
+		goto err_out;
+
+	result = apphint_debugfs_init("buildvar", 0,
+		ARRAY_SIZE(init_data_buildvar), init_data_buildvar,
+		NULL,
+		&apphint.buildvar_rootdir, apphint.buildvar_entry);
+
+	apphint.initialized = 1;
+
+err_out:
+	return result;
+}
+
+int pvr_apphint_device_register(PVRSRV_DEVICE_NODE *device)
+{
+	int result, i;
+	char device_num[APPHINT_BUFFER_SIZE];
+	int device_value_offset;
+
+	if (!apphint.initialized) {
+		result = -EAGAIN;
+		goto err_out;
+	}
+
+	if (apphint.num_devices+1 >= APPHINT_DEVICES_MAX) {
+		result = -EMFILE;
+		goto err_out;
+	}
+
+	result = snprintf(device_num, APPHINT_BUFFER_SIZE, "%d", apphint.num_devices);
+	if (result < 0) {
+		PVR_DPF((PVR_DBG_WARNING,
+			"snprintf failed (%d)", result));
+		result = -EINVAL;
+		goto err_out;
+	}
+
+	/* Set the default values for the new device */
+	device_value_offset = apphint.num_devices * APPHINT_DEBUGFS_DEVICE_ID_MAX;
+	for (i = 0; i < APPHINT_DEBUGFS_DEVICE_ID_MAX; i++) {
+		apphint.val[init_data_debugfs_device[i].id + device_value_offset].stored
+			= init_data_debugfs_device[i].default_value;
+	}
+
+	result = apphint_debugfs_init(device_num, apphint.num_devices,
+	                              ARRAY_SIZE(init_data_debugfs_device),
+	                              init_data_debugfs_device,
+	                              apphint.debugfs_rootdir,
+	                              &apphint.debugfs_device_rootdir[apphint.num_devices],
+	                              apphint.debugfs_device_entry[apphint.num_devices]);
+	if (0 != result)
+		goto err_out;
+
+	apphint.devices[apphint.num_devices] = device;
+	apphint.num_devices++;
+
+	(void)PVRSRVRegisterDbgRequestNotify(
+			&device->hAppHintDbgReqNotify,
+			device,
+			apphint_dump_state,
+			DEBUG_REQUEST_APPHINT,
+			device);
+
+err_out:
+	return result;
+}
+
+void pvr_apphint_device_unregister(PVRSRV_DEVICE_NODE *device)
+{
+	int i;
+
+	if (!apphint.initialized)
+		return;
+
+	/* find the device */
+	for (i = 0; i < APPHINT_DEVICES_MAX; i++) {
+		if (apphint.devices[i] == device)
+			break;
+	}
+
+	if (APPHINT_DEVICES_MAX == i)
+		return;
+
+	if (device->hAppHintDbgReqNotify) {
+		(void)PVRSRVUnregisterDbgRequestNotify(
+			device->hAppHintDbgReqNotify);
+		device->hAppHintDbgReqNotify = NULL;
+	}
+
+	apphint_debugfs_deinit(APPHINT_DEBUGFS_DEVICE_ID_MAX,
+	                       &apphint.debugfs_device_rootdir[i],
+	                       apphint.debugfs_device_entry[i]);
+
+	apphint.devices[i] = NULL;
+	apphint.num_devices--;
+}
+
+void pvr_apphint_deinit(void)
+{
+	int i;
+
+	if (!apphint.initialized)
+		return;
+
+	/* remove any remaining device data */
+	for (i = 0; apphint.num_devices && i < APPHINT_DEVICES_MAX; i++) {
+		if (apphint.devices[i])
+			pvr_apphint_device_unregister(apphint.devices[i]);
+	}
+
+	/* free all alloc'd string apphints and set to NULL */
+	for (i = 0; i < ARRAY_SIZE(apphint.val); i++) {
+		if (apphint.val[i].free && apphint.val[i].stored.STRING) {
+			kfree(apphint.val[i].stored.STRING);
+			apphint.val[i].stored.STRING = NULL;
+			apphint.val[i].free = false;
+		}
+	}
+
+	apphint_debugfs_deinit(APPHINT_DEBUGFS_ID_MAX,
+			&apphint.debugfs_rootdir, apphint.debugfs_entry);
+	apphint_debugfs_deinit(APPHINT_BUILDVAR_ID_MAX,
+			&apphint.buildvar_rootdir, apphint.buildvar_entry);
+
+	destroy_workqueue(apphint.workqueue);
+
+	apphint.initialized = 0;
+}
+
+void pvr_apphint_dump_state(void)
+{
+#if defined(PDUMP)
+	IMG_UINT32 ui32Flags = PDUMP_FLAGS_CONTINUOUS;
+
+	apphint_dump_state(NULL, DEBUG_REQUEST_VERBOSITY_HIGH,
+	                   apphint_pdump_values, (void *)&ui32Flags);
+#endif
+	apphint_dump_state(NULL, DEBUG_REQUEST_VERBOSITY_HIGH,
+	                   NULL, NULL);
+}
+
+int pvr_apphint_get_uint64(APPHINT_ID ue, IMG_UINT64 *pVal)
+{
+	int error = -ERANGE;
+
+	if (ue < APPHINT_ID_MAX) {
+		*pVal = apphint.val[ue].stored.UINT64;
+		error = 0;
+	}
+	return error;
+}
+
+int pvr_apphint_get_uint32(APPHINT_ID ue, IMG_UINT32 *pVal)
+{
+	int error = -ERANGE;
+
+	if (ue < APPHINT_ID_MAX) {
+		*pVal = apphint.val[ue].stored.UINT32;
+		error = 0;
+	}
+	return error;
+}
+
+int pvr_apphint_get_bool(APPHINT_ID ue, IMG_BOOL *pVal)
+{
+	int error = -ERANGE;
+
+	if (ue < APPHINT_ID_MAX) {
+		error = 0;
+		*pVal = apphint.val[ue].stored.BOOL;
+	}
+	return error;
+}
+
+int pvr_apphint_get_string(APPHINT_ID ue, IMG_CHAR *pBuffer, size_t size)
+{
+	int error = -ERANGE;
+	if (ue < APPHINT_ID_MAX && apphint.val[ue].stored.STRING) {
+		if (strlcpy(pBuffer, apphint.val[ue].stored.STRING, size) < size) {
+			error = 0;
+		}
+	}
+	return error;
+}
+
+void pvr_apphint_register_handlers_uint64(APPHINT_ID id,
+	PVRSRV_ERROR (*query)(const PVRSRV_DEVICE_NODE *device, const void *private_data, IMG_UINT64 *value),
+	PVRSRV_ERROR (*set)(const PVRSRV_DEVICE_NODE *device, const void *private_data, IMG_UINT64 value),
+	const PVRSRV_DEVICE_NODE *device,
+	const void *private_data)
+{
+	int device_value_offset;
+
+	if (id >= APPHINT_ID_MAX) {
+		PVR_DPF((PVR_DBG_ERROR,
+		         "%s: AppHint ID (%d) is out of range, max (%d)",
+		         __func__, id, APPHINT_ID_MAX-1));
+		return;
+	}
+
+	get_value_offset_from_device(device, &device_value_offset);
+
+	switch (param_lookup[id].data_type) {
+	case APPHINT_DATA_TYPE_UINT64:
+		break;
+	default:
+		PVR_DPF((PVR_DBG_ERROR,
+		         "%s: Does not match AppHint data type for ID (%d)",
+		         __func__, id));
+		return;
+	}
+
+	apphint.val[id + device_value_offset] = (struct apphint_action){
+		.query.UINT64 = query,
+		.set.UINT64 = set,
+		.device = device,
+		.private_data = private_data,
+		.stored = apphint.val[id + device_value_offset].stored
+	};
+}
+
+void pvr_apphint_register_handlers_uint32(APPHINT_ID id,
+	PVRSRV_ERROR (*query)(const PVRSRV_DEVICE_NODE *device, const void *private_data, IMG_UINT32 *value),
+	PVRSRV_ERROR (*set)(const PVRSRV_DEVICE_NODE *device, const void *private_data, IMG_UINT32 value),
+	const PVRSRV_DEVICE_NODE *device,
+	const void *private_data)
+{
+	int device_value_offset;
+
+	if (id >= APPHINT_ID_MAX) {
+		PVR_DPF((PVR_DBG_ERROR,
+		         "%s: AppHint ID (%d) is out of range, max (%d)",
+		         __func__, id, APPHINT_ID_MAX-1));
+		return;
+	}
+
+	get_value_offset_from_device(device, &device_value_offset);
+
+	switch (param_lookup[id].data_type) {
+	case APPHINT_DATA_TYPE_UINT32:
+	case APPHINT_DATA_TYPE_UINT32Bitfield:
+	case APPHINT_DATA_TYPE_UINT32List:
+		break;
+
+	default:
+		PVR_DPF((PVR_DBG_ERROR,
+		         "%s: Does not match AppHint data type for ID (%d)",
+		         __func__, id));
+		return;
+	}
+
+	apphint.val[id + device_value_offset] = (struct apphint_action){
+		.query.UINT32 = query,
+		.set.UINT32 = set,
+		.device = device,
+		.private_data = private_data,
+		.stored = apphint.val[id + device_value_offset].stored
+	};
+}
+
+void pvr_apphint_register_handlers_bool(APPHINT_ID id,
+	PVRSRV_ERROR (*query)(const PVRSRV_DEVICE_NODE *device, const void *private_data, IMG_BOOL *value),
+	PVRSRV_ERROR (*set)(const PVRSRV_DEVICE_NODE *device, const void *private_data, IMG_BOOL value),
+	const PVRSRV_DEVICE_NODE *device,
+	const void *private_data)
+{
+	int device_value_offset;
+
+	if (id >= APPHINT_ID_MAX) {
+		PVR_DPF((PVR_DBG_ERROR,
+		         "%s: AppHint ID (%d) is out of range, max (%d)",
+		         __func__, id, APPHINT_ID_MAX-1));
+		return;
+	}
+
+	get_value_offset_from_device(device, &device_value_offset);
+
+	switch (param_lookup[id].data_type) {
+	case APPHINT_DATA_TYPE_BOOL:
+		break;
+
+	default:
+		PVR_DPF((PVR_DBG_ERROR,
+		         "%s: Does not match AppHint data type for ID (%d)",
+		         __func__, id));
+		return;
+	}
+
+	apphint.val[id + device_value_offset] = (struct apphint_action){
+		.query.BOOL = query,
+		.set.BOOL = set,
+		.device = device,
+		.private_data = private_data,
+		.stored = apphint.val[id + device_value_offset].stored
+	};
+}
+
+void pvr_apphint_register_handlers_string(APPHINT_ID id,
+	PVRSRV_ERROR (*query)(const PVRSRV_DEVICE_NODE *device, const void *private_data, IMG_CHAR **value),
+	PVRSRV_ERROR (*set)(const PVRSRV_DEVICE_NODE *device, const void *private_data, IMG_CHAR *value),
+	const PVRSRV_DEVICE_NODE *device,
+	const void *private_data)
+{
+	int device_value_offset;
+
+	if (id >= APPHINT_ID_MAX) {
+		PVR_DPF((PVR_DBG_ERROR,
+		         "%s: AppHint ID (%d) is out of range, max (%d)",
+		         __func__, id, APPHINT_ID_MAX-1));
+		return;
+	}
+
+	get_value_offset_from_device(device, &device_value_offset);
+
+	switch (param_lookup[id].data_type) {
+	case APPHINT_DATA_TYPE_STRING:
+		break;
+
+	default:
+		PVR_DPF((PVR_DBG_ERROR,
+		         "%s: Does not match AppHint data type for ID (%d)",
+		         __func__, id));
+		return;
+	}
+
+	apphint.val[id + device_value_offset] = (struct apphint_action){
+		.query.STRING = query,
+		.set.STRING = set,
+		.device = device,
+		.private_data = private_data,
+		.stored = apphint.val[id + device_value_offset].stored
+	};
+}
+
+#endif /* #if defined(SUPPORT_KERNEL_SRVINIT) */
+/* EOF */
+
diff --git a/drivers/staging/imgtec/rogue/km_apphint.h b/drivers/staging/imgtec/rogue/km_apphint.h
new file mode 100644
index 0000000..833b568
--- /dev/null
+++ b/drivers/staging/imgtec/rogue/km_apphint.h
@@ -0,0 +1,151 @@
+/*************************************************************************/ /*!
+@File           km_apphint.h
+@Title          Apphint internal header
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description    Linux kernel AppHint control
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#ifndef __KM_APPHINT_H__
+#define __KM_APPHINT_H__
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+#include "km_apphint_defs.h"
+#include "device.h"
+
+#if defined(SUPPORT_KERNEL_SRVINIT)
+
+int pvr_apphint_init(void);
+void pvr_apphint_deinit(void);
+int pvr_apphint_device_register(PVRSRV_DEVICE_NODE *device);
+void pvr_apphint_device_unregister(PVRSRV_DEVICE_NODE *device);
+void pvr_apphint_dump_state(void);
+
+int pvr_apphint_get_uint64(APPHINT_ID ue, IMG_UINT64 *pVal);
+int pvr_apphint_get_uint32(APPHINT_ID ue, IMG_UINT32 *pVal);
+int pvr_apphint_get_bool(APPHINT_ID ue, IMG_BOOL *pVal);
+int pvr_apphint_get_string(APPHINT_ID ue, IMG_CHAR *pBuffer, size_t size);
+
+void pvr_apphint_register_handlers_uint64(APPHINT_ID id,
+	PVRSRV_ERROR (*query)(const PVRSRV_DEVICE_NODE *device, const void *private_data, IMG_UINT64 *value),
+	PVRSRV_ERROR (*set)(const PVRSRV_DEVICE_NODE *device, const void *private_data, IMG_UINT64 value),
+	const PVRSRV_DEVICE_NODE *device,
+	const void * private_data);
+void pvr_apphint_register_handlers_uint32(APPHINT_ID id,
+	PVRSRV_ERROR (*query)(const PVRSRV_DEVICE_NODE *device, const void *private_data, IMG_UINT32 *value),
+	PVRSRV_ERROR (*set)(const PVRSRV_DEVICE_NODE *device, const void *private_data, IMG_UINT32 value),
+	const PVRSRV_DEVICE_NODE *device,
+	const void *private_data);
+void pvr_apphint_register_handlers_bool(APPHINT_ID id,
+	PVRSRV_ERROR (*query)(const PVRSRV_DEVICE_NODE *device, const void *private_data, IMG_BOOL *value),
+	PVRSRV_ERROR (*set)(const PVRSRV_DEVICE_NODE *device, const void *private_data, IMG_BOOL value),
+	const PVRSRV_DEVICE_NODE *device,
+	const void *private_data);
+void pvr_apphint_register_handlers_string(APPHINT_ID id,
+	PVRSRV_ERROR (*query)(const PVRSRV_DEVICE_NODE *device, const void *private_data, IMG_CHAR **value),
+	PVRSRV_ERROR (*set)(const PVRSRV_DEVICE_NODE *device, const void *private_data, IMG_CHAR *value),
+	const PVRSRV_DEVICE_NODE *device,
+	const void *private_data);
+
+#else
+
+static INLINE void pvr_apphint_register_handlers_uint64(APPHINT_ID id,
+	PVRSRV_ERROR (*query)(const PVRSRV_DEVICE_NODE *device, const void *private_data, IMG_UINT64 *value),
+	PVRSRV_ERROR (*set)(const PVRSRV_DEVICE_NODE *device, const void *private_data, IMG_UINT64 value),
+	const PVRSRV_DEVICE_NODE *device,
+	const void * private_data)
+{
+	PVR_UNREFERENCED_PARAMETER(id);
+	PVR_UNREFERENCED_PARAMETER(query);
+	PVR_UNREFERENCED_PARAMETER(set);
+	PVR_UNREFERENCED_PARAMETER(device);
+	PVR_UNREFERENCED_PARAMETER(private_data);
+}
+
+static INLINE void pvr_apphint_register_handlers_uint32(APPHINT_ID id,
+	PVRSRV_ERROR (*query)(const PVRSRV_DEVICE_NODE *device, const void *private_data, IMG_UINT32 *value),
+	PVRSRV_ERROR (*set)(const PVRSRV_DEVICE_NODE *device, const void *private_data, IMG_UINT32 value),
+	const PVRSRV_DEVICE_NODE *device,
+	const void *private_data)
+{
+	PVR_UNREFERENCED_PARAMETER(id);
+	PVR_UNREFERENCED_PARAMETER(query);
+	PVR_UNREFERENCED_PARAMETER(set);
+	PVR_UNREFERENCED_PARAMETER(device);
+	PVR_UNREFERENCED_PARAMETER(private_data);
+}
+
+static INLINE void pvr_apphint_register_handlers_bool(APPHINT_ID id,
+	PVRSRV_ERROR (*query)(const PVRSRV_DEVICE_NODE *device, const void *private_data, IMG_BOOL *value),
+	PVRSRV_ERROR (*set)(const PVRSRV_DEVICE_NODE *device, const void *private_data, IMG_BOOL value),
+	const PVRSRV_DEVICE_NODE *device,
+	const void *private_data)
+{
+	PVR_UNREFERENCED_PARAMETER(id);
+	PVR_UNREFERENCED_PARAMETER(query);
+	PVR_UNREFERENCED_PARAMETER(set);
+	PVR_UNREFERENCED_PARAMETER(device);
+	PVR_UNREFERENCED_PARAMETER(private_data);
+}
+
+static INLINE void pvr_apphint_register_handlers_string(APPHINT_ID id,
+	PVRSRV_ERROR (*query)(const PVRSRV_DEVICE_NODE *device, const void *private_data, IMG_CHAR **value),
+	PVRSRV_ERROR (*set)(const PVRSRV_DEVICE_NODE *device, const void *private_data, IMG_CHAR *value),
+	const PVRSRV_DEVICE_NODE *device,
+	const void *private_data)
+{
+	PVR_UNREFERENCED_PARAMETER(id);
+	PVR_UNREFERENCED_PARAMETER(query);
+	PVR_UNREFERENCED_PARAMETER(set);
+	PVR_UNREFERENCED_PARAMETER(device);
+	PVR_UNREFERENCED_PARAMETER(private_data);
+}
+#endif
+
+#if defined(__cplusplus)
+}
+#endif
+#endif /* __KM_APPHINT_H__ */
+
+/******************************************************************************
+ End of file (apphint.h)
+******************************************************************************/
+
diff --git a/drivers/staging/imgtec/rogue/km_apphint_defs.h b/drivers/staging/imgtec/rogue/km_apphint_defs.h
new file mode 100644
index 0000000..48d0398
--- /dev/null
+++ b/drivers/staging/imgtec/rogue/km_apphint_defs.h
@@ -0,0 +1,304 @@
+/*************************************************************************/ /*!
+@File
+@Title          Services AppHint definitions
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description    Device specific functions
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+
+#ifndef __KM_APPHINT_DEFS_H__
+#define __KM_APPHINT_DEFS_H__
+
+/* NB: The 'DEVICE' AppHints must be last in this list as they will be
+ * duplicated in the case of a driver supporting multiple devices
+ */
+#define APPHINT_LIST_ALL \
+	APPHINT_LIST_BUILDVAR \
+	APPHINT_LIST_MODPARAM \
+	APPHINT_LIST_DEBUGFS \
+	APPHINT_LIST_DEPRECATED \
+	APPHINT_LIST_DEBUGFS_DEVICE
+
+/*
+*******************************************************************************
+ Build variables
+ All of these should be configurable only through the 'default' value
+******************************************************************************/
+#define APPHINT_LIST_BUILDVAR \
+/* name,                            type,           class,       default,                                         helper,         */ \
+X(HWRDebugDumpLimit,                UINT32,         DEBUG,       PVRSRV_APPHINT_HWRDEBUGDUMPLIMIT,                NULL             ) \
+X(EnableTrustedDeviceAceConfig,     BOOL,           GPUVIRT_VAL, PVRSRV_APPHINT_ENABLETRUSTEDDEVICEACECONFIG,     NULL             ) \
+X(HTBufferSize,                     UINT32,         ALWAYS,      PVRSRV_APPHINT_HTBUFFERSIZE,                     NULL             ) \
+X(CleanupThreadPriority,            UINT32,         NEVER,       PVRSRV_APPHINT_CLEANUPTHREADPRIORITY,            NULL             ) \
+X(CleanupThreadWeight,              UINT32,         NEVER,       PVRSRV_APPHINT_CLEANUPTHREADWEIGHT,              NULL             ) \
+X(WatchdogThreadPriority,           UINT32,         NEVER,       PVRSRV_APPHINT_WATCHDOGTHREADPRIORITY,           NULL             ) \
+X(WatchdogThreadWeight,             UINT32,         NEVER,       PVRSRV_APPHINT_WATCHDOGTHREADWEIGHT,             NULL             ) \
+
+/*
+*******************************************************************************
+ Module parameters
+******************************************************************************/
+#define APPHINT_LIST_MODPARAM \
+/* name,                            type,           class,       default,                                         helper,         */ \
+X(EnableSignatureChecks,            BOOL,           PDUMP,       PVRSRV_APPHINT_ENABLESIGNATURECHECKS,            NULL             ) \
+X(SignatureChecksBufSize,           UINT32,         PDUMP,       PVRSRV_APPHINT_SIGNATURECHECKSBUFSIZE,           NULL             ) \
+\
+X(DisableClockGating,               BOOL,           FWDBGCTRL,   PVRSRV_APPHINT_DISABLECLOCKGATING,               NULL             ) \
+X(DisableDMOverlap,                 BOOL,           FWDBGCTRL,   PVRSRV_APPHINT_DISABLEDMOVERLAP,                 NULL             ) \
+\
+X(EnableCDMKillingRandMode,         BOOL,           VALIDATION,  PVRSRV_APPHINT_ENABLECDMKILLINGRANDMODE,         NULL             ) \
+X(EnableFWContextSwitch,            UINT32,         FWDBGCTRL,   PVRSRV_APPHINT_ENABLEFWCONTEXTSWITCH,            NULL             ) \
+X(EnableRDPowerIsland,              UINT32,         FWDBGCTRL,   PVRSRV_APPHINT_ENABLERDPOWERISLAND,              NULL             ) \
+\
+X(GeneralNon4KHeapPageSize,         UINT32,         ALWAYS,      PVRSRV_APPHINT_GENERAL_NON4K_HEAP_PAGE_SIZE,     NULL             ) \
+\
+X(FirmwarePerf,                     UINT32,         VALIDATION,  PVRSRV_APPHINT_FIRMWAREPERF,                     NULL             ) \
+X(FWContextSwitchProfile,           UINT32,         VALIDATION,  PVRSRV_APPHINT_FWCONTEXTSWITCHPROFILE,           NULL             ) \
+X(HWPerfDisableCustomCounterFilter, BOOL,           VALIDATION,  PVRSRV_APPHINT_HWPERFDISABLECUSTOMCOUNTERFILTER, NULL             ) \
+X(HWPerfFWBufSizeInKB,              UINT32,         VALIDATION,  PVRSRV_APPHINT_HWPERFFWBUFSIZEINKB,              NULL             ) \
+X(HWPerfHostBufSizeInKB,            UINT32,         VALIDATION,  PVRSRV_APPHINT_HWPERFHOSTBUFSIZEINKB,            NULL             ) \
+\
+X(JonesDisableMask,                 UINT32,         VALIDATION,  PVRSRV_APPHINT_JONESDISABLEMASK,                 NULL             ) \
+X(NewFilteringMode,                 BOOL,           VALIDATION,  PVRSRV_APPHINT_NEWFILTERINGMODE,                 NULL             ) \
+X(TruncateMode,                     UINT32,         VALIDATION,  PVRSRV_APPHINT_TRUNCATEMODE,                     NULL             ) \
+X(UseMETAT1,                        UINT32,         VALIDATION,  PVRSRV_APPHINT_USEMETAT1,                        NULL             ) \
+X(RGXBVNC,                          STRING,         ALWAYS,      PVRSRV_APPHINT_RGXBVNC,                          NULL             ) \
+
+/*
+*******************************************************************************
+ Debugfs parameters - driver configuration
+******************************************************************************/
+#define APPHINT_LIST_DEBUGFS \
+/* name,                            type,           class,       default,                                         helper,         */ \
+X(EnableHTBLogGroup,                UINT32Bitfield, ALWAYS,      PVRSRV_APPHINT_ENABLEHTBLOGGROUP,                htb_loggroup_tbl ) \
+X(HTBOperationMode,                 UINT32List,     ALWAYS,      PVRSRV_APPHINT_HTBOPERATIONMODE,                 htb_opmode_tbl   ) \
+X(HWPerfFWFilter,                   UINT64,         ALWAYS,      PVRSRV_APPHINT_HWPERFFWFILTER,                   NULL             ) \
+X(HWPerfHostFilter,                 UINT32,         ALWAYS,      PVRSRV_APPHINT_HWPERFHOSTFILTER,                 NULL             ) \
+X(TimeCorrClock,                    UINT32List,     ALWAYS,      PVRSRV_APPHINT_TIMECORRCLOCK,                    timecorr_clk_tbl )
+
+/*
+*******************************************************************************
+ Debugfs parameters - device configuration
+******************************************************************************/
+#define APPHINT_LIST_DEBUGFS_DEVICE \
+/* name,                            type,           class,       default,                                         helper,         */ \
+/* Device Firmware config */\
+X(AssertOnHWRTrigger,               BOOL,           ALWAYS,      PVRSRV_APPHINT_ASSERTONHWRTRIGGER,               NULL             ) \
+X(AssertOutOfMemory,                BOOL,           ALWAYS,      PVRSRV_APPHINT_ASSERTOUTOFMEMORY,                NULL             ) \
+X(CheckMList,                       BOOL,           ALWAYS,      PVRSRV_APPHINT_CHECKMLIST,                       NULL             ) \
+X(EnableHWR,                        BOOL,           ALWAYS,      APPHNT_BLDVAR_ENABLEHWR,                         NULL             ) \
+X(EnableLogGroup,                   UINT32Bitfield, ALWAYS,      PVRSRV_APPHINT_ENABLELOGGROUP,                   fwt_loggroup_tbl ) \
+X(FirmwareLogType,                  UINT32List,     ALWAYS,      PVRSRV_APPHINT_FIRMWARELOGTYPE,                  fwt_logtype_tbl  ) \
+/* Device host config */ \
+X(EnableAPM,                        UINT32,         ALWAYS,      PVRSRV_APPHINT_ENABLEAPM,                        NULL             ) \
+X(DisableFEDLogging,                BOOL,           ALWAYS,      PVRSRV_APPHINT_DISABLEFEDLOGGING,                NULL             ) \
+X(ZeroFreelist,                     BOOL,           ALWAYS,      PVRSRV_APPHINT_ZEROFREELIST,                     NULL             ) \
+X(DustRequestInject,                BOOL,           VALIDATION,  PVRSRV_APPHINT_DUSTREQUESTINJECT,                NULL             ) \
+X(DisablePDumpPanic,                BOOL,           PDUMP,       PVRSRV_APPHINT_DISABLEPDUMPPANIC,                NULL             ) \
+X(EnableFWPoisonOnFree,             BOOL,           ALWAYS,      PVRSRV_APPHINT_ENABLEFWPOISONONFREE,             NULL             ) \
+X(FWPoisonOnFreeValue,              UINT32,         ALWAYS,      PVRSRV_APPHINT_FWPOISONONFREEVALUE,              NULL             ) \
+
+/*
+*******************************************************************************
+ Deprecated parameters kept for backwards compatibility
+******************************************************************************/
+#define APPHINT_LIST_DEPRECATED \
+/* name,                            type,           class,       default,                                         helper,         */ \
+X(EnableFTraceGPU,                  BOOL,           ALWAYS,      0,                                               NULL             ) \
+X(EnableRTUBypass,                  BOOL,           ALWAYS,      0,                                               NULL             ) \
+\
+X(EnableHWPerf,                     BOOL,           ALWAYS,      0,                                               NULL             ) \
+X(EnableHWPerfHost,                 BOOL,           ALWAYS,      0,                                               NULL             ) \
+\
+X(DisablePDP,                       BOOL,           PDUMP,       PVRSRV_APPHINT_DISABLEPDUMPPANIC,                NULL             ) \
+X(HWPerfFilter0,                    UINT32,         ALWAYS,      0,                                               NULL             ) \
+X(HWPerfFilter1,                    UINT32,         ALWAYS,      0,                                               NULL             ) \
+
+/*
+*******************************************************************************
+ * Types used in the APPHINT_LIST_<GROUP> lists must be defined here.
+ * New types require specific handling code to be added
+******************************************************************************/
+#define APPHINT_DATA_TYPE_LIST \
+X(BOOL) \
+X(UINT64) \
+X(UINT32) \
+X(UINT32Bitfield) \
+X(UINT32List) \
+X(STRING)
+
+#define APPHINT_CLASS_LIST \
+X(ALWAYS) \
+X(NEVER) \
+X(DEBUG) \
+X(FWDBGCTRL) \
+X(PDUMP) \
+X(VALIDATION) \
+X(GPUVIRT_VAL)
+
+/*
+*******************************************************************************
+ Visibility control for module parameters
+ These bind build variables to AppHint Visibility Groups.
+******************************************************************************/
+#define APPHINT_ENABLED_CLASS_ALWAYS IMG_TRUE
+#define APPHINT_ENABLED_CLASS_NEVER IMG_FALSE
+#define apphint_modparam_class_ALWAYS(a, b, c) apphint_modparam_enable(a, b, c)
+#if defined(DEBUG)
+	#define APPHINT_ENABLED_CLASS_DEBUG IMG_TRUE
+	#define apphint_modparam_class_DEBUG(a, b, c) apphint_modparam_enable(a, b, c)
+#else
+	#define APPHINT_ENABLED_CLASS_DEBUG IMG_FALSE
+	#define apphint_modparam_class_DEBUG(a, b, c)
+#endif
+#if defined(SUPPORT_FWDBGCTRL)
+	#define APPHINT_ENABLED_CLASS_FWDBGCTRL IMG_TRUE
+	#define apphint_modparam_class_FWDBGCTRL(a, b, c) apphint_modparam_enable(a, b, c)
+#else
+	#define APPHINT_ENABLED_CLASS_FWDBGCTRL IMG_FALSE
+	#define apphint_modparam_class_FWDBGCTRL(a, b, c)
+#endif
+#if defined(PDUMP)
+	#define APPHINT_ENABLED_CLASS_PDUMP IMG_TRUE
+	#define apphint_modparam_class_PDUMP(a, b, c) apphint_modparam_enable(a, b, c)
+#else
+	#define APPHINT_ENABLED_CLASS_PDUMP IMG_FALSE
+	#define apphint_modparam_class_PDUMP(a, b, c)
+#endif
+#if defined(SUPPORT_VALIDATION)
+	#define APPHINT_ENABLED_CLASS_VALIDATION IMG_TRUE
+	#define apphint_modparam_class_VALIDATION(a, b, c) apphint_modparam_enable(a, b, c)
+#else
+	#define APPHINT_ENABLED_CLASS_VALIDATION IMG_FALSE
+	#define apphint_modparam_class_VALIDATION(a, b, c)
+#endif
+#if defined(SUPPORT_GPUVIRT_VALIDATION)
+	#define APPHINT_ENABLED_CLASS_GPUVIRT_VAL IMG_TRUE
+	#define apphint_modparam_class_GPUVIRT_VAL(a, b, c) apphint_modparam_enable(a, b, c)
+#else
+	#define APPHINT_ENABLED_CLASS_GPUVIRT_VAL IMG_FALSE
+	#define apphint_modparam_class_GPUVIRT_VAL(a, b, c)
+#endif
+
+/*
+*******************************************************************************
+ AppHint defaults based on other build parameters
+******************************************************************************/
+#if defined(HWR_DEFAULT_ENABLED)
+	#define APPHNT_BLDVAR_ENABLEHWR         1
+#else
+	#define APPHNT_BLDVAR_ENABLEHWR         0
+#endif
+#if defined(DEBUG)
+	#define APPHNT_BLDVAR_DEBUG             1
+	#define APPHNT_BLDVAR_DBGDUMPLIMIT      RGXFWIF_HWR_DEBUG_DUMP_ALL
+#else
+	#define APPHNT_BLDVAR_DEBUG             0
+	#define APPHNT_BLDVAR_DBGDUMPLIMIT      1
+#endif
+#if defined(DEBUG) || defined(PDUMP)
+#define APPHNT_BLDVAR_ENABLESIGNATURECHECKS     IMG_TRUE
+#else
+#define APPHNT_BLDVAR_ENABLESIGNATURECHECKS     IMG_FALSE
+#endif
+
+/*
+*******************************************************************************
+
+ Table generated enums
+
+******************************************************************************/
+/* Unique ID for all AppHints */
+typedef enum {
+#define X(a, b, c, d, e) APPHINT_ID_ ## a,
+	APPHINT_LIST_ALL
+#undef X
+	APPHINT_ID_MAX
+} APPHINT_ID;
+
+/* ID for build variable Apphints - used for build variable only structures */
+typedef enum {
+#define X(a, b, c, d, e) APPHINT_BUILDVAR_ID_ ## a,
+	APPHINT_LIST_BUILDVAR
+#undef X
+	APPHINT_BUILDVAR_ID_MAX
+} APPHINT_BUILDVAR_ID;
+
+/* ID for Modparam Apphints - used for modparam only structures */
+typedef enum {
+#define X(a, b, c, d, e) APPHINT_MODPARAM_ID_ ## a,
+	APPHINT_LIST_MODPARAM
+#undef X
+	APPHINT_MODPARAM_ID_MAX
+} APPHINT_MODPARAM_ID;
+
+/* ID for Debugfs Apphints - used for debugfs only structures */
+typedef enum {
+#define X(a, b, c, d, e) APPHINT_DEBUGFS_ID_ ## a,
+	APPHINT_LIST_DEBUGFS
+#undef X
+	APPHINT_DEBUGFS_ID_MAX
+} APPHINT_DEBUGFS_ID;
+
+/* ID for Debugfs Device Apphints - used for debugfs device only structures */
+typedef enum {
+#define X(a, b, c, d, e) APPHINT_DEBUGFS_DEVICE_ID_ ## a,
+	APPHINT_LIST_DEBUGFS_DEVICE
+#undef X
+	APPHINT_DEBUGFS_DEVICE_ID_MAX
+} APPHINT_DEBUGFS_DEVICE_ID;
+
+/* data types and actions */
+typedef enum {
+	APPHINT_DATA_TYPE_INVALID = 0,
+#define X(a) APPHINT_DATA_TYPE_ ## a,
+	APPHINT_DATA_TYPE_LIST
+#undef X
+	APPHINT_DATA_TYPE_MAX
+} APPHINT_DATA_TYPE;
+
+typedef enum {
+#define X(a) APPHINT_CLASS_ ## a,
+	APPHINT_CLASS_LIST
+#undef X
+	APPHINT_CLASS_MAX
+} APPHINT_CLASS;
+
+#endif /* __KM_APPHINT_DEFS_H__ */
+
diff --git a/drivers/staging/imgtec/rogue/linkage.h b/drivers/staging/imgtec/rogue/linkage.h
index 92416e3..2cfe060 100644
--- a/drivers/staging/imgtec/rogue/linkage.h
+++ b/drivers/staging/imgtec/rogue/linkage.h
@@ -46,19 +46,15 @@
 #if !defined(__LINKAGE_H__)
 #define __LINKAGE_H__
 
+/*
+ * FIXME: This is declared here to save creating a new header which should be
+ * removed soon anyway as bridge gen should be providing this interface.
+ */
+PVRSRV_ERROR DeviceDepBridgeInit(IMG_UINT64 ui64Features);
+PVRSRV_ERROR DeviceDepBridgeDeInit(IMG_UINT64 ui64Features);
 PVRSRV_ERROR LinuxBridgeInit(void);
 PVRSRV_ERROR LinuxBridgeDeInit(void);
 
-#if !defined(SUPPORT_DRM)
-long PVRSRV_BridgeDispatchKM(struct file *file, unsigned int cmd, unsigned long arg);
-
-#if defined(CONFIG_COMPAT)
-long PVRSRV_BridgeCompatDispatchKM(struct file *file, unsigned int cmd, unsigned long arg);
-#endif
-#endif
-
-int PVRSRV_MMap(struct file *file, struct vm_area_struct *ps_vma);
-
 PVRSRV_ERROR PVROSFuncInit(void);
 void PVROSFuncDeInit(void);
 
diff --git a/drivers/staging/imgtec/rogue/linuxsrv.h b/drivers/staging/imgtec/rogue/linuxsrv.h
index 11875f9..7023870 100644
--- a/drivers/staging/imgtec/rogue/linuxsrv.h
+++ b/drivers/staging/imgtec/rogue/linuxsrv.h
@@ -45,19 +45,6 @@
 
 #include "dbgdrvif_srv5.h"
 
-typedef struct  tagIOCTL_PACKAGE
-{
-	IMG_UINT32 ui32Cmd;              // ioctl command
-	IMG_UINT32 ui32Size;			   // needs to be correctly set
-	DBG_WIDEPTR	pInBuffer;          // input data buffer
-	IMG_UINT32  ui32InBufferSize;     // size of input data buffer
-	DBG_WIDEPTR    pOutBuffer;         // output data buffer
-	IMG_UINT32  ui32OutBufferSize;    // size of output data buffer
-#if defined(SUPPORT_DRM)
-	IMG_UINT32 ui32PtrSize;
-#endif
-} IOCTL_PACKAGE;
-
 IMG_UINT32 DeviceIoControl(IMG_UINT32 hDevice,		
 						IMG_UINT32 ui32ControlCode, 
 						void *pInBuffer,
diff --git a/drivers/staging/imgtec/rogue/lists.c b/drivers/staging/imgtec/rogue/lists.c
index e7deb47..e8e7088 100644
--- a/drivers/staging/imgtec/rogue/lists.c
+++ b/drivers/staging/imgtec/rogue/lists.c
@@ -50,86 +50,11 @@
   ===================================================================*/
 
 IMPLEMENT_LIST_ANY(PVRSRV_DEVICE_NODE)
+IMPLEMENT_LIST_ANY_2(PVRSRV_DEVICE_NODE, IMG_BOOL, IMG_FALSE)
 IMPLEMENT_LIST_ANY_2(PVRSRV_DEVICE_NODE, PVRSRV_ERROR, PVRSRV_OK)
 IMPLEMENT_LIST_ANY_VA(PVRSRV_DEVICE_NODE)
 IMPLEMENT_LIST_ANY_VA_2(PVRSRV_DEVICE_NODE, PVRSRV_ERROR, PVRSRV_OK)
 IMPLEMENT_LIST_FOR_EACH(PVRSRV_DEVICE_NODE)
 IMPLEMENT_LIST_FOR_EACH_VA(PVRSRV_DEVICE_NODE)
-IMPLEMENT_LIST_INSERT(PVRSRV_DEVICE_NODE)
+IMPLEMENT_LIST_INSERT_TAIL(PVRSRV_DEVICE_NODE)
 IMPLEMENT_LIST_REMOVE(PVRSRV_DEVICE_NODE)
-
-IMPLEMENT_LIST_ANY_VA(PVRSRV_POWER_DEV)
-IMPLEMENT_LIST_ANY_VA_2(PVRSRV_POWER_DEV, PVRSRV_ERROR, PVRSRV_OK)
-IMPLEMENT_LIST_INSERT(PVRSRV_POWER_DEV)
-IMPLEMENT_LIST_REMOVE(PVRSRV_POWER_DEV)
-
-
-/*===================================================================
-  BELOW ARE IMPLEMENTED SOME COMMON CALLBACKS USED IN DIFFERENT FILES
-  ===================================================================*/
-
-
-/*************************************************************************/ /*!
-@Function       MatchDeviceKM_AnyVaCb
-@Description    Matchs a device node with an id and optionally a class.
-@Input          psDeviceNode  Pointer to the device node.
-@Input          va            Variable argument list, with te following values:
-                                ui32DevIndex  Index of de device to match.
-                                bIgnoreClass  Flag indicating if there's
-                                              no need to check the device class.
-                                eDevClass     Device class, ONLY present if
-                                              bIgnoreClass was IMG_FALSE.
-@Return         The pointer to the device node if it matchs, NULL
-                otherwise.
-*/ /**************************************************************************/
-void* MatchDeviceKM_AnyVaCb(PVRSRV_DEVICE_NODE* psDeviceNode, va_list va)
-{
-	IMG_UINT32 ui32DevIndex;
-	IMG_BOOL bIgnoreClass;
-	PVRSRV_DEVICE_CLASS eDevClass;
-
-	ui32DevIndex = va_arg(va, IMG_UINT32);
-	bIgnoreClass = va_arg(va, IMG_BOOL);
-	if (!bIgnoreClass)
-	{
-		eDevClass = va_arg(va, PVRSRV_DEVICE_CLASS);
-	}
-	else
-	{
-		/*this value will never be used, since the short circuit evaluation
-		of the first clause will stop because bIgnoreClass is true, but the
-		compiler complains if it's not initialized.*/
-		eDevClass = PVRSRV_DEVICE_CLASS_FORCE_I32;
-	}
-
-	if ((bIgnoreClass || psDeviceNode->sDevId.eDeviceClass == eDevClass) &&
-		psDeviceNode->sDevId.ui32DeviceIndex == ui32DevIndex)
-	{
-		return psDeviceNode;
-	}
-	return NULL;
-}
-
-/*!
-******************************************************************************
-@Function	MatchPowerDeviceIndex_AnyVaCb
-@Description    Matches a power device with its device index.
-@Input          va               Variable argument list
-                ui32DeviceIndex  Device index
-@Return         The pointer to the device it matched, NULL otherwise.
-******************************************************************************/
-void* MatchPowerDeviceIndex_AnyVaCb(PVRSRV_POWER_DEV *psPowerDev, va_list va)
-{
-	IMG_UINT32 ui32DeviceIndex;
-
-	ui32DeviceIndex = va_arg(va, IMG_UINT32);
-
-	if (psPowerDev->ui32DeviceIndex == ui32DeviceIndex)
-	{
-		return psPowerDev;
-	}
-	else
-	{
-		return NULL;
-	}
-}
diff --git a/drivers/staging/imgtec/rogue/lists.h b/drivers/staging/imgtec/rogue/lists.h
index 93d36cc..e7a900f 100644
--- a/drivers/staging/imgtec/rogue/lists.h
+++ b/drivers/staging/imgtec/rogue/lists.h
@@ -58,20 +58,22 @@
  ppsThis. In order to make a function available for a given type, it is required
  to use the funcion template macro that creates the actual code.
 
- There are 4 main types of functions:
- - INSERT	: given a pointer to the head pointer of the list and a pointer to
- 			  the node, inserts it as the new head.
- - REMOVE	: given a pointer to a node, removes it from its list.
- - FOR EACH	: apply a function over all the elements of a list.
- - ANY		: apply a function over the elements of a list, until one of them
- 			  return a non null value, and then returns it.
+ There are 5 main types of functions:
+ - INSERT	   : given a pointer to the head pointer of the list and a pointer
+                 to the node, inserts it as the new head.
+ - INSERT TAIL : given a pointer to the head pointer of the list and a pointer
+                 to the node, inserts the node at the tail of the list.
+ - REMOVE	   : given a pointer to a node, removes it from its list.
+ - FOR EACH	   : apply a function over all the elements of a list.
+ - ANY		   : apply a function over the elements of a list, until one of them
+                 return a non null value, and then returns it.
 
  The two last functions can have a variable argument form, with allows to pass
  additional parameters to the callback function. In order to do this, the
  callback function must take two arguments, the first is the current node and
  the second is a list of variable arguments (va_list).
 
- The ANY functions have also another for wich specifies the return type of the
+ The ANY functions have also another for which specifies the return type of the
  callback function and the default value returned by the callback function.
 
 */
@@ -270,6 +272,30 @@
 }
 
 /*************************************************************************/ /*!
+@Function       List_##TYPE##_InsertTail
+@Description    Inserts a given node at the end of the list.
+@Input          psHead   The pointer to the pointer to the head node.
+@Input          psNode   The pointer to the node to be inserted.
+*/ /**************************************************************************/
+#define DECLARE_LIST_INSERT_TAIL(TYPE) \
+void List_##TYPE##_InsertTail(TYPE **ppsHead, TYPE *psNewNode)
+
+#define IMPLEMENT_LIST_INSERT_TAIL(TYPE) \
+void List_##TYPE##_InsertTail(TYPE **ppsHead, TYPE *psNewNode)\
+{\
+	TYPE *psTempNode = *ppsHead;\
+	if (psTempNode != NULL)\
+	{\
+		while (psTempNode->psNext)\
+			psTempNode = psTempNode->psNext;\
+		ppsHead = &psTempNode->psNext;\
+	}\
+	psNewNode->ppsThis = ppsHead;\
+	psNewNode->psNext = NULL;\
+	*ppsHead = psNewNode;\
+}
+
+/*************************************************************************/ /*!
 @Function       List_##TYPE##_Reverse
 @Description    Reverse a list in place
 @Input          ppsHead    The pointer to the pointer to the head node.
@@ -306,19 +332,15 @@
 
 
 DECLARE_LIST_ANY(PVRSRV_DEVICE_NODE);
+DECLARE_LIST_ANY_2(PVRSRV_DEVICE_NODE, IMG_BOOL, IMG_FALSE);
 DECLARE_LIST_ANY_2(PVRSRV_DEVICE_NODE, PVRSRV_ERROR, PVRSRV_OK);
 DECLARE_LIST_ANY_VA(PVRSRV_DEVICE_NODE);
 DECLARE_LIST_ANY_VA_2(PVRSRV_DEVICE_NODE, PVRSRV_ERROR, PVRSRV_OK);
 DECLARE_LIST_FOR_EACH(PVRSRV_DEVICE_NODE);
 DECLARE_LIST_FOR_EACH_VA(PVRSRV_DEVICE_NODE);
-DECLARE_LIST_INSERT(PVRSRV_DEVICE_NODE);
+DECLARE_LIST_INSERT_TAIL(PVRSRV_DEVICE_NODE);
 DECLARE_LIST_REMOVE(PVRSRV_DEVICE_NODE);
 
-DECLARE_LIST_ANY_VA(PVRSRV_POWER_DEV);
-DECLARE_LIST_ANY_VA_2(PVRSRV_POWER_DEV, PVRSRV_ERROR, PVRSRV_OK);
-DECLARE_LIST_INSERT(PVRSRV_POWER_DEV);
-DECLARE_LIST_REMOVE(PVRSRV_POWER_DEV);
-
 #undef DECLARE_LIST_ANY_2
 #undef DECLARE_LIST_ANY_VA
 #undef DECLARE_LIST_ANY_VA_2
@@ -327,9 +349,6 @@
 #undef DECLARE_LIST_INSERT
 #undef DECLARE_LIST_REMOVE
 
-void* MatchDeviceKM_AnyVaCb(PVRSRV_DEVICE_NODE* psDeviceNode, va_list va);
-void* MatchPowerDeviceIndex_AnyVaCb(PVRSRV_POWER_DEV *psPowerDev, va_list va);
-
 #endif
 
 /* re-enable warnings */
diff --git a/drivers/staging/imgtec/rogue/lock.h b/drivers/staging/imgtec/rogue/lock.h
index fb01469..74a4136 100644
--- a/drivers/staging/imgtec/rogue/lock.h
+++ b/drivers/staging/imgtec/rogue/lock.h
@@ -71,23 +71,23 @@
 #define OSLockAcquireNested(hLock, subclass) ({mutex_lock_nested((hLock), (subclass)); PVRSRV_OK;})
 #define OSLockRelease(hLock) ({mutex_unlock((hLock)); PVRSRV_OK;})
 
-#define OSLockIsLocked(hLock) ({IMG_BOOL b = ((mutex_is_locked((hLock)) == 1) ? IMG_TRUE : IMG_FALSE); b;})
-#define OSTryLockAcquire(hLock) ({IMG_BOOL b = ((mutex_trylock(hLock) == 1) ? IMG_TRUE : IMG_FALSE); b;})
+#define OSLockIsLocked(hLock) ((mutex_is_locked((hLock)) == 1) ? IMG_TRUE : IMG_FALSE)
+#define OSTryLockAcquire(hLock) ((mutex_trylock(hLock) == 1) ? IMG_TRUE : IMG_FALSE)
 
 /* These _may_ be reordered or optimized away entirely by the compiler/hw */
-#define OSAtomicRead(pCounter)	({IMG_INT rv = atomic_read(pCounter); rv;})
-#define OSAtomicWrite(pCounter, i)	({ atomic_set(pCounter, i); })
+#define OSAtomicRead(pCounter)	atomic_read(pCounter)
+#define OSAtomicWrite(pCounter, i)	atomic_set(pCounter, i)
 
 /* The following atomic operations, in addition to being SMP-safe, also
    imply a memory barrier around the operation  */
-#define OSAtomicIncrement(pCounter)	({IMG_INT rv = atomic_inc_return(pCounter); rv;})
-#define OSAtomicDecrement(pCounter) ({IMG_INT rv = atomic_dec_return(pCounter); rv;})
-#define OSAtomicCompareExchange(pCounter, oldv, newv) ({IMG_INT rv = atomic_cmpxchg(pCounter,oldv,newv); rv;})
+#define OSAtomicIncrement(pCounter) atomic_inc_return(pCounter)
+#define OSAtomicDecrement(pCounter) atomic_dec_return(pCounter)
+#define OSAtomicCompareExchange(pCounter, oldv, newv) atomic_cmpxchg(pCounter,oldv,newv)
 
-#define OSAtomicAdd(pCounter, incr) ({IMG_INT rv = atomic_add_return(incr,pCounter); rv;})
-#define OSAtomicAddUnless(pCounter, incr, test) ({IMG_INT rv = __atomic_add_unless(pCounter,incr,test); rv;})
+#define OSAtomicAdd(pCounter, incr) atomic_add_return(incr,pCounter)
+#define OSAtomicAddUnless(pCounter, incr, test) __atomic_add_unless(pCounter,incr,test)
 
-#define OSAtomicSubtract(pCounter, incr) ({IMG_INT rv = atomic_add_return(-(incr),pCounter); rv;})
+#define OSAtomicSubtract(pCounter, incr) atomic_add_return(-(incr),pCounter)
 #define OSAtomicSubtractUnless(pCounter, incr, test) OSAtomicAddUnless(pCounter, -(incr), test)
 
 #else /* defined(LINUX) && defined(__KERNEL__) */
@@ -95,35 +95,96 @@
 #include "img_types.h"
 #include "pvrsrv_error.h"
 
+/**************************************************************************/ /*!
+@Function       OSLockCreate
+@Description    Creates an operating system lock object.
+@Output         phLock           The created lock.
+@Input          eLockType        The type of lock required. This may be:
+                                 LOCK_TYPE_PASSIVE - the lock will not be used
+                                 in interrupt context or
+                                 LOCK_TYPE_DISPATCH - the lock may be used
+                                 in interrupt context.
+@Return         PVRSRV_OK on success. PVRSRV_ERROR_OUT_OF_MEMORY if the driver
+                cannot allocate CPU memory needed for the lock.
+                PVRSRV_ERROR_INIT_FAILURE if the Operating System fails to
+                allocate the lock.
+ */ /**************************************************************************/
 IMG_INTERNAL
 PVRSRV_ERROR OSLockCreate(POS_LOCK *phLock, LOCK_TYPE eLockType);
+#if defined(INTEGRITY_OS)
+#define OSLockCreateNoStats OSLockCreate
+#endif
 
+/**************************************************************************/ /*!
+@Function       OSLockDestroy
+@Description    Destroys an operating system lock object.
+@Input          hLock            The lock to be destroyed.
+@Return         None.
+ */ /**************************************************************************/
 IMG_INTERNAL
-void OSLockDestroy(POS_LOCK hLock);
+PVRSRV_ERROR OSLockDestroy(POS_LOCK hLock);
 
+#if defined(INTEGRITY_OS)
+#define OSLockDestroyNoStats OSLockDestroy
+#endif
+/**************************************************************************/ /*!
+@Function       OSLockAcquire
+@Description    Acquires an operating system lock.
+                NB. This function must not return until the lock is acquired
+                (meaning the implementation should not timeout or return with
+                an error, as the caller will assume they have the lock).
+@Input          hLock            The lock to be acquired.
+@Return         None.
+ */ /**************************************************************************/
 IMG_INTERNAL
 void OSLockAcquire(POS_LOCK hLock);
 
 /* Nested notation isn't used in UM or other OS's */
+/**************************************************************************/ /*!
+@Function       OSLockAcquireNested
+@Description    For operating systems other than Linux, this equates to an
+                OSLockAcquire() call. On Linux, this function wraps a call
+                to mutex_lock_nested(). This recognises the scenario where
+                there may be multiple subclasses within a particular class
+                of lock. In such cases, the order in which the locks belonging
+                these various subclasses are acquired is important and must be
+                validated.
+@Input          hLock            The lock to be acquired.
+@Input          subclass         The subclass of the lock.
+@Return         None.
+ */ /**************************************************************************/
 #define OSLockAcquireNested(hLock, subclass) OSLockAcquire((hLock))
 
+/**************************************************************************/ /*!
+@Function       OSLockRelease
+@Description    Releases an operating system lock.
+@Input          hLock            The lock to be released.
+@Return         None.
+ */ /**************************************************************************/
 IMG_INTERNAL
 void OSLockRelease(POS_LOCK hLock);
 
+/**************************************************************************/ /*!
+@Function       OSLockIsLocked
+@Description    Tests whether or not an operating system lock is currently
+                locked.
+@Input          hLock            The lock to be tested.
+@Return         IMG_TRUE if locked, IMG_FALSE if not locked.
+ */ /**************************************************************************/
 IMG_INTERNAL
 IMG_BOOL OSLockIsLocked(POS_LOCK hLock);
 
 #if defined(LINUX)
 
 /* Use GCC intrinsics (read/write semantics consistent with kernel-side implementation) */
-#define OSAtomicRead(pCounter) ({IMG_INT rv =  *(volatile int *)&(pCounter)->counter; rv;}) 
-#define OSAtomicWrite(pCounter, i) ({(pCounter)->counter = (IMG_INT) i;}) 
-#define OSAtomicIncrement(pCounter) ({IMG_INT rv = __sync_add_and_fetch((&(pCounter)->counter), 1); rv;}) 
-#define OSAtomicDecrement(pCounter) ({IMG_INT rv = __sync_sub_and_fetch((&(pCounter)->counter), 1); rv;}) 
-#define OSAtomicCompareExchange(pCounter, oldv, newv)  \
-	({IMG_INT rv = __sync_val_compare_and_swap((&(pCounter)->counter), oldv, newv); rv;})
-	
-#define OSAtomicAdd(pCounter, incr) ({IMG_INT rv = __sync_add_and_fetch((&(pCounter)->counter), incr); rv;}) 
+#define OSAtomicRead(pCounter) (*(volatile int *)&(pCounter)->counter)
+#define OSAtomicWrite(pCounter, i) ((pCounter)->counter = (IMG_INT) i)
+#define OSAtomicIncrement(pCounter) __sync_add_and_fetch((&(pCounter)->counter), 1)
+#define OSAtomicDecrement(pCounter) __sync_sub_and_fetch((&(pCounter)->counter), 1)
+#define OSAtomicCompareExchange(pCounter, oldv, newv) \
+	__sync_val_compare_and_swap((&(pCounter)->counter), oldv, newv)
+
+#define OSAtomicAdd(pCounter, incr) __sync_add_and_fetch((&(pCounter)->counter), incr)
 #define OSAtomicAddUnless(pCounter, incr, test) ({ \
 	int c; int old; \
 	c = OSAtomicRead(pCounter); \
@@ -134,38 +195,136 @@
 		c = old; \
 	} c; })
 
-#define OSAtomicSubtract(pCounter, incr) OSAtomicAdd(pCounter, -(incr))	
+#define OSAtomicSubtract(pCounter, incr) OSAtomicAdd(pCounter, -(incr))
 #define OSAtomicSubtractUnless(pCounter, incr, test) OSAtomicAddUnless(pCounter, -(incr), test)
 
 #else
 
 /* These _may_ be reordered or optimized away entirely by the compiler/hw */
+/*************************************************************************/ /*!
+@Function       OSAtomicRead
+@Description    Read the value of a variable atomically.
+                Atomic functions must be implemented in a manner that
+                is both symmetric multiprocessor (SMP) safe and has a memory
+                barrier around each operation.
+@Input          pCounter        The atomic variable to read
+@Return         The value of the atomic variable
+*/ /**************************************************************************/
 IMG_INTERNAL
 IMG_INT OSAtomicRead(ATOMIC_T *pCounter);
 
+/*************************************************************************/ /*!
+@Function       OSAtomicWrite
+@Description    Write the value of a variable atomically.
+                Atomic functions must be implemented in a manner that
+                is both symmetric multiprocessor (SMP) safe and has a memory
+                barrier around each operation.
+@Input          pCounter        The atomic variable to be written to
+@Input          v               The value to write
+@Return         None
+*/ /**************************************************************************/
 IMG_INTERNAL
 void OSAtomicWrite(ATOMIC_T *pCounter, IMG_INT v);
 
 /* For the following atomic operations, in addition to being SMP-safe, 
    should also  have a memory barrier around each operation  */
+/*************************************************************************/ /*!
+@Function       OSAtomicIncrement
+@Description    Increment the value of a variable atomically.
+                Atomic functions must be implemented in a manner that
+                is both symmetric multiprocessor (SMP) safe and has a memory
+                barrier around each operation.
+@Input          pCounter        The atomic variable to be incremented
+@Return         The new value of *pCounter.
+*/ /**************************************************************************/
 IMG_INTERNAL
 IMG_INT OSAtomicIncrement(ATOMIC_T *pCounter);
 
+/*************************************************************************/ /*!
+@Function       OSAtomicDecrement
+@Description    Decrement the value of a variable atomically.
+                Atomic functions must be implemented in a manner that
+                is both symmetric multiprocessor (SMP) safe and has a memory
+                barrier around each operation.
+@Input          pCounter        The atomic variable to be decremented
+@Return         The new value of *pCounter.
+*/ /**************************************************************************/
 IMG_INTERNAL
 IMG_INT OSAtomicDecrement(ATOMIC_T *pCounter);
 
+/*************************************************************************/ /*!
+@Function       OSAtomicAdd
+@Description    Add a specified value to a variable atomically.
+                Atomic functions must be implemented in a manner that
+                is both symmetric multiprocessor (SMP) safe and has a memory
+                barrier around each operation.
+@Input          pCounter        The atomic variable to add the value to
+@Input          v               The value to be added
+@Return         The new value of *pCounter.
+*/ /**************************************************************************/
 IMG_INTERNAL
 IMG_INT OSAtomicAdd(ATOMIC_T *pCounter, IMG_INT v);
 
+/*************************************************************************/ /*!
+@Function       OSAtomicAddUnless
+@Description    Add a specified value to a variable atomically unless it
+                already equals a particular value.
+                Atomic functions must be implemented in a manner that
+                is both symmetric multiprocessor (SMP) safe and has a memory
+                barrier around each operation.
+@Input          pCounter        The atomic variable to add the value to
+@Input          v               The value to be added to 'pCounter'
+@Input          t               The test value. If 'pCounter' equals this,
+                                its value will not be adjusted
+@Return         The new value of *pCounter.
+*/ /**************************************************************************/
 IMG_INTERNAL
 IMG_INT OSAtomicAddUnless(ATOMIC_T *pCounter, IMG_INT v, IMG_INT t);
 
+/*************************************************************************/ /*!
+@Function       OSAtomicSubtract
+@Description    Subtract a specified value to a variable atomically.
+                Atomic functions must be implemented in a manner that
+                is both symmetric multiprocessor (SMP) safe and has a memory
+                barrier around each operation.
+@Input          pCounter        The atomic variable to subtract the value from
+@Input          v               The value to be subtracted
+@Return         The new value of *pCounter.
+*/ /**************************************************************************/
 IMG_INTERNAL
 IMG_INT OSAtomicSubtract(ATOMIC_T *pCounter, IMG_INT v);
 
+/*************************************************************************/ /*!
+@Function       OSAtomicSubtractUnless
+@Description    Subtract a specified value from a variable atomically unless
+                it already equals a particular value.
+                Atomic functions must be implemented in a manner that
+                is both symmetric multiprocessor (SMP) safe and has a memory
+                barrier around each operation.
+@Input          pCounter        The atomic variable to subtract the value from
+@Input          v               The value to be subtracted from 'pCounter'
+@Input          t               The test value. If 'pCounter' equals this,
+                                its value will not be adjusted
+@Return         The new value of *pCounter.
+*/ /**************************************************************************/
 IMG_INTERNAL
 IMG_INT OSAtomicSubtractUnless(ATOMIC_T *pCounter, IMG_INT v, IMG_INT t);
 
+/*************************************************************************/ /*!
+@Function       OSAtomicCompareExchange
+@Description    Set a variable to a given value only if it is currently
+                equal to a specified value. The whole operation must be atomic.
+                Atomic functions must be implemented in a manner that
+                is both symmetric multiprocessor (SMP) safe and has a memory
+                barrier around each operation.
+@Input          pCounter        The atomic variable to be checked and
+                                possibly updated
+@Input          oldv            The value the atomic variable must have in
+                                order to be modified
+@Input          newv            The value to write to the atomic variable if
+                                it equals 'oldv'
+@Return         The value of *pCounter after the function.
+*/ /**************************************************************************/
 IMG_INTERNAL
 IMG_INT OSAtomicCompareExchange(ATOMIC_T *pCounter, IMG_INT oldv, IMG_INT newv);
 
diff --git a/drivers/staging/imgtec/rogue/lock_types.h b/drivers/staging/imgtec/rogue/lock_types.h
index d1947bd..1162737 100644
--- a/drivers/staging/imgtec/rogue/lock_types.h
+++ b/drivers/staging/imgtec/rogue/lock_types.h
@@ -69,6 +69,9 @@
 	 * still have to be shared. This is one such case.
 	 */
 	typedef struct _OS_ATOMIC {IMG_INT counter;} ATOMIC_T;
+#elif defined(INTEGRITY_OS)
+	/*Fixed size data type to hold the largest value*/
+	typedef struct _OS_ATOMIC {IMG_UINT64 counter;} ATOMIC_T;
 #else
 	#error "Please type-define an atomic lock for this environment"
 #endif
diff --git a/drivers/staging/imgtec/rogue/log2.h b/drivers/staging/imgtec/rogue/log2.h
index 1b46a41..fd575bc 100644
--- a/drivers/staging/imgtec/rogue/log2.h
+++ b/drivers/staging/imgtec/rogue/log2.h
@@ -192,10 +192,10 @@
 		{ 0xAAAAAAAA, 0xCCCCCCCC, 0xF0F0F0F0, 0xFF00FF00, 0xFFFF0000};
 	uint32_t r = (n & b[0]) != 0;
 
-	r |= ((n & b[4]) != 0) << 4;
-	r |= ((n & b[3]) != 0) << 3;
-	r |= ((n & b[2]) != 0) << 2;
-	r |= ((n & b[1]) != 0) << 1;
+	r |= (uint32_t) ((n & b[4]) != 0) << 4;
+	r |= (uint32_t) ((n & b[3]) != 0) << 3;
+	r |= (uint32_t) ((n & b[2]) != 0) << 2;
+	r |= (uint32_t) ((n & b[1]) != 0) << 1;
 
 	return r;
 }
@@ -213,11 +213,11 @@
 		  0xFFFF0000FFFF0000ULL, 0xFFFFFFFF00000000ULL };
 	uint32_t r = (n & b[0]) != 0;
 
-	r |= ((n & b[5]) != 0) << 5;
-	r |= ((n & b[4]) != 0) << 4;
-	r |= ((n & b[3]) != 0) << 3;
-	r |= ((n & b[2]) != 0) << 2;
-	r |= ((n & b[1]) != 0) << 1;
+	r |= (uint32_t) ((n & b[5]) != 0) << 5;
+	r |= (uint32_t) ((n & b[4]) != 0) << 4;
+	r |= (uint32_t) ((n & b[3]) != 0) << 3;
+	r |= (uint32_t) ((n & b[2]) != 0) << 2;
+	r |= (uint32_t) ((n & b[1]) != 0) << 1;
 
 	return r;
 }
diff --git a/drivers/staging/imgtec/rogue/main.c b/drivers/staging/imgtec/rogue/main.c
index a9f96ff..9eae72d 100644
--- a/drivers/staging/imgtec/rogue/main.c
+++ b/drivers/staging/imgtec/rogue/main.c
@@ -48,21 +48,8 @@
 #include <linux/list.h>
 #include <linux/init.h>
 #include <linux/vmalloc.h>
-#include <linux/version.h>
-
-#if defined(LDM_PLATFORM) && !defined(SUPPORT_DRM)
-#include <linux/platform_device.h>
-#endif
-
-#if defined(LDM_PCI) && !defined(SUPPORT_DRM)
-#include <linux/pci.h>
-#endif
-
 #include <asm/uaccess.h>
-
-#if defined(SUPPORT_DRM)
 #include <drm/drmP.h>
-#endif
 
 #include "img_types.h"
 #include "linuxsrv.h"
@@ -73,50 +60,8 @@
 #include "pvr_debug.h"
 #include "pvrmodule.h"
 #include "pvr_uaccess.h"
-
-#if defined(SUPPORT_DRM)
-
-#include "pvr_drm_shared.h"
 #include "pvr_drm.h"
-
-#else /* defined(SUPPORT_DRM) */
-
-#define DRVNAME "dbgdrv"
-MODULE_SUPPORTED_DEVICE(DRVNAME);
-
-static struct class *psDbgDrvClass;
-
-static int AssignedMajorNumber = 0;
-
-long dbgdrv_ioctl(struct file *, unsigned int, unsigned long);
-long dbgdrv_ioctl_compat(struct file *, unsigned int, unsigned long);
-
-static int dbgdrv_open(struct inode unref__ * pInode, struct file unref__ * pFile)
-{
-	return 0;
-}
-
-static int dbgdrv_release(struct inode unref__ * pInode, struct file unref__ * pFile)
-{
-	return 0;
-}
-
-static int dbgdrv_mmap(struct file* pFile, struct vm_area_struct* ps_vma)
-{
-	return 0;
-}
-
-static struct file_operations dbgdrv_fops =
-{
-	.owner          = THIS_MODULE,
-	.unlocked_ioctl = dbgdrv_ioctl,
-	.compat_ioctl   = dbgdrv_ioctl_compat,
-	.open           = dbgdrv_open,
-	.release        = dbgdrv_release,
-	.mmap           = dbgdrv_mmap,
-};
-
-#endif  /* defined(SUPPORT_DRM) */
+#include "pvr_drv.h"
 
 /* Outward temp buffer used by IOCTL handler allocated once and grows as needed.
  * This optimisation means the debug driver performs less vmallocs/vfrees
@@ -138,11 +83,7 @@
 	*fn_table = &g_sDBGKMServices;
 }
 
-#if defined(SUPPORT_DRM)
 void dbgdrv_cleanup(void)
-#else
-void cleanup_module(void)
-#endif
 {
 	if (g_outTmpBuf)
 	{
@@ -150,11 +91,6 @@
 		g_outTmpBuf = NULL;
 	}
 
-#if !defined(SUPPORT_DRM)
-	device_destroy(psDbgDrvClass, MKDEV(AssignedMajorNumber, 0));
-	class_destroy(psDbgDrvClass);
-	unregister_chrdev(AssignedMajorNumber, DRVNAME);
-#endif /* !defined(SUPPORT_DRM) */
 #if defined(SUPPORT_DBGDRV_EVENT_OBJECTS)
 	HostDestroyEventObjects();
 #endif
@@ -163,20 +99,8 @@
 	return;
 }
 
-#if defined(SUPPORT_DRM)
 IMG_INT dbgdrv_init(void)
-#else
-int init_module(void)
-#endif
 {
-#if !defined(SUPPORT_DRM)
-	struct device *psDev;
-#endif
-
-#if !defined(SUPPORT_DRM)
-	int err = -EBUSY;
-#endif
-
 	/* Init API mutex */
 	if ((g_pvAPIMutex=HostCreateMutex()) == NULL)
 	{
@@ -197,60 +121,24 @@
 	(void) HostCreateEventObjects();
 #endif
 
-#if !defined(SUPPORT_DRM)
-	AssignedMajorNumber =
-		register_chrdev(AssignedMajorNumber, DRVNAME, &dbgdrv_fops);
-
-	if (AssignedMajorNumber <= 0)
-	{
-		PVR_DPF((PVR_DBG_ERROR," unable to get major\n"));
-		goto ErrDestroyEventObjects;
-	}
-
-	/*
-	 * This code (using GPL symbols) facilitates automatic device
-	 * node creation on platforms with udev (or similar).
-	 */
-	psDbgDrvClass = class_create(THIS_MODULE, DRVNAME);
-	if (IS_ERR(psDbgDrvClass))
-	{
-		PVR_DPF((PVR_DBG_ERROR, "%s: unable to create class (%ld)",
-				 __func__, PTR_ERR(psDbgDrvClass)));
-		goto ErrUnregisterCharDev;
-	}
-
-	psDev = device_create(psDbgDrvClass, NULL, MKDEV(AssignedMajorNumber, 0), NULL, DRVNAME);
-	if (IS_ERR(psDev))
-	{
-		PVR_DPF((PVR_DBG_ERROR, "%s: unable to create device (%ld)",
-								__func__, PTR_ERR(psDev)));
-		goto ErrDestroyClass;
-	}
-#endif /* !defined(SUPPORT_DRM) */
-
 	return 0;
-
-#if !defined(SUPPORT_DRM)
-ErrDestroyEventObjects:
-#if defined(SUPPORT_DBGDRV_EVENT_OBJECTS)
-	HostDestroyEventObjects();
-#endif
-ErrUnregisterCharDev:
-	unregister_chrdev(AssignedMajorNumber, DRVNAME);
-ErrDestroyClass:
-	class_destroy(psDbgDrvClass);
-	return err;
-#endif /* !defined(SUPPORT_DRM) */
 }
 
 static IMG_INT dbgdrv_ioctl_work(void *arg, IMG_BOOL bCompat)
 {
-	IOCTL_PACKAGE *pIP = (IOCTL_PACKAGE *) arg;
+	struct drm_pvr_dbgdrv_cmd *psDbgdrvCmd = (struct drm_pvr_dbgdrv_cmd *) arg;
 	char *buffer, *in, *out;
 	unsigned int cmd;
 	void *pBufferIn, *pBufferOut;
 
-	if ((pIP->ui32InBufferSize > (PAGE_SIZE >> 1) ) || (pIP->ui32OutBufferSize > (PAGE_SIZE >> 1)))
+	if (psDbgdrvCmd->pad)
+	{
+		PVR_DPF((PVR_DBG_ERROR, "Invalid pad value\n"));
+		return -EINVAL;
+	}
+
+	if ((psDbgdrvCmd->in_data_size > (PAGE_SIZE >> 1)) ||
+		(psDbgdrvCmd->out_data_size > (PAGE_SIZE >> 1)))
 	{
 		PVR_DPF((PVR_DBG_ERROR,"Sizes of the buffers are too large, cannot do ioctl\n"));
 		return -1;
@@ -266,18 +154,18 @@
 	in = buffer;
 	out = buffer + (PAGE_SIZE >>1);
 
-	pBufferIn = WIDEPTR_GET_PTR(pIP->pInBuffer, bCompat);
-	pBufferOut = WIDEPTR_GET_PTR(pIP->pOutBuffer, bCompat);
+	pBufferIn = (void *)(uintptr_t) psDbgdrvCmd->in_data_ptr;
+	pBufferOut = (void *)(uintptr_t) psDbgdrvCmd->out_data_ptr;
 
-	if (pvr_copy_from_user(in, pBufferIn, pIP->ui32InBufferSize) != 0)
+	if (pvr_copy_from_user(in, pBufferIn, psDbgdrvCmd->in_data_size) != 0)
 	{
 		goto init_failed;
 	}
 
 	/* Extra -1 because ioctls start at DEBUG_SERVICE_IOCTL_BASE + 1 */
-	cmd = MAKEIOCTLINDEX(pIP->ui32Cmd) - DEBUG_SERVICE_IOCTL_BASE - 1;
+	cmd = MAKEIOCTLINDEX(psDbgdrvCmd->cmd) - DEBUG_SERVICE_IOCTL_BASE - 1;
 
-	if (pIP->ui32Cmd == DEBUG_SERVICE_READ)
+	if (psDbgdrvCmd->cmd == DEBUG_SERVICE_READ)
 	{
 		IMG_UINT32 *pui32BytesCopied = (IMG_UINT32 *)out;
 		DBG_OUT_READ *psReadOutParams = (DBG_OUT_READ *)out;
@@ -337,7 +225,7 @@
 		(g_DBGDrivProc[cmd])(in, out, bCompat);
 	}
 
-	if (copy_to_user(pBufferOut, out, pIP->ui32OutBufferSize) != 0)
+	if (copy_to_user(pBufferOut, out, psDbgdrvCmd->out_data_size) != 0)
 	{
 		goto init_failed;
 	}
@@ -350,20 +238,12 @@
 	return -EFAULT;
 }
 
-#if defined(SUPPORT_DRM)
 int dbgdrv_ioctl(struct drm_device *dev, void *arg, struct drm_file *pFile)
-#else
-long dbgdrv_ioctl(struct file *file, unsigned int ioctlCmd, unsigned long arg)
-#endif
 {
 	return dbgdrv_ioctl_work((void *) arg, IMG_FALSE);
 }
 
-#if defined(SUPPORT_DRM)
-int dbgdrv_ioctl_compat(struct drm_device *dev, void *arg, struct drm_file *pFile)
-#else
-long dbgdrv_ioctl_compat(struct file *file, unsigned int ioctlCmd, unsigned long arg)
-#endif
+int dbgdrv_ioctl_compat(struct file *file, unsigned int ioctlCmd, unsigned long arg)
 {
 	return dbgdrv_ioctl_work((void *) arg, IMG_TRUE);
 }
diff --git a/drivers/staging/imgtec/rogue/mem_utils.c b/drivers/staging/imgtec/rogue/mem_utils.c
index 25cad79..1722695 100644
--- a/drivers/staging/imgtec/rogue/mem_utils.c
+++ b/drivers/staging/imgtec/rogue/mem_utils.c
@@ -41,35 +41,34 @@
 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */ /**************************************************************************/
 
-
-#if defined(__KERNEL__)
-#include "osfunc.h"
-#include <linux/string.h>
-#include <linux/version.h>
-#else
-#include "services.h"
-#include <string.h>
-#endif
-
-#if (defined(__arm64__) || defined(__aarch64__) || defined (PVRSRV_DEVMEM_TEST_SAFE_MEMSETCPY)) && !defined(__QNXNTO__)
-
-/*
- * Make sure that a working kernel is used when compiling for ARM32 because memset() plus
- * some compiler optimisations can lead to undefined behaviour.
+/* This workaround is only *required* on ARM64. Avoid building or including
+ * it by default on other architectures, unless the 'safe memcpy' test flag
+ * is enabled. (The code should work on other architectures.)
  */
-#if defined(__KERNEL__)
-#if defined(LINUX) && defined(CONFIG_ARM) && (LINUX_VERSION_CODE < KERNEL_VERSION(3,9,0))
-#error "PVRSRVDeviceMemSet() not usable with kernel versions < 3.9, check build config"
-#endif
-#endif
 
-#define ZERO_BUF_SIZE 1024
+#if defined(__arm64__) || defined(__aarch64__) || defined (PVRSRV_DEVMEM_TEST_SAFE_MEMSETCPY)
 
+/* NOTE: This C file is compiled with -ffreestanding to avoid pattern matching
+ *       by the compiler to stdlib functions, and it must only use the below
+ *       headers. Do not include any IMG or services headers in this file.
+ */
+#include <stddef.h>
+
+/* Prototypes to suppress warnings in -ffreestanding mode */
+void DeviceMemCopy(void *pvDst, const void *pvSrc, size_t uSize);
+void DeviceMemSet(void *pvDst, unsigned char ui8Value, size_t uSize);
+
+/* This file is only intended to be used on platforms which use GCC or Clang,
+ * due to its requirement on __attribute__((vector_size(n))), typeof() and
+ * __SIZEOF__ macros.
+ */
 #if defined(__GNUC__)
+
+#define MIN(a, b) \
+ ({__typeof(a) _a = (a); __typeof(b) _b = (b); _a > _b ? _b : _a;})
+
 #if !defined(DEVICE_MEMSETCPY_ALIGN_IN_BYTES)
-/* In case build system doesn't define below constant define it here to
- * avoid build failure. */
-#define DEVICE_MEMSETCPY_ALIGN_IN_BYTES 8 // by default align to 8 bytes
+#define DEVICE_MEMSETCPY_ALIGN_IN_BYTES __SIZEOF_LONG__
 #endif
 #if DEVICE_MEMSETCPY_ALIGN_IN_BYTES % 2 != 0
 #error "DEVICE_MEMSETCPY_ALIGN_IN_BYTES must be a power of 2"
@@ -77,203 +76,238 @@
 #if DEVICE_MEMSETCPY_ALIGN_IN_BYTES < 4
 #error "DEVICE_MEMSETCPY_ALIGN_IN_BYTES must be equal or greater than 4"
 #endif
-#define PVRSRV_MEM_ALIGN __attribute__ ((aligned (DEVICE_MEMSETCPY_ALIGN_IN_BYTES)))
-#define PVRSRV_MEM_XBIT_ALIGN_MASK (DEVICE_MEMSETCPY_ALIGN_IN_BYTES - 1)
-#define PVRSRV_MEM_32BIT_ALIGN_MASK (0x3)
-#else
-#error "PVRSRV Alignment macros need to be defined for this compiler"
+
+#if __SIZEOF_POINTER__ != __SIZEOF_LONG__
+#error No support for architectures where void* and long are sized differently
 #endif
 
-/******************************************************************************
- Function Name      : OSDeviceMemCopy / PVRSRVDeviceMemCopy
- Inputs             : pvDst - pointer to the destination memory region
-                      pvSrc - pointer to the source memory region
-                      uiSize - size of the memory region that will be copied
- Outputs            :
- Returns            :
- Description        : This is a counterpart of standard memcpy function for
-                      uncached memory. The reason for this function is that
-                      when uncached memory is used and the pointers are not
-                      64-bit aligned on Aarch64 architecture a memory
-                      exception will be thrown. This applies both to user and
-                      kernel space.
-******************************************************************************/
-IMG_EXPORT void PVRSRVDeviceMemCopy(
-        void* pvDst,
-        const void* pvSrc,
-        size_t uiSize)
+#if   __SIZEOF_LONG__ >  DEVICE_MEMSETCPY_ALIGN_IN_BYTES
+/* Meaningless, and harder to do correctly */
+# error Cannot handle DEVICE_MEMSETCPY_ALIGN_IN_BYTES < sizeof(long)
+typedef unsigned long block_t;
+#elif __SIZEOF_LONG__ <= DEVICE_MEMSETCPY_ALIGN_IN_BYTES
+typedef unsigned int block_t
+	__attribute__((vector_size(DEVICE_MEMSETCPY_ALIGN_IN_BYTES)));
+# if defined(__arm64__) || defined(__aarch64__)
+#  if   DEVICE_MEMSETCPY_ALIGN_IN_BYTES == 8
+#   define DEVICE_MEMSETCPY_ARM64
+#   define REGSZ "w"
+#   define REGCL "w"
+#   define BVCLB "r"
+#  elif DEVICE_MEMSETCPY_ALIGN_IN_BYTES == 16
+#   define DEVICE_MEMSETCPY_ARM64
+#   define REGSZ "x"
+#   define REGCL "x"
+#   define BVCLB "r"
+#  elif DEVICE_MEMSETCPY_ALIGN_IN_BYTES == 32
+#   if defined(__ARM_NEON_FP)
+#    define DEVICE_MEMSETCPY_ARM64
+#    define REGSZ "q"
+#    define REGCL "v"
+#    define BVCLB "w"
+#   endif
+#  endif
+#  if defined(DEVICE_MEMSETCPY_ARM64)
+#   if defined(DEVICE_MEMSETCPY_ARM64_NON_TEMPORAL)
+#    define NSHLD() __asm__ ("dmb nshld")
+#    define NSHST() __asm__ ("dmb nshst")
+#    define LDP "ldnp"
+#    define STP "stnp"
+#   else
+#    define NSHLD()
+#    define NSHST()
+#    define LDP "ldp"
+#    define STP "stp"
+#   endif
+ typedef unsigned int block_half_t
+	__attribute__((vector_size(DEVICE_MEMSETCPY_ALIGN_IN_BYTES / 2)));
+#  endif
+# endif
+#endif
+
+__attribute__((visibility("hidden")))
+void DeviceMemCopy(void *pvDst, const void *pvSrc, size_t uSize)
 {
-	/* Use volatile to avoid compiler optimisations */
-	volatile IMG_BYTE * pbySrc = (IMG_BYTE*)pvSrc;
-	volatile IMG_BYTE * pbyDst = (IMG_BYTE*)pvDst;
-	size_t uiTailSize = uiSize;
+	volatile const char *pcSrc = pvSrc;
+	volatile char *pcDst = pvDst;
+	size_t uPreambleBytes;
+	int bBlockCopy = 0;
 
-	/* If both pointers have same alignment we can optimise. */
-	if (((uintptr_t)pbySrc & PVRSRV_MEM_XBIT_ALIGN_MASK)
-	        == ((uintptr_t)pbyDst & PVRSRV_MEM_XBIT_ALIGN_MASK))
+	size_t uSrcUnaligned = (size_t)pcSrc % sizeof(block_t);
+	size_t uDstUnaligned = (size_t)pcDst % sizeof(block_t);
+
+	if (!uSrcUnaligned && !uDstUnaligned)
 	{
-		size_t uiAlignedSize;
-		IMG_UINT uiHeadSize;
-
-		uiHeadSize = (sizeof(void *)
-		        - ((uintptr_t)pbySrc & PVRSRV_MEM_XBIT_ALIGN_MASK))
-		        & PVRSRV_MEM_XBIT_ALIGN_MASK;
-
-		/* For 64bit aligned pointers we will almost always (not if uiSize is 0)
-		 * go in and use memcpy if the size is large enough. For other aligned
-		 * pointers if size is large enough we will copy first few bytes to
-		 * align those pointers to 64bit then use memcpy and after that copy
-		 * remaining bytes.
-		 * If uiSize is less then uiHeadSize we will skip to byte-by-byte
-		 * copy since we can't use memcpy in such case. */
-		if (uiSize > uiHeadSize)
-		{
-			uiSize -= uiHeadSize;
-			uiTailSize = uiSize & PVRSRV_MEM_XBIT_ALIGN_MASK;
-			uiAlignedSize = uiSize - uiTailSize;
-
-			/* Copy few leading bytes to align pointer to 64bit boundary. */
-			while (uiHeadSize--)
-			{
-				*pbyDst++ = *pbySrc++;
-			}
-
-			/* here pointers are already 64bit aligned so we can use memcpy. */
-			memcpy((void*)pbyDst, (void*)pbySrc, uiAlignedSize);
-
-			/* skip over copied data */
-			pbyDst += uiAlignedSize;
-			pbySrc += uiAlignedSize;
-		}
+		/* Neither pointer is unaligned. Optimal case. */
+		bBlockCopy = 1;
 	}
-	/* If pointers are 32bit aligned but not aligned in relation to each
-	 * other.*/
-	else if ((((uintptr_t)pbySrc | (uintptr_t)pbyDst)
-	        & PVRSRV_MEM_32BIT_ALIGN_MASK) == 0)
-	{
-		volatile IMG_UINT32 * pui32Src = (IMG_UINT32*)pbySrc;
-		volatile IMG_UINT32 * pui32Dst = (IMG_UINT32*)pbyDst;
-		size_t uiAlignedSize;
-
-		uiTailSize = uiSize & PVRSRV_MEM_32BIT_ALIGN_MASK;
-		uiAlignedSize = uiSize - uiTailSize;
-
-		/* do the 4 byte copy */
-		uiSize = uiSize >> 2;
-		while (uiSize--)
-		{
-			*pui32Dst++ = *pui32Src++;
-		}
-
-		pbyDst += uiAlignedSize;
-		pbySrc += uiAlignedSize;
-	}
-
-	/* Copy either remaining memory if optimisation was performed but
-	 * size was not aligned or all memory if we need to. */
-	while (uiTailSize--)
-	{
-		*pbyDst++ = *pbySrc++;
-	}
-
-}
-
-/******************************************************************************
- Function Name      : OSDeviceMemSet / PVRSRVDeviceMemSet
- Inputs             : pvDest - pointer to destination memory
-                      ui8Value - the 'set' value
-                      uiSize - size of the memory block
- Outputs            :
- Returns            :
- Description        : This is a counterpart of standard memset function for
-                      uncached memory. The reason for this function is that
-                      when uncached memory is used and the pointer is not
-                      64-bit aligned on Aarch64 architecture an memory
-                      exception will be thrown. This applies both to user and
-                      kernel space.
-******************************************************************************/
-IMG_EXPORT void PVRSRVDeviceMemSet(
-        void *pvDest,
-        IMG_UINT8 ui8Value,
-        size_t uiSize)
-{
-	/* Use volatile to avoid compiler optimisations */
-	volatile IMG_BYTE * pbyDst = (IMG_BYTE*)pvDest;
-	static IMG_BYTE gZeroBuf[ZERO_BUF_SIZE] PVRSRV_MEM_ALIGN = { 0 };
-
-	/* Run workaround if one of the address or size is not aligned, or
-	 * we are zeroing */
-	if ((ui8Value == 0) || ((((size_t)pbyDst | uiSize) & PVRSRV_MEM_XBIT_ALIGN_MASK) != 0))
-	{
-		IMG_UINT32 uiTailSize;
-
-		/* Buffer address unaligned */
-		if ((size_t)pbyDst & PVRSRV_MEM_XBIT_ALIGN_MASK)
-		{
-			/* Increment the buffer pointer */
-			for (; uiSize > 0 && ((size_t)pbyDst & PVRSRV_MEM_XBIT_ALIGN_MASK); uiSize--)
-			{
-				*pbyDst++ = ui8Value;
-			}
-			/* Did loop stop because size is zero? */
-			if (uiSize == 0) return;
-		}
-
-		/* Set the remaining part of the buffer */
-		if (ui8Value)
-		{
-			/* Non-zero set */
-			uiTailSize = (uiSize & PVRSRV_MEM_XBIT_ALIGN_MASK);
-
-			memset((void*) pbyDst, (IMG_INT) ui8Value, (size_t) uiSize-uiTailSize);
-			pbyDst += uiSize-uiTailSize;
-		}
-		else
-		{
-			/* Zero set */
-			uiTailSize = (uiSize & PVRSRV_MEM_XBIT_ALIGN_MASK);
-			uiSize -= uiTailSize;
-
-			while (uiSize > 1024)
-			{
-				memcpy((void*) pbyDst, gZeroBuf, (size_t) ZERO_BUF_SIZE);
-				pbyDst +=ZERO_BUF_SIZE;
-				uiSize -= ZERO_BUF_SIZE;
-			}
-			memcpy((void*) pbyDst, gZeroBuf, (size_t) uiSize);
-			pbyDst += uiSize;
-		}
-
-		/* Handle any tail bytes, loop skipped in tail is 0 */
-		for (; uiTailSize > 0; uiTailSize--)
-		{
-			*pbyDst++ = ui8Value;
-		}
-	}
-	/* Alignment fine, non-zero set, no need to work around device memory
-	 * use with ARM64 libc */
 	else
 	{
-		memset(pvDest, (IMG_INT) ui8Value, (size_t) uiSize);
+		if (uSrcUnaligned == uDstUnaligned)
+		{
+			/* Neither pointer is usefully aligned, but they are misaligned in
+			 * the same way, so we can copy a preamble in a slow way, then
+			 * optimize the rest.
+			 */
+			uPreambleBytes = MIN(sizeof(block_t) - uDstUnaligned, uSize);
+			uSize -= uPreambleBytes;
+			while (uPreambleBytes)
+			{
+				*pcDst++ = *pcSrc++;
+				uPreambleBytes--;
+			}
+
+			bBlockCopy = 1;
+		}
+		else if ((uSrcUnaligned | uDstUnaligned) % sizeof(int) == 0)
+		{
+			/* Both pointers are at least 32-bit aligned, and we assume that
+			 * the processor must handle all kinds of 32-bit load-stores.
+			 * NOTE: Could we optimize this with a non-temporal version?
+			 */
+			if (uSize >= sizeof(int))
+			{
+				volatile int *piSrc = (int *)pcSrc;
+				volatile int *piDst = (int *)pcDst;
+
+				while (uSize >= sizeof(int))
+				{
+					*piDst++ = *piSrc++;
+					uSize -= sizeof(int);
+				}
+
+				pcSrc = (char *)piSrc;
+				pcDst = (char *)piDst;
+			}
+		}
+	}
+
+	if (bBlockCopy && uSize >= sizeof(block_t))
+	{
+		volatile block_t *pSrc = (block_t *)pcSrc;
+		volatile block_t *pDst = (block_t *)pcDst;
+
+		NSHLD();
+
+		while (uSize >= sizeof(block_t))
+		{
+#if defined(DEVICE_MEMSETCPY_ARM64)
+			__asm__ (LDP " " REGSZ "0, " REGSZ "1, [%[pSrc]]\n\t"
+			         STP " " REGSZ "0, " REGSZ "1, [%[pDst]]"
+						:
+						: [pSrc] "r" (pSrc), [pDst] "r" (pDst)
+						: "memory", REGCL "0", REGCL "1");
+#else
+			*pDst = *pSrc;
+#endif
+			pDst++;
+			pSrc++;
+			uSize -= sizeof(block_t);
+		}
+
+		NSHST();
+
+		pcSrc = (char *)pSrc;
+		pcDst = (char *)pDst;
+	}
+
+	while (uSize)
+	{
+		*pcDst++ = *pcSrc++;
+		uSize--;
 	}
 }
 
-#else /* (defined(__arm64__) || defined(__aarch64__) || defined (PVRSRV_DEVMEM_TEST_SAFE_MEMSETCPY)) && !defined(__QNXNTO__) */
-
-IMG_EXPORT void PVRSRVDeviceMemCopy(
-        void*       pvDst,
-        const void* pvSrc,
-        size_t      uiSize)
+__attribute__((visibility("hidden")))
+void DeviceMemSet(void *pvDst, unsigned char ui8Value, size_t uSize)
 {
-	memcpy(pvDst, pvSrc, uiSize);
+	volatile char *pcDst = pvDst;
+	size_t uPreambleBytes;
+
+	size_t uDstUnaligned = (size_t)pcDst % sizeof(block_t);
+
+	if (uDstUnaligned)
+	{
+		uPreambleBytes = MIN(sizeof(block_t) - uDstUnaligned, uSize);
+		uSize -= uPreambleBytes;
+		while (uPreambleBytes)
+		{
+			*pcDst++ = ui8Value;
+			uPreambleBytes--;
+		}
+	}
+
+	if (uSize >= sizeof(block_t))
+	{
+		volatile block_t *pDst = (block_t *)pcDst;
+#if defined(DEVICE_MEMSETCPY_ARM64)
+		block_half_t bValue;
+#else
+		block_t bValue;
+# endif
+		size_t i;
+
+		for (i = 0; i < sizeof(bValue) / sizeof(unsigned int); i++)
+			bValue[i] = ui8Value << 24U |
+			            ui8Value << 16U |
+			            ui8Value <<  8U |
+			            ui8Value;
+
+		NSHLD();
+
+		while (uSize >= sizeof(block_t))
+		{
+#if defined(DEVICE_MEMSETCPY_ARM64)
+			__asm__ (STP " %" REGSZ "[bValue], %" REGSZ "[bValue], [%[pDst]]"
+						:
+						: [bValue] BVCLB (bValue), [pDst] "r" (pDst)
+						: "memory");
+#else
+			*pDst = bValue;
+#endif
+			pDst++;
+			uSize -= sizeof(block_t);
+		}
+
+		NSHST();
+
+		pcDst = (char *)pDst;
+	}
+
+	while (uSize)
+	{
+		*pcDst++ = ui8Value;
+		uSize--;
+	}
 }
 
-IMG_EXPORT void PVRSRVDeviceMemSet(
-        void *pvDest,
-        IMG_UINT8 ui8Value,
-        size_t uiSize)
+#else /* !defined(__GNUC__) */
+
+/* Potentially very slow (but safe) fallbacks for non-GNU C compilers */
+
+void DeviceMemCopy(void *pvDst, const void *pvSrc, size_t uSize)
 {
-	memset(pvDest, ui8Value, uiSize);
+	volatile const char *pcSrc = pvSrc;
+	volatile char *pcDst = pvDst;
+
+	while (uSize)
+	{
+		*pcDst++ = *pcSrc++;
+		uSize--;
+	}
 }
 
-#endif /* (defined(__arm64__) || defined(__aarch64__) || defined (PVRSRV_DEVMEM_TEST_SAFE_MEMSETCPY))) && !defined(__QNXNTO__) */
+void DeviceMemSet(void *pvDst, unsigned char ui8Value, size_t uSize)
+{
+	volatile char *pcDst = pvDst;
+
+	while (uSize)
+	{
+		*pcDst++ = ui8Value;
+		uSize--;
+	}
+}
+
+#endif /* !defined(__GNUC__) */
+
+#endif /* defined(__arm64__) || defined(__aarch64__) || defined (PVRSRV_DEVMEM_TEST_SAFE_MEMSETCPY) */
diff --git a/drivers/staging/imgtec/rogue/mm.c b/drivers/staging/imgtec/rogue/mm.c
deleted file mode 100644
index 5721567..0000000
--- a/drivers/staging/imgtec/rogue/mm.c
+++ /dev/null
@@ -1,107 +0,0 @@
-/*************************************************************************/ /*!
-@File
-@Title          Misc memory management utility functions for Linux
-@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
-@License        Dual MIT/GPLv2
-
-The contents of this file are subject to the MIT license as set out below.
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-Alternatively, the contents of this file may be used under the terms of
-the GNU General Public License Version 2 ("GPL") in which case the provisions
-of GPL are applicable instead of those above.
-
-If you wish to allow use of your version of this file only under the terms of
-GPL, and not to allow others to use your version of this file under the terms
-of the MIT license, indicate your decision by deleting the provisions above
-and replace them with the notice and other provisions required by GPL as set
-out in the file called "GPL-COPYING" included in this distribution. If you do
-not delete the provisions above, a recipient may use your version of this file
-under the terms of either the MIT license or GPL.
-
-This License is also included in this distribution in the file called
-"MIT-COPYING".
-
-EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
-PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
-BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
-PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
-COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
-IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
-CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-*/ /**************************************************************************/
-
-#include <asm/io.h>
-
-#include "img_defs.h"
-#include "pvr_debug.h"
-#include "mm.h"
-#include "pvrsrv_memallocflags.h"
-#include "devicemem_server_utils.h"
-
-#include <linux/version.h>
-
-#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,13,0))
- #if defined(CONFIG_ARM)
-  #define ioremap_cache(x,y) ioremap_cached(x,y)
- #endif
-#endif
-
-void *
-_IORemapWrapper(IMG_CPU_PHYADDR BasePAddr,
-               IMG_UINT32 ui32Bytes,
-               IMG_UINT32 ui32MappingFlags,
-               IMG_CHAR *pszFileName,
-               IMG_UINT32 ui32Line)
-{
-	void *pvIORemapCookie;
-	IMG_UINT32 ui32CPUCacheMode = DevmemCPUCacheMode(ui32MappingFlags);
-
-	switch (ui32CPUCacheMode)
-	{
-		case PVRSRV_MEMALLOCFLAG_CPU_UNCACHED:
-				pvIORemapCookie = (void *)ioremap_nocache(BasePAddr.uiAddr, ui32Bytes);
-				break;
-		case PVRSRV_MEMALLOCFLAG_CPU_WRITE_COMBINE:
-#if defined(CONFIG_X86) || defined(CONFIG_ARM) || defined(CONFIG_ARM64)
-				pvIORemapCookie = (void *)ioremap_wc(BasePAddr.uiAddr, ui32Bytes);
-#else
-				pvIORemapCookie = (void *)ioremap_nocache(BasePAddr.uiAddr, ui32Bytes);
-#endif
-				break;
-		case PVRSRV_MEMALLOCFLAG_CPU_CACHED:
-#if defined(CONFIG_X86) || defined(CONFIG_ARM)
-				pvIORemapCookie = (void *)ioremap_cache(BasePAddr.uiAddr, ui32Bytes);
-#else
-				pvIORemapCookie = (void *)ioremap(BasePAddr.uiAddr, ui32Bytes);
-#endif
-				break;
-		default:
-				return NULL;
-				break;
-	}
-
-    PVR_UNREFERENCED_PARAMETER(pszFileName);
-    PVR_UNREFERENCED_PARAMETER(ui32Line);
-
-    return pvIORemapCookie;
-}
-
-
-void
-_IOUnmapWrapper(void *pvIORemapCookie, IMG_CHAR *pszFileName, IMG_UINT32 ui32Line)
-{
-    PVR_UNREFERENCED_PARAMETER(pszFileName);
-    PVR_UNREFERENCED_PARAMETER(ui32Line);
-
-    iounmap(pvIORemapCookie);
-}
diff --git a/drivers/staging/imgtec/rogue/mm.h b/drivers/staging/imgtec/rogue/mm.h
deleted file mode 100644
index e8a4447..0000000
--- a/drivers/staging/imgtec/rogue/mm.h
+++ /dev/null
@@ -1,86 +0,0 @@
-/*************************************************************************/ /*!
-@File
-@Title          Declares various memory management utility functions for Linux.
-@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
-@License        Dual MIT/GPLv2
-
-The contents of this file are subject to the MIT license as set out below.
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-Alternatively, the contents of this file may be used under the terms of
-the GNU General Public License Version 2 ("GPL") in which case the provisions
-of GPL are applicable instead of those above.
-
-If you wish to allow use of your version of this file only under the terms of
-GPL, and not to allow others to use your version of this file under the terms
-of the MIT license, indicate your decision by deleting the provisions above
-and replace them with the notice and other provisions required by GPL as set
-out in the file called "GPL-COPYING" included in this distribution. If you do
-not delete the provisions above, a recipient may use your version of this file
-under the terms of either the MIT license or GPL.
-
-This License is also included in this distribution in the file called
-"MIT-COPYING".
-
-EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
-PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
-BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
-PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
-COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
-IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
-CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-*/ /**************************************************************************/
-#ifndef __IMG_LINUX_MM_H__
-#define __IMG_LINUX_MM_H__
-
-#include <asm/io.h>
-/*!
- *******************************************************************************
- * @brief Reserve physical IO memory and create a CPU virtual mapping for it
- *
- * @param BasePAddr 
- * @param ui32Bytes  
- * @param ui32MappingFlags  
- *
- * @return 
- ******************************************************************************/
-#if defined(DEBUG_LINUX_MEMORY_ALLOCATIONS)
-#define IORemapWrapper(BasePAddr, ui32Bytes, ui32MappingFlags) \
-	_IORemapWrapper(BasePAddr, ui32Bytes, ui32MappingFlags, __FILE__, __LINE__)
-#else
-#define IORemapWrapper(BasePAddr, ui32Bytes, ui32MappingFlags) \
-	_IORemapWrapper(BasePAddr, ui32Bytes, ui32MappingFlags, NULL, 0)
-#endif
-void *_IORemapWrapper(IMG_CPU_PHYADDR BasePAddr,
-					  IMG_UINT32 ui32Bytes,
-					  IMG_UINT32 ui32MappingFlags,
-					  IMG_CHAR *pszFileName,
-					  IMG_UINT32 ui32Line);
-
-/*!
- ******************************************************************************
- * @brief Unmaps an IO memory mapping created using IORemap
- *
- * @param pvIORemapCookie  
- *
- * @return 
- ******************************************************************************/
-#if defined(DEBUG_LINUX_MEMORY_ALLOCATIONS)
-#define IOUnmapWrapper(pvIORemapCookie) \
-	_IOUnmapWrapper(pvIORemapCookie, __FILE__, __LINE__)
-#else
-#define IOUnmapWrapper(pvIORemapCookie) \
-	_IOUnmapWrapper(pvIORemapCookie, NULL, 0)
-#endif
-void _IOUnmapWrapper(void *pvIORemapCookie, IMG_CHAR *pszFileName, IMG_UINT32 ui32Line);
-
-#endif /* __IMG_LINUX_MM_H__ */
diff --git a/drivers/staging/imgtec/rogue/mm_common.h b/drivers/staging/imgtec/rogue/mm_common.h
index 8478434..4de0a19 100644
--- a/drivers/staging/imgtec/rogue/mm_common.h
+++ b/drivers/staging/imgtec/rogue/mm_common.h
@@ -45,6 +45,7 @@
 #define MM_COMMON_H
 
 #define DEVICEMEM_HISTORY_TEXT_BUFSZ 40
+#define DEVICEMEM_HISTORY_ALLOC_INDEX_NONE 0xFFFFFFFF
 
 #endif
 
diff --git a/drivers/staging/imgtec/rogue/mmu_common.c b/drivers/staging/imgtec/rogue/mmu_common.c
index e7bc25a..0fe2f28 100644
--- a/drivers/staging/imgtec/rogue/mmu_common.c
+++ b/drivers/staging/imgtec/rogue/mmu_common.c
@@ -46,6 +46,7 @@
 /* Our own interface */
 #include "mmu_common.h"
 
+#include "rgx_bvnc_defs_km.h"
 /*
 Interfaces to other modules:
 
@@ -76,14 +77,19 @@
 #include "pmr.h"
 /* include/ */
 #include "pvr_debug.h"
+#include "pvr_notifier.h"
 #include "pvrsrv_error.h"
 #include "pvrsrv.h"
 #include "htbuffer.h"
 
+#include "rgxdevice.h"
+
 #if defined(SUPPORT_GPUVIRT_VALIDATION)
 #include "physmem_lma.h"
 #endif
 
+#include "dllist.h"
+
 // #define MMU_OBJECT_REFCOUNT_DEBUGING 1
 #if defined (MMU_OBJECT_REFCOUNT_DEBUGING)
 #define MMU_OBJ_DBG(x)	PVR_DPF(x);
@@ -100,6 +106,56 @@
 	MMU_MOD_UNMAP,
 } MMU_MOD;
 
+
+/*!
+ * Refcounted structure that is shared between the context and
+ * the cleanup thread items.
+ * It is used to keep track of all cleanup items and whether the creating
+ * MMU context has been destroyed and therefore is not allowed to be
+ * accessed anymore.
+ *
+ * The cleanup thread is used to defer the freeing of the page tables
+ * because we have to make sure that the MMU cache has been invalidated.
+ * If we don't take care of this the MMU might partially access cached
+ * and uncached tables which might lead to inconsistencies and in the
+ * worst case to MMU pending faults on random memory.
+ */
+typedef struct _MMU_CTX_CLEANUP_DATA_
+{
+	/*! Refcount to know when this structure can be destroyed */
+	ATOMIC_T iRef;
+	/*! Protect items in this structure, especially the refcount */
+	POS_LOCK hCleanupLock;
+	/*! List of all cleanup items currently in flight */
+	DLLIST_NODE sMMUCtxCleanupItemsHead;
+	/*! Was the MMU context destroyed and should not be accessed anymore? */
+	IMG_BOOL bMMUContextExists;
+} MMU_CTX_CLEANUP_DATA;
+
+
+/*!
+ * Structure holding one or more page tables that need to be
+ * freed after the MMU cache has been flushed which is signalled when
+ * the stored sync has a value that is <= the required value.
+ */
+typedef struct _MMU_CLEANUP_ITEM_
+{
+	/*! Cleanup thread data */
+	PVRSRV_CLEANUP_THREAD_WORK sCleanupThreadFn;
+	/*! List to hold all the MMU_MEMORY_MAPPINGs, i.e. page tables */
+	DLLIST_NODE sMMUMappingHead;
+	/*! Node of the cleanup item list for the context */
+	DLLIST_NODE sMMUCtxCleanupItem;
+	/* Pointer to the cleanup meta data */
+	MMU_CTX_CLEANUP_DATA *psMMUCtxCleanupData;
+	/* Sync to query if the MMU cache was flushed */
+	PVRSRV_CLIENT_SYNC_PRIM *psSync;
+	/*! The update value of the sync to signal that the cache was flushed */
+	IMG_UINT32 uiRequiredSyncVal;
+	/*! The device node needed to free the page tables */
+	PVRSRV_DEVICE_NODE *psDevNode;
+} MMU_CLEANUP_ITEM;
+
 /*!
 	All physical allocations and frees are relative to this context, so
 	we would get all the allocations of PCs, PDs, and PTs from the same
@@ -123,6 +179,11 @@
 	/*! Size of arena name string */
 	size_t uiPhysMemRANameAllocSize;
 
+	/*! Meta data for deferred cleanup */
+	MMU_CTX_CLEANUP_DATA *psCleanupData;
+	/*! Temporary list of all deferred MMU_MEMORY_MAPPINGs. */
+	DLLIST_NODE sTmpMMUMappingHead;
+
 } MMU_PHYSMEM_CONTEXT;
 
 /*!
@@ -139,13 +200,15 @@
 	/*! Device physical address of this allocation */
 	IMG_DEV_PHYADDR			sDevPAddr;
 	/*! Size of this allocation */
-	size_t				uiSize;
+	size_t					uiSize;
 	/*! Number of current mappings of this allocation */
 	IMG_UINT32				uiCpuVAddrRefCount;
+	/*! Node for the defer free list */
+	DLLIST_NODE				sMMUMappingItem;
 } MMU_MEMORY_MAPPING;
 
 /*!
-	Memory descriptor for MMU objects. There can be more then one memory
+	Memory descriptor for MMU objects. There can be more than one memory
 	descriptor per MMU memory allocation.
 */
 typedef struct _MMU_MEMORY_DESC_
@@ -216,6 +279,7 @@
 #if defined(SUPPORT_GPUVIRT_VALIDATION)
     IMG_UINT32  ui32OSid;
 	IMG_UINT32	ui32OSidReg;
+    IMG_BOOL   bOSidAxiProt;
 #endif
 
 	/*! Lock to ensure exclusive access when manipulating the MMU context or
@@ -228,7 +292,6 @@
 	/* NO OTHER MEMBERS AFTER THIS STRUCTURE ! */
 };
 
-
 static const IMG_DEV_PHYADDR gsBadDevPhyAddr = {MMU_BAD_PHYS_ADDR};
 
 #if defined(DEBUG)
@@ -241,6 +304,228 @@
  *****************************************************************************/
 
 /*************************************************************************/ /*!
+@Function       _FreeMMUMapping
+
+@Description    Free a given dllist of MMU_MEMORY_MAPPINGs and the page tables
+                they represent.
+
+@Input          psDevNode           Device node
+
+@Input          psTmpMMUMappingHead List of MMU_MEMORY_MAPPINGs to free
+*/
+/*****************************************************************************/
+static void
+_FreeMMUMapping(PVRSRV_DEVICE_NODE *psDevNode,
+                PDLLIST_NODE psTmpMMUMappingHead)
+{
+	PDLLIST_NODE psNode, psNextNode;
+
+	/* Free the current list unconditionally */
+	dllist_foreach_node(psTmpMMUMappingHead,
+						psNode,
+						psNextNode)
+	{
+		MMU_MEMORY_MAPPING *psMapping = IMG_CONTAINER_OF(psNode,
+														 MMU_MEMORY_MAPPING,
+														 sMMUMappingItem);
+
+		psDevNode->pfnDevPxFree(psDevNode, &psMapping->sMemHandle);
+		dllist_remove_node(psNode);
+		OSFreeMem(psMapping);
+	}
+}
+
+/*************************************************************************/ /*!
+@Function       _CleanupThread_FreeMMUMapping
+
+@Description    Function to be executed by the cleanup thread to free
+                MMU_MEMORY_MAPPINGs after the MMU cache has been invalidated.
+
+                This function will request a MMU cache invalidate once and
+                retry to free the MMU_MEMORY_MAPPINGs until the invalidate
+                has been executed.
+
+                If the memory context that created this cleanup item has been
+                destroyed in the meantime this function will directly free the
+                MMU_MEMORY_MAPPINGs without waiting for any MMU cache
+                invalidation.
+
+@Input          pvData           Cleanup data in form of a MMU_CLEANUP_ITEM
+
+@Return         PVRSRV_OK if successful otherwise PVRSRV_ERROR_RETRY
+*/
+/*****************************************************************************/
+static PVRSRV_ERROR
+_CleanupThread_FreeMMUMapping(void* pvData)
+{
+	PVRSRV_ERROR eError;
+	MMU_CLEANUP_ITEM *psCleanup = (MMU_CLEANUP_ITEM *) pvData;
+	MMU_CTX_CLEANUP_DATA *psMMUCtxCleanupData = psCleanup->psMMUCtxCleanupData;
+	PVRSRV_DEVICE_NODE *psDevNode = psCleanup->psDevNode;
+	IMG_BOOL bFreeNow;
+	IMG_UINT32 uiSyncCurrent;
+	IMG_UINT32 uiSyncReq;
+
+	OSLockAcquire(psMMUCtxCleanupData->hCleanupLock);
+
+	/* Don't attempt to free anything when the context has been destroyed.
+	 * Especially don't access any device specific structures anymore!*/
+	if (!psMMUCtxCleanupData->bMMUContextExists)
+	{
+		OSFreeMem(psCleanup);
+		eError = PVRSRV_OK;
+		goto e0;
+	}
+
+	if (psCleanup->psSync == NULL)
+	{
+		/* Kick to invalidate the MMU caches and get sync info */
+		psDevNode->pfnMMUCacheInvalidateKick(psDevNode,
+											 &psCleanup->uiRequiredSyncVal,
+											 IMG_TRUE);
+		psCleanup->psSync = psDevNode->psMMUCacheSyncPrim;
+	}
+
+	uiSyncCurrent = *(psCleanup->psSync->pui32LinAddr);
+	uiSyncReq = psCleanup->uiRequiredSyncVal;
+
+	/* Either the invalidate has been executed ... */
+	bFreeNow = (uiSyncCurrent >= uiSyncReq) ? IMG_TRUE :
+			/* ... with the counter wrapped around ... */
+			(uiSyncReq - uiSyncCurrent) > 0xEFFFFFFFUL ? IMG_TRUE :
+			/* ... or are we still waiting for the invalidate? */
+			IMG_FALSE;
+
+#if defined(NO_HARDWARE)
+	/* In NOHW the syncs will never be updated so just free the tables */
+	bFreeNow = IMG_TRUE;
+#endif
+
+	if (bFreeNow)
+	{
+		_FreeMMUMapping(psDevNode, &psCleanup->sMMUMappingHead);
+
+		dllist_remove_node(&psCleanup->sMMUCtxCleanupItem);
+		OSFreeMem(psCleanup);
+
+		eError = PVRSRV_OK;
+	}
+	else
+	{
+		eError = PVRSRV_ERROR_RETRY;
+	}
+
+e0:
+
+	/* If this cleanup task has been successfully executed we can
+	 * decrease the context cleanup data refcount. Successfully
+	 * means here that the MMU_MEMORY_MAPPINGs have been freed by
+	 * either this cleanup task of when the MMU context has been
+	 * destroyed. */
+	if (eError == PVRSRV_OK)
+	{
+		OSLockRelease(psMMUCtxCleanupData->hCleanupLock);
+
+		if (OSAtomicDecrement(&psMMUCtxCleanupData->iRef) == 0)
+		{
+			OSLockDestroy(psMMUCtxCleanupData->hCleanupLock);
+			OSFreeMem(psMMUCtxCleanupData);
+		}
+	}
+	else
+	{
+		OSLockRelease(psMMUCtxCleanupData->hCleanupLock);
+	}
+
+
+	return eError;
+}
+
+/*************************************************************************/ /*!
+@Function       _SetupCleanup_FreeMMUMapping
+
+@Description    Setup a cleanup item for the cleanup thread that will
+                kick off a MMU invalidate request and free the associated
+                MMU_MEMORY_MAPPINGs when the invalidate was successful.
+
+@Input          psDevNode           Device node
+
+@Input          psPhysMemCtx        The current MMU physmem context
+*/
+/*****************************************************************************/
+static void
+_SetupCleanup_FreeMMUMapping(PVRSRV_DEVICE_NODE *psDevNode,
+                             MMU_PHYSMEM_CONTEXT *psPhysMemCtx)
+{
+
+	MMU_CLEANUP_ITEM *psCleanupItem;
+	MMU_CTX_CLEANUP_DATA *psCleanupData = psPhysMemCtx->psCleanupData;
+
+	if (dllist_is_empty(&psPhysMemCtx->sTmpMMUMappingHead))
+	{
+		goto e0;
+	}
+
+#if !defined(SUPPORT_MMU_PENDING_FAULT_PROTECTION)
+	/* If users deactivated this we immediately free the page tables */
+	goto e1;
+#endif
+
+	/* Don't defer the freeing if we are currently unloading the driver
+	 * or if the sync has been destroyed */
+	if (PVRSRVGetPVRSRVData()->bUnload ||
+	    psDevNode->psMMUCacheSyncPrim == NULL)
+	{
+		goto e1;
+	}
+
+	/* Allocate a cleanup item */
+	psCleanupItem = OSAllocMem(sizeof(*psCleanupItem));
+	if(!psCleanupItem)
+	{
+		PVR_DPF((PVR_DBG_ERROR,
+				 "%s: Failed to get memory for deferred page table cleanup. "
+				 "Freeing tables immediately",
+				 __FUNCTION__));
+		goto e1;
+	}
+
+	/* Set sync to NULL to indicate we did not interact with
+	 * the FW yet. Kicking off an MMU cache invalidate should
+	 * be done in the cleanup thread to not waste time here. */
+	psCleanupItem->psSync = NULL;
+	psCleanupItem->uiRequiredSyncVal = 0;
+	psCleanupItem->psDevNode = psDevNode;
+	psCleanupItem->psMMUCtxCleanupData = psCleanupData;
+
+	OSAtomicIncrement(&psCleanupData->iRef);
+
+	/* Move the page tables to free to the cleanup item */
+	dllist_replace_head(&psPhysMemCtx->sTmpMMUMappingHead,
+	                    &psCleanupItem->sMMUMappingHead);
+
+	/* Add the cleanup item itself to the context list */
+	dllist_add_to_tail(&psCleanupData->sMMUCtxCleanupItemsHead,
+	                   &psCleanupItem->sMMUCtxCleanupItem);
+
+	/* Setup the cleanup thread data and add the work item */
+	psCleanupItem->sCleanupThreadFn.pfnFree = _CleanupThread_FreeMMUMapping;
+	psCleanupItem->sCleanupThreadFn.pvData = psCleanupItem;
+	psCleanupItem->sCleanupThreadFn.ui32RetryCount = CLEANUP_THREAD_RETRY_COUNT_DEFAULT;
+	psCleanupItem->sCleanupThreadFn.bDependsOnHW = IMG_TRUE;
+
+	PVRSRVCleanupThreadAddWork(&psCleanupItem->sCleanupThreadFn);
+
+	return;
+
+e1:
+	/* Free the page tables now */
+	_FreeMMUMapping(psDevNode, &psPhysMemCtx->sTmpMMUMappingHead);
+e0:
+	return;
+}
+
+/*************************************************************************/ /*!
 @Function       _CalcPCEIdx
 
 @Description    Calculate the page catalogue index
@@ -313,7 +598,7 @@
     {
         ui32RetVal ++;
     }
-        
+
     return ui32RetVal;
 }
 
@@ -352,7 +637,7 @@
     {
         ui32RetVal ++;
     }
-        
+
     return ui32RetVal;
 }
 
@@ -380,12 +665,13 @@
 @Output         phPriv          Handle which will be passed back when
                                 this import is freed
 
-@Return         IMG_TRUE if import alloc was successful, otherwise IMG_FALSE
+@Return         PVRSRV_OK if import alloc was successful
 */
 /*****************************************************************************/
-static IMG_BOOL _MMU_PhysMem_RAImportAlloc(RA_PERARENA_HANDLE hArenaHandle,
+static PVRSRV_ERROR _MMU_PhysMem_RAImportAlloc(RA_PERARENA_HANDLE hArenaHandle,
                                            RA_LENGTH_T uiSize,
                                            RA_FLAGS_T uiFlags,
+                                           const IMG_CHAR *pszAnnotation,
                                            RA_BASE_T *puiBase,
                                            RA_LENGTH_T *puiActualSize,
                                            RA_PERISPAN_HANDLE *phPriv)
@@ -395,11 +681,13 @@
 	MMU_MEMORY_MAPPING *psMapping;
 	PVRSRV_ERROR eError;
 
+	PVR_UNREFERENCED_PARAMETER(pszAnnotation);
 	PVR_UNREFERENCED_PARAMETER(uiFlags);
 
 	psMapping = OSAllocMem(sizeof(MMU_MEMORY_MAPPING));
 	if (psMapping == NULL)
 	{
+		eError = PVRSRV_ERROR_OUT_OF_MEMORY;
 		goto e0;
 	}
 
@@ -421,12 +709,12 @@
 	*puiBase = (RA_BASE_T)psMapping->sDevPAddr.uiAddr;
 	*puiActualSize = uiSize;
 
-	return IMG_TRUE;
+	return PVRSRV_OK;
 
 e1:
 	OSFreeMem(psMapping);
 e0:
-	return IMG_FALSE;
+	return eError;
 }
 
 /*************************************************************************/ /*!
@@ -451,15 +739,15 @@
 {
 	MMU_MEMORY_MAPPING *psMapping = (MMU_MEMORY_MAPPING *) hPriv;
 	MMU_PHYSMEM_CONTEXT *psCtx = (MMU_PHYSMEM_CONTEXT *) hArenaHandle;
-	PVRSRV_DEVICE_NODE *psDevNode = (PVRSRV_DEVICE_NODE *) psCtx->psDevNode;
 
 	PVR_UNREFERENCED_PARAMETER(uiBase);
 
 	/* Check we have dropped all CPU mappings */
 	PVR_ASSERT(psMapping->uiCpuVAddrRefCount == 0);
 
-	psDevNode->pfnDevPxFree(psDevNode, &psMapping->sMemHandle);
-	OSFreeMem(psMapping);
+	/* Add mapping to defer free list */
+	psMapping->psContext = NULL;
+	dllist_add_to_tail(&psCtx->sTmpMMUMappingHead, &psMapping->sMMUMappingItem);
 }
 
 /*************************************************************************/ /*!
@@ -484,41 +772,40 @@
                                       size_t uiBytes,
                                       size_t uiAlignment)
 {
+	PVRSRV_ERROR eError;
 	RA_BASE_T uiPhysAddr;
-	IMG_BOOL bStatus;
 
 	if (!psMemDesc || psMemDesc->bValid)
 	{
 		return PVRSRV_ERROR_INVALID_PARAMS;
 	}
 
-	bStatus = RA_Alloc(psCtx->psPhysMemRA,
-					   uiBytes,
-					   RA_NO_IMPORT_MULTIPLIER,
-					   0, // flags
-					   uiAlignment,
-					   &uiPhysAddr,
-					   NULL,
-					   (RA_PERISPAN_HANDLE *) &psMemDesc->psMapping);
-	if(!bStatus)
+	eError = RA_Alloc(psCtx->psPhysMemRA,
+	                  uiBytes,
+	                  RA_NO_IMPORT_MULTIPLIER,
+	                  0, // flags
+	                  uiAlignment,
+	                  "",
+	                  &uiPhysAddr,
+	                  NULL,
+	                  (RA_PERISPAN_HANDLE *) &psMemDesc->psMapping);
+	if(PVRSRV_OK != eError)
 	{
 		PVR_DPF((PVR_DBG_ERROR, "_MMU_PhysMemAlloc: ERROR call to RA_Alloc() failed"));
-		return PVRSRV_ERROR_OUT_OF_MEMORY;
+		return eError;
 	}
 
 	psMemDesc->bValid = IMG_TRUE;
 	psMemDesc->pvCpuVAddr = NULL;
-	psMemDesc->sDevPAddr.uiAddr = (uintptr_t) uiPhysAddr;
+	psMemDesc->sDevPAddr.uiAddr = (IMG_UINT64) uiPhysAddr;
 
 	if (psMemDesc->psMapping->uiCpuVAddrRefCount == 0)
 	{
-		PVRSRV_ERROR eError;
-
 		eError = psCtx->psDevNode->pfnDevPxMap(psCtx->psDevNode,
-										&psMemDesc->psMapping->sMemHandle,
-										psMemDesc->psMapping->uiSize,
-										&psMemDesc->psMapping->sDevPAddr,
-										&psMemDesc->psMapping->pvCpuVAddr);
+		                                       &psMemDesc->psMapping->sMemHandle,
+		                                       psMemDesc->psMapping->uiSize,
+		                                       &psMemDesc->psMapping->sDevPAddr,
+		                                       &psMemDesc->psMapping->pvCpuVAddr);
 		if (eError != PVRSRV_OK)
 		{
 			RA_Free(psCtx->psPhysMemRA, psMemDesc->sDevPAddr.uiAddr);
@@ -527,7 +814,8 @@
 	}
 
 	psMemDesc->psMapping->uiCpuVAddrRefCount++;
-	psMemDesc->pvCpuVAddr = (IMG_UINT8 *) psMemDesc->psMapping->pvCpuVAddr + (psMemDesc->sDevPAddr.uiAddr - psMemDesc->psMapping->sDevPAddr.uiAddr);
+	psMemDesc->pvCpuVAddr = (IMG_UINT8 *) psMemDesc->psMapping->pvCpuVAddr
+	                        + (psMemDesc->sDevPAddr.uiAddr - psMemDesc->psMapping->sDevPAddr.uiAddr);
 	psMemDesc->uiOffset = (psMemDesc->sDevPAddr.uiAddr - psMemDesc->psMapping->sDevPAddr.uiAddr);
 	psMemDesc->uiSize = uiBytes;
 	PVR_ASSERT(psMemDesc->pvCpuVAddr != NULL);
@@ -579,23 +867,22 @@
                                            MMU_CONTEXT *psMMUContext)
 {
 	/* Do flag conversion between devmem flags and MMU generic flags */
-
 	if (bInvalidate == IMG_FALSE)
 	{
 		*uiMMUProtFlags |= ( (uiMappingFlags & PVRSRV_MEMALLOCFLAG_DEVICE_FLAGS_MASK)
 							>> PVRSRV_MEMALLOCFLAG_DEVICE_FLAGS_OFFSET)
 							<< MMU_PROTFLAGS_DEVICE_OFFSET;
 
-		if (uiMappingFlags & PVRSRV_MEMALLOCFLAG_GPU_READABLE)
+		if (PVRSRV_CHECK_GPU_READABLE(uiMappingFlags))
 		{
 			*uiMMUProtFlags |= MMU_PROTFLAGS_READABLE;
 		}
-		if (uiMappingFlags & PVRSRV_MEMALLOCFLAG_GPU_WRITEABLE)
+		if (PVRSRV_CHECK_GPU_WRITEABLE(uiMappingFlags))
 		{
 			*uiMMUProtFlags |= MMU_PROTFLAGS_WRITEABLE;
 		}
 
-		switch ( DevmemDeviceCacheMode(uiMappingFlags) )
+		switch (DevmemDeviceCacheMode(psMMUContext->psDevNode, uiMappingFlags))
 		{
 			case PVRSRV_MEMALLOCFLAG_GPU_UNCACHED:
 			case PVRSRV_MEMALLOCFLAG_GPU_WRITE_COMBINE:
@@ -608,33 +895,32 @@
 					return;
 		}
 
-		if (DevmemDeviceCacheCoherency(uiMappingFlags))
+		if (DevmemDeviceCacheCoherency(psMMUContext->psDevNode, uiMappingFlags))
 		{
 			*uiMMUProtFlags |= MMU_PROTFLAGS_CACHE_COHERENT;
 		}
-#if defined(RGX_FEATURE_MIPS)
-		/*
-			If we are allocating on the MMU of the firmware processor, the cached/uncached attributes
-			must depend on the FIRMWARE_CACHED allocation flag.
-		 */
-		if (psMMUContext->psDevAttrs == psMMUContext->psDevNode->psFirmwareMMUDevAttrs)
-		{
-			if (uiMappingFlags & PVRSRV_MEMALLOCFLAG_DEVICE_FLAG(FIRMWARE_CACHED))
-			{
-				*uiMMUProtFlags |= MMU_PROTFLAGS_CACHED;
-			}
-			else
-			{
-				*uiMMUProtFlags &= ~MMU_PROTFLAGS_CACHED;
 
+		if( (psMMUContext->psDevNode->pfnCheckDeviceFeature) && \
+				psMMUContext->psDevNode->pfnCheckDeviceFeature(psMMUContext->psDevNode, RGX_FEATURE_MIPS_BIT_MASK))
+		{
+			/*
+				If we are allocating on the MMU of the firmware processor, the cached/uncached attributes
+				must depend on the FIRMWARE_CACHED allocation flag.
+			 */
+			if (psMMUContext->psDevAttrs == psMMUContext->psDevNode->psFirmwareMMUDevAttrs)
+			{
+				if (uiMappingFlags & PVRSRV_MEMALLOCFLAG_DEVICE_FLAG(FIRMWARE_CACHED))
+				{
+					*uiMMUProtFlags |= MMU_PROTFLAGS_CACHED;
+				}
+				else
+				{
+					*uiMMUProtFlags &= ~MMU_PROTFLAGS_CACHED;
+
+				}
+				*uiMMUProtFlags &= ~MMU_PROTFLAGS_CACHE_COHERENT;
 			}
-			*uiMMUProtFlags &= ~MMU_PROTFLAGS_CACHE_COHERENT;
 		}
-#elif defined(RGX_FEATURE_META)
-		PVR_UNREFERENCED_PARAMETER(psMMUContext);
-#else
-#error ("Build Misconfiguration. A firmware processor must be defined")
-#endif
 	}
 	else
 	{
@@ -666,14 +952,12 @@
 								const MMU_PxE_CONFIG *psConfig,
 								MMU_LEVEL eMMULevel,
 								MMU_MEMORY_DESC *psMemDesc,
-								IMG_UINT8 uiLog2Align)
+								IMG_UINT32 uiLog2Align)
 {
 	PVRSRV_ERROR eError;
 	size_t uiBytes;
 	size_t uiAlign;
-#if defined(PDUMP)
-	PVRSRV_DEVICE_NODE *psDevNode = psMMUContext->psDevNode;
-#endif
+
 	PVR_ASSERT(psConfig->uiBytesPerEntry != 0);
 
 	uiBytes = uiNumEntries * psConfig->uiBytesPerEntry;
@@ -692,12 +976,15 @@
 
 	/*
 		Clear the object
-		Note: if any MMUs are cleared with non-zero values then will need a custom
-		clear function
+		Note: if any MMUs are cleared with non-zero values then will need a
+		custom clear function
+		Note: 'Cached' is wrong for the LMA + ARM64 combination, but this is
+		unlikely
 	*/
-	OSMemSet(psMemDesc->pvCpuVAddr, 0, uiBytes);
+	OSCachedMemSet(psMemDesc->pvCpuVAddr, 0, uiBytes);
 
-	eError = psMMUContext->psDevNode->pfnDevPxClean(&psMemDesc->psMapping->sMemHandle,
+	eError = psMMUContext->psDevNode->pfnDevPxClean(psMMUContext->psDevNode,
+	                                                &psMemDesc->psMapping->sMemHandle,
 	                                                psMemDesc->uiOffset,
 	                                                psMemDesc->uiSize);
 	if(eError != PVRSRV_OK)
@@ -708,28 +995,28 @@
 #if defined(PDUMP)
 	PDUMPCOMMENT("Alloc MMU object");
 
-	PDumpMMUMalloc(psDevNode->pszMMUPxPDumpMemSpaceName,
-                   eMMULevel,
-                   &psMemDesc->sDevPAddr,
-                   uiBytes,    
-                   uiAlign,
-                   psMMUContext->psDevAttrs->eMMUType);
-	
+	PDumpMMUMalloc(psMMUContext->psDevAttrs->pszMMUPxPDumpMemSpaceName,
+	               eMMULevel,
+	               &psMemDesc->sDevPAddr,
+	               uiBytes,
+	               uiAlign,
+	               psMMUContext->psDevAttrs->eMMUType);
+
 	PDumpMMUDumpPxEntries(eMMULevel,
-						  psDevNode->pszMMUPxPDumpMemSpaceName,
-						  psMemDesc->pvCpuVAddr,
-						  psMemDesc->sDevPAddr,
-						  0,
-						  uiNumEntries,
-						  NULL, NULL, 0, /* pdump symbolic info is irrelevant here */
-						  psConfig->uiBytesPerEntry,
-						  uiLog2Align,
-						  psConfig->uiAddrShift,
-						  psConfig->uiAddrMask,
-						  psConfig->uiProtMask,
-						  psConfig->uiValidEnMask,
-						  0,
-						  psMMUContext->psDevAttrs->eMMUType);
+	                      psMMUContext->psDevAttrs->pszMMUPxPDumpMemSpaceName,
+	                      psMemDesc->pvCpuVAddr,
+	                      psMemDesc->sDevPAddr,
+	                      0,
+	                      uiNumEntries,
+	                      NULL, NULL, 0, /* pdump symbolic info is irrelevant here */
+	                      psConfig->uiBytesPerEntry,
+	                      uiLog2Align,
+	                      psConfig->uiAddrShift,
+	                      psConfig->uiAddrMask,
+	                      psConfig->uiProtMask,
+	                      psConfig->uiValidEnMask,
+	                      0,
+	                      psMMUContext->psDevAttrs->eMMUType);
 #endif
 
 	return PVRSRV_OK;
@@ -756,18 +1043,17 @@
 static void _PxMemFree(MMU_CONTEXT *psMMUContext,
 					   MMU_MEMORY_DESC *psMemDesc, MMU_LEVEL eMMULevel)
 {
-#if defined(PDUMP)
-	PVRSRV_DEVICE_NODE *psDevNode = psMMUContext->psDevNode;
-#endif
 #if defined(MMU_CLEARMEM_ON_FREE)
 	PVRSRV_ERROR eError;
 
 	/*
 		Clear the MMU object
-		Note: if any MMUs are cleared with non-zero values then will need a custom
-		clear function
+		Note: if any MMUs are cleared with non-zero values then will need a
+		custom clear function
+		Note: 'Cached' is wrong for the LMA + ARM64 combination, but this is
+		unlikely
 	*/
-	OSMemSet(psMemDesc->pvCpuVAddr, 0, psMemDesc->ui32Bytes);
+	OSCachedMemSet(psMemDesc->pvCpuVAddr, 0, psMemDesc->ui32Bytes);
 
 #if defined(PDUMP)
 	PDUMPCOMMENT("Clear MMU object before freeing it");
@@ -777,7 +1063,10 @@
 #if defined(PDUMP)
 	PDUMPCOMMENT("Free MMU object");
 	{
-		PDumpMMUFree(psDevNode->pszMMUPxPDumpMemSpaceName, eMMULevel, &psMemDesc->sDevPAddr, psMMUContext->psDevAttrs->eMMUType);
+		PDumpMMUFree(psMMUContext->psDevAttrs->pszMMUPxPDumpMemSpaceName,
+		             eMMULevel,
+		             &psMemDesc->sDevPAddr,
+		             psMMUContext->psDevAttrs->eMMUType);
 	}
 #else
 	PVR_UNREFERENCED_PARAMETER(eMMULevel);
@@ -801,9 +1090,25 @@
 {
 	MMU_MEMORY_DESC *psMemDesc = &psLevel->sMemDesc;
 	IMG_UINT64 ui64PxE64;
+	IMG_UINT64 uiAddr = psDevPAddr->uiAddr;
+
+	if(psMMUContext->psDevNode->pfnCheckDeviceFeature(psMMUContext->psDevNode, \
+			RGX_FEATURE_MIPS_BIT_MASK))
+	{
+		/*
+		 * If mapping for the MIPS FW context, check for sensitive PAs
+		 */
+		if (psMMUContext->psDevAttrs == psMMUContext->psDevNode->psFirmwareMMUDevAttrs
+			&& RGXMIPSFW_SENSITIVE_ADDR(uiAddr))
+		{
+			PVRSRV_RGXDEV_INFO *psDevice = (PVRSRV_RGXDEV_INFO *)psMMUContext->psDevNode->pvDevice;
+
+			uiAddr = psDevice->sTrampoline.sPhysAddr.uiAddr + RGXMIPSFW_TRAMPOLINE_OFFSET(uiAddr);
+		}
+	}
 
 	/* Calculate Entry */
-	ui64PxE64 =    psDevPAddr->uiAddr /* Calculate the offset to that base */
+	ui64PxE64 =    uiAddr /* Calculate the offset to that base */
 	            >> psConfig->uiAddrLog2Align /* Shift away the useless bits, because the alignment is very coarse and we address by alignment */
 	            << psConfig->uiAddrShift /* Shift back to fit address in the Px entry */
 	             & psConfig->uiAddrMask; /* Delete unused bits */
@@ -841,22 +1146,22 @@
 
 #if defined (PDUMP)
 	PDumpMMUDumpPxEntries(MMU_LEVEL_1,
-						  psMMUContext->psDevNode->pszMMUPxPDumpMemSpaceName,
-						  psMemDesc->pvCpuVAddr,
-						  psMemDesc->sDevPAddr,
-						  uiIndex,
-						  1,
-						  pszMemspaceName,
-						  pszSymbolicAddr,
-						  uiSymbolicAddrOffset,
-						  psConfig->uiBytesPerEntry,
-						  psConfig->uiAddrLog2Align,
-						  psConfig->uiAddrShift,
-						  psConfig->uiAddrMask,
-						  psConfig->uiProtMask,
-						  psConfig->uiValidEnMask,
-						  0,
-						  psMMUContext->psDevAttrs->eMMUType);
+	                      psMMUContext->psDevAttrs->pszMMUPxPDumpMemSpaceName,
+	                      psMemDesc->pvCpuVAddr,
+	                      psMemDesc->sDevPAddr,
+	                      uiIndex,
+	                      1,
+	                      pszMemspaceName,
+	                      pszSymbolicAddr,
+	                      uiSymbolicAddrOffset,
+	                      psConfig->uiBytesPerEntry,
+	                      psConfig->uiAddrLog2Align,
+	                      psConfig->uiAddrShift,
+	                      psConfig->uiAddrMask,
+	                      psConfig->uiProtMask,
+	                      psConfig->uiValidEnMask,
+	                      0,
+	                      psMMUContext->psDevAttrs->eMMUType);
 #endif /*PDUMP*/
 
 	return PVRSRV_OK;
@@ -984,7 +1289,7 @@
 				uiIndex, eMMULevel,
 				HTBLOG_U64_BITS_HIGH(ui64PxE64), HTBLOG_U64_BITS_LOW(ui64PxE64),
 				(uiProtFlags & MMU_PROTFLAGS_INVALID)? 0: 1);
-			break;	
+			break;
 		}
 		case 8:
 		{
@@ -1001,7 +1306,7 @@
 				uiIndex, eMMULevel,
 				HTBLOG_U64_BITS_HIGH(pui64Px[uiIndex]), HTBLOG_U64_BITS_LOW(pui64Px[uiIndex]),
 				(uiProtFlags & MMU_PROTFLAGS_INVALID)? 0: 1);
-			break;	
+			break;
 		}
 		default:
 			PVR_DPF((PVR_DBG_ERROR, "%s: PxE size not supported (%d) for level %d",
@@ -1012,22 +1317,22 @@
 
 #if defined (PDUMP)
 	PDumpMMUDumpPxEntries(eMMULevel,
-						  psDevNode->pszMMUPxPDumpMemSpaceName,
-						  psMemDesc->pvCpuVAddr,
-						  psMemDesc->sDevPAddr,
-						  uiIndex,
-						  1,
-						  pszMemspaceName,
-						  pszSymbolicAddr,
-						  uiSymbolicAddrOffset,
-						  psConfig->uiBytesPerEntry,
-						  psConfig->uiAddrLog2Align,
-						  psConfig->uiAddrShift,
-						  psConfig->uiAddrMask,
-						  psConfig->uiProtMask,
-						  psConfig->uiValidEnMask,
-						  0,
-						  psMMUContext->psDevAttrs->eMMUType);
+	                      psMMUContext->psDevAttrs->pszMMUPxPDumpMemSpaceName,
+	                      psMemDesc->pvCpuVAddr,
+	                      psMemDesc->sDevPAddr,
+	                      uiIndex,
+	                      1,
+	                      pszMemspaceName,
+	                      pszSymbolicAddr,
+	                      uiSymbolicAddrOffset,
+	                      psConfig->uiBytesPerEntry,
+	                      psConfig->uiAddrLog2Align,
+	                      psConfig->uiAddrShift,
+	                      psConfig->uiAddrMask,
+	                      psConfig->uiProtMask,
+	                      psConfig->uiValidEnMask,
+	                      0,
+	                      psMMUContext->psDevAttrs->eMMUType);
 #endif
 
 	psDevNode->pfnMMUCacheInvalidate(psDevNode, psMMUContext->hDevData,
@@ -1063,7 +1368,7 @@
 
 @Input          psMMUContext    MMU context to operate on
 
-@Input          psLevel                 Level info on which to to free the
+@Input          psLevel                 Level info on which to free the
                                         specified range
 
 @Input          auiStartArray           Array of start indexes (one for each level)
@@ -1078,7 +1383,7 @@
 @Input          aeMMULevel              Array of MMU levels (one for each level)
 
 @Input          pui32CurrentLevel       Pointer to a variable which is set to our
-                                        current level 
+                                        current level
 
 @Input          uiStartIndex            Start index of the range to free
 
@@ -1160,34 +1465,35 @@
 								uiNextStartIndex, uiNextEndIndex,
 								bNextFirst, bNextLast, uiLog2DataPageSize))
 			{
+				PVRSRV_ERROR eError;
+
+				/* Un-wire the entry */
+				eError = _SetupPxE(psMMUContext,
+								psLevel,
+								i,
+								psConfig,
+								aeMMULevel[uiThisLevel],
+								NULL,
+#if defined(PDUMP)
+								NULL,	/* Only required for data page */
+								NULL,	/* Only required for data page */
+								0,      /* Only required for data page */
+#endif
+								MMU_PROTFLAGS_INVALID,
+								uiLog2DataPageSize);
+
+				PVR_ASSERT(eError == PVRSRV_OK);
+
+				/* Free table of the level below, pointed to by this table entry.
+				 * We don't destroy the table inside the above _MMU_FreeLevel call because we
+				 * first have to set the table entry of the level above to invalid. */
+				_PxMemFree(psMMUContext, &psNextLevel->sMemDesc, aeMMULevel[*pui32CurrentLevel]);
+				OSFreeMem(psNextLevel);
+
 				/* The level below us is empty, drop the refcount and clear the pointer */
 				psLevel->ui32RefCount--;
 				psLevel->apsNextLevel[i] = NULL;
 
-				/* Level 1 PTE reprogramming is done in the unmap */
-				if (aeMMULevel[uiThisLevel] != MMU_LEVEL_1)
-				{
-					PVRSRV_ERROR eError;
-
-					/* Un-wire the entry */
-					eError = _SetupPxE(psMMUContext,
-									psLevel,
-									i,
-									psConfig,
-									aeMMULevel[uiThisLevel],
-									NULL,
-#if defined(PDUMP)
-									NULL,	/* Only required for data page */
-									NULL,	/* Only required for data page */
-									0,      /* Only required for data page */
-#endif
-									MMU_PROTFLAGS_INVALID,
-									uiLog2DataPageSize);		
-
-					PVR_ASSERT(eError == PVRSRV_OK);
-				}
-
-
 				/* Check we haven't wrapped around */
 				PVR_ASSERT(psLevel->ui32RefCount <= psLevel->ui32NumOfEntries);
 			}
@@ -1198,30 +1504,26 @@
 			psLevel->ui32RefCount--;
 		}
 
-
+		/*
+		   Free this level if it is no longer referenced, unless it's the base
+		   level in which case it's part of the MMU context and should be freed
+		   when the MMU context is freed
+		*/
+		if ((psLevel->ui32RefCount == 0) && (psLevel != &psMMUContext->sBaseLevelInfo))
+		{
+			bFreed = IMG_TRUE;
+		}
 	}
 
 	/* Level one flushing is done when we actually write the table entries */
 	if (aeMMULevel[uiThisLevel] != MMU_LEVEL_1)
 	{
-		psMMUContext->psDevNode->pfnDevPxClean(&psLevel->sMemDesc.psMapping->sMemHandle,
+		psMMUContext->psDevNode->pfnDevPxClean(psMMUContext->psDevNode,
+		                                       &psLevel->sMemDesc.psMapping->sMemHandle,
 		                                       uiStartIndex * psConfig->uiBytesPerEntry + psLevel->sMemDesc.uiOffset,
 		                                       (uiEndIndex - uiStartIndex) * psConfig->uiBytesPerEntry);
 	}
 
-	/*
-	   Free this level if it is no longer referenced, unless it's the base
-	   level in which case it's part of the MMU context and should be freed
-	   when the MMU context is freed
-	*/
-	if ((psLevel->ui32RefCount == 0) && (psLevel != &psMMUContext->sBaseLevelInfo))
-	{
-		_PxMemFree(psMMUContext, &psLevel->sMemDesc, aeMMULevel[uiThisLevel]);
-		OSFreeMem(psLevel);
-		psLevel = NULL;
-		bFreed = IMG_TRUE;
-	}
-
 	MMU_OBJ_DBG((PVR_DBG_ERROR, "_MMU_FreeLevel end: level = %d, refcount = %d",
 				aeMMULevel[uiThisLevel], bFreed?0:psLevel->ui32RefCount));
 
@@ -1264,7 +1566,7 @@
 @Input          aeMMULevel              Array of MMU levels (one for each level)
 
 @Input          pui32CurrentLevel       Pointer to a variable which is set to our
-                                        current level 
+                                        current level
 
 @Input          uiStartIndex            Start index of the range to free
 
@@ -1305,7 +1607,7 @@
 				uiEndIndex, psLevel->ui32RefCount));
 
 	/* Go from uiStartIndex to uiEndIndex through the Px */
-	for (i = uiStartIndex;i < uiEndIndex;i++) 
+	for (i = uiStartIndex;i < uiEndIndex;i++)
 	{
 		/* Only try an allocation if this is not the last level */
 		/*Because a PT allocation is already done while setting the entry in PD */
@@ -1330,13 +1632,12 @@
 				{
 					ui32AllocSize += sizeof(MMU_Levelx_INFO *) * (uiNextEntries - 1);
 				}
-				psNextLevel = OSAllocMem(ui32AllocSize);
+				psNextLevel = OSAllocZMem(ui32AllocSize);
 				if (psNextLevel == NULL)
 				{
 					uiAllocState = 0;
 					goto e0;
 				}
-				OSMemSet(psNextLevel, 0, ui32AllocSize);
 
 				/* Hook in this level for next time */
 				psLevel->apsNextLevel[i] = psNextLevel;
@@ -1434,9 +1735,10 @@
 	/* Level one flushing is done when we actually write the table entries */
 	if (aeMMULevel[uiThisLevel] != MMU_LEVEL_1)
 	{
-		eError = psMMUContext->psDevNode->pfnDevPxClean(&psLevel->sMemDesc.psMapping->sMemHandle,
-														uiStartIndex * psConfig->uiBytesPerEntry + psLevel->sMemDesc.uiOffset,
-														(uiEndIndex - uiStartIndex) * psConfig->uiBytesPerEntry);
+		eError = psMMUContext->psDevNode->pfnDevPxClean(psMMUContext->psDevNode,
+		                                                &psLevel->sMemDesc.psMapping->sMemHandle,
+		                                                uiStartIndex * psConfig->uiBytesPerEntry + psLevel->sMemDesc.uiOffset,
+		                                                (uiEndIndex - uiStartIndex) * psConfig->uiBytesPerEntry);
 		if (eError != PVRSRV_OK)
 			goto e0;
 	}
@@ -1451,8 +1753,8 @@
 	PVR_DPF((PVR_DBG_ERROR, "_MMU_AllocLevel: Error %d allocating Px for level %d in stage %d"
 							,eError, aeMMULevel[uiThisLevel], uiAllocState));
 
-	/* the start value of index variable i is nor initialised on purpose 
-	   indeed this for loop deinitialise what has already been initialised 
+	/* the start value of index variable i is nor initialised on purpose
+	   indeed this for loop deinitialise what has already been initialised
 	   just before failing in reverse order. So the i index has already the
 	   right value. */
 	for (/* i already set */ ; i>= uiStartIndex  &&  i< uiEndIndex; i--)
@@ -1569,7 +1871,7 @@
 
 @Input          ppsMMUDevVAddrConfig    Device virtual address config
 
-@Input			phPriv					Private data of page size config		
+@Input			phPriv					Private data of page size config
 
 @Return         IMG_TRUE if the last reference to psLevel was dropped
 */
@@ -1740,7 +2042,9 @@
 @Function       _FreePageTables
 
 @Description    Free page tables and any higher level MMU objects at are no
-                longer referenced for the specified virtual range
+                longer referenced for the specified virtual range.
+                This will fill the temporary free list of the MMU context which
+                needs cleanup after the call.
 
 @Input          psMMUContext            MMU context to operate on
 
@@ -1937,6 +2241,7 @@
 
 }
 
+
 /*****************************************************************************
  *                     Public interface functions                            *
  *****************************************************************************/
@@ -1985,7 +2290,7 @@
 	ui32Size = sizeof(MMU_CONTEXT) + 
 						((ui32BaseObjects - 1) * sizeof(MMU_Levelx_INFO *));
 
-	psMMUContext = OSAllocMem(ui32Size);
+	psMMUContext = OSAllocZMem(ui32Size);
 	if (psMMUContext == NULL)
 	{
 		PVR_DPF((PVR_DBG_ERROR, "MMU_ContextCreate: ERROR call to OSAllocMem failed"));
@@ -1993,8 +2298,6 @@
 		goto e0;
 	}
 
-	OSMemSet (psMMUContext, 0, ui32Size);
-
 #if defined(PDUMP)
 	/* Clear the refcount */
 	psMMUContext->ui32PDumpContextIDRefCount = 0;
@@ -2006,15 +2309,18 @@
 #if defined(SUPPORT_GPUVIRT_VALIDATION)
 {
 	IMG_UINT32 ui32OSid, ui32OSidReg;
-	RetrieveOSidsfromPidList(OSGetCurrentClientProcessIDKM(), &ui32OSid, &ui32OSidReg);
-	MMU_SetOSids(psMMUContext, ui32OSid, ui32OSidReg);
+    IMG_BOOL bOSidAxiProt;
+
+    RetrieveOSidsfromPidList(OSGetCurrentClientProcessIDKM(), &ui32OSid, &ui32OSidReg, &bOSidAxiProt);
+
+    MMU_SetOSids(psMMUContext, ui32OSid, ui32OSidReg, bOSidAxiProt);
 }
 #endif
 
-	/* 
+	/*
 	  Allocate physmem context and set it up
 	 */
-	psCtx = OSAllocMem(sizeof (MMU_PHYSMEM_CONTEXT));
+	psCtx = OSAllocZMem(sizeof(MMU_PHYSMEM_CONTEXT));
 	if (psCtx == NULL)
 	{
 		PVR_DPF((PVR_DBG_ERROR, "MMU_ContextCreate: ERROR call to OSAllocMem failed"));
@@ -2023,7 +2329,6 @@
 	}
 	psMMUContext->psPhysMemCtx = psCtx;
 
-	OSMemSet (psCtx, 0, sizeof(MMU_PHYSMEM_CONTEXT));
 	psCtx->psDevNode = psDevNode;
 
 	OSSNPrintf(sBuf, sizeof(sBuf)-1, "pgtables %p", psCtx);
@@ -2054,6 +2359,21 @@
 		goto e3;
 	}
 
+	/* Setup cleanup meta data to check if a MMU context
+	 * has been destroyed and should not be accessed anymore */
+	psCtx->psCleanupData = OSAllocMem(sizeof(*(psCtx->psCleanupData)));
+	if (psCtx->psCleanupData == NULL)
+	{
+		PVR_DPF((PVR_DBG_ERROR, "MMU_ContextCreate: ERROR call to OSAllocMem failed"));
+		eError = PVRSRV_ERROR_OUT_OF_MEMORY;
+		goto e4;
+	}
+
+	OSLockCreate(&psCtx->psCleanupData->hCleanupLock, LOCK_TYPE_PASSIVE);
+	psCtx->psCleanupData->bMMUContextExists = IMG_TRUE;
+	dllist_init(&psCtx->psCleanupData->sMMUCtxCleanupItemsHead);
+	OSAtomicWrite(&psCtx->psCleanupData->iRef, 1);
+
 	/* allocate the base level object */
 	/*
 	   Note: Although this is not required by the this file until
@@ -2070,9 +2390,11 @@
 	{
 		PVR_DPF((PVR_DBG_ERROR, "MMU_ContextCreate: Failed to alloc level 1 object"));
 		eError = PVRSRV_ERROR_OUT_OF_MEMORY;
-		goto e4;
+		goto e5;
 	}
 
+	dllist_init(&psMMUContext->psPhysMemCtx->sTmpMMUMappingHead);
+
 	psMMUContext->sBaseLevelInfo.ui32NumOfEntries = ui32BaseObjects;
 	psMMUContext->sBaseLevelInfo.ui32RefCount = 0;
 
@@ -2081,7 +2403,7 @@
 	if(eError != PVRSRV_OK)
 	{
 		PVR_DPF((PVR_DBG_ERROR, "MMU_ContextCreate: Failed to create lock for MMU_CONTEXT"));
-		goto e5;
+		goto e6;
 	}
 
 	/* return context */
@@ -2089,8 +2411,10 @@
 
 	return PVRSRV_OK;
 
-e5:
+e6:
 	_PxMemFree(psMMUContext, &psMMUContext->sBaseLevelInfo.sMemDesc, psDevAttrs->eTopLevel);
+e5:
+	OSFreeMem(psCtx->psCleanupData);
 e4:
 	RA_Delete(psCtx->psPhysMemRA);
 e3:
@@ -2110,6 +2434,10 @@
 MMU_ContextDestroy (MMU_CONTEXT *psMMUContext)
 {
 	PVRSRV_DATA *psPVRSRVData = PVRSRVGetPVRSRVData();
+	PDLLIST_NODE psNode, psNextNode;
+
+	PVRSRV_DEVICE_NODE *psDevNode = (PVRSRV_DEVICE_NODE *) psMMUContext->psDevNode;
+	MMU_CTX_CLEANUP_DATA *psCleanupData = psMMUContext->psPhysMemCtx->psCleanupData;
 
 	PVR_DPF ((PVR_DBG_MESSAGE, "MMU_ContextDestroy: Enter"));
 
@@ -2120,10 +2448,47 @@
 		PVR_ASSERT(psMMUContext->sBaseLevelInfo.ui32RefCount == 0);
 	}
 
-	/* Free the top level MMU object */
+	/* Cleanup lock must be acquired before MMUContext lock. Reverse order
+	 * may lead to a deadlock and is reported by lockdep. */
+	OSLockAcquire(psCleanupData->hCleanupLock);
+	OSLockAcquire(psMMUContext->hLock);
+
+	/* Free the top level MMU object - will be put on defer free list.
+	 * This has to be done before the step below that will empty the
+	 * defer-free list. */
 	_PxMemFree(psMMUContext,
-				&psMMUContext->sBaseLevelInfo.sMemDesc,
-				psMMUContext->psDevAttrs->eTopLevel);
+	           &psMMUContext->sBaseLevelInfo.sMemDesc,
+	           psMMUContext->psDevAttrs->eTopLevel);
+
+	/* Empty the temporary defer-free list of Px */
+	_FreeMMUMapping(psDevNode, &psMMUContext->psPhysMemCtx->sTmpMMUMappingHead);
+	PVR_ASSERT(dllist_is_empty(&psMMUContext->psPhysMemCtx->sTmpMMUMappingHead));
+
+	/* Empty the defer free list so the cleanup thread will
+	 * not have to access any MMU context related structures anymore */
+	dllist_foreach_node(&psCleanupData->sMMUCtxCleanupItemsHead,
+	                    psNode,
+	                    psNextNode)
+	{
+		MMU_CLEANUP_ITEM *psCleanup = IMG_CONTAINER_OF(psNode,
+		                                               MMU_CLEANUP_ITEM,
+		                                               sMMUCtxCleanupItem);
+
+		_FreeMMUMapping(psDevNode, &psCleanup->sMMUMappingHead);
+
+		dllist_remove_node(psNode);
+	}
+	PVR_ASSERT(dllist_is_empty(&psCleanupData->sMMUCtxCleanupItemsHead));
+
+	psCleanupData->bMMUContextExists = IMG_FALSE;
+
+	OSLockRelease(psCleanupData->hCleanupLock);
+
+	if (OSAtomicDecrement(&psCleanupData->iRef) == 0)
+	{
+		OSLockDestroy(psCleanupData->hCleanupLock);
+		OSFreeMem(psCleanupData);
+	}
 
 	/* Free physmem context */
 	RA_Delete(psMMUContext->psPhysMemCtx->psPhysMemRA);
@@ -2133,6 +2498,8 @@
 
 	OSFreeMem(psMMUContext->psPhysMemCtx);
 
+	OSLockRelease(psMMUContext->hLock);
+
 #if defined(SUPPORT_GPUVIRT_VALIDATION)
 	RemovePidOSidCoupling(OSGetCurrentClientProcessIDKM());
 #endif
@@ -2156,7 +2523,7 @@
            IMG_UINT32 uiProtFlags,
 		   IMG_DEVMEM_SIZE_T uDevVAddrAlignment,
 		   IMG_DEV_VIRTADDR *psDevVAddr,
-		   IMG_UINT8 uiLog2PageSize)
+		   IMG_UINT32 uiLog2PageSize)
 {
     PVRSRV_ERROR eError;
     IMG_DEV_VIRTADDR sDevVAddrEnd;
@@ -2245,11 +2612,27 @@
 	sDevVAddrEnd = sDevVAddr;
 	sDevVAddrEnd.uiAddr += uiSize;
 
+	/* The Cleanup lock has to be taken before the MMUContext hLock to
+	 * prevent deadlock scenarios. It is necessary only for parts of
+	 * _SetupCleanup_FreeMMUMapping though.*/
+	OSLockAcquire(psMMUContext->psPhysMemCtx->psCleanupData->hCleanupLock);
+
 	OSLockAcquire(psMMUContext->hLock);
 
-	_FreePageTables(psMMUContext, sDevVAddr, sDevVAddrEnd, uiLog2DataPageSize);
+	_FreePageTables(psMMUContext,
+	                sDevVAddr,
+	                sDevVAddrEnd,
+	                uiLog2DataPageSize);
+
+	_SetupCleanup_FreeMMUMapping(psMMUContext->psDevNode,
+	                             psMMUContext->psPhysMemCtx);
 
 	OSLockRelease(psMMUContext->hLock);
+
+	OSLockRelease(psMMUContext->psPhysMemCtx->psCleanupData->hCleanupLock);
+
+	return;
+
 }
 
 PVRSRV_ERROR
@@ -2260,9 +2643,9 @@
              IMG_UINT32 ui32PhysPgOffset,
              IMG_UINT32 ui32MapPageCount,
              IMG_UINT32 *paui32MapIndices,
-             IMG_UINT8 uiLog2PageSize)
+             IMG_UINT32 uiLog2PageSize)
 {
-	PVRSRV_ERROR eError = ~PVRSRV_OK;
+	PVRSRV_ERROR eError;
 	IMG_HANDLE hPriv;
 
 	MMU_Levelx_INFO *psLevel = NULL;
@@ -2294,8 +2677,8 @@
 	IMG_BOOL bNeedBacking = IMG_FALSE;
 
 #if defined(PDUMP)
-	IMG_CHAR aszMemspaceName[PMR_MAX_MEMSPACE_NAME_LENGTH_DEFAULT];
-	IMG_CHAR aszSymbolicAddress[PMR_MAX_SYMBOLIC_ADDRESS_LENGTH_DEFAULT];
+	IMG_CHAR aszMemspaceName[PHYSMEM_PDUMP_MEMSPACE_MAX_LENGTH];
+	IMG_CHAR aszSymbolicAddress[PHYSMEM_PDUMP_SYMNAME_MAX_LENGTH];
 	IMG_DEVMEM_OFFSET_T uiSymbolicAddrOffset;
 
 	PDUMPCOMMENT("Wire up Page Table entries to point to the Data Pages (%lld bytes)",
@@ -2441,17 +2824,28 @@
 
 #if defined(DEBUG)
 {
+			IMG_INT32	i32FeatureVal = 0;
 			IMG_UINT32 ui32BitLength = FloorLog2(sDevPAddr.uiAddr);
-			if (ui32BitLength > RGX_FEATURE_PHYS_BUS_WIDTH )
-			{
-				PVR_DPF((PVR_DBG_ERROR,"_MMU_MapPage Failed. The physical address bitlength (%d) "
-				         "is greater than what the chip can handle (%d).",
-				         ui32BitLength, RGX_FEATURE_PHYS_BUS_WIDTH));
 
-				PVR_ASSERT(ui32BitLength <= RGX_FEATURE_PHYS_BUS_WIDTH );
-				eError = PVRSRV_ERROR_INVALID_PARAMS;
-				goto e1;
-			}
+			i32FeatureVal = psMMUContext->psDevNode->pfnGetDeviceFeatureValue(psMMUContext->psDevNode, \
+														RGX_FEATURE_PHYS_BUS_WIDTH_BIT_MASK);
+			do {
+				/* i32FeatureVal can be negative for cases where this feature is undefined
+				 * In that situation we need to bail out than go ahead with debug comparison */
+				if(0 > i32FeatureVal)
+					break;
+
+				if (ui32BitLength > i32FeatureVal )
+				{
+					PVR_DPF((PVR_DBG_ERROR,"_MMU_MapPage Failed. The physical address bitlength (%d) "
+							 "is greater than what the chip can handle (%d).",
+							 ui32BitLength, i32FeatureVal));
+
+					PVR_ASSERT(ui32BitLength <= i32FeatureVal );
+					eError = PVRSRV_ERROR_INVALID_PARAMS;
+					goto e3;
+				}
+			}while(0);
 }
 #endif /*DEBUG*/
 
@@ -2481,9 +2875,10 @@
 				/* Flush if we moved to another psLevel, i.e. page table */
 				if (psPrevLevel != NULL)
 				{
-					eError = psMMUContext->psDevNode->pfnDevPxClean(&psPrevLevel->sMemDesc.psMapping->sMemHandle,
-																	uiFlushStart * psConfig->uiBytesPerEntry + psPrevLevel->sMemDesc.uiOffset,
-																	(uiFlushEnd+1 - uiFlushStart) * psConfig->uiBytesPerEntry);
+					eError = psMMUContext->psDevNode->pfnDevPxClean(psMMUContext->psDevNode,
+					                                                &psPrevLevel->sMemDesc.psMapping->sMemHandle,
+					                                                uiFlushStart * psConfig->uiBytesPerEntry + psPrevLevel->sMemDesc.uiOffset,
+					                                                (uiFlushEnd+1 - uiFlushStart) * psConfig->uiBytesPerEntry);
 					if (eError != PVRSRV_OK)
 						goto e3;
 				}
@@ -2504,7 +2899,7 @@
 			                   &sDevPAddr,
 			                   IMG_FALSE,
 #if defined(PDUMP)
-			                   (bValid)?aszMemspaceName:(psMMUContext->psDevNode->pszMMUPxPDumpMemSpaceName),
+			                   (bValid)?aszMemspaceName:(psMMUContext->psDevAttrs->pszMMUPxPDumpMemSpaceName),
 			                   (bValid)?aszSymbolicAddress:DUMMY_PAGE,
 			                   (bValid)?uiSymbolicAddrOffset:0,
 #endif /*PDUMP*/
@@ -2536,9 +2931,10 @@
 	/* Flush the last level we touched */
 	if (psLevel != NULL)
 	{
-		eError = psMMUContext->psDevNode->pfnDevPxClean(&psLevel->sMemDesc.psMapping->sMemHandle,
-														uiFlushStart * psConfig->uiBytesPerEntry + psLevel->sMemDesc.uiOffset,
-														(uiFlushEnd+1 - uiFlushStart) * psConfig->uiBytesPerEntry);
+		eError = psMMUContext->psDevNode->pfnDevPxClean(psMMUContext->psDevNode,
+		                                                &psLevel->sMemDesc.psMapping->sMemHandle,
+		                                                uiFlushStart * psConfig->uiBytesPerEntry + psLevel->sMemDesc.uiOffset,
+		                                                (uiFlushEnd+1 - uiFlushStart) * psConfig->uiBytesPerEntry);
 		if (eError != PVRSRV_OK)
 			goto e3;
 	}
@@ -2595,7 +2991,7 @@
                 IMG_DEV_VIRTADDR sDevVAddrBase,
                 IMG_UINT32 ui32PageCount,
                 IMG_UINT32 *pai32FreeIndices,
-                IMG_UINT8 uiLog2PageSize,
+                IMG_UINT32 uiLog2PageSize,
                 IMG_BOOL bDummyBacking)
 {
 	IMG_UINT32 uiPTEIndex = 0, ui32Loop=0;
@@ -2612,13 +3008,14 @@
 	IMG_DEV_PHYADDR sDummyPgDevPhysAddr;
 	IMG_BOOL bUnmap = IMG_TRUE;
 
-	sDummyPgDevPhysAddr.uiAddr = psMMUContext->psDevNode->sDummyPage.ui64DummyPgPhysAddr;
 #if defined(PDUMP)
 	PDUMPCOMMENT("Invalidate %d entries in page tables for virtual range: 0x%010llX to 0x%010llX",
 	             ui32PageCount,
 	             (IMG_UINT64)sDevVAddr.uiAddr,
 	             ((IMG_UINT64)sDevVAddr.uiAddr) + (uiPageSize*ui32PageCount)-1);
 #endif
+
+	sDummyPgDevPhysAddr.uiAddr = psMMUContext->psDevNode->sDummyPage.ui64DummyPgPhysAddr;
 	bUnmap = (bDummyBacking)?IMG_FALSE:IMG_TRUE;
 	/* Get PT and address configs */
 	_MMU_GetPTConfig(psMMUContext, (IMG_UINT32) uiLog2PageSize,
@@ -2666,7 +3063,8 @@
 			/* Flush if we moved to another psLevel, i.e. page table */
 			if (psPrevLevel != NULL)
 			{
-				psMMUContext->psDevNode->pfnDevPxClean(&psPrevLevel->sMemDesc.psMapping->sMemHandle,
+				psMMUContext->psDevNode->pfnDevPxClean(psMMUContext->psDevNode,
+				                                       &psPrevLevel->sMemDesc.psMapping->sMemHandle,
 				                                       uiFlushStart * psConfig->uiBytesPerEntry + psPrevLevel->sMemDesc.uiOffset,
 				                                       (uiFlushEnd+1 - uiFlushStart) * psConfig->uiBytesPerEntry);
 			}
@@ -2686,7 +3084,7 @@
 		              (bDummyBacking)?&sDummyPgDevPhysAddr:&gsBadDevPhyAddr,
 		              bUnmap,
 #if defined(PDUMP)
-		              (bDummyBacking)?(psMMUContext->psDevNode->pszMMUPxPDumpMemSpaceName):NULL,
+		              (bDummyBacking)?(psMMUContext->psDevAttrs->pszMMUPxPDumpMemSpaceName):NULL,
 		              (bDummyBacking)?DUMMY_PAGE:NULL,
 		              0U,
 #endif
@@ -2704,7 +3102,8 @@
 	/* Flush the last level we touched */
 	if (psLevel != NULL)
 	{
-		psMMUContext->psDevNode->pfnDevPxClean(&psLevel->sMemDesc.psMapping->sMemHandle,
+		psMMUContext->psDevNode->pfnDevPxClean(psMMUContext->psDevNode,
+		                                       &psLevel->sMemDesc.psMapping->sMemHandle,
 		                                       uiFlushStart * psConfig->uiBytesPerEntry + psLevel->sMemDesc.uiOffset,
 		                                       (uiFlushEnd+1 - uiFlushStart) * psConfig->uiBytesPerEntry);
 	}
@@ -2735,7 +3134,7 @@
             const PMR *psPMR,
             IMG_DEVMEM_SIZE_T uiSizeBytes,
             PVRSRV_MEMALLOCFLAGS_T uiMappingFlags,
-            IMG_UINT8 uiLog2PageSize)
+            IMG_UINT32 uiLog2PageSize)
 {
 	PVRSRV_ERROR eError = PVRSRV_OK;
 	IMG_UINT32 uiCount, i;
@@ -2755,8 +3154,8 @@
 	IMG_UINT32 uiFlushStart = 0;
 
 #if defined(PDUMP)
-	IMG_CHAR aszMemspaceName[PMR_MAX_MEMSPACE_NAME_LENGTH_DEFAULT];
-	IMG_CHAR aszSymbolicAddress[PMR_MAX_SYMBOLIC_ADDRESS_LENGTH_DEFAULT];
+	IMG_CHAR aszMemspaceName[PHYSMEM_PDUMP_MEMSPACE_MAX_LENGTH];
+	IMG_CHAR aszSymbolicAddress[PHYSMEM_PDUMP_SYMNAME_MAX_LENGTH];
 	IMG_DEVMEM_OFFSET_T uiSymbolicAddrOffset;
 	IMG_UINT32 ui32MappedCount = 0;
 	PDUMPCOMMENT("Wire up Page Table entries to point to the Data Pages (%lld bytes)", uiSizeBytes);
@@ -2787,8 +3186,8 @@
 		{
 			/* Should allocation fail, clean-up here before exit */
 			PVR_DPF((PVR_DBG_ERROR, "Failed to allocate PMR device PFN state"));
-			eError = PVRSRV_ERROR_OUT_OF_MEMORY;			
-			OSFreeMem(psDevPAddr);			
+			eError = PVRSRV_ERROR_OUT_OF_MEMORY;
+			OSFreeMem(psDevPAddr);
 			goto e0;
 		}
     }
@@ -2852,18 +3251,26 @@
 	{
 #if defined(DEBUG)
 {
-			IMG_UINT32 ui32BitLength = FloorLog2(psDevPAddr[i].uiAddr);
-			if (ui32BitLength > RGX_FEATURE_PHYS_BUS_WIDTH )
-			{
-				PVR_DPF((PVR_DBG_ERROR,"_MMU_MapPage Failed. The physical address bitlength (%d) "
-				         "is greater than what the chip can handle (%d).",
-				         ui32BitLength, RGX_FEATURE_PHYS_BUS_WIDTH));
+	IMG_INT32	i32FeatureVal = 0;
+	IMG_UINT32 ui32BitLength = FloorLog2(psDevPAddr[i].uiAddr);
+	i32FeatureVal = psMMUContext->psDevNode->pfnGetDeviceFeatureValue(psMMUContext->psDevNode, \
+			RGX_FEATURE_PHYS_BUS_WIDTH_BIT_MASK);
+	do {
+		if(0 > i32FeatureVal)
+			break;
 
-				PVR_ASSERT(ui32BitLength <= RGX_FEATURE_PHYS_BUS_WIDTH );
-				eError = PVRSRV_ERROR_INVALID_PARAMS;
-				OSLockRelease(psMMUContext->hLock);
-				goto e1;
-			}
+		if (ui32BitLength > i32FeatureVal )
+		{
+			PVR_DPF((PVR_DBG_ERROR,"_MMU_MapPage Failed. The physical address bitlength (%d) "
+					"is greater than what the chip can handle (%d).",
+					ui32BitLength, i32FeatureVal));
+
+			PVR_ASSERT(ui32BitLength <= i32FeatureVal );
+			eError = PVRSRV_ERROR_INVALID_PARAMS;
+			OSLockRelease(psMMUContext->hLock);
+			goto e1;
+		}
+	}while(0);
 }
 #endif /*DEBUG*/
 #if defined(PDUMP)
@@ -2906,9 +3313,10 @@
 		}
 		else
 		{
-			eError = psMMUContext->psDevNode->pfnDevPxClean(&psLevel->sMemDesc.psMapping->sMemHandle,
-															uiFlushStart * psConfig->uiBytesPerEntry + psLevel->sMemDesc.uiOffset,
-															(uiPTEIndex+1 - uiFlushStart) * psConfig->uiBytesPerEntry);
+			eError = psMMUContext->psDevNode->pfnDevPxClean(psMMUContext->psDevNode,
+			                                                &psLevel->sMemDesc.psMapping->sMemHandle,
+			                                                uiFlushStart * psConfig->uiBytesPerEntry + psLevel->sMemDesc.uiOffset,
+			                                                (uiPTEIndex+1 - uiFlushStart) * psConfig->uiBytesPerEntry);
 			if (eError != PVRSRV_OK)
 				goto e2;
 
@@ -2968,7 +3376,7 @@
 MMU_UnmapPMRFast(MMU_CONTEXT *psMMUContext,
                  IMG_DEV_VIRTADDR sDevVAddrBase,
                  IMG_UINT32 ui32PageCount,
-                 IMG_UINT8 uiLog2PageSize)
+                 IMG_UINT32 uiLog2PageSize)
 {
 	IMG_UINT32 uiPTEIndex = 0, ui32Loop=0;
 	IMG_UINT32 uiPageSize = 1 << uiLog2PageSize;
@@ -3057,23 +3465,23 @@
 			IMG_FALSE);
 
 #if defined (PDUMP)
-	PDumpMMUDumpPxEntries(MMU_LEVEL_1,
-						  psMMUContext->psDevNode->pszMMUPxPDumpMemSpaceName,
-						  psLevel->sMemDesc.pvCpuVAddr,
-						  psLevel->sMemDesc.sDevPAddr,
-						  uiPTEIndex,
-						  1,
-						  NULL,
-						  NULL,
-						  0,
-						  psConfig->uiBytesPerEntry,
-						  psConfig->uiAddrLog2Align,
-						  psConfig->uiAddrShift,
-						  psConfig->uiAddrMask,
-						  psConfig->uiProtMask,
-						  psConfig->uiValidEnMask,
-						  0,
-						  psMMUContext->psDevAttrs->eMMUType);
+		PDumpMMUDumpPxEntries(MMU_LEVEL_1,
+		                      psMMUContext->psDevAttrs->pszMMUPxPDumpMemSpaceName,
+		                      psLevel->sMemDesc.pvCpuVAddr,
+		                      psLevel->sMemDesc.sDevPAddr,
+		                      uiPTEIndex,
+		                      1,
+		                      NULL,
+		                      NULL,
+		                      0,
+		                      psConfig->uiBytesPerEntry,
+		                      psConfig->uiAddrLog2Align,
+		                      psConfig->uiAddrShift,
+		                      psConfig->uiAddrMask,
+		                      psConfig->uiProtMask,
+		                      psConfig->uiValidEnMask,
+		                      0,
+		                      psMMUContext->psDevAttrs->eMMUType);
 #endif /*PDUMP*/
 
 		sDevVAddr.uiAddr += uiPageSize;
@@ -3086,9 +3494,10 @@
 		}
 		else
 		{
-			psMMUContext->psDevNode->pfnDevPxClean(&psLevel->sMemDesc.psMapping->sMemHandle,
-												   uiFlushStart * psConfig->uiBytesPerEntry + psLevel->sMemDesc.uiOffset,
-												   (uiPTEIndex+1 - uiFlushStart) * psConfig->uiBytesPerEntry);
+			psMMUContext->psDevNode->pfnDevPxClean(psMMUContext->psDevNode,
+			                                       &psLevel->sMemDesc.psMapping->sMemHandle,
+			                                       uiFlushStart * psConfig->uiBytesPerEntry + psLevel->sMemDesc.uiOffset,
+			                                       (uiPTEIndex+1 - uiFlushStart) * psConfig->uiBytesPerEntry);
 
 			_MMU_GetPTInfo(psMMUContext, sDevVAddr, psDevVAddrConfig,
 						   &psLevel, &uiPTEIndex);
@@ -3141,8 +3550,8 @@
 	IMG_BOOL bValid;
 
 #if defined(PDUMP)
-	IMG_CHAR aszMemspaceName[PMR_MAX_MEMSPACE_NAME_LENGTH_DEFAULT];
-	IMG_CHAR aszSymbolicAddress[PMR_MAX_SYMBOLIC_ADDRESS_LENGTH_DEFAULT];
+	IMG_CHAR aszMemspaceName[PHYSMEM_PDUMP_MEMSPACE_MAX_LENGTH];
+	IMG_CHAR aszSymbolicAddress[PHYSMEM_PDUMP_SYMNAME_MAX_LENGTH];
 	IMG_DEVMEM_OFFSET_T uiSymbolicAddrOffset;
 	IMG_DEVMEM_OFFSET_T uiNextSymName;
 
@@ -3172,7 +3581,13 @@
 		if (bMakeValid == IMG_TRUE)
 		{
 			/* Only set valid if physical address exists (sparse allocs might have none)*/
-			PMR_IsOffsetValid(psPMR, i<<uiLog2PageSize, &bValid);
+			eError = PMR_IsOffsetValid(psPMR, uiLog2PageSize, 1, i<<uiLog2PageSize, &bValid);
+			if (eError != PVRSRV_OK)
+			{
+				PVR_DPF((PVR_DBG_ERROR, "Cannot determine validity of page table entries page"));
+				goto e_exit;
+			}
+
 			if (bValid)
 			{
 				if (psConfig->uiBytesPerEntry == 8)
@@ -3210,30 +3625,29 @@
 		}
 
 #if defined(PDUMP)
-
 		PMR_PDumpSymbolicAddr(psPMR, i<<uiLog2PageSize,
-							   sizeof(aszMemspaceName), &aszMemspaceName[0],
-							   sizeof(aszSymbolicAddress), &aszSymbolicAddress[0],
-							   &uiSymbolicAddrOffset,
-							   &uiNextSymName);
+		                      sizeof(aszMemspaceName), &aszMemspaceName[0],
+		                      sizeof(aszSymbolicAddress), &aszSymbolicAddress[0],
+		                      &uiSymbolicAddrOffset,
+		                      &uiNextSymName);
 
 		PDumpMMUDumpPxEntries(MMU_LEVEL_1,
-							  psMMUContext->psDevNode->pszMMUPxPDumpMemSpaceName,
-							  psLevel->sMemDesc.pvCpuVAddr,
-							  psLevel->sMemDesc.sDevPAddr,
-							  uiPTIndex,
-							  1,
-							  aszMemspaceName,
-							  aszSymbolicAddress,
-							  uiSymbolicAddrOffset,
-							  psConfig->uiBytesPerEntry,
-							  psConfig->uiAddrLog2Align,
-							  psConfig->uiAddrShift,
-							  psConfig->uiAddrMask,
-							  psConfig->uiProtMask,
-							  psConfig->uiValidEnMask,
-							  0,
-							  psMMUContext->psDevAttrs->eMMUType);
+		                      psMMUContext->psDevAttrs->pszMMUPxPDumpMemSpaceName,
+		                      psLevel->sMemDesc.pvCpuVAddr,
+		                      psLevel->sMemDesc.sDevPAddr,
+		                      uiPTIndex,
+		                      1,
+		                      aszMemspaceName,
+		                      aszSymbolicAddress,
+		                      uiSymbolicAddrOffset,
+		                      psConfig->uiBytesPerEntry,
+		                      psConfig->uiAddrLog2Align,
+		                      psConfig->uiAddrShift,
+		                      psConfig->uiAddrMask,
+		                      psConfig->uiProtMask,
+		                      psConfig->uiValidEnMask,
+		                      0,
+		                      psMMUContext->psDevAttrs->eMMUType);
 #endif /*PDUMP*/
 
 		sDevVAddr.uiAddr += uiPageSize;
@@ -3247,9 +3661,10 @@
 		else
 		{
 
-			eError = psMMUContext->psDevNode->pfnDevPxClean(&psLevel->sMemDesc.psMapping->sMemHandle,
-															uiFlushStart * psConfig->uiBytesPerEntry + psLevel->sMemDesc.uiOffset,
-															(uiPTIndex+1 - uiFlushStart) * psConfig->uiBytesPerEntry);
+			eError = psMMUContext->psDevNode->pfnDevPxClean(psMMUContext->psDevNode,
+			                                                &psLevel->sMemDesc.psMapping->sMemHandle,
+			                                                uiFlushStart * psConfig->uiBytesPerEntry + psLevel->sMemDesc.uiOffset,
+			                                                (uiPTIndex+1 - uiFlushStart) * psConfig->uiBytesPerEntry);
 			if (eError != PVRSRV_OK)
 				goto e_exit;
 
@@ -3309,20 +3724,22 @@
     MMU_SetOSid, MMU_GetOSid
 */
 
-void MMU_SetOSids(MMU_CONTEXT *psMMUContext, IMG_UINT32 ui32OSid, IMG_UINT32 ui32OSidReg)
+void MMU_SetOSids(MMU_CONTEXT *psMMUContext, IMG_UINT32 ui32OSid, IMG_UINT32 ui32OSidReg, IMG_BOOL bOSidAxiProt)
 {
-	psMMUContext->ui32OSid = ui32OSid;
-	psMMUContext->ui32OSidReg = ui32OSidReg;
+    psMMUContext->ui32OSid     = ui32OSid;
+    psMMUContext->ui32OSidReg  = ui32OSidReg;
+    psMMUContext->bOSidAxiProt = bOSidAxiProt;
 
     return ;
 }
 
-void MMU_GetOSids(MMU_CONTEXT *psMMUContext, IMG_UINT32 *pui32OSid, IMG_UINT32 *pui32OSidReg)
+void MMU_GetOSids(MMU_CONTEXT *psMMUContext, IMG_UINT32 *pui32OSid, IMG_UINT32 *pui32OSidReg, IMG_BOOL *pbOSidAxiProt)
 {
-	*pui32OSid = psMMUContext->ui32OSid;
-	*pui32OSidReg = psMMUContext->ui32OSidReg;
+    *pui32OSid     = psMMUContext->ui32OSid;
+    *pui32OSidReg  = psMMUContext->ui32OSidReg;
+    *pbOSidAxiProt = psMMUContext->bOSidAxiProt;
 
-	return ;
+    return ;
 }
 
 #endif
@@ -3353,7 +3770,7 @@
 
 	/*
 		At this point we don't know the page size so assume it's 4K.
-		When we get the the PD level (MMU_LEVEL_2) we can check to see
+		When we get the PD level (MMU_LEVEL_2) we can check to see
 		if this assumption is correct.
 	*/
 	eError = psDevAttrs->pfnGetPageSizeConfiguration(12,
@@ -3611,7 +4028,7 @@
                          psDevId->pszPDumpDevName,
                          psMMUContext->sBaseLevelInfo.sMemDesc.bValid?"MMUPC_":"XXX",
                          ui64PhysAddr);
-    
+
     if (uiCount + 1 > uiPDumpSymbolicNameBufferSize)
     {
         return PVRSRV_ERROR_INVALID_PARAMS;
@@ -3630,28 +4047,27 @@
                           IMG_UINT32 ui32WordSize,
                           IMG_UINT32 ui32AlignShift,
                           IMG_UINT32 ui32Shift,
-						  PDUMP_FLAGS_T uiPdumpFlags)
+                          PDUMP_FLAGS_T uiPdumpFlags)
 {
-    PVRSRV_ERROR eError;
-    IMG_CHAR aszPageCatBaseSymbolicAddr[100];
-	const IMG_CHAR *pszPDumpDevName = psMMUContext->psDevNode->pszMMUPxPDumpMemSpaceName;
-
+	PVRSRV_ERROR eError;
+	IMG_CHAR aszPageCatBaseSymbolicAddr[100];
+	const IMG_CHAR *pszPDumpDevName = psMMUContext->psDevAttrs->pszMMUPxPDumpMemSpaceName;
 
 	eError = MMU_ContextDerivePCPDumpSymAddr(psMMUContext,
                                              &aszPageCatBaseSymbolicAddr[0],
                                              sizeof(aszPageCatBaseSymbolicAddr));
-    if (eError ==  PVRSRV_OK)
-    {
+	if (eError ==  PVRSRV_OK)
+	{
 		eError = PDumpWriteSymbAddress(pszSpaceName,
-										   uiOffset,
-										   aszPageCatBaseSymbolicAddr,
-										   0, /* offset -- Could be non-zero for var. pgsz */
-										   pszPDumpDevName,
-										   ui32WordSize,
-										   ui32AlignShift,
-										   ui32Shift,
-										   uiPdumpFlags | PDUMP_FLAGS_CONTINUOUS);
-    }
+		                               uiOffset,
+		                               aszPageCatBaseSymbolicAddr,
+		                               0, /* offset -- Could be non-zero for var. pgsz */
+		                               pszPDumpDevName,
+		                               ui32WordSize,
+		                               ui32AlignShift,
+		                               ui32Shift,
+		                               uiPdumpFlags | PDUMP_FLAGS_CONTINUOUS);
+	}
 
     return eError;
 }
@@ -3680,7 +4096,7 @@
 
 /*
 	MMU_ReleasePDumpMMUContext
-*/ 
+*/
 PVRSRV_ERROR MMU_ReleasePDumpMMUContext(MMU_CONTEXT *psMMUContext)
 {
 	PVRSRV_DEVICE_IDENTIFIER *psDevId = &psMMUContext->psDevNode->sDevId;
diff --git a/drivers/staging/imgtec/rogue/mmu_common.h b/drivers/staging/imgtec/rogue/mmu_common.h
index 84e481f..32483b6 100644
--- a/drivers/staging/imgtec/rogue/mmu_common.h
+++ b/drivers/staging/imgtec/rogue/mmu_common.h
@@ -116,6 +116,8 @@
 {
 	PDUMP_MMU_TYPE eMMUType;
 
+	IMG_CHAR *pszMMUPxPDumpMemSpaceName;
+
 	/*! The type of the top level object */
 	MMU_LEVEL eTopLevel;
 
@@ -321,7 +323,7 @@
            IMG_UINT32 uiProtFlags,
            IMG_DEVMEM_SIZE_T uDevVAddrAlignment,
            IMG_DEV_VIRTADDR *psDevVAddr,
-           IMG_UINT8 uiLog2PageSize);
+           IMG_UINT32 uiLog2PageSize);
 
 
 /*************************************************************************/ /*!
@@ -382,7 +384,7 @@
              IMG_UINT32 ui32PhysPgOffset,
              IMG_UINT32 ui32MapPageCount,
              IMG_UINT32 *paui32MapIndices,
-             IMG_UINT8 uiLog2PageSize);
+             IMG_UINT32 uiLog2PageSize);
 
 /*************************************************************************/ /*!
 @Function       MMU_UnmapPages
@@ -415,7 +417,7 @@
                 IMG_DEV_VIRTADDR sDevVAddr,
                 IMG_UINT32 ui32PageCount,
                 IMG_UINT32 *pai32UnmapIndicies,
-                IMG_UINT8 uiLog2PageSize,
+                IMG_UINT32 uiLog2PageSize,
                 IMG_BOOL bDummyBacking);
 
 /*************************************************************************/ /*!
@@ -445,7 +447,7 @@
                 const PMR *psPMR,
                 IMG_DEVMEM_SIZE_T uiSizeBytes,
                 PVRSRV_MEMALLOCFLAGS_T uiMappingFlags,
-                IMG_UINT8 uiLog2PageSize);
+                IMG_UINT32 uiLog2PageSize);
 
 /*************************************************************************/ /*!
 @Function       MMU_UnmapPMRFast
@@ -468,7 +470,7 @@
 MMU_UnmapPMRFast(MMU_CONTEXT *psMMUContext,
                  IMG_DEV_VIRTADDR sDevVAddrBase,
                  IMG_UINT32 ui32PageCount,
-                 IMG_UINT8 uiLog2PageSize);
+                 IMG_UINT32 uiLog2PageSize);
 
 /*************************************************************************/ /*!
 @Function       MMU_ChangeValidity
@@ -546,28 +548,34 @@
 
 @Input			ui32OSidReg				The value that the firmware will assign to the
 										registers.
+
+@Input          bOSidAxiProt            Toggles whether the AXI prot bit will be set or
+                                        not.
 @Return None
 */
 /***********************************************************************************/
 
-void MMU_SetOSids(MMU_CONTEXT *psMMUContext, IMG_UINT32 ui32OSid, IMG_UINT32 ui32OSidReg);
+void MMU_SetOSids(MMU_CONTEXT *psMMUContext, IMG_UINT32 ui32OSid, IMG_UINT32 ui32OSidReg, IMG_BOOL bOSidAxiProt);
 
 /***********************************************************************************/ /*!
 @Function       MMU_GetOSid
 
 @Description    Retrieve the OSid associated with the MMU context.
 
-@Input          psMMUContext            MMU context to store the OSid on
+@Input          psMMUContext            MMU context in which the OSid is stored
 
-@Output			ui32OSid                the OSid in question
+@Output			pui32OSid               The OSid in question
 
-@Output			ui32OSidReg				The OSid that the firmware will assign to the
-										registers
+@Output			pui32OSidReg            The OSid that the firmware will assign to the
+                                        registers.
+
+@Output         pbOSidAxiProt           Toggles whether the AXI prot bit will be set or
+                                        not.
 @Return None
 */
 /***********************************************************************************/
 
-void MMU_GetOSids(MMU_CONTEXT *psMMUContext, IMG_UINT32 * pui32OSid, IMG_UINT32 * pui32OSidReg);
+void MMU_GetOSids(MMU_CONTEXT *psMMUContext, IMG_UINT32 * pui32OSid, IMG_UINT32 * pui32OSidReg, IMG_BOOL *pbOSidAxiProt);
 #endif
 
 /*************************************************************************/ /*!
diff --git a/drivers/staging/imgtec/rogue/module_common.c b/drivers/staging/imgtec/rogue/module_common.c
index c399e58..edee32c 100644
--- a/drivers/staging/imgtec/rogue/module_common.c
+++ b/drivers/staging/imgtec/rogue/module_common.c
@@ -40,13 +40,6 @@
 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */ /**************************************************************************/
 
-#include <linux/version.h>
-
-#if (!defined(LDM_PLATFORM) && !defined(LDM_PCI)) || \
-	(defined(LDM_PLATFORM) && defined(LDM_PCI))
-	#error "LDM_PLATFORM or LDM_PCI must be defined"
-#endif
-
 #include <linux/module.h>
 
 #include "pvr_debugfs.h"
@@ -59,10 +52,8 @@
 #include "module_common.h"
 #include "pvrsrv.h"
 #include "pvr_hwperf.h"
-
-#if defined(SUPPORT_DRM)
-#include "pvr_drm.h"
-#endif
+#include "pvr_drv.h"
+#include <linux/moduleparam.h>
 
 #if defined(SUPPORT_NATIVE_FENCE_SYNC)
 #include "pvr_sync.h"
@@ -77,321 +68,130 @@
 #endif
 
 #if defined(SUPPORT_KERNEL_SRVINIT)
+#include "km_apphint.h"
 #include "srvinit.h"
 #endif
 
-#if defined(PVRSRV_NEED_PVR_DPF) || defined(DEBUG)
-#include <linux/moduleparam.h>
-#endif /* defined(PVRSRV_NEED_PVR_DPF) || defined(DEBUG) */
+#if defined(SUPPORT_PVRSRV_GPUVIRT)
+#if !defined(PVRSRV_GPUVIRT_GUESTDRV)
+#include "vmm_pvz_server.h"
+#if defined(PVRSRV_GPUVIRT_MULTIDRV_MODEL)
+#include "vmm_pvz_mdm.h"
+#endif
+#endif
+#endif
 
 #if defined(PVRSRV_NEED_PVR_DPF)
 extern IMG_UINT32 gPVRDebugLevel;
 module_param(gPVRDebugLevel, uint, 0644);
-MODULE_PARM_DESC(gPVRDebugLevel, "Sets the level of debug output (default 0x7)");
+MODULE_PARM_DESC(gPVRDebugLevel,
+				 "Sets the level of debug output (default 0x7)");
 #endif /* defined(PVRSRV_NEED_PVR_DPF) */
 
 #if defined(DEBUG)
 extern IMG_UINT32 gPMRAllocFail;
 module_param(gPMRAllocFail, uint, 0644);
 MODULE_PARM_DESC(gPMRAllocFail, "When number of PMR allocs reaches"
-        " this value, it will fail (default value is 0 which"
-        "means that alloc function will behave normally).");
+				 " this value, it will fail (default value is 0 which"
+				 "means that alloc function will behave normally).");
 #endif /* defined(DEBUG) */
 
-#if defined(PVRSRV_GPUVIRT_GUESTDRV) && defined(PVRSRV_GPUVIRT_MULTIDRV_MODEL)
-/* 
- * Kernel symbol clash if re-exported by guest drivers in multi-driver model
- */
-#else
-/* 
+#if !defined(SUPPORT_KERNEL_SRVINIT)
+extern unsigned int gui32RGXLoadTimeDevCount;
+
+extern char *gazRGXBVNCList[PVRSRV_MAX_DEVICES];
+module_param_array_named(RGXBVNC, gazRGXBVNCList, charp, &gui32RGXLoadTimeDevCount, S_IRUGO);
+MODULE_PARM_DESC(RGXBVNC, "Array of comma separated strings that define BVNC info of the devices. "
+		"module parameter usage is RGXBVNC=x.x.x.x,y.y.y.y etc");
+#endif
+
+#if defined(SUPPORT_DISPLAY_CLASS)
+/* Display class interface */
+#include "kerneldisplay.h"
+EXPORT_SYMBOL(DCRegisterDevice);
+EXPORT_SYMBOL(DCUnregisterDevice);
+EXPORT_SYMBOL(DCDisplayConfigurationRetired);
+EXPORT_SYMBOL(DCDisplayHasPendingCommand);
+EXPORT_SYMBOL(DCImportBufferAcquire);
+EXPORT_SYMBOL(DCImportBufferRelease);
+
+/* Physmem interface (required by LMA DC drivers) */
+#include "physheap.h"
+EXPORT_SYMBOL(PhysHeapAcquire);
+EXPORT_SYMBOL(PhysHeapRelease);
+EXPORT_SYMBOL(PhysHeapGetType);
+EXPORT_SYMBOL(PhysHeapRegionGetCpuPAddr);
+EXPORT_SYMBOL(PhysHeapRegionGetSize);
+EXPORT_SYMBOL(PhysHeapCpuPAddrToDevPAddr);
+
+EXPORT_SYMBOL(PVRSRVSystemInstallDeviceLISR);
+EXPORT_SYMBOL(PVRSRVSystemUninstallDeviceLISR);
+#endif
+
+/* Host para-virtz call handlers  (required by guest drivers) */
+#if defined(PVRSRV_GPUVIRT_MULTIDRV_MODEL)
+#if !defined(PVRSRV_GPUVIRT_GUESTDRV)
+EXPORT_SYMBOL(PvzServerCreateDevConfig);
+EXPORT_SYMBOL(PvzServerDestroyDevConfig);
+EXPORT_SYMBOL(PvzServerCreateDevConfig2);
+EXPORT_SYMBOL(PvzServerDestroyDevConfig2);
+EXPORT_SYMBOL(PvzServerCreateDevPhysHeaps);
+EXPORT_SYMBOL(PvzServerDestroyDevPhysHeaps);
+EXPORT_SYMBOL(PvzServerMapDevPhysHeap);
+EXPORT_SYMBOL(PvzServerUnmapDevPhysHeap);
+EXPORT_SYMBOL(PvzServerCreateDevPhysHeaps2);
+EXPORT_SYMBOL(PvzServerDestroyDevPhysHeaps2);
+#endif
+#endif
+
+#if !(defined(PVRSRV_GPUVIRT_GUESTDRV) && defined(PVRSRV_GPUVIRT_MULTIDRV_MODEL))
+#include "pvr_notifier.h"
+
+/*
  * Export some symbols that may be needed by other drivers
- * 
+ *
  * When support for GPU virtualization is present and the multi-driver
- * model (multi-drivers in same OS instance) is being used, then only
- * the hyperv driver is a true device drivers (i.e. is registered with
+ * model (multiple drivers in same OS kernel) is being used, then only
+ * the host driver is a true device drivers (i.e. is registered with
  * the kernel to manage the physical device), the other guest drivers
  * are all modules.
  */
 EXPORT_SYMBOL(PVRSRVCheckStatus);
+EXPORT_SYMBOL(PVRSRVGetDriverStatus);
 EXPORT_SYMBOL(PVRSRVGetErrorStringKM);
 
 #include "rgxapi_km.h"
+#if defined(SUPPORT_SHARED_SLC) && !defined(PVRSRV_GPUVIRT_GUESTDRV)
+/* Guest drivers do not perform device management so RGXInitSLC is absent */
+EXPORT_SYMBOL(RGXInitSLC);
+#endif
+
 EXPORT_SYMBOL(RGXHWPerfConnect);
 EXPORT_SYMBOL(RGXHWPerfDisconnect);
 EXPORT_SYMBOL(RGXHWPerfControl);
 EXPORT_SYMBOL(RGXHWPerfConfigureAndEnableCounters);
 EXPORT_SYMBOL(RGXHWPerfDisableCounters);
-EXPORT_SYMBOL(RGXHWPerfAcquireData);
-EXPORT_SYMBOL(RGXHWPerfReleaseData);
+EXPORT_SYMBOL(RGXHWPerfAcquireEvents);
+EXPORT_SYMBOL(RGXHWPerfReleaseEvents);
+EXPORT_SYMBOL(RGXHWPerfConvertCRTimeStamp);
+#if defined(SUPPORT_KERNEL_HWPERF_TEST)
+EXPORT_SYMBOL(OSAddTimer);
+EXPORT_SYMBOL(OSEnableTimer);
+EXPORT_SYMBOL(OSDisableTimer);
+EXPORT_SYMBOL(OSRemoveTimer);
 #endif
-
-DEFINE_MUTEX(gPVRSRVLock);
-
-#if defined(PVRSRV_GPUVIRT_GUESTDRV) && defined(PVRSRV_GPUVIRT_MULTIDRV_MODEL)
-/* Functionality is n/a for guest drivers in multi-driver model */
-#else
-static DEFINE_MUTEX(gsPMMutex);
-static IMG_BOOL bDriverIsSuspended;
-static IMG_BOOL bDriverIsShutdown;
-
-#if !defined(SUPPORT_DRM_EXT)
-LDM_DEV *gpsPVRLDMDev;
 #endif
 
-DEFINE_MUTEX(gGlobalLookupPMRLock);
-
-/*!
-******************************************************************************
-
- @Function		PVRSRVDriverShutdown
-
- @Description
-
- Suspend device operation for system shutdown.  This is called as part of the
- system halt/reboot process.  The driver is put into a quiescent state by
- setting the power state to D3.
-
- @input pDevice - the device for which shutdown is requested
-
- @Return nothing
-
-*****************************************************************************/
-void PVRSRVDriverShutdown(LDM_DEV *pDevice)
-{
-	PVR_TRACE(("PVRSRVDriverShutdown (pDevice=%p)", pDevice));
-
-	mutex_lock(&gsPMMutex);
-
-	if (!bDriverIsShutdown && !bDriverIsSuspended)
-	{
-		/*
-		 * Take the bridge mutex, and never release it, to stop
-		 * processes trying to use the driver after it has been
-		 * shutdown.
-		 */
-		OSAcquireBridgeLock();
-
-		(void) PVRSRVSetPowerStateKM(PVRSRV_SYS_POWER_STATE_OFF, IMG_TRUE);
-	}
-
-	bDriverIsShutdown = IMG_TRUE;
-
-	/* The bridge mutex is held on exit */
-	mutex_unlock(&gsPMMutex);
-}
-
-/*!
-******************************************************************************
-
- @Function		PVRSRVDriverSuspend
-
- @Description
-
- Suspend device operation.
-
- @input pDevice - the device for which resume is requested
-
- @Return 0 for success or <0 for an error.
-
-*****************************************************************************/
-int PVRSRVDriverSuspend(struct device *pDevice)
-{
-	int res = 0;
-
-	PVR_TRACE(( "PVRSRVDriverSuspend (pDevice=%p)", pDevice));
-
-	mutex_lock(&gsPMMutex);
-
-	if (!bDriverIsSuspended && !bDriverIsShutdown)
-	{
-		OSAcquireBridgeLock();
-
-		if (PVRSRVSetPowerStateKM(PVRSRV_SYS_POWER_STATE_OFF, IMG_TRUE) == PVRSRV_OK)
-		{
-			bDriverIsSuspended = IMG_TRUE;
-			OSSetDriverSuspended();
-		}
-		else
-		{
-			res = -EINVAL;
-		}
-		OSReleaseBridgeLock();
-	}
-
-	mutex_unlock(&gsPMMutex);
-
-	return res;
-}
-
-/*!
-******************************************************************************
-
- @Function		PVRSRVDriverResume
-
- @Description
-
- Resume device operation.
-
- @input pDevice - the device for which resume is requested
-
- @Return 0 for success or <0 for an error.
-
-*****************************************************************************/
-int PVRSRVDriverResume(struct device *pDevice)
-{
-	int res = 0;
-
-	PVR_TRACE(("PVRSRVDriverResume (pDevice=%p)", pDevice));
-
-	mutex_lock(&gsPMMutex);
-
-	if (bDriverIsSuspended && !bDriverIsShutdown)
-	{
-		OSAcquireBridgeLock();
-
-		if (PVRSRVSetPowerStateKM(PVRSRV_SYS_POWER_STATE_ON, IMG_TRUE) == PVRSRV_OK)
-		{
-			bDriverIsSuspended = IMG_FALSE;
-			OSClearDriverSuspended();
-		}
-		else
-		{
-			res = -EINVAL;
-		}
-		OSReleaseBridgeLock();
-	}
-
-	mutex_unlock(&gsPMMutex);
-
-	return res;
-}
-#endif /* defined(PVRSRV_GPUVIRT_GUESTDRV) && defined(PVRSRV_GPUVIRT_MULTIDRV_MODEL) */
-
-#if defined(SUPPORT_DRM)
-#define PRIVATE_DATA(pFile) (PVR_DRM_FILE_FROM_FILE(pFile)->driver_priv)
-#else
-#define PRIVATE_DATA(pFile) ((pFile)->private_data)
-#endif
-
-static void *PVRSRVFindRGXDevNode(PVRSRV_DEVICE_NODE *psDevNode)
-{
-	if (psDevNode->sDevId.eDeviceType == PVRSRV_DEVICE_TYPE_RGX)
-	{
-		return psDevNode;
-	}
-
-	return NULL;
-}
-
-/*!
-******************************************************************************
-
- @Function		PVRSRVCommonOpen
-
- @Description
-
- Open the PVR services node.
-
- @input pFile - the file handle data for the actual file being opened
-
- @Return 0 for success or <0 for an error.
-
-*****************************************************************************/
-int PVRSRVCommonOpen(struct file *pFile)
-{
-	PVRSRV_DATA *psPVRSRVData = PVRSRVGetPVRSRVData();
-	ENV_CONNECTION_PRIVATE_DATA sPrivData;
-	void *pvConnectionData;
-	PVRSRV_ERROR eError;
-	int iErr;
-
-	OSAcquireBridgeLock();
-
-	if (!psPVRSRVData)
-	{
-		PVR_DPF((PVR_DBG_ERROR, "%s: No device data", __func__));
-		iErr = -ENODEV;
-		goto ErrorUnlock;
-	}
-
-#if defined(SUPPORT_KERNEL_SRVINIT)
-	eError = SrvInit();
-	if (eError != PVRSRV_OK)
-	{
-		PVR_DPF((PVR_DBG_ERROR, "%s: SrvInit failed (%d)", __func__, eError));
-		iErr = -ENODEV;
-		goto ErrorUnlock;
-	}
-#endif
-
-	sPrivData.psDevNode = List_PVRSRV_DEVICE_NODE_Any(psPVRSRVData->psDeviceNodeList,
-							  PVRSRVFindRGXDevNode);
-	if (!sPrivData.psDevNode)
-	{
-		PVR_DPF((PVR_DBG_ERROR, "%s: Failed to get device node", __func__));
-		iErr = -ENODEV;
-		goto ErrorUnlock;
-	}
-
-	sPrivData.psFile = pFile;
-
-	/*
-	 * Here we pass the file pointer which will passed through to our
-	 * OSConnectionPrivateDataInit function where we can save it so
-	 * we can back reference the file structure from it's connection
-	 */
-	eError = PVRSRVConnectionConnect(&pvConnectionData, (void *) &sPrivData);
-	if (eError != PVRSRV_OK)
-	{
-		iErr = -ENOMEM;
-		goto ErrorUnlock;
-	}
-
-	PRIVATE_DATA(pFile) = pvConnectionData;
-	OSReleaseBridgeLock();
-
-	return 0;
-
-ErrorUnlock:
-	OSReleaseBridgeLock();
-	return iErr;
-}
-
-/*!
-******************************************************************************
-
- @Function		PVRSRVCommonRelease
-
- @Description
-
- Release access the PVR services node - called when a file is closed, whether
- at exit or using close(2) system call.
-
- @input pFile - the file handle data for the actual file being released
-
- @Return 0 for success or <0 for an error.
-
-*****************************************************************************/
-void PVRSRVCommonRelease(struct file *pFile)
-{
-	void *pvConnectionData;
-
-	OSAcquireBridgeLock();
-
-	pvConnectionData = PRIVATE_DATA(pFile);
-	if (pvConnectionData)
-	{
-		PVRSRVConnectionDisconnect(pvConnectionData);
-		PRIVATE_DATA(pFile) = NULL;
-	}
-
-	OSReleaseBridgeLock();
-}
-
-
 CONNECTION_DATA *LinuxConnectionFromFile(struct file *pFile)
 {
-	return (pFile)? PRIVATE_DATA(pFile): NULL;
+	if (pFile)
+	{
+		struct drm_file *psDRMFile = pFile->private_data;
+
+		return psDRMFile->driver_priv;
+	}
+
+	return NULL;
 }
 
 struct file *LinuxFileFromConnection(CONNECTION_DATA *psConnection)
@@ -404,19 +204,24 @@
 	return psEnvConnection->psFile;
 }
 
-/*!
-*****************************************************************************
-
- @Function		PVRSRVDriverInit
-
- @Description	Do the driver-specific initialisation (as opposed to
-              the device-specific initialisation.)
-
-*****************************************************************************/
-int PVRSRVDriverInit(void)
+/**************************************************************************/ /*!
+@Function     PVRSRVCommonDriverInit
+@Description  Common one time driver initialisation
+@Return       int           0 on success and a Linux error code otherwise
+*/ /***************************************************************************/
+int PVRSRVCommonDriverInit(void)
 {
+	PVRSRV_ERROR pvrerr;
 	int error = 0;
 
+#if defined(PDUMP)
+	error = dbgdrv_init();
+	if (error != 0)
+	{
+		return error;
+	}
+#endif
+
 	error = PVRDebugFSInit();
 	if (error != 0)
 	{
@@ -437,19 +242,38 @@
 
 	LinuxBridgeInit();
 
+#if defined(SUPPORT_KERNEL_SRVINIT)
+	error = pvr_apphint_init();
+	if (error != 0)
+	{
+		PVR_DPF((PVR_DBG_WARNING,
+			 "%s: failed AppHint setup(%d)",
+			 __func__, error));
+	}
+#endif
+
+	pvrerr = PVRSRVDriverInit();
+	if (pvrerr != PVRSRV_OK)
+	{
+		return -ENODEV;
+	}
+
 	return 0;
 }
 
-/*!
-*****************************************************************************
-
- @Function		PVRSRVDriverDeinit
-
- @Description	Unwind PVRSRVDriverInit
-
-*****************************************************************************/
-void PVRSRVDriverDeinit(void)
+/**************************************************************************/ /*!
+@Function     PVRSRVCommonDriverDeinit
+@Description  Common one time driver de-initialisation
+@Return       void
+*/ /***************************************************************************/
+void PVRSRVCommonDriverDeinit(void)
 {
+	PVRSRVDriverDeInit();
+
+#if defined(SUPPORT_KERNEL_SRVINIT)
+	pvr_apphint_deinit();
+#endif
+
 	LinuxBridgeDeInit();
 
 	PVROSFuncDeInit();
@@ -458,38 +282,47 @@
 	PVRSRVStatsDestroy();
 #endif
 	PVRDebugFSDeInit();
+
+#if defined(PDUMP)
+	dbgdrv_cleanup();
+#endif
 }
 
-/*!
-*****************************************************************************
-
- @Function		PVRSRVDeviceInit
-
- @Description	Do the initialisation we have to do after registering the device
-
-*****************************************************************************/
-int PVRSRVDeviceInit(void)
+/**************************************************************************/ /*!
+@Function     PVRSRVCommonDeviceInit
+@Description  Common device related initialisation.
+@Input        psDeviceNode  The device node for which initialisation should be
+                            performed
+@Return       int           0 on success and a Linux error code otherwise
+*/ /***************************************************************************/
+int PVRSRVCommonDeviceInit(PVRSRV_DEVICE_NODE *psDeviceNode)
 {
 	int error = 0;
+	PVRSRV_RGXDEV_INFO *psDevInfo = (PVRSRV_RGXDEV_INFO *) psDeviceNode->pvDevice;
 
 #if defined(SUPPORT_NATIVE_FENCE_SYNC)
 	{
-		PVRSRV_ERROR eError = pvr_sync_init();
+		PVRSRV_ERROR eError = pvr_sync_init(psDeviceNode);
 		if (eError != PVRSRV_OK)
 		{
-			PVR_DPF((PVR_DBG_ERROR, "PVRCore_Init: unable to create sync (%d)", eError));
+			PVR_DPF((PVR_DBG_ERROR, "%s: unable to create sync (%d)",
+					 __func__, eError));
 			return -EBUSY;
 		}
 	}
 #endif
 
 #if defined(SUPPORT_BUFFER_SYNC)
-	error = pvr_buffer_sync_init();
-	if (error != 0)
+	psDeviceNode->psBufferSyncContext =
+		pvr_buffer_sync_context_create(psDeviceNode);
+	if (IS_ERR(psDeviceNode->psBufferSyncContext))
 	{
+		error = PTR_ERR(psDeviceNode->psBufferSyncContext);
+		psDeviceNode->psBufferSyncContext = NULL;
+
 		PVR_DPF((PVR_DBG_ERROR,
-			 "%s: unable to initialise buffer_sync support (%d)",
-			 __func__, error));
+				 "%s: unable to initialise buffer_sync support (%d)",
+				 __func__, error));
 		return error;
 	}
 #endif
@@ -497,41 +330,262 @@
 	error = PVRDebugCreateDebugFSEntries();
 	if (error != 0)
 	{
-		PVR_DPF((PVR_DBG_WARNING, "PVRCore_Init: failed to create default debugfs entries (%d)", error));
+		PVR_DPF((PVR_DBG_WARNING,
+			 "%s: failed to create default debugfs entries (%d)",
+			 __func__, error));
 	}
 
+#if defined(SUPPORT_GPUTRACE_EVENTS)
+	error = PVRGpuTraceInit(psDeviceNode);
+	if (error != 0)
+	{
+		PVR_DPF((PVR_DBG_WARNING,
+			 "%s: failed to initialise PVR GPU Tracing (%d)",
+			 __func__, error));
+	}
+#endif
+
+#if defined(SUPPORT_KERNEL_SRVINIT)
+	/* register the AppHint device control before device initialisation
+	 * so individual AppHints can be configured during the init phase
+	 */
+	error = pvr_apphint_device_register(psDeviceNode);
+	if (error != 0)
+	{
+		PVR_DPF((PVR_DBG_WARNING,
+			 "%s: failed to initialise device AppHints (%d)",
+			 __func__, error));
+	}
+#else
 	error = PVRSRVHWperfCreateDebugFs();
 	if (error != 0)
 	{
-		PVR_DPF((PVR_DBG_WARNING, "PVRCore_Init: failed to initialise HWPerf debugfs (%d)", error));
+		PVR_DPF((PVR_DBG_WARNING,
+			 "%s: failed to initialise HWPerf debugfs (%d)",
+			  __func__, error));
+	}
+#endif
+
+	/*Initialize the device dependent bridges */
+
+	error = DeviceDepBridgeInit(psDevInfo->sDevFeatureCfg.ui64Features);
+	if (error != 0)
+	{
+		PVR_DPF((PVR_DBG_WARNING,
+			 "%s: Device dependent bridge initialization failed (%d)",
+			 __func__, error));
 	}
 
 	return 0;
 }
 
-/*!
-*****************************************************************************
-
- @Function		PVRSRVDeviceDeinit
-
- @Description	Unwind PVRSRVDeviceInit
-
-*****************************************************************************/
-void PVRSRVDeviceDeinit(void)
+/**************************************************************************/ /*!
+@Function     PVRSRVCommonDeviceDeinit
+@Description  Common device related de-initialisation.
+@Input        psDeviceNode  The device node for which de-initialisation should
+                            be performed
+@Return       void
+*/ /***************************************************************************/
+void PVRSRVCommonDeviceDeinit(PVRSRV_DEVICE_NODE *psDeviceNode)
 {
+	int error = 0;
+	PVRSRV_RGXDEV_INFO *psDevInfo = (PVRSRV_RGXDEV_INFO *) psDeviceNode->pvDevice;
+
+#if defined(SUPPORT_KERNEL_SRVINIT)
+	pvr_apphint_device_unregister(psDeviceNode);
+#else
 	PVRSRVHWperfDestroyDebugFs();
+#endif
 
 #if defined(SUPPORT_GPUTRACE_EVENTS)
-	PVRGpuTraceDeInit();
+	PVRGpuTraceDeInit(psDeviceNode);
 #endif
 
 	PVRDebugRemoveDebugFSEntries();
 
 #if defined(SUPPORT_BUFFER_SYNC)
-	pvr_buffer_sync_deinit();
+	pvr_buffer_sync_context_destroy(psDeviceNode->psBufferSyncContext);
 #endif
 
 #if defined(SUPPORT_NATIVE_FENCE_SYNC)
 	pvr_sync_deinit();
 #endif
+
+	error = DeviceDepBridgeDeInit(psDevInfo->sDevFeatureCfg.ui64Features);
+	if (error != 0)
+	{
+		PVR_DPF((PVR_DBG_WARNING,
+			 "%s: Device dependent bridge deinitialization failed (%d)",
+			 __func__, error));
+	}
+}
+
+/**************************************************************************/ /*!
+@Function     PVRSRVCommonDeviceShutdown
+@Description  Common device shutdown.
+@Input        psDeviceNode  The device node representing the device that should
+                            be shutdown
+@Return       void
+*/ /***************************************************************************/
+
+void PVRSRVCommonDeviceShutdown(PVRSRV_DEVICE_NODE *psDeviceNode)
+{
+	/*
+	 * Take the bridge mutex, and never release it, to stop processes trying to
+	 * use the driver after it has been shutdown.
+	 */
+	OSAcquireBridgeLock();
+
+	(void) PVRSRVSetDeviceSystemPowerState(psDeviceNode,
+										   PVRSRV_SYS_POWER_STATE_OFF);
+}
+
+/**************************************************************************/ /*!
+@Function     PVRSRVCommonDeviceSuspend
+@Description  Common device suspend.
+@Input        psDeviceNode  The device node representing the device that should
+                            be suspended
+@Return       int           0 on success and a Linux error code otherwise
+*/ /***************************************************************************/
+int PVRSRVCommonDeviceSuspend(PVRSRV_DEVICE_NODE *psDeviceNode)
+{
+	/*
+	 * OSSetDriverSuspended prevents processes from using the driver while it's
+	 * suspended (this is needed for Android). Acquire the bridge lock first to
+	 * ensure the driver isn't currently in use.
+	 */
+	OSAcquireBridgeLock();
+	OSSetDriverSuspended();
+	OSReleaseBridgeLock();
+
+	if (PVRSRVSetDeviceSystemPowerState(psDeviceNode,
+										PVRSRV_SYS_POWER_STATE_OFF) != PVRSRV_OK)
+	{
+		OSClearDriverSuspended();
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+/**************************************************************************/ /*!
+@Function     PVRSRVCommonDeviceResume
+@Description  Common device resume.
+@Input        psDeviceNode  The device node representing the device that should
+                            be resumed
+@Return       int           0 on success and a Linux error code otherwise
+*/ /***************************************************************************/
+int PVRSRVCommonDeviceResume(PVRSRV_DEVICE_NODE *psDeviceNode)
+{
+	if (PVRSRVSetDeviceSystemPowerState(psDeviceNode,
+										PVRSRV_SYS_POWER_STATE_ON) != PVRSRV_OK)
+	{
+		return -EINVAL;
+	}
+
+	OSClearDriverSuspended();
+
+	/*
+	 * Reprocess the device queues in case commands were blocked during
+	 * suspend.
+	 */
+	if (psDeviceNode->eDevState == PVRSRV_DEVICE_STATE_ACTIVE)
+	{
+		PVRSRVCheckStatus(NULL);
+	}
+
+	return 0;
+}
+
+/**************************************************************************/ /*!
+@Function     PVRSRVCommonDeviceOpen
+@Description  Common device open.
+@Input        psDeviceNode  The device node representing the device being
+                            opened by a user mode process
+@Input        psDRMFile     The DRM file data that backs the file handle
+                            returned to the user mode process
+@Return       int           0 on success and a Linux error code otherwise
+*/ /***************************************************************************/
+int PVRSRVCommonDeviceOpen(PVRSRV_DEVICE_NODE *psDeviceNode,
+						   struct drm_file *psDRMFile)
+{
+	PVRSRV_DATA *psPVRSRVData = PVRSRVGetPVRSRVData();
+	ENV_CONNECTION_PRIVATE_DATA sPrivData;
+	void *pvConnectionData;
+	PVRSRV_ERROR eError;
+	int iErr = 0;
+
+	OSAcquireBridgeLock();
+
+	if (!psPVRSRVData)
+	{
+		PVR_DPF((PVR_DBG_ERROR, "%s: No device data", __func__));
+		iErr = -ENODEV;
+		goto e1;
+	}
+
+#if defined(SUPPORT_KERNEL_SRVINIT)
+	if (psDeviceNode->eDevState == PVRSRV_DEVICE_STATE_INIT)
+	{
+		eError = PVRSRVDeviceInitialise(psDeviceNode);
+		if (eError != PVRSRV_OK)
+		{
+			PVR_DPF((PVR_DBG_ERROR, "%s: Failed to initialise device (%s)",
+					 __func__, PVRSRVGetErrorStringKM(eError)));
+			iErr = -ENODEV;
+			goto e1;
+		}
+	}
+#endif
+
+	sPrivData.psDevNode = psDeviceNode;
+	sPrivData.psFile = psDRMFile->filp;
+
+	/*
+	 * Here we pass the file pointer which will passed through to our
+	 * OSConnectionPrivateDataInit function where we can save it so
+	 * we can back reference the file structure from it's connection
+	 */
+	eError = PVRSRVConnectionConnect(&pvConnectionData, (void *) &sPrivData);
+	if (eError != PVRSRV_OK)
+	{
+		iErr = -ENOMEM;
+		goto e1;
+	}
+
+	psDRMFile->driver_priv = pvConnectionData;
+	OSReleaseBridgeLock();
+
+out:
+	return iErr;
+e1:
+	OSReleaseBridgeLock();
+	goto out;
+}
+
+/**************************************************************************/ /*!
+@Function     PVRSRVCommonDeviceRelease
+@Description  Common device release.
+@Input        psDeviceNode  The device node for the device that the given file
+                            represents
+@Input        psDRMFile     The DRM file data that's being released
+@Return       void
+*/ /***************************************************************************/
+void PVRSRVCommonDeviceRelease(PVRSRV_DEVICE_NODE *psDeviceNode,
+							   struct drm_file *psDRMFile)
+{
+	void *pvConnectionData;
+
+	PVR_UNREFERENCED_PARAMETER(psDeviceNode);
+
+	OSAcquireBridgeLock();
+
+	pvConnectionData = psDRMFile->driver_priv;
+	if (pvConnectionData)
+	{
+		PVRSRVConnectionDisconnect(pvConnectionData);
+		psDRMFile->driver_priv = NULL;
+	}
+
+	OSReleaseBridgeLock();
 }
diff --git a/drivers/staging/imgtec/rogue/module_common.h b/drivers/staging/imgtec/rogue/module_common.h
index 7886dff..69d55e4 100644
--- a/drivers/staging/imgtec/rogue/module_common.h
+++ b/drivers/staging/imgtec/rogue/module_common.h
@@ -1,5 +1,5 @@
 /*************************************************************************/ /*!
-@File
+@File           module_common.h
 @Title          Common linux module setup header
 @Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
 @License        Dual MIT/GPLv2
@@ -43,50 +43,25 @@
 #ifndef _MODULE_COMMON_H_
 #define _MODULE_COMMON_H_
 
-#if defined(LDM_PLATFORM)
-#include <linux/platform_device.h>
-#define	LDM_DEV	struct platform_device
-#endif /*LDM_PLATFORM */
+/* DRVNAME is the name we use to register our driver. */
+#define DRVNAME PVR_LDM_DRIVER_REGISTRATION_NAME
 
-#if defined(LDM_PCI)
-#include <linux/pci.h>
-#define	LDM_DEV	struct pci_dev
-#endif /* LDM_PCI */
+struct _PVRSRV_DEVICE_NODE_;
+struct drm_file;
 
-extern LDM_DEV *gpsPVRLDMDev;
+int PVRSRVCommonDriverInit(void);
+void PVRSRVCommonDriverDeinit(void);
 
-/*
- * Linux 3.8 and newer kernels no longer support __devinitdata, __devinit, __devexit, or
- * __devexit_p.
- */
-#if !defined(__devinitdata)
-#define __devinitdata
-#endif
-#if !defined(__devinit)
-#define __devinit
-#endif
-#if !defined(__devexit)
-#define __devexit
-#endif
-#if !defined(__devexit_p)
-#define __devexit_p(x) (&(x))
-#endif
+int PVRSRVCommonDeviceInit(struct _PVRSRV_DEVICE_NODE_ *psDeviceNode);
+void PVRSRVCommonDeviceDeinit(struct _PVRSRV_DEVICE_NODE_ *psDeviceNode);
 
-#if defined(PVRSRV_GPUVIRT_GUESTDRV) && defined(PVRSRV_GPUVIRT_MULTIDRV_MODEL)
-/* Functionality is n/a for guest drivers in a multi-driver model */
-#else
-void PVRSRVDriverShutdown(LDM_DEV *device);
-int PVRSRVDriverSuspend(struct device *device);
-int PVRSRVDriverResume(struct device *device);
-#endif
+void PVRSRVCommonDeviceShutdown(struct _PVRSRV_DEVICE_NODE_ *psDeviceNode);
+int PVRSRVCommonDeviceSuspend(struct _PVRSRV_DEVICE_NODE_ *psDeviceNode);
+int PVRSRVCommonDeviceResume(struct _PVRSRV_DEVICE_NODE_ *psDeviceNode);
 
-int PVRSRVCommonOpen(struct file *pFile);
-void PVRSRVCommonRelease(struct file *pFile);
-
-int PVRSRVDriverInit(void);
-void PVRSRVDriverDeinit(void);
-
-int PVRSRVDeviceInit(void);
-void PVRSRVDeviceDeinit(void);
+int PVRSRVCommonDeviceOpen(struct _PVRSRV_DEVICE_NODE_ *psDeviceNode,
+						   struct drm_file *psDRMFile);
+void PVRSRVCommonDeviceRelease(struct _PVRSRV_DEVICE_NODE_ *psDeviceNode,
+							   struct drm_file *psDRMFile);
 
 #endif /* _MODULE_COMMON_H_ */
diff --git a/drivers/staging/imgtec/rogue/os_srvinit_param.c b/drivers/staging/imgtec/rogue/os_srvinit_param.c
deleted file mode 100644
index 2650e9a..0000000
--- a/drivers/staging/imgtec/rogue/os_srvinit_param.c
+++ /dev/null
@@ -1,148 +0,0 @@
-/*************************************************************************/ /*!
-@File
-@Title          Services initialisation parameter support
-@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
-@Description    Services initialisation parameter support functions for
-		the Linux kernel.
-@License        Dual MIT/GPLv2
-
-The contents of this file are subject to the MIT license as set out below.
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-Alternatively, the contents of this file may be used under the terms of
-the GNU General Public License Version 2 ("GPL") in which case the provisions
-of GPL are applicable instead of those above.
-
-If you wish to allow use of your version of this file only under the terms of
-GPL, and not to allow others to use your version of this file under the terms
-of the MIT license, indicate your decision by deleting the provisions above
-and replace them with the notice and other provisions required by GPL as set
-out in the file called "GPL-COPYING" included in this distribution. If you do
-not delete the provisions above, a recipient may use your version of this file
-under the terms of either the MIT license or GPL.
-
-This License is also included in this distribution in the file called
-"MIT-COPYING".
-
-EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
-PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
-BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
-PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
-COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
-IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
-CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-*/ /**************************************************************************/
-
-#include <linux/kernel.h>
-#include <linux/string.h>
-
-#include "pvr_debug.h"
-#include "os_srvinit_param.h"
-
-void 
-*SrvInitParamOpen(void)
-{
-	return NULL;
-}
-
-void
-SrvInitParamClose(void *pvState)
-{
-	(void) pvState;
-}
-
-void
-_SrvInitParamGetBOOL(IMG_BOOL *pbValue, bool bDefault)
-{
-	*pbValue = bDefault;
-}
-
-void
-_SrvInitParamGetUINT32(IMG_UINT32 *pui32Value, unsigned int uiDefault)
-{
-	*pui32Value = uiDefault;
-}
-
-bool
-_SrvInitParamGetUINT32BitField(IMG_UINT32 *puiValue, unsigned int uiDefault, const char **ppszValues, unsigned int uiNum, const SRV_INIT_PARAM_UINT32_LOOKUP *psLookup, unsigned int uiSize, const char *pszName)
-{
-	IMG_UINT32 uiValue = uiDefault;
-	bool bRet = false;
-	unsigned i, j;
-
-	for (i = 0; i < uiNum; i++)
-	{
-		const char *pszValue = ppszValues[i];
-
-		for (j = 0; j < uiSize; j++)
-		{
-			if (strcmp(psLookup[j].pszValue, pszValue) == 0)
-			{
-				uiValue |= psLookup[j].ui32Value;
-				bRet = true;
-				break;
-			}
-		}
-		if (j ==  uiSize)
-		{
-			if (strlen(pszValue) == 0)
-			{
-				PVR_DPF((PVR_DBG_WARNING, "No value set for initialisation parameter %s", pszName));
-			}
-			else
-			{
-				PVR_DPF((PVR_DBG_WARNING, "Unrecognised value (%s) for initialisation parameter %s", pszValue, pszName));
-			}
-		}
-	}
-
-	*puiValue = uiValue;
-
-	return bRet;
-}
-
-bool
-_SrvInitParamGetUINT32List(IMG_UINT32 *puiValue, unsigned int uiDefault, const char *pszValue, const SRV_INIT_PARAM_UINT32_LOOKUP *psLookup, unsigned int uiSize, const char *pszName)
-{
-	IMG_UINT32 uiValue = uiDefault;
-	bool bRet = false;
-	unsigned i;
-
-	if (pszValue != NULL)
-	{
-		bRet = true;
-
-		for (i = 0; i < uiSize; i++)
-		{
-			if (strcmp(psLookup[i].pszValue, pszValue) == 0)
-			{
-				uiValue = psLookup[i].ui32Value;
-				break;
-			}
-		}
-		if (i ==  uiSize)
-		{
-			if (strlen(pszValue) == 0)
-			{
-				PVR_DPF((PVR_DBG_WARNING, "No value set for initialisation parameter %s", pszName));
-			}
-			else
-			{
-				PVR_DPF((PVR_DBG_WARNING, "Unrecognised value (%s) for initialisation parameter %s", pszValue, pszName));
-			}
-		}
-	}
-
-	*puiValue = uiValue;
-
-	return bRet;
-}
diff --git a/drivers/staging/imgtec/rogue/os_srvinit_param.h b/drivers/staging/imgtec/rogue/os_srvinit_param.h
index 549d321..8f50445 100644
--- a/drivers/staging/imgtec/rogue/os_srvinit_param.h
+++ b/drivers/staging/imgtec/rogue/os_srvinit_param.h
@@ -44,71 +44,28 @@
 #ifndef __OS_SRVINIT_PARAM_H__
 #define __OS_SRVINIT_PARAM_H__
 
+#include "km_apphint_defs.h"
 
-#include <linux/module.h>
-#include <linux/moduleparam.h>
-#include <linux/stat.h>
-
-#include "img_defs.h"
-#include "img_types.h"
-
-typedef struct
-{
-	IMG_CHAR *pszValue;
-	IMG_UINT32 ui32Value;
-} SRV_INIT_PARAM_UINT32_LOOKUP;
-
-void *SrvInitParamOpen(void);
-void SrvInitParamClose(void *pvState);
-
-#define	SrvInitParamInitBOOL(name, defval) \
-	static bool __SrvInitParam_ ## name = defval; \
-	module_param_named(name, __SrvInitParam_ ## name, bool, S_IRUGO);
-
-void _SrvInitParamGetBOOL(IMG_BOOL *pbValue, bool bDefault);
+#define SrvInitParamOpen() 0
+#define SrvInitParamClose(pvState) ((void)(pvState))
 
 #define	SrvInitParamGetBOOL(state, name, value) \
-		_SrvInitParamGetBOOL(&(value), __SrvInitParam_ ## name)
-
-#define	SrvInitParamInitUINT32(name, defval) \
-	static unsigned int __SrvInitParam_ ## name = defval; \
-	module_param_named(name, __SrvInitParam_ ## name, uint, S_IRUGO);
-
-void _SrvInitParamGetUINT32(IMG_UINT32 *pui32Value, unsigned int uiDefault);
+	pvr_apphint_get_bool(APPHINT_ID_ ## name, &value)
 
 #define	SrvInitParamGetUINT32(state, name, value) \
-		_SrvInitParamGetUINT32(&(value), __SrvInitParam_ ## name)
+	pvr_apphint_get_uint32(APPHINT_ID_ ## name, &value)
 
-#define	SrvInitParamInitUINT32BitField(name, inival, lookup) \
-	static unsigned int __SrvInitParam_ ## name = inival; \
-	static SRV_INIT_PARAM_UINT32_LOOKUP * \
-		__SrvInitParamLookup_ ## name = &lookup[0]; \
-	static const unsigned int __SrvInitParamSize_ ## name = \
-					ARRAY_SIZE(lookup); \
-	static char * __SrvInitParamArray_ ## name [ARRAY_SIZE(lookup)]; \
-	static unsigned int _SrvInitParamNum_ ## name = 0; \
-	static const char * __SrvInitParamName_ ## name = #name; \
-	module_param_array_named(name, __SrvInitParamArray_ ## name, charp, &_SrvInitParamNum_ ## name, S_IRUGO);
+#define	SrvInitParamGetUINT64(state, name, value) \
+	pvr_apphint_get_uint64(APPHINT_ID_ ## name, &value)
 
-bool _SrvInitParamGetUINT32BitField(IMG_UINT32 *puiValue, unsigned int uiDefault, const char **ppszValues, unsigned int uiNum, const SRV_INIT_PARAM_UINT32_LOOKUP *psLookup, unsigned int uiSize, const char *pszName);
+#define SrvInitParamGetSTRING(state, name, buffer, size) \
+	pvr_apphint_get_string(APPHINT_ID_ ## name, buffer, size)
 
 #define	SrvInitParamGetUINT32BitField(state, name, value) \
-		_SrvInitParamGetUINT32BitField(&(value), __SrvInitParam_ ## name, (const char **)__SrvInitParamArray_ ## name,  _SrvInitParamNum_ ## name, __SrvInitParamLookup_ ## name, __SrvInitParamSize_ ## name, __SrvInitParamName_ ## name)
-
-#define	SrvInitParamInitUINT32List(name, defval, lookup) \
-	static unsigned int __SrvInitParam_ ## name = defval; \
-	static SRV_INIT_PARAM_UINT32_LOOKUP * \
-		__SrvInitParamLookup_ ## name = &lookup[0]; \
-	static const unsigned int __SrvInitParamSize_ ## name = \
-					ARRAY_SIZE(lookup); \
-	static const char * __SrvInitParamName_ ## name = #name; \
-	static char * __SrvInitParamString_ ## name = NULL; \
-	module_param_named(name, __SrvInitParamString_ ## name, charp, S_IRUGO);
-
-bool _SrvInitParamGetUINT32List(IMG_UINT32 *puiValue, unsigned int uiDefault, const char *pszValue, const SRV_INIT_PARAM_UINT32_LOOKUP *psLookup, unsigned int uiSize, const char *pszName);
+	pvr_apphint_get_uint32(APPHINT_ID_ ## name, &value)
 
 #define	SrvInitParamGetUINT32List(state, name, value) \
-		_SrvInitParamGetUINT32List(&(value), __SrvInitParam_ ## name, __SrvInitParamString_ ## name, __SrvInitParamLookup_ ## name, __SrvInitParamSize_ ## name,  __SrvInitParamName_ ## name)
+	pvr_apphint_get_uint32(APPHINT_ID_ ## name, &value)
 
 
 #endif /* __OS_SRVINIT_PARAM_H__ */
diff --git a/drivers/staging/imgtec/rogue/osconnection_server.c b/drivers/staging/imgtec/rogue/osconnection_server.c
index 8035585..fd464df 100644
--- a/drivers/staging/imgtec/rogue/osconnection_server.c
+++ b/drivers/staging/imgtec/rogue/osconnection_server.c
@@ -47,6 +47,8 @@
 #include "allocmem.h"
 #include "pvr_debug.h"
 
+#include <linux/sched.h>
+
 #if defined (SUPPORT_ION)
 #include <linux/err.h>
 #include PVR_ANDROID_ION_HEADER
@@ -67,7 +69,7 @@
 	ENV_ION_CONNECTION_DATA *psIonConnection;
 #endif
 
-	*phOsPrivateData = OSAllocMem(sizeof(ENV_CONNECTION_DATA));
+	*phOsPrivateData = OSAllocZMem(sizeof(ENV_CONNECTION_DATA));
 
 	if (*phOsPrivateData == NULL)
 	{
@@ -76,20 +78,21 @@
 	}
 
 	psEnvConnection = (ENV_CONNECTION_DATA *)*phOsPrivateData;
-	OSMemSet(psEnvConnection, 0, sizeof(*psEnvConnection));
+
+	psEnvConnection->owner = current->tgid;
 
 	/* Save the pointer to our struct file */
 	psEnvConnection->psFile = psPrivData->psFile;
 	psEnvConnection->psDevNode = psPrivData->psDevNode;
 
 #if defined(SUPPORT_ION)
-	psIonConnection = (ENV_ION_CONNECTION_DATA *)OSAllocMem(sizeof(ENV_ION_CONNECTION_DATA));
+	psIonConnection = (ENV_ION_CONNECTION_DATA *)OSAllocZMem(sizeof(ENV_ION_CONNECTION_DATA));
 	if (psIonConnection == NULL)
 	{
 		PVR_DPF((PVR_DBG_ERROR, "%s: OSAllocMem failed", __FUNCTION__));
 		return PVRSRV_ERROR_OUT_OF_MEMORY;
 	}
-	OSMemSet(psIonConnection, 0, sizeof(*psIonConnection));
+
 	psEnvConnection->psIonData = psIonConnection;
 	/*
 		We can have more then one connection per process so we need more then
diff --git a/drivers/staging/imgtec/rogue/osconnection_server.h b/drivers/staging/imgtec/rogue/osconnection_server.h
index a20d330..192ef58 100644
--- a/drivers/staging/imgtec/rogue/osconnection_server.h
+++ b/drivers/staging/imgtec/rogue/osconnection_server.h
@@ -47,7 +47,7 @@
 #include "handle.h"
 
 
-#if defined(__linux__) || defined(__QNXNTO__)
+#if defined(__linux__) || defined(__QNXNTO__) || defined(INTEGRITY_OS)
 PVRSRV_ERROR OSConnectionPrivateDataInit(IMG_HANDLE *phOsPrivateData, void *pvOSData);
 PVRSRV_ERROR OSConnectionPrivateDataDeInit(IMG_HANDLE hOsPrivateData);
 
@@ -55,10 +55,20 @@
 
 PVRSRV_DEVICE_NODE* OSGetDevData(CONNECTION_DATA *psConnection);
 
-#else	/* defined(__linux__) */
+#else	/* defined(__linux__) || defined(__QNXNTO__) || defined(INTEGRITY_OS) */
 #ifdef INLINE_IS_PRAGMA
 #pragma inline(OSConnectionPrivateDataInit)
 #endif
+/*************************************************************************/ /*!
+@Function       OSConnectionPrivateDataInit
+@Description    Allocates and initialises any OS-specific private data
+                relating to a connection.
+                Called from PVRSRVConnectionConnect().
+@Input          pvOSData            pointer to any OS private data
+@Output         phOsPrivateData     handle to the created connection
+                                    private data
+@Return         PVRSRV_OK on success, a failure code otherwise.
+*/ /**************************************************************************/
 static INLINE PVRSRV_ERROR OSConnectionPrivateDataInit(IMG_HANDLE *phOsPrivateData, void *pvOSData)
 {
 	PVR_UNREFERENCED_PARAMETER(phOsPrivateData);
@@ -70,6 +80,14 @@
 #ifdef INLINE_IS_PRAGMA
 #pragma inline(OSConnectionPrivateDataDeInit)
 #endif
+/*************************************************************************/ /*!
+@Function       OSConnectionPrivateDataDeInit
+@Description    Frees previously allocated OS-specific private data
+                relating to a connection.
+@Input          hOsPrivateData      handle to the connection private data
+                                    to be freed
+@Return         PVRSRV_OK on success, a failure code otherwise.
+*/ /**************************************************************************/
 static INLINE PVRSRV_ERROR OSConnectionPrivateDataDeInit(IMG_HANDLE hOsPrivateData)
 {
 	PVR_UNREFERENCED_PARAMETER(hOsPrivateData);
@@ -96,7 +114,7 @@
 
 	return NULL;
 }
-#endif	/* defined(__linux__) */
+#endif	/* defined(__linux__) || defined(__QNXNTO__) || defined(INTEGRITY_OS) */
 
 
 #endif /* _OSCONNECTION_SERVER_H_ */
diff --git a/drivers/staging/imgtec/rogue/osfunc.c b/drivers/staging/imgtec/rogue/osfunc.c
index 76602ef..94c1c43 100644
--- a/drivers/staging/imgtec/rogue/osfunc.c
+++ b/drivers/staging/imgtec/rogue/osfunc.c
@@ -45,6 +45,7 @@
 #include <asm/page.h>
 #include <asm/div64.h>
 #include <linux/mm.h>
+#include <linux/kernel.h>
 #include <linux/pagemap.h>
 #include <linux/hugetlb.h> 
 #include <linux/slab.h>
@@ -52,8 +53,6 @@
 #include <linux/delay.h>
 #include <linux/genalloc.h>
 #include <linux/string.h>
-#include <linux/sched.h>
-#include <linux/interrupt.h>
 #include <asm/hardirq.h>
 #include <asm/tlbflush.h>
 #include <linux/timer.h>
@@ -69,45 +68,61 @@
 #endif
 #include <linux/kthread.h>
 #include <asm/atomic.h>
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 5, 0))
+#include <linux/pfn_t.h>
+#include <linux/pfn.h>
+#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 5, 0)) */
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 11, 0))
+#include <linux/sched/clock.h>
+#include <linux/sched/signal.h>
+#else
+#include <linux/sched.h>
+#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 11, 0)) */
 
 #include "log2.h"
 #include "osfunc.h"
 #include "img_types.h"
-#include "mm.h"
 #include "allocmem.h"
-#include "env_data.h"
+#include "devicemem_server_utils.h"
 #include "pvr_debugfs.h"
 #include "event.h"
 #include "linkage.h"
 #include "pvr_uaccess.h"
 #include "pvr_debug.h"
-#include "driverlock.h"
+#include "pvrsrv_memallocflags.h"
 #if defined(PVRSRV_ENABLE_PROCESS_STATS)
 #include "process_stats.h"
 #endif
-#if defined(SUPPORT_SYSTEM_INTERRUPT_HANDLING)
-#include "syscommon.h"
-#endif
 #include "physmem_osmem_linux.h"
+
 #if defined(SUPPORT_PVRSRV_GPUVIRT)
-#include "virt_support.h"
+#include "dma_support.h"
 #endif
 
+#include "kernel_compatibility.h"
+
 #if defined(VIRTUAL_PLATFORM)
-#define EVENT_OBJECT_TIMEOUT_MS         (120000)
+#define EVENT_OBJECT_TIMEOUT_US		(120000000ULL)
 #else
 #if defined(EMULATOR)
-#define EVENT_OBJECT_TIMEOUT_MS		(2000)
+#define EVENT_OBJECT_TIMEOUT_US		(2000000ULL)
 #else
-#define EVENT_OBJECT_TIMEOUT_MS		(100)
+#define EVENT_OBJECT_TIMEOUT_US		(100000ULL)
 #endif /* EMULATOR */
 #endif
 
+/*
+ * Main driver lock, used to ensure driver code is single threaded. There are
+ * some places where this lock must not be taken, such as in the mmap related
+ * driver entry points.
+ */
+static DEFINE_MUTEX(gPVRSRVLock);
 
 static void *g_pvBridgeBuffers = NULL;
 static atomic_t g_DriverSuspended;
 
-struct task_struct *OSGetBridgeLockOwner(void);
+struct task_struct *BridgeLockGetOwner(void);
+IMG_BOOL BridgeLockIsLocked(void);
 
 
 PVRSRV_ERROR OSPhyContigPagesAlloc(PVRSRV_DEVICE_NODE *psDevNode, size_t uiSize,
@@ -144,10 +159,12 @@
 
 #if defined(PVRSRV_ENABLE_PROCESS_STATS)
 #if !defined(PVRSRV_ENABLE_MEMORY_STATS)
-	    PVRSRVStatsIncrMemAllocStat(PVRSRV_MEM_ALLOC_TYPE_ALLOC_PAGES_PT_UMA, uiSize);
+	    PVRSRVStatsIncrMemAllocStatAndTrack(PVRSRV_MEM_ALLOC_TYPE_ALLOC_PAGES_PT_UMA,
+	                                        uiSize,
+	                                        (IMG_UINT64)(uintptr_t) psPage);
 #else
 	PVRSRVStatsAddMemAllocRecord(PVRSRV_MEM_ALLOC_TYPE_ALLOC_PAGES_PT_UMA,
-								 psPage,
+	                             psPage,
 								 sCpuPAddr,
 								 uiSize,
 								 NULL);
@@ -167,9 +184,10 @@
 
 #if defined(PVRSRV_ENABLE_PROCESS_STATS)
 #if !defined(PVRSRV_ENABLE_MEMORY_STATS)
-	    PVRSRVStatsDecrMemAllocStat(PVRSRV_MEM_ALLOC_TYPE_ALLOC_PAGES_PT_UMA, uiSize);
+	PVRSRVStatsDecrMemAllocStatAndUntrack(PVRSRV_MEM_ALLOC_TYPE_ALLOC_PAGES_PT_UMA,
+	                                      (IMG_UINT64)(uintptr_t) psPage);
 #else
-	PVRSRVStatsRemoveMemAllocRecord(PVRSRV_MEM_ALLOC_TYPE_ALLOC_PAGES_PT_UMA, (IMG_UINT64)(uintptr_t)psPage);
+	PVRSRVStatsRemoveMemAllocRecord(PVRSRV_MEM_ALLOC_TYPE_ALLOC_PAGES_PT_UMA, (IMG_UINT64)(uintptr_t) psPage);
 #endif
 #endif
 
@@ -181,11 +199,12 @@
 						size_t uiSize, IMG_DEV_PHYADDR *psDevPAddr,
 						void **pvPtr)
 {
-	size_t actualSize = 1<<psMemHandle->ui32Order;
+	size_t actualSize = 1 << (PAGE_SHIFT + psMemHandle->ui32Order);
 	*pvPtr = kmap((struct page*)psMemHandle->u.pvHandle);
 
 	PVR_UNREFERENCED_PARAMETER(psDevPAddr);
 
+	PVR_UNREFERENCED_PARAMETER(actualSize); /* If we don't take an #ifdef path */
 	PVR_UNREFERENCED_PARAMETER(uiSize);
 	PVR_UNREFERENCED_PARAMETER(psDevNode);
 
@@ -214,7 +233,7 @@
 #if defined(PVRSRV_ENABLE_PROCESS_STATS)
 #if !defined(PVRSRV_ENABLE_MEMORY_STATS)
 	/* Mapping is done a page at a time */
-	PVRSRVStatsDecrMemAllocStat(PVRSRV_MEM_ALLOC_TYPE_VMAP_PT_UMA, (PAGE_SIZE << psMemHandle->ui32Order));
+	PVRSRVStatsDecrMemAllocStat(PVRSRV_MEM_ALLOC_TYPE_VMAP_PT_UMA, (1 << (PAGE_SHIFT + psMemHandle->ui32Order)));
 #else
 	PVRSRVStatsRemoveMemAllocRecord(PVRSRV_MEM_ALLOC_TYPE_VMAP_PT_UMA, (IMG_UINT64)(uintptr_t)pvPtr);
 #endif
@@ -226,7 +245,8 @@
 	kunmap((struct page*) psMemHandle->u.pvHandle);
 }
 
-PVRSRV_ERROR OSPhyContigPagesClean(PG_HANDLE *psMemHandle,
+PVRSRV_ERROR OSPhyContigPagesClean(PVRSRV_DEVICE_NODE *psDevNode,
+                                   PG_HANDLE *psMemHandle,
                                    IMG_UINT32 uiOffset,
                                    IMG_UINT32 uiLength)
 {
@@ -255,7 +275,8 @@
 	sPhysStart.uiAddr = page_to_phys(psPage) + uiOffset;
 	sPhysEnd.uiAddr = sPhysStart.uiAddr + uiLength;
 
-	OSCleanCPUCacheRangeKM(pvVirtAddrStart,
+	OSCleanCPUCacheRangeKM(psDevNode,
+	                       pvVirtAddrStart,
 	                       pvVirtAddrStart + uiLength,
 	                       sPhysStart,
 	                       sPhysEnd);
@@ -273,11 +294,6 @@
 #error "PVRSRV Alignment macros need to be defined for this compiler"
 #endif
 
-/*************************************************************************/ /*!
-@Function       OSCPUCacheAttributeSize
-@Description    Lookup dcache attribute sizes
-@Input          eCacheAttribute
-*/ /**************************************************************************/
 IMG_UINT32 OSCPUCacheAttributeSize(IMG_DCACHE_ATTRIBUTE eCacheAttribute)
 {
 	IMG_UINT32 uiSize = 0;
@@ -298,25 +314,28 @@
 	return uiSize;
 }
 
+IMG_UINT32 OSVSScanf(IMG_CHAR *pStr, const IMG_CHAR *pszFormat, ...)
+{
+	va_list argList;
+	IMG_INT32 iCount = 0;
+
+	va_start(argList, pszFormat);
+	iCount = vsscanf(pStr, pszFormat, argList);
+	va_end(argList);
+
+	return iCount;
+}
+
 IMG_INT OSMemCmp(void *pvBufA, void *pvBufB, size_t uiLen)
 {
 	return (IMG_INT) memcmp(pvBufA, pvBufB, uiLen);
 }
 
-/*************************************************************************/ /*!
-@Function       OSStringNCopy
-@Description    strcpy
-*/ /**************************************************************************/
 IMG_CHAR *OSStringNCopy(IMG_CHAR *pszDest, const IMG_CHAR *pszSrc, size_t uSize)
 {
 	return strncpy(pszDest, pszSrc, uSize);
 }
 
-/*************************************************************************/ /*!
-@Function       OSSNPrintf
-@Description    snprintf
-@Return         the chars written or -1 on error
-*/ /**************************************************************************/
 IMG_INT32 OSSNPrintf(IMG_CHAR *pStr, size_t ui32Size, const IMG_CHAR *pszFormat, ...)
 {
 	va_list argList;
@@ -344,14 +363,21 @@
 	return strcmp(pStr1, pStr2);
 }
 
-/*************************************************************************/ /*!
-@Function       OSInitEnvData
-@Description    Allocates space for env specific data
-@Input          ppvEnvSpecificData   Pointer to pointer in which to return
-                                     allocated data.
-@Input          ui32MMUMode          MMU mode.
-@Return         PVRSRV_OK
-*/ /**************************************************************************/
+IMG_INT32 OSStringNCompare(const IMG_CHAR *pStr1, const IMG_CHAR *pStr2,
+                          size_t uiSize)
+{
+	return strncmp(pStr1, pStr2, uiSize);
+}
+
+PVRSRV_ERROR OSStringToUINT32(const IMG_CHAR *pStr, IMG_UINT32 ui32Base,
+                              IMG_UINT32 *ui32Result)
+{
+	if (kstrtou32(pStr, ui32Base, ui32Result) != 0)
+		return PVRSRV_ERROR_CONVERSION_FAILED;
+
+	return PVRSRV_OK;
+}
+
 PVRSRV_ERROR OSInitEnvData(void)
 {
 	/* allocate memory for the bridge buffers to be used during an ioctl */
@@ -369,12 +395,6 @@
 }
 
 
-/*************************************************************************/ /*!
-@Function       OSDeInitEnvData
-@Description    frees env specific data memory
-@Input          pvEnvSpecificData   Pointer to private structure
-@Return         PVRSRV_OK on success else PVRSRV_ERROR_OUT_OF_MEMORY
-*/ /**************************************************************************/
 void OSDeInitEnvData(void)
 {
 
@@ -389,18 +409,12 @@
 }
 
 PVRSRV_ERROR OSGetGlobalBridgeBuffers(void **ppvBridgeInBuffer,
-							IMG_UINT32 *pui32BridgeInBufferSize,
-							void **ppvBridgeOutBuffer,
-							IMG_UINT32 *pui32BridgeOutBufferSize)
+									  void **ppvBridgeOutBuffer)
 {
 	PVR_ASSERT (ppvBridgeInBuffer && ppvBridgeOutBuffer);
-	PVR_ASSERT (pui32BridgeInBufferSize && pui32BridgeOutBufferSize);
 
 	*ppvBridgeInBuffer = g_pvBridgeBuffers;
-	*pui32BridgeInBufferSize = PVRSRV_MAX_BRIDGE_IN_SIZE;
-
-	*ppvBridgeOutBuffer = *ppvBridgeInBuffer + *pui32BridgeInBufferSize;
-	*pui32BridgeOutBufferSize = PVRSRV_MAX_BRIDGE_OUT_SIZE;
+	*ppvBridgeOutBuffer = *ppvBridgeInBuffer + PVRSRV_MAX_BRIDGE_IN_SIZE;
 
 	return PVRSRV_OK;
 }
@@ -422,22 +436,11 @@
 	return (0 < atomic_read(&g_DriverSuspended))? IMG_TRUE: IMG_FALSE;
 }
 
-/*************************************************************************/ /*!
-@Function       OSReleaseThreadQuanta
-@Description    Releases thread quanta
-*/ /**************************************************************************/ 
 void OSReleaseThreadQuanta(void)
 {
 	schedule();
 }
 
-
-#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,35))
-static inline IMG_UINT32 Clockus(void)
-{
-	return (jiffies * (1000000 / HZ));
-}
-#else
 /* Not matching/aligning this API to the Clockus() API above to avoid necessary
  * multiplication/division operations in calling code.
  */
@@ -460,78 +463,72 @@
 
 	return timenow;
 }
-#endif
 
-/*************************************************************************/ /*!
- @Function OSClockns64
- @Description
-        This function returns the clock in nanoseconds. Unlike OSClockus,
-        OSClockus64 has a near 64-bit range
-*/ /**************************************************************************/
 IMG_UINT64 OSClockns64(void)
 {
-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,35))
 	return Clockns64();	
-#else
-	return ((IMG_UINT64)Clockus()) * 1000ULL;
-#endif
 }
 
-/*************************************************************************/ /*!
- @Function OSClockus64
- @Description
-        This function returns the clock in microseconds. Unlike OSClockus,
-        OSClockus64 has a near 64-bit range
-*/ /**************************************************************************/
 IMG_UINT64 OSClockus64(void)
 {
-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,35))
 	IMG_UINT64 timenow = Clockns64();
 	IMG_UINT32 remainder;
+
 	return OSDivide64r64(timenow, 1000, &remainder);
-#else
-	return ((IMG_UINT64)Clockus());
-#endif
 }
 
-
-/*************************************************************************/ /*!
-@Function       OSClockus
-@Description    This function returns the clock in microseconds
-@Return         clock (us)
-*/ /**************************************************************************/ 
 IMG_UINT32 OSClockus(void)
 {
-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,35))
 	return (IMG_UINT32) OSClockus64();
-#else
-	return Clockus();
-#endif
 }
 
-
-/*************************************************************************/ /*!
-@Function       OSClockms
-@Description    This function returns the clock in milliseconds
-@Return         clock (ms)
-*/ /**************************************************************************/ 
 IMG_UINT32 OSClockms(void)
 {
-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,35))
 	IMG_UINT64 timenow = Clockns64();
 	IMG_UINT32 remainder;
 
 	return OSDivide64(timenow, 1000000, &remainder);
+}
+
+static inline IMG_UINT64 KClockns64(void)
+{
+	ktime_t sTime = ktime_get();
+
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 10, 0))
+	return sTime;
 #else
-	IMG_UINT64 time, j = (IMG_UINT32)jiffies;
-
-	time = j * (((1 << 16) * 1000) / HZ);
-	time >>= 16;
-
-	return (IMG_UINT32)time;
+	return sTime.tv64;
 #endif
 }
 
+PVRSRV_ERROR OSClockMonotonicns64(IMG_UINT64 *pui64Time)
+{
+	*pui64Time = KClockns64();
+	return PVRSRV_OK;
+}
+
+PVRSRV_ERROR OSClockMonotonicus64(IMG_UINT64 *pui64Time)
+{
+	IMG_UINT64 timenow = KClockns64();
+	IMG_UINT32 remainder;
+
+	*pui64Time = OSDivide64r64(timenow, 1000, &remainder);
+	return PVRSRV_OK;
+}
+
+IMG_UINT64 OSClockMonotonicRawns64(void)
+{
+	struct timespec ts;
+
+	getrawmonotonic(&ts);
+	return (IMG_UINT64) ts.tv_sec * 1000000000 + ts.tv_nsec;
+}
+
+IMG_UINT64 OSClockMonotonicRawus64(void)
+{
+	IMG_UINT32 rem;
+	return OSDivide64r64(OSClockMonotonicRawns64(), 1000, &rem);
+}
 
 /*
 	OSWaitus
@@ -551,11 +548,11 @@
 }
 
 
-/*************************************************************************/ /*!
-@Function       OSGetCurrentProcessID
-@Description    Returns ID of current process (thread group)
-@Return         ID of current process
-*****************************************************************************/
+INLINE IMG_UINT64 OSGetCurrentProcessVASpaceSize(void)
+{
+	return (IMG_UINT64)TASK_SIZE;
+}
+
 INLINE IMG_PID OSGetCurrentProcessID(void)
 {
 	if (in_interrupt())
@@ -563,32 +560,14 @@
 		return KERNEL_ID;
 	}
 
-#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0))
-	return (IMG_PID)current->pgrp;
-#else
-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,24))
 	return (IMG_PID)task_tgid_nr(current);
-#else
-	return (IMG_PID)current->tgid;
-#endif
-#endif
 }
 
-/*************************************************************************/ /*!
-@Function       OSGetCurrentProcessName
-@Description    gets name of current process
-@Return         process name
-*****************************************************************************/
 INLINE IMG_CHAR *OSGetCurrentProcessName(void)
 {
 	return current->comm;
 }
 
-/*************************************************************************/ /*!
-@Function       OSGetCurrentThreadID
-@Description    Returns ID for current thread
-@Return         ID of current thread
-*****************************************************************************/
 INLINE uintptr_t OSGetCurrentThreadID(void)
 {
 	if (in_interrupt())
@@ -599,205 +578,79 @@
 	return current->pid;
 }
 
-/*************************************************************************/ /*!
-@Function       OSGetCurrentClientProcessIDKM
-@Description    Returns ID of current client process (thread group)
-@Return         ID of current client process
-*****************************************************************************/
 IMG_PID OSGetCurrentClientProcessIDKM(void)
 {
 	return OSGetCurrentProcessID();
 }
 
-/*************************************************************************/ /*!
-@Function       OSGetCurrentClientProcessNameKM
-@Description    gets name of current client process
-@Return         client process name
-*****************************************************************************/
 IMG_CHAR *OSGetCurrentClientProcessNameKM(void)
 {
 	return OSGetCurrentProcessName();
 }
 
-/*************************************************************************/ /*!
-@Function       OSGetCurrentClientThreadIDKM
-@Description    Returns ID for current client thread
-@Return         ID of current client thread
-*****************************************************************************/
 uintptr_t OSGetCurrentClientThreadIDKM(void)
 {
 	return OSGetCurrentThreadID();
 }
-/*************************************************************************/ /*!
-@Function       OSGetPageSize
-@Description    gets page size
-@Return         page size
-*/ /**************************************************************************/
+
 size_t OSGetPageSize(void)
 {
 	return PAGE_SIZE;
 }
 
-/*************************************************************************/ /*!
-@Function       OSGetPageShift
-@Description    gets page size
-@Return         page size
-*/ /**************************************************************************/
 size_t OSGetPageShift(void)
 {
 	return PAGE_SHIFT;
 }
 
-/*************************************************************************/ /*!
-@Function       OSGetPageMask
-@Description    gets page mask
-@Return         page size
-*/ /**************************************************************************/
 size_t OSGetPageMask(void)
 {
 	return (OSGetPageSize()-1);
 }
 
-/*************************************************************************/ /*!
-@Function       OSGetOrder
-@Description    gets log base 2 (Order) value of the given size
-@Return         order
-*/ /**************************************************************************/
 size_t OSGetOrder(size_t uSize)
 {
 	return get_order(PAGE_ALIGN(uSize));
 }
 
-#if !defined(SUPPORT_SYSTEM_INTERRUPT_HANDLING)
-#if defined(PVRSRV_GPUVIRT_GUESTDRV) && defined(PVRSRV_GPUVIRT_MULTIDRV_MODEL)
-/*
-	Device interrupt (ISR/LISR) management is predicated on the following:
-		- For normal/hyperv drivers:
-			- Perform device interrupt management directly (normal case)
-		- For guest drivers, behaviour depends on:
-			- If running on a multi-driver model (same OS instance)
-				- Delegate management to hypervisor driver
-				- Register guest driver device LISRs with hyperv
-				- Hypervisor triggers guests driver device LISRs
-			- Else assume hypervisor vm monitor exposes device/irq abstraction
-				- Manage this virtual device/irq directly like a normal driver
-				- Hypervisor vm monitor triggers device/irq abstraction
-				- Setup for this is outside the scope of the DDK
- */
-#else
-typedef struct _LISR_DATA_ {
-	PFN_LISR pfnLISR;
-	void *pvData;
-	IMG_UINT32 ui32IRQ;
-} LISR_DATA;
-
-/*
-	DeviceISRWrapper
-*/
-static irqreturn_t DeviceISRWrapper(int irq, void *dev_id)
+typedef struct
 {
-	LISR_DATA *psLISRData = (LISR_DATA *) dev_id;
-	IMG_BOOL bStatus = IMG_FALSE;
+	int os_error;
+	PVRSRV_ERROR pvr_error;
+} error_map_t;
 
-	PVR_UNREFERENCED_PARAMETER(irq);
-
-#if defined(SUPPORT_PVRSRV_GPUVIRT) && defined(PVRSRV_GPUVIRT_MULTIDRV_MODEL)
-	bStatus = SysVirtTriggerAllGuestDeviceLISR() == PVRSRV_OK ? IMG_TRUE : IMG_FALSE;
-#endif
-	bStatus |= psLISRData->pfnLISR(psLISRData->pvData);
-
-	return bStatus ? IRQ_HANDLED : IRQ_NONE;
-}
-#endif
-#endif
-
-/*
-	OSInstallDeviceLISR
-*/
-PVRSRV_ERROR OSInstallDeviceLISR(PVRSRV_DEVICE_CONFIG *psDevConfig,
-				 IMG_HANDLE *hLISRData, 
-				 PFN_LISR pfnLISR,
-				 void *pvData)
+/* return -ve versions of POSIX errors as they are used in this form */
+static const error_map_t asErrorMap[] =
 {
-#if defined(SUPPORT_SYSTEM_INTERRUPT_HANDLING)
-	return SysInstallDeviceLISR(psDevConfig->ui32IRQ,
-					psDevConfig->pszName,
-					pfnLISR,
-					pvData,
-					hLISRData);
-#else
-#if defined(PVRSRV_GPUVIRT_GUESTDRV) && defined(PVRSRV_GPUVIRT_MULTIDRV_MODEL)
-	return GuestBridgeSysInstallDeviceLISR(PVRSRV_GPUVIRT_OSID,
-									psDevConfig->ui32IRQ,
-									psDevConfig->pszName,
-									pfnLISR,
-									pvData,
-									hLISRData);
-#else
-	LISR_DATA *psLISRData;
-	unsigned long flags = 0;
+	{-EFAULT, PVRSRV_ERROR_BRIDGE_EFAULT},
+	{-EINVAL, PVRSRV_ERROR_BRIDGE_EINVAL},
+	{-ENOMEM, PVRSRV_ERROR_BRIDGE_ENOMEM},
+	{-ERANGE, PVRSRV_ERROR_BRIDGE_ERANGE},
+	{-EPERM,  PVRSRV_ERROR_BRIDGE_EPERM},
+	{-ENOTTY, PVRSRV_ERROR_BRIDGE_ENOTTY},
+	{-ENOTTY, PVRSRV_ERROR_BRIDGE_CALL_FAILED},
+	{-ERANGE, PVRSRV_ERROR_BRIDGE_BUFFER_TOO_SMALL},
+	{-ENOMEM, PVRSRV_ERROR_OUT_OF_MEMORY},
+	{-EINVAL, PVRSRV_ERROR_INVALID_PARAMS},
 
-	psLISRData = OSAllocMem(sizeof(LISR_DATA));
+	{0,       PVRSRV_OK}
+};
 
-	psLISRData->pfnLISR = pfnLISR;
-	psLISRData->pvData = pvData;
-	psLISRData->ui32IRQ = psDevConfig->ui32IRQ;
+#define num_rows(a) (sizeof(a)/sizeof(a[0]))
 
-	if (psDevConfig->bIRQIsShared)
-	{
-		flags |= IRQF_SHARED;
-	}
-
-	if (psDevConfig->eIRQActiveLevel == PVRSRV_DEVICE_IRQ_ACTIVE_HIGH)
-	{
-		flags |= IRQF_TRIGGER_HIGH;
-	}
-	else if (psDevConfig->eIRQActiveLevel == PVRSRV_DEVICE_IRQ_ACTIVE_LOW)
-	{
-		flags |= IRQF_TRIGGER_LOW;
-	}
-
-	PVR_TRACE(("Installing device LISR %s on IRQ %d with cookie %p", 
-				psDevConfig->pszName, psDevConfig->ui32IRQ, pvData));
-
-	if(request_irq(psDevConfig->ui32IRQ, DeviceISRWrapper,
-		flags, psDevConfig->pszName, psLISRData))
-	{
-		PVR_DPF((PVR_DBG_ERROR,
-				"OSInstallDeviceLISR: Couldn't install device LISR on IRQ %d", 
-				psDevConfig->ui32IRQ));
-
-		return PVRSRV_ERROR_UNABLE_TO_INSTALL_ISR;
-	}
-
-	*hLISRData = (IMG_HANDLE) psLISRData;
-
-	return PVRSRV_OK;
-#endif
-#endif
-}
-
-/*
-	OSUninstallDeviceLISR
-*/
-PVRSRV_ERROR OSUninstallDeviceLISR(IMG_HANDLE hLISRData)
+int PVRSRVToNativeError(PVRSRV_ERROR e)
 {
-#if defined (SUPPORT_SYSTEM_INTERRUPT_HANDLING)
-	return SysUninstallDeviceLISR(hLISRData);
-#else
-#if defined(PVRSRV_GPUVIRT_GUESTDRV) && defined(PVRSRV_GPUVIRT_MULTIDRV_MODEL)
-	return GuestBridgeSysUninstallDeviceLISR(PVRSRV_GPUVIRT_OSID, hLISRData);
-#else
-	LISR_DATA *psLISRData = (LISR_DATA *) hLISRData;
-
-	PVR_TRACE(("Uninstalling device LISR on IRQ %d with cookie %p", psLISRData->ui32IRQ,  psLISRData->pvData));
-
-	free_irq(psLISRData->ui32IRQ, psLISRData);
-	OSFreeMem(psLISRData);
-
-	return PVRSRV_OK;
-#endif	
-#endif
+	int os_error = -EFAULT;
+	int i;
+	for (i = 0; i < num_rows(asErrorMap); i++)
+	{
+		if (e == asErrorMap[i].pvr_error)
+		{
+			os_error = asErrorMap[i].os_error;
+			break;
+		}
+	}
+	return os_error;
 }
 
 #if defined(PVR_LINUX_MISR_USING_PRIVATE_WORKQUEUE)
@@ -826,7 +679,7 @@
 {
 	MISR_DATA *psMISRData;
 
-	psMISRData = OSAllocMem(sizeof(MISR_DATA));
+	psMISRData = OSAllocMem(sizeof(*psMISRData));
 	if (psMISRData == NULL)
 	{
 		return PVRSRV_ERROR_OUT_OF_MEMORY;
@@ -837,7 +690,7 @@
 
 	PVR_TRACE(("Installing MISR with cookie %p", psMISRData));
 
-	psMISRData->psWorkQueue = create_singlethread_workqueue("pvr_workqueue" PVRSRV_GPUVIRT_OSID_STR);
+	psMISRData->psWorkQueue = create_singlethread_workqueue("pvr_workqueue");
 
 	if (psMISRData->psWorkQueue == NULL)
 	{
@@ -860,7 +713,7 @@
 {
 	MISR_DATA *psMISRData = (MISR_DATA *) hMISRData;
 
-	PVR_TRACE(("Uninstalling MISR"));
+	PVR_TRACE(("Uninstalling MISR with cookie %p", psMISRData));
 
 	destroy_workqueue(psMISRData->psWorkQueue);
 	OSFreeMem(psMISRData);
@@ -884,10 +737,13 @@
 	*/
 #if defined(NO_HARDWARE)
 	psMISRData->pfnMISR(psMISRData->hData);
-#else
-	queue_work(psMISRData->psWorkQueue, &psMISRData->sMISRWork);
-#endif
 	return PVRSRV_OK;
+#else
+	{
+		bool rc = queue_work(psMISRData->psWorkQueue, &psMISRData->sMISRWork);
+		return (rc ? PVRSRV_OK : PVRSRV_ERROR_ALREADY_EXISTS);
+	}
+#endif
 }
 #else	/* defined(PVR_LINUX_MISR_USING_PRIVATE_WORKQUEUE) */
 #if defined(PVR_LINUX_MISR_USING_WORKQUEUE)
@@ -914,7 +770,7 @@
 {
 	MISR_DATA *psMISRData;
 
-	psMISRData = OSAllocMem(sizeof(MISR_DATA));
+	psMISRData = OSAllocMem(sizeof(*psMISRData));
 	if (psMISRData == NULL)
 	{
 		return PVRSRV_ERROR_OUT_OF_MEMORY;
@@ -938,7 +794,7 @@
 */
 PVRSRV_ERROR OSUninstallMISR(IMG_HANDLE hMISRData)
 {
-	PVR_TRACE(("Uninstalling MISR"));
+	PVR_TRACE(("Uninstalling MISR with cookie %p", psMISRData));
 
 	flush_scheduled_work();
 
@@ -985,7 +841,7 @@
 {
 	MISR_DATA *psMISRData;
 
-	psMISRData = OSAllocMem(sizeof(MISR_DATA));
+	psMISRData = OSAllocMem(sizeof(*psMISRData));
 	if (psMISRData == NULL)
 	{
 		return PVRSRV_ERROR_OUT_OF_MEMORY;
@@ -1010,7 +866,7 @@
 {
 	MISR_DATA *psMISRData = (MISR_DATA *) hMISRData;
 
-	PVR_TRACE(("Uninstalling MISR"));
+	PVR_TRACE(("Uninstalling MISR with cookie %p", psMISRData));
 
 	tasklet_kill(&psMISRData->sMISRTasklet);
 
@@ -1036,12 +892,15 @@
 #endif /* #if defined(PVR_LINUX_MISR_USING_PRIVATE_WORKQUEUE) */
 
 /* OS specific values for thread priority */
-const IMG_INT32 ai32OSPriorityValues[OS_THREAD_LAST_PRIORITY] = { -20, /* OS_THREAD_HIGHEST_PRIORITY */
-																  -10, /* OS_THREAD_HIGH_PRIORITY */
-																	0, /* OS_THREAD_NORMAL_PRIORITY */
-																	9, /* OS_THREAD_LOW_PRIORITY */
-																   19, /* OS_THREAD_LOWEST_PRIORITY */
-																  -22};/* OS_THREAD_NOSET_PRIORITY */
+static const IMG_INT32 ai32OSPriorityValues[OS_THREAD_LAST_PRIORITY] =
+{
+	-20, /* OS_THREAD_HIGHEST_PRIORITY */
+	-10, /* OS_THREAD_HIGH_PRIORITY */
+	  0, /* OS_THREAD_NORMAL_PRIORITY */
+	  9, /* OS_THREAD_LOW_PRIORITY */
+	 19, /* OS_THREAD_LOWEST_PRIORITY */
+	-22, /* OS_THREAD_NOSET_PRIORITY */
+};
 
 typedef struct {
 	struct task_struct *kthread;
@@ -1088,7 +947,7 @@
 	OSThreadData *psOSThreadData;
 	PVRSRV_ERROR eError;
 
-	psOSThreadData = OSAllocMem(sizeof(OSThreadData));
+	psOSThreadData = OSAllocMem(sizeof(*psOSThreadData));
 	if (psOSThreadData == NULL)
 	{
 		eError = PVRSRV_ERROR_OUT_OF_MEMORY;
@@ -1145,200 +1004,110 @@
 #endif
 }
 
-/*************************************************************************/ /*!
-@Function       OSMapPhysToLin
-@Description    Maps the physical memory into linear addr range
-@Input          BasePAddr       Physical cpu address
-@Input          ui32Bytes       Bytes to map
-@Input          ui32CacheType   Cache type
-@Return         Linear addr of mapping on success, else NULL
- */ /**************************************************************************/
+PVRSRV_ERROR OSSetThreadPriority(IMG_HANDLE hThread,
+								 IMG_UINT32  nThreadPriority,
+								 IMG_UINT32  nThreadWeight)
+{
+	PVR_UNREFERENCED_PARAMETER(hThread);
+	PVR_UNREFERENCED_PARAMETER(nThreadPriority);
+	PVR_UNREFERENCED_PARAMETER(nThreadWeight);
+ 	/* Default priorities used on this platform */
+	
+	return PVRSRV_OK;
+}
+
 void *
 OSMapPhysToLin(IMG_CPU_PHYADDR BasePAddr,
 			   size_t ui32Bytes,
 			   IMG_UINT32 ui32MappingFlags)
 {
-	void *pvIORemapCookie;
+	void *pvLinAddr;
 
-	pvIORemapCookie = IORemapWrapper(BasePAddr, ui32Bytes, ui32MappingFlags);
-	if(pvIORemapCookie == NULL)
+	if (ui32MappingFlags & ~(PVRSRV_MEMALLOCFLAG_CPU_CACHE_MODE_MASK))
 	{
-		PVR_ASSERT(0);
+		PVR_ASSERT(!"Found non-cpu cache mode flag when mapping to the cpu");
 		return NULL;
 	}
 
-	return pvIORemapCookie;
+#if defined(SUPPORT_PVRSRV_GPUVIRT)
+	/*
+	 * This is required to support DMA physheaps for GPU virtualization.
+	 * Unfortunately, if a region of kernel managed memory is turned into
+	 * a DMA buffer, conflicting mappings can come about easily on Linux
+	 * as the original memory is mapped by the kernel as normal cached
+	 * memory whilst DMA buffers are mapped mostly as uncached device or
+	 * cache-coherent device memory. In both cases the system will have
+	 * two conflicting mappings for the same memory region and will have
+	 * "undefined behaviour" for most processors notably ARMv6 onwards
+	 * and some x86 micro-architectures
+	 *
+	 * As a result we perform ioremapping manually, for DMA physheap
+	 * allocations, by translating from CPU/VA <-> BUS/PA.
+	 */
+	pvLinAddr = SysDmaDevPAddrToCpuVAddr(BasePAddr.uiAddr, ui32Bytes);
+	if (pvLinAddr != NULL)
+	{
+		return pvLinAddr;
+	}
+#endif
+
+	switch (ui32MappingFlags)
+	{
+		case PVRSRV_MEMALLOCFLAG_CPU_UNCACHED:
+			pvLinAddr = (void *)ioremap_nocache(BasePAddr.uiAddr, ui32Bytes);
+			break;
+		case PVRSRV_MEMALLOCFLAG_CPU_WRITE_COMBINE:
+#if defined(CONFIG_X86) || defined(CONFIG_ARM) || defined(CONFIG_ARM64)
+			pvLinAddr = (void *)ioremap_wc(BasePAddr.uiAddr, ui32Bytes);
+#else
+			pvLinAddr = (void *)ioremap_nocache(BasePAddr.uiAddr, ui32Bytes);
+#endif
+			break;
+		case PVRSRV_MEMALLOCFLAG_CPU_CACHED:
+#if defined(CONFIG_X86) || defined(CONFIG_ARM)
+			pvLinAddr = (void *)ioremap_cache(BasePAddr.uiAddr, ui32Bytes);
+#else
+			pvLinAddr = (void *)ioremap(BasePAddr.uiAddr, ui32Bytes);
+#endif
+			break;
+		case PVRSRV_MEMALLOCFLAG_CPU_CACHE_COHERENT:
+		case PVRSRV_MEMALLOCFLAG_CPU_CACHE_INCOHERENT:
+			PVR_ASSERT(!"Unexpected cpu cache mode");
+			pvLinAddr = NULL;
+			break;
+		default:
+			PVR_ASSERT(!"Unsupported cpu cache mode");
+			pvLinAddr = NULL;
+			break;
+	}
+
+	return pvLinAddr;
 }
 
 
-/*************************************************************************/ /*!
-@Function       OSUnMapPhysToLin
-@Description    Unmaps memory that was mapped with OSMapPhysToLin
-@Input          pvLinAddr
-@Input          ui32Bytes
-@Return         TRUE on success, else FALSE
-*/ /**************************************************************************/
 IMG_BOOL
 OSUnMapPhysToLin(void *pvLinAddr, size_t ui32Bytes, IMG_UINT32 ui32MappingFlags)
 {
 	PVR_UNREFERENCED_PARAMETER(ui32Bytes);
 
-	IOUnmapWrapper(pvLinAddr);
+	if (ui32MappingFlags & ~(PVRSRV_MEMALLOCFLAG_CPU_CACHE_MODE_MASK))
+	{
+		PVR_ASSERT(!"Found non-cpu cache mode flag when unmapping from the cpu");
+		return IMG_FALSE;
+	}
+
+#if defined(SUPPORT_PVRSRV_GPUVIRT)
+	if (SysDmaCpuVAddrToDevPAddr(pvLinAddr))
+	{
+		return IMG_TRUE;
+	}
+#endif
+
+	iounmap(pvLinAddr);
 
 	return IMG_TRUE;
 }
 
-/*
-	OSReadHWReg8
-*/
-IMG_UINT8 OSReadHWReg8(void *pvLinRegBaseAddr,
-						IMG_UINT32	ui32Offset)
-{
-#if !defined(NO_HARDWARE)
-	return (IMG_UINT8) readb((IMG_PBYTE)pvLinRegBaseAddr+ui32Offset);
-#else
-	return 0x4e;
-#endif
-}
-
-/*
-	OSReadHWReg16
-*/
-IMG_UINT16 OSReadHWReg16(void *pvLinRegBaseAddr,
-						 IMG_UINT32	ui32Offset)
-{
-#if !defined(NO_HARDWARE)
-	return (IMG_UINT16) readw((IMG_PBYTE)pvLinRegBaseAddr+ui32Offset);
-#else
-	return 0x3a4e;
-#endif
-}
-
-/*
-	OSReadHWReg32
-*/
-IMG_UINT32 OSReadHWReg32(void *pvLinRegBaseAddr,
-						 IMG_UINT32	ui32Offset)
-{
-#if !defined(NO_HARDWARE)
-	return (IMG_UINT32) readl((IMG_PBYTE)pvLinRegBaseAddr+ui32Offset);
-#else
-	return 0x30f73a4e;
-#endif
-}
-
-
-/*
-	OSReadHWReg64
-*/
-IMG_UINT64 OSReadHWReg64(void *pvLinRegBaseAddr,
-						 IMG_UINT32	ui32Offset)
-{
-	IMG_UINT64	ui64Result;
-
-	ui64Result = OSReadHWReg32(pvLinRegBaseAddr, ui32Offset + 4);
-	ui64Result <<= 32;
-	ui64Result |= (IMG_UINT64)OSReadHWReg32(pvLinRegBaseAddr, ui32Offset);
-
-	return ui64Result;
-}
-
-/*
-	OSReadHWRegBank
-*/
-IMG_DEVMEM_SIZE_T OSReadHWRegBank(void *pvLinRegBaseAddr,
-								  IMG_UINT32 ui32Offset,
-								  IMG_UINT8 *pui8DstBuf,
-								  IMG_DEVMEM_SIZE_T uiDstBufLen)
-{
-#if !defined(NO_HARDWARE)
-	IMG_DEVMEM_SIZE_T uiCounter;
-
-	for(uiCounter = 0; uiCounter < uiDstBufLen; uiCounter++) {
-		*(pui8DstBuf + uiCounter) =
-		  readb(pvLinRegBaseAddr + ui32Offset + uiCounter);
-	}
-
-	return uiCounter;
-#else
-	return uiDstBufLen;
-#endif
-}
-
-/*
-	OSWriteHWReg8
-*/
-void OSWriteHWReg8(void			*pvLinRegBaseAddr,
-				   IMG_UINT32	ui32Offset,
-				   IMG_UINT8	ui8Value)
-{
-#if !defined(NO_HARDWARE)
-	writeb(ui8Value, (IMG_PBYTE)pvLinRegBaseAddr+ui32Offset);
-#endif
-}
-
-/*
-	OSWriteHWReg16
-*/
-void OSWriteHWReg16(void		*pvLinRegBaseAddr,
-					IMG_UINT32	ui32Offset,
-					IMG_UINT16	ui16Value)
-{
-#if !defined(NO_HARDWARE)
-	writew(ui16Value, (IMG_PBYTE)pvLinRegBaseAddr+ui32Offset);
-#endif
-}
-
-/*
-	OSWriteHWReg32
-*/
-void OSWriteHWReg32(void		*pvLinRegBaseAddr,
-					IMG_UINT32	ui32Offset,
-					IMG_UINT32	ui32Value)
-{
-#if !defined(NO_HARDWARE)
-	writel(ui32Value, (IMG_PBYTE)pvLinRegBaseAddr+ui32Offset);
-#endif
-}
-
-
-/*
-	OSWriteHWReg64
-*/
-void OSWriteHWReg64(void		*pvLinRegBaseAddr,
-					IMG_UINT32	ui32Offset,
-					IMG_UINT64	ui64Value)
-{
-#if !defined(NO_HARDWARE)
-	IMG_UINT32 ui32ValueLow, ui32ValueHigh;
-
-	ui32ValueLow = ui64Value & 0xffffffff;
-	ui32ValueHigh = ((IMG_UINT64) (ui64Value >> 32)) & 0xffffffff;
-
-	writel(ui32ValueLow, pvLinRegBaseAddr + ui32Offset);
-	writel(ui32ValueHigh, pvLinRegBaseAddr + ui32Offset + 4);
-#endif
-}
-
-IMG_DEVMEM_SIZE_T OSWriteHWRegBank(void *pvLinRegBaseAddr,
-								   IMG_UINT32 ui32Offset,
-								   IMG_UINT8 *pui8SrcBuf,
-								   IMG_DEVMEM_SIZE_T uiSrcBufLen)
-{
-#if !defined(NO_HARDWARE)
-	IMG_DEVMEM_SIZE_T uiCounter;
-
-	for(uiCounter = 0; uiCounter < uiSrcBufLen; uiCounter++) {
-		writeb(*(pui8SrcBuf + uiCounter),
-		       pvLinRegBaseAddr + ui32Offset + uiCounter);
-	}
-
-	return uiCounter;
-#else
-	return uiSrcBufLen;
-#endif
-}
-
 #define	OS_MAX_TIMERS	8
 
 /* Timer callback strucure used by OSAddTimer */
@@ -1362,15 +1131,11 @@
 static TIMER_CALLBACK_DATA sTimers[OS_MAX_TIMERS];
 
 #if defined(PVR_LINUX_TIMERS_USING_WORKQUEUES) || defined(PVR_LINUX_TIMERS_USING_SHARED_WORKQUEUE)
-DEFINE_MUTEX(sTimerStructLock);
+static DEFINE_MUTEX(sTimerStructLock);
 #else
-#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,39))
 /* The lock is used to control access to sTimers */
-static spinlock_t sTimerStructLock = SPIN_LOCK_UNLOCKED;
-#else
 static DEFINE_SPINLOCK(sTimerStructLock);
 #endif
-#endif
 
 static void OSTimerCallbackBody(TIMER_CALLBACK_DATA *psTimerCBData)
 {
@@ -1421,14 +1186,6 @@
 }
 #endif
 
-/*************************************************************************/ /*!
-@Function       OSAddTimer
-@Description    OS specific function to install a timer callback
-@Input          pfnTimerFunc    Timer callback
-@Input         *pvData          Callback data
-@Input          ui32MsTimeout   Callback period
-@Return         Valid handle success, NULL failure
-*/ /**************************************************************************/
 IMG_HANDLE OSAddTimer(PFN_TIMER_FUNC pfnTimerFunc, void *pvData, IMG_UINT32 ui32MsTimeout)
 {
 	TIMER_CALLBACK_DATA	*psTimerCBData;
@@ -1502,12 +1259,6 @@
 	return &sTimers[ui32i];
 }
 
-/*************************************************************************/ /*!
-@Function       OSRemoveTimer
-@Description    OS specific function to remove a timer callback
-@Input          hTimer : timer handle
-@Return         PVRSRV_ERROR
-*/ /**************************************************************************/
 PVRSRV_ERROR OSRemoveTimer (IMG_HANDLE hTimer)
 {
 	TIMER_CALLBACK_DATA *psTimerCBData = GetTimerStructure(hTimer);
@@ -1521,13 +1272,6 @@
 	return PVRSRV_OK;
 }
 
-
-/*************************************************************************/ /*!
-@Function       OSEnableTimer
-@Description    OS specific function to enable a timer callback
-@Input          hTimer    Timer handle
-@Return         PVRSRV_ERROR
-*/ /**************************************************************************/
 PVRSRV_ERROR OSEnableTimer (IMG_HANDLE hTimer)
 {
 	TIMER_CALLBACK_DATA *psTimerCBData = GetTimerStructure(hTimer);
@@ -1548,12 +1292,6 @@
 }
 
 
-/*************************************************************************/ /*!
-@Function       OSDisableTimer
-@Description    OS specific function to disable a timer callback
-@Input          hTimer    Timer handle
-@Return         PVRSRV_ERROR
-*/ /**************************************************************************/
 PVRSRV_ERROR OSDisableTimer (IMG_HANDLE hTimer)
 {
 	TIMER_CALLBACK_DATA *psTimerCBData = GetTimerStructure(hTimer);
@@ -1593,13 +1331,6 @@
 }
 
 
-/*************************************************************************/ /*!
-@Function       OSEventObjectCreate
-@Description    OS specific function to create an event object
-@Input          pszName      Globally unique event object name (if null name must be autogenerated)
-@Output         hEventObject OS event object info structure
-@Return         PVRSRV_ERROR
-*/ /**************************************************************************/
 PVRSRV_ERROR OSEventObjectCreate(const IMG_CHAR *pszName, IMG_HANDLE *hEventObject)
 {
 	PVRSRV_ERROR eError = PVRSRV_OK;
@@ -1623,12 +1354,6 @@
 }
 
 
-/*************************************************************************/ /*!
-@Function       OSEventObjectDestroy
-@Description    OS specific function to destroy an event object
-@Input          hEventObject   OS event object info structure
-@Return         PVRSRV_ERROR
-*/ /**************************************************************************/
 PVRSRV_ERROR OSEventObjectDestroy(IMG_HANDLE hEventObject)
 {
 	PVRSRV_ERROR eError = PVRSRV_OK;
@@ -1650,85 +1375,44 @@
  * EventObjectWaitTimeout()
  */
 static PVRSRV_ERROR EventObjectWaitTimeout(IMG_HANDLE hOSEventKM,
-										   IMG_UINT32 uiTimeoutMs,
+										   IMG_UINT64 uiTimeoutus,
 										   IMG_BOOL bHoldBridgeLock)
 {
-    PVRSRV_ERROR eError;
+	PVRSRV_ERROR eError;
 
-	if(hOSEventKM && uiTimeoutMs > 0)
+	if(hOSEventKM && uiTimeoutus > 0)
 	{
-		eError = LinuxEventObjectWait(hOSEventKM, uiTimeoutMs, bHoldBridgeLock);
+		eError = LinuxEventObjectWait(hOSEventKM, uiTimeoutus, bHoldBridgeLock);
 	}
 	else
 	{
-		PVR_DPF((PVR_DBG_ERROR, "OSEventObjectWait: invalid arguments %p, %d", hOSEventKM, uiTimeoutMs ));
+		PVR_DPF((PVR_DBG_ERROR, "OSEventObjectWait: invalid arguments %p, %lld", hOSEventKM, uiTimeoutus));
 		eError = PVRSRV_ERROR_INVALID_PARAMS;
 	}
 
 	return eError;
 }
 
-/*************************************************************************/ /*!
-@Function       OSEventObjectWaitTimeout
-@Description    Wait for an event with timeout as supplied. Called from client
-@Input          hOSEventKM    OS and kernel specific handle to event object
-@Input          uiTimeoutMs   Non zero time period in milliseconds to wait
-@Return         PVRSRV_ERROR_TIMEOUT : Wait reached wait limit and timed out
-@Return         PVRSRV_ERROR         : any other system error code
-*/ /**************************************************************************/
-PVRSRV_ERROR OSEventObjectWaitTimeout(IMG_HANDLE hOSEventKM, IMG_UINT32 uiTimeoutMs)
+PVRSRV_ERROR OSEventObjectWaitTimeout(IMG_HANDLE hOSEventKM, IMG_UINT64 uiTimeoutus)
 {
-    return EventObjectWaitTimeout(hOSEventKM, uiTimeoutMs, IMG_FALSE);
+	return EventObjectWaitTimeout(hOSEventKM, uiTimeoutus, IMG_FALSE);
 }
 
-/*************************************************************************/ /*!
-@Function       OSEventObjectWait
-@Description    OS specific function to wait for an event object. Called
-				from client. Uses a default wait with 100ms timeout.
-@Input          hOSEventKM    OS and kernel specific handle to event object
-@Return         PVRSRV_ERROR_TIMEOUT  : Reached wait limit and timed out
-@Return         PVRSRV_ERROR  : any other system error code
-*/ /**************************************************************************/
 PVRSRV_ERROR OSEventObjectWait(IMG_HANDLE hOSEventKM)
 {
-	return OSEventObjectWaitTimeout(hOSEventKM, EVENT_OBJECT_TIMEOUT_MS);
+	return OSEventObjectWaitTimeout(hOSEventKM, EVENT_OBJECT_TIMEOUT_US);
 }
 
-/*************************************************************************/ /*!
-@Function       OSEventObjectWaitTimeoutAndHoldBridgeLock
-@Description    Wait for an event with timeout as supplied. Called from client
-                NOTE: Holds bridge lock during wait.
-@Input          hOSEventKM    OS and kernel specific handle to event object
-@Input          uiTimeoutMs   Non zero time period in milliseconds to wait
-@Return         PVRSRV_ERROR_TIMEOUT : Wait reached wait limit and timed out
-@Return         PVRSRV_ERROR         : any other system error code
-*/ /**************************************************************************/
-PVRSRV_ERROR OSEventObjectWaitTimeoutAndHoldBridgeLock(IMG_HANDLE hOSEventKM, IMG_UINT32 uiTimeoutMs)
+PVRSRV_ERROR OSEventObjectWaitTimeoutAndHoldBridgeLock(IMG_HANDLE hOSEventKM, IMG_UINT64 uiTimeoutus)
 {
-	return EventObjectWaitTimeout(hOSEventKM, uiTimeoutMs, IMG_TRUE);
+	return EventObjectWaitTimeout(hOSEventKM, uiTimeoutus, IMG_TRUE);
 }
 
-/*************************************************************************/ /*!
-@Function       OSEventObjectWaitAndHoldBridgeLock
-@Description    OS specific function to wait for an event object. Called
-				from client. Uses a default wait with 100ms timeout.
-                NOTE: Holds bridge lock during wait.
-@Input          hOSEventKM    OS and kernel specific handle to event object
-@Return         PVRSRV_ERROR_TIMEOUT  : Reached wait limit and timed out
-@Return         PVRSRV_ERROR  : any other system error code
-*/ /**************************************************************************/
 PVRSRV_ERROR OSEventObjectWaitAndHoldBridgeLock(IMG_HANDLE hOSEventKM)
 {
-	return OSEventObjectWaitTimeoutAndHoldBridgeLock(hOSEventKM, EVENT_OBJECT_TIMEOUT_MS);
+	return OSEventObjectWaitTimeoutAndHoldBridgeLock(hOSEventKM, EVENT_OBJECT_TIMEOUT_US);
 }
 
-/*************************************************************************/ /*!
-@Function       OSEventObjectOpen
-@Description    OS specific function to open an event object.  Called from client
-@Input          hEventObject  Pointer to an event object
-@Output         phOSEvent     OS and kernel specific handle to event object
-@Return         PVRSRV_ERROR
-*/ /**************************************************************************/
 PVRSRV_ERROR OSEventObjectOpen(IMG_HANDLE hEventObject,
 											IMG_HANDLE *phOSEvent)
 {
@@ -1751,12 +1435,6 @@
 	return eError;
 }
 
-/*************************************************************************/ /*!
-@Function       OSEventObjectClose
-@Description    OS specific function to close an event object.  Called from client
-@Input          hOSEventKM    OS and kernel specific handle to event object
-@Return         PVRSRV_ERROR  :
-*/ /**************************************************************************/
 PVRSRV_ERROR OSEventObjectClose(IMG_HANDLE hOSEventKM)
 {
 	PVRSRV_ERROR eError = PVRSRV_OK;
@@ -1779,12 +1457,6 @@
 	return eError;
 }
 
-/*************************************************************************/ /*!
-@Function       OSEventObjectSignal
-@Description    OS specific function to 'signal' an event object.  Called from L/MISR
-@Input          hOSEventKM   OS and kernel specific handle to event object
-@Return         PVRSRV_ERROR
-*/ /**************************************************************************/
 PVRSRV_ERROR OSEventObjectSignal(IMG_HANDLE hEventObject)
 {
 	PVRSRV_ERROR eError;
@@ -1802,24 +1474,11 @@
 	return eError;
 }
 
-/*************************************************************************/ /*!
-@Function       OSProcHasPrivSrvInit
-@Description    Does the process have sufficient privileges to initialise services?
-@Return         IMG_BOOL
-*/ /**************************************************************************/
 IMG_BOOL OSProcHasPrivSrvInit(void)
 {
 	return capable(CAP_SYS_ADMIN) != 0;
 }
 
-/*************************************************************************/ /*!
-@Function       OSCopyToUser
-@Description    Copy a block of data into user space
-@Input          pvSrc
-@Output         pvDest
-@Input          ui32Bytes
-@Return   PVRSRV_ERROR  :
-*/ /**************************************************************************/
 PVRSRV_ERROR OSCopyToUser(void *pvProcess,
 						  void *pvDest,
 						  const void *pvSrc,
@@ -1833,14 +1492,6 @@
 		return PVRSRV_ERROR_FAILED_TO_COPY_VIRT_MEMORY;
 }
 
-/*************************************************************************/ /*!
-@Function       OSCopyFromUser
-@Description    Copy a block of data from the user space
-@Output         pvDest
-@Input          pvSrc
-@Input          ui32Bytes
-@Return         PVRSRV_ERROR  :
-*/ /**************************************************************************/
 PVRSRV_ERROR OSCopyFromUser(void *pvProcess,
 							void *pvDest,
 							const void *pvSrc,
@@ -1854,14 +1505,6 @@
 		return PVRSRV_ERROR_FAILED_TO_COPY_VIRT_MEMORY;
 }
 
-/*************************************************************************/ /*!
-@Function       OSAccessOK
-@Description    Checks if a user space pointer is valide
-@Input          eVerification
-@Input          pvUserPtr
-@Input          ui32Bytes
-@Return         IMG_BOOL :
-*/ /**************************************************************************/
 IMG_BOOL OSAccessOK(IMG_VERIFY_TEST eVerification, void *pvUserPtr, size_t ui32Bytes)
 {
 	IMG_INT linuxType;
@@ -1879,18 +1522,6 @@
 	return access_ok(linuxType, pvUserPtr, ui32Bytes);
 }
 
-
-void OSWriteMemoryBarrier(void)
-{
-	wmb();
-}
-
-
-void OSMemoryBarrier(void)
-{
-	mb();
-}
-
 IMG_UINT64 OSDivide64r64(IMG_UINT64 ui64Divident, IMG_UINT32 ui32Divisor, IMG_UINT32 *pui32Remainder)
 {
 	*pui32Remainder = do_div(ui64Divident, ui32Divisor);
@@ -1912,7 +1543,7 @@
 	{
 		PVR_ASSERT(!psTimerWorkQueue);
 
-		psTimerWorkQueue = create_workqueue("pvr_timer" PVRSRV_GPUVIRT_OSID_STR);
+		psTimerWorkQueue = create_workqueue("pvr_timer");
 		if (psTimerWorkQueue == NULL)
 		{
 			PVR_DPF((PVR_DBG_ERROR, "%s: couldn't create timer workqueue", __FUNCTION__));
@@ -1970,41 +1601,16 @@
 	mutex_unlock(&gPVRSRVLock);
 }
 
-struct task_struct *OSGetBridgeLockOwner(void)
+struct task_struct *BridgeLockGetOwner(void)
 {
 	return gsOwner;
 }
 
-static struct task_struct *gsPMRLockOwner;
-
-void PMRLock(void)
+IMG_BOOL BridgeLockIsLocked(void)
 {
-	OSLockAcquire(&gGlobalLookupPMRLock);
-	gsPMRLockOwner = current;
+	return OSLockIsLocked(&gPVRSRVLock);
 }
 
-void PMRUnlock(void)
-{
-	gsPMRLockOwner = NULL;
-	OSLockRelease(&gGlobalLookupPMRLock);
-}
-
-static struct task_struct *OSGetPMRLockOwner(void)
-{
-	return gsPMRLockOwner;
-}
-
-IMG_BOOL PMRIsLocked(void)
-{
-	return OSLockIsLocked(&gGlobalLookupPMRLock);
-}
-
-IMG_BOOL PMRIsLockedByMe(void)
-{
-	return (OSGetPMRLockOwner() == current);
-}
-
-
 /*************************************************************************/ /*!
 @Function		OSCreateStatisticEntry
 @Description	Create a statistic entry in the specified folder.
@@ -2046,6 +1652,19 @@
 	PVRDebugFSRemoveStatisticEntry((PVR_DEBUGFS_DRIVER_STAT *)pvEntry);
 } /* OSRemoveStatisticEntry */
 
+#if defined(PVRSRV_ENABLE_MEMTRACK_STATS_FILE)
+void *OSCreateRawStatisticEntry(const IMG_CHAR *pszFileName, void *pvParentDir,
+                                OS_STATS_PRINT_FUNC *pfStatsPrint)
+{
+	return (void *) PVRDebugFSCreateRawStatisticEntry(pszFileName, pvParentDir,
+	                                                  pfStatsPrint);
+}
+
+void OSRemoveRawStatisticEntry(void *pvEntry)
+{
+	PVRDebugFSRemoveRawStatisticEntry(pvEntry);
+}
+#endif
 
 /*************************************************************************/ /*!
 @Function		OSCreateStatisticFolder
@@ -2081,69 +1700,70 @@
 } /* OSRemoveStatisticFolder */
 
 
-/*************************************************************************/ /*!
-@Function		OSChangeSparseMemCPUAddrMap
-@Description    This function changes the CPU map of the underlying sparse
-				allocation.
-@return			PVRSRV_OK on success & error code on failure.
-*/ /**************************************************************************/
 PVRSRV_ERROR OSChangeSparseMemCPUAddrMap(void **psPageArray,
-		IMG_UINT64 sCpuVAddrBase,
-		uintptr_t sCpuPAHeapBase,
-		IMG_UINT32 ui32AllocPageCount,
-		IMG_UINT32 *pai32AllocIndices,
-		IMG_UINT32 ui32FreePageCount,
-		IMG_UINT32 *pai32FreeIndices,
-		IMG_UINT32	*pui32Status,
-		IMG_BOOL bIsLMA)
+                                         IMG_UINT64 sCpuVAddrBase,
+                                         IMG_CPU_PHYADDR sCpuPAHeapBase,
+                                         IMG_UINT32 ui32AllocPageCount,
+                                         IMG_UINT32 *pai32AllocIndices,
+                                         IMG_UINT32 ui32FreePageCount,
+                                         IMG_UINT32 *pai32FreeIndices,
+                                         IMG_BOOL bIsLMA)
 {
-	int eError = ~PVRSRV_OK;
-	struct mm_struct  *psMM= current->mm;
-	struct vm_area_struct *psVMA=NULL;
-	IMG_UINT64 uiPFN = 0, uiCPUVirtAddr=0;
-	IMG_UINT32	ui32Loop=0, ui32PageSize = OSGetPageSize();
-	struct address_space *mapping = NULL;
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 5, 0))
+	pfn_t sPFN;
+#else
+	IMG_UINT64 uiPFN;
+#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 5, 0)) */
+
+	PVRSRV_ERROR eError;
+
+	struct mm_struct  *psMM = current->mm;
+	struct vm_area_struct *psVMA = NULL;
+	struct address_space *psMapping = NULL;
+	struct page *psPage = NULL;
+
+	IMG_UINT64 uiCPUVirtAddr = 0;
+	IMG_UINT32 ui32Loop = 0;
+	IMG_UINT32 ui32PageSize = OSGetPageSize();
 	IMG_BOOL bMixedMap = IMG_FALSE;
-	struct page *page = NULL;
-	PVR_UNREFERENCED_PARAMETER(pui32Status);
 
 	/*
 	 * Acquire the lock before manipulating the VMA
 	 * In this case only mmap_sem lock would suffice as the pages associated with this VMA
-	 * are never meant to be swapped out
+	 * are never meant to be swapped out.
 	 *
-	 * In future in case the pages are marked as swapped, page_table_lock need to be acquired
-	 * in conjunction with this to stop the swap out of the pages
+	 * In the future, in case the pages are marked as swapped, page_table_lock needs
+	 * to be acquired in conjunction with this to disable page swapping.
 	 */
-	/*Find the Virtual Memory Area associated with the user base address */
+
+	/* Find the Virtual Memory Area associated with the user base address */
 	psVMA = find_vma(psMM, (uintptr_t)sCpuVAddrBase);
-	if(NULL == psVMA)
+	if (NULL == psVMA)
 	{
 		eError = PVRSRV_ERROR_PMR_NO_CPU_MAP_FOUND;
 		return eError;
 	}
 
-	/*Acquire the memory sem */
+	/* Acquire the memory sem */
 	down_write(&psMM->mmap_sem);
 
-	mapping = psVMA->vm_file->f_mapping;
+	psMapping = psVMA->vm_file->f_mapping;
 	
-	/*Set the page offset to the correct value as this is disturbed in MMAP_PMR func*/
+	/* Set the page offset to the correct value as this is disturbed in MMAP_PMR func */
 	psVMA->vm_pgoff = (psVMA->vm_start >>  PAGE_SHIFT);
 
-	/*Delete the entries for the pages that got freed */
-	if(ui32FreePageCount && (pai32FreeIndices != NULL))
+	/* Delete the entries for the pages that got freed */
+	if (ui32FreePageCount && (pai32FreeIndices != NULL))
 	{
-		for(ui32Loop = 0; ui32Loop < ui32FreePageCount; ui32Loop++)
+		for (ui32Loop = 0; ui32Loop < ui32FreePageCount; ui32Loop++)
 		{
-			uiCPUVirtAddr = (uintptr_t)(sCpuVAddrBase+(pai32FreeIndices[ui32Loop] * ui32PageSize));
+			uiCPUVirtAddr = (uintptr_t)(sCpuVAddrBase + (pai32FreeIndices[ui32Loop] * ui32PageSize));
 
-			unmap_mapping_range(mapping,uiCPUVirtAddr,ui32PageSize,1);
-
+			unmap_mapping_range(psMapping, uiCPUVirtAddr, ui32PageSize, 1);
 
 #ifndef PVRSRV_UNMAP_ON_SPARSE_CHANGE
 			/*
-			 * Still need to map pages in case remap flag is set
+			 * Still need to map pages in case remap flag is set.
 			 * That is not done until the remap case succeeds
 			 */
 #endif
@@ -2151,22 +1771,28 @@
 		eError = PVRSRV_OK;
 	}
 
-	if((psVMA->vm_flags & VM_MIXEDMAP) || bIsLMA)
+	if ((psVMA->vm_flags & VM_MIXEDMAP) || bIsLMA)
 	{
 		psVMA->vm_flags |=  VM_MIXEDMAP;
 		bMixedMap = IMG_TRUE;
 	}
 	else
 	{
-		if(ui32AllocPageCount && (NULL != pai32AllocIndices))
+		if (ui32AllocPageCount && (NULL != pai32AllocIndices))
 		{
-			for(ui32Loop = 0; ui32Loop < ui32AllocPageCount; ui32Loop++)
+			for (ui32Loop = 0; ui32Loop < ui32AllocPageCount; ui32Loop++)
 			{
 
-				page = (struct page *)psPageArray[pai32AllocIndices[ui32Loop]];
-				uiPFN = page_to_pfn((struct page *)psPageArray[pai32AllocIndices[ui32Loop]]);
+				psPage = (struct page *)psPageArray[pai32AllocIndices[ui32Loop]];
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 5, 0))
+				sPFN = page_to_pfn_t(psPage);
 
-				if(!pfn_valid(uiPFN) || (page_count(pfn_to_page(uiPFN)) == 0))
+				if (!pfn_t_valid(sPFN) || page_count(pfn_t_to_page(sPFN)) == 0)
+#else
+				uiPFN = page_to_pfn(psPage);
+
+				if (!pfn_valid(uiPFN) || (page_count(pfn_to_page(uiPFN)) == 0))
+#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 5, 0)) */
 				{
 					bMixedMap = IMG_TRUE;
 					psVMA->vm_flags |= VM_MIXEDMAP;
@@ -2176,43 +1802,96 @@
 		}
 	}
 
-	/*Map the pages that got allocated */
-	if(ui32AllocPageCount && (NULL != pai32AllocIndices))
+	/* Map the pages that got allocated */
+	if (ui32AllocPageCount && (NULL != pai32AllocIndices))
 	{
-		for(ui32Loop = 0; ui32Loop < ui32AllocPageCount; ui32Loop++)
+		for (ui32Loop = 0; ui32Loop < ui32AllocPageCount; ui32Loop++)
 		{
-			uiCPUVirtAddr = (uintptr_t)(sCpuVAddrBase+(pai32AllocIndices[ui32Loop] * ui32PageSize));
+			int err;
 
-			unmap_mapping_range(mapping,uiCPUVirtAddr,ui32PageSize, 1);
-			if(bIsLMA)
-			{
-				uiPFN = sCpuPAHeapBase+((IMG_DEV_PHYADDR *)psPageArray)[pai32AllocIndices[ui32Loop]].uiAddr;
-				uiPFN  = uiPFN >> PAGE_SHIFT;
-				page = pfn_to_page(uiPFN);
-			}else{
-				page = (struct page *)psPageArray[pai32AllocIndices[ui32Loop]];
-				uiPFN = page_to_pfn((struct page *)psPageArray[pai32AllocIndices[ui32Loop]]);
-			}
+			uiCPUVirtAddr = (uintptr_t)(sCpuVAddrBase + (pai32AllocIndices[ui32Loop] * ui32PageSize));
+			unmap_mapping_range(psMapping, uiCPUVirtAddr, ui32PageSize, 1);
 
-			if(bMixedMap )
+			if (bIsLMA)
 			{
-				eError = vm_insert_mixed(psVMA,uiCPUVirtAddr, uiPFN);
+				phys_addr_t uiAddr = sCpuPAHeapBase.uiAddr +
+				                     ((IMG_DEV_PHYADDR *)psPageArray)[pai32AllocIndices[ui32Loop]].uiAddr;
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 5, 0))
+				sPFN = phys_to_pfn_t(uiAddr, 0);
+				psPage = pfn_t_to_page(sPFN);
+#else
+				uiPFN = uiAddr >> PAGE_SHIFT;
+				psPage = pfn_to_page(uiPFN);
+#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 5, 0)) */
 			}
 			else
 			{
-				eError = vm_insert_page(psVMA,uiCPUVirtAddr,page);
+				psPage = (struct page *)psPageArray[pai32AllocIndices[ui32Loop]];
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 5, 0))
+				sPFN = page_to_pfn_t(psPage);
+#else
+				uiPFN = page_to_pfn(psPage);
+#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 5, 0)) */
 			}
 
-			if(0 != eError)
+			if (bMixedMap)
 			{
-				PVR_DPF((PVR_DBG_MESSAGE,"Remap failure error code: %d", eError));
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 5, 0))
+				err = vm_insert_mixed(psVMA, uiCPUVirtAddr, sPFN);
+#else
+				err = vm_insert_mixed(psVMA, uiCPUVirtAddr, uiPFN);
+#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 5, 0)) */
+			}
+			else
+			{
+				err = vm_insert_page(psVMA, uiCPUVirtAddr, psPage);
+			}
+
+			if (err)
+			{
+				PVR_DPF((PVR_DBG_MESSAGE, "Remap failure error code: %d", err));
 				eError = PVRSRV_ERROR_PMR_CPU_PAGE_MAP_FAILED;
 				goto eFailed;
 			}
 		}
 	}
+
 	eError = PVRSRV_OK;
 	eFailed:
 	up_write(&psMM->mmap_sem);
+
 	return eError;
 }
+
+/*************************************************************************/ /*!
+@Function       OSDebugSignalPID
+@Description    Sends a SIGTRAP signal to a specific PID in user mode for
+                debugging purposes. The user mode process can register a handler
+                against this signal.
+                This is necessary to support the Rogue debugger. If the Rogue
+                debugger is not used then this function may be implemented as
+                a stub.
+@Input          ui32PID    The PID for the signal.
+@Return         PVRSRV_OK on success, a failure code otherwise.
+*/ /**************************************************************************/
+PVRSRV_ERROR OSDebugSignalPID(IMG_UINT32 ui32PID)
+{
+	int err;
+	struct pid *psPID;
+
+	psPID = find_vpid(ui32PID);
+	if (psPID == NULL)
+	{
+		PVR_DPF((PVR_DBG_ERROR, "%s: Failed to get PID struct.", __func__));
+		return PVRSRV_ERROR_NOT_FOUND;
+	}
+
+	err = kill_pid(psPID, SIGTRAP, 0);
+	if (err != 0)
+	{
+		PVR_DPF((PVR_DBG_ERROR, "%s: Signal Failure %d", __func__, err));
+		return PVRSRV_ERROR_SIGNAL_FAILED;
+	}
+
+	return PVRSRV_OK;
+}
diff --git a/drivers/staging/imgtec/rogue/osfunc.h b/drivers/staging/imgtec/rogue/osfunc.h
index 55f324c..26fb8e2 100644
--- a/drivers/staging/imgtec/rogue/osfunc.h
+++ b/drivers/staging/imgtec/rogue/osfunc.h
@@ -50,17 +50,25 @@
 #define __OSFUNC_H__
 
 
-#if defined(__KERNEL__) && defined(ANDROID) && !defined(__GENKSYMS__)
+#if defined(__KERNEL__) && defined(LINUX) && !defined(__GENKSYMS__)
 #define __pvrsrv_defined_struct_enum__
 #include <services_kernel_client.h>
 #endif
 
+#if defined(LINUX) && defined(__KERNEL__) && !defined(NO_HARDWARE)
+#include <asm/io.h>
+#endif
+
 #if defined(__QNXNTO__)
 #include <stdio.h>
 #include <stdarg.h>
 #include <string.h>
 #endif
 
+#if defined(INTEGRITY_OS)
+#include <string.h>
+#endif
+
 #include "img_types.h"
 #include "pvrsrv_device.h"
 #include "device.h"
@@ -71,43 +79,194 @@
 #define KERNEL_ID			0xffffffffL
 #define ISR_ID				0xfffffffdL
 
+/*************************************************************************/ /*!
+@Function       OSClockns64
+@Description    This function returns the number of ticks since system boot
+                expressed in nanoseconds. Unlike OSClockns, OSClockns64 has
+                a near 64-bit range.
+@Return         The 64-bit clock value, in nanoseconds.
+*/ /**************************************************************************/
 IMG_UINT64 OSClockns64(void);
+
+/*************************************************************************/ /*!
+@Function       OSClockus64
+@Description    This function returns the number of ticks since system boot
+                expressed in microseconds. Unlike   OSClockus, OSClockus64 has
+                a near 64-bit range.
+@Return         The 64-bit clock value, in microseconds.
+*/ /**************************************************************************/
 IMG_UINT64 OSClockus64(void);
+
+/*************************************************************************/ /*!
+@Function       OSClockus
+@Description    This function returns the number of ticks since system boot
+                in microseconds.
+@Return         The 32-bit clock value, in microseconds.
+*/ /**************************************************************************/
 IMG_UINT32 OSClockus(void);
+
+/*************************************************************************/ /*!
+@Function       OSClockms
+@Description    This function returns the number of ticks since system boot
+                in milliseconds.
+@Return         The 32-bit clock value, in milliseconds.
+*/ /**************************************************************************/
 IMG_UINT32 OSClockms(void);
 
+/*************************************************************************/ /*!
+@Function       OSClockMonotonicns64
+@Description    This function returns a clock value based on the system
+                monotonic clock.
+@Output         pui64Time     The 64-bit clock value, in nanoseconds.
+@Return         Error Code.
+*/ /**************************************************************************/
+PVRSRV_ERROR OSClockMonotonicns64(IMG_UINT64 *pui64Time);
+
+/*************************************************************************/ /*!
+@Function       OSClockMonotonicus64
+@Description    This function returns a clock value based on the system
+                monotonic clock.
+@Output         pui64Time     The 64-bit clock value, in microseconds.
+@Return         Error Code.
+*/ /**************************************************************************/
+PVRSRV_ERROR OSClockMonotonicus64(IMG_UINT64 *pui64Time);
+
+/*************************************************************************/ /*!
+@Function       OSClockMonotonicRawns64
+@Description    This function returns a clock value based on the system
+                monotonic raw clock.
+@Return         64bit ns timestamp
+*/ /**************************************************************************/
+IMG_UINT64 OSClockMonotonicRawns64(void);
+
+/*************************************************************************/ /*!
+@Function       OSClockMonotonicRawns64
+@Description    This function returns a clock value based on the system
+                monotonic raw clock.
+@Return         64bit us timestamp
+*/ /**************************************************************************/
+IMG_UINT64 OSClockMonotonicRawus64(void);
+
+/*************************************************************************/ /*!
+@Function       OSGetPageSize
+@Description    This function returns the page size.
+                If the OS is not using memory mappings it should return a
+                default value of 4096.
+@Return         The size of a page, in bytes.
+*/ /**************************************************************************/
 size_t OSGetPageSize(void);
+
+/*************************************************************************/ /*!
+@Function       OSGetPageShift
+@Description    This function returns the page size expressed as a power
+                of two. A number of pages, left-shifted by this value, gives
+                the equivalent size in bytes.
+                If the OS is not using memory mappings it should return a
+                default value of 12.
+@Return         The page size expressed as a power of two.
+*/ /**************************************************************************/
 size_t OSGetPageShift(void);
+
+/*************************************************************************/ /*!
+@Function       OSGetPageMask
+@Description    This function returns a bitmask that may be applied to an
+                address to mask off the least-significant bits so as to
+                leave the start address of the page containing that address.
+@Return         The page mask.
+*/ /**************************************************************************/
 size_t OSGetPageMask(void);
+
+/*************************************************************************/ /*!
+@Function       OSGetOrder
+@Description    This function returns the order of power of two for a given
+                size. Eg. for a uSize of 4096 bytes the function would
+                return 12 (4096 = 2^12).
+@Input          uSize     The size in bytes.
+@Return         The order of power of two.
+*/ /**************************************************************************/
 size_t OSGetOrder(size_t uSize);
 
+typedef void (*PFN_MISR)(void *pvData);
 typedef void (*PFN_THREAD)(void *pvData);
 
+/**************************************************************************/ /*!
+@Function       OSChangeSparseMemCPUAddrMap
+@Description    This function changes the CPU mapping of the underlying
+                sparse allocation. It is used by a PMR 'factory'
+                implementation if that factory supports sparse
+                allocations.
+@Input          psPageArray        array representing the pages in the
+                                   sparse allocation
+@Input          sCpuVAddrBase      the virtual base address of the sparse
+                                   allocation ('first' page)
+@Input          sCpuPAHeapBase     the physical address of the virtual
+                                   base address 'sCpuVAddrBase'
+@Input          ui32AllocPageCount the number of pages referenced in
+                                   'pai32AllocIndices'
+@Input          pai32AllocIndices  list of indices of pages within
+                                   'psPageArray' that we now want to
+                                   allocate and map
+@Input          ui32FreePageCount  the number of pages referenced in
+                                   'pai32FreeIndices'
+@Input          pai32FreeIndices   list of indices of pages within
+                                   'psPageArray' we now want to
+                                   unmap and free
+@Input          bIsLMA             flag indicating if the sparse allocation
+                                   is from LMA or UMA memory
+@Return         PVRSRV_OK on success, a failure code otherwise.
+ */ /**************************************************************************/
 PVRSRV_ERROR OSChangeSparseMemCPUAddrMap(void **psPageArray,
-										IMG_UINT64 sCpuVAddrBase,
-										uintptr_t sCpuPAHeapBase,
-										IMG_UINT32 ui32AllocPageCount,
-										IMG_UINT32 *pai32AllocIndices,
-										IMG_UINT32 ui32FreePageCount,
-										IMG_UINT32 *pai32FreeIndices,
-										IMG_UINT32	*pui32Status,
-										IMG_BOOL bIsLMA);
+                                         IMG_UINT64 sCpuVAddrBase,
+                                         IMG_CPU_PHYADDR sCpuPAHeapBase,
+                                         IMG_UINT32 ui32AllocPageCount,
+                                         IMG_UINT32 *pai32AllocIndices,
+                                         IMG_UINT32 ui32FreePageCount,
+                                         IMG_UINT32 *pai32FreeIndices,
+                                         IMG_BOOL bIsLMA);
 
-PVRSRV_ERROR OSInstallDeviceLISR(PVRSRV_DEVICE_CONFIG *psDevConfig,
-								 IMG_HANDLE *hLISRData,
-								 PFN_LISR pfnLISR,
-								 void *hData);
-PVRSRV_ERROR OSUninstallDeviceLISR(IMG_HANDLE hLISRData);
-
+/*************************************************************************/ /*!
+@Function       OSInstallMISR
+@Description    Installs a Mid-level Interrupt Service Routine (MISR)
+                which handles higher-level processing of interrupts from
+                the device (GPU).
+                An MISR runs outside of interrupt context, and so may be
+                descheduled. This means it can contain code that would
+                not be permitted in the LISR.
+                An MISR is invoked when OSScheduleMISR() is called. This
+                call should be made by installed LISR once it has completed
+                its interrupt processing.
+                Multiple MISRs may be installed by the driver to handle
+                different causes of interrupt.
+@Input          pfnMISR       pointer to the function to be installed
+                              as the MISR
+@Input          hData         private data provided to the MISR
+@Output         hMISRData     handle to the installed MISR (to be used
+                              for a subsequent uninstall)
+@Return         PVRSRV_OK on success, a failure code otherwise.
+*/ /**************************************************************************/
 PVRSRV_ERROR OSInstallMISR(IMG_HANDLE *hMISRData,
 						   PFN_MISR pfnMISR,
 						   void *hData);
+
+/*************************************************************************/ /*!
+@Function       OSUninstallMISR
+@Description    Uninstalls a Mid-level Interrupt Service Routine (MISR).
+@Input          hMISRData     handle to the installed MISR
+@Return         PVRSRV_OK on success, a failure code otherwise.
+*/ /**************************************************************************/
 PVRSRV_ERROR OSUninstallMISR(IMG_HANDLE hMISRData);
+
+/*************************************************************************/ /*!
+@Function       OSScheduleMISR
+@Description    Schedules a Mid-level Interrupt Service Routine (MISR) to be
+                executed. An MISR should be executed outside of interrupt
+                context, for example in a work queue.
+@Input          hMISRData     handle to the installed MISR
+@Return         PVRSRV_OK on success, a failure code otherwise.
+*/ /**************************************************************************/
 PVRSRV_ERROR OSScheduleMISR(IMG_HANDLE hMISRData);
 
 
-
-
 /*************************************************************************/ /*!
 @Function       OSThreadCreate
 @Description    Creates a kernel thread and starts it running. The caller
@@ -166,238 +325,1058 @@
                 thread to finish successfully, thereby providing a sync point
                 for the thread completing its work. No attempt is made to kill
                 or otherwise terminate the thread.
-@Input          phThread  The thread handle returned by OSThreadCreate().
+@Input          hThread   The thread handle returned by OSThreadCreate().
 @Return         Standard PVRSRV_ERROR error code.
 */ /**************************************************************************/
 PVRSRV_ERROR OSThreadDestroy(IMG_HANDLE hThread);
 
-void PVRSRVDeviceMemSet(void *pvDest, IMG_UINT8 ui8Value, size_t ui32Size);
-void PVRSRVDeviceMemCopy(void *pvDst, const void *pvSrc, size_t ui32Size);
+/*************************************************************************/ /*!
+@Function       OSSetThreadPriority
+@Description    Set the priority and weight of a thread
+@Input          hThread  			The thread handle.
+@Input			nThreadPriority		The integer value of the thread priority
+@Input			nThreadWeight		The integer value of the thread weight
+@Return         Standard PVRSRV_ERROR error code.
+*/ /**************************************************************************/
+PVRSRV_ERROR OSSetThreadPriority( IMG_HANDLE hThread,
+								  IMG_UINT32  nThreadPriority,
+								  IMG_UINT32  nThreadWeight);
 
 #if defined(__arm64__) || defined(__aarch64__) || defined (PVRSRV_DEVMEM_TEST_SAFE_MEMSETCPY)
-#define OSDeviceMemSet(a,b,c) PVRSRVDeviceMemSet((a), (b), (c))
-#define OSDeviceMemCopy(a,b,c) PVRSRVDeviceMemCopy((a), (b), (c))
-#define OSMemSet(a,b,c)  PVRSRVDeviceMemSet((a), (b), (c))
-#define OSMemCopy(a,b,c)  PVRSRVDeviceMemCopy((a), (b), (c))
-#else
-#define OSDeviceMemSet(a,b,c) memset((a), (b), (c))
-#define OSDeviceMemCopy(a,b,c) memcpy((a), (b), (c))
-#define OSMemSet(a,b,c)  memset((a), (b), (c))
-#define OSMemCopy(a,b,c)  memcpy((a), (b), (c))
-#endif
 
-#define OSCachedMemSet(a,b,c) memset((a), (b), (c))
+/* Workarounds for assumptions made that memory will not be mapped uncached
+ * in kernel or user address spaces on arm64 platforms (or other testing).
+ */
+
+/**************************************************************************/ /*!
+@Function       DeviceMemSet
+@Description    Set memory, whose mapping may be uncached, to a given value.
+                On some architectures, additional processing may be needed
+                if the mapping is uncached. In such cases, OSDeviceMemSet()
+                is defined as a call to this function.
+@Input          pvDest     void pointer to the memory to be set
+@Input          ui8Value   byte containing the value to be set
+@Input          ui32Size   the number of bytes to be set to the given value
+@Return         None
+ */ /**************************************************************************/
+void DeviceMemSet(void *pvDest, IMG_UINT8 ui8Value, size_t ui32Size);
+
+/**************************************************************************/ /*!
+@Function       DeviceMemCopy
+@Description    Copy values from one area of memory, to another, when one
+                or both mappings may be uncached.
+                On some architectures, additional processing may be needed
+                if mappings are uncached. In such cases, OSDeviceMemCopy()
+                is defined as a call to this function.
+@Input          pvDst      void pointer to the destination memory
+@Input          pvSrc      void pointer to the source memory
+@Input          ui32Size   the number of bytes to be copied
+@Return         None
+ */ /**************************************************************************/
+void DeviceMemCopy(void *pvDst, const void *pvSrc, size_t ui32Size);
+
+#define OSDeviceMemSet(a,b,c)  DeviceMemSet((a), (b), (c))
+#define OSDeviceMemCopy(a,b,c) DeviceMemCopy((a), (b), (c))
+#define OSCachedMemSet(a,b,c)  memset((a), (b), (c))
 #define OSCachedMemCopy(a,b,c) memcpy((a), (b), (c))
 
+#else /* !(defined(__arm64__) || defined(__aarch64__) || defined(PVRSRV_DEVMEM_TEST_SAFE_MEMSETCPY)) */
+
+/* Everything else */
+
+/**************************************************************************/ /*!
+@Function       OSDeviceMemSet
+@Description    Set memory, whose mapping may be uncached, to a given value.
+                On some architectures, additional processing may be needed
+                if the mapping is uncached.
+@Input          a     void pointer to the memory to be set
+@Input          b     byte containing the value to be set
+@Input          c     the number of bytes to be set to the given value
+@Return         Pointer to the destination memory.
+ */ /**************************************************************************/
+#define OSDeviceMemSet(a,b,c) memset((a), (b), (c))
+
+/**************************************************************************/ /*!
+@Function       OSDeviceMemCopy
+@Description    Copy values from one area of memory, to another, when one
+                or both mappings may be uncached.
+                On some architectures, additional processing may be needed
+                if mappings are uncached.
+@Input          a     void pointer to the destination memory
+@Input          b     void pointer to the source memory
+@Input          c     the number of bytes to be copied
+@Return         Pointer to the destination memory.
+ */ /**************************************************************************/
+#define OSDeviceMemCopy(a,b,c) memcpy((a), (b), (c))
+
+/**************************************************************************/ /*!
+@Function       OSCachedMemSet
+@Description    Set memory, where the mapping is known to be cached, to a
+                given value. This function exists to allow an optimal memset
+                to be performed when memory is known to be cached.
+@Input          a     void pointer to the memory to be set
+@Input          b     byte containing the value to be set
+@Input          c     the number of bytes to be set to the given value
+@Return         Pointer to the destination memory.
+ */ /**************************************************************************/
+#define OSCachedMemSet(a,b,c)  memset((a), (b), (c))
+
+/**************************************************************************/ /*!
+@Function       OSCachedMemCopy
+@Description    Copy values from one area of memory, to another, when both
+                mappings are known to be cached.
+                This function exists to allow an optimal memcpy to be
+                performed when memory is known to be cached.
+@Input          a     void pointer to the destination memory
+@Input          b     void pointer to the source memory
+@Input          c     the number of bytes to be copied
+@Return         Pointer to the destination memory.
+ */ /**************************************************************************/
+#define OSCachedMemCopy(a,b,c) memcpy((a), (b), (c))
+
+#endif /* !(defined(__arm64__) || defined(__aarch64__) || defined(PVRSRV_DEVMEM_TEST_SAFE_MEMSETCPY)) */
+
+/**************************************************************************/ /*!
+@Function       OSMapPhysToLin
+@Description    Maps physical memory into a linear address range.
+@Input          BasePAddr    physical CPU address
+@Input          ui32Bytes    number of bytes to be mapped
+@Input          ui32Flags    flags denoting the caching mode to be employed
+                             for the mapping (uncached/write-combined,
+                             cached coherent or cached incoherent).
+                             See pvrsrv_memallocflags.h for full flag bit
+                             definitions.
+@Return         Pointer to the new mapping if successful, NULL otherwise.
+ */ /**************************************************************************/
 void *OSMapPhysToLin(IMG_CPU_PHYADDR BasePAddr, size_t ui32Bytes, IMG_UINT32 ui32Flags);
+
+/**************************************************************************/ /*!
+@Function       OSUnMapPhysToLin
+@Description    Unmaps physical memory previously mapped by OSMapPhysToLin().
+@Input          pvLinAddr    the linear mapping to be unmapped
+@Input          ui32Bytes    number of bytes to be unmapped
+@Input          ui32Flags    flags denoting the caching mode that was employed
+                             for the original mapping.
+@Return         IMG_TRUE if unmapping was successful, IMG_FALSE otherwise.
+ */ /**************************************************************************/
 IMG_BOOL OSUnMapPhysToLin(void *pvLinAddr, size_t ui32Bytes, IMG_UINT32 ui32Flags);
 
-
+/**************************************************************************/ /*!
+@Function       OSCPUOperation
+@Description    Perform the specified cache operation on the CPU.
+@Input          eCacheOp      the type of cache operation to be performed
+@Return         PVRSRV_OK on success, a failure code otherwise.
+ */ /**************************************************************************/
 PVRSRV_ERROR OSCPUOperation(PVRSRV_CACHE_OP eCacheOp);
 
-void OSFlushCPUCacheRangeKM(void *pvVirtStart,
-							void *pvVirtEnd,
-							IMG_CPU_PHYADDR sCPUPhysStart,
-							IMG_CPU_PHYADDR sCPUPhysEnd);
+/**************************************************************************/ /*!
+@Function       OSFlushCPUCacheRangeKM
+@Description    Clean and invalidate the CPU cache for the specified
+                address range.
+@Input          psDevNode     device on which the allocation was made
+@Input          pvVirtStart   virtual start address of the range to be
+                              flushed
+@Input          pvVirtEnd     virtual end address of the range to be
+                              flushed
+@Input          sCPUPhysStart physical start address of the range to be
+                              flushed
+@Input          sCPUPhysEnd   physical end address of the range to be
+                              flushed
+@Return         None
+ */ /**************************************************************************/
+void OSFlushCPUCacheRangeKM(PVRSRV_DEVICE_NODE *psDevNode,
+                            void *pvVirtStart,
+                            void *pvVirtEnd,
+                            IMG_CPU_PHYADDR sCPUPhysStart,
+                            IMG_CPU_PHYADDR sCPUPhysEnd);
 
 
-void OSCleanCPUCacheRangeKM(void *pvVirtStart,
-							void *pvVirtEnd,
-							IMG_CPU_PHYADDR sCPUPhysStart,
-							IMG_CPU_PHYADDR sCPUPhysEnd);
+/**************************************************************************/ /*!
+@Function       OSCleanCPUCacheRangeKM
+@Description    Clean the CPU cache for the specified address range.
+                This writes out the contents of the cache and unsets the
+                'dirty' bit (which indicates the physical memory is
+                consistent with the cache contents).
+@Input          psDevNode     device on which the allocation was made
+@Input          pvVirtStart   virtual start address of the range to be
+                              cleaned
+@Input          pvVirtEnd     virtual end address of the range to be
+                              cleaned
+@Input          sCPUPhysStart physical start address of the range to be
+                              cleaned
+@Input          sCPUPhysEnd   physical end address of the range to be
+                              cleaned
+@Return         None
+ */ /**************************************************************************/
+void OSCleanCPUCacheRangeKM(PVRSRV_DEVICE_NODE *psDevNode,
+                            void *pvVirtStart,
+                            void *pvVirtEnd,
+                            IMG_CPU_PHYADDR sCPUPhysStart,
+                            IMG_CPU_PHYADDR sCPUPhysEnd);
 
-void OSInvalidateCPUCacheRangeKM(void *pvVirtStart,
-								 void *pvVirtEnd,
-								 IMG_CPU_PHYADDR sCPUPhysStart,
-								 IMG_CPU_PHYADDR sCPUPhysEnd);
+/**************************************************************************/ /*!
+@Function       OSInvalidateCPUCacheRangeKM
+@Description    Invalidate the CPU cache for the specified address range.
+                The cache must reload data from those addresses if they
+                are accessed.
+@Input          psDevNode     device on which the allocation was made
+@Input          pvVirtStart   virtual start address of the range to be
+                              invalidated
+@Input          pvVirtEnd     virtual end address of the range to be
+                              invalidated
+@Input          sCPUPhysStart physical start address of the range to be
+                              invalidated
+@Input          sCPUPhysEnd   physical end address of the range to be
+                              invalidated
+@Return         None
+ */ /**************************************************************************/
+void OSInvalidateCPUCacheRangeKM(PVRSRV_DEVICE_NODE *psDevNode,
+                                 void *pvVirtStart,
+                                 void *pvVirtEnd,
+                                 IMG_CPU_PHYADDR sCPUPhysStart,
+                                 IMG_CPU_PHYADDR sCPUPhysEnd);
 
-
+/**************************************************************************/ /*!
+@Function       OSCPUCacheOpAddressType
+@Description    Returns the address type (i.e. virtual/physical/both) that is 
+                used to perform cache maintenance on the CPU. This is used
+				to infer whether the virtual or physical address supplied to
+				the OSxxxCPUCacheRangeKM functions can be omitted when called.
+@Input          uiCacheOp       the type of cache operation to be performed
+@Return         PVRSRV_CACHE_OP_ADDR_TYPE
+ */ /**************************************************************************/
 PVRSRV_CACHE_OP_ADDR_TYPE OSCPUCacheOpAddressType(PVRSRV_CACHE_OP uiCacheOp);
 
+/*!
+ ******************************************************************************
+ * Cache attribute size type
+ *****************************************************************************/
 typedef enum _IMG_DCACHE_ATTRIBUTE_
 {
-	PVR_DCACHE_LINE_SIZE = 0,
-	PVR_DCACHE_ATTRIBUTE_COUNT
+	PVR_DCACHE_LINE_SIZE = 0,    /*!< The cache line size */
+	PVR_DCACHE_ATTRIBUTE_COUNT   /*!< The number of attributes (must be last) */
 } IMG_DCACHE_ATTRIBUTE;
 
+/**************************************************************************/ /*!
+@Function       OSCPUCacheAttributeSize
+@Description    Returns the size of a given cache attribute.
+                Typically this function is used to return the cache line
+                size, but may be extended to return the size of other
+                cache attributes.
+@Input          eCacheAttribute   the cache attribute whose size should
+                                  be returned.
+@Return         The size of the specified cache attribute, in bytes.
+ */ /**************************************************************************/
 IMG_UINT32 OSCPUCacheAttributeSize(IMG_DCACHE_ATTRIBUTE eCacheAttribute);
 
+/*************************************************************************/ /*!
+@Function       OSGetCurrentProcessID
+@Description    Returns ID of current process (thread group)
+@Return         ID of current process
+*****************************************************************************/
 IMG_PID OSGetCurrentProcessID(void);
+
+/*************************************************************************/ /*!
+@Function       OSGetCurrentProcessName
+@Description    Gets the name of current process
+@Return         Process name
+*****************************************************************************/
 IMG_CHAR *OSGetCurrentProcessName(void);
+
+/*************************************************************************/ /*!
+@Function		OSGetCurrentProcessVASpaceSize
+@Description	Returns the CPU virtual address space size of current process
+@Return			Process VA space size
+*/ /**************************************************************************/
+IMG_UINT64 OSGetCurrentProcessVASpaceSize(void);
+
+/*************************************************************************/ /*!
+@Function       OSGetCurrentThreadID
+@Description    Returns ID for current thread
+@Return         ID of current thread
+*****************************************************************************/
 uintptr_t OSGetCurrentThreadID(void);
 
+/*************************************************************************/ /*!
+@Function       OSGetCurrentClientProcessIDKM
+@Description    Returns ID of current client process (thread group) which
+                has made a bridge call into the server.
+                For some operating systems, this may simply be the current
+                process id. For others, it may be that a dedicated thread
+                is used to handle the processing of bridge calls and that
+                some additional processing is required to obtain the ID of
+                the client process making the bridge call.
+@Return         ID of current client process
+*****************************************************************************/
 IMG_PID OSGetCurrentClientProcessIDKM(void);
+
+/*************************************************************************/ /*!
+@Function       OSGetCurrentClientProcessNameKM
+@Description    Gets the name of current client process
+@Return         Client process name
+*****************************************************************************/
 IMG_CHAR *OSGetCurrentClientProcessNameKM(void);
+
+/*************************************************************************/ /*!
+@Function       OSGetCurrentClientThreadIDKM
+@Description    Returns ID for current client thread
+                For some operating systems, this may simply be the current
+                thread id. For others, it may be that a dedicated thread
+                is used to handle the processing of bridge calls and that
+                some additional processing is require to obtain the ID of
+                the client thread making the bridge call.
+@Return         ID of current client thread
+*****************************************************************************/
 uintptr_t OSGetCurrentClientThreadIDKM(void);
 
-
-
-
+/**************************************************************************/ /*!
+@Function       OSMemCmp
+@Description    Compares two blocks of memory for equality.
+@Input          pvBufA      Pointer to the first block of memory
+@Input          pvBufB      Pointer to the second block of memory
+@Input          uiLen       The number of bytes to be compared
+@Return         Value < 0 if pvBufA is less than pvBufB.
+                Value > 0 if pvBufB is less than pvBufA.
+                Value = 0 if pvBufA is equal to pvBufB.
+*****************************************************************************/
 IMG_INT OSMemCmp(void *pvBufA, void *pvBufB, size_t uiLen);
 
+/*************************************************************************/ /*!
+@Function       OSPhyContigPagesAlloc
+@Description    Allocates a number of contiguous physical pages.
+                If allocations made by this function are CPU cached then
+                OSPhyContigPagesClean has to be implemented to write the
+                cached data to memory.
+@Input          psDevNode     the device for which the allocation is
+                              required
+@Input          uiSize        the size of the required allocation (in bytes)
+@Output         psMemHandle   a returned handle to be used to refer to this
+                              allocation
+@Output         psDevPAddr    the physical address of the allocation
+@Return         PVRSRV_OK on success, a failure code otherwise.
+*****************************************************************************/
 PVRSRV_ERROR OSPhyContigPagesAlloc(PVRSRV_DEVICE_NODE *psDevNode, size_t uiSize,
 							PG_HANDLE *psMemHandle, IMG_DEV_PHYADDR *psDevPAddr);
 
+/*************************************************************************/ /*!
+@Function       OSPhyContigPagesFree
+@Description    Frees a previous allocation of contiguous physical pages
+@Input          psDevNode     the device on which the allocation was made
+@Input          psMemHandle   the handle of the allocation to be freed
+@Return         None.
+*****************************************************************************/
 void OSPhyContigPagesFree(PVRSRV_DEVICE_NODE *psDevNode, PG_HANDLE *psMemHandle);
 
+/*************************************************************************/ /*!
+@Function       OSPhyContigPagesMap
+@Description    Maps the specified allocation of contiguous physical pages
+                to a kernel virtual address
+@Input          psDevNode     the device on which the allocation was made
+@Input          psMemHandle   the handle of the allocation to be mapped
+@Input          uiSize        the size of the allocation (in bytes)
+@Input          psDevPAddr    the physical address of the allocation
+@Output         pvPtr         the virtual kernel address to which the
+                              allocation is now mapped
+@Return         PVRSRV_OK on success, a failure code otherwise.
+*****************************************************************************/
 PVRSRV_ERROR OSPhyContigPagesMap(PVRSRV_DEVICE_NODE *psDevNode, PG_HANDLE *psMemHandle,
 						size_t uiSize, IMG_DEV_PHYADDR *psDevPAddr,
 						void **pvPtr);
 
+/*************************************************************************/ /*!
+@Function       OSPhyContigPagesUnmap
+@Description    Unmaps the kernel mapping for the specified allocation of
+                contiguous physical pages
+@Input          psDevNode     the device on which the allocation was made
+@Input          psMemHandle   the handle of the allocation to be unmapped
+@Input          pvPtr         the virtual kernel address to which the
+                              allocation is currently mapped
+@Return         None.
+*****************************************************************************/
 void OSPhyContigPagesUnmap(PVRSRV_DEVICE_NODE *psDevNode, PG_HANDLE *psMemHandle, void *pvPtr);
 
 /*************************************************************************/ /*!
 @Function       OSPhyContigPagesClean
 @Description    Write the content of the specified allocation from CPU cache to
                 memory from (start + uiOffset) to (start + uiOffset + uiLength)
-
+                It is expected to be implemented as a cache clean operation but
+                it is allowed to fall back to a cache clean + invalidate
+                (i.e. flush).
+                If allocations returned by OSPhyContigPagesAlloc are always
+                uncached this can be implemented as nop.
+@Input          psDevNode     device on which the allocation was made
 @Input          psMemHandle   the handle of the allocation to be flushed
 @Input          uiOffset      the offset in bytes from the start of the 
                               allocation from where to start flushing
 @Input          uiLength      the amount to flush from the offset in bytes
 @Return         PVRSRV_OK on success, a failure code otherwise.
 *****************************************************************************/
-PVRSRV_ERROR OSPhyContigPagesClean(PG_HANDLE *psMemHandle,
+PVRSRV_ERROR OSPhyContigPagesClean(PVRSRV_DEVICE_NODE *psDevNode,
+                                   PG_HANDLE *psMemHandle,
                                    IMG_UINT32 uiOffset,
                                    IMG_UINT32 uiLength);
 
 
+/**************************************************************************/ /*!
+@Function       OSInitEnvData
+@Description    Called to initialise any environment-specific data. This
+                could include initialising the bridge calling infrastructure
+                or device memory management infrastructure.
+@Return         PVRSRV_OK on success, a failure code otherwise.
+ */ /**************************************************************************/
 PVRSRV_ERROR OSInitEnvData(void);
+
+/**************************************************************************/ /*!
+@Function       OSDeInitEnvData
+@Description    The counterpart to OSInitEnvData(). Called to free any
+                resources which may have been allocated by OSInitEnvData().
+@Return         None.
+ */ /**************************************************************************/
 void OSDeInitEnvData(void);
 
+/**************************************************************************/ /*!
+@Function       OSSScanf
+@Description    OS function to support the standard C sscanf() function.
+ */ /**************************************************************************/
+IMG_UINT32 OSVSScanf(IMG_CHAR *pStr, const IMG_CHAR *pszFormat, ...);
+
+/**************************************************************************/ /*!
+@Function       OSStringNCopy
+@Description    OS function to support the standard C strncpy() function.
+ */ /**************************************************************************/
 IMG_CHAR* OSStringNCopy(IMG_CHAR *pszDest, const IMG_CHAR *pszSrc, size_t uSize);
-IMG_INT32 OSSNPrintf(IMG_CHAR *pStr, size_t ui32Size, const IMG_CHAR *pszFormat, ...) IMG_FORMAT_PRINTF(3, 4);
+
+/**************************************************************************/ /*!
+@Function       OSSNPrintf
+@Description    OS function to support the standard C snprintf() function.
+ */ /**************************************************************************/
+IMG_INT32 OSSNPrintf(IMG_CHAR *pStr, size_t ui32Size, const IMG_CHAR *pszFormat, ...) __printf(3, 4);
+
+/**************************************************************************/ /*!
+@Function       OSStringLength
+@Description    OS function to support the standard C strlen() function.
+ */ /**************************************************************************/
 size_t OSStringLength(const IMG_CHAR *pStr);
+
+/**************************************************************************/ /*!
+@Function       OSStringNLength
+@Description    Return the length of a string, excluding the terminating null
+                byte ('\0'), but return at most 'uiCount' bytes. Only the first
+                'uiCount' bytes of 'pStr' are interrogated.
+@Input          pStr     pointer to the string
+@Input          uiCount  the maximum length to return
+@Return         Length of the string if less than 'uiCount' bytes, otherwise
+                'uiCount'.
+ */ /**************************************************************************/
 size_t OSStringNLength(const IMG_CHAR *pStr, size_t uiCount);
+
+/**************************************************************************/ /*!
+@Function       OSStringCompare
+@Description    OS function to support the standard C strcmp() function.
+ */ /**************************************************************************/
 IMG_INT32 OSStringCompare(const IMG_CHAR *pStr1, const IMG_CHAR *pStr2);
 
+/**************************************************************************/ /*!
+@Function       OSStringNCompare
+@Description    OS function to support the standard C strncmp() function.
+ */ /**************************************************************************/
+IMG_INT32 OSStringNCompare(const IMG_CHAR *pStr1, const IMG_CHAR *pStr2,
+                           size_t uiSize);
+
+/**************************************************************************/ /*!
+@Function       OSStringToUINT32
+@Description    Changes string to IMG_UINT32.
+ */ /**************************************************************************/
+PVRSRV_ERROR OSStringToUINT32(const IMG_CHAR *pStr, IMG_UINT32 ui32Base,
+                              IMG_UINT32 *ui32Result);
+
+/*************************************************************************/ /*!
+@Function       OSEventObjectCreate
+@Description    Create an event object.
+@Input          pszName         name to assign to the new event object.
+@Output         EventObject     the created event object.
+@Return         PVRSRV_OK on success, a failure code otherwise.
+*/ /**************************************************************************/
 PVRSRV_ERROR OSEventObjectCreate(const IMG_CHAR *pszName,
 								 IMG_HANDLE *EventObject);
+
+/*************************************************************************/ /*!
+@Function       OSEventObjectDestroy
+@Description    Destroy an event object.
+@Input          hEventObject    the event object to destroy.
+@Return         PVRSRV_OK on success, a failure code otherwise.
+*/ /**************************************************************************/
 PVRSRV_ERROR OSEventObjectDestroy(IMG_HANDLE hEventObject);
+
+/*************************************************************************/ /*!
+@Function       OSEventObjectSignal
+@Description    Signal an event object. Any thread waiting on that event
+                object will be woken.
+@Input          hEventObject    the event object to signal.
+@Return         PVRSRV_OK on success, a failure code otherwise.
+*/ /**************************************************************************/
 PVRSRV_ERROR OSEventObjectSignal(IMG_HANDLE hEventObject);
+
+/*************************************************************************/ /*!
+@Function       OSEventObjectWait
+@Description    Wait for an event object to signal. The function is passed
+                an OS event object handle (which allows the OS to have the
+                calling thread wait on the associated event object).
+                The calling thread will be rescheduled when the associated
+                event object signals.
+                If the event object has not signalled after a default timeout
+                period (defined in EVENT_OBJECT_TIMEOUT_MS), the function
+                will return with the result code PVRSRV_ERROR_TIMEOUT.
+
+                Note: The global bridge lock should be released while waiting
+                for the event object to signal (if held by the current thread).
+                The following logic should be implemented in the OS
+                implementation:
+                ...
+                bReleasePVRLock = (!bHoldBridgeLock &&
+                                   BridgeLockIsLocked() &&
+                                   current == BridgeLockGetOwner());
+                if (bReleasePVRLock == IMG_TRUE) OSReleaseBridgeLock();
+                ...
+                / * sleep & reschedule - wait for signal * /
+                ...
+                if (bReleasePVRLock == IMG_TRUE) OSReleaseBridgeLock();
+                ...
+
+@Input          hOSEventKM    the OS event object handle associated with
+                              the event object.
+@Return         PVRSRV_OK on success, a failure code otherwise.
+*/ /**************************************************************************/
 PVRSRV_ERROR OSEventObjectWait(IMG_HANDLE hOSEventKM);
-PVRSRV_ERROR OSEventObjectWaitTimeout(IMG_HANDLE hOSEventKM, IMG_UINT32 uiTimeoutMs);
+
+/*************************************************************************/ /*!
+@Function       OSEventObjectWaitTimeout
+@Description    Wait for an event object to signal or timeout. The function
+                is passed an OS event object handle (which allows the OS to
+                have the calling thread wait on the associated event object).
+                The calling thread will be rescheduled when the associated
+                event object signals.
+                If the event object has not signalled after the specified
+                timeout period (passed in 'uiTimeoutus'), the function
+                will return with the result code PVRSRV_ERROR_TIMEOUT.
+                NB. The global bridge lock should be released while waiting
+                for the event object to signal (if held by the current thread)
+                See OSEventObjectWait() for details.
+@Input          hOSEventKM    the OS event object handle associated with
+                              the event object.
+@Input          uiTimeoutus   the timeout period (in usecs)
+@Return         PVRSRV_OK on success, a failure code otherwise.
+*/ /**************************************************************************/
+PVRSRV_ERROR OSEventObjectWaitTimeout(IMG_HANDLE hOSEventKM, IMG_UINT64 uiTimeoutus);
+
+/*************************************************************************/ /*!
+@Function       OSEventObjectWaitAndHoldBridgeLock
+@Description    Wait for an event object to signal. The function is passed
+                an OS event object handle (which allows the OS to have the
+                calling thread wait on the associated event object).
+                The calling thread will be rescheduled when the associated
+                event object signals.
+                If the event object has not signalled after a default timeout
+                period (defined in EVENT_OBJECT_TIMEOUT_MS), the function
+                will return with the result code PVRSRV_ERROR_TIMEOUT.
+                The global bridge lock is held while waiting for the event
+                object to signal (this will prevent other bridge calls from
+                being serviced during this time).
+                See OSEventObjectWait() for details.
+@Input          hOSEventKM    the OS event object handle associated with
+                              the event object.
+@Return         PVRSRV_OK on success, a failure code otherwise.
+*/ /**************************************************************************/
 PVRSRV_ERROR OSEventObjectWaitAndHoldBridgeLock(IMG_HANDLE hOSEventKM);
-PVRSRV_ERROR OSEventObjectWaitTimeoutAndHoldBridgeLock(IMG_HANDLE hOSEventKM, IMG_UINT32 uiTimeoutMs);
+
+/*************************************************************************/ /*!
+@Function       OSEventObjectWaitTimeoutAndHoldBridgeLock
+@Description    Wait for an event object to signal or timeout. The function
+                is passed an OS event object handle (which allows the OS to
+                have the calling thread wait on the associated event object).
+                The calling thread will be rescheduled when the associated
+                event object signals.
+                If the event object has not signalled after the specified
+                timeout period (passed in 'uiTimeoutus'), the function
+                will return with the result code PVRSRV_ERROR_TIMEOUT.
+                The global bridge lock is held while waiting for the event
+                object to signal (this will prevent other bridge calls from
+                being serviced during this time).
+                See OSEventObjectWait() for details.
+@Input          hOSEventKM    the OS event object handle associated with
+                              the event object.
+@Input          uiTimeoutus   the timeout period (in usecs)
+@Return         PVRSRV_OK on success, a failure code otherwise.
+*/ /**************************************************************************/
+PVRSRV_ERROR OSEventObjectWaitTimeoutAndHoldBridgeLock(IMG_HANDLE hOSEventKM, IMG_UINT64 uiTimeoutus);
+
+/*************************************************************************/ /*!
+@Function       OSEventObjectOpen
+@Description    Open an OS handle on the specified event object.
+                This OS handle may then be used to make a thread wait for
+                that event object to signal.
+@Input          hEventObject    Event object handle.
+@Output         phOSEvent       OS handle to the returned event object.
+@Return         PVRSRV_OK on success, a failure code otherwise.
+*/ /**************************************************************************/
 PVRSRV_ERROR OSEventObjectOpen(IMG_HANDLE hEventObject,
 											IMG_HANDLE *phOSEvent);
+
+/*************************************************************************/ /*!
+@Function       OSEventObjectClose
+@Description    Close an OS handle previously opened for an event object.
+@Input          hOSEventKM      OS event object handle to close.
+@Return         PVRSRV_OK on success, a failure code otherwise.
+*/ /**************************************************************************/
 PVRSRV_ERROR OSEventObjectClose(IMG_HANDLE hOSEventKM);
 
-/* Avoid macros so we don't evaluate pslzSrc twice */
+/**************************************************************************/ /*!
+@Function       OSStringCopy
+@Description    OS function to support the standard C strcpy() function.
+ */ /**************************************************************************/
+/* Avoid macros so we don't evaluate pszSrc twice */
 static INLINE IMG_CHAR *OSStringCopy(IMG_CHAR *pszDest, const IMG_CHAR *pszSrc)
 {
 	return OSStringNCopy(pszDest, pszSrc, OSStringLength(pszSrc) + 1);
 }
 
-/*!
-******************************************************************************
-
- @Function OSWaitus
- 
- @Description 
-    This function implements a busy wait of the specified microseconds
-    This function does NOT release thread quanta
- 
- @Input ui32Timeus - (us)
-
- @Return void
-
-******************************************************************************/ 
+/*************************************************************************/ /*!
+@Function      OSWaitus
+@Description   Implements a busy wait of the specified number of microseconds.
+               This function does NOT release thread quanta.
+@Input         ui32Timeus     The duration of the wait period (in us)
+@Return        None.
+*/ /**************************************************************************/
 void OSWaitus(IMG_UINT32 ui32Timeus);
 
-
-/*!
-******************************************************************************
-
- @Function OSSleepms
- 
- @Description 
-    This function implements a sleep of the specified milliseconds
-    This function may allow pre-emption if implemented
- 
- @Input ui32Timems - (ms)
-
- @Return void
-
-******************************************************************************/ 
+/*************************************************************************/ /*!
+@Function       OSSleepms
+@Description    Implements a sleep of the specified number of milliseconds.
+                This function may allow pre-emption, meaning the thread
+                may potentially not be rescheduled for a longer period.
+@Input          ui32Timems    The duration of the sleep (in ms)
+@Return         None.
+*/ /**************************************************************************/
 void OSSleepms(IMG_UINT32 ui32Timems);
 
+/*************************************************************************/ /*!
+@Function       OSReleaseThreadQuanta
+@Description    Relinquishes the current thread's execution time-slice,
+                permitting the OS scheduler to schedule another thread.
+@Return         None.
+*/ /**************************************************************************/
 void OSReleaseThreadQuanta(void);
 
-IMG_UINT8 OSReadHWReg8(void *pvLinRegBaseAddr, IMG_UINT32 ui32Offset);
-IMG_UINT16 OSReadHWReg16(void *pvLinRegBaseAddr, IMG_UINT32 ui32Offset);
-IMG_UINT32 OSReadHWReg32(void *pvLinRegBaseAddr, IMG_UINT32 ui32Offset);
-IMG_UINT64 OSReadHWReg64(void *pvLinRegBaseAddr, IMG_UINT32 ui32Offset);
-IMG_UINT64 OSReadHWRegBank(void *pvLinRegBaseAddr, IMG_UINT32 ui32Offset, IMG_UINT8 *pui8DstBuf, IMG_UINT64 ui64DstBufLen);
+#if defined(LINUX) && defined(__KERNEL__) && !defined(NO_HARDWARE)
+	#define OSReadHWReg8(addr, off)  (IMG_UINT8)readb((IMG_PBYTE)(addr) + (off))
+	#define OSReadHWReg16(addr, off) (IMG_UINT16)readw((IMG_PBYTE)(addr) + (off))
+	#define OSReadHWReg32(addr, off) (IMG_UINT32)readl((IMG_PBYTE)(addr) + (off))
+	/* Little endian support only */
+	#define OSReadHWReg64(addr, off) \
+			({ \
+				__typeof__(addr) _addr = addr; \
+				__typeof__(off) _off = off; \
+				(IMG_UINT64) \
+				( \
+					( (IMG_UINT64)(readl((IMG_PBYTE)(_addr) + (_off) + 4)) << 32) \
+					| readl((IMG_PBYTE)(_addr) + (_off)) \
+				); \
+			})
 
-void OSWriteHWReg8(void *pvLinRegBaseAddr, IMG_UINT32 ui32Offset, IMG_UINT8 ui32Value);
-void OSWriteHWReg16(void *pvLinRegBaseAddr, IMG_UINT32 ui32Offset, IMG_UINT16 ui32Value);
-void OSWriteHWReg32(void *pvLinRegBaseAddr, IMG_UINT32 ui32Offset, IMG_UINT32 ui32Value);
-void OSWriteHWReg64(void *pvLinRegBaseAddr, IMG_UINT32 ui32Offset, IMG_UINT64 ui64Value);
-IMG_UINT64 OSWriteHWRegBank(void *pvLinRegBaseAddr, IMG_UINT32 ui32Offset, IMG_UINT8 *pui8SrcBuf, IMG_UINT64 ui64rcBufLen);
+	#define OSWriteHWReg8(addr, off, val)  writeb((IMG_UINT8)(val), (IMG_PBYTE)(addr) + (off))
+	#define OSWriteHWReg16(addr, off, val) writew((IMG_UINT16)(val), (IMG_PBYTE)(addr) + (off))
+	#define OSWriteHWReg32(addr, off, val) writel((IMG_UINT32)(val), (IMG_PBYTE)(addr) + (off))
+	/* Little endian support only */
+	#define OSWriteHWReg64(addr, off, val) do \
+			{ \
+				__typeof__(addr) _addr = addr; \
+				__typeof__(off) _off = off; \
+				__typeof__(val) _val = val; \
+				writel((IMG_UINT32)((_val) & 0xffffffff), (_addr) + (_off));	\
+				writel((IMG_UINT32)(((IMG_UINT64)(_val) >> 32) & 0xffffffff), (_addr) + (_off) + 4); \
+			} while (0)
+
+#elif defined(NO_HARDWARE)
+	/* FIXME: OSReadHWReg should not exist in no hardware builds */
+	#define OSReadHWReg8(addr, off)  (0x4eU)
+	#define OSReadHWReg16(addr, off) (0x3a4eU)
+	#define OSReadHWReg32(addr, off) (0x30f73a4eU)
+	#define OSReadHWReg64(addr, off) (0x5b376c9d30f73a4eU)
+
+	#define OSWriteHWReg8(addr, off, val)
+	#define OSWriteHWReg16(addr, off, val)
+	#define OSWriteHWReg32(addr, off, val)
+	#define OSWriteHWReg64(addr, off, val)
+#else
+/*************************************************************************/ /*!
+@Function       OSReadHWReg8
+@Description    Read from an 8-bit memory-mapped device register.
+                The implementation should not permit the compiler to
+                reorder the I/O sequence.
+                The implementation should ensure that for a NO_HARDWARE
+                build the code does not attempt to read from a location
+                but instead returns a constant value.
+@Input          pvLinRegBaseAddr   The virtual base address of the register
+                                   block.
+@Input          ui32Offset         The byte offset from the base address of
+                                   the register to be read.
+@Return         The byte read.
+*/ /**************************************************************************/
+	IMG_UINT8 OSReadHWReg8(void *pvLinRegBaseAddr, IMG_UINT32 ui32Offset);
+
+/*************************************************************************/ /*!
+@Function       OSReadHWReg16
+@Description    Read from a 16-bit memory-mapped device register.
+                The implementation should not permit the compiler to
+                reorder the I/O sequence.
+                The implementation should ensure that for a NO_HARDWARE
+                build the code does not attempt to read from a location
+                but instead returns a constant value.
+@Input          pvLinRegBaseAddr   The virtual base address of the register
+                                   block.
+@Input          ui32Offset         The byte offset from the base address of
+                                   the register to be read.
+@Return         The word read.
+*/ /**************************************************************************/
+	IMG_UINT16 OSReadHWReg16(void *pvLinRegBaseAddr, IMG_UINT32 ui32Offset);
+
+/*************************************************************************/ /*!
+@Function       OSReadHWReg32
+@Description    Read from a 32-bit memory-mapped device register.
+                The implementation should not permit the compiler to
+                reorder the I/O sequence.
+                The implementation should ensure that for a NO_HARDWARE
+                build the code does not attempt to read from a location
+                but instead returns a constant value.
+@Input          pvLinRegBaseAddr   The virtual base address of the register
+                                   block.
+@Input          ui32Offset         The byte offset from the base address of
+                                   the register to be read.
+@Return         The long word read.
+*/ /**************************************************************************/
+	IMG_UINT32 OSReadHWReg32(void *pvLinRegBaseAddr, IMG_UINT32 ui32Offset);
+
+/*************************************************************************/ /*!
+@Function       OSReadHWReg64
+@Description    Read from a 64-bit memory-mapped device register.
+                The implementation should not permit the compiler to
+                reorder the I/O sequence.
+                The implementation should ensure that for a NO_HARDWARE
+                build the code does not attempt to read from a location
+                but instead returns a constant value.
+@Input          pvLinRegBaseAddr   The virtual base address of the register
+                                   block.
+@Input          ui32Offset         The byte offset from the base address of
+                                   the register to be read.
+@Return         The long long word read.
+*/ /**************************************************************************/
+	IMG_UINT64 OSReadHWReg64(void *pvLinRegBaseAddr, IMG_UINT32 ui32Offset);
+
+/*************************************************************************/ /*!
+@Function       OSWriteHWReg8
+@Description    Write to an 8-bit memory-mapped device register.
+                The implementation should not permit the compiler to
+                reorder the I/O sequence.
+                The implementation should ensure that for a NO_HARDWARE
+                build the code does not attempt to write to a location.
+@Input          pvLinRegBaseAddr   The virtual base address of the register
+                                   block.
+@Input          ui32Offset         The byte offset from the base address of
+                                   the register to be written to.
+@Input          ui8Value           The byte to be written to the register.
+@Return         None.
+*/ /**************************************************************************/
+	void OSWriteHWReg8(void *pvLinRegBaseAddr, IMG_UINT32 ui32Offset, IMG_UINT8 ui8Value);
+
+/*************************************************************************/ /*!
+@Function       OSWriteHWReg16
+@Description    Write to a 16-bit memory-mapped device register.
+                The implementation should not permit the compiler to
+                reorder the I/O sequence.
+                The implementation should ensure that for a NO_HARDWARE
+                build the code does not attempt to write to a location.
+@Input          pvLinRegBaseAddr   The virtual base address of the register
+                                   block.
+@Input          ui32Offset         The byte offset from the base address of
+                                   the register to be written to.
+@Input          ui16Value          The word to be written to the register.
+@Return         None.
+*/ /**************************************************************************/
+	void OSWriteHWReg16(void *pvLinRegBaseAddr, IMG_UINT32 ui32Offset, IMG_UINT16 ui16Value);
+
+/*************************************************************************/ /*!
+@Function       OSWriteHWReg32
+@Description    Write to a 32-bit memory-mapped device register.
+                The implementation should not permit the compiler to
+                reorder the I/O sequence.
+                The implementation should ensure that for a NO_HARDWARE
+                build the code does not attempt to write to a location.
+@Input          pvLinRegBaseAddr   The virtual base address of the register
+                                   block.
+@Input          ui32Offset         The byte offset from the base address of
+                                   the register to be written to.
+@Input          ui32Value          The long word to be written to the register.
+@Return         None.
+*/ /**************************************************************************/
+	void OSWriteHWReg32(void *pvLinRegBaseAddr, IMG_UINT32 ui32Offset, IMG_UINT32 ui32Value);
+
+/*************************************************************************/ /*!
+@Function       OSWriteHWReg64
+@Description    Write to a 64-bit memory-mapped device register.
+                The implementation should not permit the compiler to
+                reorder the I/O sequence.
+                The implementation should ensure that for a NO_HARDWARE
+                build the code does not attempt to write to a location.
+@Input          pvLinRegBaseAddr   The virtual base address of the register
+                                   block.
+@Input          ui32Offset         The byte offset from the base address of
+                                   the register to be written to.
+@Input          ui64Value          The long long word to be written to the
+                                   register.
+@Return         None.
+*/ /**************************************************************************/
+	void OSWriteHWReg64(void *pvLinRegBaseAddr, IMG_UINT32 ui32Offset, IMG_UINT64 ui64Value);
+#endif
 
 typedef void (*PFN_TIMER_FUNC)(void*);
+/*************************************************************************/ /*!
+@Function       OSAddTimer
+@Description    OS specific function to install a timer callback. The
+                timer will then need to be enabled, as it is disabled by
+                default.
+                When enabled, the callback will be invoked once the specified
+                timeout has elapsed.
+@Input          pfnTimerFunc    Timer callback
+@Input          *pvData         Callback data
+@Input          ui32MsTimeout   Callback period
+@Return         Valid handle on success, NULL if a failure
+*/ /**************************************************************************/
 IMG_HANDLE OSAddTimer(PFN_TIMER_FUNC pfnTimerFunc, void *pvData, IMG_UINT32 ui32MsTimeout);
+
+/*************************************************************************/ /*!
+@Function       OSRemoveTimer
+@Description    Removes the specified timer. The handle becomes invalid and
+                should no longer be used.
+@Input          hTimer          handle of the timer to be removed
+@Return         PVRSRV_OK on success, a failure code otherwise.
+*/ /**************************************************************************/
 PVRSRV_ERROR OSRemoveTimer(IMG_HANDLE hTimer);
+
+/*************************************************************************/ /*!
+@Function       OSEnableTimer
+@Description    Enable the specified timer. after enabling, the timer will
+                invoke the associated callback at an interval determined by
+                the configured timeout period until disabled.
+@Input          hTimer          handle of the timer to be enabled
+@Return         PVRSRV_OK on success, a failure code otherwise.
+*/ /**************************************************************************/
 PVRSRV_ERROR OSEnableTimer(IMG_HANDLE hTimer);
+
+/*************************************************************************/ /*!
+@Function       OSDisableTimer
+@Description    Disable the specified timer
+@Input          hTimer          handle of the timer to be disabled
+@Return         PVRSRV_OK on success, a failure code otherwise.
+*/ /**************************************************************************/
 PVRSRV_ERROR OSDisableTimer(IMG_HANDLE hTimer);
 
 
-/******************************************************************************
-
- @Function		OSPanic
-
- @Description	Take action in response to an unrecoverable driver error
-
- @Input    void
-
- @Return   void
-
-******************************************************************************/
+/*************************************************************************/ /*!
+ @Function      OSPanic
+ @Description   Take action in response to an unrecoverable driver error
+ @Return        None
+*/ /**************************************************************************/
 void OSPanic(void);
 
+/*************************************************************************/ /*!
+@Function       OSProcHasPrivSrvInit
+@Description    Checks whether the current process has sufficient privileges
+                to initialise services
+@Return         IMG_TRUE if it does, IMG_FALSE if it does not.
+*/ /**************************************************************************/
 IMG_BOOL OSProcHasPrivSrvInit(void);
 
+/*!
+ ******************************************************************************
+ * Access operation verification type
+ *****************************************************************************/
 typedef enum _img_verify_test
 {
-	PVR_VERIFY_WRITE = 0,
-	PVR_VERIFY_READ
+	PVR_VERIFY_WRITE = 0,  /*!< Used with OSAccessOK() to check writing is possible */
+	PVR_VERIFY_READ        /*!< Used with OSAccessOK() to check reading is possible */
 } IMG_VERIFY_TEST;
 
+/*************************************************************************/ /*!
+@Function       OSAccessOK
+@Description    Checks that a user space pointer is valid
+@Input          eVerification    the test to be verified. This can be either
+                                 PVRSRV_VERIFY_WRITE or PVRSRV_VERIFY_READ.
+@Input          pvUserPtr        pointer to the memory to be checked
+@Input          ui32Bytes        size of the memory to be checked
+@Return         IMG_TRUE if the specified access is valid, IMG_FALSE if not.
+*/ /**************************************************************************/
 IMG_BOOL OSAccessOK(IMG_VERIFY_TEST eVerification, void *pvUserPtr, size_t ui32Bytes);
 
+/*************************************************************************/ /*!
+@Function       OSCopyFromUser
+@Description    Copy data from user-addressable memory to kernel-addressable
+                memory.
+                For operating systems that do not have a user/kernel space
+                distinction, this function should be implemented as a stub
+                which simply returns PVRSRV_ERROR_NOT_SUPPORTED.
+@Input          pvProcess        handle of the connection
+@Input          pvDest           pointer to the destination Kernel memory
+@Input          pvSrc            pointer to the source User memory
+@Input          ui32Bytes        size of the data to be copied
+@Return         PVRSRV_OK on success, a failure code otherwise.
+*/ /**************************************************************************/
 PVRSRV_ERROR OSCopyToUser(void *pvProcess, void *pvDest, const void *pvSrc, size_t ui32Bytes);
+
+/*************************************************************************/ /*!
+@Function       OSCopyToUser
+@Description    Copy data to user-addressable memory from kernel-addressable
+                memory.
+                For operating systems that do not have a user/kernel space
+                distinction, this function should be implemented as a stub
+                which simply returns PVRSRV_ERROR_NOT_SUPPORTED.
+@Input          pvProcess        handle of the connection
+@Input          pvDest           pointer to the destination User memory
+@Input          pvSrc            pointer to the source Kernel memory
+@Input          ui32Bytes        size of the data to be copied
+@Return         PVRSRV_OK on success, a failure code otherwise.
+*/ /**************************************************************************/
 PVRSRV_ERROR OSCopyFromUser(void *pvProcess, void *pvDest, const void *pvSrc, size_t ui32Bytes);
 
-#if defined (__linux__) || defined (WINDOWS_WDF)
+#if defined (__linux__) || defined (WINDOWS_WDF) || defined(INTEGRITY_OS)
 #define OSBridgeCopyFromUser OSCopyFromUser
 #define OSBridgeCopyToUser OSCopyToUser
 #else
+/*************************************************************************/ /*!
+@Function       OSBridgeCopyFromUser
+@Description    Copy data from user-addressable memory into kernel-addressable
+                memory as part of a bridge call operation.
+                For operating systems that do not have a user/kernel space
+                distinction, this function will require whatever implementation
+                is needed to pass data for making the bridge function call.
+                For operating systems which do have a user/kernel space
+                distinction (such as Linux) this function may be defined so
+                as to equate to a call to OSCopyFromUser().
+@Input          pvProcess        handle of the connection
+@Input          pvDest           pointer to the destination Kernel memory
+@Input          pvSrc            pointer to the source User memory
+@Input          ui32Bytes        size of the data to be copied
+@Return         PVRSRV_OK on success, a failure code otherwise.
+*/ /**************************************************************************/
 PVRSRV_ERROR OSBridgeCopyFromUser (void *pvProcess,
 						void *pvDest,
 						const void *pvSrc,
 						size_t ui32Bytes);
+
+/*************************************************************************/ /*!
+@Function       OSBridgeCopyToUser
+@Description    Copy data to user-addressable memory from kernel-addressable
+                memory as part of a bridge call operation.
+                For operating systems that do not have a user/kernel space
+                distinction, this function will require whatever implementation
+                is needed to pass data for making the bridge function call.
+                For operating systems which do have a user/kernel space
+                distinction (such as Linux) this function may be defined so
+                as to equate to a call to OSCopyToUser().
+@Input          pvProcess        handle of the connection
+@Input          pvDest           pointer to the destination User memory
+@Input          pvSrc            pointer to the source Kernel memory
+@Input          ui32Bytes        size of the data to be copied
+@Return         PVRSRV_OK on success, a failure code otherwise.
+*/ /**************************************************************************/
 PVRSRV_ERROR OSBridgeCopyToUser (void *pvProcess,
 						void *pvDest,
 						const void *pvSrc,
 						size_t ui32Bytes);
 #endif
 
-/* Fairly arbitrary sizes - hopefully enough for all bridge calls */
-#define PVRSRV_MAX_BRIDGE_IN_SIZE      0x2000
-#define PVRSRV_MAX_BRIDGE_OUT_SIZE     0x1000
+/* To be increased if required in future */
+#define PVRSRV_MAX_BRIDGE_IN_SIZE      0x2000    /*!< Size of the memory block used to hold data passed in to a bridge call */
+#define PVRSRV_MAX_BRIDGE_OUT_SIZE     0x1000    /*!< Size of the memory block used to hold data returned from a bridge call */
 
+/*************************************************************************/ /*!
+@Function       OSGetGlobalBridgeBuffers
+@Description    Returns the addresses and sizes of the buffers used to pass
+                data into and out of bridge function calls.
+@Output         ppvBridgeInBuffer         pointer to the input bridge data buffer
+                                          of size PVRSRV_MAX_BRIDGE_IN_SIZE.
+@Output         ppvBridgeOutBuffer        pointer to the output bridge data buffer
+                                          of size PVRSRV_MAX_BRIDGE_OUT_SIZE.
+@Return         PVRSRV_OK on success, a failure code otherwise.
+*/ /**************************************************************************/
 PVRSRV_ERROR OSGetGlobalBridgeBuffers (void **ppvBridgeInBuffer,
-							IMG_UINT32 *pui32BridgeInBufferSize,
-							void **ppvBridgeOutBuffer,
-							IMG_UINT32 *pui32BridgeOutBufferSize);
+									   void **ppvBridgeOutBuffer);
 
+/*************************************************************************/ /*!
+@Function       OSSetDriverSuspended
+@Description    Prevent processes from using the driver while it is
+                suspended. This function is not required for most operating
+                systems.
+@Return         IMG_TRUE on success, IMG_FALSE otherwise.
+*/ /**************************************************************************/
 IMG_BOOL OSSetDriverSuspended(void);
+
+/*************************************************************************/ /*!
+@Function       OSClearDriverSuspended
+@Description    Re-allows processes to use the driver when it is no longer
+                suspended. This function is not required for most operating
+                systems.
+@Return         IMG_TRUE on success, IMG_FALSE otherwise.
+*/ /**************************************************************************/
 IMG_BOOL OSClearDriverSuspended(void);
+
+/*************************************************************************/ /*!
+@Function       OSGetDriverSuspended
+@Description    Returns whether or not processes are unable to use the driver
+                (due to  it being suspended). This function is not required
+                for most operating systems.
+@Return         IMG_TRUE if the driver is suspended (use is not possible),
+                IMG_FALSE if the driver is not suspended (use is possible).
+*/ /**************************************************************************/
 IMG_BOOL OSGetDriverSuspended(void);
 
+#if defined(LINUX) && defined(__KERNEL__)
+#define OSWriteMemoryBarrier() wmb()
+#define OSReadMemoryBarrier() rmb()
+#define OSMemoryBarrier() mb()
+#else
+/*************************************************************************/ /*!
+@Function       OSWriteMemoryBarrier
+@Description    Insert a write memory barrier.
+                The write memory barrier guarantees that all store operations
+                (writes) specified before the barrier will appear to happen
+                before all of the store operations specified after the barrier.
+@Return         PVRSRV_OK on success, a failure code otherwise.
+*/ /**************************************************************************/
 void OSWriteMemoryBarrier(void);
+#define OSReadMemoryBarrier() OSMemoryBarrier()
+/*************************************************************************/ /*!
+@Function       OSMemoryBarrier
+@Description    Insert a read/write memory barrier.
+                The read and write memory barrier guarantees that all load
+                (read) and all store (write) operations specified before the
+                barrier will appear to happen before all of the load/store
+                operations specified after the barrier.
+@Return         None.
+*/ /**************************************************************************/
 void OSMemoryBarrier(void);
+#endif
+
+/*************************************************************************/ /*!
+@Function       PVRSRVToNativeError
+@Description    Returns the OS-specific equivalent error number/code for
+                the specified PVRSRV_ERROR value.
+                If there is no equivalent, or the PVRSRV_ERROR value is
+                PVRSRV_OK (no error), 0 is returned.
+@Return         The OS equivalent error code.
+*/ /**************************************************************************/
+int PVRSRVToNativeError(PVRSRV_ERROR e);
+#define OSPVRSRVToNativeError(e) ( (PVRSRV_OK == e)? 0: PVRSRVToNativeError(e) )
+
 
 #if defined(LINUX) && defined(__KERNEL__)
 
@@ -420,7 +1399,7 @@
 #define OSWRLockAcquireWrite(psLock) ({down_write(psLock); PVRSRV_OK;})
 #define OSWRLockReleaseWrite(psLock) ({up_write(psLock); PVRSRV_OK;})
 
-#elif defined(LINUX) || defined(__QNXNTO__)
+#elif defined(LINUX) || defined(__QNXNTO__) || defined (INTEGRITY_OS)
 /* User-mode unit tests use these definitions on Linux */
 
 typedef struct _OSWR_LOCK_ *POSWR_LOCK;
@@ -440,57 +1419,143 @@
 	typedef struct _OSWR_LOCK_ *POSWR_LOCK;
 #endif
 
+/*************************************************************************/ /*!
+@Function       OSWRLockCreate
+@Description    Create a writer/reader lock.
+                This type of lock allows multiple concurrent readers but
+                only a single writer, allowing for optimized performance.
+@Output         ppsLock     A handle to the created WR lock.
+@Return         PVRSRV_OK on success, a failure code otherwise.
+*/ /**************************************************************************/
 static INLINE PVRSRV_ERROR OSWRLockCreate(POSWR_LOCK *ppsLock)
 {
 	PVR_UNREFERENCED_PARAMETER(ppsLock);
 	return PVRSRV_OK;
 }
 
+/*************************************************************************/ /*!
+@Function       OSWRLockDestroy
+@Description    Destroys a writer/reader lock.
+@Input          psLock     The handle of the WR lock to be destroyed.
+@Return         None.
+*/ /**************************************************************************/
 static INLINE void OSWRLockDestroy(POSWR_LOCK psLock)
 {
 	PVR_UNREFERENCED_PARAMETER(psLock);
 }
 
+/*************************************************************************/ /*!
+@Function       OSWRLockAcquireRead
+@Description    Acquire a writer/reader read lock.
+                If the write lock is already acquired, the caller will
+                block until it is released.
+@Input          psLock     The handle of the WR lock to be acquired for
+                           reading.
+@Return         None.
+*/ /**************************************************************************/
 static INLINE void OSWRLockAcquireRead(POSWR_LOCK psLock)
 {
 	PVR_UNREFERENCED_PARAMETER(psLock);
 }
 
+/*************************************************************************/ /*!
+@Function       OSWRLockReleaseRead
+@Description    Release a writer/reader read lock.
+@Input          psLock     The handle of the WR lock whose read lock is to
+                           be released.
+@Return         None.
+*/ /**************************************************************************/
 static INLINE void OSWRLockReleaseRead(POSWR_LOCK psLock)
 {
 	PVR_UNREFERENCED_PARAMETER(psLock);
 }
 
+/*************************************************************************/ /*!
+@Function       OSWRLockAcquireWrite
+@Description    Acquire a writer/reader write lock.
+                If the write lock or any read lock are already acquired,
+                the caller will block until all are released.
+@Input          psLock     The handle of the WR lock to be acquired for
+                           writing.
+@Return         None.
+*/ /**************************************************************************/
 static INLINE void OSWRLockAcquireWrite(POSWR_LOCK psLock)
 {
 	PVR_UNREFERENCED_PARAMETER(psLock);
 }
 
+/*************************************************************************/ /*!
+@Function       OSWRLockReleaseWrite
+@Description    Release a writer/reader write lock.
+@Input          psLock     The handle of the WR lock whose write lock is to
+                           be released.
+@Return         None
+*/ /**************************************************************************/
 static INLINE void OSWRLockReleaseWrite(POSWR_LOCK psLock)
 {
 	PVR_UNREFERENCED_PARAMETER(psLock);
 }
 #endif
 
+/*************************************************************************/ /*!
+@Function       OSDivide64r64
+@Description    Divide a 64-bit value by a 32-bit value. Return the 64-bit
+                quotient.
+                The remainder is also returned in 'pui32Remainder'.
+@Input          ui64Divident        The number to be divided.
+@Input          ui32Divisor         The 32-bit value 'ui64Divident' is to
+                                    be divided by.
+@Output         pui32Remainder      The remainder of the division.
+@Return         The 64-bit quotient (result of the division).
+*/ /**************************************************************************/
 IMG_UINT64 OSDivide64r64(IMG_UINT64 ui64Divident, IMG_UINT32 ui32Divisor, IMG_UINT32 *pui32Remainder);
+
+/*************************************************************************/ /*!
+@Function       OSDivide64
+@Description    Divide a 64-bit value by a 32-bit value. Return a 32-bit
+                quotient.
+                The remainder is also returned in 'pui32Remainder'.
+                This function allows for a more optional implementation
+                of a 64-bit division when the result is known to be
+                representable in 32-bits.
+@Input          ui64Divident        The number to be divided.
+@Input          ui32Divisor         The 32-bit value 'ui64Divident' is to
+                                    be divided by.
+@Output         pui32Remainder      The remainder of the division.
+@Return         The 32-bit quotient (result of the division).
+*/ /**************************************************************************/
 IMG_UINT32 OSDivide64(IMG_UINT64 ui64Divident, IMG_UINT32 ui32Divisor, IMG_UINT32 *pui32Remainder);
 
+/*************************************************************************/ /*!
+@Function       OSDumpStack
+@Description    Dump the current task information and its stack trace.
+@Return         None
+*/ /**************************************************************************/
 void OSDumpStack(void);
 
+/*************************************************************************/ /*!
+@Function       OSAcquireBridgeLock
+@Description    Acquire the global bridge lock.
+                This prevents another bridge call from being actioned while
+                we are still servicing the current bridge call.
+                NB. This function must not return until the lock is acquired
+                (meaning the implementation should not timeout or return with
+                an error, as the caller will assume they have the lock).
+                This function has an OS-specific implementation rather than
+                an abstracted implementation for efficiency reasons, as it
+                is called frequently.
+@Return         None
+*/ /**************************************************************************/
 void OSAcquireBridgeLock(void);
+/*************************************************************************/ /*!
+@Function       OSReleaseBridgeLock
+@Description    Release the global bridge lock.
+                This function has an OS-specific implementation rather than
+                an abstracted implementation for efficiency reasons, as it
+                is called frequently.
+@Return         None
+*/ /**************************************************************************/
 void OSReleaseBridgeLock(void);
-#if defined(LINUX)
-void PMRLock(void);
-void PMRUnlock(void);
-IMG_BOOL PMRIsLocked(void);
-IMG_BOOL PMRIsLockedByMe(void);
-#else
-#define PMRLock()
-#define PMRUnlock()
-#define PMRIsLocked() IMG_FALSE
-#define PMRIsLockedByMe() IMG_FALSE
-#endif
-
 
 /*
  *  Functions for providing support for PID statistics.
@@ -504,17 +1569,143 @@
 typedef IMG_UINT32 (OS_INC_STATS_MEM_REFCOUNT_FUNC)(void *pvStatPtr);
 typedef IMG_UINT32 (OS_DEC_STATS_MEM_REFCOUNT_FUNC)(void *pvStatPtr);
 
+/*************************************************************************/ /*!
+@Function       OSCreateStatisticEntry
+@Description    Create a statistic entry in the specified folder.
+                Where operating systems do not support a debugfs,
+                file system this function may be implemented as a stub.
+@Input          pszName        String containing the name for the entry.
+@Input          pvFolder       Reference from OSCreateStatisticFolder() of the
+                               folder to create the entry in, or NULL for the
+                               root.
+@Input          pfnStatsPrint  Pointer to function that can be used to print the
+                               values of all the statistics.
+@Input          pfnIncMemRefCt Pointer to function that can be used to take a
+                               reference on the memory backing the statistic
+                               entry.
+@Input          pfnDecMemRefCt Pointer to function that can be used to drop a
+                               reference on the memory backing the statistic
+                               entry.
+@Input          pvData         OS specific reference that can be used by
+                               pfnGetElement.
+@Return	        Pointer void reference to the entry created, which can be
+                passed to OSRemoveStatisticEntry() to remove the entry.
+*/ /**************************************************************************/
 void *OSCreateStatisticEntry(IMG_CHAR* pszName, void *pvFolder,
 							 OS_STATS_PRINT_FUNC* pfnStatsPrint,
 							 OS_INC_STATS_MEM_REFCOUNT_FUNC* pfnIncMemRefCt,
 							 OS_DEC_STATS_MEM_REFCOUNT_FUNC* pfnDecMemRefCt,
 							 void *pvData);
+
+/*************************************************************************/ /*!
+@Function       OSRemoveStatisticEntry
+@Description    Removes a statistic entry.
+                Where operating systems do not support a debugfs,
+                file system this function may be implemented as a stub.
+@Input          pvEntry  Pointer void reference to the entry created by
+                         OSCreateStatisticEntry().
+*/ /**************************************************************************/
 void OSRemoveStatisticEntry(void *pvEntry);
+
+#if defined(PVRSRV_ENABLE_MEMTRACK_STATS_FILE)
+/*************************************************************************/ /*!
+@Function       OSCreateRawStatisticEntry
+@Description    Create a raw statistic entry in the specified folder.
+                Where operating systems do not support a debugfs
+                file system this function may be implemented as a stub.
+@Input          pszFileName    String containing the name for the entry.
+@Input          pvParentDir    Reference from OSCreateStatisticFolder() of the
+                               folder to create the entry in, or NULL for the
+                               root.
+@Input          pfnStatsPrint  Pointer to function that can be used to print the
+                               values of all the statistics.
+@Return	        Pointer void reference to the entry created, which can be
+                passed to OSRemoveRawStatisticEntry() to remove the entry.
+*/ /**************************************************************************/
+void *OSCreateRawStatisticEntry(const IMG_CHAR *pszFileName, void *pvParentDir,
+                                OS_STATS_PRINT_FUNC *pfStatsPrint);
+
+/*************************************************************************/ /*!
+@Function       OSRemoveRawStatisticEntry
+@Description    Removes a raw statistic entry.
+                Where operating systems do not support a debugfs
+                file system this function may be implemented as a stub.
+@Input          pvEntry  Pointer void reference to the entry created by
+                         OSCreateRawStatisticEntry().
+*/ /**************************************************************************/
+void OSRemoveRawStatisticEntry(void *pvEntry);
+#endif
+
+/*************************************************************************/ /*!
+@Function       OSCreateStatisticFolder
+@Description    Create a statistic folder to hold statistic entries.
+                Where operating systems do not support a debugfs,
+                file system this function may be implemented as a stub.
+@Input          pszName   String containing the name for the folder.
+@Input          pvFolder  Reference from OSCreateStatisticFolder() of the folder
+                          to create the folder in, or NULL for the root.
+@Return         Pointer void reference to the folder created, which can be
+                passed to OSRemoveStatisticFolder() to remove the folder.
+*/ /**************************************************************************/
 void *OSCreateStatisticFolder(IMG_CHAR *pszName, void *pvFolder);
+
+/*************************************************************************/ /*!
+@Function       OSRemoveStatisticFolder
+@Description    Removes a statistic folder.
+                Where operating systems do not support a debugfs,
+                file system this function may be implemented as a stub.
+@Input          ppvFolder  Reference from OSCreateStatisticFolder() of the
+                           folder that should be removed.
+                           This needs to be double pointer because it has to
+                           be NULLed right after memory is freed to avoid
+                           possible races and use-after-free situations.
+*/ /**************************************************************************/
 void OSRemoveStatisticFolder(void **ppvFolder);
 
+/*************************************************************************/ /*!
+@Function       OSUserModeAccessToPerfCountersEn
+@Description    Permit User-mode access to CPU performance counter
+                registers.
+                This function is called during device initialisation.
+                Certain CPU architectures may need to explicitly permit
+                User mode access to performance counters - if this is
+                required, the necessary code should be implemented inside
+                this function.
+@Return         None.
+*/ /**************************************************************************/
 void OSUserModeAccessToPerfCountersEn(void);
 
+/*************************************************************************/ /*!
+@Function       OSDebugSignalPID
+@Description    Sends a SIGTRAP signal to a specific PID in user mode for
+                debugging purposes. The user mode process can register a handler
+                against this signal.
+                This is necessary to support the Rogue debugger. If the Rogue
+                debugger is not used then this function may be implemented as
+                a stub.
+@Input          ui32PID    The PID for the signal.
+@Return         PVRSRV_OK on success, a failure code otherwise.
+*/ /**************************************************************************/
+PVRSRV_ERROR OSDebugSignalPID(IMG_UINT32 ui32PID);
+
+#if defined(LINUX) && defined(__KERNEL__)
+#define OSWarnOn(a) WARN_ON(a)
+#else
+#define OSWarnOn(a) do { if(!!(a)) { OSDumpStack(); } } while(0)
+#endif
+
+#if defined(CONFIG_L4)
+#include <asm/api-l4env/api.h>
+#include <asm/io.h>
+
+#if defined(page_to_phys)
+#undef page_to_phys
+#define page_to_phys(x) l4x_virt_to_phys(x)
+#else
+#error "Unable to override page_to_phys() implementation"
+#endif
+#endif
+
 #endif /* __OSFUNC_H__ */
 
 /******************************************************************************
diff --git a/drivers/staging/imgtec/rogue/osfunc_arm.c b/drivers/staging/imgtec/rogue/osfunc_arm.c
index 69ac10a..d74f328 100644
--- a/drivers/staging/imgtec/rogue/osfunc_arm.c
+++ b/drivers/staging/imgtec/rogue/osfunc_arm.c
@@ -93,12 +93,6 @@
 	#define OUTER_FLUSH_ALL()
 #endif /* CONFIG_OUTER_CACHE */
 
-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27))
-#define ON_EACH_CPU(func, info, wait) on_each_cpu(func, info, wait)
-#else
-#define ON_EACH_CPU(func, info, wait) on_each_cpu(func, info, 0, wait)
-#endif
-
 static void per_cpu_cache_flush(void *arg)
 {
 	PVR_UNREFERENCED_PARAMETER(arg);
@@ -113,24 +107,14 @@
 	{
 		/* Fall-through */
 		case PVRSRV_CACHE_OP_CLEAN:
-			/* No full (inner) cache clean op */
-			ON_EACH_CPU(per_cpu_cache_flush, NULL, 1);
+			on_each_cpu(per_cpu_cache_flush, NULL, 1);
 			OUTER_CLEAN_RANGE();
 			break;
 
 		case PVRSRV_CACHE_OP_INVALIDATE:
 		case PVRSRV_CACHE_OP_FLUSH:
-			ON_EACH_CPU(per_cpu_cache_flush, NULL, 1);
-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37))
-			/* To use the "deferred flush" (not clean) DDK feature you need a kernel
-			 * implementation of outer_flush_all() for ARM CPUs with an outer cache
-			 * controller (e.g. PL310, common with Cortex A9 and later).
-			 *
-			 * Reference DDKs don't require this functionality, as they will only
-			 * clean the cache, never flush (clean+invalidate) it.
-			 */
+			on_each_cpu(per_cpu_cache_flush, NULL, 1);
 			OUTER_FLUSH_ALL();
-#endif
 			break;
 
 		case PVRSRV_CACHE_OP_NONE:
@@ -148,18 +132,19 @@
 	return eError;
 }
 
-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,34))
 static inline size_t pvr_dmac_range_len(const void *pvStart, const void *pvEnd)
 {
 	return (size_t)((char *)pvEnd - (char *)pvStart);
 }
-#endif
 
-void OSFlushCPUCacheRangeKM(void *pvVirtStart,
-							void *pvVirtEnd,
-							IMG_CPU_PHYADDR sCPUPhysStart,
-							IMG_CPU_PHYADDR sCPUPhysEnd)
+void OSFlushCPUCacheRangeKM(PVRSRV_DEVICE_NODE *psDevNode,
+                            void *pvVirtStart,
+                            void *pvVirtEnd,
+                            IMG_CPU_PHYADDR sCPUPhysStart,
+                            IMG_CPU_PHYADDR sCPUPhysEnd)
 {
+	PVR_UNREFERENCED_PARAMETER(psDevNode);
+
 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,7,0))
 	arm_dma_ops.sync_single_for_device(NULL, sCPUPhysStart.uiAddr, sCPUPhysEnd.uiAddr - sCPUPhysStart.uiAddr, DMA_TO_DEVICE);
 	arm_dma_ops.sync_single_for_cpu(NULL, sCPUPhysStart.uiAddr, sCPUPhysEnd.uiAddr - sCPUPhysStart.uiAddr, DMA_FROM_DEVICE);
@@ -172,43 +157,41 @@
 #endif	/* (LINUX_VERSION_CODE >= KERNEL_VERSION(3,7,0)) */
 }
 
-void OSCleanCPUCacheRangeKM(void *pvVirtStart,
-							void *pvVirtEnd,
-							IMG_CPU_PHYADDR sCPUPhysStart,
-							IMG_CPU_PHYADDR sCPUPhysEnd)
+void OSCleanCPUCacheRangeKM(PVRSRV_DEVICE_NODE *psDevNode,
+                            void *pvVirtStart,
+                            void *pvVirtEnd,
+                            IMG_CPU_PHYADDR sCPUPhysStart,
+                            IMG_CPU_PHYADDR sCPUPhysEnd)
 {
+	PVR_UNREFERENCED_PARAMETER(psDevNode);
+
 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,7,0))
 	arm_dma_ops.sync_single_for_device(NULL, sCPUPhysStart.uiAddr, sCPUPhysEnd.uiAddr - sCPUPhysStart.uiAddr, DMA_TO_DEVICE);
 #else	/* (LINUX_VERSION_CODE >= KERNEL_VERSION(3,7,0)) */
 	/* Inner cache */
-#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,34))
-	dmac_clean_range(pvVirtStart, pvVirtEnd);
-#else
 	dmac_map_area(pvVirtStart, pvr_dmac_range_len(pvVirtStart, pvVirtEnd), DMA_TO_DEVICE);
-#endif
 
 	/* Outer cache */
 	outer_clean_range(sCPUPhysStart.uiAddr, sCPUPhysEnd.uiAddr);
 #endif	/* (LINUX_VERSION_CODE >= KERNEL_VERSION(3,7,0)) */
 }
 
-void OSInvalidateCPUCacheRangeKM(void *pvVirtStart,
-								 void *pvVirtEnd,
-								 IMG_CPU_PHYADDR sCPUPhysStart,
-								 IMG_CPU_PHYADDR sCPUPhysEnd)
+void OSInvalidateCPUCacheRangeKM(PVRSRV_DEVICE_NODE *psDevNode,
+                                 void *pvVirtStart,
+                                 void *pvVirtEnd,
+                                 IMG_CPU_PHYADDR sCPUPhysStart,
+                                 IMG_CPU_PHYADDR sCPUPhysEnd)
 {
+	PVR_UNREFERENCED_PARAMETER(psDevNode);
+
 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,7,0))
 	arm_dma_ops.sync_single_for_cpu(NULL, sCPUPhysStart.uiAddr, sCPUPhysEnd.uiAddr - sCPUPhysStart.uiAddr, DMA_FROM_DEVICE);
 #else	/* (LINUX_VERSION_CODE >= KERNEL_VERSION(3,7,0)) */
 #if defined(PVR_LINUX_DONT_USE_RANGE_BASED_INVALIDATE)
-	OSCleanCPUCacheRangeKM(pvVirtStart, pvVirtEnd, sCPUPhysStart, sCPUPhysEnd);
+	OSCleanCPUCacheRangeKM(psDevNode, pvVirtStart, pvVirtEnd, sCPUPhysStart, sCPUPhysEnd);
 #else
 	/* Inner cache */
-#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,34))
-	dmac_inv_range(pvVirtStart, pvVirtEnd);
-#else
 	dmac_map_area(pvVirtStart, pvr_dmac_range_len(pvVirtStart, pvVirtEnd), DMA_FROM_DEVICE);
-#endif
 
 	/* Outer cache */
 	outer_inv_range(sCPUPhysStart.uiAddr, sCPUPhysEnd.uiAddr);
@@ -232,11 +215,13 @@
 static void per_cpu_perf_counter_user_access_en(void *data)
 {
 	PVR_UNREFERENCED_PARAMETER(data);
+#if !defined(CONFIG_L4)
 	/* Enable user-mode access to counters. */
 	asm volatile("mcr p15, 0, %0, c9, c14, 0" :: "r"(PMUSERENR_EN));
+#endif
 }
 
 void OSUserModeAccessToPerfCountersEn(void)
 {
-	ON_EACH_CPU(per_cpu_perf_counter_user_access_en, NULL, 1);
+	on_each_cpu(per_cpu_perf_counter_user_access_en, NULL, 1);
 }
diff --git a/drivers/staging/imgtec/rogue/osfunc_arm64.c b/drivers/staging/imgtec/rogue/osfunc_arm64.c
index cc46590..7d33a4a 100644
--- a/drivers/staging/imgtec/rogue/osfunc_arm64.c
+++ b/drivers/staging/imgtec/rogue/osfunc_arm64.c
@@ -41,6 +41,7 @@
 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */ /**************************************************************************/
 #include <linux/version.h>
+#include <linux/cpumask.h>
 #include <linux/dma-mapping.h>
 #include <asm/cacheflush.h>
 
@@ -48,7 +49,6 @@
 #include "img_types.h"
 #include "osfunc.h"
 #include "pvr_debug.h"
-#include "module_common.h"
 
 #if defined(CONFIG_OUTER_CACHE)
   /* If you encounter a 64-bit ARM system with an outer cache, you'll need
@@ -58,6 +58,32 @@
 	#error "CONFIG_OUTER_CACHE not supported on arm64."
 #endif
 
+static void per_cpu_cache_flush(void *arg)
+{
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4,2,0))
+	static IMG_BOOL bLog = IMG_TRUE;
+	/*
+		NOTE: Regarding arm64 global flush support on >= Linux v4.2:
+		- Global cache flush support is deprecated from v4.2 onwards
+		- Cache maintenance is done using UM/KM VA maintenance _only_
+		- If you find that more time is spent in VA cache maintenance
+			- Implement arm64 assembly sequence for global flush here
+				- asm volatile ();
+		- If you do not want to implement the global cache assembly
+			- Disable KM cache maintenance support in UM cache.c
+			- Remove this PVR_LOG message
+	*/
+	if (bLog)
+	{
+		PVR_LOG(("Global d-cache flush assembly not implemented, using rangebased flush"));
+		bLog = IMG_FALSE;
+	}
+#else
+	flush_cache_all();
+#endif
+	PVR_UNREFERENCED_PARAMETER(arg);
+}
+
 PVRSRV_ERROR OSCPUOperation(PVRSRV_CACHE_OP uiCacheOp)
 {
 	PVRSRV_ERROR eError = PVRSRV_OK;
@@ -67,7 +93,10 @@
 		case PVRSRV_CACHE_OP_CLEAN:
 		case PVRSRV_CACHE_OP_FLUSH:
 		case PVRSRV_CACHE_OP_INVALIDATE:
+			on_each_cpu(per_cpu_cache_flush, NULL, 1);
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4,2,0))
 			eError = PVRSRV_ERROR_NOT_IMPLEMENTED;
+#endif
 			break;
 
 		case PVRSRV_CACHE_OP_NONE:
@@ -85,12 +114,14 @@
 	return eError;
 }
 
-void OSFlushCPUCacheRangeKM(void *pvVirtStart,
+void OSFlushCPUCacheRangeKM(PVRSRV_DEVICE_NODE *psDevNode,
+							void *pvVirtStart,
 							void *pvVirtEnd,
 							IMG_CPU_PHYADDR sCPUPhysStart,
 							IMG_CPU_PHYADDR sCPUPhysEnd)
 {
-	struct dma_map_ops *dma_ops = get_dma_ops(&gpsPVRLDMDev->dev);
+	struct dma_map_ops *dma_ops = get_dma_ops(psDevNode->psDevConfig->pvOSDevice);
+
 	PVR_UNREFERENCED_PARAMETER(pvVirtStart);
 	PVR_UNREFERENCED_PARAMETER(pvVirtEnd);
 
@@ -98,24 +129,28 @@
 	dma_ops->sync_single_for_cpu(NULL, sCPUPhysStart.uiAddr, sCPUPhysEnd.uiAddr - sCPUPhysStart.uiAddr, DMA_FROM_DEVICE);
 }
 
-void OSCleanCPUCacheRangeKM(void *pvVirtStart,
+void OSCleanCPUCacheRangeKM(PVRSRV_DEVICE_NODE *psDevNode,
+							void *pvVirtStart,
 							void *pvVirtEnd,
 							IMG_CPU_PHYADDR sCPUPhysStart,
 							IMG_CPU_PHYADDR sCPUPhysEnd)
 {
-	struct dma_map_ops *dma_ops = get_dma_ops(&gpsPVRLDMDev->dev);
+	struct dma_map_ops *dma_ops = get_dma_ops(psDevNode->psDevConfig->pvOSDevice);
+
 	PVR_UNREFERENCED_PARAMETER(pvVirtStart);
 	PVR_UNREFERENCED_PARAMETER(pvVirtEnd);
 
 	dma_ops->sync_single_for_device(NULL, sCPUPhysStart.uiAddr, sCPUPhysEnd.uiAddr - sCPUPhysStart.uiAddr, DMA_TO_DEVICE);
 }
 
-void OSInvalidateCPUCacheRangeKM(void *pvVirtStart,
+void OSInvalidateCPUCacheRangeKM(PVRSRV_DEVICE_NODE *psDevNode,
+								 void *pvVirtStart,
 								 void *pvVirtEnd,
 								 IMG_CPU_PHYADDR sCPUPhysStart,
 								 IMG_CPU_PHYADDR sCPUPhysEnd)
 {
-	struct dma_map_ops *dma_ops = get_dma_ops(&gpsPVRLDMDev->dev);
+	struct dma_map_ops *dma_ops = get_dma_ops(psDevNode->psDevConfig->pvOSDevice);
+
 	PVR_UNREFERENCED_PARAMETER(pvVirtStart);
 	PVR_UNREFERENCED_PARAMETER(pvVirtEnd);
 
diff --git a/drivers/staging/imgtec/rogue/osfunc_x86.c b/drivers/staging/imgtec/rogue/osfunc_x86.c
index dfd36c1..c672c53 100644
--- a/drivers/staging/imgtec/rogue/osfunc_x86.c
+++ b/drivers/staging/imgtec/rogue/osfunc_x86.c
@@ -40,11 +40,8 @@
 IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */ /**************************************************************************/
-#include <linux/version.h>
+
 #include <linux/smp.h>
-#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
-#include <asm/system.h>
-#endif
 
 #include "pvrsrv_error.h"
 #include "img_types.h"
@@ -52,11 +49,6 @@
 #include "osfunc.h"
 #include "pvr_debug.h"
 
-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27))
-#define ON_EACH_CPU(func, info, wait) on_each_cpu(func, info, wait)
-#else
-#define ON_EACH_CPU(func, info, wait) on_each_cpu(func, info, 0, wait)
-#endif
 
 static void per_cpu_cache_flush(void *arg)
 {
@@ -109,11 +101,13 @@
 	mb();
 }
 
-void OSFlushCPUCacheRangeKM(void *pvVirtStart,
-							void *pvVirtEnd,
-							IMG_CPU_PHYADDR sCPUPhysStart,
-							IMG_CPU_PHYADDR sCPUPhysEnd)
+void OSFlushCPUCacheRangeKM(PVRSRV_DEVICE_NODE *psDevNode,
+                            void *pvVirtStart,
+                            void *pvVirtEnd,
+                            IMG_CPU_PHYADDR sCPUPhysStart,
+                            IMG_CPU_PHYADDR sCPUPhysEnd)
 {
+	PVR_UNREFERENCED_PARAMETER(psDevNode);
 	PVR_UNREFERENCED_PARAMETER(sCPUPhysStart);
 	PVR_UNREFERENCED_PARAMETER(sCPUPhysEnd);
 
@@ -121,11 +115,13 @@
 }
 
 
-void OSCleanCPUCacheRangeKM(void *pvVirtStart,
-							void *pvVirtEnd,
-							IMG_CPU_PHYADDR sCPUPhysStart,
-							IMG_CPU_PHYADDR sCPUPhysEnd)
+void OSCleanCPUCacheRangeKM(PVRSRV_DEVICE_NODE *psDevNode,
+                            void *pvVirtStart,
+                            void *pvVirtEnd,
+                            IMG_CPU_PHYADDR sCPUPhysStart,
+                            IMG_CPU_PHYADDR sCPUPhysEnd)
 {
+	PVR_UNREFERENCED_PARAMETER(psDevNode);
 	PVR_UNREFERENCED_PARAMETER(sCPUPhysStart);
 	PVR_UNREFERENCED_PARAMETER(sCPUPhysEnd);
 
@@ -133,11 +129,13 @@
 	x86_flush_cache_range(pvVirtStart, pvVirtEnd);
 }
 
-void OSInvalidateCPUCacheRangeKM(void *pvVirtStart,
-								 void *pvVirtEnd,
-								 IMG_CPU_PHYADDR sCPUPhysStart,
-								 IMG_CPU_PHYADDR sCPUPhysEnd)
+void OSInvalidateCPUCacheRangeKM(PVRSRV_DEVICE_NODE *psDevNode,
+                                 void *pvVirtStart,
+                                 void *pvVirtEnd,
+                                 IMG_CPU_PHYADDR sCPUPhysStart,
+                                 IMG_CPU_PHYADDR sCPUPhysEnd)
 {
+	PVR_UNREFERENCED_PARAMETER(psDevNode);
 	PVR_UNREFERENCED_PARAMETER(sCPUPhysStart);
 	PVR_UNREFERENCED_PARAMETER(sCPUPhysEnd);
 
diff --git a/drivers/staging/imgtec/rogue/oskm_apphint.h b/drivers/staging/imgtec/rogue/oskm_apphint.h
new file mode 100644
index 0000000..8c2444c
--- /dev/null
+++ b/drivers/staging/imgtec/rogue/oskm_apphint.h
@@ -0,0 +1,213 @@
+/*************************************************************************/ /*!
+@File           oskm_apphint.h
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description    OS-independent interface for retrieving KM apphints
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+#include "img_defs.h"
+#if defined(LINUX)
+#include "km_apphint.h"
+#else
+#include "services_client_porting.h"
+#endif
+#if !defined(__OSKM_APPHINT_H__)
+#define __OSKM_APPHINT_H__
+
+
+#if defined(LINUX) && !defined(DOXYGEN)
+#if defined(SUPPORT_KERNEL_SRVINIT)
+static INLINE IMG_UINT os_get_km_apphint_UINT32(void *state, APPHINT_ID id, IMG_UINT32 *pAppHintDefault, IMG_UINT32 *pVal) {
+	return !pvr_apphint_get_uint32(id, pVal);
+}
+static INLINE IMG_UINT os_get_km_apphint_UINT64(void *state, APPHINT_ID id, IMG_UINT64 *pAppHintDefault, IMG_UINT64 *pVal) {
+	return !pvr_apphint_get_uint64(id, pVal);
+}
+static INLINE IMG_UINT os_get_km_apphint_BOOL(void *state, APPHINT_ID id, IMG_BOOL *pAppHintDefault, IMG_BOOL *pVal) {
+	return !pvr_apphint_get_bool(id, pVal);
+}
+static INLINE IMG_UINT os_get_km_apphint_STRING(void *state, APPHINT_ID id, IMG_CHAR **pAppHintDefault, IMG_CHAR *buffer, size_t size) {
+	return !pvr_apphint_get_string(id, buffer, size);
+}
+
+#define OSGetKMAppHintUINT32(state, name, appHintDefault, value) \
+	os_get_km_apphint_UINT32(state, APPHINT_ID_ ## name, appHintDefault, value)
+
+#define OSGetKMAppHintUINT64(state, name, appHintDefault, value) \
+	os_get_km_apphint_UINT64(state, APPHINT_ID_ ## name, appHintDefault, value)
+
+#define OSGetKMAppHintBOOL(state, name, appHintDefault, value) \
+	os_get_km_apphint_BOOL(state, APPHINT_ID_ ## name, appHintDefault, value)
+
+#define OSGetKMAppHintSTRING(state, name, appHintDefault, buffer, size) \
+	os_get_km_apphint_STRING(state, APPHINT_ID_ ## name, appHintDefault, buffer, size)
+
+#else
+static INLINE IMG_UINT os_get_apphint_default_UINT32(IMG_UINT32 *pAppHintDefault, IMG_UINT32 *pVal) {
+	*pVal = *pAppHintDefault;
+	return IMG_TRUE;
+}
+static INLINE IMG_UINT os_get_apphint_default_UINT64(IMG_UINT64 *pAppHintDefault, IMG_UINT64 *pVal) {
+	*pVal = *pAppHintDefault;
+	return IMG_TRUE;
+}
+static INLINE IMG_UINT os_get_apphint_default_BOOL(IMG_BOOL *pAppHintDefault, IMG_BOOL *pVal) {
+	*pVal = *pAppHintDefault;
+	return IMG_TRUE;
+}
+static INLINE IMG_UINT os_get_apphint_default_STRING(IMG_CHAR **pAppHintDefault, IMG_CHAR *buffer, IMG_UINT32 size) {
+	strlcpy(buffer, *pAppHintDefault, size);
+	return IMG_TRUE;
+}
+
+#define OSGetKMAppHintUINT32(state, name, appHintDefault, value) \
+	os_get_apphint_default_UINT32(appHintDefault, value)
+
+#define OSGetKMAppHintUINT64(state, name, appHintDefault, value) \
+	os_get_apphint_default_UINT64(appHintDefault, value)
+
+#define OSGetKMAppHintBOOL(state, name, appHintDefault, value) \
+	os_get_apphint_default_BOOL(appHintDefault, value)
+
+#define OSGetKMAppHintSTRING(state, name, appHintDefault, buffer, size) \
+	os_get_apphint_default_STRING(appHintDefault, buffer, size)
+
+#endif
+
+#define OSCreateKMAppHintState(state) \
+	PVR_UNREFERENCED_PARAMETER(state)
+
+#define OSFreeKMAppHintState(state) \
+	PVR_UNREFERENCED_PARAMETER(state)
+
+#else /* #if defined(LINUX) && !defined(DOXYGEN) */
+
+static INLINE IMG_BOOL os_get_km_apphint_STRING(void *state, IMG_CHAR *name, IMG_CHAR **pAppHintDefault, IMG_CHAR *buffer, size_t size) {
+	PVR_UNREFERENCED_PARAMETER(size);
+	return PVRSRVGetAppHint(state, name, IMG_STRING_TYPE, pAppHintDefault, buffer);
+}
+
+/**************************************************************************/ /*!
+@def OSGetKMAppHintUINT32(state, name, appHintDefault, value)
+@Description    Interface for retrieval of uint32 km app hint.
+				For non-linux operating systems, this macro implements a call
+				from server code to PVRSRVGetAppHint() declared in
+				services_client_porting.h, effectively making it 'shared' code.
+@Input          state             App hint state
+@Input          name              Name used to identify app hint
+@Input          appHintDefault    Default value to be returned if no
+								  app hint is found.
+@Output         value             Pointer to returned app hint value.
+ */ /**************************************************************************/
+#define OSGetKMAppHintUINT32(state, name, appHintDefault, value) \
+	PVRSRVGetAppHint(state, # name, IMG_UINT_TYPE, appHintDefault, value)
+
+/**************************************************************************/ /*!
+@def OSGetKMAppHintUINT64(state, name, appHintDefault, value)
+@Description    Interface for retrieval of uint64 km app hint.
+				For non-linux operating systems, this macro implements a call
+				from server code to PVRSRVGetAppHint() declared in
+				services_client_porting.h, effectively making it 'shared' code.
+@Input          state             App hint state
+@Input          name              Name used to identify app hint
+@Input          appHintDefault    Default value to be returned if no
+								  app hint is found.
+@Output         value             Pointer to returned app hint value.
+ */ /**************************************************************************/
+#define OSGetKMAppHintUINT64(state, name, appHintDefault, value) \
+	PVRSRVGetAppHint(state, # name, IMG_UINT_TYPE, appHintDefault, value)
+
+/**************************************************************************/ /*!
+@def OSGetKMAppHintBOOL(state, name, appHintDefault, value)
+@Description    Interface for retrieval of IMG_BOOL km app hint.
+				For non-linux operating systems, this macro implements a call
+				from server code to PVRSRVGetAppHint() declared in
+				services_client_porting.h, effectively making it 'shared' code.
+@Input          state             App hint state
+@Input          name              Name used to identify app hint
+@Input          appHintDefault    Default value to be returned if no
+								  app hint is found.
+@Output         value             Pointer to returned app hint value.
+ */ /**************************************************************************/
+#define OSGetKMAppHintBOOL(state, name, appHintDefault, value) \
+	PVRSRVGetAppHint(state, # name, IMG_UINT_TYPE, appHintDefault, value)
+
+/**************************************************************************/ /*!
+@def OSGetKMAppHintSTRING(state, name, appHintDefault, buffer, size)
+@Description    Interface for retrieval of string km app hint.
+				For non-linux operating systems, this macro implements a call
+				from server code to PVRSRVGetAppHint() declared in
+				services_client_porting.h, effectively making it 'shared' code.
+@Input          state             App hint state
+@Input          name              Name used to identify app hint
+@Input          appHintDefault    Default value to be returned if no
+								  app hint is found.
+@Output         buffer            Buffer used to return app hint string.
+@Input			size			  Size of the buffer.
+ */ /**************************************************************************/
+#define OSGetKMAppHintSTRING(state, name, appHintDefault, buffer, size) \
+	os_get_km_apphint_STRING(state, # name, appHintDefault, buffer, size)
+
+/**************************************************************************/ /*!
+@def OSCreateKMAppHintState(state)
+@Description    Creates the app hint state.
+				For non-linux operating systems, this macro implements a call
+				from server code to PVRSRVCreateAppHintState() declared in
+				services_client_porting.h, effectively making it 'shared' code.
+@Output          state             App hint state
+ */ /**************************************************************************/
+#define OSCreateKMAppHintState(state) \
+	PVRSRVCreateAppHintState(IMG_SRV_UM, 0, state)
+
+/**************************************************************************/ /*!
+@def OSFreeKMAppHintState
+@Description    Free the app hint state.
+				For non-linux operating systems, this macro implements a call
+				from server code to PVRSRVCreateAppHintState() declared in
+				services_client_porting.h, effectively making it 'shared' code.
+@Output          state             App hint state
+ */ /**************************************************************************/
+#define OSFreeKMAppHintState(state) \
+	PVRSRVFreeAppHintState(IMG_SRV_UM, state)
+
+#endif /* #if defined(LINUX) */
+
+#endif /* __OSKM_APPHINT_H__ */
+
+/******************************************************************************
+ End of file (oskm_apphint.h)
+******************************************************************************/
diff --git a/drivers/staging/imgtec/rogue/osmmap.h b/drivers/staging/imgtec/rogue/osmmap.h
new file mode 100644
index 0000000..bc83151
--- /dev/null
+++ b/drivers/staging/imgtec/rogue/osmmap.h
@@ -0,0 +1,123 @@
+/*************************************************************************/ /*!
+@File
+@Title          OS Interface for mapping PMRs into CPU space.
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description    OS abstraction for the mmap2 interface for mapping PMRs into
+                User Mode memory
+@License        Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#ifndef _OSMMAP_H_
+#define _OSMMAP_H_
+
+#include <powervr/mem_types.h>
+
+#include "img_types.h"
+#include "pvrsrv_error.h"
+
+/**************************************************************************/ /*!
+@Function       OSMMapPMR
+@Description    Maps the specified PMR into CPU memory so that it may be
+                accessed by the user process.
+                Whether the memory is mapped read only, read/write, or not at
+                all, is dependent on the PMR itself.
+                The PMR handle is opaque to the user, and lower levels of this
+                stack ensure that the handle is private to this process, such that
+                this API cannot be abused to gain access to other people's PMRs.
+                The OS implementation of this function should return the virtual
+                address and length for the User to use. The "PrivData" is to be
+                stored opaquely by the caller (N.B. he should make no assumptions,
+                in particular, NULL is a valid handle) and given back to the
+                call to OSMUnmapPMR.
+                The OS implementation is free to use the PrivData handle for any
+                purpose it sees fit.
+@Input          hBridge              The bridge handle.
+@Input          hPMR                 The handle of the PMR to be mapped.
+@Input          uiPMRLength          The size of the PMR.
+@Input          uiFlags              Flags indicating how the mapping should
+                                     be done (read-only, etc). These may not
+                                     be honoured if the PMR does not permit
+                                     them.
+@Input          uiPMRLength          The size of the PMR.
+@Output         phOSMMapPrivDataOut  Returned private data.
+@Output         ppvMappingAddressOut The returned mapping.
+@Output         puiMappingLengthOut  The size of the returned mapping.
+@Return         PVRSRV_OK on success, failure code otherwise.
+ */ /**************************************************************************/
+extern PVRSRV_ERROR
+OSMMapPMR(IMG_HANDLE hBridge,
+          IMG_HANDLE hPMR,
+          IMG_DEVMEM_SIZE_T uiPMRLength,
+          IMG_UINT32 uiFlags,
+          IMG_HANDLE *phOSMMapPrivDataOut,
+          void **ppvMappingAddressOut,
+          size_t *puiMappingLengthOut);
+
+/**************************************************************************/ /*!
+@Function       OSMUnmapPMR
+@Description    Unmaps the specified PMR from CPU memory.
+                This function is the counterpart to OSMMapPMR.
+                The caller is required to pass the PMR handle back in along
+                with the same 3-tuple of information that was returned by the
+                call to OSMMapPMR in phOSMMapPrivDataOut.
+                It is possible to unmap only part of the original mapping
+                with this call, by specifying only the address range to be
+                unmapped in pvMappingAddress and uiMappingLength.
+@Input          hBridge              The bridge handle.
+@Input          hPMR                 The handle of the PMR to be unmapped.
+@Input          hOSMMapPrivData      The OS private data of the mapping.
+@Input          pvMappingAddress     The address to be unmapped.
+@Input          uiMappingLength      The size to be unmapped.
+@Return         PVRSRV_OK on success, failure code otherwise.
+ */ /**************************************************************************/
+/*
+   FIXME:
+   perhaps this function should take _only_ the hOSMMapPrivData arg,
+   and the implementation is required to store any of the other data
+   items that it requires to do the unmap?
+*/
+extern void
+OSMUnmapPMR(IMG_HANDLE hBridge,
+            IMG_HANDLE hPMR,
+            IMG_HANDLE hOSMMapPrivData,
+            void *pvMappingAddress,
+            size_t uiMappingLength);
+
+
+#endif /* _OSMMAP_H_ */
+
diff --git a/drivers/staging/imgtec/rogue/devicemem_mmap_stub.c b/drivers/staging/imgtec/rogue/osmmap_stub.c
similarity index 99%
rename from drivers/staging/imgtec/rogue/devicemem_mmap_stub.c
rename to drivers/staging/imgtec/rogue/osmmap_stub.c
index 13c4ea7..fbddf87 100644
--- a/drivers/staging/imgtec/rogue/devicemem_mmap_stub.c
+++ b/drivers/staging/imgtec/rogue/osmmap_stub.c
@@ -43,7 +43,7 @@
 */ /**************************************************************************/
 
 /* our exported API */
-#include "devicemem_mmap.h"
+#include "osmmap.h"
 
 /* include/ */
 #include "img_types.h"
diff --git a/drivers/staging/imgtec/rogue/pdump.c b/drivers/staging/imgtec/rogue/pdump.c
index 490a6ff..b49301b 100644
--- a/drivers/staging/imgtec/rogue/pdump.c
+++ b/drivers/staging/imgtec/rogue/pdump.c
@@ -50,7 +50,6 @@
 #include "osfunc.h"
 
 #include "dbgdrvif_srv5.h"
-#include "mm.h"
 #include "allocmem.h"
 #include "pdump_km.h"
 #include "pdump_osfunc.h"
@@ -167,7 +166,7 @@
 /*!
  * \name	PDumpOSVSprintf
  */
-PVRSRV_ERROR PDumpOSVSprintf(IMG_CHAR *pszComment, IMG_UINT32 ui32ScriptSizeMax, IMG_CHAR* pszFormat, PDUMP_va_list vaArgs)
+PVRSRV_ERROR PDumpOSVSprintf(IMG_CHAR *pszComment, IMG_UINT32 ui32ScriptSizeMax, const IMG_CHAR* pszFormat, PDUMP_va_list vaArgs)
 {
 	IMG_INT32 n;
 
@@ -189,6 +188,8 @@
 void PDumpOSDebugPrintf(IMG_CHAR* pszFormat, ...)
 {
 	PVR_UNREFERENCED_PARAMETER(pszFormat);
+
+	/* FIXME: Implement using services PVR_DBG or otherwise with kprintf */
 }
 
 /*!
@@ -397,7 +398,7 @@
 
 void PDumpOSDestroyLock(void)
 {
-	/* no destruction work to do, just assert
+	/* no destruction work to be done, just assert
 	 * the lock is not held */
 	PVR_ASSERT(mutex_is_locked(&gsPDumpMutex) == 0);
 }
diff --git a/drivers/staging/imgtec/rogue/pdump.h b/drivers/staging/imgtec/rogue/pdump.h
index bb67914..48d126b 100644
--- a/drivers/staging/imgtec/rogue/pdump.h
+++ b/drivers/staging/imgtec/rogue/pdump.h
@@ -46,12 +46,13 @@
 
 typedef IMG_UINT32 PDUMP_FLAGS_T;
 
+#define PDUMP_FLAGS_NONE		0x00000000UL /*<! Output this entry with no special treatment i.e. output only if in frame range */
 
 #define PDUMP_FLAGS_DEINIT		    0x20000000UL /*<! Output this entry to the de-initialisation section */
 
 #define PDUMP_FLAGS_POWER		0x08000000UL /*<! Output this entry even when a power transition is ongoing */
 
-#define PDUMP_FLAGS_CONTINUOUS		PVRSRV_PDUMP_FLAGS_CONTINUOUS /*<! Defined in serviceS_km.h */
+#define PDUMP_FLAGS_CONTINUOUS		PDUMP_CONT /*<! Defined in serviceS_km.h */
 
 #define PDUMP_FLAGS_PERSISTENT		0x80000000UL /*<! Output this entry always regardless of app and range,
                                                       used by persistent processes e.g. compositor, window mgr etc/ */
@@ -74,5 +75,6 @@
 #define PDUMP_PARAM_N_FILE_NAME     "%%0%%_%02u.prm" /*!< Param filename used when PRM file split */
 #define PDUMP_PARAM_MAX_FILE_NAME   32               /*!< Max Size of parameter name used in out2.txt */
 
+#define PDUMP_IS_CONTINUOUS(flags) 	((flags & PDUMP_FLAGS_CONTINUOUS) != 0)
 
 #endif /* _SERVICES_PDUMP_H_ */
diff --git a/drivers/staging/imgtec/rogue/pdump_common.c b/drivers/staging/imgtec/rogue/pdump_common.c
index 2bc8469..63884a5 100644
--- a/drivers/staging/imgtec/rogue/pdump_common.c
+++ b/drivers/staging/imgtec/rogue/pdump_common.c
@@ -80,15 +80,10 @@
 #define MAX_PDUMP_MMU_CONTEXTS	(32)
 static void *gpvTempBuffer = NULL;
 
-#define PERSISTANT_MAGIC           ((uintptr_t) 0xe33ee33e)
-#define PDUMP_PERSISTENT_HASH_SIZE 10
-
 #define PRM_FILE_SIZE_MAX	0x7FDFFFFFU /*!< Default maximum file size to split output files, 2GB-2MB as fwrite limits it to 2GB-1 on 32bit systems */
 #define FRAME_UNSET			0xFFFFFFFFU /*|< Used to signify no or invalid frame number */
 
 
-static HASH_TABLE *g_psPersistentHash = NULL;
-
 static IMG_BOOL		g_PDumpInitialised = IMG_FALSE;
 static IMG_UINT32	g_ConnectionCount = 0;
 
@@ -132,7 +127,7 @@
 #define PDUMP_REFCOUNT_PRINT(fmt, ...)
 #endif
 
-/* Prototype for the test/debug state dump rotuine used in debugging */
+/* Prototype for the test/debug state dump routine used in debugging */
 void PDumpCommonDumpState(IMG_BOOL bDumpOSLayerState);
 #undef PDUMP_TRACE_STATE
 
@@ -500,7 +495,7 @@
 	/* The following checks are made when the driver has completed initialisation */
 
 	/* If PDump client connected allow continuous flagged writes */
-	if (ui32Flags & PDUMP_FLAGS_CONTINUOUS)
+	if (PDUMP_IS_CONTINUOUS(ui32Flags))
 	{
 		if (PDumpCtrlCaptureRangeUnset()) /* Is client connected? */
 		{
@@ -512,7 +507,7 @@
 	}
 
 	/* No last/deinit statements allowed when not in initialisation phase */
-	if (ui32Flags & PDUMP_FLAGS_DEINIT)
+	if (PDUMP_IS_CONTINUOUS(ui32Flags))
 	{
 		if (PDumpCtrlInitPhaseComplete())
 		{
@@ -723,7 +718,7 @@
 
 			/* Don't write continuous data if client not connected */
 			PDumpCtrlLockAcquire();
-			if ((ui32Flags & PDUMP_FLAGS_CONTINUOUS) && PDumpCtrlCaptureRangeUnset())
+			if (PDUMP_IS_CONTINUOUS(ui32Flags) && PDumpCtrlCaptureRangeUnset())
 			{
 				PDumpCtrlLockRelease();
 				return IMG_TRUE;
@@ -774,6 +769,33 @@
 	return IMG_TRUE;
 }
 
+#if defined(PDUMP_DEBUG_OUTFILES)
+
+static IMG_UINT32 _GenerateChecksum(void *pvData, size_t uiSize)
+{
+	IMG_UINT32 ui32Sum = 0;
+	IMG_UINT32 *pui32Data = pvData;
+	IMG_UINT8 *pui8Data = pvData;
+	IMG_UINT32 i;
+	IMG_UINT32 ui32LeftOver;
+
+	for(i = 0; i < uiSize / sizeof(IMG_UINT32); i++)
+	{
+		ui32Sum += pui32Data[i];
+	}
+
+	ui32LeftOver = uiSize % sizeof(IMG_UINT32);
+
+	while(ui32LeftOver)
+	{
+		ui32Sum += pui8Data[uiSize - ui32LeftOver];
+		ui32LeftOver--;
+	}
+
+	return ui32Sum;
+}
+
+#endif
 
 PVRSRV_ERROR PDumpWriteParameter(IMG_UINT8 *pui8Data, IMG_UINT32 ui32Size, IMG_UINT32 ui32Flags,
 		IMG_UINT32* pui32FileOffset, IMG_CHAR* aszFilenameStr)
@@ -788,7 +810,7 @@
 
 	if (!PDumpWriteAllowed(ui32Flags))
 	{
-		/* Abort write for the above reason but indicate what happended to
+		/* Abort write for the above reason but indicate what happened to
 		 * caller to avoid disrupting the driver, caller should treat it as OK
 		 * but skip any related PDump writes to the script file.  */
 		return PVRSRV_ERROR_PDUMP_NOT_ALLOWED;
@@ -846,6 +868,28 @@
 		PDUMP_HERE(7);
 		PVR_LOGG_IF_ERROR(eError, "PDumpWrite", errExit);
 	}
+#if defined(PDUMP_DEBUG_OUTFILES)
+	else
+	{
+		IMG_UINT32 ui32Checksum;
+		PDUMP_GET_SCRIPT_STRING();
+
+		ui32Checksum = _GenerateChecksum(pui8Data, ui32Size);
+
+		/* CHK CHKSUM SIZE PRMOFFSET PRMFILE */
+		eError = PDumpOSBufprintf(hScript, ui32MaxLen, "-- CHK 0x%08X 0x%08X 0x%08X %s",
+									ui32Checksum,
+									ui32Size,
+									*pui32FileOffset,
+									aszFilenameStr);
+		if(eError != PVRSRV_OK)
+		{
+			goto errExit;
+		}
+
+		PDumpWriteScript(hScript, ui32Flags);
+	}
+#endif
 
 	return PVRSRV_OK;
 
@@ -923,26 +967,6 @@
 						 __FUNCTION__, psPDumpConnectionData, ui32RefCount);
 }
 
-#ifdef INLINE_IS_PRAGMA
-#pragma inline(PDumpIsPersistent)
-#endif
-
-IMG_BOOL PDumpIsPersistent(void)
-{
-	IMG_PID uiPID = OSGetCurrentClientProcessIDKM();
-	uintptr_t puiRetrieve;
-
-	puiRetrieve = HASH_Retrieve(g_psPersistentHash, uiPID);
-	if (puiRetrieve != 0)
-	{
-		PVR_ASSERT(puiRetrieve == PERSISTANT_MAGIC);
-		PDUMP_HEREA(110);
-		return IMG_TRUE;
-	}
-	return IMG_FALSE;
-}
-
-
 /**************************************************************************
  * Function Name  : GetTempBuffer
  * Inputs         : None
@@ -953,7 +977,7 @@
 static void *GetTempBuffer(void)
 {
 	/*
-	 * Allocate the temporary buffer, it it hasn't been allocated already.
+	 * Allocate the temporary buffer, if it hasn't been allocated already.
 	 * Return the address of the temporary buffer, or NULL if it
 	 * couldn't be allocated.
 	 * It is expected that the buffer will be allocated once, at driver
@@ -1079,10 +1103,6 @@
 	/* Allocate temporary buffer for copying from user space */
 	(void) GetTempBuffer();
 
-	eError = PVRSRV_ERROR_OUT_OF_MEMORY;
-	g_psPersistentHash = HASH_Create(PDUMP_PERSISTENT_HASH_SIZE);
-	PVR_LOGG_IF_FALSE((g_psPersistentHash != NULL), "Failed to create persistent process hash", errExit);
-
 	/* create the global PDump lock */
 	eError = PDumpCreateLockKM();
 	PVR_LOGG_IF_ERROR(eError, "PDumpCreateLockKM", errExit);
@@ -1096,8 +1116,6 @@
 	PVR_LOGG_IF_ERROR(eError, "PDumpCtrlInit", errExitOSDeInit);
 
 	/* Test PDump initialised and ready by logging driver details */
-	eError = PDumpCommentWithFlags(PDUMP_FLAGS_CONTINUOUS, "Driver Product Name: %s", PVRSRVGetSystemName());
-	PVR_LOGG_IF_ERROR(eError, "PDumpCommentWithFlags", errExitCtrl);
 	eError = PDumpCommentWithFlags(PDUMP_FLAGS_CONTINUOUS, "Driver Product Version: %s - %s (%s)", PVRVERSION_STRING, PVR_BUILD_DIR, PVR_BUILD_TYPE);
 	PVR_LOGG_IF_ERROR(eError, "PDumpCommentWithFlags", errExitCtrl);
 	if (pszEnvComment != NULL)
@@ -1153,33 +1171,6 @@
 	return g_PDumpInitialised;
 }
 
-
-PVRSRV_ERROR PDumpAddPersistantProcess(void)
-{
-	IMG_PID uiPID = OSGetCurrentClientProcessIDKM();
-	uintptr_t puiRetrieve;
-	PVRSRV_ERROR eError = PVRSRV_OK;
-
-	PDUMP_HEREA(121);
-
-	puiRetrieve = HASH_Retrieve(g_psPersistentHash, uiPID);
-	if (puiRetrieve == 0)
-	{
-		if (!HASH_Insert(g_psPersistentHash, uiPID, PERSISTANT_MAGIC))
-		{
-			eError = PVRSRV_ERROR_OUT_OF_MEMORY;
-		}
-	}
-	else
-	{
-		PVR_ASSERT(puiRetrieve == PERSISTANT_MAGIC);
-	}
-	PDUMP_HEREA(122);
-
-	return eError;
-}
-
-
 void PDumpStopInitPhase(IMG_BOOL bPDumpClient, IMG_BOOL bInitClient)
 {
 	/* Check with the OS we a running on */
@@ -1196,17 +1187,13 @@
 	}
 }
 
-PVRSRV_ERROR PDumpIsLastCaptureFrameKM(void)
+PVRSRV_ERROR PDumpIsLastCaptureFrameKM(IMG_BOOL *pbIsLastCaptureFrame)
 {
-	IMG_BOOL bIsLastCaptureFrame = IMG_FALSE;
-
 	PDumpCtrlLockAcquire();
-	bIsLastCaptureFrame = PDumpCtrlIsLastCaptureFrame();
+	*pbIsLastCaptureFrame = PDumpCtrlIsLastCaptureFrame();
 	PDumpCtrlLockRelease();
 
-	/* We're using INVALID_PARAMS error as true value and OK as false.
-	 * This is mapped to IMG_BOOL in user space. */
-	return bIsLastCaptureFrame ? PVRSRV_ERROR_INVALID_PARAMS : PVRSRV_OK;
+	return PVRSRV_OK;
 }
 
 
@@ -1258,7 +1245,7 @@
 	OSFreeMem(psData);
 }
 
-PVRSRV_ERROR PDumpTransition(PDUMP_CONNECTION_DATA *psPDumpConnectionData, IMG_BOOL bInto, IMG_BOOL bContinuous)
+PVRSRV_ERROR PDumpTransition(PDUMP_CONNECTION_DATA *psPDumpConnectionData, IMG_BOOL bInto, IMG_UINT32 ui32PDumpFlags)
 {
 	DLLIST_NODE *psNode, *psNext;
 	PVRSRV_ERROR eError;
@@ -1272,7 +1259,7 @@
 			PDUMP_Transition_DATA *psData =
 				IMG_CONTAINER_OF(psNode, PDUMP_Transition_DATA, sNode);
 
-			eError = psData->pfnCallback(psData->hPrivData, bInto, bContinuous);
+			eError = psData->pfnCallback(psData->hPrivData, bInto, ui32PDumpFlags);
 
 			if (eError != PVRSRV_OK)
 			{
@@ -1309,13 +1296,15 @@
 	/*
 		Note:
 		As we can't test to see if the new frame will be in capture range
-		before we set the frame number and we don't want to roll back
-		the frame number if we fail then we have to save the "transient"
-		data which decides if we're entering or exiting capture range
-		along with a failure boolean so we know what to do on a retry
+		before we set the frame number and we don't want to roll back the
+		frame number if we fail then we have to save the "transient" data
+		which decides if we're entering or exiting capture range along
+		with a failure boolean so we know what's required on a retry
 	*/
 	if (psPDumpConnectionData->ui32LastSetFrameNumber != ui32Frame)
 	{
+		(void) PDumpCommentWithFlags(PDUMP_FLAGS_CONTINUOUS, "Set pdump frame %u", ui32Frame);
+
 		/*
 			The boolean values below decide if the PDump transition
 			should trigger because of the current context setting the
@@ -1353,7 +1342,7 @@
 
 	if (!bWasInCaptureRange && bIsInCaptureRange)
 	{
-		eError = PDumpTransition(psPDumpConnectionData, IMG_TRUE, IMG_FALSE);
+		eError = PDumpTransition(psPDumpConnectionData, IMG_TRUE, PDUMP_FLAGS_NONE);
 		if (eError != PVRSRV_OK)
 		{
 			goto fail_Transition;
@@ -1361,7 +1350,7 @@
 	}
 	else if (bWasInCaptureRange && !bIsInCaptureRange)
 	{
-		eError = PDumpTransition(psPDumpConnectionData, IMG_FALSE, IMG_FALSE);
+		eError = PDumpTransition(psPDumpConnectionData, IMG_FALSE, PDUMP_FLAGS_NONE);
 		if (eError != PVRSRV_OK)
 		{
 			goto fail_Transition;
@@ -1369,8 +1358,9 @@
 	}
 	else
 	{
-		/* Here both previous and current frames are in or out of range */
-		/* Should never reach here due to the above goto success */
+		/* Here both previous and current frames are in or out of range.
+		 * There is no transition in this case.
+		 */
 	}
 
 	psPDumpConnectionData->bLastTransitionFailed = IMG_FALSE;
@@ -1393,8 +1383,9 @@
 	PVR_DPF((PVR_DBG_WARNING, "PDumpSetFrameKM: ui32Frame( %d )", ui32Frame));
 #endif
 
-	/* Ignore errors as it is not fatal if the comments do not appear */
+#if defined(PDUMP_DEBUG_OUTFILES)
 	(void) PDumpCommentWithFlags(PDUMP_FLAGS_CONTINUOUS, "Set pdump frame %u (pre)", ui32Frame);
+#endif
 
 	eError = _PDumpSetFrameKM(psConnection, ui32Frame);
 	if ((eError != PVRSRV_OK) && (eError != PVRSRV_ERROR_RETRY))
@@ -1402,7 +1393,9 @@
 		PVR_LOG_ERROR(eError, "_PDumpSetFrameKM");
 	}
 
+#if defined(PDUMP_DEBUG_OUTFILES)
 	(void) PDumpCommentWithFlags(PDUMP_FLAGS_CONTINUOUS, "Set pdump frame %u (post)", ui32Frame);
+#endif
 
 	return eError;
 }
@@ -1561,8 +1554,8 @@
                                   IMG_UINT32 ui32Flags)
 {
 	PVRSRV_ERROR eErr;
-	IMG_CHAR aszMemspaceName[PMR_MAX_MEMSPACE_NAME_LENGTH_DEFAULT];
-	IMG_CHAR aszSymbolicName[PMR_MAX_SYMBOLIC_ADDRESS_LENGTH_DEFAULT];
+	IMG_CHAR aszMemspaceName[PHYSMEM_PDUMP_MEMSPACE_MAX_LENGTH];
+	IMG_CHAR aszSymbolicName[PHYSMEM_PDUMP_SYMNAME_MAX_LENGTH];
 	IMG_DEVMEM_OFFSET_T uiPDumpSymbolicOffset;
 	IMG_DEVMEM_OFFSET_T uiNextSymName;
 
@@ -1571,9 +1564,9 @@
 
 	eErr = PMR_PDumpSymbolicAddr(psPMR,
                                      uiLogicalOffset,
-                                     PMR_MAX_MEMSPACE_NAME_LENGTH_DEFAULT,
+                                     PHYSMEM_PDUMP_MEMSPACE_MAX_LENGTH,
                                      aszMemspaceName,
-                                     PMR_MAX_SYMBOLIC_ADDRESS_LENGTH_DEFAULT,
+                                     PHYSMEM_PDUMP_SYMNAME_MAX_LENGTH,
                                      aszSymbolicName,
                                      &uiPDumpSymbolicOffset,
                                      &uiNextSymName);
@@ -1612,8 +1605,8 @@
 								  IMG_UINT32 ui32Flags)
 {
 	PVRSRV_ERROR eErr;
-	IMG_CHAR aszMemspaceName[PMR_MAX_MEMSPACE_NAME_LENGTH_DEFAULT];
-	IMG_CHAR aszSymbolicName[PMR_MAX_SYMBOLIC_ADDRESS_LENGTH_DEFAULT];
+	IMG_CHAR aszMemspaceName[PHYSMEM_PDUMP_MEMSPACE_MAX_LENGTH];
+	IMG_CHAR aszSymbolicName[PHYSMEM_PDUMP_SYMNAME_MAX_LENGTH];
 	IMG_DEVMEM_OFFSET_T uiPDumpSymbolicOffset;
 	IMG_DEVMEM_OFFSET_T uiNextSymName;
 
@@ -1622,9 +1615,9 @@
 
 	eErr = PMR_PDumpSymbolicAddr(psPMR,
 									 uiLogicalOffset,
-									 PMR_MAX_MEMSPACE_NAME_LENGTH_DEFAULT,
+									 PHYSMEM_PDUMP_MEMSPACE_MAX_LENGTH,
 									 aszMemspaceName,
-									 PMR_MAX_SYMBOLIC_ADDRESS_LENGTH_DEFAULT,
+									 PHYSMEM_PDUMP_SYMNAME_MAX_LENGTH,
 									 aszSymbolicName,
 									 &uiPDumpSymbolicOffset,
 									 &uiNextSymName);
@@ -1664,8 +1657,8 @@
                                         IMG_UINT32	ui32Flags)
 {
 	PVRSRV_ERROR eErr;
-	IMG_CHAR aszMemspaceName[PMR_MAX_MEMSPACE_NAME_LENGTH_DEFAULT];
-	IMG_CHAR aszSymbolicName[PMR_MAX_SYMBOLIC_ADDRESS_LENGTH_DEFAULT];
+	IMG_CHAR aszMemspaceName[PHYSMEM_PDUMP_MEMSPACE_MAX_LENGTH];
+	IMG_CHAR aszSymbolicName[PHYSMEM_PDUMP_SYMNAME_MAX_LENGTH];
 	IMG_DEVMEM_OFFSET_T uiPDumpSymbolicOffset;
 	IMG_DEVMEM_OFFSET_T uiNextSymName;
 
@@ -1674,9 +1667,9 @@
 
 	eErr = PMR_PDumpSymbolicAddr(psPMR,
                                      uiLogicalOffset,
-                                     PMR_MAX_MEMSPACE_NAME_LENGTH_DEFAULT,
+                                     PHYSMEM_PDUMP_MEMSPACE_MAX_LENGTH,
                                      aszMemspaceName,
-                                     PMR_MAX_SYMBOLIC_ADDRESS_LENGTH_DEFAULT,
+                                     PHYSMEM_PDUMP_SYMNAME_MAX_LENGTH,
                                      aszSymbolicName,
                                      &uiPDumpSymbolicOffset,
                                      &uiNextSymName);
@@ -1852,10 +1845,10 @@
                                   IMG_UINT32	ui32Flags)
 {
 	PVRSRV_ERROR eErr;
-	IMG_CHAR aszMemspaceNameSource[PMR_MAX_MEMSPACE_NAME_LENGTH_DEFAULT];
-	IMG_CHAR aszSymbolicNameSource[PMR_MAX_SYMBOLIC_ADDRESS_LENGTH_DEFAULT];
-	IMG_CHAR aszMemspaceNameDest[PMR_MAX_MEMSPACE_NAME_LENGTH_DEFAULT];
-	IMG_CHAR aszSymbolicNameDest[PMR_MAX_SYMBOLIC_ADDRESS_LENGTH_DEFAULT];
+	IMG_CHAR aszMemspaceNameSource[PHYSMEM_PDUMP_MEMSPACE_MAX_LENGTH];
+	IMG_CHAR aszSymbolicNameSource[PHYSMEM_PDUMP_SYMNAME_MAX_LENGTH];
+	IMG_CHAR aszMemspaceNameDest[PHYSMEM_PDUMP_MEMSPACE_MAX_LENGTH];
+	IMG_CHAR aszSymbolicNameDest[PHYSMEM_PDUMP_MEMSPNAME_SYMB_ADDR_MAX_LENGTH];
 	IMG_DEVMEM_OFFSET_T uiPDumpSymbolicOffsetSource;
 	IMG_DEVMEM_OFFSET_T uiPDumpSymbolicOffsetDest;
 	IMG_DEVMEM_OFFSET_T uiNextSymNameSource;
@@ -1867,9 +1860,9 @@
 
 	eErr = PMR_PDumpSymbolicAddr(psPMRSource,
                                      uiLogicalOffsetSource,
-                                     PMR_MAX_MEMSPACE_NAME_LENGTH_DEFAULT,
+                                     PHYSMEM_PDUMP_MEMSPACE_MAX_LENGTH,
                                      aszMemspaceNameSource,
-                                     PMR_MAX_SYMBOLIC_ADDRESS_LENGTH_DEFAULT,
+                                     PHYSMEM_PDUMP_SYMNAME_MAX_LENGTH,
                                      aszSymbolicNameSource,
                                      &uiPDumpSymbolicOffsetSource,
                                      &uiNextSymNameSource);
@@ -1881,9 +1874,9 @@
 
 	eErr = PMR_PDumpSymbolicAddr(psPMRDest,
                                      uiLogicalOffsetDest,
-                                     PMR_MAX_MEMSPACE_NAME_LENGTH_DEFAULT,
+                                     PHYSMEM_PDUMP_MEMSPACE_MAX_LENGTH,
                                      aszMemspaceNameDest,
-                                     PMR_MAX_SYMBOLIC_ADDRESS_LENGTH_DEFAULT,
+                                     PHYSMEM_PDUMP_SYMNAME_MAX_LENGTH,
                                      aszSymbolicNameDest,
                                      &uiPDumpSymbolicOffsetDest,
                                      &uiNextSymNameDest);
@@ -1926,10 +1919,10 @@
 								  IMG_UINT32	ui32Flags)
 {
 	PVRSRV_ERROR eErr;
-	IMG_CHAR aszMemspaceNameSource[PMR_MAX_MEMSPACE_NAME_LENGTH_DEFAULT];
-	IMG_CHAR aszSymbolicNameSource[PMR_MAX_SYMBOLIC_ADDRESS_LENGTH_DEFAULT];
-	IMG_CHAR aszMemspaceNameDest[PMR_MAX_MEMSPACE_NAME_LENGTH_DEFAULT];
-	IMG_CHAR aszSymbolicNameDest[PMR_MAX_SYMBOLIC_ADDRESS_LENGTH_DEFAULT];
+	IMG_CHAR aszMemspaceNameSource[PHYSMEM_PDUMP_MEMSPACE_MAX_LENGTH];
+	IMG_CHAR aszSymbolicNameSource[PHYSMEM_PDUMP_SYMNAME_MAX_LENGTH];
+	IMG_CHAR aszMemspaceNameDest[PHYSMEM_PDUMP_MEMSPACE_MAX_LENGTH];
+	IMG_CHAR aszSymbolicNameDest[PHYSMEM_PDUMP_SYMNAME_MAX_LENGTH];
 	IMG_DEVMEM_OFFSET_T uiPDumpSymbolicOffsetSource;
 	IMG_DEVMEM_OFFSET_T uiPDumpSymbolicOffsetDest;
 	IMG_DEVMEM_OFFSET_T uiNextSymNameSource;
@@ -1941,9 +1934,9 @@
 
 	eErr = PMR_PDumpSymbolicAddr(psPMRSource,
 									 uiLogicalOffsetSource,
-									 PMR_MAX_MEMSPACE_NAME_LENGTH_DEFAULT,
+									 PHYSMEM_PDUMP_MEMSPACE_MAX_LENGTH,
 									 aszMemspaceNameSource,
-									 PMR_MAX_SYMBOLIC_ADDRESS_LENGTH_DEFAULT,
+									 PHYSMEM_PDUMP_SYMNAME_MAX_LENGTH,
 									 aszSymbolicNameSource,
 									 &uiPDumpSymbolicOffsetSource,
 									 &uiNextSymNameSource);
@@ -1955,9 +1948,9 @@
 
 	eErr = PMR_PDumpSymbolicAddr(psPMRDest,
 									 uiLogicalOffsetDest,
-									 PMR_MAX_MEMSPACE_NAME_LENGTH_DEFAULT,
+									 PHYSMEM_PDUMP_MEMSPACE_MAX_LENGTH,
 									 aszMemspaceNameDest,
-									 PMR_MAX_SYMBOLIC_ADDRESS_LENGTH_DEFAULT,
+									 PHYSMEM_PDUMP_SYMNAME_MAX_LENGTH,
 									 aszSymbolicNameDest,
 									 &uiPDumpSymbolicOffsetDest,
 									 &uiNextSymNameDest);
@@ -2097,8 +2090,6 @@
 
 	PVR_DPF((PVR_DBG_ERROR, "PDumpSAW\n"));
 
-	uiPDumpFlags |= (PDumpIsPersistent()) ? PDUMP_FLAGS_PERSISTENT : 0;
-
 	PDUMP_LOCK();
 	eError = PDumpOSBufprintf(hScript,
 	                          ui32MaxLen,
@@ -2157,11 +2148,6 @@
 
 	PDUMP_GET_SCRIPT_STRING();
 	PDUMP_DBG(("PDumpRegPolKM"));
-	if ( PDumpIsPersistent() )
-	{
-		/* Don't pdump-poll if the process is persistent */
-		return PVRSRV_OK;
-	}
 
 	ui32PollCount = POLL_COUNT_LONG;
 
@@ -2194,13 +2180,6 @@
 	PDUMP_GET_SCRIPT_STRING();
 	PDUMP_DBG(("PDumpCommentKM"));
 
-#if defined(PDUMP_DEBUG_OUTFILES)
-	/* Include comments in the "extended" init phase.
-	 * The default is to ignore them.
-	 */
-	ui32Flags |= ( PDumpIsPersistent() ) ? PDUMP_FLAGS_PERSISTENT : 0;
-#endif
-
 	if((pszComment == NULL) || (PDumpOSBuflen(pszComment, ui32MaxLen) == 0))
 	{
 		/* PDumpOSVerifyLineEnding silently fails if pszComment is too short to
@@ -2238,7 +2217,7 @@
 
 	if (!PDumpWriteScript(hScript, ui32Flags))
 	{
-		if(ui32Flags & PDUMP_FLAGS_CONTINUOUS)
+		if(PDUMP_IS_CONTINUOUS(ui32Flags))
 		{
 			eErr = PVRSRV_ERROR_PDUMP_BUFFER_FULL;
 			PVR_LOGG_IF_ERROR(eErr, "PDumpWriteScript", ErrUnlock);
@@ -2286,15 +2265,33 @@
 PVRSRV_ERROR PDumpCommentWithFlags(IMG_UINT32 ui32Flags, IMG_CHAR * pszFormat, ...)
 {
 	PVRSRV_ERROR eErr = PVRSRV_OK;
-	PDUMP_va_list ap;
+	va_list args;
+
+	va_start(args, pszFormat);
+	PDumpCommentWithFlagsVA(ui32Flags, pszFormat, args);
+	va_end(args);
+
+	return eErr;
+}
+
+/**************************************************************************
+ * Function Name  : PDumpCommentWithFlagsVA
+ * Inputs         : psPDev    - PDev for PDump device
+ *				  : pszFormat - format string for comment
+ *				  : args      - pre-started va_list args for format string
+ * Outputs        : None
+ * Returns        : None
+ * Description    : PDumps a comments
+**************************************************************************/
+PVRSRV_ERROR PDumpCommentWithFlagsVA(IMG_UINT32 ui32Flags, const IMG_CHAR * pszFormat, va_list args)
+{
+	PVRSRV_ERROR eErr = PVRSRV_OK;
 	PDUMP_GET_MSG_STRING();
 
 	PDUMP_LOCK();
 
 	/* Construct the string */
-	PDUMP_va_start(ap, pszFormat);
-	eErr = PDumpOSVSprintf(pszMsg, ui32MaxLen, pszFormat, ap);
-	PDUMP_va_end(ap);
+	eErr = PDumpOSVSprintf(pszMsg, ui32MaxLen, pszFormat, args);
 
 	if(eErr != PVRSRV_OK)
 	{
@@ -2342,9 +2339,8 @@
 	/* Check the supplied panic reason string is within length limits */
 	PVR_ASSERT(OSStringLength(pszPanicMsg)+sizeof("PANIC   ") < PVRSRV_PDUMP_MAX_COMMENT_SIZE-1);
 
-	/* Add persistent flag if required and obtain lock to keep the multi-line
+	/* Obtain lock to keep the multi-line
 	 * panic statement together in a single atomic write */
-	uiPDumpFlags |= (PDumpIsPersistent()) ? PDUMP_FLAGS_PERSISTENT : 0;
 	PDUMP_LOCK();
 
 
@@ -2400,10 +2396,8 @@
 	/* Check the supplied panic reason string is within length limits */
 	PVR_ASSERT(OSStringLength(pszErrorMsg)+sizeof(pszFormatStr) < PVRSRV_PDUMP_MAX_COMMENT_SIZE-1);
 
-	/* Add persistent flag if required and obtain lock to keep the multi-line
+	/* Obtain lock to keep the multi-line 
 	 * panic statement together in a single atomic write */
-	uiPDumpFlags |= (PDumpIsPersistent()) ? PDUMP_FLAGS_PERSISTENT : 0;
-
 	PDUMP_LOCK();
 
 	/* Write driver error message to the script file */
@@ -2456,11 +2450,6 @@
 	PVRSRV_ERROR eErr=0;
 	PDUMP_GET_SCRIPT_STRING();
 
-	if ( PDumpIsPersistent() )
-	{
-		return PVRSRV_OK;
-	}
-	
 	PDumpCommentWithFlags(ui32PDumpFlags, "Dump bitmap of render.");
 	
 	switch (ePixelFormat)
@@ -3381,12 +3370,8 @@
 
 void PDumpCommonDumpState(IMG_BOOL bDumpOSLayerState)
 {
-	IMG_UINT32* ui32HashData = (IMG_UINT32*)g_psPersistentHash;
-
 	PVR_LOG(("--- PDUMP COMMON: g_PDumpInitialised( %d )",
 			g_PDumpInitialised) );
-	PVR_LOG(("--- PDUMP COMMON: g_psPersistentHash( %p ) uSize( %d ) uCount( %d )",
-			g_psPersistentHash, ui32HashData[0], ui32HashData[1]) );
 	PVR_LOG(("--- PDUMP COMMON: g_PDumpScript.sCh.hInit( %p ) g_PDumpScript.sCh.hMain( %p ) g_PDumpScript.sCh.hDeinit( %p )",
 			g_PDumpScript.sCh.hInit, g_PDumpScript.sCh.hMain, g_PDumpScript.sCh.hDeinit) );
 	PVR_LOG(("--- PDUMP COMMON: g_PDumpParameters.sCh.hInit( %p ) g_PDumpParameters.sCh.hMain( %p ) g_PDumpParameters.sCh.hDeinit( %p )",
diff --git a/drivers/staging/imgtec/rogue/pdump_km.h b/drivers/staging/imgtec/rogue/pdump_km.h
index f98976f..cddf4d6 100644
--- a/drivers/staging/imgtec/rogue/pdump_km.h
+++ b/drivers/staging/imgtec/rogue/pdump_km.h
@@ -44,6 +44,10 @@
 #ifndef _PDUMP_KM_H_
 #define _PDUMP_KM_H_
 
+#if defined(PDUMP)
+#include <stdarg.h>
+#endif
+
 /* services/srvkm/include/ */
 #include "device.h"
 
@@ -51,7 +55,7 @@
 #include "pvrsrv_error.h"
 
 
-#if defined(__KERNEL__) && defined(ANDROID) && !defined(__GENKSYMS__)
+#if defined(__KERNEL__) && defined(LINUX) && !defined(__GENKSYMS__)
 #define __pvrsrv_defined_struct_enum__
 #include <services_kernel_client.h>
 #endif
@@ -85,14 +89,14 @@
 #endif
 
 typedef struct _PDUMP_CONNECTION_DATA_ PDUMP_CONNECTION_DATA;
-typedef PVRSRV_ERROR (*PFN_PDUMP_TRANSITION)(void **pvData, IMG_BOOL bInto, IMG_BOOL bContinuous);
+typedef PVRSRV_ERROR (*PFN_PDUMP_TRANSITION)(void **pvData, IMG_BOOL bInto, IMG_UINT32 ui32PDumpFlags);
 
 #ifdef PDUMP
 
 /*! Macro used to record a panic in the PDump script stream */
-#define PDUMP_PANIC(_type, _id, _msg) do \
+#define PDUMP_PANIC(_id, _msg) do \
 		{ PVRSRV_ERROR _eE;\
-			_eE = PDumpPanic((PVRSRV_DEVICE_TYPE_ ## _type)<<16 | ((_type ## _PDUMP_PANIC_ ## _id)&0xFFFF), _msg, __FUNCTION__, __LINE__);\
+			_eE = PDumpPanic(((RGX_PDUMP_PANIC_ ## _id) & 0xFFFF), _msg, __FUNCTION__, __LINE__);	\
 			PVR_LOG_IF_ERROR(_eE, "PDumpPanic");\
 		MSC_SUPPRESS_4127\
 		} while (0)
@@ -237,7 +241,11 @@
 
 	PVRSRV_ERROR PDumpCommentWithFlags(IMG_UINT32	ui32Flags,
 									   IMG_CHAR*	pszFormat,
-									   ...) IMG_FORMAT_PRINTF(2, 3);
+									   ...) __printf(2, 3);
+
+	PVRSRV_ERROR PDumpCommentWithFlagsVA(IMG_UINT32 ui32Flags,
+									    const IMG_CHAR * pszFormat,
+										va_list args);
 
 	PVRSRV_ERROR PDumpPanic(IMG_UINT32      ui32PanicNo,
 							IMG_CHAR*       pszPanicMsg,
@@ -259,27 +267,10 @@
 									 IMG_UINT32		ui32Flags,
 									 IMG_HANDLE		hUniqueTag);
 
-	PVRSRV_ERROR PDumpIsLastCaptureFrameKM(void);
+	PVRSRV_ERROR PDumpIsLastCaptureFrameKM(IMG_BOOL *pbIsLastCaptureFrame);
 
 	PVRSRV_ERROR PDumpIsCaptureFrameKM(IMG_BOOL *bIsCapturing);
 
-	void PDumpMallocPagesPhys(PVRSRV_DEVICE_IDENTIFIER	*psDevID,
-							  IMG_UINT64			ui64DevVAddr,
-							  IMG_PUINT32			pui32PhysPages,
-							  IMG_UINT32			ui32NumPages,
-							  IMG_HANDLE			hUniqueTag);
-	PVRSRV_ERROR PDumpSetMMUContext(PVRSRV_DEVICE_TYPE eDeviceType,
-									IMG_CHAR *pszMemSpace,
-									IMG_UINT32 *pui32MMUContextID,
-									IMG_UINT32 ui32MMUType,
-									IMG_HANDLE hUniqueTag1,
-									IMG_HANDLE hOSMemHandle,
-									void *pvPDCPUAddr);
-	PVRSRV_ERROR PDumpClearMMUContext(PVRSRV_DEVICE_TYPE eDeviceType,
-									IMG_CHAR *pszMemSpace,
-									IMG_UINT32 ui32MMUContextID,
-									IMG_UINT32 ui32MMUType);
-
 	PVRSRV_ERROR PDumpRegRead32(IMG_CHAR *pszPDumpRegName,
 								const IMG_UINT32 dwRegOffset,
 								IMG_UINT32	ui32Flags);
@@ -290,14 +281,6 @@
 	PVRSRV_ERROR PDumpIDLWithFlags(IMG_UINT32 ui32Clocks, IMG_UINT32 ui32Flags);
 	PVRSRV_ERROR PDumpIDL(IMG_UINT32 ui32Clocks);
 
-	IMG_IMPORT PVRSRV_ERROR PDumpHWPerfCBKM(PVRSRV_DEVICE_IDENTIFIER *psDevId,
-										IMG_CHAR			*pszFileName,
-										IMG_UINT32			ui32FileOffset,
-										IMG_DEV_VIRTADDR	sDevBaseAddr,
-										IMG_UINT32 			ui32Size,
-										IMG_UINT32			ui32MMUContextID,
-										IMG_UINT32 			ui32PDumpFlags);
-
 	PVRSRV_ERROR PDumpRegBasedCBP(IMG_CHAR		*pszPDumpRegName,
 								  IMG_UINT32	ui32RegOffset,
 								  IMG_UINT32	ui32WPosVal,
@@ -319,13 +302,6 @@
 	void PDumpLock(void);
 	void PDumpUnlock(void);
 
-	/*
-	    Process persistence common API for use by common
-	    clients e.g. mmu and physmem.
-	 */
-	IMG_BOOL PDumpIsPersistent(void);
-	PVRSRV_ERROR PDumpAddPersistantProcess(void);
-
 	PVRSRV_ERROR PDumpIfKM(IMG_CHAR		*pszPDumpCond);
 	PVRSRV_ERROR PDumpElseKM(IMG_CHAR	*pszPDumpCond);
 	PVRSRV_ERROR PDumpFiKM(IMG_CHAR		*pszPDumpCond);
@@ -422,7 +398,7 @@
 extern void PDumpUnregisterTransitionCallback(void *pvHandle);
 
 /* Notify PDump of a Transition into/out of capture range */
-extern PVRSRV_ERROR PDumpTransition(PDUMP_CONNECTION_DATA *psPDumpConnectionData, IMG_BOOL bInto, IMG_BOOL bContinuous);
+extern PVRSRV_ERROR PDumpTransition(PDUMP_CONNECTION_DATA *psPDumpConnectionData, IMG_BOOL bInto, IMG_UINT32 ui32PDumpFlags);
 
 /* Wires-up a MIPS TLB in the page table*/
 extern PVRSRV_ERROR PdumpWireUpMipsTLB(PMR *psPMRSource,
@@ -452,8 +428,6 @@
 	#define PDUMPCOMMENT(...)		PDumpCommentWithFlags(PDUMP_FLAGS_CONTINUOUS, __VA_ARGS__)
 	#define PDUMPCOMMENTWITHFLAGS	PDumpCommentWithFlags
 	#define PDUMPREGPOL				PDumpRegPolKM
-	#define PDUMPSETMMUCONTEXT		PDumpSetMMUContext
-	#define PDUMPCLEARMMUCONTEXT	PDumpClearMMUContext
 	#define PDUMPPDREG				PDumpPDReg
 	#define PDUMPPDREGWITHFLAGS		PDumpPDRegWithFlags
 	#define PDUMPREGBASEDCBP		PDumpRegBasedCBP
@@ -469,11 +443,11 @@
 #else
 	/*
 		We should be clearer about which functions can be called
-		across the bridge as this looks rather unblanced
+		across the bridge as this looks rather unbalanced
 	*/
 
 /*! Macro used to record a panic in the PDump script stream */
-#define PDUMP_PANIC(_type, _id, _msg)  ((void)0);
+#define PDUMP_PANIC(_id, _msg)  ((void)0);
 
 /*! Macro used to record a driver error in the PDump script stream to invalidate the capture */
 #define PDUMP_ERROR(_err, _msg) ((void)0);
@@ -539,16 +513,6 @@
 }
 
 #ifdef INLINE_IS_PRAGMA
-#pragma inline(PDumpAddPersistantProcess)
-#endif
-static INLINE PVRSRV_ERROR
-PDumpAddPersistantProcess(void)
-{
-	return PVRSRV_OK;
-}
-
-
-#ifdef INLINE_IS_PRAGMA
 #pragma inline(PDumpStopInitPhase)
 #endif
 static INLINE void
@@ -575,7 +539,9 @@
 #pragma inline(PDumpGetFrameKM)
 #endif
 static INLINE PVRSRV_ERROR
-PDumpGetFrameKM(CONNECTION_DATA *psConnection, IMG_UINT32* pui32Frame)
+PDumpGetFrameKM(CONNECTION_DATA *psConnection,
+                PVRSRV_DEVICE_NODE *psDeviceNode,
+                IMG_UINT32* pui32Frame)
 {
 	PVR_UNREFERENCED_PARAMETER(psConnection);
 	PVR_UNREFERENCED_PARAMETER(pui32Frame);
@@ -650,9 +616,9 @@
 #pragma inline(PDumpIsLastCaptureFrameKM)
 #endif
 static INLINE PVRSRV_ERROR
-PDumpIsLastCaptureFrameKM(void)
+PDumpIsLastCaptureFrameKM(IMG_BOOL *pbIsLastCaptureFrame)
 {
-	/* PVRSRV_OK means FALSE to the upper levels. */
+	*pbIsLastCaptureFrame = IMG_FALSE;
 	return PVRSRV_OK;
 }
 
@@ -750,11 +716,11 @@
 #pragma inline(PDumpTransition)
 #endif
 static INLINE
-PVRSRV_ERROR PDumpTransition(PDUMP_CONNECTION_DATA *psPDumpConnectionData, IMG_BOOL bInto, IMG_BOOL bContinuous)
+PVRSRV_ERROR PDumpTransition(PDUMP_CONNECTION_DATA *psPDumpConnectionData, IMG_BOOL bInto, IMG_UINT32 ui32PDumpFlags)
 {
 	PVR_UNREFERENCED_PARAMETER(psPDumpConnectionData);
 	PVR_UNREFERENCED_PARAMETER(bInto);
-	PVR_UNREFERENCED_PARAMETER(bContinuous);
+	PVR_UNREFERENCED_PARAMETER(ui32PDumpFlags);
 	return PVRSRV_OK;
 }
 
@@ -767,8 +733,6 @@
 		#define PDUMPREGREAD64(...)			/ ## * PDUMPREGREAD64(__VA_ARGS__) * ## /
 		#define PDUMPCOMMENT(...)		/ ## * PDUMPCOMMENT(__VA_ARGS__) * ## /
 		#define PDUMPREGPOL(...)		/ ## * PDUMPREGPOL(__VA_ARGS__) * ## /
-		#define PDUMPSETMMUCONTEXT(...)		/ ## * PDUMPSETMMUCONTEXT(__VA_ARGS__) * ## /
-		#define PDUMPCLEARMMUCONTEXT(...)	/ ## * PDUMPCLEARMMUCONTEXT(__VA_ARGS__) * ## /
 		#define PDUMPPDREG(...)			/ ## * PDUMPPDREG(__VA_ARGS__) * ## /
 		#define PDUMPPDREGWITHFLAGS(...)	/ ## * PDUMPPDREGWITHFLAGS(__VA_ARGS__) * ## /
 		#define PDUMPSYNC(...)			/ ## * PDUMPSYNC(__VA_ARGS__) * ## /
@@ -791,7 +755,7 @@
 		#define PDUMP_LOCK			/ ## * PDUMP_LOCK(__VA_ARGS__) * ## /
 		#define PDUMP_UNLOCK			/ ## * PDUMP_UNLOCK(__VA_ARGS__) * ## /
 	#else
-		#if defined LINUX || defined GCC_IA32 || defined GCC_ARM || defined __QNXNTO__
+		#if defined LINUX || defined GCC_IA32 || defined GCC_ARM || defined __QNXNTO__ || defined(INTEGRITY_OS)
 			#define PDUMPINIT	PDumpInitCommon
 			#define PDUMPDEINIT(args...)
 			#define PDUMPREG32(args...)
@@ -800,8 +764,6 @@
 			#define PDUMPREGREAD64(args...)
 			#define PDUMPCOMMENT(args...)
 			#define PDUMPREGPOL(args...)
-			#define PDUMPSETMMUCONTEXT(args...)
-			#define PDUMPCLEARMMUCONTEXT(args...)
 			#define PDUMPPDREG(args...)
 			#define PDUMPPDREGWITHFLAGS(args...)
 			#define PDUMPSYNC(args...)
diff --git a/drivers/staging/imgtec/rogue/pdump_mmu.c b/drivers/staging/imgtec/rogue/pdump_mmu.c
index 7a7a32f..218c6b2 100644
--- a/drivers/staging/imgtec/rogue/pdump_mmu.c
+++ b/drivers/staging/imgtec/rogue/pdump_mmu.c
@@ -47,6 +47,7 @@
 #include "pdump_mmu.h"
 #include "pdump_osfunc.h"
 #include "pdump_km.h"
+#include "pdump_physmem.h"
 #include "osfunc.h"
 #include "pvr_debug.h"
 #include "pvrsrv_error.h"
@@ -54,8 +55,6 @@
 #define MAX_PDUMP_MMU_CONTEXTS	(10)
 static IMG_UINT32 guiPDumpMMUContextAvailabilityMask = (1<<MAX_PDUMP_MMU_CONTEXTS)-1;
 
-/* arbitrary buffer length here. */
-#define MAX_SYMBOLIC_ADDRESS_LENGTH 40
 
 #define MMUPX_FMT(X) ((X<3) ? ((X<2) ?  "MMUPT_\0" : "MMUPD_\0") : "MMUPC_\0")
 #define MIPSMMUPX_FMT(X) ((X<3) ? ((X<2) ?  "MIPSMMUPT_\0" : "MIPSMMUPD_\0") : "MIPSMMUPC_\0")
@@ -183,8 +182,6 @@
 
 	PDUMP_GET_SCRIPT_STRING();
 
-	ui32Flags |= ( PDumpIsPersistent() ) ? PDUMP_FLAGS_PERSISTENT : 0;
-
 	if (eMMULevel >= MMU_LEVEL_LAST)
 	{
 		eErr = PVRSRV_ERROR_INVALID_PARAMS;
@@ -266,8 +263,6 @@
 
 	PDUMP_GET_SCRIPT_STRING();
 
-	ui32Flags |= ( PDumpIsPersistent() ) ? PDUMP_FLAGS_PERSISTENT : 0;
-
 	if (eMMULevel >= MMU_LEVEL_LAST)
 	{
 		eErr = PVRSRV_ERROR_INVALID_PARAMS;
@@ -338,8 +333,6 @@
 
 	PDUMP_GET_SCRIPT_STRING();
 
-	ui32Flags |= ( PDumpIsPersistent() ) ? PDUMP_FLAGS_PERSISTENT : 0;
-
 	PDUMP_LOCK();
 	/*
 		Write a comment to the PDump2 script streams indicating the memory allocation
@@ -395,8 +388,6 @@
 
 	PDUMP_GET_SCRIPT_STRING();
 
-	ui32Flags |= ( PDumpIsPersistent() ) ? PDUMP_FLAGS_PERSISTENT : 0;
-
 	PDUMP_LOCK();
 	/*
 		Write a comment to the PDUMP2 script streams indicating the memory free
@@ -443,8 +434,8 @@
 								  IMG_UINT64 ui64PxSymAddr)
 {
 
-	IMG_CHAR aszMemspaceNameDest[PMR_MAX_MEMSPACE_NAME_LENGTH_DEFAULT];
-	IMG_CHAR aszSymbolicNameDest[PMR_MAX_SYMBOLIC_ADDRESS_LENGTH_DEFAULT];
+	IMG_CHAR aszMemspaceNameDest[PHYSMEM_PDUMP_MEMSPACE_MAX_LENGTH];
+	IMG_CHAR aszSymbolicNameDest[PHYSMEM_PDUMP_SYMNAME_MAX_LENGTH];
 	IMG_DEVMEM_OFFSET_T uiPDumpSymbolicOffsetDest;
 	IMG_DEVMEM_OFFSET_T uiNextSymNameDest;
 	PVRSRV_ERROR eErr = PVRSRV_OK;
@@ -454,9 +445,9 @@
 
 	eErr = PMR_PDumpSymbolicAddr(psPMRDest,
 									 uiLogicalOffsetDest,
-									 PMR_MAX_MEMSPACE_NAME_LENGTH_DEFAULT,
+									 PHYSMEM_PDUMP_MEMSPACE_MAX_LENGTH,
 									 aszMemspaceNameDest,
-									 PMR_MAX_SYMBOLIC_ADDRESS_LENGTH_DEFAULT,
+									 PHYSMEM_PDUMP_SYMNAME_MAX_LENGTH,
 									 aszSymbolicNameDest,
 									 &uiPDumpSymbolicOffsetDest,
 									 &uiNextSymNameDest);
@@ -525,15 +516,13 @@
     IMG_INT32  iShiftAmount;
     IMG_CHAR   *pszWrwSuffix = 0;
     void *pvRawBytes = 0;
-    IMG_CHAR aszPxSymbolicAddr[MAX_SYMBOLIC_ADDRESS_LENGTH];
+    IMG_CHAR aszPxSymbolicAddr[PHYSMEM_PDUMP_SYMNAME_MAX_LENGTH];
     IMG_UINT64 ui64PxE64;
     IMG_UINT64 ui64Protflags64;
     IMG_CHAR *pszMMUPX;
 
 	PDUMP_GET_SCRIPT_STRING();
 
-	ui32Flags |= ( PDumpIsPersistent() ) ? PDUMP_FLAGS_PERSISTENT : 0;
-
 	if (!PDumpReady())
 	{
 		eErr = PVRSRV_ERROR_PDUMP_NOT_AVAILABLE;
@@ -568,7 +557,7 @@
 		pszMMUPX = MMUPX_FMT(eMMULevel);
 	}
     OSSNPrintf(aszPxSymbolicAddr,
-               MAX_SYMBOLIC_ADDRESS_LENGTH,
+               PHYSMEM_PDUMP_SYMNAME_MAX_LENGTH,
                ":%s:%s%016llX",
                pszPDumpDevName,
                pszMMUPX,
@@ -908,11 +897,11 @@
 
 
 /**************************************************************************
- * Function Name  : PDumpSetMMUContext
+ * Function Name  : PDumpMMUAllocMMUContext
  * Inputs         :
  * Outputs        : None
  * Returns        : PVRSRV_ERROR
- * Description    : Set MMU Context
+ * Description    : Alloc MMU Context
 **************************************************************************/
 PVRSRV_ERROR PDumpMMUAllocMMUContext(const IMG_CHAR *pszPDumpMemSpaceName,
                                      IMG_DEV_PHYADDR sPCDevPAddr,
@@ -929,7 +918,8 @@
 	eErr = _PdumpAllocMMUContext(&ui32MMUContextID);
 	if(eErr != PVRSRV_OK)
 	{
-		PVR_DPF((PVR_DBG_ERROR, "PDumpSetMMUContext: _PdumpAllocMMUContext failed: %d", eErr));
+		PVR_DPF((PVR_DBG_ERROR, "%s: _PdumpAllocMMUContext failed: %d",
+				 __func__, eErr));
         PVR_DBG_BREAK;
 		goto ErrOut;
 	}
@@ -984,11 +974,11 @@
 
 
 /**************************************************************************
- * Function Name  : PDumpClearMMUContext
+ * Function Name  : PDumpMMUFreeMMUContext
  * Inputs         :
  * Outputs        : None
  * Returns        : PVRSRV_ERROR
- * Description    : Clear MMU Context
+ * Description    : Free MMU Context
 **************************************************************************/
 PVRSRV_ERROR PDumpMMUFreeMMUContext(const IMG_CHAR *pszPDumpMemSpaceName,
                                     IMG_UINT32 ui32MMUContextID)
@@ -1022,7 +1012,8 @@
 	eErr = _PdumpFreeMMUContext(ui32MMUContextID);
 	if(eErr != PVRSRV_OK)
 	{
-		PVR_DPF((PVR_DBG_ERROR, "PDumpClearMMUContext: _PdumpFreeMMUContext failed: %d", eErr));
+		PVR_DPF((PVR_DBG_ERROR, "%s: _PdumpFreeMMUContext failed: %d",
+				 __func__, eErr));
 		goto ErrUnlock;
 	}
 
@@ -1049,8 +1040,6 @@
 
 	PDUMP_GET_SCRIPT_STRING();
 
-	ui32Flags |= ( PDumpIsPersistent() ) ? PDUMP_FLAGS_PERSISTENT : 0;
-
 	if (!PDumpReady())
 	{
 		eErr = PVRSRV_ERROR_PDUMP_NOT_AVAILABLE;
@@ -1111,8 +1100,6 @@
 
 	PDUMP_GET_SCRIPT_STRING();
 
-	ui32PDumpFlags |= ( PDumpIsPersistent() ) ? PDUMP_FLAGS_PERSISTENT : 0;
-
 	if (!PDumpReady())
 	{
 		eErr = PVRSRV_ERROR_PDUMP_NOT_AVAILABLE;
@@ -1163,10 +1150,10 @@
 								IMG_UINT32 ui32Flags)
 {
 	PVRSRV_ERROR eErr = PVRSRV_OK;
-	IMG_CHAR aszMemspaceNameSource[PMR_MAX_MEMSPACE_NAME_LENGTH_DEFAULT];
-	IMG_CHAR aszSymbolicNameSource[PMR_MAX_SYMBOLIC_ADDRESS_LENGTH_DEFAULT];
-	IMG_CHAR aszMemspaceNameDest[PMR_MAX_MEMSPACE_NAME_LENGTH_DEFAULT];
-	IMG_CHAR aszSymbolicNameDest[PMR_MAX_SYMBOLIC_ADDRESS_LENGTH_DEFAULT];
+	IMG_CHAR aszMemspaceNameSource[PHYSMEM_PDUMP_MEMSPACE_MAX_LENGTH];
+	IMG_CHAR aszSymbolicNameSource[PHYSMEM_PDUMP_SYMNAME_MAX_LENGTH];
+	IMG_CHAR aszMemspaceNameDest[PHYSMEM_PDUMP_MEMSPACE_MAX_LENGTH];
+	IMG_CHAR aszSymbolicNameDest[PHYSMEM_PDUMP_SYMNAME_MAX_LENGTH];
 	IMG_DEVMEM_OFFSET_T uiPDumpSymbolicOffsetSource;
 	IMG_DEVMEM_OFFSET_T uiPDumpSymbolicOffsetDest;
 	IMG_DEVMEM_OFFSET_T uiNextSymNameSource;
@@ -1177,9 +1164,9 @@
 
 	eErr = PMR_PDumpSymbolicAddr(psPMRSource,
 									 uiLogicalOffsetSource,
-									 PMR_MAX_MEMSPACE_NAME_LENGTH_DEFAULT,
+									 PHYSMEM_PDUMP_MEMSPACE_MAX_LENGTH,
 									 aszMemspaceNameSource,
-									 PMR_MAX_SYMBOLIC_ADDRESS_LENGTH_DEFAULT,
+									 PHYSMEM_PDUMP_SYMNAME_MAX_LENGTH,
 									 aszSymbolicNameSource,
 									 &uiPDumpSymbolicOffsetSource,
 									 &uiNextSymNameSource);
@@ -1191,9 +1178,9 @@
 
 	eErr = PMR_PDumpSymbolicAddr(psPMRDest,
 									 uiLogicalOffsetDest,
-									 PMR_MAX_MEMSPACE_NAME_LENGTH_DEFAULT,
+									 PHYSMEM_PDUMP_MEMSPACE_MAX_LENGTH,
 									 aszMemspaceNameDest,
-									 PMR_MAX_SYMBOLIC_ADDRESS_LENGTH_DEFAULT,
+									 PHYSMEM_PDUMP_SYMNAME_MAX_LENGTH,
 									 aszSymbolicNameDest,
 									 &uiPDumpSymbolicOffsetDest,
 									 &uiNextSymNameDest);
@@ -1268,8 +1255,8 @@
 									IMG_UINT32 ui32Flags)
 {
 	PVRSRV_ERROR eErr = PVRSRV_OK;
-	IMG_CHAR aszMemspaceNameDest[PMR_MAX_MEMSPACE_NAME_LENGTH_DEFAULT];
-	IMG_CHAR aszSymbolicNameDest[PMR_MAX_SYMBOLIC_ADDRESS_LENGTH_DEFAULT];
+	IMG_CHAR aszMemspaceNameDest[PHYSMEM_PDUMP_MEMSPACE_MAX_LENGTH];
+	IMG_CHAR aszSymbolicNameDest[PHYSMEM_PDUMP_SYMNAME_MAX_LENGTH];
 	IMG_DEVMEM_OFFSET_T uiPDumpSymbolicOffsetDest;
 	IMG_DEVMEM_OFFSET_T uiNextSymNameDest;
 
@@ -1278,9 +1265,9 @@
 
 	eErr = PMR_PDumpSymbolicAddr(psPMRDest,
 									 uiLogicalOffsetDest,
-									 PMR_MAX_MEMSPACE_NAME_LENGTH_DEFAULT,
+									 PHYSMEM_PDUMP_MEMSPACE_MAX_LENGTH,
 									 aszMemspaceNameDest,
-									 PMR_MAX_SYMBOLIC_ADDRESS_LENGTH_DEFAULT,
+									 PHYSMEM_PDUMP_SYMNAME_MAX_LENGTH,
 									 aszSymbolicNameDest,
 									 &uiPDumpSymbolicOffsetDest,
 									 &uiNextSymNameDest);
diff --git a/drivers/staging/imgtec/rogue/pdump_mmu.h b/drivers/staging/imgtec/rogue/pdump_mmu.h
index e035657..24c2663 100644
--- a/drivers/staging/imgtec/rogue/pdump_mmu.h
+++ b/drivers/staging/imgtec/rogue/pdump_mmu.h
@@ -80,6 +80,7 @@
 
 typedef struct _PDUMP_MMU_ATTRIB_
 {
+    /* FIXME: would these be better as pointers rather than copies? */
     struct _PDUMP_MMU_ATTRIB_DEVICE_ sDevice;
     struct _PDUMP_MMU_ATTRIB_CONTEXT_ sContext;
     struct _PDUMP_MMU_ATTRIB_HEAP_ sHeap;
@@ -149,6 +150,7 @@
 												IMG_UINT32 uiRegAddr,
 												const IMG_CHAR *pszPDumpPCSymbolicName);
 
+	/* FIXME: split to separate file... (debatable whether this is anything to do with MMU) */
 extern PVRSRV_ERROR
 PDumpMMUSAB(const IMG_CHAR *pszPDumpMemNamespace,
             IMG_UINT32 uiPDumpMMUCtx,
diff --git a/drivers/staging/imgtec/rogue/pdump_osfunc.h b/drivers/staging/imgtec/rogue/pdump_osfunc.h
index b23d5fd..1ec9ac2 100644
--- a/drivers/staging/imgtec/rogue/pdump_osfunc.h
+++ b/drivers/staging/imgtec/rogue/pdump_osfunc.h
@@ -47,6 +47,16 @@
 #include "pvrsrv_device_types.h"
 
 
+/* FIXME
+ * Some OSes (WinXP,CE) allocate the string on the stack, but some
+ * (Linux) use a global variable/lock instead.
+ * Would be good to use the same across all OSes.
+ *
+ * A handle is returned which represents IMG_CHAR* type on all OSes.
+ *
+ * The allocated buffer length is also returned on OSes where it's
+ * supported (e.g. Linux).
+ */
 #define MAX_PDUMP_STRING_LENGTH (256)
 #if defined(WIN32)
 #define PDUMP_GET_SCRIPT_STRING()	\
@@ -115,31 +125,34 @@
 	eErrorPDump = PDumpOSGetFilenameString(&pszFileName, &ui32MaxLenFileName);\
 	PVR_LOGR_IF_ERROR(eErrorPDump, "PDumpOSGetFilenameString");
 
-	/*!
-	 * @name	PDumpOSGetScriptString
-	 * @brief	Get the "script" buffer
-	 * @param	phScript - buffer handle for pdump script
-	 * @param	pui32MaxLen - max length of the script buffer
-	 * @return	error (always PVRSRV_OK on some OSes)
-	 */
+	/**************************************************************************/ /*!
+	@Function       PDumpOSGetScriptString
+	@Description    Get the handle of the PDump "script" buffer.
+	                This function is only called if PDUMP is defined.
+	@Output         phScript           Handle of the PDump script buffer
+	@Output         pui32MaxLen        max length the script buffer can be
+	@Return         PVRSRV_OK on success, a failure code otherwise.
+	*/ /**************************************************************************/
 	PVRSRV_ERROR PDumpOSGetScriptString(IMG_HANDLE *phScript, IMG_UINT32 *pui32MaxLen);
 
-	/*!
-	 * @name	PDumpOSGetMessageString
-	 * @brief	Get the "message" buffer
-	 * @param	pszMsg - buffer pointer for pdump messages
-	 * @param	pui32MaxLen - max length of the message buffer
-	 * @return	error (always PVRSRV_OK on some OSes)
-	 */
+	/**************************************************************************/ /*!
+	@Function       PDumpOSGetMessageString
+	@Description    Get the PDump "message" buffer.
+	                This function is only called if PDUMP is defined.
+	@Output         ppszMsg            Pointer to the PDump message buffer
+	@Output         pui32MaxLen        max length the message buffer can be
+	@Return         PVRSRV_OK on success, a failure code otherwise.
+	*/ /**************************************************************************/
 	PVRSRV_ERROR PDumpOSGetMessageString(IMG_CHAR **ppszMsg, IMG_UINT32 *pui32MaxLen);
 
-	/*!
-	 * @name	PDumpOSGetFilenameString
-	 * @brief	Get the "filename" buffer
-	 * @param	ppszFile - buffer pointer for filename
-	 * @param	pui32MaxLen - max length of the filename buffer
-	 * @return	error (always PVRSRV_OK on some OSes)
-	 */
+	/**************************************************************************/ /*!
+	@Function       PDumpOSGetFilenameString
+	@Description    Get the PDump "filename" buffer.
+	                This function is only called if PDUMP is defined.
+	@Output         ppszFile           Pointer to the PDump filename buffer
+	@Output         pui32MaxLen        max length the filename buffer can be
+	@Return         PVRSRV_OK on success, a failure code otherwise.
+	*/ /**************************************************************************/
 	PVRSRV_ERROR PDumpOSGetFilenameString(IMG_CHAR **ppszFile, IMG_UINT32 *pui32MaxLen);
 
 #endif /* __QNXNTO__ */
@@ -157,23 +170,56 @@
 	IMG_HANDLE hDeinit;      /*!< Driver/HW de-initialisation PDump stream */
 } PDUMP_CHANNEL;
 
+/**************************************************************************/ /*!
+@Function       PDumpOSInit
+@Description    Reset the connection to vldbgdrv, then try to connect to
+                PDump streams. This function is only called if PDUMP is
+                defined.
+@Input          psParam            PDump channel to be used for logging
+                                   parameters
+@Input          psScript           PDump channel to be used for logging
+                                   commands / events
+@Output         pui32InitCapMode   The initial PDump capture mode.
+@Output         ppszEnvComment     Environment-specific comment that is
+                                   output when writing to the PDump
+                                   stream (this may be NULL).
+@Return         PVRSRV_OK on success, a failure code otherwise.
+*/ /**************************************************************************/
 PVRSRV_ERROR PDumpOSInit(PDUMP_CHANNEL* psParam, PDUMP_CHANNEL* psScript,
 		IMG_UINT32* pui32InitCapMode, IMG_CHAR** ppszEnvComment);
 
+/**************************************************************************/ /*!
+@Function       PDumpOSDeInit
+@Description    Disconnect the PDump streams and close the connection to
+                vldbgdrv. This function is only called if PDUMP is defined.
+@Input          psParam            PDump parameter channel to be closed
+@Input          psScript           PDump command channel to be closed
+@Return         None
+*/ /**************************************************************************/
 void PDumpOSDeInit(PDUMP_CHANNEL* psParam, PDUMP_CHANNEL* psScript);
 
-/*!
- * @name	PDumpOSSetSplitMarker
- * @brief	Inform the PDump client to start a new file at the given marker.
- * @param	hStream - stream
- * @param   ui32Marker - byte file position
- */
+/**************************************************************************/ /*!
+@Function       PDumpOSSetSplitMarker
+@Description    Inform the PDump client to start a new file at the given
+                marker. This function is only called if PDUMP is defined.
+@Input          hStream            handle of PDump stream
+@Input          ui32Marker         byte file position
+@Return         IMG_TRUE
+*/ /**************************************************************************/
 IMG_BOOL PDumpOSSetSplitMarker(IMG_HANDLE hStream, IMG_UINT32 ui32Marker);
 
-/*
-	PDumpOSDebugDriverWrite - ENV layer write entry point from COMMON layer
-	                          A call back down the PDump software layer
- */
+/**************************************************************************/ /*!
+@Function       PDumpOSDebugDriverWrite
+@Description    Writes a given number of bytes from the specified buffer
+                to a PDump stream. This function is only called if PDUMP
+                is defined.
+@Input          psStream           handle of PDump stream to write into
+@Input          pui8Data           buffer to write data from
+@Input          ui32BCount         number of bytes to write
+@Return         The number of bytes actually written (may be less than
+                ui32BCount if there is insufficient space in the target
+                PDump stream buffer)
+*/ /**************************************************************************/
 IMG_UINT32 PDumpOSDebugDriverWrite(IMG_HANDLE psStream,
                                    IMG_UINT8 *pui8Data,
                                    IMG_UINT32 ui32BCount);
@@ -187,119 +233,114 @@
 #define PDUMP_va_end	va_end
 
 
-/*!
- * @name	PDumpOSBufprintf
- * @brief	Printf to OS-specific pdump state buffer
- * @param	hBuf - buffer handle to write into
- * @param	ui32ScriptSizeMax - maximum size of data to write (not supported on all OSes)
- * @param	pszFormat - format string
- */
-PVRSRV_ERROR PDumpOSBufprintf(IMG_HANDLE hBuf, IMG_UINT32 ui32ScriptSizeMax, IMG_CHAR* pszFormat, ...) IMG_FORMAT_PRINTF(3, 4);
+/**************************************************************************/ /*!
+@Function       PDumpOSBufprintf
+@Description    Printf to OS-specific PDump state buffer. This function is
+                only called if PDUMP is defined.
+@Input          hBuf               handle of buffer to write into
+@Input          ui32ScriptSizeMax  maximum size of data to write (chars)
+@Input          pszFormat          format string
+@Return         None
+*/ /**************************************************************************/
+PVRSRV_ERROR PDumpOSBufprintf(IMG_HANDLE hBuf, IMG_UINT32 ui32ScriptSizeMax, IMG_CHAR* pszFormat, ...) __printf(3, 4);
 
-/*!
- * @name	PDumpOSDebugPrintf
- * @brief	Debug message during pdumping
- * @param	pszFormat - format string
- */
-void PDumpOSDebugPrintf(IMG_CHAR* pszFormat, ...) IMG_FORMAT_PRINTF(1, 2);
+/**************************************************************************/ /*!
+@Function       PDumpOSDebugPrintf
+@Description    Debug message during PDumping. This function is only called
+                if PDUMP is defined.
+@Input          pszFormat            format string
+@Return         None
+*/ /**************************************************************************/
+void PDumpOSDebugPrintf(IMG_CHAR* pszFormat, ...) __printf(1, 2);
 
 /*
  * Write into a IMG_CHAR* on all OSes. Can be allocated on the stack or heap.
  */
-/*!
- * @name	PDumpOSSprintf
- * @brief	Printf to IMG char array
- * @param	pszComment - char array to print into
- * @param	pszFormat - format string
- */
-PVRSRV_ERROR PDumpOSSprintf(IMG_CHAR *pszComment, IMG_UINT32 ui32ScriptSizeMax, IMG_CHAR *pszFormat, ...) IMG_FORMAT_PRINTF(3, 4);
+/**************************************************************************/ /*!
+@Function       PDumpOSSprintf
+@Description    Printf to IMG char array. This function is only called if
+                PDUMP is defined.
+@Input          ui32ScriptSizeMax    maximum size of data to write (chars)
+@Input          pszFormat            format string
+@Output         pszComment           char array to print into
+@Return         PVRSRV_OK on success, a failure code otherwise.
+*/ /**************************************************************************/
+PVRSRV_ERROR PDumpOSSprintf(IMG_CHAR *pszComment, IMG_UINT32 ui32ScriptSizeMax, IMG_CHAR *pszFormat, ...) __printf(3, 4);
 
-/*!
- * @name	PDumpOSVSprintf
- * @brief	Printf to IMG string using variable args (see stdarg.h). This is necessary
- * 			because the ... notation does not support nested function calls.
- * @param	pszMsg - char array to print into
- * @param	ui32ScriptSizeMax - maximum size of data to write (not supported on all OSes)
- * @param	pszFormat - format string
- * @param	vaArgs - variable args structure (from stdarg.h)
- */
-PVRSRV_ERROR PDumpOSVSprintf(IMG_CHAR *pszMsg, IMG_UINT32 ui32ScriptSizeMax, IMG_CHAR* pszFormat, PDUMP_va_list vaArgs) IMG_FORMAT_PRINTF(3, 0);
+/**************************************************************************/ /*!
+@Function       PDumpOSVSprintf
+@Description    Printf to IMG string using variable args (see stdarg.h).
+                This is necessary because the '...' notation does not
+                support nested function calls.
+                This function is only called if PDUMP is defined.
+@Input          ui32ScriptSizeMax    maximum size of data to write (chars)
+@Input          pszFormat            format string
+@Input          vaArgs               variable args structure (from stdarg.h)
+@Output         pszMsg               char array to print into
+@Return         PVRSRV_OK on success, a failure code otherwise.
+*/ /**************************************************************************/
+PVRSRV_ERROR PDumpOSVSprintf(IMG_CHAR *pszMsg, IMG_UINT32 ui32ScriptSizeMax, const IMG_CHAR* pszFormat, PDUMP_va_list vaArgs) __printf(3, 0);
 
-/*!
- * @name	PDumpOSBuflen
- * @param	hBuffer - handle to buffer
- * @param	ui32BuffeRSizeMax - max size of buffer (chars)
- * @return	length of buffer, will always be <= ui32BufferSizeMax
- */
+/**************************************************************************/ /*!
+@Function       PDumpOSBuflen
+@Description    Returns the length of the specified buffer (in chars).
+                This function is only called if PDUMP is defined.
+@Input          hBuffer              handle to buffer
+@Input          ui32BufferSizeMax    max size of buffer (chars)
+@Return         The length of the buffer, will always be <= ui32BufferSizeMax
+*/ /**************************************************************************/
 IMG_UINT32 PDumpOSBuflen(IMG_HANDLE hBuffer, IMG_UINT32 ui32BufferSizeMax);
 
-/*!
- * @name	PDumpOSVerifyLineEnding
- * @brief	Put line ending sequence at the end if it isn't already there
- * @param	hBuffer - handle to buffer
- * @param	ui32BufferSizeMax - max size of buffer (chars)
- */
+/**************************************************************************/ /*!
+@Function       PDumpOSVerifyLineEnding
+@Description    Put line ending sequence at the end if it isn't already
+                there. This function is only called if PDUMP is defined.
+@Input          hBuffer              handle to buffer
+@Input          ui32BufferSizeMax    max size of buffer (chars)
+@Return         None
+*/ /**************************************************************************/
 void PDumpOSVerifyLineEnding(IMG_HANDLE hBuffer, IMG_UINT32 ui32BufferSizeMax);
 
-/*!
- * @name	PDumpOSCPUVAddrToDevPAddr
- * @brief	OS function to convert CPU virtual to device physical for dumping pages
- * @param	hOSMemHandle	mem allocation handle (used if kernel virtual mem space is limited, e.g. linux)
- * @param	ui32Offset		dword offset into allocation (for use with mem handle, e.g. linux)
- * @param	pui8LinAddr		CPU linear addr (usually a kernel virtual address)
- * @param	ui32PageSize	page size, used for assertion check
- * @return	psDevPAddr		device physical addr
- */
-void PDumpOSCPUVAddrToDevPAddr(PVRSRV_DEVICE_TYPE eDeviceType,
-        IMG_HANDLE hOSMemHandle,
-		IMG_UINT32 ui32Offset,
-		IMG_UINT8 *pui8LinAddr,
-		IMG_UINT32 ui32PageSize,
-		IMG_DEV_PHYADDR *psDevPAddr);
-
-/*!
- * @name	PDumpOSCPUVAddrToPhysPages
- * @brief	OS function to convert CPU virtual to backing physical pages
- * @param	hOSMemHandle	mem allocation handle (used if kernel virtual mem space is limited, e.g. linux)
- * @param	ui32Offset		offset within mem allocation block
- * @param	pui8LinAddr		CPU linear addr
- * @param	ui32DataPageMask	mask for data page (= data page size -1)
- * @return	pui32PageOffset	CPU page offset (same as device page offset if page sizes equal)
- */
-void PDumpOSCPUVAddrToPhysPages(IMG_HANDLE hOSMemHandle,
-		IMG_UINT32 ui32Offset,
-		IMG_PUINT8 pui8LinAddr,
-		IMG_UINT32 ui32DataPageMask,
-		IMG_UINT32 *pui32PageOffset);
-
-/*!
- * @name	PDumpOSReleaseExecution
- * @brief	OS function to switch to another process, to clear pdump buffers
- */
+/**************************************************************************/ /*!
+@Function       PDumpOSReleaseExecution
+@Description    OS function to switch to another process, to clear PDump
+                buffers.
+                This function can simply wrap OSReleaseThreadQuanta.
+                This function is only called if PDUMP is defined.
+@Return         None
+*/ /**************************************************************************/
 void PDumpOSReleaseExecution(void);
 
-/*!
- * @name	PDumpOSCreateLock
- * @brief	Create the global pdump lock
- */
+/**************************************************************************/ /*!
+@Function       PDumpOSCreateLock
+@Description    Create the global pdump lock. This function is only called
+                if PDUMP is defined.
+@Return         None
+*/ /**************************************************************************/
 PVRSRV_ERROR PDumpOSCreateLock(void);
 
-/*!
- * @name	PDumpOSDestroyLock
- * @brief	Destroy the global pdump lock
- */
+/**************************************************************************/ /*!
+@Function       PDumpOSDestroyLock
+@Description    Destroy the global pdump lock This function is only called
+                if PDUMP is defined.
+@Return         None
+*/ /**************************************************************************/
 void PDumpOSDestroyLock(void);
 
-/*!
- * @name	PDumpOSLock
- * @brief	Acquire the global pdump lock
- */
+/**************************************************************************/ /*!
+@Function       PDumpOSLock
+@Description    Acquire the global pdump lock. This function is only called
+                if PDUMP is defined.
+@Return         None
+*/ /**************************************************************************/
 void PDumpOSLock(void);
 
-/*!
- * @name	PDumpOSUnlock
- * @brief	Release the global pdump lock
- */
+/**************************************************************************/ /*!
+@Function       PDumpOSUnlock
+@Description    Release the global pdump lock. This function is only called
+                if PDUMP is defined.
+@Return         None
+*/ /**************************************************************************/
 void PDumpOSUnlock(void);
 
 /*!
diff --git a/drivers/staging/imgtec/rogue/pdump_physmem.c b/drivers/staging/imgtec/rogue/pdump_physmem.c
index cc42ab0..3776965 100644
--- a/drivers/staging/imgtec/rogue/pdump_physmem.c
+++ b/drivers/staging/imgtec/rogue/pdump_physmem.c
@@ -43,6 +43,12 @@
 
 #if defined(PDUMP)
 
+#if defined(LINUX)
+#include <linux/ctype.h>
+#else
+#include <ctype.h>
+#endif
+
 #include "img_types.h"
 #include "pvr_debug.h"
 #include "pvrsrv_error.h"
@@ -58,17 +64,51 @@
 /* static IMG_UINT32 guiPDumpMMUContextAvailabilityMask = (1<<MAX_PDUMP_MMU_CONTEXTS)-1; */
 
 
-/* arbitrary buffer length here. */
-#define MAX_SYMBOLIC_ADDRESS_LENGTH 40
-
 struct _PDUMP_PHYSMEM_INFO_T_
 {
-    IMG_CHAR aszSymbolicAddress[MAX_SYMBOLIC_ADDRESS_LENGTH];
+    IMG_CHAR aszSymbolicAddress[PHYSMEM_PDUMP_MEMSPNAME_SYMB_ADDR_MAX_LENGTH];
     IMG_UINT64 ui64Size;
     IMG_UINT32 ui32Align;
     IMG_UINT32 ui32SerialNum;
 };
 
+static IMG_BOOL _IsAllowedSym(IMG_CHAR sym)
+{
+	/* Numbers, Characters or '_' are allowed */
+	if (isalnum(sym) || sym == '_')
+		return IMG_TRUE;
+	else
+		return IMG_FALSE;
+}
+
+static IMG_BOOL _IsLowerCaseSym(IMG_CHAR sym)
+{
+	if (sym >= 'a' && sym <= 'z')
+		return IMG_TRUE;
+	else
+		return IMG_FALSE;
+}
+
+void PDumpMakeStringValid(IMG_CHAR *pszString,
+                          IMG_UINT32 ui32StrLen)
+{
+	IMG_UINT32 i;
+	for (i = 0; i < ui32StrLen; i++)
+	{
+		if (_IsAllowedSym(pszString[i]))
+		{
+			if (_IsLowerCaseSym(pszString[i]))
+				pszString[i] = pszString[i]-32;
+			else
+				pszString[i] = pszString[i];
+		}
+		else
+		{
+			pszString[i] = '_';
+		}
+	}
+}
+
 /**************************************************************************
  * Function Name  : PDumpMalloc
  * Inputs         :
@@ -80,6 +120,8 @@
                             const IMG_CHAR *pszSymbolicAddress,
                             IMG_UINT64 ui64Size,
                             IMG_DEVMEM_ALIGN_T uiAlign,
+                            IMG_BOOL bInitialise,
+                            IMG_UINT32 ui32InitValue,
                             IMG_BOOL bForcePersistent,
                             IMG_HANDLE *phHandlePtr)
 {
@@ -97,17 +139,13 @@
 	{
 		ui32Flags |= PDUMP_FLAGS_PERSISTENT;
 	}
-	else
-	{
-		ui32Flags |= ( PDumpIsPersistent() ) ? PDUMP_FLAGS_PERSISTENT : 0;
-	}
 
 	/*
 		construct the symbolic address
 	*/
 
     OSSNPrintf(psPDumpAllocationInfo->aszSymbolicAddress,
-               sizeof(psPDumpAllocationInfo->aszSymbolicAddress),
+               sizeof(psPDumpAllocationInfo->aszSymbolicAddress)+sizeof(pszDevSpace),
                ":%s:%s",
                pszDevSpace,
                pszSymbolicAddress);
@@ -116,10 +154,22 @@
 		Write to the MMU script stream indicating the memory allocation
 	*/
 	PDUMP_LOCK();
-	eError = PDumpOSBufprintf(hScript, ui32MaxLen, "MALLOC %s 0x%llX 0x%llX\n",
-                            psPDumpAllocationInfo->aszSymbolicAddress,
-                            ui64Size,
-                            uiAlign);
+	if (bInitialise)
+	{
+		eError = PDumpOSBufprintf(hScript, ui32MaxLen, "CALLOC %s 0x%llX 0x%llX 0x%X\n",
+								psPDumpAllocationInfo->aszSymbolicAddress,
+								ui64Size,
+								uiAlign,
+								ui32InitValue);
+	}
+	else
+	{
+		eError = PDumpOSBufprintf(hScript, ui32MaxLen, "MALLOC %s 0x%llX 0x%llX\n",
+								psPDumpAllocationInfo->aszSymbolicAddress,
+								ui64Size,
+								uiAlign);
+	}
+
 	if(eError != PVRSRV_OK)
 	{
 		OSFreeMem(psPDumpAllocationInfo);
@@ -157,8 +207,6 @@
 
     psPDumpAllocationInfo = (PDUMP_PHYSMEM_INFO_T *)hPDumpAllocationInfoHandle;
 
-	ui32Flags |= ( PDumpIsPersistent() ) ? PDUMP_FLAGS_PERSISTENT : 0;
-
 	/*
 		Write to the MMU script stream indicating the memory free
 	*/
@@ -189,8 +237,6 @@
 
 	PDUMP_GET_SCRIPT_STRING()
 
-	uiPDumpFlags |= (PDumpIsPersistent()) ? PDUMP_FLAGS_PERSISTENT : 0;
-
 	PDUMP_LOCK();
 	eError = PDumpOSBufprintf(hScript,
                               ui32MaxLen,
@@ -223,8 +269,6 @@
 
 	PDUMP_GET_SCRIPT_STRING()
 
-	uiPDumpFlags |= (PDumpIsPersistent()) ? PDUMP_FLAGS_PERSISTENT : 0;
-
 	PDUMP_LOCK();
 	eError = PDumpOSBufprintf(hScript,
                               ui32MaxLen,
@@ -259,8 +303,6 @@
 
 	PDUMP_GET_SCRIPT_STRING()
 
-	uiPDumpFlags |= (PDumpIsPersistent()) ? PDUMP_FLAGS_PERSISTENT : 0;
-
 	PDUMP_LOCK();
 	eError = PDumpOSBufprintf(hScript,
                               ui32MaxLen,
@@ -297,8 +339,7 @@
 
 	PDUMP_GET_SCRIPT_STRING()
 
-    uiPDumpFlags = 0; //PDUMP_FLAGS_CONTINUOUS;
-	uiPDumpFlags |= ( PDumpIsPersistent() ) ? PDUMP_FLAGS_PERSISTENT : 0;
+	uiPDumpFlags = 0;
 
 	PDUMP_LOCK();
 	eError = PDumpOSBufprintf(hScript,
@@ -339,9 +380,6 @@
 
 	PDUMP_GET_SCRIPT_STRING()
 
-
-	uiPDumpFlags |= ( PDumpIsPersistent() ) ? PDUMP_FLAGS_PERSISTENT : 0;
-
 	PDUMP_LOCK();
 	eError = PDumpOSBufprintf(hScript,
                               ui32MaxLen,
@@ -380,8 +418,6 @@
 
 	PDUMP_GET_SCRIPT_STRING()
 
-	uiPDumpFlags |= ( PDumpIsPersistent() ) ? PDUMP_FLAGS_PERSISTENT : 0;
-
 	PDUMP_LOCK();
 	eError = PDumpOSBufprintf(hScript,
                               ui32MaxLen,
@@ -448,40 +484,4 @@
 	return eError;
 }
 
-IMG_INTERNAL void
-PDumpPMRMallocPMR(const PMR *psPMR,
-                  IMG_DEVMEM_SIZE_T uiSize,
-                  IMG_DEVMEM_ALIGN_T uiBlockSize,
-                  IMG_BOOL bForcePersistent,
-                  IMG_HANDLE *phPDumpAllocInfoPtr)
-{
-    PVRSRV_ERROR eError;
-    IMG_HANDLE hPDumpAllocInfo;
-    IMG_CHAR aszMemspaceName[30];
-    IMG_CHAR aszSymbolicName[30];
-    IMG_DEVMEM_OFFSET_T uiOffset;
-    IMG_DEVMEM_OFFSET_T uiNextSymName;
-
-    uiOffset = 0;
-    eError = PMR_PDumpSymbolicAddr(psPMR,
-                                   uiOffset,
-                                   sizeof(aszMemspaceName),
-                                   &aszMemspaceName[0],
-                                   sizeof(aszSymbolicName),
-                                   &aszSymbolicName[0],
-                                   &uiOffset,
-				   &uiNextSymName);
-    PVR_ASSERT(eError == PVRSRV_OK);
-    PVR_ASSERT(uiOffset == 0);
-    PVR_ASSERT((uiOffset + uiSize) <= uiNextSymName);
-
-	PDumpMalloc(aszMemspaceName,
-				   aszSymbolicName,
-				   uiSize,
-				   uiBlockSize,
-				   bForcePersistent,
-				   &hPDumpAllocInfo);
-
-	*phPDumpAllocInfoPtr = hPDumpAllocInfo;
-}
 #endif /* PDUMP */
diff --git a/drivers/staging/imgtec/rogue/pdump_physmem.h b/drivers/staging/imgtec/rogue/pdump_physmem.h
index 20f16c8..6363a9c 100644
--- a/drivers/staging/imgtec/rogue/pdump_physmem.h
+++ b/drivers/staging/imgtec/rogue/pdump_physmem.h
@@ -48,6 +48,9 @@
 #include "pvrsrv_error.h"
 #include "pmr.h"
 
+#define PHYSMEM_PDUMP_MEMSPACE_MAX_LENGTH 40
+#define PHYSMEM_PDUMP_SYMNAME_MAX_LENGTH 60
+#define PHYSMEM_PDUMP_MEMSPNAME_SYMB_ADDR_MAX_LENGTH (PHYSMEM_PDUMP_SYMNAME_MAX_LENGTH + PHYSMEM_PDUMP_MEMSPACE_MAX_LENGTH)
 
 typedef struct _PDUMP_PHYSMEM_INFO_T_ PDUMP_PHYSMEM_INFO_T;
 
@@ -60,18 +63,17 @@
                   minimum contiguity - i.e. smallest allowable
                   page-size. */
                IMG_DEVMEM_ALIGN_T uiAlign,
+               IMG_BOOL bInitialise,
+               IMG_UINT32 ui32InitValue,
                IMG_BOOL bForcePersistent,
                IMG_HANDLE *phHandlePtr);
 
-IMG_INTERNAL void
-PDumpPMRMallocPMR(const PMR *psPMR,
-                  IMG_DEVMEM_SIZE_T uiSize,
-                  IMG_DEVMEM_ALIGN_T uiBlockSize,
-                  IMG_BOOL bForcePersistent,
-                  IMG_HANDLE *phPDumpAllocInfoPtr);
-
 extern
 PVRSRV_ERROR PDumpFree(IMG_HANDLE hPDumpAllocationInfoHandle);
+
+IMG_INTERNAL void
+PDumpMakeStringValid(IMG_CHAR *pszString,
+                     IMG_UINT32 ui32StrLen);
 #else	/* PDUMP */
 
 #ifdef INLINE_IS_PRAGMA
@@ -82,6 +84,8 @@
                const IMG_CHAR *pszSymbolicAddress,
                IMG_UINT64 ui64Size,
                IMG_DEVMEM_ALIGN_T uiAlign,
+               IMG_BOOL bInitialise,
+               IMG_UINT32 ui32InitValue,
                IMG_BOOL bForcePersistent,
                IMG_HANDLE *phHandlePtr)
 {
@@ -89,29 +93,14 @@
 	PVR_UNREFERENCED_PARAMETER(pszSymbolicAddress);
 	PVR_UNREFERENCED_PARAMETER(ui64Size);
 	PVR_UNREFERENCED_PARAMETER(uiAlign);
+	PVR_UNREFERENCED_PARAMETER(bInitialise);
+	PVR_UNREFERENCED_PARAMETER(ui32InitValue);
 	PVR_UNREFERENCED_PARAMETER(bForcePersistent);
 	PVR_UNREFERENCED_PARAMETER(phHandlePtr);
 	PVR_UNREFERENCED_PARAMETER(bForcePersistent);
 	return PVRSRV_OK;
 }
 
-static INLINE void
-PDumpPMRMallocPMR(const PMR *psPMR,
-                  IMG_DEVMEM_SIZE_T uiSize,
-                  IMG_DEVMEM_ALIGN_T uiBlockSize,
-                  IMG_BOOL bForcePersistent,
-                  IMG_HANDLE *phPDumpAllocInfoPtr)
-{
-	PVR_UNREFERENCED_PARAMETER(psPMR);
-	PVR_UNREFERENCED_PARAMETER(uiSize);
-	PVR_UNREFERENCED_PARAMETER(uiBlockSize);
-	PVR_UNREFERENCED_PARAMETER(bForcePersistent);
-	PVR_UNREFERENCED_PARAMETER(phPDumpAllocInfoPtr);
-}
-
-#ifdef INLINE_IS_PRAGMA
-#pragma inline(PVRSRVSyncPrimPDumpPolKM)
-#endif
 static INLINE PVRSRV_ERROR
 PDumpFree(IMG_HANDLE hPDumpAllocationInfoHandle)
 {
@@ -121,15 +110,17 @@
 #endif	/* PDUMP */
 
 #define PMR_DEFAULT_PREFIX "PMR"
-#define PMR_SYMBOLICADDR_FMTSPEC "%s%llu"
+#define PMR_SYMBOLICADDR_FMTSPEC "%s%llu_%llu_%s"
+#define PMR_MEMSPACE_FMTSPEC "%s"
+#define PMR_MEMSPACE_CACHE_COHERENT_FMTSPEC "CC_%s"
 
 #if defined(PDUMP)
-#define PDUMP_PHYSMEM_MALLOC_OSPAGES(pszPDumpMemDevName, ui32SerialNum, ui32Size, ui32Align, phHandlePtr) \
-    PDumpMalloc(pszPDumpMemDevName, PMR_OSALLOCPAGES_PREFIX, ui32SerialNum, ui32Size, ui32Align, phHandlePtr)
+#define PDUMP_PHYSMEM_MALLOC_OSPAGES(pszPDumpMemDevName, ui32SerialNum, ui32Size, ui32Align, bInitialise, ui32InitValue, phHandlePtr) \
+    PDumpMalloc(pszPDumpMemDevName, PMR_OSALLOCPAGES_PREFIX, ui32SerialNum, ui32Size, ui32Align, bInitialise, ui32InitValue, phHandlePtr)
 #define PDUMP_PHYSMEM_FREE_OSPAGES(hHandle) \
     PDumpFree(hHandle)
 #else
-#define PDUMP_PHYSMEM_MALLOC_OSPAGES(pszPDumpMemDevName, ui32SerialNum, ui32Size, ui32Align, phHandlePtr) \
+#define PDUMP_PHYSMEM_MALLOC_OSPAGES(pszPDumpMemDevName, ui32SerialNum, ui32Size, ui32Align, bInitialise, ui32InitValue, phHandlePtr) \
     ((void)(*phHandlePtr=NULL))
 #define PDUMP_PHYSMEM_FREE_OSPAGES(hHandle) \
     ((void)(0))
diff --git a/drivers/staging/imgtec/rogue/pdumpdefs.h b/drivers/staging/imgtec/rogue/pdumpdefs.h
index a7ed2a4..9ab8e97 100644
--- a/drivers/staging/imgtec/rogue/pdumpdefs.h
+++ b/drivers/staging/imgtec/rogue/pdumpdefs.h
@@ -161,6 +161,9 @@
 #define PVRSRV_PDUMP_ADDRMODE_FBCCOMPAT_BASE			(1 << PVRSRV_PDUMP_ADDRMODE_FBCCOMPAT_SHIFT)
 #define PVRSRV_PDUMP_ADDRMODE_FBCCOMPAT_ENHANCED		(2 << PVRSRV_PDUMP_ADDRMODE_FBCCOMPAT_SHIFT)
 #define PVRSRV_PDUMP_ADDRMODE_FBCCOMPAT_V2				(3 << PVRSRV_PDUMP_ADDRMODE_FBCCOMPAT_SHIFT)
+#define PVRSRV_PDUMP_ADDRMODE_FBCCOMPAT_V3_SURFACE		(4 << PVRSRV_PDUMP_ADDRMODE_FBCCOMPAT_SHIFT)
+#define PVRSRV_PDUMP_ADDRMODE_FBCCOMPAT_V3_RESOURCE		(5 << PVRSRV_PDUMP_ADDRMODE_FBCCOMPAT_SHIFT)
+
 
 /*! PDump Poll Operator */
 typedef enum _PDUMP_POLL_OPERATOR
diff --git a/drivers/staging/imgtec/rogue/physheap.c b/drivers/staging/imgtec/rogue/physheap.c
index 69aaea1..aab4cfc 100644
--- a/drivers/staging/imgtec/rogue/physheap.c
+++ b/drivers/staging/imgtec/rogue/physheap.c
@@ -49,37 +49,33 @@
 #include "allocmem.h"
 #include "pvr_debug.h"
 #include "osfunc.h"
+#include "pvrsrv.h"
 
 struct _PHYS_HEAP_
 {
-	/*! ID of this physcial memory heap */
+	/*! ID of this physical memory heap */
 	IMG_UINT32					ui32PhysHeapID;
 	/*! The type of this heap */
 	PHYS_HEAP_TYPE			eType;
 
-	/*! Start address of the physcial memory heap (LMA only) */
-	IMG_CPU_PHYADDR				sStartAddr;
-	/*! Size of the physcial memory heap (LMA only) */
-	IMG_UINT64					uiSize;
-	/*! Heap card base (GPU view of sStartAddr, LMA only) */
-	IMG_UINT64					uiCardBase;
-
-
-	/*! PDump name of this physcial memory heap */
+	/*! PDump name of this physical memory heap */
 	IMG_CHAR					*pszPDumpMemspaceName;
 	/*! Private data for the translate routines */
 	IMG_HANDLE					hPrivData;
 	/*! Function callbacks */
 	PHYS_HEAP_FUNCTIONS			*psMemFuncs;
 
+	/*! Array of sub-regions of the heap */
+	PHYS_HEAP_REGION			*pasRegions;
+	IMG_UINT32					ui32NumOfRegions;
 
 	/*! Refcount */
 	IMG_UINT32					ui32RefCount;
-	/*! Pointer to next physcial heap */
+	/*! Pointer to next physical heap */
 	struct _PHYS_HEAP_		*psNext;
 };
 
-PHYS_HEAP *g_psPhysHeapList;
+static PHYS_HEAP *g_psPhysHeapList;
 
 #if defined(REFCOUNT_DEBUG)
 #define PHYSHEAP_REFCOUNT_PRINT(fmt, ...)	\
@@ -125,14 +121,14 @@
 
 	psNew->ui32PhysHeapID = psConfig->ui32PhysHeapID;
 	psNew->eType = psConfig->eType;
-	psNew->sStartAddr = psConfig->sStartAddr;
-	psNew->uiCardBase = psConfig->uiCardBase;
-	psNew->uiSize = psConfig->uiSize;
 	psNew->psMemFuncs = psConfig->psMemFuncs;
 	psNew->hPrivData = psConfig->hPrivData;
 	psNew->ui32RefCount = 0;
 	psNew->pszPDumpMemspaceName = psConfig->pszPDumpMemspaceName;
 
+	psNew->pasRegions = psConfig->pasRegions;
+	psNew->ui32NumOfRegions = psConfig->ui32NumOfRegions;
+
 	psNew->psNext = g_psPhysHeapList;
 	g_psPhysHeapList = psNew;
 
@@ -145,7 +141,12 @@
 {
 	PVR_DPF_ENTERED1(psPhysHeap);
 
-	PVR_ASSERT(psPhysHeap->ui32RefCount == 0);
+#if defined(PVRSRV_FORCE_UNLOAD_IF_BAD_STATE)
+	if (PVRSRVGetPVRSRVData()->eServicesState == PVRSRV_SERVICES_STATE_OK)
+#endif
+	{
+		PVR_ASSERT(psPhysHeap->ui32RefCount == 0);
+	}
 
 	if (g_psPhysHeapList == psPhysHeap)
 	{
@@ -213,46 +214,59 @@
 	return psPhysHeap->eType;
 }
 
-PVRSRV_ERROR PhysHeapGetAddress(PHYS_HEAP *psPhysHeap,
+/*
+ * This function will set the psDevPAddr to whatever the system layer
+ * has set it for the referenced region.
+ * It will not fail if the psDevPAddr is invalid.
+ */
+PVRSRV_ERROR PhysHeapRegionGetDevPAddr(PHYS_HEAP *psPhysHeap,
+								IMG_UINT32 ui32RegionId,
+								IMG_DEV_PHYADDR *psDevPAddr)
+{
+	if (ui32RegionId < psPhysHeap->ui32NumOfRegions)
+	{
+		*psDevPAddr = psPhysHeap->pasRegions[ui32RegionId].sCardBase;
+		return PVRSRV_OK;
+	}
+	else
+	{
+		return PVRSRV_ERROR_INVALID_PARAMS;
+	}
+}
+
+/*
+ * This function will set the psCpuPAddr to whatever the system layer
+ * has set it for the referenced region.
+ * It will not fail if the psCpuPAddr is invalid.
+ */
+PVRSRV_ERROR PhysHeapRegionGetCpuPAddr(PHYS_HEAP *psPhysHeap,
+								IMG_UINT32 ui32RegionId,
 								IMG_CPU_PHYADDR *psCpuPAddr)
 {
-	if (psPhysHeap->eType == PHYS_HEAP_TYPE_LMA)
+	if (ui32RegionId < psPhysHeap->ui32NumOfRegions)
 	{
-		*psCpuPAddr = psPhysHeap->sStartAddr;
+		*psCpuPAddr = psPhysHeap->pasRegions[ui32RegionId].sStartAddr;
 		return PVRSRV_OK;
 	}
-
-	return PVRSRV_ERROR_INVALID_PARAMS;
+	else
+	{
+		return PVRSRV_ERROR_INVALID_PARAMS;
+	}
 }
 
-PVRSRV_ERROR PhysHeapGetBase(PHYS_HEAP *psPhysHeap,
-							 IMG_UINT64 *puiBase)
+PVRSRV_ERROR PhysHeapRegionGetSize(PHYS_HEAP *psPhysHeap,
+								   IMG_UINT32 ui32RegionId,
+								   IMG_UINT64 *puiSize)
 {
-	if (psPhysHeap->eType == PHYS_HEAP_TYPE_LMA)
+	if (ui32RegionId < psPhysHeap->ui32NumOfRegions)
 	{
-		IMG_UINT64 uiTmp = 0;
-		if (psPhysHeap->uiCardBase == --uiTmp)
-		{
-			return PVRSRV_ERROR_INVALID_HEAPINFO;
-		}
-
-		*puiBase = psPhysHeap->uiCardBase;
+		*puiSize = psPhysHeap->pasRegions[ui32RegionId].uiSize;
 		return PVRSRV_OK;
 	}
-
-	return PVRSRV_ERROR_INVALID_PARAMS;
-}
-
-PVRSRV_ERROR PhysHeapGetSize(PHYS_HEAP *psPhysHeap,
-							   IMG_UINT64 *puiSize)
-{
-	if (psPhysHeap->eType == PHYS_HEAP_TYPE_LMA)
+	else
 	{
-		*puiSize = psPhysHeap->uiSize;
-		return PVRSRV_OK;
+		return PVRSRV_ERROR_INVALID_PARAMS;
 	}
-
-	return PVRSRV_ERROR_INVALID_PARAMS;
 }
 
 void PhysHeapCpuPAddrToDevPAddr(PHYS_HEAP *psPhysHeap,
@@ -277,6 +291,18 @@
 												 psDevPAddr);
 }
 
+IMG_UINT32 PhysHeapGetRegionId(PHYS_HEAP *psPhysHeap,
+								PVRSRV_MEMALLOCFLAGS_T uiAllocFlags)
+{
+	if (psPhysHeap->psMemFuncs->pfnGetRegionId == NULL)
+	{
+		return 0;
+	}
+
+	return psPhysHeap->psMemFuncs->pfnGetRegionId(psPhysHeap->hPrivData,
+												 uiAllocFlags);
+}
+
 IMG_CHAR *PhysHeapPDumpMemspaceName(PHYS_HEAP *psPhysHeap)
 {
 	return psPhysHeap->pszPDumpMemspaceName;
@@ -295,3 +321,8 @@
 
 	return PVRSRV_OK;
 }
+
+IMG_UINT32 PhysHeapNumberOfRegions(PHYS_HEAP *psPhysHeap)
+{
+	return psPhysHeap->ui32NumOfRegions;
+}
diff --git a/drivers/staging/imgtec/rogue/physheap.h b/drivers/staging/imgtec/rogue/physheap.h
index 1ab8ebc..add748b 100644
--- a/drivers/staging/imgtec/rogue/physheap.h
+++ b/drivers/staging/imgtec/rogue/physheap.h
@@ -1,6 +1,6 @@
 /*************************************************************************/ /*!
 @File
-@Title          Physcial heap management header
+@Title          Physical heap management header
 @Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
 @Description    Defines the interface for the physical heap management
 @License        Dual MIT/GPLv2
@@ -43,6 +43,7 @@
 
 #include "img_types.h"
 #include "pvrsrv_error.h"
+#include "pvrsrv_memallocflags.h"
 
 #ifndef _PHYSHEAP_H_
 #define _PHYSHEAP_H_
@@ -59,12 +60,17 @@
 								   IMG_CPU_PHYADDR *psCpuPAddr,
 								   IMG_DEV_PHYADDR *psDevPAddr);
 
+typedef IMG_UINT32 (*GetRegionId)(IMG_HANDLE hPrivData,
+								   PVRSRV_MEMALLOCFLAGS_T uiAllocationFlags);
+
 typedef struct _PHYS_HEAP_FUNCTIONS_
 {
 	/*! Translate CPU physical address to device physical address */
 	CpuPAddrToDevPAddr	pfnCpuPAddrToDevPAddr;
 	/*! Translate device physical address to CPU physical address */
 	DevPAddrToCpuPAddr	pfnDevPAddrToCpuPAddr;
+	/*! Return id of heap region to allocate from */
+	GetRegionId			pfnGetRegionId;
 } PHYS_HEAP_FUNCTIONS;
 
 typedef enum _PHYS_HEAP_TYPE_
@@ -72,21 +78,32 @@
 	PHYS_HEAP_TYPE_UNKNOWN = 0,
 	PHYS_HEAP_TYPE_UMA,
 	PHYS_HEAP_TYPE_LMA,
+#if defined(SUPPORT_PVRSRV_GPUVIRT)
+	PHYS_HEAP_TYPE_DMA,
+#endif
 } PHYS_HEAP_TYPE;
 
+typedef struct _PHYS_HEAP_REGION_
+{
+	IMG_CPU_PHYADDR			sStartAddr;
+	IMG_DEV_PHYADDR			sCardBase;
+	IMG_UINT64				uiSize;
+#if defined(SUPPORT_PVRSRV_GPUVIRT)
+	IMG_HANDLE				hPrivData;
+	IMG_BOOL				bDynAlloc;
+#endif
+} PHYS_HEAP_REGION;
+
 typedef struct _PHYS_HEAP_CONFIG_
 {
 	IMG_UINT32				ui32PhysHeapID;
 	PHYS_HEAP_TYPE			eType;
-	/*
-		Note:
-		sStartAddr, uiCardBase and uiSize are only required for LMA heaps
-	*/
-	IMG_CPU_PHYADDR			sStartAddr;
-	IMG_UINT64				uiCardBase;
-	IMG_UINT64				uiSize;
 	IMG_CHAR				*pszPDumpMemspaceName;
 	PHYS_HEAP_FUNCTIONS		*psMemFuncs;
+
+	PHYS_HEAP_REGION		*pasRegions;
+	IMG_UINT32				ui32NumOfRegions;
+
 	IMG_HANDLE				hPrivData;
 } PHYS_HEAP_CONFIG;
 
@@ -102,24 +119,39 @@
 
 PHYS_HEAP_TYPE PhysHeapGetType(PHYS_HEAP *psPhysHeap);
 
-PVRSRV_ERROR PhysHeapGetAddress(PHYS_HEAP *psPhysHeap,
+PVRSRV_ERROR PhysHeapRegionGetCpuPAddr(PHYS_HEAP *psPhysHeap,
+									   IMG_UINT32 ui32RegionId,
 								IMG_CPU_PHYADDR *psCpuPAddr);
 
-PVRSRV_ERROR PhysHeapGetBase(PHYS_HEAP *psPhysHeap,
-							IMG_UINT64 *puiBase);
 
-PVRSRV_ERROR PhysHeapGetSize(PHYS_HEAP *psPhysHeap,
+PVRSRV_ERROR PhysHeapRegionGetSize(PHYS_HEAP *psPhysHeap,
+							IMG_UINT32 ui32RegionId,
 						     IMG_UINT64 *puiSize);
 
+PVRSRV_ERROR PhysHeapRegionGetDevPAddr(PHYS_HEAP *psPhysHeap,
+									   IMG_UINT32 ui32RegionId,
+							 		   IMG_DEV_PHYADDR *psDevPAddr);
+
+PVRSRV_ERROR PhysHeapRegionGetSize(PHYS_HEAP *psPhysHeap,
+								   IMG_UINT32 ui32RegionId,
+						     	   IMG_UINT64 *puiSize);
+
+IMG_UINT32 PhysHeapNumberOfRegions(PHYS_HEAP *psPhysHeap);
+
 void PhysHeapCpuPAddrToDevPAddr(PHYS_HEAP *psPhysHeap,
 								IMG_UINT32 ui32NumOfAddr,
 								IMG_DEV_PHYADDR *psDevPAddr,
 								IMG_CPU_PHYADDR *psCpuPAddr);
+
 void PhysHeapDevPAddrToCpuPAddr(PHYS_HEAP *psPhysHeap,
 								IMG_UINT32 ui32NumOfAddr,
 								IMG_CPU_PHYADDR *psCpuPAddr,
 								IMG_DEV_PHYADDR *psDevPAddr);
 
+IMG_UINT32 PhysHeapGetRegionId(PHYS_HEAP *psPhysHeap,
+						PVRSRV_MEMALLOCFLAGS_T uiAllocFlags);
+
+
 IMG_CHAR *PhysHeapPDumpMemspaceName(PHYS_HEAP *psPhysHeap);
 
 PVRSRV_ERROR PhysHeapInit(void);
diff --git a/drivers/staging/imgtec/rogue/physmem.c b/drivers/staging/imgtec/rogue/physmem.c
index c12752e..2175166 100644
--- a/drivers/staging/imgtec/rogue/physmem.c
+++ b/drivers/staging/imgtec/rogue/physmem.c
@@ -49,7 +49,7 @@
 #include "osfunc.h"
 #include "pdump_physmem.h"
 #include "pdump_km.h"
-
+#include "rgx_heaps.h"
 
 #if defined(DEBUG)
 IMG_UINT32 gPMRAllocFail = 0;
@@ -96,6 +96,8 @@
 								ui32MemSize,
 								ui32PageSize,
 								IMG_FALSE,
+								0,
+								IMG_FALSE,
 								phHandlePtr);
 	if(PVRSRV_OK != eError)
 	{
@@ -120,10 +122,12 @@
 		}
 
 		/*Fill the memory with given content */
-		OSMemSet(pvCpuVAddr, u8Value, ui32MemSize);
+		/*NOTE: Wrong for the LMA + ARM64 combination, but this is unlikely */
+		OSCachedMemSet(pvCpuVAddr, u8Value, ui32MemSize);
 
 		/*Map the page to the CPU VA space */
-		eError = psDevNode->pfnDevPxClean(psMemHandle,
+		eError = psDevNode->pfnDevPxClean(psDevNode,
+		                                  psMemHandle,
 		                                  0,
 		                                  ui32MemSize);
 		if(PVRSRV_OK != eError)
@@ -166,8 +170,8 @@
 										PDUMP_FLAGS_CONTINUOUS);
 			if(PVRSRV_OK != eError)
 			{
-				PDUMP_ERROR(eError, "Failed to write LDB statment to script file");
-				PVR_DPF((PVR_DBG_ERROR, "Failed to write LDB statment to script file, error %d", eError));
+				PDUMP_ERROR(eError, "Failed to write LDB statement to script file");
+				PVR_DPF((PVR_DBG_ERROR, "Failed to write LDB statement to script file, error %d", eError));
 			}
 
 		}
@@ -224,68 +228,71 @@
                        IMG_UINT32 *pui32MappingTable,
                        IMG_UINT32 uiLog2PageSize,
                        PVRSRV_MEMALLOCFLAGS_T uiFlags,
+                       IMG_UINT32 uiAnnotationLength,
+                       const IMG_CHAR *pszAnnotation,
                        PMR **ppsPMRPtr)
 {
 	PVRSRV_DEVICE_PHYS_HEAP ePhysHeapIdx;
-	PFN_SYS_DEV_CHECK_MEM_ALLOC_SIZE pfnCheckMemAllocSize = \
-										psDevNode->psDevConfig->pfnCheckMemAllocSize;
-
-#if defined(DEBUG)	
-	static IMG_UINT32 ui32AllocCount = 1;
-
-	if (ui32NumVirtChunks > 1)
-	{	/* We don't currently support sparse memory with non OS page sized heaps */
-		PVR_ASSERT(uiLog2PageSize == OSGetPageShift());
-	}
-#endif /* defined(DEBUG) */
-
+	PFN_SYS_DEV_CHECK_MEM_ALLOC_SIZE pfnCheckMemAllocSize =
+		psDevNode->psDevConfig->pfnCheckMemAllocSize;
 
 	PVR_UNREFERENCED_PARAMETER(psConnection);
+	PVR_UNREFERENCED_PARAMETER(uiAnnotationLength);
+
+	/* We don't currently support sparse memory with non OS page sized heaps */
+	if (ui32NumVirtChunks > 1 && (uiLog2PageSize != OSGetPageShift()))
+	{
+		PVR_DPF((PVR_DBG_ERROR,
+				"Requested page size for sparse 2^%u is not OS page size.",
+				uiLog2PageSize));
+		return PVRSRV_ERROR_INVALID_PARAMS;
+	}
+
+	/* Protect against ridiculous page sizes */
+	if (uiLog2PageSize > RGX_HEAP_2MB_PAGE_SHIFT)
+	{
+		PVR_DPF((PVR_DBG_ERROR, "Page size is too big: 2^%u.", uiLog2PageSize));
+		return PVRSRV_ERROR_INVALID_PARAMS;
+	}
 
 	/* Lookup the requested physheap index to use for this PMR allocation */
-	ePhysHeapIdx = (uiFlags & PVRSRV_MEMALLOCFLAG_FW_LOCAL)  ? PVRSRV_DEVICE_PHYS_HEAP_FW_LOCAL  :
-				   (uiFlags & PVRSRV_MEMALLOCFLAG_CPU_LOCAL) ? PVRSRV_DEVICE_PHYS_HEAP_CPU_LOCAL :
-						   	   	   	   	   	   	   	   	   	   PVRSRV_DEVICE_PHYS_HEAP_GPU_LOCAL;
-
-	/********************************
-	 * Sanity check the cache flags *
-	 ********************************/
-	/* Check if we can honour cached cache-coherent allocations */
-	if ((PVRSRV_CPU_CACHE_MODE(uiFlags) == PVRSRV_MEMALLOCFLAG_CPU_CACHED_CACHE_COHERENT) &&
-		(!PVRSRVSystemHasCacheSnooping()))
+	if (PVRSRV_CHECK_FW_LOCAL(uiFlags))
 	{
+		ePhysHeapIdx = PVRSRV_DEVICE_PHYS_HEAP_FW_LOCAL;
+	}
+	else if (PVRSRV_CHECK_CPU_LOCAL(uiFlags))
+	{
+		ePhysHeapIdx = PVRSRV_DEVICE_PHYS_HEAP_CPU_LOCAL;
+	}
+	else
+	{
+		ePhysHeapIdx = PVRSRV_DEVICE_PHYS_HEAP_GPU_LOCAL;
+	}
+
+	/* Fail if requesting coherency on one side but uncached on the other */
+	if ( (PVRSRV_CHECK_CPU_CACHE_COHERENT(uiFlags) &&
+	         (PVRSRV_CHECK_GPU_UNCACHED(uiFlags) || PVRSRV_CHECK_GPU_WRITE_COMBINE(uiFlags))) )
+	{
+		PVR_DPF((PVR_DBG_ERROR, "Request for CPU coherency but specifying GPU uncached "
+				"Please use GPU cached flags for coherency."));
 		return PVRSRV_ERROR_UNSUPPORTED_CACHE_MODE;
 	}
 
-	/* Both or neither have to be cache-coherent */
-	if ((PVRSRV_CPU_CACHE_MODE(uiFlags) == PVRSRV_MEMALLOCFLAG_CPU_CACHE_COHERENT) ^
-		(PVRSRV_GPU_CACHE_MODE(uiFlags) == PVRSRV_MEMALLOCFLAG_GPU_CACHE_COHERENT))
+	if ( (PVRSRV_CHECK_GPU_CACHE_COHERENT(uiFlags) &&
+	         (PVRSRV_CHECK_CPU_UNCACHED(uiFlags) || PVRSRV_CHECK_CPU_WRITE_COMBINE(uiFlags))) )
 	{
+		PVR_DPF((PVR_DBG_ERROR, "Request for GPU coherency but specifying CPU uncached "
+				"Please use CPU cached flags for coherency."));
 		return PVRSRV_ERROR_UNSUPPORTED_CACHE_MODE;
 	}
 
-	if ((PVRSRV_CPU_CACHE_MODE(uiFlags) == PVRSRV_MEMALLOCFLAG_CPU_CACHED_CACHE_COHERENT) ^
-		(PVRSRV_GPU_CACHE_MODE(uiFlags) == PVRSRV_MEMALLOCFLAG_GPU_CACHED_CACHE_COHERENT))
-	{
-		return PVRSRV_ERROR_UNSUPPORTED_CACHE_MODE;
-	}
-
-
-	if (uiLog2PageSize > OSGetPageShift())
-	{
-		/* If we do support it, this check must become a page size validation */
-		PVR_DPF((PVR_DBG_ERROR, "PVRSRV currently does not support "
-		        "page sizes that are larger than OS page size. Requested 2^%u, OS 2^%u ",
-		        uiLog2PageSize,
-		        (IMG_UINT32) OSGetPageShift()));
-		return PVRSRV_ERROR_INVALID_PARAMS;
-	}
-
 	/* Apply memory budgeting policy */
 	if (pfnCheckMemAllocSize)
 	{
-		PVRSRV_ERROR eError = \
-						pfnCheckMemAllocSize(psDevNode, (IMG_UINT64)uiChunkSize*ui32NumPhysChunks);
+		IMG_UINT64 uiMemSize = (IMG_UINT64)uiChunkSize * ui32NumPhysChunks;
+		PVRSRV_ERROR eError;
+
+		eError = pfnCheckMemAllocSize(psDevNode->psDevConfig->hSysData, uiMemSize);
 		if (eError != PVRSRV_OK)
 		{
 			return eError;
@@ -295,6 +302,8 @@
 #if defined(DEBUG)
 	if (gPMRAllocFail > 0)
 	{
+		static IMG_UINT32 ui32AllocCount = 1;
+
 		if (ui32AllocCount < gPMRAllocFail)
 		{
 			ui32AllocCount++;
@@ -316,6 +325,7 @@
 											pui32MappingTable,
 											uiLog2PageSize,
 											uiFlags,
+											pszAnnotation,
 											ppsPMRPtr);
 }
 
@@ -329,6 +339,8 @@
 							IMG_UINT32 *pui32MappingTable,
 							IMG_UINT32 uiLog2PageSize,
 							PVRSRV_MEMALLOCFLAGS_T uiFlags,
+							IMG_UINT32 uiAnnotationLength,
+							const IMG_CHAR *pszAnnotation,
 							PMR **ppsPMRPtr)
 {
 
@@ -342,11 +354,13 @@
 									pui32MappingTable,
 									uiLog2PageSize,
 									uiFlags,
+									uiAnnotationLength,
+									pszAnnotation,
 									ppsPMRPtr);
 
 	if (eError == PVRSRV_OK)
 	{
-		eError = PMRLockSysPhysAddresses(*ppsPMRPtr, uiLog2PageSize);
+		eError = PMRLockSysPhysAddresses(*ppsPMRPtr);
 	}
 
 	return eError;
diff --git a/drivers/staging/imgtec/rogue/physmem.h b/drivers/staging/imgtec/rogue/physmem.h
index 74864f1..a7b698e 100644
--- a/drivers/staging/imgtec/rogue/physmem.h
+++ b/drivers/staging/imgtec/rogue/physmem.h
@@ -65,13 +65,13 @@
 @Input 				bInitPage				Flag to control initialisation
 @Input         		pszDevSpace             PDUMP memory space in which the
 											allocation is to be done
-@Input 				pszSymbolicAddress		Symboic name of the allocation
+@Input 				pszSymbolicAddress		Symbolic name of the allocation
 @Input 				phHandlePtr				PDUMP handle to the allocation
 @Output      	    psMemHandle             Handle to the allocated memory
 @Output    		    psDevPhysAddr           Device Physical address of allocated
 											page
 
-@Return         PVRSRV_OK if the alloction is successfull
+@Return         PVRSRV_OK if the allocation is successful
 */
 /*****************************************************************************/
 extern PVRSRV_ERROR DevPhysMemAlloc(PVRSRV_DEVICE_NODE *psDevNode,
@@ -149,6 +149,8 @@
                        IMG_UINT32 *pui32MappingTable,
                        IMG_UINT32 uiLog2PageSize,
                        PVRSRV_MEMALLOCFLAGS_T uiFlags,
+                       IMG_UINT32 uiAnnotationLength,
+                       const IMG_CHAR *pszAnnotation,
                        PMR **ppsPMROut);
 
 
@@ -177,6 +179,8 @@
                              IMG_UINT32 *pui32MappingTable,
                              IMG_UINT32 uiLog2PageSize,
                              PVRSRV_MEMALLOCFLAGS_T uiFlags,
+                             IMG_UINT32 uiAnnotationLength,
+                             const IMG_CHAR *pszAnnotation,
                              PMR **ppsPMRPtr);
 
 #endif /* _SRVSRV_PHYSMEM_H_ */
diff --git a/drivers/staging/imgtec/rogue/physmem_dmabuf.c b/drivers/staging/imgtec/rogue/physmem_dmabuf.c
index a8b2330..991a242 100644
--- a/drivers/staging/imgtec/rogue/physmem_dmabuf.c
+++ b/drivers/staging/imgtec/rogue/physmem_dmabuf.c
@@ -48,11 +48,12 @@
 #include "pvrsrv.h"
 #include "pmr.h"
 
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,5,0) || defined(SUPPORT_ION) || defined(KERNEL_HAS_DMABUF_VMAP_MMAP)
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,5,0)) || defined(SUPPORT_ION) || defined(KERNEL_HAS_DMABUF_VMAP_MMAP)
 
-#if defined(SUPPORT_DRM)
-#include "pvr_drm.h"
-#endif
+#include <linux/err.h>
+#include <linux/slab.h>
+#include <linux/dma-buf.h>
+#include <linux/scatterlist.h>
 
 #include "img_types.h"
 #include "pvr_debug.h"
@@ -61,29 +62,16 @@
 
 #include "allocmem.h"
 #include "osfunc.h"
-#include "pdump_physmem.h"
 #include "pmr_impl.h"
 #include "hash.h"
 #include "private_data.h"
 #include "module_common.h"
 
-#if defined(SUPPORT_DRM)
-#include <drm/drmP.h>
-#endif
-
 #if defined(PVR_RI_DEBUG)
 #include "ri_server.h"
 #endif
 
-#include <linux/err.h>
-#include <linux/slab.h>
-#include <linux/dma-buf.h>
-#include <linux/scatterlist.h>
-
-#if defined(CHROMIUMOS_WORKAROUNDS_KERNEL318)
-#define dma_buf_begin_cpu_access(A,B,C,D) dma_buf_begin_cpu_access(A,D)
-#define dma_buf_end_cpu_access(A,B,C,D)   dma_buf_end_cpu_access(A,D)
-#endif
+#include "kernel_compatibility.h"
 
 /*
  * dma_buf_ops
@@ -150,12 +138,12 @@
 	struct dma_buf_attachment *psAttachment;
 	PFN_DESTROY_DMABUF_PMR pfnDestroy;
 	IMG_BOOL bPoisonOnFree;
-	IMG_HANDLE hPDumpAllocInfo;
 
 	/* Modified by PMR lock/unlock */
 	struct sg_table *psSgTable;
 	IMG_DEV_PHYADDR *pasDevPhysAddr;
-	IMG_UINT32 ui32PageCount;
+	IMG_UINT32 ui32PhysPageCount;
+	IMG_UINT32 ui32VirtPageCount;
 } PMR_DMA_BUF_DATA;
 
 /* Start size of the g_psDmaBufHash hash table */
@@ -203,24 +191,27 @@
 static PVRSRV_ERROR PMRFinalizeDmaBuf(PMR_IMPL_PRIVDATA pvPriv)
 {
 	PMR_DMA_BUF_DATA *psPrivData = pvPriv;
-	struct dma_buf *psDmaBuf = psPrivData->psAttachment->dmabuf;
+	struct dma_buf_attachment *psAttachment = psPrivData->psAttachment;
+	struct dma_buf *psDmaBuf = psAttachment->dmabuf;
+	struct sg_table *psSgTable = psPrivData->psSgTable;
 	PVRSRV_ERROR eError;
 
-	if (psPrivData->hPDumpAllocInfo)
-	{
-		PDumpFree(psPrivData->hPDumpAllocInfo);
-		psPrivData->hPDumpAllocInfo = NULL;
-	}
+	psPrivData->ui32PhysPageCount = 0;
+
+	dma_buf_unmap_attachment(psAttachment, psSgTable, DMA_BIDIRECTIONAL);
+
 
 	if (psPrivData->bPoisonOnFree)
 	{
 		void *pvKernAddr;
 		int i, err;
 
-		err = dma_buf_begin_cpu_access(psDmaBuf, 0, psDmaBuf->size, DMA_FROM_DEVICE);
+		err = dma_buf_begin_cpu_access(psDmaBuf, DMA_FROM_DEVICE);
 		if (err)
 		{
-			PVR_DPF((PVR_DBG_ERROR, "%s: Failed to begin cpu access for free poisoning", __func__));
+			PVR_DPF((PVR_DBG_ERROR,
+					 "%s: Failed to begin cpu access for free poisoning (err=%d)",
+					 __func__, err));
 			PVR_ASSERT(IMG_FALSE);
 			goto exit;
 		}
@@ -230,7 +221,9 @@
 			pvKernAddr = dma_buf_kmap(psDmaBuf, i);
 			if (IS_ERR_OR_NULL(pvKernAddr))
 			{
-				PVR_DPF((PVR_DBG_ERROR, "%s: Failed to poison allocation before free", __func__));
+				PVR_DPF((PVR_DBG_ERROR,
+						 "%s: Failed to poison allocation before free (err=%ld)",
+						 __func__, pvKernAddr ? PTR_ERR(pvKernAddr) : -ENOMEM));
 				PVR_ASSERT(IMG_FALSE);
 				goto exit_end_access;
 			}
@@ -241,7 +234,9 @@
 		}
 
 exit_end_access:
-		dma_buf_end_cpu_access(psDmaBuf, 0, psDmaBuf->size, DMA_TO_DEVICE);
+		do {
+			err = dma_buf_end_cpu_access(psDmaBuf, DMA_TO_DEVICE);
+		} while (err == -EAGAIN || err == -EINTR);
 	}
 
 exit:
@@ -254,100 +249,26 @@
 		}
 	}
 
+	OSFreeMem(psPrivData->pasDevPhysAddr);
 	OSFreeMem(psPrivData);
 
 	return PVRSRV_OK;
 }
 
-static PVRSRV_ERROR PMRLockPhysAddressesDmaBuf(PMR_IMPL_PRIVDATA pvPriv,
-					       IMG_UINT32 uiLog2DevPageSize)
+static PVRSRV_ERROR PMRLockPhysAddressesDmaBuf(PMR_IMPL_PRIVDATA pvPriv)
 {
-	PMR_DMA_BUF_DATA *psPrivData = pvPriv;
-	struct dma_buf_attachment *psAttachment = psPrivData->psAttachment;
-	IMG_DEV_PHYADDR *pasDevPhysAddr = NULL;
-	IMG_UINT32 ui32PageCount = 0;
-	struct scatterlist *sg;
-	struct sg_table *table;
-	PVRSRV_ERROR eError;
-	IMG_UINT32 i;
-
-	table = dma_buf_map_attachment(psAttachment, DMA_BIDIRECTIONAL);
-	if (!table)
-	{
-		eError = PVRSRV_ERROR_INVALID_PARAMS;
-		goto fail_map;
-	}
-
-	/*
-	 * We do a two pass process, 1st workout how many pages there
-	 * are, 2nd fill in the data.
-	 */
-	for_each_sg(table->sgl, sg, table->nents, i)
-	{
-		ui32PageCount += PAGE_ALIGN(pvr_sg_length(sg)) / PAGE_SIZE;
-	}
-
-	if (WARN_ON(!ui32PageCount))
-	{
-		PVR_DPF((PVR_DBG_ERROR, "%s: Failed to lock dmabuf with no pages",
-				 __func__));
-		eError = PVRSRV_ERROR_INVALID_PARAMS;
-		goto fail_page_count;
-	}
-
-	pasDevPhysAddr = OSAllocMem(sizeof(*pasDevPhysAddr) * ui32PageCount);
-	if (!pasDevPhysAddr)
-	{
-		eError = PVRSRV_ERROR_OUT_OF_MEMORY;
-		goto fail_alloc;
-	}
-
-	ui32PageCount = 0;
-
-	for_each_sg(table->sgl, sg, table->nents, i)
-	{
-		IMG_UINT32 j;
-
-		for (j = 0; j < pvr_sg_length(sg); j += PAGE_SIZE)
-		{
-			/* Pass 2: Get the page data */
-			pasDevPhysAddr[ui32PageCount].uiAddr = sg_dma_address(sg) + j;
-			ui32PageCount++;
-		}
-	}
-
-	psPrivData->pasDevPhysAddr = pasDevPhysAddr;
-	psPrivData->ui32PageCount = ui32PageCount;
-	psPrivData->psSgTable = table;
-
+	PVR_UNREFERENCED_PARAMETER(pvPriv);
 	return PVRSRV_OK;
-
-fail_alloc:
-fail_page_count:
-	dma_buf_unmap_attachment(psAttachment, table, DMA_BIDIRECTIONAL);
-
-fail_map:
-	PVR_ASSERT(eError!= PVRSRV_OK);
-	return eError;
 }
 
 static PVRSRV_ERROR PMRUnlockPhysAddressesDmaBuf(PMR_IMPL_PRIVDATA pvPriv)
 {
-	PMR_DMA_BUF_DATA *psPrivData = pvPriv;
-	struct dma_buf_attachment *psAttachment = psPrivData->psAttachment;
-	struct sg_table *psSgTable = psPrivData->psSgTable;
-
-	OSFreeMem(psPrivData->pasDevPhysAddr);
-
-	psPrivData->pasDevPhysAddr = NULL;
-	psPrivData->ui32PageCount = 0;
-
-	dma_buf_unmap_attachment(psAttachment, psSgTable, DMA_BIDIRECTIONAL);
-
+	PVR_UNREFERENCED_PARAMETER(pvPriv);
 	return PVRSRV_OK;
 }
 
 static PVRSRV_ERROR PMRDevPhysAddrDmaBuf(PMR_IMPL_PRIVDATA pvPriv,
+					 IMG_UINT32 ui32Log2PageSize,
 					 IMG_UINT32 ui32NumOfPages,
 					 IMG_DEVMEM_OFFSET_T *puiOffset,
 					 IMG_BOOL *pbValid,
@@ -357,6 +278,11 @@
 	IMG_UINT32 ui32PageIndex;
 	IMG_UINT32 idx;
 
+	if (ui32Log2PageSize != PAGE_SHIFT)
+	{
+		return PVRSRV_ERROR_PMR_INCOMPATIBLE_CONTIGUITY;
+	}
+
 	for (idx=0; idx < ui32NumOfPages; idx++)
 	{
 		if (pbValid[idx])
@@ -366,13 +292,12 @@
 			ui32PageIndex = puiOffset[idx] >> PAGE_SHIFT;
 			ui32InPageOffset = puiOffset[idx] - ((IMG_DEVMEM_OFFSET_T)ui32PageIndex << PAGE_SHIFT);
 
-			PVR_ASSERT(ui32PageIndex < psPrivData->ui32PageCount);
-			PVR_ASSERT(ui32InPageOffset < PAGE_SIZE);
 
+			PVR_ASSERT(ui32PageIndex < psPrivData->ui32VirtPageCount);
+			PVR_ASSERT(ui32InPageOffset < PAGE_SIZE);
 			psDevPAddr[idx].uiAddr = psPrivData->pasDevPhysAddr[ui32PageIndex].uiAddr + ui32InPageOffset;
 		}
 	}
-
 	return PVRSRV_OK;
 }
 
@@ -390,7 +315,15 @@
 	PVRSRV_ERROR eError;
 	int err;
 
-	err = dma_buf_begin_cpu_access(psDmaBuf, 0, psDmaBuf->size, DMA_BIDIRECTIONAL);
+	if (psPrivData->ui32PhysPageCount != psPrivData->ui32VirtPageCount)
+	{
+		PVR_DPF((PVR_DBG_ERROR, "%s: Kernel mappings for sparse DMABufs "
+				"are not allowed!", __func__));
+		eError = PVRSRV_ERROR_PMR_NO_KERNEL_MAPPING;
+		goto fail;
+	}
+
+	err = dma_buf_begin_cpu_access(psDmaBuf, DMA_BIDIRECTIONAL);
 	if (err)
 	{
 		eError = PVRSRV_ERROR_PMR_NO_KERNEL_MAPPING;
@@ -410,7 +343,9 @@
 	return PVRSRV_OK;
 
 fail_kmap:
-	dma_buf_end_cpu_access(psDmaBuf, 0, psDmaBuf->size, DMA_BIDIRECTIONAL);
+	do {
+		err = dma_buf_end_cpu_access(psDmaBuf, DMA_BIDIRECTIONAL);
+	} while (err == -EAGAIN || err == -EINTR);
 
 fail:
 	PVR_ASSERT(eError != PVRSRV_OK);
@@ -423,22 +358,31 @@
 	PMR_DMA_BUF_DATA *psPrivData = pvPriv;
 	struct dma_buf *psDmaBuf = psPrivData->psAttachment->dmabuf;
 	void *pvKernAddr = hHandle;
+	int err;
 
 	dma_buf_vunmap(psDmaBuf, pvKernAddr);
 
-	dma_buf_end_cpu_access(psDmaBuf, 0, psDmaBuf->size, DMA_BIDIRECTIONAL);
+	do {
+		err = dma_buf_end_cpu_access(psDmaBuf, DMA_BIDIRECTIONAL);
+	} while (err == -EAGAIN || err == -EINTR);
 }
 
 static PVRSRV_ERROR PMRMMapDmaBuf(PMR_IMPL_PRIVDATA pvPriv,
-				  const PMR *psPMR,
-				  PMR_MMAP_DATA pOSMMapData)
+                                  PMR *psPMR,
+                                  PMR_MMAP_DATA pOSMMapData)
 {
 	PMR_DMA_BUF_DATA *psPrivData = pvPriv;
 	struct dma_buf *psDmaBuf = psPrivData->psAttachment->dmabuf;
 	struct vm_area_struct *psVma = pOSMMapData;
 	int err;
 
-	PVR_UNREFERENCED_PARAMETER(psPMR);
+	if (psPrivData->ui32PhysPageCount != psPrivData->ui32VirtPageCount)
+	{
+		PVR_DPF((PVR_DBG_ERROR,
+				"%s: Not possible to MMAP sparse DMABufs",
+				__func__));
+		return PVRSRV_ERROR_NOT_IMPLEMENTED;
+	}
 
 	err = dma_buf_mmap(psDmaBuf, psVma, 0);
 	if (err)
@@ -465,80 +409,78 @@
  *****************************************************************************/
 
 PVRSRV_ERROR
-PhysmemCreateNewDmaBufBackedPMR(PHYS_HEAP *psHeap,
-				struct dma_buf_attachment *psAttachment,
-				PFN_DESTROY_DMABUF_PMR pfnDestroy,
-				PVRSRV_MEMALLOCFLAGS_T uiFlags,
-				PMR **ppsPMRPtr)
+PhysmemCreateNewDmaBufBackedPMR(PVRSRV_DEVICE_NODE *psDevNode,
+                                PHYS_HEAP *psHeap,
+                                struct dma_buf_attachment *psAttachment,
+                                PFN_DESTROY_DMABUF_PMR pfnDestroy,
+                                PVRSRV_MEMALLOCFLAGS_T uiFlags,
+                                IMG_DEVMEM_SIZE_T uiChunkSize,
+                                IMG_UINT32 ui32NumPhysChunks,
+                                IMG_UINT32 ui32NumVirtChunks,
+                                IMG_UINT32 *pui32MappingTable,
+                                PMR **ppsPMRPtr)
 {
 	struct dma_buf *psDmaBuf = psAttachment->dmabuf;
 	PMR_DMA_BUF_DATA *psPrivData;
-	IMG_BOOL bMappingTable = IMG_TRUE;
 	PMR_FLAGS_T uiPMRFlags;
 	IMG_BOOL bZeroOnAlloc;
 	IMG_BOOL bPoisonOnAlloc;
 	IMG_BOOL bPoisonOnFree;
 	PVRSRV_ERROR eError;
+	IMG_UINT32 i, j;
+	IMG_UINT32 uiPagesPerChunk = uiChunkSize >> PAGE_SHIFT;
+	IMG_UINT32 ui32PageCount = 0;
+	struct scatterlist *sg;
+	struct sg_table *table;
+	IMG_UINT32 uiSglOffset;
 
-	if (uiFlags & PVRSRV_MEMALLOCFLAG_ZERO_ON_ALLOC)
-	{
-		bZeroOnAlloc = IMG_TRUE;
-	}
-	else
-	{
-		bZeroOnAlloc = IMG_FALSE;
-	}
-
-	if (uiFlags & PVRSRV_MEMALLOCFLAG_POISON_ON_ALLOC)
-	{
-		bPoisonOnAlloc = IMG_TRUE;
-	}
-	else
-	{
-		bPoisonOnAlloc = IMG_FALSE;
-	}
-
-	if (uiFlags & PVRSRV_MEMALLOCFLAG_POISON_ON_FREE)
-	{
-		bPoisonOnFree = IMG_TRUE;
-	}
-	else
-	{
-		bPoisonOnFree = IMG_FALSE;
-	}
+	bZeroOnAlloc = PVRSRV_CHECK_ZERO_ON_ALLOC(uiFlags);
+	bPoisonOnAlloc = PVRSRV_CHECK_POISON_ON_ALLOC(uiFlags);
+	bPoisonOnFree = PVRSRV_CHECK_POISON_ON_FREE(uiFlags);
 
 	if (bZeroOnAlloc && bPoisonOnFree)
 	{
 		/* Zero on Alloc and Poison on Alloc are mutually exclusive */
 		eError = PVRSRV_ERROR_INVALID_PARAMS;
-		goto fail_params;
+		goto errReturn;
 	}
 
 	psPrivData = OSAllocZMem(sizeof(*psPrivData));
 	if (psPrivData == NULL)
 	{
 		eError = PVRSRV_ERROR_OUT_OF_MEMORY;
-		goto fail_priv_alloc;
+		goto errReturn;
 	}
 
 	psPrivData->psPhysHeap = psHeap;
 	psPrivData->psAttachment = psAttachment;
 	psPrivData->pfnDestroy = pfnDestroy;
 	psPrivData->bPoisonOnFree = bPoisonOnFree;
+	psPrivData->ui32VirtPageCount =
+			(ui32NumVirtChunks * uiChunkSize) >> PAGE_SHIFT;
+
+	psPrivData->pasDevPhysAddr =
+			OSAllocZMem(sizeof(*(psPrivData->pasDevPhysAddr)) *
+			            psPrivData->ui32VirtPageCount);
+	if (!psPrivData->pasDevPhysAddr)
+	{
+		PVR_DPF((PVR_DBG_ERROR,
+				"%s: Failed to allocate buffer for physical addresses (oom)",
+				 __func__));
+		eError = PVRSRV_ERROR_OUT_OF_MEMORY;
+		goto errFreePrivData;
+	}
 
 	if (bZeroOnAlloc || bPoisonOnAlloc)
 	{
 		void *pvKernAddr;
 		int i, err;
 
-		err = dma_buf_begin_cpu_access(psDmaBuf,
-					       0,
-					       psDmaBuf->size,
-					       DMA_FROM_DEVICE);
+		err = dma_buf_begin_cpu_access(psDmaBuf, DMA_FROM_DEVICE);
 		if (err)
 		{
 			eError = PVRSRV_ERROR_PMR_NO_KERNEL_MAPPING;
-			goto fail_begin;
+			goto errFreePhysAddr;
 		}
 
 		for (i = 0; i < psDmaBuf->size / PAGE_SIZE; i++)
@@ -547,17 +489,16 @@
 			if (IS_ERR_OR_NULL(pvKernAddr))
 			{
 				PVR_DPF((PVR_DBG_ERROR,
-					 "%s: Failed to map page for %s",
-					 __func__,
-					 bZeroOnAlloc ? "zeroing" : "poisoning"));
+						 "%s: Failed to map page for %s (err=%ld)",
+						 __func__, bZeroOnAlloc ? "zeroing" : "poisoning",
+						 pvKernAddr ? PTR_ERR(pvKernAddr) : -ENOMEM));
 				eError = PVRSRV_ERROR_PMR_NO_KERNEL_MAPPING;
 
-				dma_buf_end_cpu_access(psDmaBuf,
-						       0,
-						       psDmaBuf->size,
-						       DMA_TO_DEVICE);
+				do {
+					err = dma_buf_end_cpu_access(psDmaBuf, DMA_TO_DEVICE);
+				} while (err == -EAGAIN || err == -EINTR);
 
-				goto fail_kmap;
+				goto errFreePhysAddr;
 			}
 
 			if (bZeroOnAlloc)
@@ -572,10 +513,79 @@
 			dma_buf_kunmap(psDmaBuf, i, pvKernAddr);
 		}
 
-		dma_buf_end_cpu_access(psDmaBuf,
-				       0,
-				       psDmaBuf->size,
-				       DMA_TO_DEVICE);
+		do {
+			err = dma_buf_end_cpu_access(psDmaBuf, DMA_TO_DEVICE);
+		} while (err == -EAGAIN || err == -EINTR);
+	}
+
+	table = dma_buf_map_attachment(psAttachment, DMA_BIDIRECTIONAL);
+	if (IS_ERR_OR_NULL(table))
+	{
+		eError = PVRSRV_ERROR_INVALID_PARAMS;
+		goto errFreePhysAddr;
+	}
+
+	/*
+	 * We do a two pass process: first work out how many pages there
+	 * are and second, fill in the data.
+	 */
+	for_each_sg(table->sgl, sg, table->nents, i)
+	{
+		ui32PageCount += PAGE_ALIGN(pvr_sg_length(sg)) / PAGE_SIZE;
+	}
+
+	if (WARN_ON(!ui32PageCount))
+	{
+		PVR_DPF((PVR_DBG_ERROR, "%s: Number of phys. pages must not be zero",
+				 __func__));
+		eError = PVRSRV_ERROR_INVALID_PARAMS;
+		goto errUnmap;
+	}
+
+	if  (WARN_ON(ui32PageCount != ui32NumPhysChunks * uiPagesPerChunk))
+	{
+		PVR_DPF((PVR_DBG_ERROR, "%s: Requested physical chunks and actual "
+				"number of physical dma buf pages don't match",
+				 __func__));
+		eError = PVRSRV_ERROR_INVALID_PARAMS;
+		goto errUnmap;
+	}
+
+	psPrivData->ui32PhysPageCount = ui32PageCount;
+	psPrivData->psSgTable = table;
+	ui32PageCount = 0;
+	sg = table->sgl;
+	uiSglOffset = 0;
+
+
+	/* Fill physical address array */
+	for (i = 0; i < ui32NumPhysChunks; i++)
+	{
+		for (j = 0; j < uiPagesPerChunk; j++)
+		{
+			IMG_UINT32 uiIdx = pui32MappingTable[i] * uiPagesPerChunk + j;
+
+			psPrivData->pasDevPhysAddr[uiIdx].uiAddr =
+					sg_dma_address(sg) + uiSglOffset;
+
+			/* Get the next offset for the current sgl or the next sgl */
+			uiSglOffset += PAGE_SIZE;
+			if (uiSglOffset >= pvr_sg_length(sg))
+			{
+				sg = sg_next(sg);
+				uiSglOffset = 0;
+
+				/* Check that we haven't looped */
+				if (WARN_ON(sg == table->sgl))
+				{
+					PVR_DPF((PVR_DBG_ERROR, "%s: Failed to fill phys. address "
+							"array ",
+							 __func__));
+					eError = PVRSRV_ERROR_INVALID_PARAMS;
+					goto errUnmap;
+				}
+			}
+		}
 	}
 
 	uiPMRFlags = (PMR_FLAGS_T)(uiFlags & PVRSRV_MEMALLOCFLAGS_PMRFLAGSMASK);
@@ -586,48 +596,37 @@
 	 */
 	PVR_ASSERT(uiPMRFlags == (uiFlags & PVRSRV_MEMALLOCFLAGS_PMRFLAGSMASK));
 
-	eError = PMRCreatePMR(psHeap,
-			      psDmaBuf->size,
-			      psDmaBuf->size,
-			      1,
-			      1,
-			      &bMappingTable,
+	eError = PMRCreatePMR(psDevNode,
+			      psHeap,
+			      ui32NumVirtChunks * uiChunkSize,
+			      uiChunkSize,
+			      ui32NumPhysChunks,
+			      ui32NumVirtChunks,
+			      pui32MappingTable,
 			      PAGE_SHIFT,
 			      uiPMRFlags,
-			      "PMRDMABUF",
+			      "IMPORTED_DMABUF",
 			      &_sPMRDmaBufFuncTab,
 			      psPrivData,
+			      PMR_TYPE_DMABUF,
 			      ppsPMRPtr,
-			      &psPrivData->hPDumpAllocInfo,
 			      IMG_FALSE);
 	if (eError != PVRSRV_OK)
 	{
-		PVR_DPF((PVR_DBG_ERROR, "%s: Failed to create PMR", __func__));
-		goto fail_create_pmr;
+		PVR_DPF((PVR_DBG_ERROR, "%s: Failed to create PMR (%s)",
+				 __func__, PVRSRVGetErrorStringKM(eError)));
+		goto errFreePhysAddr;
 	}
 
-#if defined(PVR_RI_DEBUG)
-	eError = RIWritePMREntryKM(*ppsPMRPtr,
-				   sizeof("DMABUF"),
-				   "DMABUF",
-				   psDmaBuf->size);
-	if (eError != PVRSRV_OK)
-	{
-		PVR_DPF((PVR_DBG_WARNING,
-			 "%s: Failed to write PMR entry (%s)",
-			 __func__, PVRSRVGetErrorStringKM(eError)));
-	}
-#endif
-
 	return PVRSRV_OK;
 
-fail_create_pmr:
-fail_kmap:
-fail_begin:
+errUnmap:
+	dma_buf_unmap_attachment(psAttachment, table, DMA_BIDIRECTIONAL);
+errFreePhysAddr:
+	OSFreeMem(psPrivData->pasDevPhysAddr);
+errFreePrivData:
 	OSFreeMem(psPrivData);
-
-fail_priv_alloc:
-fail_params:
+errReturn:
 	PVR_ASSERT(eError != PVRSRV_OK);
 	return eError;
 }
@@ -708,10 +707,8 @@
 
 	if (IS_ERR_OR_NULL(psDmaBuf))
 	{
-		PVR_DPF((PVR_DBG_ERROR,
-		         "%s: dma_buf_export failed (err=%ld)",
-		         __func__,
-		         PTR_ERR(psDmaBuf)));
+		PVR_DPF((PVR_DBG_ERROR, "%s: Failed to export buffer (err=%ld)",
+		         __func__, psDmaBuf ? PTR_ERR(psDmaBuf) : -ENOMEM));
 		eError = PVRSRV_ERROR_OUT_OF_MEMORY;
 		goto fail_pmr_ref;
 	}
@@ -719,10 +716,8 @@
 	iFd = dma_buf_fd(psDmaBuf, O_RDWR);
 	if (iFd < 0)
 	{
-		PVR_DPF((PVR_DBG_ERROR,
-		         "%s: dma_buf_fd failed (err=%d)",
-		         __func__,
-		         iFd));
+		PVR_DPF((PVR_DBG_ERROR, "%s: Failed to get dma-buf fd (err=%d)",
+		         __func__, iFd));
 		eError = PVRSRV_ERROR_OUT_OF_MEMORY;
 		goto fail_dma_buf;
 	}
@@ -742,51 +737,99 @@
 
 PVRSRV_ERROR
 PhysmemImportDmaBuf(CONNECTION_DATA *psConnection,
-		    PVRSRV_DEVICE_NODE *psDevNode,
-		    IMG_INT fd,
-		    PVRSRV_MEMALLOCFLAGS_T uiFlags,
-		    PMR **ppsPMRPtr,
-		    IMG_DEVMEM_SIZE_T *puiSize,
-		    IMG_DEVMEM_ALIGN_T *puiAlign)
+                    PVRSRV_DEVICE_NODE *psDevNode,
+                    IMG_INT fd,
+                    PVRSRV_MEMALLOCFLAGS_T uiFlags,
+                    PMR **ppsPMRPtr,
+                    IMG_DEVMEM_SIZE_T *puiSize,
+                    IMG_DEVMEM_ALIGN_T *puiAlign)
 {
-#if defined(SUPPORT_DRM)
-	struct file *psFile;
-	struct drm_file *psFilePriv;
-#endif
-	struct device *psDev;
+	IMG_DEVMEM_SIZE_T uiSize;
+	IMG_UINT32 ui32MappingTable = 0;
+	struct dma_buf *psDmaBuf;
+
+	/* Get the buffer handle */
+	psDmaBuf = dma_buf_get(fd);
+	if (IS_ERR_OR_NULL(psDmaBuf))
+	{
+		PVR_DPF((PVR_DBG_ERROR, "%s: Failed to get dma-buf from fd (err=%ld)",
+